Add highlighting to items in suggest box
This adds highlighting of the currently typed text into the shown items of the suggest box.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
import { styled } from "styled-components";
|
||||
import type { Snippet } from "./highlight";
|
||||
|
||||
const Normal = styled.span``;
|
||||
const Highlighted = styled.span`
|
||||
font-weight: 700;
|
||||
color: var(--vscode-editorSuggestWidget-focusHighlightForeground);
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
snippets: Snippet[];
|
||||
};
|
||||
|
||||
export const HighlightedText = ({ snippets }: Props) => {
|
||||
return (
|
||||
<>
|
||||
{snippets.map((snippet, index) =>
|
||||
snippet.highlight ? (
|
||||
<Highlighted key={index}>{snippet.text}</Highlighted>
|
||||
) : (
|
||||
<Normal key={index}>{snippet.text}</Normal>
|
||||
),
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useMemo } from "react";
|
||||
import { createHighlights } from "./highlight";
|
||||
import { HighlightedText } from "./HighlightedText";
|
||||
import type { Option } from "./options";
|
||||
|
||||
type Props<T extends Option<T>> = {
|
||||
item: T;
|
||||
|
||||
tokens: string[];
|
||||
};
|
||||
|
||||
export const LabelText = <T extends Option<T>>({ item, tokens }: Props<T>) => {
|
||||
const highlights = useMemo(() => {
|
||||
const highlightedToken = tokens[tokens.length - 1] ?? "";
|
||||
|
||||
return createHighlights(item.label, highlightedToken);
|
||||
}, [item, tokens]);
|
||||
|
||||
return <HighlightedText snippets={highlights} />;
|
||||
};
|
||||
@@ -18,6 +18,7 @@ import { VSCodeTextField } from "@vscode/webview-ui-toolkit/react";
|
||||
import type { Option } from "./options";
|
||||
import { findMatchingOptions } from "./options";
|
||||
import { SuggestBoxItem } from "./SuggestBoxItem";
|
||||
import { LabelText } from "./LabelText";
|
||||
|
||||
const Input = styled(VSCodeTextField)`
|
||||
width: 430px;
|
||||
@@ -147,9 +148,13 @@ export const SuggestBox = <T extends Option<T>>({
|
||||
[onChange],
|
||||
);
|
||||
|
||||
const tokens = useMemo(() => {
|
||||
return parseValueToTokens(value);
|
||||
}, [value, parseValueToTokens]);
|
||||
|
||||
const suggestionItems = useMemo(() => {
|
||||
return findMatchingOptions(options, parseValueToTokens(value));
|
||||
}, [options, value, parseValueToTokens]);
|
||||
return findMatchingOptions(options, tokens);
|
||||
}, [options, tokens]);
|
||||
|
||||
useEffect(() => {
|
||||
if (disabled) {
|
||||
@@ -222,7 +227,7 @@ export const SuggestBox = <T extends Option<T>>({
|
||||
})}
|
||||
active={activeIndex === index}
|
||||
icon={getIcon?.(item)}
|
||||
labelText={item.label}
|
||||
labelText={<LabelText tokens={tokens} item={item} />}
|
||||
details={getDetails?.(item)}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
type Snippet = {
|
||||
export type Snippet = {
|
||||
text: string;
|
||||
highlight: boolean;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user