Prefer focusing TagInput in onMount

This commit is contained in:
Henrik Giesel 2021-06-26 20:47:52 +02:00
parent 52a705e839
commit 2cdc0b308a
3 changed files with 36 additions and 34 deletions

View file

@ -16,9 +16,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let initialNames = ["en::foobar", "test", "def"]; export let initialNames = ["en::foobar", "test", "def"];
export let suggestions = ["en::idioms", "anki::functionality", "math"]; export let suggestions = ["en::idioms", "anki::functionality", "math"];
export let active: number | null = null;
export let input: HTMLInputElement;
export let size = isApplePlatform() ? 1.6 : 2.0; export let size = isApplePlatform() ? 1.6 : 2.0;
let tags = initialNames.map((name) => attachId(name)); let tags = initialNames.map(attachId);
function isFirst(index: number): boolean { function isFirst(index: number): boolean {
return index === 0; return index === 0;
@ -30,32 +33,26 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
async function addEmptyTag(): Promise<void> { async function addEmptyTag(): Promise<void> {
const lastTag = tags[tags.length - 1]; const lastTag = tags[tags.length - 1];
if (lastTag.name.length === 0) { if (lastTag.name.length === 0) {
lastTag.active = true;
return; return;
} }
const idx = tags.push(attachId("", true)); const index = tags.push(attachId("")) - 1;
tags = tags; tags = tags;
activate(index);
await tick();
tags[idx - 1].input?.focus();
} }
async function insertEmptyTagAt(index: number): Promise<void> { async function insertEmptyTagAt(index: number): Promise<void> {
tags.splice(index, 0, attachId("", true)); tags.splice(index, 0, attachId(""));
tags = tags; tags = tags;
active = index;
await tick();
tags[index].input?.focus();
} }
async function appendEmptyTagAt(index: number): Promise<void> { async function appendEmptyTagAt(index: number): Promise<void> {
tags.splice(index + 1, 0, attachId("", true)); tags.splice(index + 1, 0, attachId(""));
tags = tags; tags = tags;
activate(index + 1);
await tick();
tags[index].input?.focus();
} }
function checkIfContainsNameAt(index: number): boolean { function checkIfContainsNameAt(index: number): boolean {
@ -72,11 +69,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
function addTagAt(index: number): void { function addTagAt(index: number): void {
console.log("eyo");
if (checkIfContainsNameAt(index)) { if (checkIfContainsNameAt(index)) {
deleteTagAt(index); deleteTagAt(index);
insertEmptyTagAt(index); insertEmptyTagAt(index);
} else { } else {
deactivate(index);
appendEmptyTagAt(index); appendEmptyTagAt(index);
} }
} }
@ -121,9 +118,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return; return;
} }
const previousTag = tags[index - 1]; active = index - 1;
previousTag.active = true;
tags = tags;
} }
async function moveToNextTag(index: number): Promise<void> { async function moveToNextTag(index: number): Promise<void> {
@ -132,21 +127,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return; return;
} }
const nextTag = tags[index + 1]; active = index + 1;
nextTag.active = true;
tags = tags;
await tick(); await tick();
nextTag.input?.setSelectionRange(0, 0); input.setSelectionRange(0, 0);
} }
function deactivate(index: number): void { function deactivate(index: number): void {
tags[index].active = false; active = null;
} }
function checkForActivation(index: number): void { async function activate(index: number): Promise<void> {
active = index;
}
async function checkForActivation(index: number): Promise<void> {
const selection = window.getSelection()!; const selection = window.getSelection()!;
tags[index].active = selection.isCollapsed; if (selection.isCollapsed) {
await activate(index);
}
} }
</script> </script>
@ -162,10 +161,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
let:destroyAutocomplete let:destroyAutocomplete
> >
{#each tags as tag, index (tag.id)} {#each tags as tag, index (tag.id)}
{#if tag.active} {#if index === active}
<TagInput <TagInput
bind:name={tag.name} bind:name={tag.name}
bind:input={tag.input} bind:input
on:blur={() => deactivate(index)} on:blur={() => deactivate(index)}
on:tagupdate={() => addTagAt(index)} on:tagupdate={() => addTagAt(index)}
on:tagadd={() => insertTagAt(index)} on:tagadd={() => insertTagAt(index)}
@ -177,7 +176,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
/> />
{:else} {:else}
<Tag <Tag
bind:name={tag.name} name={tag.name}
bind:blink={tag.blink} bind:blink={tag.blink}
on:click={() => checkForActivation(index)} on:click={() => checkForActivation(index)}
on:tagdelete={() => deleteTagAt(index)} on:tagdelete={() => deleteTagAt(index)}
@ -190,6 +189,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
on:click={addEmptyTag} on:click={addEmptyTag}
/> />
</TagAutocomplete> </TagAutocomplete>
<div>{JSON.stringify(tags)}</div>
</ButtonToolbar> </ButtonToolbar>
</div> </div>
</StickyBottom> </StickyBottom>

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 License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="typescript"> <script lang="typescript">
import { createEventDispatcher, onMount, tick } from "svelte"; import { onMount, createEventDispatcher, tick } from "svelte";
import { normalizeTagname } from "./tags"; import { normalizeTagname } from "./tags";
export let name: string; export let name: string;
@ -145,6 +145,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
name = last; name = last;
} }
} }
onMount(() => {
console.log("focus", input);
input.focus();
});
</script> </script>
<label class="ps-2 pe-1" data-value={name}> <label class="ps-2 pe-1" data-value={name}>

View file

@ -18,17 +18,13 @@ export function normalizeTagname(tagname: string): string {
interface Tag { interface Tag {
id: string; id: string;
name: string; name: string;
input: HTMLInputElement;
active: boolean;
blink: boolean; blink: boolean;
} }
export function attachId(name: string, active = false): Tag { export function attachId(name: string): Tag {
return { return {
id: Math.random().toString(36).substring(2), id: Math.random().toString(36).substring(2),
name, name,
input: null as unknown as HTMLInputElement,
active,
blink: false, blink: false,
}; };
} }