jellytau/src/lib/components/Search.svelte

62 lines
1.7 KiB
Svelte

<script lang="ts">
interface Props {
value?: string;
placeholder?: string;
onSearch?: (query: string) => void;
}
let { value = $bindable(""), placeholder = "Search...", onSearch }: Props = $props();
let debounceTimer: ReturnType<typeof setTimeout>;
function handleInput(e: Event) {
const target = e.target as HTMLInputElement;
value = target.value;
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
onSearch?.(value);
}, 300);
}
function handleClear() {
value = "";
onSearch?.("");
}
function handleSubmit(e: Event) {
e.preventDefault();
clearTimeout(debounceTimer);
onSearch?.(value);
}
</script>
<form onsubmit={handleSubmit} class="relative">
<div class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
</div>
<input
type="text"
{value}
{placeholder}
oninput={handleInput}
class="w-full pl-10 pr-10 py-2 bg-[var(--color-surface)] border border-gray-700 rounded-lg focus:outline-none focus:border-[var(--color-jellyfin)] text-white placeholder-gray-500"
/>
{#if value}
<button
type="button"
onclick={handleClear}
class="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white"
aria-label="Clear search"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
{/if}
</form>