Delete when updating tagname to empty text

This commit is contained in:
Henrik Giesel 2021-06-25 00:49:17 +02:00
parent dbf1472029
commit d705d049ce
5 changed files with 66 additions and 46 deletions

View file

@ -28,6 +28,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:btn-night={nightMode} class:btn-night={nightMode}
title={tooltip} title={tooltip}
on:click on:click
on:focus
on:keydown
on:mousedown|preventDefault on:mousedown|preventDefault
> >
<slot /> <slot />
@ -43,7 +45,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
font-size: calc(var(--buttons-size) / 2.3); font-size: calc(var(--buttons-size) / 2.3);
background: none; background: none;
box-shadow: none; box-shadow: none !important;
border: none; border: none;
} }

View file

@ -21,12 +21,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
function deleteTag(event: Event): void { function deleteTag(event: Event): void {
dispatch("tagdelete", { name }); dispatch("tagdelete");
event.stopPropagation(); event.stopPropagation();
} }
function updateTag() { function updateTag(event: Event) {
active = false; active = false;
if (name.length === 0) {
deleteTag(event);
}
} }
</script> </script>
@ -41,7 +45,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
{:else} {:else}
<span <span
class="d-inline-flex align-items-center tag text-nowrap bg-secondary rounded ps-2 pe-1 me-1" class="d-inline-flex align-items-center tag text-nowrap bg-secondary rounded ps-2 pe-1 me-1"
on:click|stopPropagation={checkForActivation} on:click={checkForActivation}
> >
<span>{name}</span> <span>{name}</span>
<Badge class="delete-icon rounded ms-1 mt-1" on:click={deleteTag} <Badge class="delete-icon rounded ms-1 mt-1" on:click={deleteTag}

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, onDestroy } from "svelte"; import { createEventDispatcher } from "svelte";
import DropdownMenu from "components/DropdownMenu.svelte"; import DropdownMenu from "components/DropdownMenu.svelte";
import DropdownItem from "components/DropdownItem.svelte"; import DropdownItem from "components/DropdownItem.svelte";
@ -27,43 +27,60 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
event.preventDefault(); event.preventDefault();
} }
function onKeydown(event: KeyboardEvent) { function switchUpDown(event: KeyboardEvent): void {
const target = event.currentTarget as HTMLButtonElement;
console.log(
event.code,
target.nextElementSibling,
target.previousElementSibling
);
if (event.code === "ArrowUp") { if (event.code === "ArrowUp") {
activeItem = activeItem === tagValues.length - 1 ? 0 : ++activeItem; if (target.nextElementSibling) {
name = tagValues[activeItem]; (target.nextElementSibling as HTMLButtonElement).focus();
}
event.preventDefault(); event.preventDefault();
} else if (event.code === "ArrowDown") { } else if (event.code === "ArrowDown") {
activeItem = activeItem === 0 ? tagValues.length - 1 : --activeItem; if (target.previousElementSibling) {
name = tagValues[activeItem]; (target.previousElementSibling as HTMLButtonElement).focus();
}
event.preventDefault(); event.preventDefault();
} else if (event.code === "Enter") {
/* const dropdownActive = dropdown._element.classList.contains("show"); */
/* if (dropdownActive) { */
/* if (typeof activeItem === "number") { */
/* name = tagValues[activeItem]; */
/* activeItem = null; */
/* } */
/* dropdown.hide(); */
/* } else { */
/* dispatch("accept"); */
/* } */
} }
} }
function updateActiveItem(even: FocusEvent): void {}
/* else if (event.code === "Enter") { */
/* const dropdownActive = dropdown._element.classList.contains("show"); */
/* if (dropdownActive) { */
/* if (typeof activeItem === "number") { */
/* name = tagValues[activeItem]; */
/* activeItem = null; */
/* } */
/* dropdown.hide(); */
/* } else { */
/* dispatch("accept"); */
/* } */
/* } */
</script> </script>
<div bind:this={menu} class="dropup dropdown-reverse" on:keydown={onKeydown}> <div bind:this={menu} class="dropup dropdown-reverse">
<slot {triggerId} {triggerClass} {dropdown} /> <slot {triggerId} {triggerClass} {dropdown} />
<DropdownMenu labelledby={triggerId}> <DropdownMenu labelledby={triggerId}>
{#each suggestions as tag} {#each suggestions as tag}
<DropdownItem>{tag}</DropdownItem> <DropdownItem on:focus={updateActiveItem} on:keydown={switchUpDown}
>{tag}</DropdownItem
>
{/each} {/each}
</DropdownMenu> </DropdownMenu>
</div> </div>
<style lang="scss"> <style lang="scss">
/* .dropdown-reverse :global(.dropdown-menu) { */ .dropdown-reverse :global(.dropdown-menu.show) {
/* display: flex; */ display: flex;
/* flex-direction: column-reverse; */ flex-direction: column-reverse;
/* } */ font-size: 13px;
}
</style> </style>

View file

@ -8,7 +8,7 @@ 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 TagInput from "./TagInput.svelte"; import TagInput from "./TagInput.svelte";
export let tags = ["en::foobar", "zh::あっちこっち"]; export let tags = ["en::foobar", "zh::あっちこっち", "test", "def"];
let tagInputNew: HTMLInputElement; let tagInputNew: HTMLInputElement;
let newName: string = ""; let newName: string = "";
@ -17,12 +17,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tagInputNew.focus(); tagInputNew.focus();
} }
function deleteTag({ detail }: CustomEvent) { function deleteTag(index: number): void {
tags.splice(tags.indexOf(detail.name), 1); tags.splice(index, 1);
tags = tags; tags = tags;
} }
function addTag() { function addTag(): void {
if (!tags.includes(newName) && newName.length > 0) { if (!tags.includes(newName) && newName.length > 0) {
tags.push(newName); tags.push(newName);
} }
@ -35,11 +35,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<div class="d-flex flex-wrap"> <div class="d-flex flex-wrap">
<AddTagBadge on:click={focusInputNew} /> <AddTagBadge on:click={focusInputNew} />
{#each tags as tag} {#each tags as tag, index}
<Tag name={tag} on:tagdelete={deleteTag} /> <Tag bind:name={tag} on:tagdelete={() => deleteTag(index)} />
{/each} {/each}
<TagInput bind:input={tagInputNew} name={newName} on:tagupdate={addTag} /> <TagInput bind:input={tagInputNew} bind:name={newName} on:tagupdate={addTag} />
</div> </div>
</StickyBottom> </StickyBottom>

View file

@ -3,8 +3,6 @@ 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 type Dropdown from "bootstrap/js/dist/dropdown";
import { createEventDispatcher, onMount } from "svelte"; import { createEventDispatcher, onMount } from "svelte";
import { normalizeTagname } from "./tags"; import { normalizeTagname } from "./tags";
@ -15,21 +13,21 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
function onFocus(event: FocusEvent, dropdown: Dropdown): void { function onFocus(): void {
/* dropdown.show(); */ /* dropdown.show(); */
} }
function onAccept(event: Event): void { function onAccept(): void {
name = normalizeTagname(name); name = normalizeTagname(name);
dispatch("tagupdate", { name }); dispatch("tagupdate", { name });
} }
function dropdownBlur(event: Event, dropdown: Dropdown): void { function dropdownBlur(): void {
onAccept(event); onAccept();
/* dropdown.hide(); */ /* dropdown.hide(); */
} }
function onKeydown(event: KeyboardEvent, dropdown: Dropdown): void { function onKeydown(event: KeyboardEvent): void {
if (event.code === "Space") { if (event.code === "Space") {
name += "::"; name += "::";
event.preventDefault(); event.preventDefault();
@ -37,7 +35,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
name = name.slice(0, -2); name = name.slice(0, -2);
event.preventDefault(); event.preventDefault();
} else if (event.code === "Enter") { } else if (event.code === "Enter") {
onAccept(event); onAccept();
event.preventDefault(); event.preventDefault();
} }
} }
@ -66,7 +64,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
bind:name bind:name
let:triggerId let:triggerId
let:triggerClass let:triggerClass
let:dropdown
on:nameChosen={setTagname} on:nameChosen={setTagname}
on:accept={onAccept} on:accept={onAccept}
> >
@ -84,10 +81,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
tabindex="-1" tabindex="-1"
size="1" size="1"
bind:value={name} bind:value={name}
on:focus={(event) => onFocus(event, dropdown)} on:focus={onFocus}
on:blur={(event) => dropdownBlur(event, dropdown)} on:blur={dropdownBlur}
on:focusout on:focusout
on:keydown={(event) => onKeydown(event, dropdown)} on:keydown={onKeydown}
on:paste={onPaste} on:paste={onPaste}
on:click on:click
/> />