Hierarchical checkbox tree for nested categories with expand/collapse rows. Checking a parent checks its whole subtree, and partially selected parents turn indeterminate.
The import and the props worth knowing about, in one place.
import { FilterTree } from "@/components/beste/component/filter-tree";
const categories = [
{
label: "Shoes",
value: "shoes",
children: [
{ label: "Sneakers", value: "sneakers", count: 24 },
{ label: "Boots", value: "boots", count: 10 },
],
},
{ label: "Accessories", value: "accessories", count: 12 },
];
<FilterTree
label="Category"
options={categories}
defaultValue={["shoes"]} // expands to shoes + sneakers + boots
onChange={(value) => console.log("selected:", value)} // includes descendants
/>Turn the props on the right; the snippet under them is what you would write to get what you see.
import { FilterTree } from "@/components/beste/component/filter-tree";
<FilterTree
label="Category"
defaultValue={["sneakers"]}
className="w-64"
options={[{"label":"Shoes","value":"shoes","count":42,"children":[{"label":"Sneakers","value":"sneakers","count":24},{"label":"Boots","value":"boots","count":10},{"label":"Sandals","value":"sandals","count":8}]},{"label":"Apparel","value":"apparel","count":38,"children":[{"label":"T-Shirts","value":"t-shirts","count":18},{"label":"Outerwear","value":"outerwear","count":20,"children":[{"label":"Hoodies","value":"hoodies","count":9},{"label":"Jackets","value":"jackets","count":11}]}]},{"label":"Accessories","value":"accessories","count":12}]}
/>Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.
| Tab | Move between the boxes — each is its own control, not one list with an inner cursor. |
|---|---|
| Space | Tick or untick the focused one. |
| The disclosure arrow | Opens a branch. Ticking a parent takes its children with it. |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Optional group heading rendered above the tree |
options | FilterTreeOption[] | — | |
value | string[] | — | Controlled selection; omit to let the component manage its own state. Checking a node checks its whole subtree, and a parent turns indeterminate while only some of its descendants are selected. The selection always contains every checked value, descendants included. |
defaultValue | string[] | — | Initial selection when uncontrolled; parents expand to their subtree |
defaultExpanded | string[] | — | Values whose children start expanded; ancestors of the initial selection expand automatically |
onChange | (value: string[]) => void | — | |
className | string | — |
Multi-select checkbox list with optional result counts. Works controlled or uncontrolled, designed for filter sidebars and toolbars.
Dropdown with checkbox rows and a selection-count badge. Keeps many-option filters compact in toolbars where a checkbox list would not fit.
Single-select segmented control built on Tabs for mutually exclusive choices like gender or condition. Clicking the active segment clears the selection.
Single-select dropdown for long option lists that would crowd a sidebar. Supports a clear item, result counts, and a disabled state for dependent filters.