React Faceted Filter Sidebar
The faceting engine on its own, not bolted to a table. Parametric Search bundles an Advanced Table and Resource Library bundles a card grid; this owns only the facets and hands the filtered items back through a render prop, so the same sidebar can drive a table, a card grid, a map, or anything you can render from an array.
Kelvin · MCU · QFN-32
STMicro · Regulator · TSSOP-16
Infineon · Op-amp · SOIC-8
Analog Devices · MOSFET · SOT-23
onsemi · Sensor · BGA-64
Texas Instruments · Interface · QFN-32
Nexperia · MCU · TSSOP-16
Kelvin · Regulator · SOIC-8
STMicro · Op-amp · SOT-23
Infineon · MOSFET · BGA-64
Analog Devices · Sensor · QFN-32
onsemi · Interface · TSSOP-16
Texas Instruments · MCU · SOIC-8
Nexperia · Regulator · SOT-23
Kelvin · Op-amp · BGA-64
STMicro · MOSFET · QFN-32
Infineon · Sensor · TSSOP-16
Analog Devices · Interface · SOIC-8
onsemi · MCU · SOT-23
Texas Instruments · Regulator · BGA-64
Nexperia · Op-amp · QFN-32
Kelvin · MOSFET · TSSOP-16
STMicro · Sensor · SOIC-8
Infineon · Interface · SOT-23
Analog Devices · MCU · BGA-64
onsemi · Regulator · QFN-32
Texas Instruments · Op-amp · TSSOP-16
Nexperia · MOSFET · SOIC-8
Kelvin · Sensor · SOT-23
STMicro · Interface · BGA-64
Infineon · MCU · QFN-32
Analog Devices · Regulator · TSSOP-16
onsemi · Op-amp · SOIC-8
Texas Instruments · MOSFET · SOT-23
Nexperia · Sensor · BGA-64
Kelvin · Interface · QFN-32
STMicro · MCU · TSSOP-16
Infineon · Regulator · SOIC-8
Analog Devices · Op-amp · SOT-23
onsemi · MOSFET · BGA-64
Texas Instruments · Sensor · QFN-32
Nexperia · Interface · TSSOP-16
Kelvin · MCU · SOIC-8
STMicro · Regulator · SOT-23
Infineon · Op-amp · BGA-64
Analog Devices · MOSFET · QFN-32
onsemi · Sensor · TSSOP-16
Texas Instruments · Interface · SOIC-8
Installation
Props
| Prop | Type | Description |
|---|---|---|
| items | T[] | The full dataset to filter |
| facets | FacetDef<T>[] | Facet definitions (see kinds below) |
| value | FilterState | Controlled filter state |
| defaultValue | FilterState | Initial state when uncontrolled |
| onChange | (state, filtered) => void | Fires when the filter set or results change |
| children | (filtered: T[]) => React.ReactNode | Render prop for the results view |
| title | string | Sidebar heading (default "Filters") |
Four facet kinds, one engine
A FacetDef is a discriminated union, so each kind carries exactly the config it needs and TypeScript narrows on kind:
checkbox— multi-select; within a facet the selections are OR-ed. Give anaccessorreturning astringor astring[]for multi-valued rows like tags. Options are derived from the data unless you pass them.radio— single-select, for mutually exclusive facets like lifecycle. Selecting a second value replaces the first.range— numeric min/max, committed on blur or Enter, with an optionalunit.toggle— a boolean gate driven by apredicate, for "in stock" or "RoHS compliant".
Long lists get two affordances a facet sidebar lives or dies on: searchable adds an option-search box, and maxVisible collapses to the first N options behind a "show more". Any facet can be collapsible.
Counts are leave-one-out, and they never lie
The number beside each option is the result count you'd get if you selected it — computed against every other active facet but not this one. That is the distributor convention, and it is the correct one: if selecting a value within a facet narrowed its own options' counts, every count would drop to reflect a choice you haven't made yet, and the ones you didn't pick would misleadingly read zero. Options that would yield nothing dim to signal a dead end without removing them, so the shape of the data stays visible.
Decoupled by construction
The component renders the sidebar, the applied-filter chips, a live result count, and a mobile drawer — and then calls children(filtered) with the surviving items. It never renders your results, which is the point: the demo drives a plain card grid, but the same instance would drive a table or a <canvas> map without changing a line of the filter code. State can be left uncontrolled, or lifted via value / onChange to sync with the URL so a filtered view is shareable. On mobile the whole sidebar folds into a drawer behind a Filters button that carries a badge with the active-facet count, because a filter panel that eats the screen on a phone is a filter panel nobody opens.
New components every week
Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.