fix: add arrows navigation for tag hint

This commit is contained in:
Antonella Sgarlatta
2021-06-03 20:46:44 -03:00
parent 622cca770f
commit a9f0c6fd2f
4 changed files with 63 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
import { AppState } from '@/ui_models/app_state';
import { observer } from 'mobx-react-lite';
import { useRef, useEffect } from 'preact/hooks';
import { Icon } from './Icon';
type Props = {
@@ -9,6 +10,10 @@ type Props = {
export const AutocompleteTagHint = observer(
({ appState, closeOnBlur }: Props) => {
const { autocompleteTagHintFocused } = appState.noteTags;
const hintRef = useRef<HTMLButtonElement>();
const { autocompleteSearchQuery, autocompleteTagResults } =
appState.noteTags;
@@ -16,16 +21,46 @@ export const AutocompleteTagHint = observer(
await appState.noteTags.createAndAddNewTag();
};
const onFocus = () => {
appState.noteTags.setAutocompleteTagHintFocused(true);
};
const onBlur = (event: FocusEvent) => {
closeOnBlur(event);
appState.noteTags.setAutocompleteTagHintFocused(false);
};
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === 'ArrowUp') {
if (autocompleteTagResults.length > 0) {
const lastTagResult =
autocompleteTagResults[autocompleteTagResults.length - 1];
appState.noteTags.setFocusedTagResultUuid(lastTagResult.uuid);
} else {
appState.noteTags.setAutocompleteInputFocused(true);
}
}
};
useEffect(() => {
if (autocompleteTagHintFocused) {
hintRef.current.focus();
}
}, [appState.noteTags, autocompleteTagHintFocused]);
return (
<>
{autocompleteTagResults.length > 0 && (
<div className="h-1px my-2 bg-border"></div>
)}
<button
ref={hintRef}
type="button"
className="sn-dropdown-item"
onClick={onTagHintClick}
onBlur={closeOnBlur}
onFocus={onFocus}
onBlur={onBlur}
onKeyDown={onKeyDown}
>
<span>Create new tag:</span>
<span className="bg-contrast rounded text-xs color-text py-1 pl-1 pr-2 flex items-center ml-2">

View File

@@ -61,6 +61,8 @@ export const AutocompleteTagInput = observer(({ appState }: Props) => {
event.preventDefault();
if (autocompleteTagResults.length > 0) {
appState.noteTags.setFocusedTagResultUuid(autocompleteTagResults[0].uuid);
} else if (autocompleteTagHintVisible) {
appState.noteTags.setAutocompleteTagHintFocused(true);
}
break;
default:

View File

@@ -12,7 +12,12 @@ type Props = {
export const AutocompleteTagResult = observer(
({ appState, tagResult, closeOnBlur }: Props) => {
const { autocompleteSearchQuery, autocompleteTagResults, focusedTagResultUuid } = appState.noteTags;
const {
autocompleteSearchQuery,
autocompleteTagHintVisible,
autocompleteTagResults,
focusedTagResultUuid,
} = appState.noteTags;
const tagResultRef = useRef<HTMLButtonElement>();
@@ -23,7 +28,10 @@ export const AutocompleteTagResult = observer(
};
const onKeyDown = (event: KeyboardEvent) => {
const tagResultIndex = appState.noteTags.getTagIndex(tagResult, autocompleteTagResults);
const tagResultIndex = appState.noteTags.getTagIndex(
tagResult,
autocompleteTagResults
);
switch (event.key) {
case 'ArrowUp':
event.preventDefault();
@@ -35,7 +43,14 @@ export const AutocompleteTagResult = observer(
break;
case 'ArrowDown':
event.preventDefault();
appState.noteTags.focusNextTagResult(tagResult);
if (
tagResultIndex === autocompleteTagResults.length - 1 &&
autocompleteTagHintVisible
) {
appState.noteTags.setAutocompleteTagHintFocused(true);
} else {
appState.noteTags.focusNextTagResult(tagResult);
}
break;
default:
return;

View File

@@ -6,6 +6,7 @@ import { AppState } from './app_state';
export class NoteTagsState {
autocompleteInputFocused = false;
autocompleteSearchQuery = '';
autocompleteTagHintFocused = false;
autocompleteTagResults: SNTag[] = [];
focusedTagResultUuid: UuidString | undefined = undefined;
focusedTagUuid: UuidString | undefined = undefined;
@@ -20,6 +21,7 @@ export class NoteTagsState {
makeObservable(this, {
autocompleteInputFocused: observable,
autocompleteSearchQuery: observable,
autocompleteTagHintFocused: observable,
autocompleteTagResults: observable,
focusedTagUuid: observable,
focusedTagResultUuid: observable,
@@ -33,6 +35,7 @@ export class NoteTagsState {
focusPreviousTag: action,
setAutocompleteInputFocused: action,
setAutocompleteSearchQuery: action,
setAutocompleteTagHintFocused: action,
setAutocompleteTagResults: action,
setFocusedTagResultUuid: action,
setFocusedTagUuid: action,
@@ -69,6 +72,10 @@ export class NoteTagsState {
this.autocompleteSearchQuery = query;
}
setAutocompleteTagHintFocused(focused: boolean): void {
this.autocompleteTagHintFocused = focused;
}
setAutocompleteTagResults(results: SNTag[]): void {
this.autocompleteTagResults = results;
}