Replace store dropdown with checkbox toggle chips

Each store appears as a clickable chip with a checkmark. Click to
exclude a store from results (greys out with strikethrough). Click
again to re-include. Multiple stores can be toggled independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
mariosemes
2026-03-26 21:49:55 +01:00
parent a8d4a9ce3a
commit 4fb0d65710

View File

@@ -11,7 +11,7 @@
let sortBy = $state('price');
let sortAsc = $state(true);
let filterText = $state('');
let filterStore = $state('');
let excludedStores = $state(new Set());
onMount(async () => {
const params = $page.url.searchParams;
@@ -72,8 +72,8 @@
}
// Store filter
if (filterStore) {
items = items.filter(r => r.storeName === filterStore);
if (excludedStores.size > 0) {
items = items.filter(r => !excludedStores.has(r.storeName));
}
// Sort
@@ -102,6 +102,13 @@
catch { return `${currency} ${price.toFixed(2)}`; }
}
function toggleStore(name) {
const next = new Set(excludedStores);
if (next.has(name)) next.delete(name);
else next.add(name);
excludedStores = next;
}
function sortIcon(column) {
if (sortBy !== column) return '';
return sortAsc ? '\u2191' : '\u2193';
@@ -154,15 +161,32 @@
text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:outline-none transition-colors" />
</div>
<select bind:value={filterStore} class="input-field w-auto text-xs py-1 px-2">
<option value="">All stores</option>
<div class="flex items-center gap-1.5">
{#each storeNames() as name}
<option value={name}>{name}</option>
<button
onclick={() => toggleStore(name)}
class="flex items-center gap-1.5 text-2xs px-2 py-1 rounded border transition-colors duration-100
{excludedStores.has(name)
? 'bg-surface border-surface-border text-text-tertiary line-through opacity-50 hover:opacity-75'
: 'bg-accent-muted border-accent/30 text-accent-text hover:bg-accent/20'}"
>
<span class="w-3 h-3 rounded-sm border flex items-center justify-center flex-shrink-0
{excludedStores.has(name)
? 'border-text-tertiary/30'
: 'border-accent/50 bg-accent/20'}">
{#if !excludedStores.has(name)}
<svg class="w-2 h-2 text-accent-text" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
</svg>
{/if}
</span>
{name}
</button>
{/each}
</select>
</div>
<span class="text-2xs text-text-tertiary">
{filteredAndSorted().length} of {results.length} shown
<span class="text-2xs text-text-tertiary whitespace-nowrap">
{filteredAndSorted().length} of {results.length}
</span>
</div>
{/if}