Collapsible

An interactive component which expands and collapses a panel.

Stimulus: shadcn--collapsible

@peduarte starred 3 repositories

Installation

Add the component to your project:

rails generate shadcn:component collapsible

Usage

<%= render Shadcn::CollapsibleComponent.new do |collapsible| %>
  <% collapsible.with_trigger do %>
    <%= render Shadcn::ButtonComponent.new(variant: :ghost, size: :sm) do %>
      <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2">
        <circle cx="12" cy="12" r="1"></circle>
        <circle cx="19" cy="12" r="1"></circle>
        <circle cx="5" cy="12" r="1"></circle>
      </svg>
      Can I use this in production?
    <% end %>
  <% end %>
  <% collapsible.with_body do %>
    <div class="rounded-md border px-4 py-3 font-mono text-sm">
      Yes! This component is production-ready and follows the shadcn/ui design system.
    </div>
  <% end %>
<% end %>

Examples

Basic

A simple collapsible with a trigger button and content area.

Initially Open

Set open: true to start with content expanded.

<%= render Shadcn::CollapsibleComponent.new(open: true) do |collapsible| %>
  <% collapsible.with_trigger do %>
    <%= render Shadcn::ButtonComponent.new(variant: :outline) do %>
      Toggle Details
    <% end %>
  <% end %>
  <% collapsible.with_body do %>
    <div class="rounded-md border px-4 py-3 text-sm">
      This content is visible by default because the <code>open</code> parameter is set to <code>true</code>.
    </div>
  <% end %>
<% end %>

Disabled

Prevent toggling by setting disabled: true.

<%= render Shadcn::CollapsibleComponent.new(disabled: true) do |collapsible| %>
  <% collapsible.with_trigger do %>
    <%= render Shadcn::ButtonComponent.new(variant: :ghost, disabled: true) do %>
      Disabled Collapsible
    <% end %>
  <% end %>
  <% collapsible.with_body do %>
    <div class="rounded-md border px-4 py-3 text-sm">
      This content cannot be toggled because the collapsible is disabled.
    </div>
  <% end %>
<% end %>

With Smooth Animation

The collapsible includes smooth height animations by default, powered by the Stimulus controller.

Settings Panel

A practical example showing a collapsible settings panel.

Account Settings

Manage your account preferences

Notification Preferences
Configure how you receive notifications
<%= render Shadcn::CardComponent.new(class_name: "w-full max-w-md") do |card| %>
  <% card.with_header do |header| %>
    <% header.with_title { "Account Settings" } %>
    <% header.with_description { "Manage your account preferences" } %>
  <% end %>
  <% card.with_content do %>
    <div class="space-y-4">
      <%= render Shadcn::CollapsibleComponent.new do |collapsible| %>
        <% collapsible.with_trigger do %>
          <div class="flex items-center justify-between w-full">
            <div class="space-y-0.5">
              <div class="text-sm font-medium">Notification Preferences</div>
              <div class="text-sm text-muted-foreground">Configure how you receive notifications</div>
            </div>
            <%= render Shadcn::ButtonComponent.new(variant: :ghost, size: :sm) do %>
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="m6 9 6 6 6-6"></path>
              </svg>
            <% end %>
          </div>
        <% end %>
        <% collapsible.with_body do %>
          <div class="pt-4 space-y-3">
            <div class="flex items-center justify-between">
              <span class="text-sm">Email notifications</span>
              <%= render Shadcn::SwitchComponent.new %>
            </div>
            <div class="flex items-center justify-between">
              <span class="text-sm">Push notifications</span>
              <%= render Shadcn::SwitchComponent.new %>
            </div>
          </div>
        <% end %>
      <% end %>
    </div>
  <% end %>
<% end %>

Nested Content

Collapsible works with complex nested content and other components.

Project Files

API Reference

CollapsibleComponent

API Reference

Prop Type Default Description
open Boolean false Whether the collapsible starts in the expanded state
disabled Boolean false When true, prevents toggling the collapsible state
class_name String nil Additional CSS classes to apply to the container

Slots

Slot Description
with_trigger The clickable element that toggles the collapsible. Can contain any content (buttons, text, etc.)
with_body The collapsible content that is shown/hidden when toggled

Stimulus Controller

This component requires JavaScript. The Stimulus controller docs provides interactivity.

Manages the collapsible state and handles smooth expand/collapse animations with automatic height calculation.

Installation

Add to your config/importmap.rb:

pin "shadcn-rails", to: "shadcn/index.js"

Then in your app/javascript/controllers/index.js:

import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"

const application = Application.start()
registerShadcnControllers(application)

Or import just this controller:

import DocsController from "shadcn-rails/controllers/docs_controller"

application.register("docs", DocsController)

Targets

Name Description
trigger The clickable element that toggles the state
content The content area that expands/collapses

Values

Name Type Default Description
open Boolean Current open/closed state of the collapsible
disabled Boolean Whether the collapsible is disabled

Actions

Action Description
toggle Toggles between open and closed states (respects disabled)
open Opens the collapsible (respects disabled)
close Closes the collapsible

TypeScript

Type definitions are included. Import types as needed:

import type { DocsController } from "shadcn-rails"

Accessibility

  • Uses data-state attributes to track open/closed state
  • Content is properly hidden with hidden attribute when collapsed
  • Smooth height animations provide visual feedback during state changes
  • Disabled state prevents interaction and can be communicated to assistive technologies
  • Dispatches custom events (opened, closed) for integration with other functionality

Best Practices:

  • Use semantic trigger elements (buttons) with descriptive labels
  • Consider adding aria-expanded to the trigger for screen readers
  • Provide visual indicators (icons, arrows) that show the current state
  • Ensure sufficient color contrast for all states