Unify the upstream top-bar search box and the local SearchFilterBar into
one filtering capability sharing a single state store, with the URL as
its projection:
- lib/stores/filter.svelte.ts: module-level $state store, the single
source of truth; every surface mutates the same proxy in place
- lib/composables/useFilterUrlSync.svelte.ts: one $effect serves both
directions (URL -> store adoption, store -> URL replaceState write)
with echo suppression so the loop settles in one round-trip
- FilterFields.svelte: the five selects (type/size/modified/created/
kind) + recursive switch; word lists and i18n labels live in one
place; SearchFilterBar reuses it instead of its own copies
- TopBarFilterPanel.svelte: dropdown panel anchored inside the top-bar
search input (in-field toggle button with active-count badge);
Escape/outside-click close, no overlay stacking with suggestions
- FilterChips.svelte: dismissible chips on /search, which is now
URL-driven and loses its three inline <select>s
- New dimensions the backend already supported: kind (file/folder,
resource_types) and created (created_after); URL keys q/type/size/
date/created/kind/recursive, non-defaults only, unknown values
degrade to defaults
- /files keeps in-place filtering (no navigation); folderTarget
carries filter params through folder entry; ?file= and in/scope
survive filter writes
- topbar.css: input right padding reserves the three in-field controls
Backend unchanged.
Co-Authored-By: Claude Code <noreply@anthropic.com>