diff --git a/ts/components/DropdownItem.svelte b/ts/components/DropdownItem.svelte index 85cd8d130..ddb603353 100644 --- a/ts/components/DropdownItem.svelte +++ b/ts/components/DropdownItem.svelte @@ -30,6 +30,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html class:btn-night={nightMode} title={tooltip} on:click + on:mouseenter on:focus on:keydown on:mousedown|preventDefault diff --git a/ts/editor/TagAutocomplete.svelte b/ts/editor/TagAutocomplete.svelte index ae5565de8..8f0f48979 100644 --- a/ts/editor/TagAutocomplete.svelte +++ b/ts/editor/TagAutocomplete.svelte @@ -15,7 +15,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html export { className as class }; let autocomplete: Dropdown | undefined; + let original: string | undefined; + let displayed: string[] = []; + let selected: number | null = null; + let active: boolean = false; + + function select(index: number) { + selected = index; + } + + function choose() {} function switchUpDown(event: KeyboardEvent): void { const target = event.currentTarget as HTMLButtonElement; @@ -37,10 +47,40 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html const updateAutocomplete = (createDropdown: (element: HTMLElement) => Dropdown) => (event: KeyboardEvent): Dropdown => { - const target = event.target as HTMLElement; + const target = event.target as HTMLInputElement; autocomplete = createDropdown(target); autocomplete.show(); + displayed = suggestions; + + if ( + event.code === "ArrowDown" || + (event.code === "Tab" && event.shiftKey) + ) { + event.preventDefault(); + if (selected === null) { + selected = displayed.length - 1; + } else if (selected === 0) { + selected = null; + } else { + selected--; + } + } else if (event.code === "ArrowUp" || event.code === "Tab") { + event.preventDefault(); + if (selected === null) { + selected = 0; + } else if (selected >= displayed.length - 1) { + selected = null; + } else { + selected++; + } + } else if (event.code === "Enter") { + event.preventDefault(); + active = true; + } else { + original = target.value; + } + return autocomplete; }; @@ -50,6 +90,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html } autocomplete.hide(); + selected = null; + active = false; } @@ -57,11 +99,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html - {#each suggestions as tag} - {tag} + {#each displayed as tag, i} + select(i)} + on:click>{tag} {/each} diff --git a/ts/editor/TagEditor.svelte b/ts/editor/TagEditor.svelte index 911585f3d..1e0bfc515 100644 --- a/ts/editor/TagEditor.svelte +++ b/ts/editor/TagEditor.svelte @@ -156,8 +156,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html {}} - on:blur={() => {}} + on:keydown={updateAutocomplete} + on:blur={destroyAutocomplete} on:tagupdate={appendTag} on:tagadd={appendTag} on:tagjoinprevious={joinWithLastTag}