Tag suggestions

This commit is contained in:
Dallas Hoffman 2023-09-28 00:55:41 -04:00
parent 5f256aba19
commit 162615f789
3 changed files with 43 additions and 6 deletions

View File

@ -40,7 +40,7 @@
<NoteTagButton on:click={focusTags} /> <NoteTagButton on:click={focusTags} />
</div> </div>
<div hidden={!showTags && $noteTags.length === 0}> <div hidden={!showTags && $noteTags.length === 0}>
<NoteTags {noteTags} bind:this={tagsComponent} /> <NoteTags {note} {noteTags} bind:this={tagsComponent} />
</div> </div>
</header> </header>
<div class="note-card__body" class:note-card__body--editing={$editing}> <div class="note-card__body" class:note-card__body--editing={$editing}>

View File

@ -1,9 +1,11 @@
<script lang="ts"> <script lang="ts">
import FaXmark from '$icon/fa-xmark.svelte'; import FaXmark from '$icon/fa-xmark.svelte';
import type { NoteTagsStore } from '$lib/stores/note-tags'; import type { NoteTagsStore } from '$lib/stores/note-tags';
import type { Note } from '$lib/stores/notes';
import type { Tag } from '$lib/stores/tags'; import type { Tag } from '$lib/stores/tags';
import Button from '../button.svelte'; import Button from '../button.svelte';
export let note: Note;
export let noteTags: NoteTagsStore; export let noteTags: NoteTagsStore;
export function focusTextbox() { export function focusTextbox() {
@ -12,12 +14,20 @@
let textbox: HTMLInputElement; let textbox: HTMLInputElement;
let newTagLabel: string = ''; let newTagLabel: string = '';
let suggestions: string[] = [];
function addTag(event: KeyboardEvent) { async function onKeyup(event: KeyboardEvent) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
addTag();
} else {
suggestions = await noteTags.search(newTagLabel);
}
}
function addTag() {
noteTags.add({ label: newTagLabel }); noteTags.add({ label: newTagLabel });
newTagLabel = ''; newTagLabel = '';
} suggestions = [];
} }
function removeTag(tagId: Tag['id']) { function removeTag(tagId: Tag['id']) {
@ -49,9 +59,15 @@
bind:this={textbox} bind:this={textbox}
name="newTag" name="newTag"
aria-label="New tag" aria-label="New tag"
list={`note-tag--${note.id}`}
bind:value={newTagLabel} bind:value={newTagLabel}
on:keypress={addTag} on:keyup={onKeyup}
/> />
<datalist id={`note-tag--${note.id}`}>
{#each suggestions as suggestion}
<option value={suggestion} />
{/each}
</datalist>
</div> </div>
</div> </div>
@ -115,6 +131,10 @@
&:focus { &:focus {
border: 1px solid hsl(0 0% 0% / 0.4); border: 1px solid hsl(0 0% 0% / 0.4);
} }
&::-webkit-calendar-picker-indicator {
display: none !important;
}
} }
} }
} }

View File

@ -1,4 +1,4 @@
import { writable, type Readable } from 'svelte/store'; import { writable, type Readable, get } from 'svelte/store';
import type { Note, NotesStore } from './notes'; import type { Note, NotesStore } from './notes';
import { db } from '$lib/db/client'; import { db } from '$lib/db/client';
import type { Tag, NewTag, TagsStore } from './tags'; import type { Tag, NewTag, TagsStore } from './tags';
@ -77,4 +77,21 @@ export class NoteTagsStore implements Readable<Tag[]> {
this.notes.refreshNotes(); this.notes.refreshNotes();
this.tags.refreshTags(); this.tags.refreshTags();
}; };
search = async (searchString: string): Promise<string[]> => {
if (!searchString) {
return [];
}
const currentTags = get(this.noteTags).map((tag) => tag.label);
const results = await db
.selectFrom('tag')
.select('label')
.where('label', 'like', `%${searchString}%`)
.where('label', 'not in', [...currentTags, searchString])
.limit(10)
.execute();
return results.map((result) => result.label);
};
} }