Tree view
A nested, collapsible list of things inside other things: files, teams, a documentation sidebar. Nested lists and <details>, so it works with Tab alone and no script.
A file tree
Three levels deep. The current file is aria-current, and every folder on its way is open; the others start shut.
<div class="w-72">
<%= tree_view label: "Files" do |tree| %>
<% tree.branch "app", icon: :folder do |app| %>
<% app.branch "models", icon: :folder do |models| %>
<% models.branch "concerns", icon: :folder do |concerns| %>
<% concerns.leaf "searchable.rb", href: "#", icon: :file_code %>
<% end %>
<% models.leaf "invoice.rb", href: "#", icon: :file_code, current: true %>
<% models.leaf "invoice_line_item_with_a_rather_long_name.rb", href: "#", icon: :file_code %>
<% end %>
<% app.branch "views", icon: :folder do |views| %>
<% views.leaf "index.html.erb", href: "#", icon: :file_code %>
<% end %>
<% end %>
<% tree.leaf "Gemfile", href: "#", icon: :file %>
<% tree.leaf "README.md", href: "#", icon: :file_text %>
<% end %>
</div>Markup in a leaf
A leaf's block takes markup, a badge here. meta: keeps a short reading whole at the end of the row while the label truncates.
Design
<div class="w-72">
<%= tree_view label: "Teams" do |tree| %>
<% tree.branch "Engineering", open: true, meta: 3 do |engineering| %>
<% engineering.leaf href: "#" do %>Platform <%= badge "on call", tone: :warn %><% end %>
<% engineering.leaf "Payments", href: "#", meta: 8 %>
<% engineering.leaf "Search and recommendations", href: "#", meta: 5 %>
<% end %>
<% tree.branch "Design", meta: 1 do |design| %>
<% design.leaf "Brand", href: "#", meta: 4 %>
<% end %>
<% end %>
</div>Without guides
guides: false drops the line beside each level. An empty branch says so.
Getting started
Recipes
Empty
<div class="w-72">
<%= tree_view label: "Guides", guides: false do |tree| %>
<% tree.branch "Getting started", open: true do |start| %>
<% start.leaf "Installation", href: "#" %>
<% start.leaf "Theming", href: "#" %>
<% end %>
<% tree.branch "Recipes", open: true %>
<% end %>
</div>