Overview
Composed filtering toolbar with a leading search field, select-based or custom facet controls, removable applied-filter chips, and a clear-all action. Designed for dense operational list views such as workflow queues, failure triage dashboards, and schedule browsers.
Overview
FacetedFilterBar composes SearchField, Chip (removable mode), and native select controls into one accessible filtering surface. It owns no routing, persistence, or data fetching — it emits change events and the consumer owns the filter state and data loading.
The bar supports two facet types:
select— a fixed list of options rendered as a styled native select. Use for status, category, queue, or any enumerable dimension.custom— a consumer-supplied snippet that renders any control (combobox, date-range picker, etc.) and receives the current value plus a change callback.
Applied filters are displayed as removable chips. A visually-hidden live region announces the active filter count and each applied value to screen readers whenever the filter state changes.
Usage
Custom facet (snippet escape-hatch)
Use type: 'custom' with a control snippet for any facet that cannot be expressed as a select list, such as a date-range picker or combobox:
Props
| Prop | Type | Default | Description |
|---|---|---|---|
aria-label |
string |
'Filters' |
Accessible label for the filter toolbar region. |
searchQuery |
string |
— | Controlled search query. When provided, the search field is controlled by the parent. |
searchPlaceholder |
string |
'Search…' |
Placeholder text shown in the leading search field. |
searchAriaLabel |
string |
'Search' |
Accessible label for the search input. |
facets |
FacetDefinition[] |
[] |
Facet definitions rendered as filter controls after the search field. |
appliedFilters |
AppliedFilter[] |
[] |
Applied filters displayed as removable chips. |
disabled |
boolean |
false |
When true, all filter controls and chips are disabled. |
class |
string |
— | Additional CSS classes applied to the root element. |
onSearchChange |
(query: string) => void |
— | Fires when the search query changes. |
onFacetChange |
(key: string, value: string) => void |
— | Fires when a facet value changes. |
onFilterRemove |
(key: string) => void |
— | Fires when a specific applied filter chip is removed. |
onClearAll |
() => void |
— | Fires when the clear-all button is clicked. |
FacetDefinition
AppliedFilter
Accessibility
FacetedFilterBar uses role="search" on the root element to expose the filtering surface as a landmark. Consumers should provide a meaningful aria-label prop (e.g. "Workflow filters") so screen reader users can navigate to it by landmark.
Each select facet receives an aria-label attribute equal to its label prop, and an associated visually-hidden label element is rendered via the cinder-sr-only class for redundancy.
Applied-filter chip remove buttons are labeled "Remove filter: {label}: {value}" so screen reader users know exactly which filter they are removing.
A role="status" live region (polite) always stays in the DOM and announces the active filter count and each applied value whenever the appliedFilters prop changes. The region is never conditionally rendered with {#if} — this ensures assistive technologies register it before any content is injected.
See faceted-filter-bar.a11y.md for the full keyboard and pointer interaction model.
When to use
- Filtering a list or table by multiple dimensions such as status, category, and queue simultaneously.
- Showing applied filters as removable chips so users can see and undo active constraints.
- A single search field or one select is sufficient — compose SearchField or Select directly.
- Filtering navigates to a new page — the bar owns no routing or persistence.
Examples
Basic faceted filter bar
Search field with status and queue facets, applied-filter chips, and a clear-all action.
Disabled state
All controls are disabled when disabled=true — selects, chips, and the clear-all button.
Workflow list filters
Status, failure category, queue, and workflow type facets for a dense operational workflow list view.
Props
| Name | Type | Default | Required | Bindable | Description |
|---|---|---|---|---|---|
searchQuery | text | Current text search query. When provided, the search field is controlled. | |||
searchVisible | boolean | true | Whether to render the leading search field. Defaults to true. | ||
searchPlaceholder | text | 'Search…' | Placeholder text shown in the leading search field. | ||
searchAriaLabel | text | 'Search' | Accessible label for the search input. Defaults to 'Search'. | ||
facets | readonly FacetDefinition[] | [] | Facet definitions rendered as filter controls after the search field. Each entry is either a select-type facet or a custom snippet-driven facet. | ||
appliedFilters | readonly AppliedFilter[] | [] | Applied filters displayed as removable chips below the controls row. Controlled by the consumer; each entry is a key/value/label triple. | ||
disabled | boolean | false | When true, all filter controls and chips are disabled. | ||
onSearchChange | (query: string) => void | Fires when the search query changes. | |||
onFacetChange | (key: string, value: string) => void | Fires when a facet value changes, with the facet key and new value. | |||
onFilterRemove | (key: string) => void | Fires when a specific applied filter chip is removed. | |||
onClearAll | () => void | Fires when the clear-all button is clicked. |