HyTreeItem
Usage examples on this page are written for Lit / plain HTML (
<hy-tree-item>). The same component ships asHyTreeItemin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
A single row inside an hy-tree. Renders a chevron, an optional leading icon slot, the label (or default slot), an optional trailing slot, and a hidden-by-default children slot that unhides when expanded is true.
Items are focus-managed by the parent tree via roving tabindex — call setTabIndex(0) to mark the item as the tab target, and focus() to move keyboard focus. The host element carries role="treeitem" and reflects aria-expanded, aria-selected, aria-disabled.
Click zones depend on the parent tree's expand-on policy (forwarded onto each item). The chevron always toggles expansion and stops propagation. The row's click does one of three things, layered:
- Non-selectable rows with children always expand on row click — their row has no rival action, so the chevron-only fallback would leave the row dead.
- With
expand-on='row'(and the row is selectable + has children), the row click both selects AND expands. - Otherwise (
'chevron'default, or'double-click'), the row click just selects; expansion goes through the chevron ordblclick.
Level, aria-level, aria-posinset, and aria-setsize are written by the parent hy-tree during its DOM walk — don't set them manually on an item. The item detects whether it has children by observing its own children slot; it does not read across the DOM.
Examples
Nested file-explorer rows
<hy-tree>
<hy-tree-item value="src" label="src" expanded>
<hy-tree-item slot="children" value="src/index.ts" label="index.ts"></hy-tree-item>
<hy-tree-item slot="children" value="src/app.ts" label="app.ts"></hy-tree-item>
</hy-tree-item>
<hy-tree-item value="package.json" label="package.json"></hy-tree-item>
<hy-tree-item value="readme" label="README.md"></hy-tree-item>
</hy-tree>Leading icon and trailing content
<hy-tree-item value="tokens" label="tokens.json" selected>
<hy-icon slot="leading" name="folder" decorative></hy-icon>
<span slot="trailing">12 kB</span>
</hy-tree-item>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
value | value | string | '' | Identifier used in tree-item-click / expand / collapse events. |
label | label | string | '' | Label text. When empty, the default slot is rendered. |
expanded | expanded | boolean | false | Whether the children group is visible. Reflected. |
selected | selected | boolean | false | Whether this item is the selected one in its tree. Reflected. |
active | active | boolean | false | Whether this item currently owns the tab stop in its tree's roving tabindex (i.e. the parent tree's keyboard focus rests here). Reflected so the modal focus trap can match hy-tree-item[active] and so consumer CSS can highlight the current item independent of selection. Managed by the parent hy-tree — do not set manually. |
disabled | disabled | boolean | false | Disables the item — skipped in keyboard nav, no click activation. |
selectable | selectable | boolean | true | When false, clicking the row focuses the item but does not produce a selection. Use on group-only rows (e.g. category headers in a DTCG tree). |
level | level | number | 0 | Nesting depth — written by the parent hy-tree during its walk. Do not set manually. |
size | size | 'small' | 'medium' | 'large' | 'medium' | Size variant. Inherited from the parent hy-tree when there is one, else from the parent hy-tree-item — set it on the root and every nested item follows. An explicit value on a nested item is overwritten by its parent's, exactly as hy-tree has always overwritten every item's: one size per tree, set at the top. |
expandOn | expand-on | 'chevron' | 'row' | 'double-click' | 'chevron' | Activation policy for the row's primary click. Inherited from the parent hy-tree when there is one, else from the parent hy-tree-item — set it on the root, not on every row. A nested item's own value is overwritten by its parent's. |
hasChildren | — | boolean | — | Whether this item has slotted children (auto-detected via slotchange). |
Events
| Event | Detail | Description |
|---|---|---|
tree-item-click | — | { value, item, originalEvent } — bubbles to parent tree. |
expand | — | { value, item } — bubbles to parent tree. |
collapse | — | { value, item } — bubbles to parent tree. |
tree-structure-change | — | Internal structural notification to the ancestor tree (children added/removed, so it can re-stamp spatial attributes). Bubbles but does not cross shadow DOM (composed: false). |
Slots
| Slot | Description |
|---|---|
default | Label content when the label prop is empty. |
leading | Leading icon or avatar. |
trailing | Trailing content (value preview, copy button, badge). |
children | Nested hy-tree-item elements. |
expand-icon | Override the default chevron icon. |
CSS Parts
| Part | Description |
|---|---|
row | The interactive row element. |
chevron | The chevron region. |
label | The label container. |
children | The nested-children container. |
CSS Custom Properties
| Property | Description |
|---|---|
--hy-tree-item-background-rest | — |
--hy-tree-item-background-hover | — |
--hy-tree-item-background-selected | — |
--hy-tree-item-foreground-default | — |
--hy-tree-item-foreground-subtle | — |
--hy-tree-item-foreground-disabled | — |
--hy-tree-item-gap | — |
--hy-tree-item-padding-block | — |
--hy-tree-item-padding-inline | — |
--hy-tree-item-radius | — |
--hy-tree-item-indent | — |
--hy-tree-item-chevron-size | — |
--hy-tree-item-expand-duration | Transition duration for the expand and collapse animation |
--hy-tree-item-expand-easing | Transition easing for the expand and collapse animation |
Methods
setTabIndex()
Sets tabindex on the focusable row element AND mirrors the tab-stop state to the host's reflected [active] attribute so the focus trap (and CSS) can see which item is the current tab stop. Called by the parent tree's roving-tabindex controller.
focus()
Imperative focus — delegates to the row element.
toggleExpand()
Toggle expansion. No-op if the item has no children or is disabled.