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 sortBy = $state('price');
let sortAsc = $state(true); let sortAsc = $state(true);
let filterText = $state(''); let filterText = $state('');
let filterStore = $state(''); let excludedStores = $state(new Set());
onMount(async () => { onMount(async () => {
const params = $page.url.searchParams; const params = $page.url.searchParams;
@@ -72,8 +72,8 @@
} }
// Store filter // Store filter
if (filterStore) { if (excludedStores.size > 0) {
items = items.filter(r => r.storeName === filterStore); items = items.filter(r => !excludedStores.has(r.storeName));
} }
// Sort // Sort
@@ -102,6 +102,13 @@
catch { return `${currency} ${price.toFixed(2)}`; } 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) { function sortIcon(column) {
if (sortBy !== column) return ''; if (sortBy !== column) return '';
return sortAsc ? '\u2191' : '\u2193'; return sortAsc ? '\u2191' : '\u2193';
@@ -154,15 +161,32 @@
text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:outline-none transition-colors" /> text-text-primary placeholder-text-tertiary focus:border-accent/50 focus:outline-none transition-colors" />
</div> </div>
<select bind:value={filterStore} class="input-field w-auto text-xs py-1 px-2"> <div class="flex items-center gap-1.5">
<option value="">All stores</option>
{#each storeNames() as name} {#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} {/each}
</select> </div>
<span class="text-2xs text-text-tertiary"> <span class="text-2xs text-text-tertiary whitespace-nowrap">
{filteredAndSorted().length} of {results.length} shown {filteredAndSorted().length} of {results.length}
</span> </span>
</div> </div>
{/if} {/if}