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:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user