TreeSelect
TreeSelect component for selecting values from hierarchical tree data structures. It supports single and multiple selection, cascading, filtering, and asynchronous data loading.
Default TreeSelect
Basic tree select with hierarchical options.
<template>
<HLTreeSelect id="tree-select-default" :options="options" :value="selectedValue" @update:value="handleChange" />
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedValue = ref(null)
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{
label: 'Drive My Car',
key: 'Drive My Car',
},
{
label: 'Norwegian Wood',
key: 'Norwegian Wood',
},
],
},
{
label: 'Let It Be',
key: 'Let It Be Album',
children: [
{
label: 'Two Of Us',
key: 'Two Of Us',
},
{
label: 'Let It Be',
key: 'Let It Be',
},
],
},
]
const handleChange = value => {
selectedValue.value = value
}
</script>Size Variants
TreeSelect supports sm, md, and lg sizes. Size affects control height, internal border radius, and focus visuals.
<template>
<HLTreeSelect :options="options" :value="selectedValue" @update:value="handleChange" size="sm" clearable />
<HLTreeSelect :options="options" :value="selectedValue" @update:value="handleChange" size="md" clearable />
<HLTreeSelect :options="options" :value="selectedValue" @update:value="handleChange" size="lg" clearable />
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedValue = ref(null)
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
const handleChange = value => {
selectedValue.value = value
}
</script>Multiple Selection
Enable multiple selection with the multiple prop.
<template>
<HLTreeSelect id="tree-select-multiple" :options="options" :value="multipleValue" @update:value="(val) => multipleValue = val" multiple />
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const multipleValue = ref([])
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
</script>Filterable and Clearable
Add search functionality and clear button.
<template>
<HLTreeSelect id="tree-select-filterable" :options="options" :value="selectedValue" @update:value="handleChange" filterable clearable />
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedValue = ref(null)
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
const handleChange = value => {
selectedValue.value = value
}
</script>Max Tag Count
Limit the number of visible tags in multiple selection mode.
<template>
<HLTreeSelect
id="tree-select-max-tags"
:options="options"
:value="multipleValue"
@update:value="(val) => multipleValue = val"
multiple
:max-tag-count="4"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const multipleValue = ref([])
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
</script>Cascade Selection
Enable cascade mode where selecting a parent automatically selects all children. This will support with checkable prop and multiple selection.
<template>
<HLTreeSelect
id="tree-select-cascade"
:options="options"
:value="cascadeValue"
@update:value="(val) => cascadeValue = val"
multiple
cascade
checkable
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const cascadeValue = ref([])
</script>Check Strategy
When you tick a parent in a cascading tree, the parent and all its children become checked. checkStrategy decides which of those keys are actually reported back to you — it changes the emitted value and the tags shown, never what the user is allowed to tick.
Requires checkable + cascade.
Take a "Songs" branch holding Two Of Us and Dig A Pony. Ticking the parent gives:
checkStrategy | Emitted value | Tags shown |
|---|---|---|
'all' (default) | ['Songs', 'Two Of Us', 'Dig A Pony'] | parent + both children |
'parent' | ['Songs'] | just the parent |
'child' | ['Two Of Us', 'Dig A Pony'] | just the two children |
Same clicks, three different payloads. Tick the "Let It Be" parent in each picker below to compare.
check-strategy="all" (default)
check-strategy="parent"
check-strategy="child"
<template>
<!-- Emits the parent and all its children -->
<HLTreeSelect :options="options" :value="value" @update:value="onChange" multiple cascade checkable check-strategy="all" />
<!-- Emits just the parent key -->
<HLTreeSelect :options="options" :value="value" @update:value="onChange" multiple cascade checkable check-strategy="parent" />
<!-- Emits just the leaf keys -->
<HLTreeSelect :options="options" :value="value" @update:value="onChange" multiple cascade checkable check-strategy="child" />
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const value = ref([])
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
const onChange = val => {
value.value = val
}
</script>INFO
Pick the strategy that matches your API: 'parent' keeps the payload small when a whole branch is selected, 'child' suits backends that only accept leaf ids. A partially-checked parent is never included by 'parent' — only fully-checked ones.
Default Expand All
Expand all tree nodes by default.
<template>
<HLTreeSelect id="tree-select-expand-all" :options="options" :value="selectedValue" @update:value="handleChange" default-expand-all />
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedValue = ref(null)
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
const handleChange = value => {
selectedValue.value = value
}
</script>Default Expanded Keys
Specify which nodes should be expanded by default using their keys.
<template>
<HLTreeSelect
id="tree-select-expanded-keys"
:options="options"
:value="selectedValue"
@update:value="handleChange"
:default-expanded-keys="['Let It Be Album']"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedValue = ref(null)
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [
{ label: 'Drive My Car', key: 'Drive My Car' },
{ label: 'Norwegian Wood', key: 'Norwegian Wood' },
],
},
{ label: 'Let It Be', key: 'Let It Be Album' },
]
const handleChange = value => {
selectedValue.value = value
}
</script>Controlled Expanded Keys
defaultExpandedKeys (above) is uncontrolled — the tree takes it as a starting point and then manages expansion itself. To drive expansion from your own state, bind expandedKeys and handle @update:expandedKeys; without that handler the tree will not expand at all, because nothing updates the bound value.
<template>
<div>Expanded: {{ expandedKeys.join(', ') }}</div>
<HLTreeSelect
id="tree-select-controlled-expanded"
:options="options"
:value="value"
@update:value="(val) => value = val"
:expanded-keys="expandedKeys"
@update:expanded-keys="(keys) => expandedKeys = keys"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const value = ref(null)
// Bound both ways: the tree reads this, and the handler writes it back
const expandedKeys = ref(['Rubber Soul'])
</script>Override Default Node Click Behavior
Customize what happens when a node is clicked.Here is the example to toggle expand when a node is clicked.
<template>
<HLTreeSelect
id="tree-select-click-behavior"
:options="options"
:value="selectedValue"
@update:value="handleChange"
:override-default-node-click-behavior="overrideDefaultNodeClickBehavior"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedValue = ref(null)
const overrideDefaultNodeClickBehavior = info => {
// If the node has children, toggle expand instead of selecting
if (info?.option?.children?.length) {
return 'toggleExpand'
}
return 'default'
}
const handleChange = value => {
selectedValue.value = value
}
</script>Custom Slots
Customize various parts of the tree select using slots.
<template>
<HLTreeSelect id="tree-select-slots" :options="options" :value="selectedValue" @update:value="handleChange" multiple filterable>
<!-- Pinned above the option list -->
<template #header>
<div class="p-2 text-sm font-medium text-gray-700">Pick one or more tracks</div>
</template>
<!-- Pinned below the option list -->
<template #action>
<div class="p-2 text-sm text-gray-600">If you click this demo, you may need it.</div>
</template>
<template #empty>
<div class="p-4 text-center text-gray-500">Empty handler when options are empty</div>
</template>
<template #arrow>
<Star01Icon class="w-5 h-5" />
</template>
</HLTreeSelect>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { Star01Icon } from '@gohighlevel/ghl-icons/24/outline'
import { ref } from 'vue'
const selectedValue = ref(null)
</script>Show Check Mark
Enable Checkmark at end of the selected option. This can be done with showCheckMark prop.
<template>
<HLTreeSelect
id="tree-select-cascade"
:options="options"
:value="selectedCheckMarkValue"
@update:value="(val) => selectedCheckMarkValue = val"
showCheckMark
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const selectedCheckMarkValue = ref(null)
</script>Render Label
Customize how labels are rendered in the tree.
<template>
<HLTreeSelect
id="tree-select-render-label"
:options="options"
:value="renderLabelValue"
@update:value="(val) => renderLabelValue = val"
:render-label="renderLabel"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref, h } from 'vue'
const renderLabelValue = ref(null)
const renderLabel = info => {
return h(
'div',
{
style: {
display: 'flex',
alignItems: 'center',
},
},
[
h(
'div',
{
style: {
fontWeight: 400,
fontSize: '14px',
lineHeight: '20px',
padding: '12px',
},
class: info.selected ? 'bg-primary' : '',
},
[
h(
'p',
{
style: { margin: 0 },
class: info.selected ? 'bg-primary' : '',
},
[info.option.label]
),
]
),
]
)
}
</script>Render Tag
Customize how selected tags are rendered in multiple selection mode.
<template>
<HLTreeSelect
id="tree-select-render-tag"
:options="options"
:value="renderTagValue"
@update:value="(val) => renderTagValue = val"
:render-tag="renderTag"
multiple
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref, h } from 'vue'
const renderTagValue = ref(['Let It Be Album'])
const renderTag = info => {
return h('div', { class: 'bg-primary border border-solid border-black px-2' }, [
info.option.label,
h('button', { class: 'ml-2', onClick: () => info.handleClose() }, 'X'),
])
}
</script>Render Prefix
Add custom prefix content to tree nodes.
<template>
<HLTreeSelect
id="tree-select-render-prefix"
:options="options"
:value="renderPrefixValue"
@update:value="(val) => renderPrefixValue = val"
:render-prefix="renderPrefix"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { Star01Icon } from '@gohighlevel/ghl-icons/24/outline'
import { ref, h } from 'vue'
const renderPrefixValue = ref(null)
const renderPrefix = info => {
return h(Star01Icon, {
style: {
width: '16px',
height: '16px',
fill: info.checked ? 'blue' : 'none',
},
})
}
</script>Render Suffix
Add custom suffix content to tree nodes.
<template>
<HLTreeSelect
id="tree-select-render-suffix"
:options="options"
:value="renderSuffixValue"
@update:value="(val) => renderSuffixValue = val"
:render-suffix="renderSuffix"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { Star01Icon } from '@gohighlevel/ghl-icons/24/outline'
import { ref, h } from 'vue'
const renderSuffixValue = ref(null)
const renderSuffix = info => {
return h(Star01Icon, {
style: {
width: '16px',
height: '16px',
fill: info.checked ? 'blue' : 'none',
},
})
}
</script>Async Loading
Load child nodes asynchronously when expanding parent nodes.
<template>
<HLTreeSelect
id="tree-select-async"
:options="asyncOptions"
:value="asyncValue"
@update:value="(val) => asyncValue = val"
:on-load="handleLoad"
allow-checking-not-loaded
multiple
checkable
cascade
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const asyncValue = ref(null)
const asyncOptions = ref([
{
label: 'Rubber Soul',
key: 'Rubber Soul',
depth: 1,
isLeaf: false,
},
])
const getChildren = option => {
const children = []
for (let i = 0; i <= option.depth; ++i) {
children.push({
label: option.label + '-' + i,
key: option.label + '-' + i,
depth: option.depth + 1,
isLeaf: option.depth === 3,
})
}
return children
}
const handleLoad = option => {
return new Promise(resolve => {
window.setTimeout(() => {
option.children = getChildren(option)
resolve()
}, 1000)
})
}
</script>Infinite Scroll
Paginate the top-level options as the user scrolls. The @scroll event forwards the dropdown list's raw scroll event, so you decide when to fetch the next page — detect the bottom from event.target in the handler and append the next page of options. This composes with on-load for lazy-loading each node's children on expand.
Detect the bottom with scrollTop + clientHeight >= scrollHeight - threshold. Use a small threshold (px from the bottom) to start fetching a little early, e.g. 40.
INFO
@scroll fires on every scroll event, so guard the handler: only fetch when near the bottom, skip while a request is in flight, and stop once all data is loaded (as below). This keeps a single page from being requested repeatedly.
<template>
<HLTreeSelect
id="tree-select-infinite"
:options="options"
:value="selectedValue"
@update:value="(val) => selectedValue = val"
@scroll="handleScroll"
:on-load="handleLoad"
placeholder="Scroll to load more albums"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const PAGE_SIZE = 20
const TOTAL = 80
// px from the bottom at which to fetch the next page.
const SCROLL_END_THRESHOLD = 40
const selectedValue = ref(null)
const loadedCount = ref(PAGE_SIZE)
const isLoadingMore = ref(false)
// A parent node is loadable (isLeaf: false) but has no children yet — they
// arrive lazily via on-load when the node is expanded.
const makeAlbum = i => ({ label: `Album ${i}`, key: `album-${i}`, isLeaf: false })
const options = ref(Array.from({ length: PAGE_SIZE }, (_, i) => makeAlbum(i + 1)))
// @scroll forwards the raw scroll event; detect the bottom yourself. Guard
// against an in-flight request and stop once everything is loaded.
const handleScroll = e => {
const el = e.target
const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - SCROLL_END_THRESHOLD
if (!nearBottom || isLoadingMore.value || loadedCount.value >= TOTAL) return
isLoadingMore.value = true
// Replace with your paginated API call.
window.setTimeout(() => {
const next = Math.min(loadedCount.value + PAGE_SIZE, TOTAL)
for (let i = loadedCount.value; i < next; ++i) options.value.push(makeAlbum(i + 1))
loadedCount.value = next
isLoadingMore.value = false
}, 600)
}
// Lazy-load a node's children when it is expanded.
const handleLoad = node => {
return new Promise(resolve => {
window.setTimeout(() => {
node.children = Array.from({ length: 5 }, (_, i) => ({
label: `${node.label} — Track ${i + 1}`,
key: `${node.key}-track-${i + 1}`,
isLeaf: true,
}))
resolve()
}, 600)
})
}
</script>Placement
placement sets which side of the trigger the dropdown opens on. It accepts the four sides (top, bottom, left, right) and their -start / -end alignment variants; the default is bottom-start.
<template>
<HLTreeSelect
id="tree-select-placement"
:options="options"
:value="value"
@update:value="onChange"
placement="top-start"
placeholder="Opens upward"
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const value = ref(null)
const onChange = val => {
value.value = val
}
</script>Consistent Menu Width
By default the dropdown matches the trigger's width, so long labels wrap or truncate. Set :consistent-menu-width="false" to let the menu size itself to its content and grow wider than the trigger — useful for deep trees whose indented labels would otherwise be cramped.
Default — menu matches the trigger width
:consistent-menu-width="false" — menu grows to fit
<template>
<!-- Menu is locked to the trigger width (default) -->
<HLTreeSelect :options="options" :value="value" @update:value="onChange" default-expand-all />
<!-- Menu sizes to its content, so it can be wider than the trigger -->
<HLTreeSelect
:options="options"
:value="value"
@update:value="onChange"
:consistent-menu-width="false"
default-expand-all
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const value = ref(null)
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
children: [{ label: "Everybody's Got Something to Hide Except Me and My Monkey", key: 'long-one' }],
},
]
const onChange = val => {
value.value = val
}
</script>Show Avatar in Tags
showAvatarInTags controls the avatars the component renders by default — in the dropdown labels as well as in the selected tags. It is true by default; set it to false for a plain text-only tree.
An option's src supplies the avatar image; without one, the avatar falls back to initials derived from the option's label.
Default — avatars in labels and tags
:show-avatar-in-tags="false" — text only
<template>
<!-- Avatars shown (default) -->
<HLTreeSelect :options="options" :value="value" @update:value="onChange" multiple default-expand-all />
<!-- Text only -->
<HLTreeSelect
:options="options"
:value="value"
@update:value="onChange"
multiple
:show-avatar-in-tags="false"
default-expand-all
/>
</template>
<script setup>
import { HLTreeSelect } from '@platform-ui/highrise'
import { ref } from 'vue'
const value = ref(['Two Of Us'])
const options = [
{
label: 'Rubber Soul',
key: 'Rubber Soul',
// `src` supplies the avatar image; without it the avatar shows initials
src: 'https://picsum.photos/seed/FeB6P/640/480',
children: [{ label: 'Drive My Car', key: 'Drive My Car' }],
},
{
label: 'Let It Be',
key: 'Let It Be Album',
children: [{ label: 'Two Of Us', key: 'Two Of Us' }],
},
]
const onChange = val => {
value.value = val
}
</script>INFO
showAvatarInTags only affects the component's built-in rendering. A custom renderLabel or renderTag replaces that rendering entirely, so the avatar is then yours to draw (or omit).
Empty Data
Render an empty state by passing an empty options array. The built-in empty indicator renders inside the menu panel; the trigger remains interactive so users can still blur or retry.
<template>
<HLTreeSelect id="tree-select-empty" :options="[]" placeholder="No options available" />
</template>Loading State
Use the loading prop to show the in-panel loading indicator. Combine with an empty options array when you have no cached data, or leave the previous options in place to avoid content shift during async refresh.
<template>
<HLTreeSelect
id="tree-select-loading"
:options="[]"
:loading="true"
placeholder="Loading options..."
/>
</template>Error State
Set status="error" to apply the error-toned border and focus-ring tokens. Pair with HLFormItem validationStatus="error" + feedback so assistive tech announces the failure through aria-invalid + aria-describedby.
<template>
<HLTreeSelect
id="tree-select-error"
:options="[]"
status="error"
placeholder="Failed to load options"
/>
</template>Imports
import { HLTreeSelect } from '@platform-ui/highrise'Props
| Prop | Type | Default | Description |
|---|---|---|---|
| id * | string | undefined | Unique identifier for the tree select |
| allowCheckingNotLoaded | boolean | false | Allow checking nodes that haven't been loaded yet (for async loading) |
| cascade | boolean | false | Whether to cascade selection to child nodes |
| checkable | boolean | false | Show checkboxes for nodes |
| checkStrategy | 'all' | 'parent' | 'child' | 'all' | Strategy for what values are shown when cascading: 'all' shows all checked nodes, 'parent' shows only parent nodes, 'child' shows only leaf nodes |
| clearable | boolean | false | Show clear button |
| consistentMenuWidth | boolean | true | Whether dropdown menu width matches the select width |
| defaultExpandAll | boolean | false | Expand all nodes by default |
| defaultExpandedKeys | Array<string | number> | [] | Keys of nodes that should be expanded by default |
| disabled | boolean | false | Disable the tree select |
| expandedKeys | Array<string | number> | undefined | Controlled expanded keys (requires @update:expandedKeys handler) |
| filterable | boolean | false | Enable search/filter functionality |
| loading | boolean | false | Show loading state |
| maxTagCount | number | 'responsive' | 'responsive' | Maximum number of visible tags in multiple mode |
| multiple | boolean | false | Enable multiple selection |
| onLoad | (node: TreeSelectOption) => Promise<void> | undefined | Async function to load child nodes |
| options | TreeSelectOption[] | [] | Tree data options |
| overrideDefaultNodeClickBehavior | (info: { option: TreeSelectOption }) => ClickBehaviourType | undefined | Override default click behavior for nodes |
| placeholder | string | 'Please Select' | Placeholder text |
| placement | FollowerPlacement | 'bottom-start' | Dropdown placement |
| renderLabel | (info: { option: TreeSelectOption; checked: boolean; selected: boolean }) => VNodeChild | undefined | Custom label render function |
| renderPrefix | (info: { option: TreeSelectOption; checked: boolean; selected: boolean }) => VNodeChild | undefined | Custom prefix render function |
| renderSuffix | (info: { option: TreeSelectOption; checked: boolean; selected: boolean }) => VNodeChild | undefined | Custom suffix render function |
| renderTag | (info: { option: TreeSelectOption; handleClose: () => void }) => VNodeChild | undefined | Custom tag render function |
| show | boolean | undefined | Control dropdown visibility |
| showAvatarInTags | boolean | true | Show the default avatar in dropdown labels and in selected tags. Ignored where a custom renderLabel / renderTag takes over |
| size | 'sm' | 'md' | 'lg' | 'md' | Size of the tree select |
| status | 'success' | 'warning' | 'error' | undefined | Validation status |
| value | string | number | Array<string | number> | null | undefined | Selected value(s) |
| showCheckMark | boolean | false | Show check mark icon in checked nodes |
| to | string | HTMLElement | false | undefined | Teleport target for the dropdown menu. Pass a CSS selector or HTMLElement to mount the menu inside a specific container. Pass false to disable teleporting. |
TreeSelectOption
- Always provide unique
keyvalues for each node to ensure proper tracking and updates.
interface HLTreeSelectOption {
key: string | number // Unique identifier for the node
label: string // Display text for the node
description?: string // Optional description text
src?: string // Optional image source (e.g., for avatars)
children?: TreeSelectOption[] // Child nodes
disabled?: boolean // Whether the node is disabled
isLeaf?: boolean // Indicates if the node is a leaf (no children, used in async loading)
depth?: number // Depth level (used in async loading)
renderOption?: () => VNodeChild // Custom render function for the option
[key: string]: any // Additional custom properties
}Emits
| Event | Parameters | Description |
|---|---|---|
@update:value | (value: string | number | Array<string | number>, option: TreeSelectOption | TreeSelectOption[], meta: { node: TreeSelectOption, action: string }) | Emitted when selection changes |
@update:expandedKeys | (keys: Array<string | number>, meta: { node: TreeSelectOption, action: string }) | Emitted when expanded keys change |
@scroll | (e: Event) | Emitted on the dropdown list's native scroll event. Detect the bottom from e.target for infinite-scroll / pagination of top-level options |
Slots
| Name | Parameters | Description |
|---|---|---|
| action | () | Footer content in the dropdown |
| arrow | () | Custom arrow icon |
| empty | () | Content shown when there are no options |
| header | () | Header content in the dropdown |