Filter Bar
A search input, an optional filter select and a primary action in one row.
In context
Projects
Search and filter bar
To Be Sorted At The Harvest
What the parable of the wheat and the weeds asks of us now.
6 min read12 OctMotherhood
A conversation about a mother, a doubt and a lighted window.
4 min read9 OctThe Fire That Cleanses
Why the purifying fire is mercy before it is judgment.
8 min read2 OctIllusive Fruit
Fruit that looks ripe and is not: a short reflection.
3 min read25 SepOn the Perils of Conscience
A letter on examining conscience without scrupulosity.
7 min read18 SepWhat the Rosary Teaches the Hurried
Ten decades, slowly. A practice for the hurried.
5 min read11 SepTo Be Sorted At The Harvest
What the parable of the wheat and the weeds asks of us now.
6 min read12 OctMotherhood
A conversation about a mother, a doubt and a lighted window.
4 min read9 OctThe Fire That Cleanses
Why the purifying fire is mercy before it is judgment.
8 min read2 OctIllusive Fruit
Fruit that looks ripe and is not: a short reflection.
3 min read25 SepOn the Perils of Conscience
A letter on examining conscience without scrupulosity.
7 min read18 SepWhat the Rosary Teaches the Hurried
Ten decades, slowly. A practice for the hurried.
5 min read11 SepFilterBar props
| Prop | Type | Required | Default |
|---|---|---|---|
search | boolean | undefined | No | — |
searchValue | string | undefined | No | — |
defaultSearchValue | string | undefined | No | |
onSearchChange | ((value: string) => void) | undefined | No | — |
searchPlaceholder | string | undefined | No | Search |
searchLabel | string | undefined | No | Search |
options | FilterPillOption[] | undefined | No | — |
value | string | undefined | No | — |
defaultValue | string | undefined | No | — |
onValueChange | ((value: string) => void) | undefined | No | — |
filterLabel | string | undefined | No | Filter |
scrollPills | boolean | undefined | No | false |
sortOptions | FilterBarSortOption[] | undefined | No | — |
sortValue | string | undefined | No | — |
defaultSortValue | string | undefined | No | — |
onSortChange | ((value: string) => void) | undefined | No | — |
sortLabel | string | undefined | No | Sort |
count | number | undefined | No | — |
noun | string | undefined | No | result |
plural | string | undefined | No | — |
actions | ReactNode | No | — |
onClear | (() => void) | undefined | No | — |
FilterPills props
| Prop | Type | Required | Default |
|---|---|---|---|
options | FilterPillOption[] | Yes | — |
value | string | undefined | No | — |
defaultValue | string | undefined | No | — |
onValueChange | ((value: string) => void) | undefined | No | — |
aria-label | string | undefined | No | Filter |
scroll | boolean | undefined | No | false |
ResultCount props
| Prop | Type | Required | Default |
|---|---|---|---|
count | number | Yes | — |
noun | string | undefined | No | result |
plural | string | undefined | No | — |
query | string | undefined | No | — |
filter | string | undefined | No | — |
onClear | (() => void) | undefined | No | — |
clearLabel | string | undefined | No | Clear filters |
Search, filter, sort and count
FilterBar is the component behind the block's new fields: a pill search field (Escape or the clear button empties it), single-select FilterPills with an optional count each, a pill-shaped sort Select with a muted label, and a ResultCount live region ("9 Perspectives in Ethics") with a Clear filters button. Every value is controlled or uncontrolled. When the count is 0 render an Empty in place of the grid.
The filter-bar block turns on this look when it has pills, sortOptions or resultCount. Otherwise it stays the plain search, select and button row.
{ type: "filter-bar", searchPlaceholder: "Search Perspectives…", pills: ["All", "Ethics", "Grace"], sortOptions: ["Newest", "Oldest"], resultCount: { count: 24, noun: "Perspective" } }Accessibility
The search is a real type="search" input named by searchLabel. The pills are a named group of toggle buttons (aria-pressed), 44px tall. The count is role="status" (polite), so a screen reader hears the new total after each change. On a phone scrollPills keeps the pills on one line and scrolls them sideways.
Shape
{ type: "filter-bar", searchPlaceholder?: string, filterLabel?: string, filterOptions?: string[], actionLabel?: string, pills?: string[], sortOptions?: string[], sortLabel?: string, resultCount?: { count: number, noun?: string, plural?: string } }