From 58eadd6d7bbcb31fa774d4ade75853bd4bb8ccc5 Mon Sep 17 00:00:00 2001 From: Yidadaa Date: Wed, 3 May 2023 16:22:37 +0800 Subject: [PATCH] feat: close #782 select prompt with arrow down / up --- app/components/chat.tsx | 57 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 7da9b8c86..bae9c5ba2 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -224,18 +224,63 @@ export function PromptHints(props: { prompts: Prompt[]; onPromptSelect: (prompt: Prompt) => void; }) { - if (props.prompts.length === 0) return null; + const noPrompts = props.prompts.length === 0; + const [selectIndex, setSelectIndex] = useState(0); + const selectedRef = useRef(null); + useEffect(() => { + setSelectIndex(0); + }, [props.prompts.length]); + + useEffect(() => { + const onKeyDown = (e: KeyboardEvent) => { + if (noPrompts) return; + + // arrow up / down to select prompt + const changeIndex = (delta: number) => { + e.stopPropagation(); + e.preventDefault(); + const nextIndex = Math.max( + 0, + Math.min(props.prompts.length - 1, selectIndex + delta), + ); + setSelectIndex(nextIndex); + selectedRef.current?.scrollIntoView({ + block: "center", + }); + }; + + if (e.key === "ArrowUp") { + changeIndex(1); + } else if (e.key === "ArrowDown") { + changeIndex(-1); + } else if (e.key === "Enter") { + const selectedPrompt = props.prompts.at(selectIndex); + if (selectedPrompt) { + props.onPromptSelect(selectedPrompt); + } + } + }; + + window.addEventListener("keydown", onKeyDown); + + return () => window.removeEventListener("keydown", onKeyDown); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [noPrompts, selectIndex]); + + if (noPrompts) return null; return (
{props.prompts.map((prompt, i) => (
{ - console.log("click hint"); - props.onPromptSelect(prompt); - }} + onClick={() => props.onPromptSelect(prompt)} + onMouseEnter={() => setSelectIndex(i)} >
{prompt.title}
{prompt.content}