1
0
mirror of https://github.com/koloml/furbooru-tagging-assistant.git synced 2025-12-24 07:12:57 +00:00

Tags Editor: Removed Web Component with a component made with Svelte

Additionally, this editor works a little bit better when used with
keyboard. It supports tabbing between "remove" buttons inside the tags
and pressing them with Space/Enter.

Web Component was an idea to keep the editor the same between frontend
and Svelte app, but as I figured out later, extensions can't use those.
Unfortunate.
This commit is contained in:
2024-06-27 00:43:29 +04:00
parent 15d318ec90
commit e6e537ea0c
2 changed files with 81 additions and 192 deletions

View File

@@ -1,21 +1,94 @@
<script>
import "$lib/web-components/TagEditorComponent.js";
/**
* List of tags to edit. Any duplicated tags present in the array will be removed on the first edit.
* @type {string[]}
*/
export let tags = [];
let tagsAttribute = tags.join(',');
/** @type {Set<string>} */
let uniqueTags = new Set();
$: uniqueTags = new Set(tags);
/** @type {string} */
let addedTagName = '';
/**
* @param {CustomEvent<string[]>} event
* Create a callback function to pass into both mouse & keyboard events for tag removal.
* @param {string} tagName
* @return {function(Event)} Callback to pass as event listener.
*/
function onTagsChanged(event) {
tags = event.detail;
function createTagRemoveHandler(tagName) {
return event => {
if (event.type === 'click') {
removeTag(tagName);
}
if (event instanceof KeyboardEvent && (event.code === 'Enter' || event.code === 'Space')) {
// To be more comfortable, automatically focus next available tag's remove button in the list.
if (event.currentTarget instanceof HTMLElement) {
const currenTagElement = event.currentTarget.closest('.tag');
const nextTagElement = currenTagElement?.previousElementSibling ?? currenTagElement?.parentElement?.firstElementChild;
const nextRemoveButton = nextTagElement?.querySelector('.remove');
if (nextRemoveButton instanceof HTMLElement) {
nextRemoveButton.focus();
}
}
removeTag(tagName);
}
}
}
$: tagsAttribute = tags.join(',');
/**
* @param {string} tagName
*/
function removeTag(tagName) {
uniqueTags.delete(tagName);
tags = Array.from(uniqueTags);
}
/**
* @param {string} tagName
*/
function addTag(tagName) {
uniqueTags.add(tagName);
tags = Array.from(uniqueTags);
}
/**
* Handle adding new tags to the list or removing them when backspace is pressed.
* @param {KeyboardEvent} event
*/
function handleKeyPresses(event) {
if (event.code === 'Enter' && addedTagName.length) {
addTag(addedTagName)
addedTagName = '';
}
if (event.code === 'Backspace' && !addedTagName.length && tags?.length) {
removeTag(tags[tags.length - 1]);
}
}
</script>
<tags-editor tags="{tagsAttribute}" on:change={onTagsChanged}></tags-editor>
<div class="tags-editor">
{#each uniqueTags.values() as tagName}
<div class="tag">
{tagName}
<span class="remove" on:click={createTagRemoveHandler(tagName)}
on:keydown={createTagRemoveHandler(tagName)}
role="button" tabindex="0">x</span>
</div>
{/each}
<input type="text" bind:value={addedTagName} on:keydown={handleKeyPresses}/>
</div>
<style lang="scss">
.tags-editor {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
</style>