FilterBar
Labelled filters on one line that fold behind one button when the line no longer fits.
Preview
import { Select } from '@usefragments/ui';
<FilterBar size="sm" activeCount={1} onReset={() => {}} doneLabel="Show 3 companies">
<FilterBar.Item label="Owner">
<Select size="sm" defaultValue="noah">
<Select.Trigger />Usage
Use when
- Two or more filters above a table or list that must stay usable on a phone
- A toolbar whose filters compete with actions for one row
Avoid when
- One filter: place the Select or SearchInput on its own
- Filters that need applying as a batch: use a Dialog with a form and a submit
- Switching views of the same data: use Tabs or ToggleGroup
Implementation notes
- One control per FilterBar.Item; the label names it on the line and in the sheet
- Filters apply as they change, so doneLabel says the result ("Show 14 companies")
- Pass activeCount and onReset so the folded button shows how much is filtered and the sheet can undo it
- Give the bar the toolbar's free room (it grows to fill a flex row) and keep actions outside it
Installation
pnpm add @usefragments/uiImport styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.
Anatomy
Import FilterBar once, then compose its parts with dot notation.
FilterBar.Item
Filters beside a table's actions; they fold behind one button on narrow screens.
import { Select } from '@usefragments/ui';
<FilterBar size="sm" activeCount={1} onReset={() => {}} doneLabel="Show 3 companies">
<FilterBar.Item label="Owner">
<Select size="sm" defaultValue="noah">
<Select.Trigger />
<Select.Content>
<Select.Item value="all">All owners</Select.Item>
<Select.Item value="noah">Noah Lee</Select.Item>
</Select.Content>
</Select>
</FilterBar.Item>
<FilterBar.Item label="Stage">
<Select size="sm" defaultValue="any">
<Select.Trigger />
<Select.Content>
<Select.Item value="any">Any</Select.Item>
<Select.Item value="pilot">Pilot</Select.Item>API reference
Prop | Type | Default | Description |
|---|---|---|---|
activeCount | number | undefined | 0 | How many filters differ from their defaults; the folded button shows it and Reset is disabled at 0 |
childrenRequired | React.ReactNode | Not set | The filters: FilterBar.Item nodes, each holding one control |
collapse | FilterBarCollapse | undefinedautoalwaysnever | auto | auto folds while the filters do not fit the room the bar is given; always and never fix it |
doneLabel | string | undefined | Done | The sheet's closing action; say what the person will see ("Show 14 companies") |
Item.childrenRequired | React.ReactNode | Not set | One control: Select, Combobox, Input, NumberField join the label on their own; wrap anything else in `Field.Control`. |
Item.labelRequired | React.ReactNode | Not set | The filter's name, shown beside the control on the line and above it in the sheet. |
label | string | undefined | Filters | Names the group, the folded button and the sheet's title |
onReset | (() => void) | undefined | Not set | Puts every filter back to its default; without it the sheet has no Reset |
resetLabel | string | undefined | Reset | The Reset action's label |
size | "xs" | "sm" | "md" | "lg" | undefinedxssmmdlg | Not set | Size of the folded button and the sheet's actions; match the controls |
Accessibility
- On the line the filters sit in role="group" named by label
- Each Item is a Field, so its label names the control
- The folded button reads its label and the active count ("Filters 2 active"); the sheet is a dialog titled by label
Related components
Next steps
- Accessibility guidanceThe keyboard, focus and naming rules every component carries.
- Every componentThe catalog, grouped by what each component does.