- The root has
role="search" and is named by label; the default name is “Filters”. A screen reader announces it as a search region and lists it among landmarks.
- Every control has a label: the search box label is visually hidden but read; Select, Toggle and the multi-select button carry visible labels. In the multi-select panel a
<fieldset> and <legend> give the field name.
- Toggle carries
aria-pressed. The multi-select button opens the panel and reports aria-expanded while open.
- The chips are a named list (“Applied filters”). Every remove button is named after its filter: “Remove Status filter”; in a multi-select “Remove Category, Category A filter”.
- The result count is announced in a
role="status" region (aria-live="polite"). The visible text is hidden from screen readers; only the announcement region is read.
- While loading, the root is
aria-busy; the Apply button announces its loading state.
- The “More filters” button carries
aria-expanded and aria-controls; the badge number joins the button name: “More filters 2”.
| Key |
Behaviour |
| Tab |
Moves through the controls in DOM order: search, “More filters” (narrow screens), fields, Apply, Reset, Clear, chips. |
| Enter |
In the search box in batch mode, applies the draft. Activates buttons. |
| Space |
Activates the Toggle, buttons and checkboxes. |
| Arrow keys |
Move between options while a Select is open. |
| Escape |
Closes a Select or the multi-select panel; focus stays on the trigger. |
| Backspace, Delete |
Removes the focused chip. |
Each control uses its own 2 px focus ring. When “Clear filters” is used, or the last chip is removed, the button or chip disappears; focus then moves to the first control (usually the search box) so it is never lost. When a chip is removed focus goes to the next chip’s remove button.
| Example |
Read |
| Root |
“Filters, search” |
| Search box |
“Search, search text field” |
| Chip button |
“Remove Status filter, button” |
| When the count changes |
“12 results” (500 ms after typing stops, once) |
| Clear |
“Clear filters, button” |
Text is at least 4.5:1 in every brand and mode; values are computed from the bigbang output. The controls’ own contrast is given on their pages.
| Pair |
Light mode |
Dark mode |
color-text-default / color-surface-default |
16.16:1 |
17.18:1 |
color-text-subtle / color-surface-default (result count) |
8.77:1 |
10.27:1 |
| Criterion |
How FilterBar meets it |
What the product team does |
| 1.3.1 Info and relationships |
A search region, visible or hidden labels, fieldset/legend. |
Give each FilterBar its own label when there are several. |
| 2.1.1 Keyboard |
All functions work by keyboard. |
- |
| 2.4.3 Focus order |
Focus order matches visual order; after clearing, focus is on the first control. |
In a custom layout, match the FilterBar.* order to the visual order. |
| 2.4.7 Focus visible |
Every control has its ring. |
Do not remove outline with className. |
| 3.3.2 Labels or instructions |
Every control is labelled. |
Write short, distinct labels. |
| 4.1.3 Status messages |
The result count is announced with role="status", delayed by 500 ms. |
Update resultCount as soon as the filter is applied. |
| 2.5.8 Target size |
Chip remove buttons are 24 px; buttons are 36 px, 40 px on a touch screen. |
- |