For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/components/tree-select.md.

TreeSelect 树选择器

从层级数据中选择一个或多个值。

选择与搜索

当前值: 未选择
basic.tsx
import { Space, Text, TreeSelect } from '@ifhover/leaf-ui';

import { useState } from 'react';

import { treeOptions } from './options';

export function TreeSelectBasic() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <Space direction="vertical" align="stretch">
      <TreeSelect
        options={treeOptions}
        value={value}
        onChange={setValue}
        defaultExpandAll
        aria-label="所属团队"
        placeholder="选择所属团队"
      />
      <output>
        <Text tone="muted">当前值: {typeof value === 'string' ? value : '未选择'}</Text>
      </output>
    </Space>
  );
}

多选与勾选

视觉设计
视觉设计
设计团队
multiple.tsx
import { Form, FormField, TreeSelect } from '@ifhover/leaf-ui';

import { treeOptions } from './options';

export function TreeSelectMultiple() {
  return (
    <Form layout="vertical">
      <FormField label="多选 · 逐项选择">
        <TreeSelect options={treeOptions} multiple defaultValue={['visual']} defaultExpandAll />
      </FormField>
      <FormField label="勾选联动 · 提交子节点">
        <TreeSelect
          options={treeOptions}
          treeCheckable
          defaultValue={['visual']}
          defaultExpandAll
        />
      </FormField>
      <FormField label="勾选联动 · 合并显示父节点">
        <TreeSelect
          options={treeOptions}
          treeCheckable
          showCheckedStrategy="parent"
          defaultValue={['design']}
          defaultExpandAll
        />
      </FormField>
    </Form>
  );
}

状态与浮层

states.tsx
import { Form, FormField, TreeSelect } from '@ifhover/leaf-ui';

import { treeOptions } from './options';

export function TreeSelectStates() {
  return (
    <Form layout="vertical">
      <FormField label="禁用">
        <TreeSelect options={treeOptions} disabled defaultValue="web" />
      </FormField>
      <FormField label="校验反馈">
        <TreeSelect options={treeOptions} status="error" placeholder="请选择一个团队" />
      </FormField>
      <FormField label="自定义浮层宽度">
        <TreeSelect options={treeOptions} popupWidth={320} popupMaxWidth={360} defaultExpandAll />
      </FormField>
    </Form>
  );
}

扩展用法

extensions.tsx
import { TreeSelect } from '@ifhover/leaf-ui';

export function ExtensionDemo() {
  return (
    <TreeSelect
      placeholder="展开团队加载成员"
      options={[{ value: 'team', label: '团队', isLeaf: false }]}
      virtual
      loadData={async (option) => {
        await new Promise((resolve) => setTimeout(resolve, 500));
        return [
          { value: `${option.value}-design`, label: '设计组', isLeaf: true },
          { value: `${option.value}-dev`, label: '开发组', isLeaf: true },
        ];
      }}
    />
  );
}

选择限制与节点展示

浮层默认与控件等宽(popupWidth="trigger")。设置 popupWidth="auto" 仅按内容定宽,也可以比控件窄;popupWidth={300} 固定为 300px,也支持 CSS 长度。popupMaxWidth 默认未设置,下面的示例按内容定宽并显式设置最大宽度。浮层仍会在视口边缘避让。

最多选择两人,只展示一个标签
capabilities.tsx
import { Flex, Space, Text, TreeSelect } from '@ifhover/leaf-ui';

import { useState } from 'react';

const options = [
  {
    value: 'team',
    label: 'Team',
    children: [
      { value: 'alice', label: 'Alice' },
      { value: 'bob', label: 'Bob' },
      { value: 'carol', label: 'Carol' },
    ],
  },
];

export function Capabilities() {
  const [expanded, setExpanded] = useState<readonly string[]>(['team']);
  return (
    <Space direction="vertical" align="stretch">
      <Flex direction="column" gap="sm" align="center">
        <Text>
          {'最多选择两人,只展示一个标签'}
        </Text>
        <TreeSelect
          aria-label={'团队成员'}
          popupWidth="auto"
          popupMaxWidth={320}
          treeCheckable
          options={options}
          maxCount={2}
          maxTagCount={1}
          treeExpandedKeys={expanded}
          onExpand={setExpanded}
          nodeRender={(node) => <strong>{node.label}</strong>}
          filterTreeNode={(node, query) =>
            String(node.label).toLowerCase().includes(query.toLowerCase())
          }
          showSearch
        />
      </Flex>
    </Space>
  );
}

单行多选

设置 tagWrap={false} 后,已选项始终展示在一行内。长文字自动省略,放不下的选项合并为 +N;空间很窄时只显示数量,打开浮层可查看和修改选择。maxTagCount 可进一步限制标签数量,maxTagCount="responsive" 也会启用单行自动折叠。

再次打开会保留上次展开的分支。不可选分类可点击整行展开;勾选模式可点击整行或按 Enter / 空格勾选,箭头只负责展开或收起。搜索临时展开匹配分支,不改变原有展开状态。

视觉设计产品设计前端开发服务端开发
single-line.tsx
import { Form, FormField, TreeSelect } from '@ifhover/leaf-ui';

import { treeOptions } from './options';

export function SingleLine() {
  return (
    <Form layout="vertical">
      <FormField label="单行多选">
        <TreeSelect
          treeCheckable
          tagWrap={false}
          options={treeOptions}
          defaultValue={['visual', 'product', 'web', 'server']}
          treeDefaultExpandedKeys={['design']}
        />
      </FormField>
    </Form>
  );
}

