Skip to main content

Treegrid

Hierarchical grid combining tree and grid patterns.

Usage

<w-treegrid label="File browser">
<w-slot row data-level="1" expandable>
<div>
<w-slot cell><div>Documents</div></w-slot>
<w-slot cell><div>Folder</div></w-slot>
</div>
</w-slot>
<w-slot row data-level="2">
<div>
<w-slot cell><div>Report.pdf</div></w-slot>
<w-slot cell><div>File</div></w-slot>
</div>
</w-slot>
</w-treegrid>

Sized columns

Use size="N" on a cell slot to give it a wider flex grow value. Sizes 1–12 are supported.

<w-treegrid label="File browser">
<w-slot row data-level="1" expandable>
<div>
<w-slot cell size="2"><div>Name</div></w-slot>
<w-slot cell><div>Type</div></w-slot>
</div>
</w-slot>
</w-treegrid>

Fixed height + sticky header

Set height on the treegrid to make it scroll, and add sticky to a row slot to pin it to the top. Give the header row a solid background so scrolling content doesn't bleed through.

<w-treegrid height="240px">
<w-slot row sticky>
<div style="background: #f5f5f5;">
<w-slot cell><div>Name</div></w-slot>
<w-slot cell><div>Type</div></w-slot>
</div>
</w-slot>
<!-- many rows… -->
</w-treegrid>

Layout

Rows default to display: flex and cells default to flex: 1, so a bare treegrid lays out as a horizontal row of equal-width cells without any inline styles. <w-slot cell size="N"> sets flex: N on the cell (1–12). Defaults are applied with zero specificity (:where()), so any inline style="flex: ..." or class-based rule overrides them — note that custom cell classes (e.g. a .treegrid-cell { flex: 1 } rule) will override size because class selectors out-rank :where().

Props

PropTypeDefaultDescription
labelstring""Accessible label
selection-mode"none" | "single" | "multiple""single"Selection behavior on rows
heightstringCSS height (e.g. "240px", "50vh"). Applies overflow: auto for you.

Slots

SlotElementDescription
rowContainerGrid row (use data-level, expandable attributes)
cellAnyGrid cell

Row Attributes

AttributeDescription
data-levelNesting level (1, 2, 3, etc.)
expandableRow can be expanded
stickyPins the row to the top of a scrolling treegrid (position: sticky)

Cell Attributes

AttributeValuesDescription
size112Sets flex: N on the cell. Default 1.

Keyboard

KeyAction
ArrowRightExpand row or move right
ArrowLeftCollapse row or move left
ArrowDownNext visible row
ArrowUpPrevious visible row

Styling

Rows are flex; cells default to flex: 1. Depth is exposed via aria-level and the library mirrors expansion state to data-expanded. aria-selected marks selected rows.

/* Indent rows by depth */
w-treegrid w-slot[row] > *[aria-level="1"] {
padding-left: 0;
}
w-treegrid w-slot[row] > *[aria-level="2"] {
padding-left: 1.5rem;
}
w-treegrid w-slot[row] > *[aria-level="3"] {
padding-left: 3rem;
}

/* Expanded folder row */
w-treegrid w-slot[row] > *[aria-expanded="true"] {
background: #fafafa;
}

/* Selected row */
w-treegrid w-slot[row] > *[aria-selected="true"] {
background: #eef2ff;
}

/* Sticky header */
w-treegrid w-slot[row][sticky] > * {
background: #f5f5f5;
font-weight: 600;
}
SelectorTargets
w-treegrid w-slot[row] > *[aria-level="N"]Rows at depth N
w-treegrid w-slot[row] > *[aria-expanded="true"]Expanded folder row
w-treegrid w-slot[row] > *[aria-selected="true"]Selected row
w-treegrid w-slot[row][sticky] > *Sticky header row

Accessibility

  • Combines role="treegrid" with tree navigation
  • Rows have aria-expanded when expandable
  • aria-level indicates depth