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 TagAutocomplete from "./TagAutocomplete.svelte";
import ButtonToolbar from "components/ButtonToolbar.svelte";
import TagInput from "./TagInput.svelte";
import { attachId, getName } from "./tags";
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;
let tags = initialNames.map(attachId);
let newInput: HTMLInputElement;
let newName: string = "";
let tags = initialNames.map((name) => attachId(name));
function focusNewInput(): void {
newInput.focus();
function addEmptyTag(): void {
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);
if (contained >= 0) {
tags[contained].blink = true;
@ -36,20 +52,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
return false;
}
function checkIfContainsName(newName: string): boolean {
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 {
function addTagAt(index: number): void {
if (checkIfContainsNameAt(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;
await tick();
focusNewInput();
/* focusNewInput(); */
}
tags[index].active = false;
@ -121,40 +129,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
await tick();
(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>
<StickyBottom>
<div class="row-gap">
<ButtonToolbar class="dropup d-flex flex-wrap align-items-center" {size}>
<AddTagBadge on:click={focusNewInput} />
<AddTagBadge on:click={addEmptyTag} />
<TagAutocomplete
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
>
{#each tags as tag, index (tag.id)}
<Tag
bind:name={tag.name}
bind:active={tag.active}
bind:blink={tag.blink}
on:keydown={() => {}}
on:blur={() => {}}
on:tagupdate={() => checkForDuplicateNameAt(index)}
on:tagadd={() => insertTagAt(index)}
on:tagdelete={() => deleteTagAt(index)}
on:tagjoinprevious={() => joinWithPreviousTag(index)}
on:tagjoinnext={() => joinWithNextTag(index)}
on:tagmoveprevious={() => moveToPreviousTag(index)}
on:tagmovenext={() => moveToNextTag(index)}
/>
{#if index !== tags.length - 1}
<Tag
bind:name={tag.name}
bind:active={tag.active}
bind:blink={tag.blink}
on:tagupdate={() => addTagAt(index)}
on:tagadd={() => insertTagAt(index)}
on:tagdelete={() => deleteTagAt(index)}
on:tagjoinprevious={() => joinWithPreviousTag(index)}
on:tagjoinnext={() => joinWithNextTag(index)}
on:tagmoveprevious={() => moveToPreviousTag(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}
<TagInput
bind:input={newInput}
bind:name={newName}
on:keydown={updateAutocomplete}
on:blur={destroyAutocomplete}
on:tagupdate={appendTag}
on:tagadd={appendTag}
on:tagjoinprevious={joinWithLastTag}
on:tagmoveprevious={moveToLastTag}
on:tagmovenext={appendTag}
<div
class="tag-spacer flex-grow-1 align-self-stretch"
on:click={addEmptyTag}
/>
</TagAutocomplete>
</ButtonToolbar>
@ -199,4 +183,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
.row-gap > :global(.d-flex > *) {
margin-bottom: 2px;
}
.tag-spacer {
cursor: text;
}
</style>

View file

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

View file

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