fix: add arrows navigation for tag hint
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user