---
title: "TreeSelect"
description: "A select that picks from tree-shaped data in a dropdown."
category: Form
status: beta
since: 0.3.4
tags: [tree-select, form, hierarchy]
syncStatus: reviewed
verified: true
---

## Usage

### Basic
:::TuffDemoWrapper{demo="TreeSelectTreeSelectDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import type { TreeSelectNode, TreeSelectValue } from '@talex-touch/tuffex'
  import { ref } from 'vue'

  const multiple = ref(false)
  const value = ref<TreeSelectValue>(undefined)

  const nodes: TreeSelectNode[] = [
    {
      key: 'general',
      label: 'General',
      children: [
        { key: 'appearance', label: 'Appearance' },
        { key: 'language', label: 'Language' },
      ],
    },
    {
      key: 'danger',
      label: 'Danger Zone',
      disabled: true,
      children: [{ key: 'delete', label: 'Delete account', disabled: true }],
    },
  ]
  </script>

  <template>
    <TxTreeSelect v-model="value" :nodes="nodes" :multiple="multiple" :dropdown-max-height="260" />
  </template>
---
:::

### Permission Orchestration
`TxTreeSelect` picks the owner team and forms an authorization flow with `TxTransfer` and `TxTimeline`.
:::TuffDemoWrapper{demo="ComponentsPermissionOrchestrationDemo" code-lang="vue"}
---
code: |
  <template>
    <TxTreeSelect
      v-model="ownerTeam"
      :nodes="nodes"
      placeholder="Owner team"
      :default-expanded-keys="['ops']"
      :dropdown-max-height="220"
    />
  </template>
---
:::

### Best Practices

- Use `TxTreeSelect` for compact owner, namespace, category, and org-unit picks; use `TxTree` when users need persistent context, bulk operations, or custom row controls.
- Give `nodes` stable `key` and `label` fields instead of a legacy `value` field, with keys independent of localized text.
- Match the value's shape to `multiple` before render; switching at runtime doesn't convert between a scalar and an array.
- Keep default expansion shallow, such as root departments or product areas.
- Use the `node` slot only for badges or subtitles, never for click targets that compete with row selection.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|------|
| `modelValue` | `string \| number \| Array<string \| number> \| undefined` | - | Selected key in single mode; an array of keys with `multiple`. |
| `nodes` | `TreeSelectNode[]` | `[]` | Tree nodes for the dropdown, also used to resolve the trigger text. |
| `multiple` | `boolean` | `false` | Checkbox multi-select, shown as tags in the trigger. |
| `disabled` | `boolean` | `false` | Disables the trigger, dropdown interaction, keyboard toggling, and clearing. |
| `placeholder` | `string` | `'请选择'` | Placeholder when no selected key resolves to a label. |
| `searchable` | `boolean` | `true` | Shows a search field whose text goes to the inner `TxTree` as `filterText`. |
| `clearable` | `boolean` | `true` | Shows a clear button when something is selected and the component is enabled. |
| `placement` | `PopoverPlacement` | `'bottom-start'` | Placement of the dropdown. |
| `dropdownOffset` | `number` | `6` | Distance between the dropdown and the trigger. |
| `dropdownWidth` | `number` | `0` | Dropdown width; `0` leaves it to `TxPopover`. |
| `dropdownMaxWidth` | `number` | `480` | Maximum dropdown width. |
| `dropdownMaxHeight` | `number` | `320` | Maximum tree height; taller content scrolls. |
| `defaultExpandedKeys` | `Array<string \| number>` | `[]` | Keys the inner `TxTree` starts expanded. |

### Events

| Event | Params | Description |
|------|------|------|
| `update:modelValue` | `value: TreeSelectValue` | Fires after a selection, a clear, or `setValue()`. |
| `change` | `value: TreeSelectValue` | Fires right after `update:modelValue` with the same value. |
| `open` | - | Fires when the dropdown opens. |
| `close` | - | Fires when the dropdown closes. |

### Slots

| Slot | Props | Description |
|------|------|------|
| `node` | `{ node, level, expanded, selected }` | Replaces the node label area of a row; caret, checkbox, indent, and click handling stay with the component. |

### Exposed Methods

| Name | Type | Description |
|------|------|------|
| `open()` | `() => void` | Opens the dropdown. |
| `close()` | `() => void` | Closes the dropdown. |
| `toggle()` | `() => void` | Toggles the dropdown. |
| `focus()` | `() => void` | Focuses the combobox trigger. |
| `blur()` | `() => void` | Blurs the combobox trigger. |
| `clear()` | `() => void` | Unless disabled, emits `undefined` in single mode or `[]` in multiple mode. |
| `setValue(value)` | `(value: TreeSelectValue) => void` | Emits the given value through `update:modelValue` and `change`, without checking it against `nodes`. |
| `getValue()` | `() => TreeSelectValue` | Returns the current `modelValue`. |
| `getCheckedKeys()` | `() => Array<string \| number>` | Returns the selected keys as an array, in single mode too. |

### Types

:::TuffCodeBlock{lang="ts"}
---
code: |
  type TreeSelectValue = string | number | Array<string | number> | undefined

  interface TreeSelectNode {
    key: string | number // stable and unique; the selected value
    label: string // node text, default search target, and trigger text
    disabled?: boolean // blocks selecting this node
    children?: TreeSelectNode[]
  }
---
:::

## Overview

- The trigger is a focusable `role="combobox"` (`aria-haspopup="tree"`, `aria-controls` pointing at the popup) whose popup holds a `role="tree"` `TxTree`; Enter and Space toggle the dropdown, Escape closes it.
- Single selection closes the dropdown and clears to `undefined`; multiple selection stays open and clears to `[]`.
- Disabled nodes can't be selected but still expand when they have children.
- Search uses `TxTree`'s default label filter, with no custom `filterMethod` or controlled `expandedKeys`; for domain search, compose an external search or use `TxTree` directly.
- Trigger text is resolved from the current `nodes`; unknown selected keys stay selected but show no text.
- `setValue()` only emits; the parent still owns `modelValue` through `v-model`, which ordinary code should prefer.

## Technologies

- The dropdown is a `TxPopover` that receives the placement and width props; the tree reuses `TxTree`, passing only `defaultExpandedKeys`, `filterText`, and `multiple`.
- Source: `packages/tuffex/packages/components/src/tree-select/`.

<TuffDocSourceLink />
