v1.1.1

Tree View

A hierarchical tree structure for displaying nested data like file systems or navigation menus.

Interactive Requires: veritheme.js JS init: automatic

File Explorer

Classic file tree with folders and files, expandable/collapsible branches.

html
<div class="vt-w-72 vt-rounded-2xl vt-border vt-border-border-default vt-bg-surface-card vt-p-3" data-tree="">
  <!-- src (open) -->
  <div data-tree-branch="" class="open">
    <button type="button" class="vt-tree-toggle">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4 vt-shrink-0 vt-tree-chevron">
        <path d="m9 18 6-6-6-6"></path>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder-open vt-w-4 vt-h-4 vt-shrink-0 vt-text-info-fill">
        <path d="m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2"></path>
      </svg>
      <span>src</span>
    </button>
    <div class="vt-tree-children">
      <!-- components (open) -->
      <div data-tree-branch="" class="open">
        <button type="button" class="vt-tree-toggle">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4 vt-shrink-0 vt-tree-chevron">
            <path d="m9 18 6-6-6-6"></path>
          </svg>
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder-open vt-w-4 vt-h-4 vt-shrink-0 vt-text-info-fill">
            <path d="m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2"></path>
          </svg>
          <span>components</span>
        </button>
        <div class="vt-tree-children">
          <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-code vt-w-4 vt-h-4 vt-shrink-0 vt-text-success-fill">
              <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 12.5 8 15l2 2.5"></path><path d="m14 12.5 2 2.5-2 2.5"></path>
            </svg> Button.astro</a>
          <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-code vt-w-4 vt-h-4 vt-shrink-0 vt-text-success-fill">
              <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 12.5 8 15l2 2.5"></path><path d="m14 12.5 2 2.5-2 2.5"></path>
            </svg> Card.astro</a>
          <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-code vt-w-4 vt-h-4 vt-shrink-0 vt-text-success-fill">
              <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 12.5 8 15l2 2.5"></path><path d="m14 12.5 2 2.5-2 2.5"></path>
            </svg> Dialog.astro</a>
        </div>
      </div>
      <!-- pages (closed) -->
      <div data-tree-branch="">
        <button type="button" class="vt-tree-toggle">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4 vt-shrink-0 vt-tree-chevron">
            <path d="m9 18 6-6-6-6"></path>
          </svg>
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder vt-w-4 vt-h-4 vt-shrink-0 vt-text-info-fill">
            <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path>
          </svg>
          <span>pages</span>
        </button>
        <div class="vt-tree-children">
          <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-code vt-w-4 vt-h-4 vt-shrink-0 vt-text-success-fill">
              <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 12.5 8 15l2 2.5"></path><path d="m14 12.5 2 2.5-2 2.5"></path>
            </svg> index.astro</a>
          <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-code vt-w-4 vt-h-4 vt-shrink-0 vt-text-success-fill">
              <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 12.5 8 15l2 2.5"></path><path d="m14 12.5 2 2.5-2 2.5"></path>
            </svg> about.astro</a>
        </div>
      </div>
      <!-- styles -->
      <div data-tree-branch="">
        <button type="button" class="vt-tree-toggle">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4 vt-shrink-0 vt-tree-chevron">
            <path d="m9 18 6-6-6-6"></path>
          </svg>
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder vt-w-4 vt-h-4 vt-shrink-0 vt-text-info-fill">
            <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"></path>
          </svg>
          <span>styles</span>
        </button>
        <div class="vt-tree-children">
          <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-text vt-w-4 vt-h-4 vt-shrink-0 vt-text-warning-fill">
              <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 9H8"></path><path d="M16 13H8"></path><path d="M16 17H8"></path>
            </svg> main.scss</a>
        </div>
      </div>
      <!-- root files -->
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-text vt-w-4 vt-h-4 vt-shrink-0 vt-text-foreground-muted">
          <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 9H8"></path><path d="M16 13H8"></path><path d="M16 17H8"></path>
        </svg> package.json</a>
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-text vt-w-4 vt-h-4 vt-shrink-0 vt-text-foreground-muted">
          <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><path d="M10 9H8"></path><path d="M16 13H8"></path><path d="M16 17H8"></path>
        </svg> tsconfig.json</a>
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file-image vt-w-4 vt-h-4 vt-shrink-0 vt-text-error-fill">
          <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path><circle cx="10" cy="12" r="2"></circle><path d="m20 17-1.296-1.296a2.41 2.41 0 0 0-3.408 0L9 22"></path>
        </svg> favicon.svg</a>
    </div>
  </div>
</div>

Tree structure used as a navigation menu with icons.