TreeSelect API

属性类型默认值说明
popupPlacement'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end'—浮层相对触发控件的位置。
popupClassNamestring—浮层的自定义类名。
popupStyleCSSProperties—浮层的自定义样式。
popupRender(content: React.ReactNode) => React.ReactNode—包装或补充面板内容,保留传入的内容以维持交互。
getPopupContainer() => Element | DocumentFragment—返回浮层的挂载容器,也可返回 ShadowRoot。
optionsreadonly TreeSelectOption[]必填必需。层级选项
checkStrictlybooleanfalse父子节点独立勾选
showCheckedStrategy'child' | 'parent' | 'all''child'勾选后显示与输出子节点、合并父节点或全部节点
showSearchbooleantrue通过输入过滤节点
onSearch(query: string) => void—搜索文字变化
allowClearbooleantrue允许清除可用选项
defaultExpandAllbooleanfalse初始展开全部
treeDefaultExpandedKeysreadonly string[][]初始展开的 value
size'sm' | 'md' | 'lg''md'控件尺寸
status'error' | 'warning'—校验反馈
popupWidthnumber | string'trigger'浮层宽度;trigger 与控件等宽,auto 按内容定宽(可比控件窄),数字为固定像素值,也支持 CSS 长度
popupMaxWidthnumber | string—可选的最大宽度;默认不限制,仍受视口限制
notFoundContentReactNode暂无选项无匹配内容
onOpenChange(open: boolean) => void—展开状态变化
loadData( option: TreeSelectOption, signal: AbortSignal, ) => Promise<readonly TreeSelectOption[]>—展开时加载子项,signal 用于取消
onLoadError(error: unknown, option: TreeSelectOption) => void—加载失败,再次展开可重试
virtualbooleanfalse仅渲染可见项目
listHeightnumber256列表高度
itemHeightnumber38跟随区域控件高度和密度的预估行高,包含行间距;实际行会被测量。
inputReadOnlyboolean—只禁止手动输入,仍可在面板中选择。
openboolean—控制面板是否展开。
defaultOpenboolean—面板初始展开状态。
maxTagCountnumber | 'responsive'—最多展示的标签数;responsive 根据可用宽度自动折叠。
tagWrapbooleantrue允许多选标签换行;false 单行显示并自动折叠溢出项。
maxCountnumber—最多可选的数量。
treeExpandedKeysreadonly string[]—受控的展开节点。
onExpand(keys: string[]) => void—展开节点发生变化时调用。
filterTreeNode(option: TreeSelectOption, query: string) => boolean—自定义节点的搜索匹配。
nodeRender(option: TreeSelectOption) => ReactNode—自定义节点展示内容。
cacheKeystring | number—数据版本改变时清空懒加载缓存,并取消旧请求。
multiplefalse | true | booleanfalse多选 / 复选框模式,后者自动开启多选
treeCheckablefalse | boolean | truefalse多选 / 复选框模式,后者自动开启多选
valuestring | null | readonly string[] | readonly string[]null受控 / 初始值;多选使用数组
defaultValuestring | null | readonly string[] | readonly string[]null受控 / 初始值;多选使用数组
onChange(((value: string | null) => void) | ((value: readonly string[]) => void)) | ((value: readonly string[]) => void)—选择变化,清除单选返回 null,多选返回 []
disabledbooleanfalse禁用交互。
requiredbooleanfalse要求整体值非空,复合控件只校验一次。
namestring—原生 FormData 中的字段名。
formstring—关联的原生表单 ID。

TreeSelectOption

属性类型默认值说明
valuestring—必需。唯一值,必填
labelReactNode—必需。展示内容,必填
childrenreadonly TreeSelectOption[]—子选项,结构相同
disabledboolean—禁用交互。
selectableboolean—设为 false 可让分类节点仅用于浏览
disableCheckboxboolean—禁止勾选并阻断联动
iconReactNode—节点图标
searchLabelstring—label 为节点时提供搜索和读屏文字
isLeafboolean—明确指定是否为叶子节点,配合异步加载使用。

类型

可导入以下类型定义属性、组装数据或处理回调。

import type { TreeSelectProps, TreeSelectOption, TreeSelectValue } from '@ifhover/leaf-ui';

使用说明

选项的 value 应唯一且稳定。示例数据:

import type { TreeSelectOption } from '@ifhover/leaf-ui';
export const treeOptions: readonly TreeSelectOption[] = [
  {
    value: 'design',
    label: '设计团队',
    selectable: false,
    children: [
      { value: 'visual', label: '视觉设计' },
      { value: 'product', label: '产品设计' },
      { value: 'archive', label: '归档团队', disabled: true },
    ],
  },
  {
    value: 'engineering',
    label: '研发团队',
    selectable: false,
    children: [
      { value: 'web', label: '前端开发' },
      { value: 'server', label: '服务端开发' },
    ],
  },
];

TreeSelectValue 是 string | readonly string[] | null,可用于组装受控值。复选框默认提交最终子节点;showCheckedStrategy 同时决定显示和回调值。禁用的已有选项不会被清除或父子联动修改。

方向键下进入树,Enter 选择,空格勾选,Escape 关闭。多选时,搜索为空按 Backspace 可移除最后一个可用选项。FormData 在同一字段名下提交多个值,使用 getAll(name) 读取;非受控字段响应表单 reset。