Index filters with saved views
Composite search + filter chips + saved views companion of data-table — handles full-text search, faceted filtering, multi- condition combination, URL serialization, persisted named views. Modeled after Polaris IndexFilters.
Component — Index filters
*tatus* v0.1.0 — Draft. Sits in the toolbar above
specs/components/data-table.kmd.
R1 — Layout
Single horizontal row at the top of the data-table container:
| Section | Width | Content |
|---|---|---|
| Search box | flex 1 | Magnifying-glass icon + input + clear (×) |
| Filter chip area | flex 2 | Active filter chips inline, wraps on overflow |
| Saved-views dropdown | auto | Caret + view name (default: Default) |
| "Add filter" button | auto | + icon + label, opens filter picker popover |
R2 — Filter chip anatomy
Per active filter:
- Label: filter name (
Status) - Operator: optional (
is,is not,contains) - Value: human-readable (
Active,Active, Pendingfor multi) - Dismiss (×): removes filter immediately
Chip background: --kdr-surface-2; text: --kdr-text; dismiss icon: --kdr-text-muted.
R3 — Multi-condition expression
- Multiple filters compose with AND by default.
- Each filter MAY have OR within its own values (
Status: Active OR Pending). - Explicit grouping (parentheses) NOT supported in v0 — covered by future advanced-query ticket if demand surfaces.
R4 — Saved views
- "View" = name + columns + sort + filter set.
- Each view persisted per
user + pertableidentity (same scope as datatable saved views). - View dropdown shows: Default (always present, locked) + user-created views + "Save current as new view" CTA.
- Renaming, deleting, sharing per view: hover menu on each entry.
- Sharing across users not in v0.
R5 — URL serialization
- Active filters MUST reflect in the URL querystring as
?filter[Status]=Active,Pending&filter[Date]=>2026-01-01. - Refreshing the page restores the same filter state.
- Saved
view selection appears as `?view=myopen-issues`; loading a view applies its filters (overriding any explicit filter params).
R6 — Keyboard navigation
| Key | Action |
|---|---|
| Cmd+F / Ctrl+F | Focus the search box |
| Esc (in search) | Clear search and blur |
| Tab | Move through search, chips, dropdown, Add Filter |
| Enter on chip dismiss | Remove chip |
| Enter on Add Filter | Open filter picker |
| Esc (in picker) | Close picker without applying |
R7 — Internationalization
- All strings (placeholder, operators, button labels) translatable per
specs/i18n/contract.kmd. - Default-view name "Default" translates per locale.
- Date
typed filter values use localeaware formatting (perspecs/i18n/contract.kmddate-time section).
R8 — Accessibility
- Search box:
<input type="search">with associated label. - Chip set:
role="list"with each chiprole="listitem"; dismiss is a button inside. - Add-filter popover:
role="dialog"with focus trap; Esc closes. - Live-region announces filter changes ("Filter added: Status is Active").
R9 — Empty state interaction
When current filter set returns 0 rows: datatable shows emptystate (per specs/patterns/empty-state.kmd) with a Clear filters secondary action.
Não-escopo
- Sharing saved views across users (separate ticket if pursued).
- Advanced query expression with explicit grouping (separate ticket).
- Server
side filter execution (transportagnostic). - Pro
layer bundling (this primitive composed with `datatable` +density toggle + column-visibility menu + export into a single drop-in component) — evaluated in design
RFC008 and *atified Option C*(20260523) — the composition pattern ships asspecs/patterns/admin-data-table.kmdrather than a bundled component.