Skip to content

tree-rows

Terminal window
$ npx shadcn@latest add https://lacodda.github.io/dowel/r/tree-rows.json
See it liveThe same tree flattened, closed and open.→

Split out of TreeView for the reason table-sort and calendar-math were split out of theirs: these are the sums, and the component is the thing that draws them.

Flattening is what makes the keyboard simple. Down is the next row of this list and Up the previous, and neither has to know about nesting. A recursive walk at every keystroke would ask the same question — what is visually next — and answer it differently at each depth.

const rows = visibleRows(nodes, open)
// [{ node, depth: 0, parent: undefined }, { node, depth: 1, parent: 'src' }, …]

parent is what Left uses. Getting out of a deep folder in one press rather than walking back up through every sibling needs to know which branch a row is inside — and that is a fact about the flattened list, not about the node.

It is also the answer to “how many rows is this tree”, which is what a product needs before putting a tree inside a VirtualList: the window has to be computed from the visible rows, and those depend on what is open.

An empty folder is a folder. children: [] says nothing — absence of children is what a leaf looks like — so empty marks a folder that opens and shows nothing, and isBranch counts it as one.

Type
visibleRows (nodes, open, depth?, parent?) => TreeRow[] The rows, in the order the eye travels
isBranch (node) => boolean Something that opens, even if empty
TreeNode { id, label, children?, empty? }
TreeRow { node, depth, parent? }

Accessibility

The examples on the stand, through axe 4.14.0 in a browser, in both themes, against WCAG 2.2 A and AA and axe's best practices: 5 rules applied and passed, and none failed. The accessibility report has every item.

History

Each release that changed ui/tree-rows.tsx - the file a product copies - newest first.

  1. v0.22.0
    • feat a long list, a deep one, and the facts beside them 4cbd42e