Try to remove special handling of last tag / inputNew

This commit is contained in:
Henrik Giesel 2021-06-26 16:15:56 +02:00
parent 15ef6d51b3
commit e80e6ff34b
3 changed files with 63 additions and 81 deletions

View file

@ -10,7 +10,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import Tag from "./Tag.svelte"; import Tag from "./Tag.svelte";
import TagAutocomplete from "./TagAutocomplete.svelte"; import TagAutocomplete from "./TagAutocomplete.svelte";
import ButtonToolbar from "components/ButtonToolbar.svelte"; import ButtonToolbar from "components/ButtonToolbar.svelte";
import TagInput from "./TagInput.svelte";
import { attachId, getName } from "./tags"; import { attachId, getName } from "./tags";
export let initialNames = ["en::foobar", "test", "def"]; export let initialNames = ["en::foobar", "test", "def"];
@ -18,15 +17,32 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let size = isApplePlatform() ? 1.6 : 2.0; export let size = isApplePlatform() ? 1.6 : 2.0;
let tags = initialNames.map(attachId); let tags = initialNames.map((name) => attachId(name));
let newInput: HTMLInputElement;
let newName: string = "";
function focusNewInput(): void { function addEmptyTag(): void {
newInput.focus(); if (tags[tags.length - 1].name.length === 0) {
tags[tags.length - 1].active = true;
return;
}
tags.push(attachId("", true));
tags = tags;
} }
function checkIfContains(newName: string, names: string[]): boolean { function insertEmptyTagAt(index: number): void {
tags.splice(index, 0, attachId("", true));
tags = tags;
}
function appendEmptyTagAt(index: number): void {
tags.splice(index + 1, 0, attachId("", true));
tags = tags;
}
function checkIfContainsNameAt(index: number): boolean {
const names = tags.map(getName);
const newName = names.splice(index, 1, "")[0];
const contained = names.indexOf(newName); const contained = names.indexOf(newName);
if (contained >= 0) { if (contained >= 0) {
tags[contained].blink = true; tags[contained].blink = true;
@ -36,20 +52,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return false; return false;
} }
function checkIfContainsName(newName: string): boolean { function addTagAt(index: number): void {
const names = tags.map(getName);
return checkIfContains(newName, names);
}
function checkIfContainsNameAt(index: number): boolean {
const names = tags.map(getName);
const newName = names.splice(index, 1, "")[0];
return checkIfContains(newName, names);
}
function checkForDuplicateNameAt(index: number): void {
if (checkIfContainsNameAt(index)) { if (checkIfContainsNameAt(index)) {
deleteTagAt(index); deleteTagAt(index);
insertEmptyTagAt(index);
} else {
appendEmptyTagAt(index);
} }
} }
@ -111,7 +119,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tags = tags; tags = tags;
await tick(); await tick();
focusNewInput(); /* focusNewInput(); */
} }
tags[index].active = false; tags[index].active = false;
@ -121,40 +129,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
await tick(); await tick();
(document.activeElement as HTMLInputElement).setSelectionRange(0, 0); (document.activeElement as HTMLInputElement).setSelectionRange(0, 0);
} }
function appendTag(): boolean {
let added = false;
if (!checkIfContainsName(newName)) {
tags.push(attachId(newName));
added = true;
}
tags = tags;
newName = "";
return added;
}
function joinWithLastTag(): void {
const popped = tags.pop();
tags = tags;
if (popped) {
newName = popped.name + newName;
}
}
async function moveToLastTag(): Promise<void> {
const newTag = appendTag() ? tags[tags.length - 2] : tags[tags.length - 1];
newTag.active = true;
}
</script> </script>
<StickyBottom> <StickyBottom>
<div class="row-gap"> <div class="row-gap">
<ButtonToolbar class="dropup d-flex flex-wrap align-items-center" {size}> <ButtonToolbar class="dropup d-flex flex-wrap align-items-center" {size}>
<AddTagBadge on:click={focusNewInput} /> <AddTagBadge on:click={addEmptyTag} />
<TagAutocomplete <TagAutocomplete
class="d-flex flex-column-reverse" class="d-flex flex-column-reverse"
@ -163,32 +143,36 @@ 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)}
<Tag {#if index !== tags.length - 1}
bind:name={tag.name} <Tag
bind:active={tag.active} bind:name={tag.name}
bind:blink={tag.blink} bind:active={tag.active}
on:keydown={() => {}} bind:blink={tag.blink}
on:blur={() => {}} on:tagupdate={() => addTagAt(index)}
on:tagupdate={() => checkForDuplicateNameAt(index)} on:tagadd={() => insertTagAt(index)}
on:tagadd={() => insertTagAt(index)} on:tagdelete={() => deleteTagAt(index)}
on:tagdelete={() => deleteTagAt(index)} on:tagjoinprevious={() => joinWithPreviousTag(index)}
on:tagjoinprevious={() => joinWithPreviousTag(index)} on:tagjoinnext={() => joinWithNextTag(index)}
on:tagjoinnext={() => joinWithNextTag(index)} on:tagmoveprevious={() => moveToPreviousTag(index)}
on:tagmoveprevious={() => moveToPreviousTag(index)} on:tagmovenext={() => moveToNextTag(index)}
on:tagmovenext={() => moveToNextTag(index)} />
/> {:else}
<Tag
bind:name={tag.name}
bind:active={tag.active}
bind:blink={tag.blink}
on:tagupdate={() => addTagAt(index)}
on:tagadd={() => insertTagAt(index)}
on:tagjoinprevious={() => joinWithPreviousTag(index)}
on:tagmoveprevious={() => moveToPreviousTag(index)}
on:tagmovenext={() => moveToNextTag(index)}
/>
{/if}
{/each} {/each}
<TagInput <div
bind:input={newInput} class="tag-spacer flex-grow-1 align-self-stretch"
bind:name={newName} on:click={addEmptyTag}
on:keydown={updateAutocomplete}
on:blur={destroyAutocomplete}
on:tagupdate={appendTag}
on:tagadd={appendTag}
on:tagjoinprevious={joinWithLastTag}
on:tagmoveprevious={moveToLastTag}
on:tagmovenext={appendTag}
/> />
</TagAutocomplete> </TagAutocomplete>
</ButtonToolbar> </ButtonToolbar>
@ -199,4 +183,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.row-gap > :global(.d-flex > *) { .row-gap > :global(.d-flex > *) {
margin-bottom: 2px; margin-bottom: 2px;
} }
.tag-spacer {
cursor: text;
}
</style> </style>

View file

@ -171,12 +171,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
display: inline-grid; display: inline-grid;
height: 100%; height: 100%;
cursor: text;
&:focus-within {
cursor: default;
}
&::after, &::after,
input { input {
color: var(--text-fg); color: var(--text-fg);

View file

@ -22,10 +22,10 @@ interface Tag {
id: string; id: string;
} }
export function attachId(name: string): Tag { export function attachId(name: string, active = false): Tag {
return { return {
name, name,
active: false, active,
blink: false, blink: false,
id: Math.random().toString(36).substring(2), id: Math.random().toString(36).substring(2),
}; };