SutraUI.TreeView (Sutra UI v0.4.0)

View Source

A hierarchical tree for nested navigation, file browsers, or category structures.

Uses native <details>/<summary> elements for a dependency-free expand/collapse baseline. Pass an id to enable the colocated JS enhancement: roving tabindex, arrow-key navigation, and aria-expanded management.

Each node can be a folder (collapsible) or a leaf (clickable link or selectable item). You control the content via the :trigger slot or the label/icon attrs.

Examples

<.tree_view label="Project files">
  <.tree_item label="lib" expanded>
    <.tree_item label="sutra_ui" expanded>
      <.tree_item label="button.ex" href="/files/button.ex" />
      <.tree_item label="calendar.ex" selected />
    </.tree_item>
  </.tree_item>
  <.tree_item label="README.md" href="/files/README.md" />
</.tree_view>

# Interactive selection — emit an event when a leaf is clicked
<.tree_view id="settings-tree" label="Settings" select_event="select_node">
  <.tree_item label="Workspace" expanded value="ws">
    <.tree_item label="General" value="general" selected />
    <.tree_item label="Members" value="members" />
  </.tree_item>
</.tree_view>

# Custom trigger content
<.tree_item expanded>
  <:trigger>
    <svg viewBox="0 0 24 24" class="size-4" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
      <path d="M3 7h5l2 3h11v9H3z" />
    </svg>
    My Folder
  </:trigger>
  <.tree_item label="child.ex" />
</.tree_item>

Attributes

tree_view:

  • label - Accessible label for the tree. Defaults to "Tree view".
  • id - Stable DOM id. Required for keyboard enhancement and select_event.
  • select_event - When set, leaf nodes without href emit this event with %{"node" => value}.
  • class - Additional CSS classes.

tree_item:

  • label - Node label (used if no :trigger slot).
  • expanded - Expand child nodes by default. Defaults to false.
  • selected - Mark node selected.
  • disabled - Mark node disabled.
  • href - Optional href for leaf nodes (renders as <a>).
  • icon - Custom text/emoji icon for the node.
  • value - Node value, emitted as %{"node" => value} when select_event is set.
  • class - Additional CSS classes.

Slots

  • :trigger - Custom trigger content (overrides label/icon).
  • :inner_block - Child tree items.

Accessibility

  • Uses role="tree" on the container and role="treeitem" on each node.
  • Parent nodes set aria-expanded based on their open/closed state.
  • role="group" on child containers.
  • With id, roving tabindex keeps one focusable item active at a time. Arrow keys move focus:
    • Up/Down — navigate between visible items.
    • Right — expand a collapsed parent, or move into its first child.
    • Left — collapse an expanded parent, or move to the parent.
    • Home/End — jump to first/last visible item.
    • Enter/Space — activate the item (click link, emit select event).
  • <details>/<summary> provides a no-JS baseline — the tree works even if JavaScript fails to load.

Summary

Functions

tree_item(assigns)

Attributes

  • label (:string) - Node label. Defaults to nil.
  • expanded (:boolean) - Expand child nodes by default. Defaults to false.
  • selected (:boolean) - Mark node selected. Defaults to false.
  • disabled (:boolean) - Mark node disabled. Defaults to false.
  • href (:string) - Optional href for leaf nodes. Defaults to nil.
  • icon (:string) - Custom text/emoji icon for the node. Defaults to nil.
  • value (:string) - Node value emitted with select_event. Defaults to nil.
  • class (:any) - Additional CSS classes. Defaults to nil.
  • Global attributes are accepted. Additional HTML attributes.

Slots

  • trigger - Custom trigger content (overrides label/icon).
  • inner_block - Child tree items.

tree_view(assigns)

Attributes

  • label (:string) - Accessible label. Defaults to "Tree view".
  • id (:string) - Stable DOM id for keyboard enhancement. Defaults to nil.
  • select_event (:string) - Event emitted when a leaf node is clicked. Defaults to nil.
  • class (:any) - Additional CSS classes. Defaults to nil.
  • Global attributes are accepted. Additional HTML attributes.

Slots

  • inner_block (required)