The Collapsible component provides a simple way to show and hide content. It’s useful for hiding secondary information, creating expandable sections, or managing space-constrained interfaces.
Installation
npx shadcn@latest add @eo-n/collapsible
Copy the component code
Copy and paste the Collapsible component code into your project at components/ui/collapsible.tsx.components/ui/collapsible.tsx
"use client";
import * as React from "react";
import { Collapsible as CollapsiblePrimitive } from "@base-ui/react";
import { cn } from "@/lib/utils";
function Collapsible({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
}
function CollapsibleTrigger({
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.Trigger>) {
return (
<CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />
);
}
function CollapsibleContent({
className,
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.Panel>) {
return (
<CollapsiblePrimitive.Panel
data-slot="collapsible-content"
className={cn(
"flex h-[var(--collapsible-panel-height)] flex-col overflow-hidden text-sm transition-all duration-300 ease-out data-[ending-style]:h-0 data-[starting-style]:h-0",
className
)}
{...props}
/>
);
}
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
Update imports
Update the import paths to match your project setup.
Usage
Import the Collapsible components and compose them together:
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
<Collapsible>
<CollapsibleTrigger>Is there any cost involved?</CollapsibleTrigger>
<CollapsibleContent>
No, it's completely free to use for both personal and professional projects.
</CollapsibleContent>
</Collapsible>
Component API
Collapsible
The root container component that manages collapsible state.
Whether the collapsible is open by default.
The controlled open state of the collapsible.
Callback fired when the open state changes.
Whether the collapsible is disabled.
CollapsibleTrigger
The trigger element that toggles the collapsible content.
Additional CSS classes to apply to the trigger.
CollapsibleContent
The content that can be collapsed or expanded.
Additional CSS classes to apply to the content.
Examples
Basic Collapsible
<Collapsible>
<CollapsibleTrigger asChild>
<Button variant="ghost">Toggle Details</Button>
</CollapsibleTrigger>
<CollapsibleContent>
<div className="rounded-md border p-4">
<p>Additional details appear here when expanded.</p>
</div>
</CollapsibleContent>
</Collapsible>
With Custom Trigger
<Collapsible>
<CollapsibleTrigger className="flex items-center gap-2 p-2 hover:bg-muted rounded-md">
<ChevronRight className="h-4 w-4 transition-transform data-[state=open]:rotate-90" />
<span className="font-medium">More Information</span>
</CollapsibleTrigger>
<CollapsibleContent className="pl-8 pt-2">
<p className="text-sm text-muted-foreground">
This is additional information that can be toggled on and off.
</p>
</CollapsibleContent>
</Collapsible>
Default Open
<Collapsible defaultOpen>
<CollapsibleTrigger>Terms and Conditions</CollapsibleTrigger>
<CollapsibleContent>
<p>Read our terms and conditions...</p>
</CollapsibleContent>
</Collapsible>
Controlled Collapsible
function ControlledCollapsible() {
const [isOpen, setIsOpen] = React.useState(false);
return (
<div className="space-y-2">
<Button onClick={() => setIsOpen(!isOpen)}>
{isOpen ? "Hide" : "Show"} Advanced Settings
</Button>
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
<CollapsibleContent>
<div className="space-y-2 p-4 border rounded-md">
<p>Advanced settings go here</p>
</div>
</CollapsibleContent>
</Collapsible>
</div>
);
}
FAQ Section
<div className="space-y-2">
<Collapsible>
<CollapsibleTrigger className="flex justify-between w-full p-4 text-left hover:bg-muted rounded-md">
<span className="font-medium">What is included?</span>
<ChevronDown className="h-4 w-4" />
</CollapsibleTrigger>
<CollapsibleContent className="px-4 pb-4">
<p>All components are included with full source code and documentation.</p>
</CollapsibleContent>
</Collapsible>
<Collapsible>
<CollapsibleTrigger className="flex justify-between w-full p-4 text-left hover:bg-muted rounded-md">
<span className="font-medium">How do I get started?</span>
<ChevronDown className="h-4 w-4" />
</CollapsibleTrigger>
<CollapsibleContent className="px-4 pb-4">
<p>Install via CLI or copy the components manually into your project.</p>
</CollapsibleContent>
</Collapsible>
</div>
Disabled State
<Collapsible disabled>
<CollapsibleTrigger className="opacity-50 cursor-not-allowed">
Disabled Section
</CollapsibleTrigger>
<CollapsibleContent>
<p>This content cannot be accessed.</p>
</CollapsibleContent>
</Collapsible>
Collapsible vs Accordion
Use Collapsible when:
- You need a single independent expandable section
- You want full control over the trigger styling and layout
- You’re building custom expandable UI patterns
Use Accordion when:
- You have multiple related sections that should work as a group
- You want only one section open at a time (or controlled multi-open)
- You need the standard accordion interaction pattern
Accessibility
The Collapsible component is built on Base UI’s accessible Collapsible primitive, which:
- Uses appropriate ARIA attributes for state communication
- Supports keyboard navigation (Space/Enter to toggle)
- Properly manages focus
- Announces state changes to screen readers
- Respects reduced motion preferences
For more details, see the Base UI Collapsible documentation.