Tree view select
This is a form select element that displays options in a hierarchical tree structure. It supports expanding and collapsing branches, single and multiple selection, an optional search input for filtering, and configurable per-level colors using either a FluxColor name or any CSS/HEX color string. The tree structure is rendered with connecting lines to visualize the hierarchy.
Required icons
Props
model-value: FluxFormTreeViewSelectValue
The selected value(s) of the tree view select.
auto-focus?: boolean
Focus the trigger when the form is mounted.
disabled?: boolean
If the tree view select is disabled.
error?: string | null
Error message describing why the tree view select is invalid. Sets aria-invalid and a red border.
is-condensed?: boolean
Renders the trigger in a compact style with reduced padding.
is-loading?: boolean
Marks the tree view select as loading.
is-multiple?: boolean
If the tree view select allows multiple values to be selected.
is-readonly?: boolean
If the tree view select is readonly. Blocks opening the popup.
is-searchable?: boolean
If the tree view select has a search input to filter options.
is-secondary?: boolean
If the field is secondary and is rendered in an alternative style.
name?: string
The name attribute passed to the underlying form control.
level-colors?: (FluxColor | string)[]
An array of colors per depth level. Index 0 = root level, index 1 = first child level, etc. Each entry can be a `FluxColor` name (e.g. `primary`, `danger`) or any CSS color string (e.g. `#6366f1`). Levels without an entry show no color dot.
options: FluxFormTreeViewSelectOption[]
The tree structure of options to display.
placeholder?: string
The placeholder text to display when no value is selected.
Emits
update:model-value: [FluxFormTreeViewSelectValue]
Triggered when the selected value changes.
Option object
Each entry in the options array (and nested children arrays) is a FluxFormTreeViewSelectOption:
Property | Type | Description |
|---|---|---|
id | string | number | Unique identifier used as the value when selected. |
label | string | Display label for the node. |
icon | FluxIconName | Optional icon shown before the label. |
selectable | boolean | Whether this node can be selected. Defaults to true. Set to false on parent nodes to make them act as group headers — clicking them only expands or collapses their children. |
children | FluxFormTreeViewSelectOption[] | Nested child options. A node with children shows an expand/collapse chevron. |
Keyboard navigation
Key | Action |
|---|---|
Enter / Space | Open the popup (when closed) or select/activate the highlighted node. |
Arrow Down | Move highlight to the next visible node. |
Arrow Up | Move highlight to the previous visible node. |
Arrow Right | Expand the highlighted node (if collapsed). If already expanded, moves to its first child. |
Arrow Left | Collapse the highlighted node (if expanded). If already collapsed, moves to its parent. |
Backspace | (multiple mode) Removes the last selected tag when the search field is empty. |
Escape | Close the popup and return focus to the trigger. |
Tab | Close the popup. |
Any letter | Jump to the first visible node whose label starts with that letter. |
Examples
Basic
A tree view select with per-level colors.
<template>
<FluxPane style="max-width: 390px">
<FluxPaneBody>
<FluxFormField label="Category">
<FluxFormTreeViewSelect
v-model="selectedValue"
:level-colors="['primary', 'info', 'success']"
:options="options"
placeholder="Select a category..."/>
</FluxFormField>
</FluxPaneBody>
</FluxPane>
</template>
<script
lang="ts"
setup>
import { FluxFormField, FluxFormTreeViewSelect, FluxPane, FluxPaneBody } from '@flux-ui/components';
import { ref } from 'vue';
const selectedValue = ref<number | null>(null);
const options = [
{
id: 1,
label: 'Electronics',
children: [
{
id: 2,
label: 'Computers',
children: [
{ id: 3, label: 'Laptops' },
{ id: 4, label: 'Desktops' },
{ id: 5, label: 'Tablets' }
]
},
{
id: 6,
label: 'Phones',
children: [
{ id: 7, label: 'Smartphones' },
{ id: 8, label: 'Feature phones' }
]
}
]
},
{
id: 9,
label: 'Clothing',
children: [
{ id: 10, label: 'Men' },
{ id: 11, label: 'Women' },
{ id: 12, label: 'Kids' }
]
},
{
id: 13,
label: 'Home & Garden',
children: [
{ id: 14, label: 'Furniture' },
{ id: 15, label: 'Garden tools' }
]
}
];
</script>Multiple
A tree view select that allows selecting multiple items across the tree.
<template>
<FluxPane style="max-width: 390px">
<FluxPaneBody>
<FluxFormField label="Categories">
<FluxFormTreeViewSelect
v-model="selectedValues"
:level-colors="['primary', 'info', 'success']"
:options="options"
is-multiple
placeholder="Select categories..."/>
</FluxFormField>
</FluxPaneBody>
</FluxPane>
</template>
<script
lang="ts"
setup>
import { FluxFormField, FluxFormTreeViewSelect, FluxPane, FluxPaneBody } from '@flux-ui/components';
import { ref } from 'vue';
const selectedValues = ref<number[]>([]);
const options = [
{
id: 1,
label: 'Electronics',
children: [
{
id: 2,
label: 'Computers',
children: [
{ id: 3, label: 'Laptops' },
{ id: 4, label: 'Desktops' },
{ id: 5, label: 'Tablets' }
]
},
{
id: 6,
label: 'Phones',
children: [
{ id: 7, label: 'Smartphones' },
{ id: 8, label: 'Feature phones' }
]
}
]
},
{
id: 9,
label: 'Clothing',
children: [
{ id: 10, label: 'Men' },
{ id: 11, label: 'Women' },
{ id: 12, label: 'Kids' }
]
},
{
id: 13,
label: 'Home & Garden',
children: [
{ id: 14, label: 'Furniture' },
{ id: 15, label: 'Garden tools' }
]
}
];
</script>Searchable
A tree view select with a search input. Matching nodes are shown flattened while searching.
<template>
<FluxPane style="max-width: 390px">
<FluxPaneBody>
<FluxFormField label="Category">
<FluxFormTreeViewSelect
v-model="selectedValue"
:level-colors="['primary', 'info', 'success']"
:options="options"
is-searchable
placeholder="Search and select..."/>
</FluxFormField>
</FluxPaneBody>
</FluxPane>
</template>
<script
lang="ts"
setup>
import { FluxFormField, FluxFormTreeViewSelect, FluxPane, FluxPaneBody } from '@flux-ui/components';
import { ref } from 'vue';
const selectedValue = ref<number | null>(null);
const options = [
{
id: 1,
label: 'Electronics',
children: [
{
id: 2,
label: 'Computers',
children: [
{ id: 3, label: 'Laptops' },
{ id: 4, label: 'Desktops' },
{ id: 5, label: 'Tablets' }
]
},
{
id: 6,
label: 'Phones',
children: [
{ id: 7, label: 'Smartphones' },
{ id: 8, label: 'Feature phones' }
]
}
]
},
{
id: 9,
label: 'Clothing',
children: [
{ id: 10, label: 'Men' },
{ id: 11, label: 'Women' },
{ id: 12, label: 'Kids' }
]
},
{
id: 13,
label: 'Home & Garden',
children: [
{ id: 14, label: 'Furniture' },
{ id: 15, label: 'Garden tools' }
]
}
];
</script>Non-selectable parents
Parent nodes can have `selectable: false` so they act as group headers. Only leaf nodes can be selected.
<template>
<FluxPane style="max-width: 390px">
<FluxPaneBody>
<FluxFormField label="Product">
<FluxFormTreeViewSelect
v-model="selectedValue"
:level-colors="['gray', 'primary']"
:options="options"
placeholder="Select a product..."/>
</FluxFormField>
</FluxPaneBody>
</FluxPane>
</template>
<script
lang="ts"
setup>
import { FluxFormField, FluxFormTreeViewSelect, FluxPane, FluxPaneBody } from '@flux-ui/components';
import { ref } from 'vue';
const selectedValue = ref<number | null>(null);
// Parent nodes have `selectable: false` — only leaves can be selected.
const options = [
{
id: 1,
label: 'Electronics',
selectable: false,
children: [
{ id: 2, label: 'MacBook Pro 14"' },
{ id: 3, label: 'MacBook Air 13"' },
{ id: 4, label: 'iPhone 16 Pro' }
]
},
{
id: 5,
label: 'Clothing',
selectable: false,
children: [
{ id: 6, label: 'Classic T-shirt' },
{ id: 7, label: 'Slim-fit Jeans' }
]
},
{
id: 8,
label: 'Home & Garden',
selectable: false,
children: [
{ id: 9, label: 'Desk Lamp' },
{ id: 10, label: 'Bookshelf' }
]
}
];
</script>Custom colors
Using HEX colors instead of FluxColor names for each level.
<template>
<FluxPane style="max-width: 390px">
<FluxPaneBody>
<FluxFormField label="Category">
<FluxFormTreeViewSelect
v-model="selectedValue"
:level-colors="['#6366f1', '#f59e0b', '#10b981']"
:options="options"
placeholder="Select a category..."/>
</FluxFormField>
</FluxPaneBody>
</FluxPane>
</template>
<script
lang="ts"
setup>
import { FluxFormField, FluxFormTreeViewSelect, FluxPane, FluxPaneBody } from '@flux-ui/components';
import { ref } from 'vue';
const selectedValue = ref<number | null>(null);
const options = [
{
id: 1,
label: 'Electronics',
children: [
{
id: 2,
label: 'Computers',
children: [
{ id: 3, label: 'Laptops' },
{ id: 4, label: 'Desktops' }
]
},
{
id: 5,
label: 'Phones',
children: [
{ id: 6, label: 'Smartphones' }
]
}
]
},
{
id: 7,
label: 'Clothing',
children: [
{ id: 8, label: 'Men' },
{ id: 9, label: 'Women' }
]
}
];
</script>