# VelvetKit

## Collapsible (`UI::Collapsible`)

A section that opens and closes under its trigger, like a branch of a nav tree.

Add it: `bin/rails generate velvetkit:add collapsible`

Also adds: `icon`

### Arguments

```ruby
UI::Collapsible.new(open: false, size: :default, trigger_class: nil, content_class: nil, class: nil, **html_attrs)
```

Slots: `with_trigger`

### Notes

A section that opens and closes under its trigger: a tree of links in a
sidebar, "Show more" details, an advanced-settings block.

Built on <details> and <summary>, so it works before any JavaScript loads,
Enter and Space toggle it, screen readers announce it as expanded or
collapsed, and find-in-page opens it to show a match. Browsers that can
animate to auto height slide it open; the rest open it at once.

  <%= render(UI::Collapsible.new(open: current_page_is_a_form?)) do |c| %>
    <% c.with_trigger { "Forms" } %>
    <%= link_to "Input", input_path %>
  <% end %>

Collapsibles nest, so a trigger inside the content makes a deeper branch.

### Example: Navigation tree

```erb
<%# A sidebar tree: branches open on click, and the one holding the current page starts open. %>
<nav aria-label="Documentation" class="w-56 text-sm">
  <%= render(UI::Collapsible.new(open: true, trigger_class: "font-medium hover:bg-accent", content_class: "ml-3 space-y-0.5 border-l pl-2")) do |c| %>
    <% c.with_trigger { "Forms" } %>
    <a href="#" class="block rounded-md px-3 py-1.5 text-muted-foreground hover:bg-accent hover:text-foreground">Input</a>
    <a href="#" aria-current="page" class="block rounded-md bg-primary/10 px-3 py-1.5 font-medium text-primary">Textarea</a>
    <%= render(UI::Collapsible.new(trigger_class: "text-muted-foreground hover:bg-accent hover:text-foreground", content_class: "ml-3 space-y-0.5 border-l pl-2")) do |inner| %>
      <% inner.with_trigger { "Choices" } %>
      <a href="#" class="block rounded-md px-3 py-1.5 text-muted-foreground hover:bg-accent hover:text-foreground">Select</a>
      <a href="#" class="block rounded-md px-3 py-1.5 text-muted-foreground hover:bg-accent hover:text-foreground">Checkbox</a>
    <% end %>
  <% end %>
  <%= render(UI::Collapsible.new(trigger_class: "font-medium hover:bg-accent", content_class: "ml-3 space-y-0.5 border-l pl-2")) do |c| %>
    <% c.with_trigger { "Overlays" } %>
    <a href="#" class="block rounded-md px-3 py-1.5 text-muted-foreground hover:bg-accent hover:text-foreground">Dialog</a>
    <a href="#" class="block rounded-md px-3 py-1.5 text-muted-foreground hover:bg-accent hover:text-foreground">Sheet</a>
  <% end %>
</nav>
```

### Example: Show more

```erb
<div class="max-w-md rounded-lg border p-4">
  <p class="text-sm">Payments are collected on the 1st of each month.</p>
  <%= render(UI::Collapsible.new(size: :sm, class: "mt-2", trigger_class: "w-auto -ml-2 text-primary hover:underline")) do |c| %>
    <% c.with_trigger { "How refunds work" } %>
    <p class="px-0 text-sm text-muted-foreground">Cancel within 14 days for a full refund. After that, the rest of the month is credited to your next invoice.</p>
  <% end %>
</div>
```
