For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt, and this page is available as Markdown at https://ifhover.github.io/leaf-ui/v/0.6.0/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 },
            ];
          }}
        />
      );
    }
    

    选择限制与节点展示

    最多选择两人,只展示一个标签
    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
              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内容宽度浮层宽度 / 最大宽度;至少与触发器等宽
    popupMaxWidthnumber | string420浮层宽度 / 最大宽度;至少与触发器等宽
    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。