Tree Select
Material Design 3 hierarchical dropdown selection component
Tree Select
Tree Select is a hierarchical dropdown component that allows users to select from nested options. Itβs ideal for categories, organizational structures, file systems, or any parent-child data relationships. Uses the native HTML Popover API for dropdown behavior.
Basic Usage
Basic Tree Select
html
<div class="tree-select">
<button class="tree-select-trigger" popovertarget="tree-select-1">
<span class="tree-select-value">Select a category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-1" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 2</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 3</span>
</div>
</div>
</div>
</div>With Dropdown Open
Tree Select Dropdown
html
<div class="tree-select">
<button class="tree-select-trigger" popovertarget="tree-select-2">
<span class="tree-select-value">Select a category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-2" popover="auto">
<div class="tree-select-search">
<input type="text" class="tree-select-search-input" placeholder="Search..." />
</div>
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-expanded">
<button class="tree-select-node-toggle">
<svg class="tree-select-node-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<span class="tree-select-node-label">Electronics</span>
</div>
<div class="tree-select-children">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Smartphones</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Laptops</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Tablets</span>
</div>
</div>
<div class="tree-select-node">
<button class="tree-select-node-toggle">
<svg class="tree-select-node-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<span class="tree-select-node-label">Clothing</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Books</span>
</div>
</div>
</div>
</div>With Selection
Tree Select with Selection
Electronics / Smartphones
html
<div class="tree-select">
<div class="tree-select-trigger" role="combobox" aria-expanded="false" tabindex="0">
<span class="tree-select-value tree-select-value-selected">
<span class="tree-select-path">Electronics / Smartphones</span>
</span>
<button type="button" class="tree-select-clear" aria-label="Clear selection">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</div>
<div class="tree-select-dropdown" id="tree-select-3" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-expanded">
<button class="tree-select-node-toggle">
<svg class="tree-select-node-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<span class="tree-select-node-label">Electronics</span>
</div>
<div class="tree-select-children">
<div class="tree-select-node tree-select-node-leaf tree-select-node-selected">
<span class="tree-select-node-label">Smartphones</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Laptops</span>
</div>
</div>
</div>
</div>
</div>Variants
Outlined (Default)
Outlined Tree Select
html
<div class="tree-select tree-select-outlined">
<button class="tree-select-trigger" popovertarget="tree-select-outlined">
<span class="tree-select-value">Select category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-outlined" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
</div>
</div>
</div>Filled
Filled Tree Select
html
<div class="tree-select tree-select-filled">
<button class="tree-select-trigger" popovertarget="tree-select-filled">
<span class="tree-select-value">Select category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-filled" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
</div>
</div>
</div>Sizes
Small
Small Tree Select
html
<div class="tree-select tree-select-sm">
<button class="tree-select-trigger" popovertarget="tree-select-sm">
<span class="tree-select-value">Select</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-sm" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
</div>
</div>
</div>Large
Large Tree Select
html
<div class="tree-select tree-select-lg">
<button class="tree-select-trigger" popovertarget="tree-select-lg">
<span class="tree-select-value">Select category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-lg" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
</div>
</div>
</div>With Checkboxes (Multiple Selection)
Tree Select with Checkboxes
html
<div class="tree-select tree-select-multiple">
<button class="tree-select-trigger" popovertarget="tree-select-checkbox">
<span class="tree-select-value">Select categories</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-checkbox" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-expanded">
<label class="tree-select-checkbox">
<input type="checkbox" class="tree-select-checkbox-input" />
<span class="tree-select-checkbox-box"></span>
</label>
<button class="tree-select-node-toggle">
<svg class="tree-select-node-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<span class="tree-select-node-label">Electronics</span>
</div>
<div class="tree-select-children">
<div class="tree-select-node tree-select-node-leaf tree-select-node-selected">
<label class="tree-select-checkbox">
<input type="checkbox" class="tree-select-checkbox-input" checked />
<span class="tree-select-checkbox-box"></span>
</label>
<span class="tree-select-node-label">Smartphones</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<label class="tree-select-checkbox">
<input type="checkbox" class="tree-select-checkbox-input" />
<span class="tree-select-checkbox-box"></span>
</label>
<span class="tree-select-node-label">Laptops</span>
</div>
</div>
</div>
</div>
</div>States
Error State
Error State
html
<div class="form-group">
<label class="form-label form-label-required">Category</label>
<div class="tree-select tree-select-error">
<button class="tree-select-trigger" popovertarget="tree-select-error">
<span class="tree-select-value">Select a category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-error" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
</div>
</div>
</div>
<span class="helper-text helper-text-error">Please select a category</span>
</div>Disabled
Disabled State
html
<div class="tree-select tree-select-disabled">
<button class="tree-select-trigger" disabled>
<span class="tree-select-value">Select a category</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
</div>Loading
Loading State
html
<div class="tree-select tree-select-loading">
<button class="tree-select-trigger" disabled>
<span class="tree-select-value">Loading categories...</span>
<span class="tree-select-spinner"></span>
</button>
</div>With Icons
Tree Select with Icons
html
<div class="tree-select">
<button class="tree-select-trigger" popovertarget="tree-select-icons">
<span class="tree-select-value">Select location</span>
<svg class="tree-select-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<div class="tree-select-dropdown" id="tree-select-icons" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-expanded">
<button class="tree-select-node-toggle">
<svg class="tree-select-node-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</button>
<svg class="tree-select-node-custom-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span class="tree-select-node-label">North America</span>
</div>
<div class="tree-select-children">
<div class="tree-select-node tree-select-node-leaf">
<svg class="tree-select-node-custom-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
</svg>
<span class="tree-select-node-label">United States</span>
</div>
<div class="tree-select-node tree-select-node-leaf">
<svg class="tree-select-node-custom-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
</svg>
<span class="tree-select-node-label">Canada</span>
</div>
</div>
</div>
</div>
</div>API Reference
Class Names
| Class | Description |
|---|---|
.tree-select | Base container (required) |
.tree-select-trigger | Trigger button (use with popovertarget) |
.tree-select-value | Selected value display |
.tree-select-value-selected | Has selection state |
.tree-select-path | Path breadcrumb display |
.tree-select-arrow | Dropdown arrow icon |
.tree-select-clear | Clear selection button |
.tree-select-dropdown | Dropdown container (use with popover attribute) |
.tree-select-search | Search input container |
.tree-select-search-input | Search input field |
.tree-select-options | Options container |
.tree-select-node | Tree node |
.tree-select-node-expanded | Expanded node |
.tree-select-node-leaf | Leaf node (no children) |
.tree-select-node-selected | Selected node |
.tree-select-node-toggle | Expand/collapse toggle |
.tree-select-node-icon | Toggle icon |
.tree-select-node-label | Node label text |
.tree-select-node-custom-icon | Custom node icon |
.tree-select-children | Child nodes container |
.tree-select-checkbox | Checkbox for multi-select |
.tree-select-outlined | Outlined variant |
.tree-select-filled | Filled variant |
.tree-select-sm | Small size |
.tree-select-lg | Large size |
.tree-select-multiple | Multiple selection mode |
.tree-select-error | Error state |
.tree-select-disabled | Disabled state |
.tree-select-loading | Loading state |
.tree-select-spinner | Loading spinner |
HTML Structure with Popover API
<div class="tree-select">
<button class="tree-select-trigger" popovertarget="dropdown-id">
<span class="tree-select-value">Select a category</span>
<svg class="tree-select-arrow">...</svg>
</button>
<div class="tree-select-dropdown" id="dropdown-id" popover="auto">
<div class="tree-select-options">
<div class="tree-select-node tree-select-node-leaf">
<span class="tree-select-node-label">Category 1</span>
</div>
</div>
</div>
</div>
With Clear Button (Clearable)
When using a clear button, use a div with role="combobox" instead of a nested button:
<div class="tree-select">
<div class="tree-select-trigger" role="combobox" aria-expanded="false" tabindex="0">
<span class="tree-select-value tree-select-value-selected">
<span class="tree-select-path">Selected Item</span>
</span>
<button type="button" class="tree-select-clear" aria-label="Clear selection">
<svg fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
<svg class="tree-select-arrow">...</svg>
</div>
<div class="tree-select-dropdown" id="dropdown-id" popover="auto">...</div>
</div>
Related Components
- Select - Single dropdown
- Multi-Select - Multiple selection
- Autocomplete - Search with suggestions