html
<nav class="vt-w-64 vt-rounded-2xl vt-border vt-border-border-default vt-bg-surface-card vt-p-3" data-tree="">
  <!-- Settings (open) -->
  <div data-tree-branch="" class="open">
    <button type="button" class="vt-tree-toggle">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4 vt-shrink-0 vt-tree-chevron">
        <path d="m9 18 6-6-6-6"></path>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-settings vt-w-4 vt-h-4 vt-shrink-0 vt-text-foreground-muted">
        <path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle>
      </svg>
      <span>Settings</span>
    </button>
    <div class="vt-tree-children">
      <a class="vt-tree-leaf vt-tree-active"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-user vt-w-4 vt-h-4 vt-shrink-0">
          <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle>
        </svg> Profile</a>
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-mail vt-w-4 vt-h-4 vt-shrink-0">
          <path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"></path><rect x="2" y="4" width="20" height="16" rx="2"></rect>
        </svg> Notifications</a>
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-settings vt-w-4 vt-h-4 vt-shrink-0">
          <path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"></path><circle cx="12" cy="12" r="3"></circle>
        </svg> Preferences</a>
    </div>
  </div>
  <!-- Account -->
  <div data-tree-branch="">
    <button type="button" class="vt-tree-toggle">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-4 vt-h-4 vt-shrink-0 vt-tree-chevron">
        <path d="m9 18 6-6-6-6"></path>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-user vt-w-4 vt-h-4 vt-shrink-0 vt-text-foreground-muted">
        <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle>
      </svg>
      <span>Account</span>
    </button>
    <div class="vt-tree-children">
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-shrink-0">
          <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
        </svg> Billing</a>
      <a class="vt-tree-leaf"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-file vt-w-4 vt-h-4 vt-shrink-0">
          <path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"></path><path d="M14 2v5a1 1 0 0 0 1 1h5"></path>
        </svg> Security</a>
    </div>
  </div>
</nav>

Compact

Minimal tree without icons for simple hierarchies.

html
<div class="vt-w-56 vt-rounded-2xl vt-border vt-border-border-default vt-bg-surface-card vt-p-3" data-tree="">
  <div data-tree-branch="" class="open">
    <button type="button" class="vt-tree-toggle">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-3.5 vt-h-3.5 vt-shrink-0 vt-tree-chevron">
        <path d="m9 18 6-6-6-6"></path>
      </svg>
      <span>Documentation</span>
    </button>
    <div class="vt-tree-children">
      <a class="vt-tree-leaf">Getting Started</a>
      <div data-tree-branch="" class="open">
        <button type="button" class="vt-tree-toggle">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-3.5 vt-h-3.5 vt-shrink-0 vt-tree-chevron">
            <path d="m9 18 6-6-6-6"></path>
          </svg>
          <span>Components</span>
        </button>
        <div class="vt-tree-children">
          <a class="vt-tree-leaf">Button</a>
          <a class="vt-tree-leaf">Input</a>
          <a class="vt-tree-leaf">Card</a>
        </div>
      </div>
      <div data-tree-branch="">
        <button type="button" class="vt-tree-toggle">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-chevron-right vt-w-3.5 vt-h-3.5 vt-shrink-0 vt-tree-chevron">
            <path d="m9 18 6-6-6-6"></path>
          </svg>
          <span>Guides</span>
        </button>
        <div class="vt-tree-children">
          <a class="vt-tree-leaf">Theming</a>
          <a class="vt-tree-leaf">Dark Mode</a>
        </div>
      </div>
    </div>
  </div>
</div>

Guidelines

Hierarchical parent/child data (files, org structure) with expand/collapse. Flat data → list.

Do
Use a tree for nested data with expand/collapse.
Don't
Don't force flat, non-nested data into a tree — use a list.

Anatomy

HTML structure of the Tree View component.

div[data-tree]                             ← Tree root
└── div[data-tree-branch]                  ← Expandable branch
    ├── button.vt-tree-toggle              ← Toggle button
    │   ├── svg.vt-tree-chevron            ← Rotating chevron
    │   ├── svg (icon)                     ← Node icon
    │   └── span                           ← Node label
    └── div.vt-tree-children               ← Children wrapper
        ├── div[data-tree-branch]          ← Nested branch (recursive)
        └── a.vt-tree-leaf                 ← Leaf node (no children)

API Reference

All CSS classes available for the Tree View component.

Class Type Description
data-tree Base Root container attribute for tree view initialization
data-tree-branch Base Branch node that can expand/collapse
vt-tree-toggle Base Toggle button for expanding/collapsing a branch
vt-tree-children Base Container for nested items with animated expand/collapse
vt-tree-leaf Base Leaf node (non-expandable item)
vt-tree-chevron Style Rotation indicator that rotates 90deg when branch is open
vt-tree-active State Highlighted state for the currently selected leaf
open State Class on data-tree-branch to expand its children
vt-rounded-2xl vt-border vt-border-border-default Style Card container for the tree
vt-text-info-fill Color Folder icon and active item color
vt-text-success-fill Color Code file icon color

Accessibility

Keyboard and screen reader support.

Feature Details
Role Use role="tree" on container, role="treeitem" on each node
Nesting Nested groups use role="group" inside parent treeitem
Keyboard Arrow keys navigate, Enter/Space select, Left/Right expand/collapse
Expanded Expandable nodes use aria-expanded="true/false"
Selected Selected items use aria-selected="true"
Built with: