When to Use
When the options to select is in tree structure, you could use TreeSelect, e.g. department hierarchy, subject system, category directory and etc.
Demos
How to import
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
</script>
Basic Usage
By default, TreeSelect is in single select mode and each item is selectable.
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const style = { width: '300px' };
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
</script>
<template>
<TreeSelect :dropdownStyle="dropdownStyle" placeholder="请选择" :style="style" :treeData="treeData" />
</template>Multi-choice
You could use multiple to set mode to multi-choice. When all child items are selected, the parent item will be selected.
In multiple mode v-model and defaultValue are arrays. Use leafOnly if you prefer to render leaf nodes only, and the value of v-model and of the change event will also hold leaf node values only.
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
{
label: 'Chengdu',
value: 'Chengdu',
key: '0-0-2',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0',
},
],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0',
},
{
label: 'Canada',
value: 'Canada',
key: '1-1',
},
],
},
];
</script>
<template>
<div>
<TreeSelect :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" multiple placeholder="请选择" style="width: 300px" :treeData="treeData" />
<br />
<br />
<TreeSelect :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" leafOnly multiple placeholder="只渲染叶子节点" style="width: 300px" :treeData="treeData" />
<br />
<br />
</div>
</template>Limit Tags Number
In the multi-selection scenario, maxTagCount can be used to limit the number of tags displayed, and the excess part will be displayed in the form of +N.
Use showRestTagsPopover (>= v2.22.0) to set whether hover +N displays Popover after exceeding maxTagCount, the default is false. Also, popovers can be configured in the restTagsPopoverProps property.
maxTagCount=2:
maxTagCount=2, showRestTagsPopover:
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
{
label: 'Chengdu',
value: 'Chengdu',
key: '0-0-2',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0',
},
],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0',
},
{
label: 'Canada',
value: 'Canada',
key: '1-1',
},
],
},
];
const textStyle = { margin: '20px 0 10px' };
</script>
<template>
<div>
<h4 :style="textStyle">maxTagCount=2:</h4>
<TreeSelect :defaultValue="['Beijing', 'Chengdu', 'Canada']" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :maxTagCount="2" multiple placeholder="当选中标签超过两个将折叠" style="width: 300px" :treeData="treeData" />
<h4 :style="textStyle">maxTagCount=2, showRestTagsPopover:</h4>
<TreeSelect :defaultValue="['Beijing', 'Chengdu', 'Canada']" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :maxTagCount="2" multiple placeholder="hover +N 查看" :restTagsPopoverProps="{ position: 'top' }" showRestTagsPopover style="width: 300px" :treeData="treeData" />
</div>
</template>Searchable
Use filterTreeNode to support search input. By default it searches the label property of the data. You can use treeNodeFilterProp to set another property to search or pass in a function to filterTreeNode to customize search behavior.
You could also use showFilteredOnly if you prefer to display filtered results only.
If you want to get specific information about the search results, listen to the search event. See the API list for its parameters.
Code
<script setup lang="ts">
import { ref } from 'vue';
import { Switch, TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const showFilteredOnly = ref(false);
const treeData: TreeNodeData[] = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{ label: 'Beijing', value: 'Beijing', key: '0-0-0' },
{ label: 'Shanghai', value: 'Shanghai', key: '0-0-1' },
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [{ label: 'Osaka', value: 'Osaka', key: '0-1-0' }],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{ label: 'United States', value: 'United States', key: '1-0' },
{ label: 'Canada', value: 'Canada', key: '1-1' },
],
},
];
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
function onSearch(inputValue: string, filteredExpandedKeys: string[], filteredNodes: TreeNodeData[]) {
console.log('onSearch', inputValue, filteredExpandedKeys, filteredNodes);
}
</script>
<template>
<span id="treeselect-searchable-filtered-only">showFilteredOnly</span>
<Switch v-model="showFilteredOnly" aria-labelledby="treeselect-searchable-filtered-only" size="small" />
<br />
<br />
<TreeSelect :dropdownStyle="dropdownStyle" filterTreeNode placeholder="单选可搜索的" :showFilteredOnly="showFilteredOnly" style="width: 300px" :treeData="treeData" @search="onSearch" />
<br />
<br />
<TreeSelect :dropdownStyle="dropdownStyle" filterTreeNode :maxTagCount="2" multiple placeholder="多选可搜索的" searchPlaceholder="请输入关键字开始搜索" :showFilteredOnly="showFilteredOnly" style="width: 300px" :treeData="treeData" @search="onSearch" />
<br />
<br />
<TreeSelect :dropdownStyle="dropdownStyle" filterTreeNode :maxTagCount="2" multiple placeholder="搜索框autofocus" searchAutoFocus searchPlaceholder="autofocus" :showFilteredOnly="showFilteredOnly" style="width: 300px" :treeData="treeData" @search="onSearch" />
</template>Remote Search
By setting the remote property, you can enable remote search. When enabled, local filtering is skipped on input and only the search event is emitted, allowing users to handle remote data fetching and update treeData (only a new array updates it).
Code
<script setup lang="ts">
import { ref, shallowRef } from 'vue';
import { TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const value = ref<string>();
const treeData = shallowRef<TreeNodeData[]>([]);
function onSearch(inputValue: string) {
if (!inputValue) {
treeData.value = [];
return;
}
setTimeout(() => {
treeData.value = [
{ label: `${inputValue} - 结果1`, value: `${inputValue}-1`, key: `${inputValue}-1` },
{ label: `${inputValue} - 结果2`, value: `${inputValue}-2`, key: `${inputValue}-2` },
{ label: `${inputValue} - 结果3`, value: `${inputValue}-3`, key: `${inputValue}-3` },
];
}, 500);
}
</script>
<template>
<TreeSelect v-model="value" filterTreeNode placeholder="请输入关键字进行远程搜索" remote style="width: 300px" :treeData="treeData" @search="onSearch" />
</template>Search Box Position
You can use searchPosition to set the position of the search box, optional: dropdown (default), trigger.
When the input box is at trigger:
- The placeholder of the search box is controlled by
placeholder; - When
showClear=true, click the clear button of the input box, the inputValue and value will be cleared at the same time.
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0',
},
],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0',
},
{
label: 'Canada',
value: 'Canada',
key: '1-1',
},
],
},
];
</script>
<template>
<TreeSelect :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" filterTreeNode placeholder="单选" searchPosition="trigger" style="width: 300px" :treeData="treeData" />
<br />
<br />
<TreeSelect :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" filterTreeNode :maxTagCount="2" multiple placeholder="多选" searchPosition="trigger" style="width: 300px" :treeData="treeData" />
</template>Wrap tags in trigger (triggerTagWrap)
In multiple + searchable + searchPosition="trigger" mode, if there are many selected items or the input is long, the trigger may prefer to keep a single-line layout by default.
Turn on triggerTagWrap to allow selected tags to wrap into multiple lines within the trigger.
Code
<script setup lang="ts">
import { TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const treeData: TreeNodeData[] = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{ label: 'Beijing', value: 'Beijing', key: '0-0-0' },
{ label: 'Shanghai', value: 'Shanghai', key: '0-0-1' },
{ label: 'Shenzhen', value: 'Shenzhen', key: '0-0-2' },
{ label: 'Guangzhou', value: 'Guangzhou', key: '0-0-3' },
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [{ label: 'Osaka', value: 'Osaka', key: '0-1-0' }],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{ label: 'United States', value: 'United States', key: '1-0' },
{ label: 'Canada', value: 'Canada', key: '1-1' },
],
},
];
const defaultValue = ['Beijing', 'Shanghai', 'Shenzhen', 'Guangzhou'];
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
</script>
<template>
<TreeSelect :defaultValue="defaultValue" :dropdownStyle="dropdownStyle" filterTreeNode multiple placeholder="请选择多个选项或输入长文本" searchPosition="trigger" style="width: 260px" :treeData="treeData" triggerTagWrap />
</template>Size
You can set the size by size, one of: 'small'、'default'、'large'
Code
<script setup lang="ts">
import { TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const treeData: TreeNodeData[] = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{ label: '北京', value: 'Beijing', key: '0-0-0' },
{ label: '上海', value: 'Shanghai', key: '0-0-1' },
],
},
],
},
{ label: '北美洲', value: 'North America', key: '1' },
];
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
</script>
<template>
<div>
<TreeSelect :dropdownStyle="dropdownStyle" multiple placeholder="small" size="small" style="width: 300px" :treeData="treeData" />
<br />
<br />
<TreeSelect :dropdownStyle="dropdownStyle" multiple placeholder="default" size="default" style="width: 300px" :treeData="treeData" />
<br />
<br />
<TreeSelect :dropdownStyle="dropdownStyle" multiple placeholder="large" size="large" style="width: 300px" :treeData="treeData" />
</div>
</template>Default Expand All
Both defaultExpandAll and expandAll can set the default expanded/collapsed state of TreeSelect. The difference between the two is that defaultExpandAll only takes effect during initialization, while expandAll will take effect not only during initialization, but also when the data (treeData) is dynamically updated.
In the demo below, after TreeData is updated, defaultExpandAll becomes invalid, and expandAll still takes effect.
Code
<script setup lang="ts">
import { onBeforeUnmount, onMounted, shallowRef } from 'vue';
import { TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const source: TreeNodeData[] = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const firstStyle = { width: '300px', marginBottom: '20px' };
const secondStyle = { width: '300px' };
const data = shallowRef<TreeNodeData[]>([]);
let timer: ReturnType<typeof setTimeout> | undefined;
onMounted(() => {
timer = setTimeout(() => {
data.value = source;
}, 500);
});
onBeforeUnmount(() => clearTimeout(timer));
</script>
<template>
<TreeSelect expandAll placeholder="expandAll" :style="firstStyle" :treeData="data" />
<TreeSelect defaultExpandAll placeholder="defaultExpandAll" :style="secondStyle" :treeData="data" />
</template>Disabled
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const style = { width: '300px' };
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
</script>
<template>
<div>
<TreeSelect disabled :dropdownStyle="dropdownStyle" placeholder="禁用下拉菜单" :style="style" :treeData="treeData" />
<br />
<br />
<TreeSelect defaultValue="Shanghai" disabled :dropdownStyle="dropdownStyle" :style="style" :treeData="treeData" />
<br />
<br />
<TreeSelect :defaultValue="['Shanghai', 'North America']" disabled :dropdownStyle="dropdownStyle" multiple :style="style" :treeData="treeData" />
</div>
</template>Disable Strictly
You can use disableStrictly to enable strict disabling. After enabling strict disabling, when the node is disabled, the selected state cannot be changed through the relationship between the child or the parent.
Take the following demo as an example, the node "China" is strictly disabled. Therefore, when we change the selected state of its parent node "Asia", it will not affect the selected state of the node "China".
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
disabled: true,
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: '日本',
value: 'Japan',
key: '0-1',
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const style = { width: '300px' };
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
</script>
<template>
<div>
<TreeSelect :defaultValue="['Shanghai']" disableStrictly :dropdownStyle="dropdownStyle" multiple :style="style" :treeData="treeData" />
</div>
</template>Controlled Component
Bind the selected value with v-model to use TreeSelect as a controlled component; changes are written back through update:modelValue. You can also pass modelValue and listen to the change event.
Code
<script setup lang="ts">
import { ref } from 'vue';
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const style = { width: '300px' };
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
const value = ref<string | undefined>('Shanghai');
</script>
<template>
<TreeSelect v-model="value" :dropdownStyle="dropdownStyle" placeholder="请选择" :style="style" :treeData="treeData" />
</template>Checked RelationShip
Version: >= 2.5.0
In multiple, checkRelation can be used to set the type of node selection relationship, optional: 'related' (default), 'unRelated'. When the selection relationship is 'unRelated', it means that selections between nodes do not affect each other.
Code
<script setup lang="ts">
import { TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const style = { width: '300px' };
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
</script>
<template>
<TreeSelect checkRelation="unRelated" :defaultValue="['Asia']" :dropdownStyle="dropdownStyle" multiple :style="style" :treeData="treeData" />
</template>Controlled Expansion with Search
Bind the expanded nodes with v-model:expandedKeys to make the expansion controlled; you can also pass expandedKeys and listen to the expand event. When the expansion is controlled, if the filterTreeNode is turned on and the search is performed, the node will no longer be automatically expanded. At this time, the expansion of the node is completely controlled by the expandedKeys. You can use the parameter filteredExpandedKeys of the search event to realize the search expansion effect when the expansion is controlled.
Code
<script setup lang="ts">
import { ref } from 'vue';
import { TreeSelect } from '@fibrous/semi-ui-vue';
const expandedKeys = ref<string[]>([]);
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: '日本',
value: 'Japan',
key: '0-1',
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
function onSearch(_inputValue: string, filteredExpandedKeys: string[]) {
expandedKeys.value = [...filteredExpandedKeys, ...expandedKeys.value];
}
</script>
<template>
<TreeSelect v-model:expandedKeys="expandedKeys" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" filterTreeNode style="width: 300px" :treeData="treeData" @search="onSearch" />
</template>Virtualized TreeSelect
If you need to render large sets of tree structured data, you could use virtualized tree. In virtualized mode, animation / motion is disabled for better performance.
The property virtualize is an object consisting of the following values:
- height: Height of the dropDown, If passed in as a string, computed height should not be zero for render purpose, in other words, parent node should have offsetHeight. Pass in a number recommended.
- width: Width of the dropDown.
- itemSize: Height for each line of treeNode, required
If tree is searchable, you could also turn on showFilteredOnly to reduce time of rendering for results.
Code
<script setup lang="ts">
import { ref, shallowRef } from 'vue';
import { Button, TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const treeData = shallowRef<TreeNodeData[]>([]);
const total = ref(0);
// x: nodes per level. y: nodes with children per level. z: depth (0 is one level).
function generateData(x = 5, y = 4, z = 3) {
const data: TreeNodeData[] = [];
function fill(level: number, preKey: string, nodes: TreeNodeData[]) {
const parents: string[] = [];
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`;
nodes.push({ label: `${key}-标签`, key: `${key}-key`, value: `${key}-value` });
if (i < y) {
parents.push(key);
}
}
if (level < 0) {
return;
}
parents.forEach((key, index) => {
const children: TreeNodeData[] = [];
nodes[index].children = children;
fill(level - 1, key, children);
});
}
fill(z, '0', data);
let count = 0;
for (let n = z + 1; n >= 0; n--) {
count += x * y ** n;
}
return { data, count };
}
function onGen() {
const { data, count } = generateData();
treeData.value = data;
total.value = count;
}
const dropdownStyle = { overflow: 'hidden' };
// Dropdown height 300 minus the search box, minus the 8 * 2 padding; a set dropdown height fills the remaining space.
const virtualize = { itemSize: 28, height: 236 };
</script>
<template>
<div style="padding: 0 20px">
<Button @click="onGen">生成数据: </Button>
<span>共 {{ total }} 个节点</span>
<br />
<br />
<TreeSelect v-if="treeData.length" :dropdownStyle="dropdownStyle" filterTreeNode placeholder="Please select" showFilteredOnly style="width: 300px" :treeData="treeData" :virtualize="virtualize" />
</div>
</template>Dynamic Update of Data
Code
<script setup lang="ts">
import { shallowRef } from 'vue';
import { Button, TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const style = { width: '300px' };
const dropdownStyle = { maxHeight: '400px', overflow: 'auto' };
const treeData = shallowRef<TreeNodeData[]>([]);
function add() {
const itemLength = Math.floor(Math.random() * 5) + 1;
treeData.value = Array.from({ length: itemLength }, (_, i) => {
const length = Math.floor(Math.random() * 3);
const children = Array.from({ length }, (_, ci) => ({
key: `${i}-${ci}`,
label: `Leaf-${i}-${ci}`,
value: `${i}-${ci}`,
}));
return {
key: `${i}`,
label: `Item-${i}`,
value: `${i}`,
children,
};
});
}
</script>
<template>
<TreeSelect :dropdownStyle="dropdownStyle" placeholder="请选择" :style="style" :treeData="treeData" />
<br />
<br />
<Button @click="add">动态改变数据</Button>
</template>Load Data Asynchronously
You could use loadData to load treeData asynchronously on node expansion. Notice isLeaf is required to mark node as leaf in treeData.
Code
<script setup lang="ts">
import { shallowRef } from 'vue';
import { TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const treeData = shallowRef<TreeNodeData[]>([
{
label: 'Expand to load',
value: '0',
key: '0',
},
{
label: 'Expand to load',
value: '1',
key: '1',
},
{
label: 'Leaf Node',
value: '2',
key: '2',
isLeaf: true,
},
]);
function updateTreeData(list: TreeNodeData[], key: string | undefined, children: TreeNodeData[]): TreeNodeData[] {
return list.map((node) => {
if (node.key === key) {
return { ...node, children };
}
if (node.children) {
return { ...node, children: updateTreeData(node.children, key, children) };
}
return node;
});
}
function loadData({ key, children }: TreeNodeData) {
return new Promise<void>((resolve) => {
if (children) {
resolve();
return;
}
setTimeout(() => {
treeData.value = updateTreeData(treeData.value, key, [
{
label: 'Child Node',
key: `${key}-0`,
},
{
label: 'Child Node',
key: `${key}-1`,
},
]);
resolve();
}, 1000);
});
}
</script>
<template>
<TreeSelect :loadData="loadData" placeholder="请选择" style="width: 300px" :treeData="treeData" />
</template>Custom Trigger
If the default trigger style cannot meet your needs, you can use the #trigger slot to customize the display of the select box.
The slot parameters are as follows, typed as TreeSelectTriggerSlotProps:
interface TreeSelectTriggerSlotProps {
componentProps: TreeSelectProps; // TreeSelect props
disabled: boolean; // disabled status
value: TreeNodeData[]; // data of the selected node
inputValue: string; // value of the input box
placeholder?: string; // placeholder
// Clears the value; pass the click event when bound to a control inside
// the trigger, so that the click does not also open the dropdown
onClear: (event?: MouseEvent) => void;
// Called when deleting a single item, with the key of the item
onRemove: (key: string) => void;
// Starts the search when the value of your own Input is updated;
// filterTreeNode must be non-false and searchPosition must be 'trigger'
onSearch: (inputValue: string) => void;
}
Code
<script setup lang="ts">
import { Tag, TagInput, TreeSelect, type TreeNodeData } from '@fibrous/semi-ui-vue';
const treeData: TreeNodeData[] = [
{
label: '亚洲',
value: '亚洲',
key: '0',
children: [
{
label: '中国',
value: '中国',
key: '0-0',
children: [
{ label: '北京', value: '北京', key: '0-0-0' },
{ label: '上海', value: '上海', key: '0-0-1' },
],
},
],
},
{ label: '北美洲', value: '北美洲', key: '1' },
];
function onChange(value: unknown) {
console.log('onChange', value);
}
</script>
<template>
<TreeSelect filterTreeNode multiple placeholder="Custom Trigger" searchPosition="trigger" style="width: 300px" :treeData="treeData" @change="onChange">
<template #trigger="{ value, inputValue, onSearch, onRemove }">
<TagInput :inputValue="inputValue" :modelValue="value.flatMap((item) => item.key ?? [])" @inputChange="onSearch">
<template #tag="{ value: key }">
<Tag :key="key" closable style="margin-inline-start: 2px" :tagKey="key" @close="onRemove(key)">
{{ value.find((item) => item.key === key)?.label }}
</Tag>
</template>
</TagInput>
</template>
</TreeSelect>
</template>Custom Rendering Selected Item
You can use the #selectedItem and #tag slots to customize the rendering structure of the selected items in the selection box. Both take the same parameters, typed as TreeSelectSelectedItemSlotProps: item (the node data), index, disabled and onClose (removes the tag, or clears the selection in single mode).
- In single mode the content of
#selectedItemis what the select box shows; empty content shows theplaceholder - In multiple mode the content of
#selectedItemis rendered inside the built-in Tag (with background color and close button);#tagreplaces the whole Tag and takes precedence over#selectedItem, so bindonCloseto your own Tag when it needs a close button - In multiple mode, empty content from either slot leaves the tag out
单选
多选 + 标签内渲染
多选 + 替换整个标签
Code
<script setup lang="ts">
import { Tag, TreeSelect } from '@fibrous/semi-ui-vue';
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
{
label: '南美洲',
value: 'South America',
key: '2',
},
{
label: '南极洲',
value: 'Antarctica',
key: '3',
},
];
</script>
<template>
<h4>单选</h4>
<TreeSelect style="width: 300px" :treeData="treeData">
<template #selectedItem="{ item }">{{ item.label }}</template>
</TreeSelect>
<h4>多选 + 标签内渲染</h4>
<TreeSelect multiple style="width: 300px" :treeData="treeData">
<template #selectedItem="{ item }">{{ item.label }}</template>
</TreeSelect>
<h4>多选 + 替换整个标签</h4>
<TreeSelect :maxTagCount="2" multiple style="width: 300px" :treeData="treeData">
<template #tag="{ item, onClose }">
<Tag closable color="white" @close="onClose">{{ item.value }}</Tag>
</template>
</TreeSelect>
</template>API Reference
TreeSelect
Props
| Property | Description | Type | Default |
|---|---|---|---|
| modelValue | Value of the selected node (its key when it has no value), bound with v-model; an array only when multiple. Passing it makes the component controlled, and undefined clears the selection. | TypeByMultiple<Multiple, T | undefined, T[]> | undefined |
| defaultValue | The initially selected items, read once on mount; an array only when multiple. | TypeByMultiple<Multiple, T | undefined, T[]> | semiGlobalDefault("TreeSelect", "defaultValue") |
| multiple | Whether several nodes can be selected. A parent is checked automatically once all its children are. | Multiple | undefined |
| treeData | Node data; keys are unique across the tree. Only a new array updates the options, changes made in place are not seen. | TreeNodeData[] | semiDefault("TreeSelect", "treeData", []) |
| keyMaps | Custom field names for key, label, value, disabled, children, isLeaf and icon in a node. When label is mapped and search is on, set treeNodeFilterProp to one of the keys in treeData or provide filterTreeNode. | KeyMapProps | semiGlobalDefault("TreeSelect", "keyMaps") |
| treeNodeLabelProp | The node field shown in the trigger, label by default. | string | semiDefault("TreeSelect", "treeNodeLabelProp", "label") |
| treeNodeFilterProp | The node field matched against the search input, label by default. | string | semiDefault("TreeSelect", "treeNodeFilterProp", "label") |
| filterTreeNode | Whether to filter by the input: true matches the field named by treeNodeFilterProp, or pass a custom matching function. | Typeboolean | ((inputValue: string, treeNodeString: string, data?: TreeNodeData | undefined) => boolean) | undefined |
| showFilteredOnly | Shows only the filtered nodes while searching. | boolean | semiDefault("TreeSelect", "showFilteredOnly", false) |
| searchPosition | Where the search box sits: dropdown in the panel, trigger inside the select box. | TreeSelectSearchPosition | semiDefault("TreeSelect", "searchPosition", "dropdown") |
| searchPlaceholder | Placeholder of the search box in the dropdown. | string | semiGlobalDefault("TreeSelect", "searchPlaceholder") |
| searchAutoFocus | Focuses the search box automatically. | boolean | semiDefault("TreeSelect", "searchAutoFocus", false) |
| showSearchClear | Whether the search box shows a clear button. | boolean | semiDefault("TreeSelect", "showSearchClear", true) |
| remote | Enables remote search: typing skips local filtering and only emits search, so the caller can fetch data and update treeData. | boolean | semiDefault("TreeSelect", "remote", false) |
| expandAll | Expands every node, and keeps doing so when treeData changes. | boolean | semiDefault("TreeSelect", "expandAll", false) |
| defaultExpandAll | Expands every node on mount. Later changes of treeData do not affect it; use expandAll for that. | boolean | semiDefault("TreeSelect", "defaultExpandAll", false) |
| defaultExpandedKeys | Nodes expanded initially, showing their direct children. | string[] | semiGlobalDefault("TreeSelect", "defaultExpandedKeys") |
| expandedKeys | Expanded nodes, bound with v-model:expandedKeys. Passing it makes expansion fully controlled. | string[] | semiGlobalDefault("TreeSelect", "expandedKeys") |
| autoExpandParent | Whether the parents of the nodes in expandedKeys expand automatically when expandedKeys changes; they always do on mount. When on, controlled expansion collapses a parent only after its expanded children are collapsed. | boolean | semiDefault("TreeSelect", "autoExpandParent", false) |
| expandAction | How a node expands: false only through the arrow, click on a click, doubleClick on a double click. The keyboard does not use it. | ExpandAction | semiDefault("TreeSelect", "expandAction", false) |
| motionExpand | Whether expanding and collapsing nodes are animated; animation is off for a virtualized list. | boolean | semiDefault("TreeSelect", "motionExpand", true) |
| loadData | Loads the children of a node and returns a Promise; a node without isLeaf shows the expand arrow while it is set. After a rejection the node can be expanded again to retry. | Type((data: TreeNodeData) => Promise<void>) | undefined |
| loadedKeys | Nodes already loaded, used with loadData and bound with v-model:loadedKeys. | string[] | semiGlobalDefault("TreeSelect", "loadedKeys") |
| leafOnly | In multiple mode, the value, the payload of change and the displayed tags hold leaf nodes only. | boolean | semiDefault("TreeSelect", "leafOnly", false) |
| checkRelation | How the checked states of nodes relate in multiple mode: related links parents and children, unRelated keeps them independent. | CheckRelation | semiDefault("TreeSelect", "checkRelation", "related") |
| disableStrictly | Strict disabling: a disabled node cannot change state through the selection of its parent or children. | boolean | semiDefault("TreeSelect", "disableStrictly", false) |
| autoMergeValue | When a parent is selected the value leaves out its descendants; applies when leafOnly is false. | boolean | semiDefault("TreeSelect", "autoMergeValue", true) |
| changeWithObject | A boolean attribute, not an event: when true the payload of modelValue and change is the node object instead of its value; a controlled modelValue and defaultValue must then be objects with a value. | boolean | semiDefault("TreeSelect", "changeWithObject", false) |
| maxTagCount | The most tags shown in multiple mode; the rest collapse into +N. | number | semiGlobalDefault("TreeSelect", "maxTagCount") |
| showRestTagsPopover | Whether hovering +N shows the remaining tags in a Popover once maxTagCount is exceeded. | boolean | semiDefault("TreeSelect", "showRestTagsPopover", false) |
| restTagsPopoverProps | Configuration of the Popover for the remaining tags; see Popover. | PopoverProps | semiGlobalDefault("TreeSelect", "restTagsPopoverProps") |
| labelEllipsis | Whether an overflowing label is truncated; on by default for a virtualized list. | boolean | semiGlobalDefault("TreeSelect", "labelEllipsis") |
| showLine | Shows connecting lines between nodes in the dropdown. | boolean | semiDefault("TreeSelect", "showLine", false) |
| virtualize | List virtualization for many nodes: height, width and itemSize (required). Animation is off once enabled. | Virtualize | semiGlobalDefault("TreeSelect", "virtualize") |
| placeholder | Placeholder of the select box. | string | semiGlobalDefault("TreeSelect", "placeholder") |
| disabled | Whether the component is disabled. | boolean | semiDefault("TreeSelect", "disabled", false) |
| size | Size of the select box: small, default or large. | Size | semiDefault("TreeSelect", "size", "default") |
| borderless | Borderless mode. | boolean | semiDefault("TreeSelect", "borderless", false) |
| validateStatus | Validation status, which only affects the style: default, warning or error. | "default" | "error" | "warning" | "success" | semiGlobalDefault("TreeSelect", "validateStatus") |
| insetLabelId | The id of the element around the insetLabel slot, for aria-labelledby to point at; an internal id is used when omitted. | string | undefined |
| showClear | Whether the select box shows a clear button when it has a value. | boolean | semiDefault("TreeSelect", "showClear", false) |
| clickToHide | Whether the dropdown closes after a node is selected in single mode. | boolean | semiDefault("TreeSelect", "clickToHide", true) |
| clickTriggerToHide | Whether clicking the select box closes the open dropdown. | boolean | semiDefault("TreeSelect", "clickTriggerToHide", true) |
| defaultOpen | Opens the dropdown on mount. | boolean | semiDefault("TreeSelect", "defaultOpen", false) |
| motion | Whether the dropdown animates in and out. | boolean | semiDefault("TreeSelect", "motion", true) |
| autoAdjustOverflow | Whether the dropdown flips when it would be clipped. | boolean | semiDefault("TreeSelect", "autoAdjustOverflow", true) |
| position | Position of the dropdown; see the position of Tooltip. | Type"top" | "bottom" | "left" | "right" | "topLeft" | "topRight" | "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "bottomLeft" | "bottomRight" | "leftTopOver" | "rightTopOver" | "leftBottomOver" | "rightBottomOver" | semiGlobalDefault("TreeSelect", "position") |
| stopPropagation | Whether click events on the dropdown stop propagating; a string is treated as a boolean. | string | boolean | semiDefault("TreeSelect", "stopPropagation", true) |
| dropdownClassName | Class of the dropdown. | string | semiGlobalDefault("TreeSelect", "dropdownClassName") |
| dropdownStyle | Style of the dropdown. | StyleValue | semiGlobalDefault("TreeSelect", "dropdownStyle") |
| dropdownMatchSelectWidth | Whether the minimum width of the dropdown equals the width of the select box. | boolean | semiDefault("TreeSelect", "dropdownMatchSelectWidth", true) |
| optionListStyle | Style of the node list, the element with role="tree". | StyleValue | semiGlobalDefault("TreeSelect", "optionListStyle") |
| preventScroll | Whether focusing stops the browser from scrolling the page to the newly focused element. | boolean | semiGlobalDefault("TreeSelect", "preventScroll") |
| triggerTagWrap | Lets the tags in the trigger wrap onto more lines; applies with multiple, filterTreeNode and searchPosition set to trigger. | boolean | semiDefault("TreeSelect", "triggerTagWrap", false) |
Events
| Event | Description | Callback parameters |
|---|---|---|
| update:modelValue | Emitted when the selection changes; used by v-model. The payload is undefined once cleared. | Type[value: ByMultiple<Multiple, T | undefined, T[]>] |
| change | Emitted when the selection changes, with the value, the node and the triggering event; the value equals that of update:modelValue. It is undefined once cleared and arrays in multiple mode; the event is null for a closed tag; with changeWithObject the value and the node are the same node object. It shadows the native event of the same name on the root element. | Type[value: ByMultiple<Multiple, T | undefined, T[]>, node: ByMultiple<Multiple, TreeNodeData | undefined, TreeNodeData[]>, event: TreeSelectChangeEvent] |
| update:expandedKeys | Emitted when the expanded nodes change; used by v-model:expandedKeys. | [expandedKeys: string[]] |
| expand | Emitted when a node expands or collapses; info holds expanded and node. | Type[expandedKeys: string[], info: { expanded: boolean; node: TreeNodeData; }] |
| update:loadedKeys | Emitted when the loaded nodes change; used by v-model:loadedKeys. | [loadedKeys: string[]] |
| load | Emitted when a node has loaded; loadedKeys is the Set of keys of loaded nodes. | Type[loadedKeys: Set<string>, node: TreeNodeData] |
| select | Emitted when a node is selected or deselected, with its key, whether it is selected and its data. It shadows the native event of the same name on the root element. | [selectedKey: string, selected: boolean, node: TreeNodeData] |
| search | Emitted when the search input changes; filteredExpandedKeys are the nodes expanded by the search or by modelValue and defaultValue, which controlled expansion can use to show the results; filteredNodes are the nodes that matched. | Type[input: string, filteredExpandedKeys: string[], filteredNodes: TreeNodeData[]] |
| dropdownVisibleChange | Emitted when the dropdown opens or closes. Deactivating the component inside KeepAlive closes it and emits false, without a blur. | [visible: boolean] |
| focus | Emitted when focus enters the select box (including its search box and clear button) or the dropdown from outside, with a FocusEvent; moving between them does not emit again. It also fires when a click or key reopens the dropdown after a selection closed it, with that click or key event, and null for searchAutoFocus on mount. It is not emitted while disabled. It shadows the native event of the same name on the root element. | [event: MouseEvent | KeyboardEvent | FocusEvent | null] |
| blur | Emitted once after each focus: a FocusEvent when focus leaves the select box and the dropdown, a MouseEvent for a click outside, and the click or key event when a selection closes the dropdown. It shadows the native event of the same name on the root element. | [event: MouseEvent | KeyboardEvent | FocusEvent] |
| clear | Emitted when the clear button is used by click or keyboard; the payload is the triggering event, null when cleared through a slot function without an event. | [event: TreeSelectChangeEvent] |
| keydown | A key press, emitted before the TreeSelect handles the key. It shadows the native event of the same name on the root element. | [event: KeyboardEvent] |
Slots
| Slot | Description | Scope parameters |
|---|---|---|
| label | Content of a node's label. Search still matches the label text in treeData. | TreeLabelSlotProps |
| icon | A node's icon, which can differ by node data. | TreeIconSlotProps |
| expandIcon | The expand icon. A single element gets the class and the click that expands; the parameters can also be bound by hand. | TreeExpandIconSlotProps |
| fullLabel | Content of the whole row. TreeSelect provides the row element carrying the id, role and state; the slot holds only what is inside. | TreeFullLabelSlotProps |
| selectedItem | A selected item: the content shown in the select box in single mode, or the content of a built-in tag in multiple mode; empty content shows the placeholder in single mode and leaves the tag out in multiple mode. | TreeSelectSelectedItemSlotProps |
| tag | Replaces each tag in multiple mode, taking precedence over selectedItem; empty content leaves the tag out. | TreeSelectSelectedItemSlotProps |
| trigger | Replaces the content of the trigger; the parameters hold the selected nodes, the input value, and the onSearch, onClear and onRemove methods. | TypeTreeSelectTriggerSlotProps<T, Multiple> |
| search | Replaces the search box. The parameters can be bound to a Semi Input with v-bind, and inputRef must be bound; an empty slot hides the search box. | TreeSelectSearchSlotProps |
| prefix | Content before the value in the select box. | any |
| suffix | Content after the value in the select box. | any |
| insetLabel | A label inside the select box, which also names the dropdown tree. | any |
| arrowIcon | The dropdown arrow on the right; an empty slot hides it. With showClear and a value, hovering shows the clear button first. | any |
| clearIcon | The icon of the clear button, used when showClear is true; empty content keeps the default icon. | any |
| emptyContent | Content shown when there are no nodes or the search finds none; an empty slot hides the empty state. | any |
| outerTopSlot | Content at the top of the dropdown, beside the node list; it takes the place of the search box in the dropdown. | any |
| outerBottomSlot | Content at the bottom of the dropdown, beside the node list. | any |
Exposes
| Name | Description | Type |
|---|---|---|
| None |
The Vue TreeSelect has no className property: undeclared attributes such as class, style and data-* land on the root element, while aria-label, aria-labelledby, aria-describedby, aria-errormessage, aria-invalid and aria-required land on the current combobox (see ARIA). focus, blur, change, select and keydown are events of the component and shadow the native events of the same name on the root element.
TreeNodeData
Key for
TreeNodeDatais required and must be unique,labelcan be duplicated. Value is not required. In this case, the value property inv-model,defaultValue, thechangeevent andchangeWithObjectwill point to key property. To ensure everything behave as expected, keep a consistency of whether to have value or not to have value.
| Properties | Instructions | type | Default |
|---|---|---|---|
| value | Value | string|number | - |
| label | Displayed label; use the #label slot for custom content | string|number | - |
| disabled | Disabled, supported in multiple select mode | boolean | false |
| key | Required and must be unique | string | - |
| isLeaf | Whether it is a leaf node | boolean | - |
| children | Child nodes | TreeNodeData[] | - |
The icon of a node comes from the #icon slot and is not declared in the data.
Methods
TreeSelect exposes the search(value) and close() methods through a template ref, typed as TreeSelectHandle. search searches as if the value were typed, opening the dropdown first, and filterTreeNode must be set; close closes the dropdown. If you need to customize the search box externally, call search when the value of the custom search box changes to change the filtering results.
<script setup lang="ts">
import { useTemplateRef } from 'vue';
import { TreeSelect } from '@fibrous/semi-ui-vue';
import type { TreeSelectHandle } from '@fibrous/semi-ui-vue';
const treeSelect = useTemplateRef<TreeSelectHandle>('treeSelect');
const search = (value: string) => treeSelect.value?.search(value);
</script>
<template>
<TreeSelect ref="treeSelect" filterTreeNode :treeData="treeData" />
</template>
Accessibility
ARIA
- Following the ARIA 1.2 combobox pattern, exactly one element is the combobox. Its name comes from, in order of priority:
aria-labelledby,aria-label, the rendered insetLabel (#insetLabelin Vue; withoutinsetLabelIdthe component generates the id; with a prefix the insetLabel is not rendered and does not name it), and otherwise the name in the locale:- Without search, or with
searchPosition="dropdown", the trigger is a select-only combobox. The search input in the dropdown stays a text box witharia-controls,aria-autocompleteandaria-activedescendant - With
searchPosition="trigger", the search input is the combobox and the only Tab stop, witharia-autocomplete="list"; the trigger has no role. In single mode the input is empty until the user types, so the selected text is linked to it as its description (aria-describedby). Clicking anywhere on the trigger moves focus to the input;
- Without search, or with
- TreeSelect allows users to set
aria-describedby,aria-errormessage,aria-invalid,aria-labelledby,aria-required, in addition, Form will automatically set these properties for Form.TreeSelect; - The
role="tree"list in the dropdown uses the same name source as the combobox: the samearia-labelledbyids, the samearia-labelor the same insetLabel; with none of them it takes the name in the locale, like the combobox;
aria-label,aria-labelledby,aria-describedby,aria-errormessage,aria-invalidandaria-requiredland on the current combobox: the root element without search, the nativeinputof the search box in a single-choice trigger search, and the tag input in a multi-choice trigger search. Witharia-labelledbyset, the combobox no longer adds the defaultaria-label; with only#insetLabel, the combobox'saria-labelledbypoints at it;- The nodes in the dropdown are the same as in Tree:
role="treeitem"witharia-level,aria-setsize,aria-posinsetandaria-disabled, andaria-expandedon nodes that can expand; a single-choice TreeSelect usesaria-selected, a multi-choice one usesaria-checked(mixedwhen half checked). The content of#fullLabelis wrapped in anlicarrying theid,role="treeitem"and these states;
- The expand arrow and the checkbox in front of a node only picture its state: they are hidden from screen readers and take no focus.
Keyboard Interaction
TreeSelect follows the WAI-ARIA Combobox pattern with a tree popup: focus always stays on the trigger or the search input, aria-activedescendant points at the current node, and the current node shows the focus ring. There is no current node when the dropdown opens.
- While the dropdown is closed:
ArrowDown,ArrowUp,EnterandSpaceopen it;HomeandEndopen it and move to the first or last visible node ArrowDown,ArrowUp: move to the next or previous visible node; the firstArrowDownmoves to the first node;Home,End: move to the first or last visible nodeArrowRight: expand a collapsed node; on an expanded node, move to its first child (swapped withArrowLeftin RTL)ArrowLeft: collapse an expanded node; otherwise move to the parentEnter,Space: select the current node, or check and uncheck it in a multi-choice TreeSelect; disabled nodes do not respond- Typing characters: while the dropdown is open, move to the next visible node after the current one whose label starts with the typed text; characters typed in quick succession form one search string. A closed dropdown ignores them
Esc: close the dropdown
While focus is in a search input, only ArrowDown, ArrowUp and Enter move and select; the other keys (including characters, Space, Home, End, ArrowLeft and ArrowRight) edit the text.
The parameters of the #search slot include these ARIA attributes (aria-activedescendant, aria-controls, aria-autocomplete and the name; on the trigger, the whole set of combobox attributes including role and aria-expanded); bind the whole parameter object onto the input (a Semi Input) with v-bind, or screen readers do not announce the current node. inputRef must be bound to the input too; it lets a click on the selected text inside the trigger move focus to it.
With showClear, a selected value or search text, and no disabled, the trigger renders a clear button. It is a native button named "Clear TreeSelect value" from the locale, shown on hover, while the dropdown is open, or while focus is inside the TreeSelect. From the trigger or the search input, Tab moves to the clear button; Enter or Space clears, as a mouse click does, and the focus goes back to the trigger or the search input. In multiple mode Backspace in the search input also removes tags.
Demo:
<TreeSelect aria-label="example treeSelect" :treeData="treeData" />
Design Tokens
| Sass variable | Value | Usage |
|---|---|---|
| $color-treeSelect_default-bg-default | var(--semi-color-fill-0) | 树选择器选择框背景颜色 - 默认 |
| $color-treeSelect_default-bg-hover | var(--semi-color-fill-1) | 树选择器选择框背景颜色 - 悬停 |
| $color-treeSelect_default-bg-active | var(--semi-color-fill-2) | 树选择器选择框背景颜色 - 按下 |
| $color-treeSelect_default-bg-focus | var(--semi-color-fill-0) | 树选择器选择框背景颜色 - 选中 |
| $color-treeSelect_default-border-default | transparent | 树选择器选择框描边颜色 - 默认 |
| $color-treeSelect_selection-text-default | var(--semi-color-text-0) | 树选择器选择框回填内容文本颜色 - 默认 |
| $color-treeSelect_default-icon-default | var(--semi-color-text-2) | 树选择器选择框图标颜色 - 默认 |
| $color-treeSelect_default-icon-hover | var(--semi-color-primary-hover) | 树选择器选择框清空按钮颜色 - 悬停 |
| $color-treeSelect_default-icon-active | var(--semi-color-primary-active) | 树选择器选择框清空按钮颜色 - 按下 |
| $color-treeSelect_default-border-hover | transparent | 树选择器选择框描边颜色 - 悬浮 |
| $color-treeSelect_default-border-focus | var(--semi-color-focus-border) | 树选择器选择框描边颜色 - 选中 |
| $color-treeSelect_search-border-default | var(--semi-color-fill-0) | 树选择器菜单搜索框描边颜色 - 默认 |
| $color-treeSelect_tag_disabled-bg-default | transparent | 禁用树选择器菜单标签背景颜色 |
| $color-treeSelect_input_disabled-bg-default | var(--semi-color-disabled-fill) | 禁用树选择器选择框背景颜色 |
| $color-treeSelect_input_disabled-text-default | var(--semi-color-disabled-text) | 禁用树选择器选择框文本颜色 |
| $color-treeSelect_input_disabled-bg-hover | var(--semi-color-disabled-fill) | 禁用树选择器选择框背景颜色 - 悬浮 |
| $color-treeSelect_input_placeholder-text-default | var(--semi-color-text-2) | 树选择器选择框占位文本颜色 |
| $color-treeSelect_warning-bg-default | var(--semi-color-warning-light-default) | 警告树选择器选择框背景颜色 - 默认 |
| $color-treeSelect_warning-border-default | var(--semi-color-warning-light-default) | 警告树选择器选择框描边颜色 - 默认 |
| $color-treeSelect_warning-bg-hover | var(--semi-color-warning-light-hover) | 警告树选择器选择框背景颜色 - 悬浮 |
| $color-treeSelect_warning-border-hover | var(--semi-color-warning-light-hover) | 警告树选择器选择框描边颜色 - 悬浮 |
| $color-treeSelect_warning-bg-focus | var(--semi-color-warning-light-default) | 警告树选择器选择框背景颜色 - 选中 |
| $color-treeSelect_warning-border-focus | var(--semi-color-warning) | 警告树选择器选择框描边颜色 - 选中 |
| $color-treeSelect_warning-bg-active | var(--semi-color-warning-light-active) | 警告树选择器选择框背景颜色 - 激活 |
| $color-treeSelect_warning-border-active | var(--semi-color-warning-light-active) | 警告树选择器选择框描边颜色 - 激活 |
| $color-treeSelect_danger-bg-default | var(--semi-color-danger-light-default) | 错误树选择器选择框背景颜色 - 默认 |
| $color-treeSelect_danger-border-default | var(--semi-color-danger-light-default) | 错误树选择器选择框描边颜色 - 默认 |
| $color-treeSelect_danger-bg-hover | var(--semi-color-danger-light-hover) | 错误树选择器选择框背景颜色 - 悬浮 |
| $color-treeSelect_danger-border-hover | var(--semi-color-danger-light-hover) | 错误树选择器选择框描边颜色 - 悬浮 |
| $color-treeSelect_danger-bg-focus | var(--semi-color-danger-light-default) | 错误树选择器选择框背景颜色 - 选中 |
| $color-treeSelect_danger-border-focus | var(--semi-color-danger) | 错误树选择器选择框描边颜色 - 选中 |
| $color-treeSelect_danger-bg-active | var(--semi-color-danger-light-active) | 错误树选择器选择框背景颜色 - 激活 |
| $color-treeSelect_danger-border-active | var(--semi-color-danger-light-active) | 错误树选择器选择框描边颜色 - 激活 |
| $radius-treeSelect | var(--semi-border-radius-small) | 树选择器圆角 |
| $width-treeSelect-border | 1px | 树选择器描边宽度 |
| $width-treeSelect_search_wrapper-border | 1px | 树选择器搜索框描边宽度 |
| $width-treeSelect_hover-border | $border-thickness-control-focus | 树选择器选择框描边宽度 - 悬浮 |
| $width-treeSelect_focus-border | $width-treeSelect_hover-border | 树选择器选择框描边宽度 - 选中 |
| $width-treeSelect_default | 80px | 树选择器最小宽度 |
| $height-treeSelect_default | $height-control-default | 树选择器选择器高度 - 默认 |
| $font-treeSelect_default-lineHeight | $height-treeSelect_default | 树选择器选择器文本行高 |
| $font-treeSelect_default-fontWeight | $font-weight-regular | 树选择器选择器文本字重 |
| $height-treeSelect_small | $height-control-small | 小尺寸树选择器选择器高度 |
| $font-treeSelect_small-lineHeight | $height-treeSelect_small | 小尺寸树选择器选择器文本行高 |
| $height-treeSelect_large | $height-control-large | 大尺寸树选择器选择器文本行高 |
| $font-treeSelect_large-lineHeight | $height-treeSelect_large | 大尺寸树选择器选择器文本行高 |
| $font-treeSelect_prefix_suffix_fontWeight | $font-weight-bold | 树选择器前缀后缀文本字重 |
| $spacing-treeSelect_selection_tagInput_wrapper-paddingX | $spacing-extra-tight | 树选择器多选标签容器水平内边距 |
| $spacing-treeSelect_selection_tagInput_empty-marginLeft | $spacing-extra-tight | 树选择器多选标签容器为空时左侧外边距 |
| $spacing-treeSelect_selection_tagInput_notEmpty-marginLeft | -$spacing-extra-tight | 树选择器多选标签容器不为空时左侧外边距 |
| $spacing-treeSelect_selection-paddingLeft | $spacing-base-tight | 树选择器单选左侧内边距 |
| $spacing-treeSelect_tag-marginX | $spacing-super-tight | 树选择器多选标签水平外边距 |
| $spacing-treeSelect_tag-marginY | 1px | 树选择器多选标签垂直外边距 |
| $spacing-treeSelect_selection_multiple-paddingLeft | 4px | 树选择器多选标签左侧内边距 |
| $spacing-treeSelect_placeholder_multiple-paddingLeft | 8px | 树选择器多选占位文本左侧外边距 |
| $spacing-treeSelect_prefix_text-marginY | 0px | 树选择器前缀文本垂直外边距 |
| $spacing-treeSelect_prefix_text-marginX | $spacing-base-tight | 树选择器前缀文本水平外边距 |
| $spacing-treeSelect_prefix_icon-marginY | 0px | 树选择器前缀图标垂直外边距 |
| $spacing-treeSelect_prefix_icon-marginX | $spacing-tight | 树选择器前缀图标水平外边距 |
| $spacing-treeSelect_selection_withSuffix-paddingRight | 0px | 树选择器有后缀时内容右侧内边距 |
| $color-treeSelect_selection_TriggerSearchItem_disabled-text-default | var(--semi-color-disabled-text) | 带搜索的树选择器触发器占位文本默认颜色 |
| $color-treeSelect_inputTrigger-border-default | none | 带搜索的树选择器触发器描边颜色 |
| $color-treeSelect_inputTrigger-bg-default | transparent | 带搜索的树选择器触发器背景颜色 |
| $color-treeSelect_prefix_suffix_text-default | var(--semi-color-text-2) | 带搜索的树选择器前后缀文本颜色 |
| $width-treeSelect_arrow | 32px | 树选择器展开箭头宽度 |
| $width-treeSelect_option | 230px | 树选择器菜单项宽度 |
| $height-treeSelect_popover | 300px | 树选择器菜单高度 |
| $height-treeSelect_selection_tagInput_wrapper_small | 22px | 树选择器多选搜索,搜索框在选择框时选择框最小高度 - 小尺寸 |
| $height-treeSelect_selection_tagInput_wrapper_default | 30px | 树选择器多选搜索,搜索框在选择框时选择框最小高度 - 默认尺寸 |
| $height-treeSelect_selection_tagInput_wrapper_large | 38px | 树选择器多选搜索,搜索框在选择框时选择框最小高度 - 大尺寸 |