Rename TagAutocomplete to WithAutocomplete

It's general enough to be used in other cases too
This commit is contained in:
Henrik Giesel 2021-06-28 17:40:04 +02:00
parent a9538ce6a7
commit ed1f19048d
2 changed files with 28 additions and 27 deletions

View file

@ -10,7 +10,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import AddTagBadge from "./AddTagBadge.svelte";
import Tag from "./Tag.svelte";
import TagInput from "./TagInput.svelte";
import TagAutocomplete from "./TagAutocomplete.svelte";
import WithAutocomplete from "./WithAutocomplete.svelte";
import ButtonToolbar from "components/ButtonToolbar.svelte";
import type { Tag as TagType } from "./tags";
import { attachId, getName } from "./tags";
@ -45,6 +45,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
}
function updateSuggestions(): void {}
function updateWithTagName(tag: TagType): void {
tag.name = activeName;
tags = tags;
@ -217,11 +219,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{#each tags as tag, index (tag.id)}
{#if index === active}
<TagAutocomplete
<WithAutocomplete
class="d-flex flex-column-reverse"
{suggestions}
search={tags[active ?? -1]?.name ?? ""}
on:autocomplete={onAutocomplete}
on:update={updateSuggestions}
let:updateAutocomplete
>
<TagInput
@ -248,7 +250,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
decideNextActive();
}}
/>
</TagAutocomplete>
</WithAutocomplete>
{:else}
<Tag
name={tag.name}

View file

@ -3,7 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import { createEventDispatcher, onDestroy } from "svelte";
import { createEventDispatcher, onDestroy, tick } from "svelte";
import type Dropdown from "bootstrap/js/dist/dropdown";
@ -15,11 +15,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export { className as class };
export let suggestions: string[];
export let search: string;
let autocomplete: Dropdown | undefined;
let displayed: string[] = [];
let selected: number | null = null;
// blue highlight
@ -29,12 +26,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const updateAutocomplete =
(createDropdown: (element: HTMLElement) => Dropdown) =>
(event: KeyboardEvent): Dropdown => {
async (event: KeyboardEvent): Promise<void> => {
const target = event.target as HTMLInputElement;
autocomplete = createDropdown(target);
autocomplete.show();
displayed = suggestions;
if (!autocomplete) {
autocomplete = createDropdown(target);
}
autocomplete.update();
if (
event.code === "ArrowDown" ||
@ -42,55 +41,55 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
) {
event.preventDefault();
if (selected === null) {
selected = displayed.length - 1;
selected = suggestions.length - 1;
} else if (selected === 0) {
selected = null;
} else {
selected--;
}
const choice = displayed[selected ?? -1];
const choice = suggestions[selected ?? -1];
dispatch("autocomplete", { choice });
} else if (event.code === "ArrowUp" || event.code === "Tab") {
event.preventDefault();
if (selected === null) {
selected = 0;
} else if (selected >= displayed.length - 1) {
} else if (selected >= suggestions.length - 1) {
selected = null;
} else {
selected++;
}
const choice = displayed[selected ?? -1];
const choice = suggestions[selected ?? -1];
dispatch("autocomplete", { choice });
} else if (event.code === "Enter") {
event.preventDefault();
active = true;
} else {
search = target.value;
dispatch("update");
}
return autocomplete;
await tick();
if (suggestions.length > 0) {
autocomplete.show();
} else {
autocomplete.hide();
}
};
onDestroy(() => {
if (!autocomplete) {
return;
}
autocomplete.hide();
});
onDestroy(() => autocomplete?.dispose());
</script>
<WithDropdownMenu let:menuId let:createDropdown>
<slot updateAutocomplete={updateAutocomplete(createDropdown)} />
<DropdownMenu id={menuId} class={className}>
{#each displayed as tag, i}
{#each suggestions as suggestion, i}
<div class="suggestion-item">
<DropdownItem
class={i === selected ? (active ? "active" : "focus") : ""}
on:click>{tag}</DropdownItem
on:click>{suggestion}</DropdownItem
>
</div>
{/each}