antuikit's TreeSelect is Ant Design's TreeSelect, installed into your project as a file you own. It takes the same props and keeps both generic parameters. The arrow, the chip remove and the clear icons come from your icon pack, set in the file itself, and the expand arrows in the tree come from AntuikitProvider.
Install
npx antuikit@latest init
npx antuikit@latest add tree-select
The first command installs AntuikitProvider and the theme, and the second adds TreeSelect.
Import
From @/components/ui/tree-select, never from antd. The file is yours once it is installed, so the import path is a path in your project rather than a package.
import { TreeSelect } from "@/components/ui/tree-select"
The axes
The enumerated props, and the values each one takes. The first three are the same as Select's.
variant takes outlined (the default), filled, borderless and underlined. Inherited from ConfigProvider when unset, which is how a whole form picks one.
size takes small, medium (the default) and large. middle is the older spelling of medium. A Space.Compact around the field overrides it.
status takes error and warning, and nothing else. Form.Item sets it for you, so writing it by hand usually means the validation lives somewhere it should not.
placement takes bottomLeft, bottomRight, topLeft and topRight, defaulting to bottomLeft and to bottomRight under RTL.
showCheckedStrategy takes SHOW_CHILD (the default), SHOW_PARENT and SHOW_ALL, all three on TreeSelect so TreeSelect.SHOW_PARENT needs no second import. It changes the value rather than the look.
treeExpandAction takes false (the default), click and doubleClick: what opens a branch besides the switcher itself.
Pick one value per axis and keep it across a view. An axis that changes per instance stops meaning anything.
Flags
Each of these turns one behavior on, and three of them change what value contains rather than how the field looks. They compose, and when two contradict, one silently wins.
multiple gives tags instead of one value. Forced on by treeCheckable, which warns in development if you pass multiple={false} beside it.
treeCheckable adds checkboxes and the parent/child cascade. Typed as boolean | React.ReactNode, but any truthy value draws the standard checkbox, so treat it as a boolean.
treeCheckStrictly breaks the cascade and turns labelInValue on: the value becomes { value, label } entries and may carry halfChecked. This is the one that breaks code rather than layout.
labelInValue does that shape change on its own, without touching the checking behavior.
treeDefaultExpandAll opens everything on mount. Fine on a demo, a performance trap on a real tree: prefer treeExpandedKeys with onTreeExpand.
virtual is on by default and windows the popup's rows. It turns itself off when popupMatchSelectWidth is false, so pair it with a listHeight and leave the width alone.
treeLine draws the connecting lines, and takes { showLeafIcon } as well as a boolean.
treeIcon shows each node's own icon field. Without it the icons are data nobody sees.
disabled takes the whole field out of the tab order. Disabling single nodes (disabled, disableCheckbox or checkable: false on the node) is usually the better answer.
Slots
The props that take a node. A slot is where your own markup goes, and it is the route to reach for before a descendant selector, which matters more here than usual: the tree renders outside this component's root element, in a portal.
suffixIcon, the trigger arrow, and removeIcon, the × on a tag. Both default to the icon pack. Pass null as suffixIcon to hide the arrow. A nullremoveIcon shows a plain × instead of an icon.
allowClear takes true or { clearIcon }, as on Select, and the clear icon defaults to the pack's close icon. The same object takes label, which is the button's accessible name.
switcherIcon takes a node or a function of { expanded }. The provider's default is the function form, so the arrow can turn as a branch opens.
treeTitleRender replaces a row's title in the popup. It does not change what the closed field shows: that is treeNodeLabelProp.
popupRender wraps the whole popup, for a footer or a hint above the tree. notFoundContent replaces the empty state inside it.
tagRender and maxTagPlaceholder own the tags under multiple. Take tagRender and you own the remove affordance and its accessible name too.
prefix and placeholder sit inside the closed field.
Two props that look like slots and are not.treeCheckable is typed as a node but draws the standard checkbox for anything truthy, and children is the legacy TreeSelect.TreeNode form, which is deprecated and not exported by the kit. Build the tree with treeData.
Events
onChange fires with the whole value. Its second argument, the label list, is null once the value is labeled, because the labels are then inside the value.
onSelect and onDeselect fire per node, with the node itself, and not for the cascade under a checked parent.
onTreeExpand fires with the whole expanded set, which is what a controlled treeExpandedKeys is written from.
onTreeLoad fires after loadData resolves, with the full loaded set.
onOpenChange is the popup's open callback. onPopupVisibleChange is the base Select's older one and onDropdownVisibleChange is deprecated: prefer onOpenChange in new code.
onClear fires beside onChange when the clear button is used, which is how you tell an emptied field from an unset one.
loadData is not an event: it returns a promise, and the branch shows as loading until that promise settles. It is also not called while a search is active, so a lazily loaded tree can only be searched over the part that has already arrived.
Styling
classNames and styles take the same keys, one per part. Reach for them before a descendant selector, since a keyed part stays stable across versions.
1
<TreeSelect
2
classNames={{
3
root: "…",
4
prefix: "…",
5
input: "…",
6
suffix: "…",
7
content: "…",
8
placeholder: "…",
9
item: "…",
10
itemContent: "…",
11
itemRemove: "…",
12
popup: "…",
13
}}
14
/>
A Tailwind class on one of these keys wins without !important. Setting a component token's CSS variable on the root has no effect, so style the part instead.
API Reference
TreeSelect
TreeSelect's props. Rows marked antuikit in the Version column are added by the kit.