Filter
A single-select row of chips with a reset, for faceted product/category filtering. Radio semantics: one chip at a time; the reset clears the choice. Pair with FilterItems.
Colors
Real use · category filter
Showing: All
Using Filter
Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.
Plain HTML — CSS classes
The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path ships no JavaScript, so Filter is styled but inert: its behavior comes from toggle-group. For that behavior with no framework, use the node-tree path below.
/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";Root class filter, with 10 modifiers:
.filter.filter-accent.filter-error.filter-info.filter-item.filter-neutral.filter-primary.filter-reset.filter-secondary.filter-success.filter-warning
React
Typed components over those same classes, with behavior and accessibility from Base UI.
npm i @wizeworks/silicaui-reactimport { Filter } from "@wizeworks/silicaui-react";Props
FilterProps
| Prop | Type | Required | Description |
|---|---|---|---|
| value | string | no | Controlled selected value (undefined = nothing selected). |
| defaultValue | string | no | Uncontrolled initial value. |
| onValueChange | (value: string | undefined) => void | no | Fires with the new value, or undefined when reset. |
| color | SilicaColor | no | Accent for the selected chip. |
| disabled | boolean | no | Disable every chip + the reset. |
| showReset | boolean | no | Render the reset (×) once something is selected (default true). |
| resetLabel | string | no | Accessible label for the reset control. |
FilterItemProps
| Prop | Type | Required | Description |
|---|---|---|---|
| value | string | yes | This chip's value. |
Source of the demo above
The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.
Show source
import { useState } from "react";
import { Filter, FilterItem } from "@wizeworks/silicaui-react";
import { Section } from "../lib/Section";
import { COLORS } from "../lib/data";
const CATEGORIES = ["All", "Apparel", "Footwear", "Accessories", "Sale"];
export function FilterDemo() {
const [category, setCategory] = useState<string | undefined>("All");
return (
<>
<Section title="Colors">
<div className="flex flex-col gap-3">
{COLORS.slice(0, 6).map((color) => (
<Filter key={color} color={color} defaultValue="all">
<FilterItem value="all">All</FilterItem>
<FilterItem value="new">New</FilterItem>
<FilterItem value="sale">Sale</FilterItem>
</Filter>
))}
</div>
</Section>
<Section title="Real use · category filter">
<div className="flex flex-col gap-2">
<Filter color="primary" value={category} onValueChange={setCategory}>
{CATEGORIES.map((c) => (
<FilterItem key={c} value={c}>
{c}
</FilterItem>
))}
</Filter>
<p className="text-sm opacity-60">
Showing: {category ?? "nothing selected"}
</p>
</div>
</Section>
</>
);
}Vanilla — node tree to HTML
Filter — a single-select chip row with a reset. This is the EXISTING toggle-group behavior, not a new one: same single-select press semantics, same roving focus, same aria-pressed buttons. Build a node tree, project it with toHtml(), and let the zero-dependency runtime hydrate it. This is the path for generated or user-authored documents — a site builder, CMS output, a static export.
npm i @wizeworks/silicaui-html @wizeworks/silicaui-behaviorsimport { atom, toHtml } from "@wizeworks/silicaui-html";
const node = atom("Filter", "filter", { /* props */ }, [/* children */]);
const markup = toHtml(node);Styling on this path is the class string in the second argument — the same classes as the Plain HTML section above. There is no color prop here; write "filter filter-primary" rather than passing a colour as a prop.
- Takes children
- yes
- Hydrated by
toggle-group
Load @wizeworks/silicaui-behaviors on the page or this markup renders correctly and does nothing.
The full API for Filter, on every path, is available through the Silica MCP server.