FilterPanel

Organism
Sidebar filter rail: grouped checkbox options under mono group headings, each with its count, and a "Clear N" action in the header while any filter is on (a plain accent text action). On the web an option's label is the 400 14px row label, 10px from its box.

Playground

Every control sets a real prop of FilterPanelProps. The JSX below updates as you go.
Filters
Status
Schema
Props
bordered
boolean
compact
boolean
activeCount
number
3
JSX · FilterPanelProps
<FilterPanel bordered activeCount={3} />

Variants

1 examples from src/organisms/filter-panel/filter-panel.md, each rendered live from its own JSX.
Filters
Status
Schema
Responsive drawer
At desktop widths this renders the docked panel unchanged; at and below the sm breakpoint it renders the "Filters" trigger with its count and the panel opens in a drawer.
<FilterPanel
responsive
groups={[
{ title: "Status", options: [
{ label: "Active", checked: true },
{ label: "Archived" }
] },
{ title: "Schema", options: [
{ label: "Default" },
{ label: "Custom" }
] }
]}
/>

Anatomy

Filters
Status
Schema
1
Panel
2
Group heading
3
Option
4
Count
5
Clear all
Dimmed parts appear only in some states or variants.

Props

16 props on FilterPanelProps, grouped as they are declared in source. Required props are marked *.
Prop
Type
Default
Description
Props
7 props
groups *
FilterGroup[]
–
Filter groups, each a heading plus its checkbox options.
value
string[]
–
Controlled selection: the keys of the checked options (each option's value, falling back to "groupIndex:optionIndex"). Provide it with onSelectionChange to drive or reset selection from a parent (e.g. from a URL query).
defaultValue
string[]
–
Initial selection for uncontrolled use. When omitted, the panel seeds from each option's checked flag.
activeCount
number
–
Active-filter count shown in the header's "Clear N" action. Omit to derive it from the checked options.
onClear
() => void
–
Fired when the header "Clear N" action is pressed (it shows while a filter is on).
onSelectionChange
(selected: string[]) => void
–
Fired with the full set of checked keys whenever the selection changes (both modes) — the controlled signal a parent mirrors into value.
onChange
(groupIndex: number, optionIndex: number, next: boolean) => void
–
Fired when a single option row toggles, with its group/option indexes and next value. Fires alongside onSelectionChange.
Surface
pick one
1 prop
bordered
boolean
false
Density
pick one
1 prop
compact
boolean
false
Responsive drawer axis
7 props
responsive
boolean
false
Opt in to the responsive panel->drawer behavior. Off by default: a bare panel is the docked column at every width, exactly as before.
drawerBreakpoint
BreakpointKey
–
The width at and below which responsive collapses to the drawer (default sm = 640).
open
boolean
false
The responsive drawer's open state (CONTROLLED). Omit for the self-managed trigger button.
defaultOpen
boolean
false
Initial open state for the uncontrolled responsive drawer (default closed).
onOpenChange
(open: boolean) => void
–
Fired when the responsive drawer opens or closes (trigger, scrim, back).
testID
string
–
E2E hook forwarded to the root element.
style
StyleProp<ViewStyle>
–
Outer layout composition only (width/flex within a parent), never a restyle hook.

Accessibility and keyboard

Keyboard
Space
Toggles
Tab
Moves focus on
Semantics
Roles
checkbox
States
checked
ARIA on web
aria-checked
aria-hidden
Below the platform minimum, the touch area grows to 44 pt on iOS and 48 dp on Android without moving the layout.

Platform skins

The playground's props on each platform: same tree, native shapes, type and touch sizes.
Filters
Status
Schema
Web
control 10 · field 10 · card 16 · Instrument Sans
Filters
Status
Schema
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt
Filters
Status
Schema
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

Usage

<FilterPanel
bordered
groups={[
{ title: "Status", options: [
{ label: "Active", checked: true, count: "128" },
{ label: "Pending", count: "12" },
{ label: "Archived", count: "2" }
] },
{ title: "Schema", options: [
{ label: "Default", count: "96" },
{ label: "Custom", count: "46" }
] }
]}
/>
Add responsive and at and below drawerBreakpoint (default sm = 640) the docked panel collapses to a small secondary "Filters" button, carrying the live count, that opens the same panel inside a start-edge drawer, so a phone keeps its width for the results; open / defaultOpen / onOpenChange drive the drawer for controlled use.
On iOS an option row marks a chosen filter the way an iOS list does: the label leads, the count follows, and a trailing check closes the row. The web and Android lead each row with the platform's selection checkbox. The native rows keep the platform's touch height (44 pt, 48 dp).

Tokens

Read from the playground render. Values follow the scheme and the ion hue.
--fd
--fm
--ft
--ion
--ion-fg
--ion-tx
--ln2
--sf
--tx3

Related components