FilterPanel

Sidebar filter rail: grouped checkbox options with count badges and a Clear header.
Add responsive and at and below drawerBreakpoint (default sm = 640) the docked panel collapses to a "Filters (n)" outline button 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.
Filters
1
Status
Schema
iOS
Filters
1
Status
Schema
Android
Filters
1
Status
Schema
Web
tsx
<FilterPanel
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" }
] }
]}
/>

Props

Prop
Description
groups
required
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 next to the "Filters" title. Omit to derive it from the checked options.
onClear
() => void
Fired when the header "Clear" action is pressed.
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`.
bordered
boolean
Surface (pick one path): a rounded, bordered card vs. a bare panel.
compact
boolean
Density (pick one): tighten the panel's padding and row spacing.
responsive
boolean
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
The responsive drawer's open state (CONTROLLED). Omit for the self-managed trigger button.
defaultOpen
boolean
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.

Do & Don’t

Group by facet

Don’t
Filters
1
Filters
Pour every option into one group; statuses and regions run together, and nothing says which choices narrow the same field.
Do
Filters
1
Status
Region
Give each facet its own titled group, so a reader sees which options narrow the same field.