TreeSelect
tree-selectSelects one or more values from a searchable hierarchical tree.
Usage
Single selection + search
Default radio selection: Click the leaf to submit and close it. searchable A search box appears at the top of the floating layer, which can be used to jump in multiple layers. For uncontrolled use, use defaultValue to set the initial value.
<TreeSelect
nodes={nodes}
searchable
placeholder="Select the department to which you belong"
onChange={(v) => setValue(v)}
/>Multiple selection (parent-child cascade)
When multiple clicks on the check box, check the parent cascade to the leaf, cancel a single leaf and leave the parent half-selected; value converges into a set of leaf keys.
<TreeSelect
nodes={nodes}
multiple
defaultValue={["fe-web", "fe-mini"]}
placeholder="Check visible departments"
onChange={(v) => setValue(v)}
/>Clearable (clearable)
When it has a value and is not disabled, a clear button (the arrow gives way) will appear on the right side of hover or the keyboard focus trigger. Click to return to the unselected state: single selection returns an empty string, and multiple selection returns an empty array. Leave the hierarchical filtering dimension blank = no limit, required.
Current value:"fe-web"
<TreeSelect
nodes={nodes}
clearable
value={value}
onChange={setValue}
placeholder="All departments"
/>Multiple selections can be cleared
Use the clear button under multi-select to clear all the check boxes at once (return []), without canceling one by one.
<TreeSelect nodes={nodes} multiple clearable defaultValue={["fe-web", "fe-mini"]} />Disabled
<TreeSelect nodes={nodes} disabled defaultValue="fe-web" />When to use
Use TreeSelect to choose one or more nodes from a hierarchy such as an organization, category tree, or region while keeping the field collapsed. Use Combobox or Listbox for flat options, or RegionCascader for China's built-in province/city hierarchy.
Import
import { TreeSelect } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| nodes* | TreeNode[] | — | Hierarchical data with key, label, and optional children, using the shared Tree node model. |
| value | string | string[] | — | Controlled value: a string in single mode or string[] in multiple mode. |
| defaultValue | string | string[] | — | Initial value in uncontrolled mode. |
| multiple | boolean | false | Whether to enable checkbox-based multiple selection with parent-child cascading. |
| placeholder | string | "\u8bf7\u9009\u62e9" | Trigger placeholder; the built-in Chinese copy means “Please select.” |
| disabled | boolean | false | Whether to disable the selector. |
| invalid | boolean | false | Applies invalid styling. |
| size | "sm" | "md" | "lg" | "md" | Trigger size. |
| clearable | boolean | false | Whether to reveal a clear button on trigger hover or focus when a value exists. Clearing emits "" in single mode or [] in multiple mode, matching Select. |
| searchable | boolean | false | Shows a search field in the popup and expands matching paths. |
| expandTrigger | "row" | "icon" | "row" | What toggles expand/collapse, forwarded to the inner Tree. With the `"row"` default, single selection can only reach leaf nodes. Pass "icon" to select an intermediate level (a department, a top-level category, one volume): the arrow expands, the rest of the row selects. |
| showLine | boolean | false | Shows tree connection lines. |
| className | string | — | Additional class name passed to the trigger. |
Events
| Event | Type | Description |
|---|---|---|
| onChange | (value: string | string[]) => void | Called with a string in single mode or string[] in multiple mode when selection changes. |
Example
// Single selection with search
const [v, setV] = useState<string | string[]>("");
<TreeSelect nodes={NODES} value={v} onChange={setV} placeholder="Select a department" searchable />
// Multiple selection cascades parent checks to leaves and derives half-checked parents
const [v, setV] = useState<string | string[]>(["fe-web", "fe-mini"]);
<TreeSelect nodes={NODES} multiple value={v} onChange={setV} placeholder="Check visible departments" />
// Clearable optional filter: an empty value means no restriction
const [dept, setDept] = useState<string | string[]>("");
<TreeSelect nodes={NODES} clearable value={dept} onChange={setDept} placeholder="All departments" />Usage guidelines
- Single selection is not clearable by default. Enable
clearablefor optional filters; otherwise users can narrow the filter but cannot return it to “no restriction.” - Switching
multiplechanges controlledvalueandonChangebetweenstringandstring[]. Branch state by the active mode rather than storing both shapes together. - Single selection only reaches leaves by default.
expandTriggerdefaults to"row", so clicking a row that has children only expands it and never firesonChange— no number of clicks will select it. PassexpandTrigger="icon"to submit any level (arrow expands, row selects), or use Cascader withchangeOnSelect. Multiple mode is unaffected because the checkbox is its own hit area. - In multiple mode, pass selected leaf keys only. Half-checked parent state is derived from the tree; do not insert those parent keys manually.
Related
SecretField · Combobox · Listbox · Mentions · InputOTP · Rating
Playground
<TreeSelect
nodes={nodes}
searchable
value={value}
onChange={setValue}
/>