diff options
Diffstat (limited to 'src/console/components')
-rw-r--r-- | src/console/components/CommandPrompt.tsx | 36 | ||||
-rw-r--r-- | src/console/components/console/Completion.tsx | 8 | ||||
-rw-r--r-- | src/console/components/console/CompletionItem.tsx | 14 |
3 files changed, 39 insertions, 19 deletions
diff --git a/src/console/components/CommandPrompt.tsx b/src/console/components/CommandPrompt.tsx index 0e2506c..5d4cb6e 100644 --- a/src/console/components/CommandPrompt.tsx +++ b/src/console/components/CommandPrompt.tsx @@ -3,6 +3,7 @@ import Completion from "./console/Completion"; import Input from "./console//Input"; import styled from "styled-components"; import { useCompletions, useSelectCompletion } from "../completion/hooks"; +import useDebounce from "../hooks/useDebounce"; import useAutoResize from "../hooks/useAutoResize"; import { CompletionProvider } from "../completion/provider"; import { useExecCommand, useHide } from "../app/hooks"; @@ -17,14 +18,23 @@ interface Props { initialInputValue: string; } +enum SelectQueueType { + SelectNext, + SelectPrev, +} + const CommandPromptInner: React.FC<Props> = ({ initialInputValue }) => { const hide = useHide(); const [inputValue, setInputValue] = React.useState(initialInputValue); - const { completions, updateCompletions } = useCompletions(); + const debouncedValue = useDebounce(inputValue, 100); + const { completions, loading } = useCompletions(debouncedValue); const { select, currentValue, selectNext, selectPrev } = useSelectCompletion(); const execCommand = useExecCommand(); + // The value is set after the user presses Tab (or Shift+Tab) key and waiting the completion + const [selecting, setSelecting] = React.useState<SelectQueueType>(); + useAutoResize(); const onBlur = () => { @@ -65,9 +75,9 @@ const CommandPromptInner: React.FC<Props> = ({ initialInputValue }) => { execCommand(value); hide(); } else if (isNextKey(e)) { - selectNext(); + setSelecting(SelectQueueType.SelectNext); } else if (isPrevKey(e)) { - selectPrev(); + setSelecting(SelectQueueType.SelectPrev); } else { return; } @@ -76,15 +86,25 @@ const CommandPromptInner: React.FC<Props> = ({ initialInputValue }) => { e.preventDefault(); }; + React.useEffect(() => { + if (inputValue !== debouncedValue || loading) { + // The completions of the latest input value are not fetched + return; + } + if (selecting === SelectQueueType.SelectNext) { + selectNext(); + setSelecting(undefined); + } else if (selecting === SelectQueueType.SelectPrev) { + selectPrev(); + setSelecting(undefined); + } + }, [inputValue, debouncedValue, selecting, loading]); + const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { const text = e.target.value; setInputValue(text); }; - React.useEffect(() => { - updateCompletions(inputValue); - }, [inputValue]); - return ( <ConsoleWrapper> <Completion @@ -97,7 +117,7 @@ const CommandPromptInner: React.FC<Props> = ({ initialInputValue }) => { onBlur={onBlur} onKeyDown={onKeyDown} onChange={onChange} - value={select == -1 ? inputValue : currentValue} + value={select == -1 || loading ? inputValue : currentValue} /> </ConsoleWrapper> ); diff --git a/src/console/components/console/Completion.tsx b/src/console/components/console/Completion.tsx index ed271aa..6a58a40 100644 --- a/src/console/components/console/Completion.tsx +++ b/src/console/components/console/Completion.tsx @@ -4,8 +4,8 @@ import CompletionTitle from "./CompletionTitle"; interface Item { icon?: string; - caption?: string; - url?: string; + primary?: string; + secondary?: string; } interface Group { @@ -75,8 +75,8 @@ const Completion: React.FC<Props> = ({ select, size, completions }) => { shown={viewOffset <= viewIndex && viewIndex < viewOffset + size} key={`item-${itemIndex}`} icon={item.icon} - caption={item.caption} - url={item.url} + primary={item.primary} + secondary={item.secondary} highlight={itemIndex === select} aria-selected={itemIndex === select} role="menuitem" diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx index 2de1375..394af04 100644 --- a/src/console/components/console/CompletionItem.tsx +++ b/src/console/components/console/CompletionItem.tsx @@ -23,14 +23,14 @@ const Container = styled.li<{ white-space: pre; `; -const Caption = styled.span` +const Primary = styled.span` display: inline-block; width: 40%; text-overflow: ellipsis; overflow: hidden; `; -const Description = styled.span` +const Secondary = styled.span` display: inline-block; color: ${({ theme }) => theme.completionItemDescriptionForeground}; width: 60%; @@ -41,19 +41,19 @@ const Description = styled.span` interface Props extends React.HTMLAttributes<HTMLElement> { shown: boolean; highlight: boolean; - caption?: string; - url?: string; + primary?: string; + secondary?: string; icon?: string; } const CompletionItem: React.FC<Props> = (props) => ( <Container icon={props.icon || ""} - aria-labelledby={`completion-item-${props.caption}`} + aria-labelledby={`completion-item-${props.primary}`} {...props} > - <Caption id={`completion-item-${props.caption}`}>{props.caption}</Caption> - <Description>{props.url}</Description> + <Primary id={`completion-item-${props.primary}`}>{props.primary}</Primary> + <Secondary>{props.secondary}</Secondary> </Container> ); |