Components

Tree view

A nested disclosure list for hierarchies — folders, taxonomies, navigation. Flat and sharp: a chevron that rotates on expand, a faint guide rule for nesting, and an accent left border for the selected row. No radius, no shadow.

Expanded

Fully expanded · one selected
  • Pricing
    • Matrices
      • Standard
      • Volume
    • Currencies
  • Settings
<ul class="ds-tree" role="tree">
  <li class="ds-tree__item" role="treeitem" aria-expanded="true">
    <div class="ds-tree__row">
      <button class="ds-tree__toggle" type="button" aria-expanded="true" aria-label="Toggle">&rsaquo;</button>
      <span class="ds-tree__label">Pricing</span>
    </div>
    <ul class="ds-tree__children" role="group">
      <li class="ds-tree__item" role="treeitem" aria-expanded="true">
        <div class="ds-tree__row">
          <button class="ds-tree__toggle" type="button" aria-expanded="true" aria-label="Toggle">&rsaquo;</button>
          <span class="ds-tree__label">Matrices</span>
        </div>
        <ul class="ds-tree__children" role="group">
          <li class="ds-tree__item" role="treeitem" aria-selected="true">
            <div class="ds-tree__row">
              <span class="ds-tree__toggle ds-tree__toggle--leaf" aria-hidden="true"></span>
              <span class="ds-tree__label is-selected">Standard</span>
            </div>
          </li>
          <li class="ds-tree__item" role="treeitem">
            <div class="ds-tree__row">
              <span class="ds-tree__toggle ds-tree__toggle--leaf" aria-hidden="true"></span>
              <span class="ds-tree__label">Volume</span>
            </div>
          </li>
        </ul>
      </li>
      <li class="ds-tree__item" role="treeitem">
        <div class="ds-tree__row">
          <span class="ds-tree__toggle ds-tree__toggle--leaf" aria-hidden="true"></span>
          <span class="ds-tree__label">Currencies</span>
        </div>
      </li>
    </ul>
  </li>
  <li class="ds-tree__item" role="treeitem">
    <div class="ds-tree__row">
      <span class="ds-tree__toggle ds-tree__toggle--leaf" aria-hidden="true"></span>
      <span class="ds-tree__label">Settings</span>
    </div>
  </li>
</ul>

Interactive

Click chevrons to expand · click labels to select
  • Components
    • Button
  • Tokens
<ul class="ds-tree" role="tree" id="demoTree">
  <li class="ds-tree__item" role="treeitem" aria-expanded="true">
    <div class="ds-tree__row">
      <button class="ds-tree__toggle" type="button" aria-expanded="true" aria-label="Toggle">&rsaquo;</button>
      <span class="ds-tree__label">Components</span>
    </div>
    <ul class="ds-tree__children" role="group">
      <li class="ds-tree__item" role="treeitem" aria-expanded="false">
        <div class="ds-tree__row">
          <button class="ds-tree__toggle" type="button" aria-expanded="false" aria-label="Toggle">&rsaquo;</button>
          <span class="ds-tree__label">Inputs</span>
        </div>
        <ul class="ds-tree__children is-collapsed" role="group">
          <li class="ds-tree__item" role="treeitem">…</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<script>
  (function () {
    var root = document.getElementById("demoTree");
    root.querySelectorAll(".ds-tree__toggle:not(.ds-tree__toggle--leaf)").forEach(function (btn) {
      btn.addEventListener("click", function () {
        var open = btn.getAttribute("aria-expanded") === "true";
        btn.setAttribute("aria-expanded", String(!open));
        var item = btn.closest(".ds-tree__item");
        item.setAttribute("aria-expanded", String(!open));
        var kids = item.querySelector(".ds-tree__children");
        if (kids) kids.classList.toggle("is-collapsed", open);
      });
    });
    root.querySelectorAll(".ds-tree__label").forEach(function (label) {
      label.addEventListener("click", function () {
        root.querySelectorAll(".ds-tree__label.is-selected").forEach(function (s) {
          s.classList.remove("is-selected");
          s.closest(".ds-tree__item").removeAttribute("aria-selected");
        });
        label.classList.add("is-selected");
        label.closest(".ds-tree__item").setAttribute("aria-selected", "true");
      });
    });
  })();
</script>

React

<Tree />
import { Tree } from "@diametral/design-system/react";

const nodes = [
  {
    id: "pricing",
    label: "Pricing",
    children: [
      {
        id: "matrices",
        label: "Matrices",
        children: [
          { id: "standard", label: "Standard" },
          { id: "volume", label: "Volume" },
        ],
      },
      { id: "currencies", label: "Currencies" },
    ],
  },
  { id: "settings", label: "Settings" },
];

<Tree
  nodes={nodes}
  defaultExpanded={["pricing", "matrices"]}
  onSelect={(node) => console.log("selected", node.id)}
/>