From 3e76ef6b6f3fa0bc0174dc83d3a1e8baed69bbd8 Mon Sep 17 00:00:00 2001 From: Antonella Sgarlatta Date: Thu, 1 Jul 2021 14:36:21 -0300 Subject: [PATCH 1/2] fix: fix tags keyboard navigation --- .../components/AutocompleteTagHint.tsx | 1 + .../components/AutocompleteTagInput.tsx | 2 +- .../components/AutocompleteTagResult.tsx | 1 + app/assets/javascripts/components/NoteTag.tsx | 15 +++++++++++++-- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/components/AutocompleteTagHint.tsx b/app/assets/javascripts/components/AutocompleteTagHint.tsx index 00cc04af7..bbb1ec928 100644 --- a/app/assets/javascripts/components/AutocompleteTagHint.tsx +++ b/app/assets/javascripts/components/AutocompleteTagHint.tsx @@ -62,6 +62,7 @@ export const AutocompleteTagHint = observer( onFocus={onFocus} onBlur={onBlur} onKeyDown={onKeyDown} + tabIndex={-1} > Create new tag: diff --git a/app/assets/javascripts/components/AutocompleteTagInput.tsx b/app/assets/javascripts/components/AutocompleteTagInput.tsx index 2dddf3077..e3771024d 100644 --- a/app/assets/javascripts/components/AutocompleteTagInput.tsx +++ b/app/assets/javascripts/components/AutocompleteTagInput.tsx @@ -92,7 +92,6 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => { useEffect(() => { if (autocompleteInputFocused) { inputRef.current.focus(); - appState.noteTags.setAutocompleteInputFocused(false); } }, [appState.noteTags, autocompleteInputFocused]); @@ -113,6 +112,7 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => { onBlur={onBlur} onFocus={onFocus} onKeyDown={onKeyDown} + tabIndex={tags.length === 0 ? 0 : -1} /> {dropdownVisible && (autocompleteTagResults.length > 0 || autocompleteTagHintVisible) && ( diff --git a/app/assets/javascripts/components/NoteTag.tsx b/app/assets/javascripts/components/NoteTag.tsx index f08c94ef8..ba80ebe48 100644 --- a/app/assets/javascripts/components/NoteTag.tsx +++ b/app/assets/javascripts/components/NoteTag.tsx @@ -10,7 +10,7 @@ type Props = { }; export const NoteTag = observer(({ appState, tag }: Props) => { - const { focusedTagUuid, tags } = appState.noteTags; + const { autocompleteInputFocused, focusedTagUuid, tags } = appState.noteTags; const [showDeleteButton, setShowDeleteButton] = useState(false); const [tagClicked, setTagClicked] = useState(false); @@ -51,6 +51,16 @@ export const NoteTag = observer(({ appState, tag }: Props) => { } }; + const getTabIndex = () => { + if (focusedTagUuid) { + return focusedTagUuid === tag.uuid ? 0 : -1; + } + if (autocompleteInputFocused) { + return -1; + } + return tags[0].uuid === tag.uuid ? 0 : -1; + }; + const onKeyDown = (event: KeyboardEvent) => { const tagIndex = appState.noteTags.getTagIndex(tag, tags); switch (event.key) { @@ -75,7 +85,6 @@ export const NoteTag = observer(({ appState, tag }: Props) => { useEffect(() => { if (focusedTagUuid === tag.uuid) { tagRef.current.focus(); - appState.noteTags.setFocusedTagUuid(undefined); } }, [appState.noteTags, focusedTagUuid, tag]); @@ -87,6 +96,7 @@ export const NoteTag = observer(({ appState, tag }: Props) => { onKeyDown={onKeyDown} onFocus={onFocus} onBlur={onBlur} + tabIndex={getTabIndex()} > @@ -99,6 +109,7 @@ export const NoteTag = observer(({ appState, tag }: Props) => { className="ml-2 -mr-1 border-0 p-0 bg-transparent cursor-pointer flex" onBlur={onBlur} onClick={onDeleteTagClick} + tabIndex={-1} > Date: Thu, 1 Jul 2021 14:36:56 -0300 Subject: [PATCH 2/2] fix: don't clear search query when navigating back to input --- .../components/AutocompleteTagInput.tsx | 104 ++++++++++-------- 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/app/assets/javascripts/components/AutocompleteTagInput.tsx b/app/assets/javascripts/components/AutocompleteTagInput.tsx index e3771024d..80c865f39 100644 --- a/app/assets/javascripts/components/AutocompleteTagInput.tsx +++ b/app/assets/javascripts/components/AutocompleteTagInput.tsx @@ -25,10 +25,10 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => { const [dropdownMaxHeight, setDropdownMaxHeight] = useState('auto'); - const dropdownRef = useRef(); + const containerRef = useRef(); const inputRef = useRef(); - const [closeOnBlur] = useCloseOnBlur(dropdownRef, (visible: boolean) => { + const [closeOnBlur] = useCloseOnBlur(containerRef, (visible: boolean) => { setDropdownVisible(visible); appState.noteTags.clearAutocompleteSearch(); }); @@ -69,7 +69,9 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => { case 'ArrowDown': event.preventDefault(); if (autocompleteTagResults.length > 0) { - appState.noteTags.setFocusedTagResultUuid(autocompleteTagResults[0].uuid); + appState.noteTags.setFocusedTagResultUuid( + autocompleteTagResults[0].uuid + ); } else if (autocompleteTagHintVisible) { appState.noteTags.setAutocompleteTagHintFocused(true); } @@ -96,50 +98,60 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => { }, [appState.noteTags, autocompleteInputFocused]); return ( -
0 ? 'mt-2' : ''}`} - > - - 0 ? 'w-80' : 'w-70 mr-10'} bg-transparent text-xs +
+ 0 ? 'mt-2' : ''}`} + > + + 0 ? 'w-80' : 'w-70 mr-10' + } bg-transparent text-xs color-text no-border h-7 focus:outline-none focus:shadow-none focus:border-bottom`} - value={autocompleteSearchQuery} - onChange={onSearchQueryChange} - type="text" - placeholder="Add tag" - onBlur={onBlur} - onFocus={onFocus} - onKeyDown={onKeyDown} - tabIndex={tags.length === 0 ? 0 : -1} - /> - {dropdownVisible && (autocompleteTagResults.length > 0 || autocompleteTagHintVisible) && ( - 0 ? 'w-80' : 'w-70 mr-10'} sn-dropdown flex flex-col py-2 absolute`} - style={{ maxHeight: dropdownMaxHeight, maxWidth: tagsContainerMaxWidth }} - onBlur={closeOnBlur} - > -
- {autocompleteTagResults.map((tagResult: SNTag) => ( - - ))} -
- {autocompleteTagHintVisible && ( - + value={autocompleteSearchQuery} + onChange={onSearchQueryChange} + type="text" + placeholder="Add tag" + onBlur={onBlur} + onFocus={onFocus} + onKeyDown={onKeyDown} + tabIndex={tags.length === 0 ? 0 : -1} + /> + {dropdownVisible && + (autocompleteTagResults.length > 0 || + autocompleteTagHintVisible) && ( + 0 ? 'w-80' : 'w-70 mr-10' + } sn-dropdown flex flex-col py-2 absolute`} + style={{ + maxHeight: dropdownMaxHeight, + maxWidth: tagsContainerMaxWidth, + }} + onBlur={closeOnBlur} + > +
+ {autocompleteTagResults.map((tagResult: SNTag) => ( + + ))} +
+ {autocompleteTagHintVisible && ( + + )} +
)} -
- )} -
- + + +
); });