Collapsible
An interactive component which expands and collapses a panel.
@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.
open parameter is set to true.
<%= 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.
The animation automatically adjusts to the content height.
This creates a smooth, natural expand/collapse effect.
The 200ms transition provides responsive feedback without feeling sluggish.
Settings Panel
A practical example showing a collapsible settings panel.
Account Settings
Manage your account preferences
<%= 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)
Install the package:
npm install shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
yarn add shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails
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-stateattributes to track open/closed state - Content is properly hidden with
hiddenattribute 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-expandedto the trigger for screen readers - Provide visual indicators (icons, arrows) that show the current state
- Ensure sufficient color contrast for all states
On This Page