CommerceCategoryFilters
Filter sidebar for a category page: a stack of collapsible filter groups (price, color, size, brand). Uses native <details> so no JS is needed for collapse — Server Component friendly. Each group's controls are caller-supplied; state and submission live with the consumer.
Installation
pnpm dlx @hex-core/cli add commerce-category-filtersUsage
import { CommerceCategoryFilters } from "@/components/ui/commerce-category-filters"API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
groupsrequired | object | — | ReadonlyArray<{ title; content: ReactNode; defaultOpen? }>. Filter groups. Each content is a caller-supplied stack of controls (Checkbox / RadioGroup / Slider / range Input). |
title | ReactNode | — | Optional sidebar title (e.g. 'Filters'). |
actions | ReactNode | — | Optional header actions (e.g. a 'Clear all' link). |
className | string | — | Additional classes applied to the root <aside>. |
AI Guidance
When to use
Use on a category / search results page beside the product grid. The block is layout-only — pass real controls (Checkbox, RadioGroup, Slider, range Input) in each group's content. Wire selection state and result filtering in the parent.
When not to use
Don't use for storefront top nav (use commerce-store-nav). Don't use for in-product settings (use app-settings). Don't put the entire facet tree here — group by ~3–6 most-useful facets.
Common mistakes
- Putting form submission inside the block — the block doesn't render a form; wrap your controls in a parent <form> if you want classic submit, or wire onChange handlers per control.
- Putting more than ~6 groups — long sidebars get ignored; lift secondary facets into a modal or 'More filters' affordance.
- Forgetting `<Label htmlFor>` on inputs — accessible names are the consumer's job.
Accessibility
Root is an <aside> labelled 'Filters'. Each group uses native <details>/<summary> — keyboard-toggleable (Enter/Space) with built-in aria-expanded. The chevron rotates via CSS on [open]; it's aria-hidden so it doesn't pollute the summary's accessible name.
Token budget: 982
Verified against @hex-core/components@1.14.0