Collapsible
LayoutA controlled or uncontrolled disclosure for related content.
Responsive viewport — resize the window to explore. Direction and density apply only to this preview. Theme applies to the docs too.
"use client";
import {
Collapsible,
CollapsibleTrigger,
CollapsibleContent,
} from "@/components/ui/collapsible";
import { Button } from "@dashboardpack/core/components/ui/button";
import { useState } from "react";
import { ChevronDown } from "lucide-react";
export default function CollapsibleExample() {
const [open, setOpen] = useState(false);
return (
<div className="w-full max-w-sm">
<Collapsible open={open} onOpenChange={setOpen}>
<div className="flex items-center justify-between gap-4 rounded-lg border p-3">
<div>
<p className="text-sm font-medium">Project attachments</p>
<p className="text-xs text-muted-foreground">
3 files in this project
</p>
</div>
<CollapsibleTrigger asChild>
<Button
size="icon-sm"
variant="ghost"
aria-label={open ? "Hide attachments" : "Show attachments"}
>
<ChevronDown className={open ? "size-4 rotate-180" : "size-4"} />
</Button>
</CollapsibleTrigger>
</div>
<CollapsibleContent className="pt-2">
{["Brand guidelines.pdf", "Project brief.md", "Assets.zip"].map(
(file) => (
<div key={file} className="rounded-lg border px-3 py-2 text-sm">
{file}
</div>
),
)}
</CollapsibleContent>
</Collapsible>
</div>
);
}Usage
Wrap a trigger and content in Collapsible. Use asChild on the trigger with a single button child. Use Accordion for a collection of related disclosures.
import {
Collapsible,
CollapsibleTrigger,
CollapsibleContent,
} from "@/components/ui/collapsible";Shipped as editable source in src/components/ui/collapsible.tsx in both apps. Copy the implementation below when moving it to another project. Copy the complete example from Source code for all imports and state. Add "use client" when using hooks or event handlers. See installation and theming for project setup.
Component source
The complete implementation is included in both apps. It uses the React, Radix, Lucide, and shared-core dependencies already installed in Apex. Keep your project’s semantic theme tokens when reusing it.
src/components/ui/collapsible.tsx
"use client";
import type { ComponentProps } from "react";
import { cn } from "@dashboardpack/core/lib/utils";
import { Collapsible as Primitive } from "radix-ui";
export const Collapsible = Primitive.Root;
export const CollapsibleTrigger = Primitive.Trigger;
export function CollapsibleContent({
className,
...props
}: ComponentProps<typeof Primitive.Content>) {
return (
<Primitive.Content
className={cn("space-y-2 text-sm data-[state=closed]:hidden", className)}
{...props}
/>
);
}API reference
Common props and defaults. Slot-specific props are named below; native elements also accept their standard HTML attributes. The component TypeScript definitions are the complete type reference.
| Prop | Type / Default | Description |
|---|---|---|
| open / defaultOpen | booleanDefault: false | Controlled or initial visibility. |
| onOpenChange | (open: boolean) => voidDefault: — | Respond to disclosure changes. |
| disabled | booleanDefault: false | Prevent interaction. |
| asChild (CollapsibleTrigger) | booleanDefault: false | Use your own single trigger element. |