Styles live in scss/components/_tree.scss. A tree is a nested <ul class="tree"> with role="tree", expandable folders, and file rows. The component is narrow by default (150px); widen it in your layout when labels are longer.
Expand/collapse toggle
.tree__toggle is a 24px round control with a 16px chevron. Add .tree__toggle--open to rotate the arrow. Use aria-expanded and aria-controls on the button, and toggle the hidden attribute on the matching .tree__group.
Level 1 row states
Each row is a flex line: toggle + .tree__content (16px icon in a 20px slot + label). Selected rows use .tree__row--selected and aria-current="true" on the label button.
Levels 2 and 3 (live)
.tree__row--level-2 indents folders. Files at level 3 use .tree__row--level-3 and a .tree__toggle-spacer so the label aligns with folder rows. This mini tree is interactive (data-tree-live).
Click the chevrons to expand/collapse, and a row label to select it.
File type icons
PimentCSS does not ship icons. In this doc we use Phosphor (ph-image, ph-file-pdf, etc.): pick one glyph per media type and reuse it for every matching extension.
File tree (interactive)
Example with folders and mixed files. Chevrons expand branches; clicking a name selects that row. Production apps should add keyboard support per the ARIA treeview pattern.
<ul class="tree" role="tree" data-tree-live="" aria-label="Files">
<li role="treeitem" aria-expanded="false">
<div class="tree__row"><button type="button" class="tree__toggle" aria-expanded="false" aria-controls="group-a" aria-label="Expand Assets">…</button><button type="button" class="tree__content">
<span class="tree__icon" aria-hidden="true">…</span>
<span class="tree__label">Assets</span>
</button></div>
<ul class="tree__group" id="group-a" role="group" hidden="">
<li role="treeitem">
<div class="tree__row tree__row--level-3"><span class="tree__toggle-spacer" aria-hidden="true"></span><button type="button" class="tree__content">…</button></div>
</li>
</ul>
</li>
</ul>
JavaScript
import { wireAllTrees } from './tree-behavior';
wireAllTrees();
Class reference
| Class | Description |
|---|---|
.tree | Root list (column, max-width 150px by default) |
.tree__group | Nested ul for children |
.tree__row | Horizontal row (toggle + content) |
.tree__row--level-2 | 16px left inset for nested folders |
.tree__row--level-3 | 16px inset + .tree__toggle-spacer (aligns with folder row) |
.tree__toggle-spacer | Empty slot when a row has no toggle (files) |
.tree__row--selected | Selected row |
.tree__toggle | 24px expand/collapse control |
.tree__toggle--open | Chevron rotated 90° |
.tree__content | Label button (icon + text) |
.tree__icon | 20px slot, 16px icon |
.tree__label | Truncated label text |
Customize (Sass)
-
Tree spacing
Adjust indentation and icon sizes. Override max-width on .tree in your app if filenames are long.@use "pimentcss-design-system" with ( $tree-level-2-pl: 1rem, $tree-level-3-pl: 1rem, $tree-icon-size: 1.25rem ); -
Rebuild CSS
Run after editing _tree.scss.npm run build:css
Accessibility (RGAA / WCAG)
Tree widget
- Roles, root
role="tree", itemsrole="treeitem", child listsrole="group". - Expand, set
aria-expandedon the toggle and matchingtreeitem; hide collapsed groups with thehiddenattribute. - Controls, link toggle to its group with
aria-controls+ stableidon.tree__group. - Selection, expose the current node with
aria-current="true"on.tree__content(single-select side nav). - Keyboard, for production apps follow the ARIA treeview pattern (arrows, Home/End); the doc demo uses pointer interaction only.