From a2e4334361ceb2710a3cf828464a2f85327af1ca Mon Sep 17 00:00:00 2001 From: Eric Doughty-Papassideris Date: Tue, 12 Mar 2024 22:21:43 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=B8=20Add=20keyboard=20selection=20of?= =?UTF-8?q?=20user=20search=20result=20(#30)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../body/drive/components/select-users.tsx | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/tdrive/frontend/src/app/views/client/body/drive/components/select-users.tsx b/tdrive/frontend/src/app/views/client/body/drive/components/select-users.tsx index b829605a..5128f8f7 100644 --- a/tdrive/frontend/src/app/views/client/body/drive/components/select-users.tsx +++ b/tdrive/frontend/src/app/views/client/body/drive/components/select-users.tsx @@ -23,11 +23,41 @@ export default (props: { const [isFocus, setFocus] = useState(false); const inputElement = useRef(null); const maxUserResultsShown = 5; + const [selectedUserKey, setSelectedUserKey] = useState(''); useEffect(() => { if (users.length) props.onChange(users); }, [users]); + const shownResults = _.reverse(result.slice(0, maxUserResultsShown)); + const selectedKeyIndex = shownResults.findIndex(({id}) => id === selectedUserKey); + + const moveSelection = (offset: number) => { + if (selectedKeyIndex === -1) { + if (offset < 0) + setSelectedUserKey(shownResults[shownResults.length - 1].id || ''); + else if (offset > 0) + setSelectedUserKey(shownResults[0].id || ''); + } else { + const nextIndex = (selectedKeyIndex + shownResults.length + offset) % shownResults.length; + setSelectedUserKey(shownResults[nextIndex].id || ''); + } + }; + const doEnterKey = () => { + const user = shownResults[selectedKeyIndex]; + if (user) { + setUsers([user]); + search(''); + } + setSelectedUserKey(''); + }; + + const keyEvents : { [key: string]: () => void } = { + "ArrowUp": () => moveSelection(-1), + "ArrowDown": () => moveSelection(1), + "Enter": () => doEnterKey(), + }; + return (
{ + if (e.code in keyEvents) { + keyEvents[e.code](); + e.preventDefault(); + } + }} placeholder={Languages.t('components.select-users_search_users')} className={props.className + ' ' + className + ' w-full'} theme="plain" - onChange={e => search(e.target.value)} + onChange={e => { + search(e.target.value); + setSelectedUserKey(''); + }} inputRef={inputElement} /> )} @@ -58,9 +97,11 @@ export default (props: { {Languages.t('components.user_picker.modal_no_result')}
)} - {_.reverse(result.slice(0, maxUserResultsShown)).map((user, i) => { + {shownResults.map((user, i) => { return ( -
0 ? ' border-t' : '')}> +
0 && i !== (selectedKeyIndex + 1) ? ' border-t' : ''))}>
@@ -72,6 +113,7 @@ export default (props: { onClick={() => { setUsers([user]); search(''); + setSelectedUserKey(''); }} size="sm" >