From 39ae7dff7a4ee4bb695d19f73c806dec0466a884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?O=CC=88zgu=CC=88r=20Can=20Alt=C4=B1nok?= Date: Sun, 12 Jun 2022 00:26:33 +0300 Subject: [PATCH] Add jump with keys into demos using onKeyDown event --- site/comps/Select.tsx | 38 ++++++++++++++++++++++++++++++++++---- site/lib/array.ts | 6 ++++++ 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 site/lib/array.ts diff --git a/site/comps/Select.tsx b/site/comps/Select.tsx index a8880f5a3..18237db59 100644 --- a/site/comps/Select.tsx +++ b/site/comps/Select.tsx @@ -3,6 +3,7 @@ import View, { ViewProps } from "comps/View" import Text from "comps/Text" import useClickOutside from "hooks/useClickOutside" import useKey from "hooks/useKey" +import { findLastIndex } from "lib/array" interface PromptProps { name: string, @@ -67,7 +68,6 @@ interface SelectProps { } // TODO: scroll to cur at expand -// TODO: jump with key const Select: React.FC = ({ options, value, @@ -78,6 +78,7 @@ const Select: React.FC = ({ const dropdownRef = React.useRef(null) const [ curItem, setCurItem ] = React.useState(value ?? options[0]) + const [ curItemIndex, setCurItemIndex ] = React.useState(0) const [ expanded, setExpanded ] = React.useState(false) useClickOutside(dropdownRef, () => setExpanded(false), [ setExpanded ]) @@ -138,13 +139,42 @@ const Select: React.FC = ({ { - // TODO - console.log(e.key) + const indexFound = options.findIndex((opt, i) => { + if (curItem[0] === e.key) { + if (!curItemIndex) return e.key === opt[0] && i > 0 + if (curItemIndex === findLastIndex(options, curItem, 0)) { + setCurItemIndex(null) + return e.key === opt[0] + } + else return e.key === opt[0] && curItemIndex < i + } else if (curItem[0] !== e.key) { + return e.key === opt[0] + } + }) + + const newItem = options[indexFound] + + if (e.key !== "Enter" && newItem && curItem !== newItem) { + setCurItem(newItem) + setCurItemIndex(indexFound) + + const selected = dropdownRef.current!.children[indexFound] as HTMLDivElement + + if (selected) { + dropdownRef.current!.scrollTop = selected.offsetTop + } + } + + if (e.key === "Enter") { + onChange && onChange(curItem) + } + }} css={{ overflowY: "auto", diff --git a/site/lib/array.ts b/site/lib/array.ts new file mode 100644 index 000000000..90475ff40 --- /dev/null +++ b/site/lib/array.ts @@ -0,0 +1,6 @@ +export const findLastIndex = (array: string[], searchValue: string, searchIndex: number) => { + const index = array.slice().reverse().findIndex((item: string) => item[searchIndex] === searchValue[searchIndex]) + const count = array.length - 1 + const lastIndex = index >= 0 ? count - index : index + return lastIndex +} \ No newline at end of file