Blocks

Collapsible

An interactive disclosure that toggles visibility of its content. Small Stimulus controller; composes with sidebar menu sub-items, FAQ-style details, filter panels.

Installation

bin/rails g shadcnrb:component collapsible

Example

Click the trigger to show / hide the content. Pass open: true on the root to start expanded.

@shadcn starred 3 repositories
@radix-ui/primitives
<%= sui.collapsible open: false, class: "w-80 rounded-md border p-3 space-y-2" do |c| %>
  <div class="flex items-center justify-between">
    <span class="text-sm font-medium">@shadcn starred 3 repositories</span>
    <%= c.trigger variant: :ghost, size: :"icon-sm", "aria-label": "Toggle" do %>
      <%= sui.icon :"chevron-down", class: "size-4 transition-transform data-[state=open]:rotate-180" %>
    <% end %>
  </div>
  <div class="text-sm rounded-md border px-3 py-2">@radix-ui/primitives</div>
  <%= c.content class: "space-y-2" do %>
    <div class="text-sm rounded-md border px-3 py-2">@radix-ui/colors</div>
    <div class="text-sm rounded-md border px-3 py-2">@stitches/react</div>
  <% end %>
<% end %>

Composing with sidebar_menu_button

In a sidebar sub-section, the menu button IS the trigger โ€” pass collapsible: true and it wires the toggle action itself instead of nesting a collapsible_trigger inside.

sui.sidebar_wrapper do |s|
  sui.collapsible open: true do |c|
    s.menu_item do
      s.menu_button "Docs", collapsible: true, icon: :folder do
        c.chevron
      end
    end

    c.content do
      s.menu_sub do
        s.menu_sub_item { s.menu_sub_button "Introduction", "#" }
        s.menu_sub_item { s.menu_sub_button "Installation", "#" }
      end
    end
  end
end

API

MethodArgsDescription
sui.collapsibleopen:, **optsRoot. Mounts the shadcnrb--collapsible--component controller; sets initial data-state. Yields a c proxy.
c.trigger(name)**button optsDefault <button> trigger. For custom triggers, add data-action="click->shadcnrb--collapsible--component#toggle" and data-slot="collapsible-trigger" to your element directly.
c.content**optsPanel shown when data-state="open". Uses hidden data-[state=open]:block; stays out of layout when closed.
c.chevronname = :"chevron-down", **optsRotating chevron icon that flips when the surrounding collapsible is open.