Collapsible
A trigger-and-panel pair for file trees, advanced settings, and show-more sections — with the neobrutalist borders-and-shadows treatment.
"use client"
import * as React from "react"The collapsible is the accordion's single-section sibling: one trigger, one panel, open or closed. Built on the Base UI Collapsible component and styled to the neobrutalist recipe: thick borders, hard shadows, and bold type.
Reach for it when:
- File trees and nested navigation — nest collapsibles to expand folders (see the file tree example below).
- Advanced settings — keep the common options visible and fold the rest behind a toggle.
- "Show more" content — long changelogs, truncated lists, optional detail on dense pages.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/collapsible.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/collapsible.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/collapsible.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/collapsible.json
Install the following dependencies:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copy and paste the following code into your project.
"use client"
import { Collapsible as CollapsiblePrimitive } from "radix-ui"
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.CollapsibleTrigger>) {
return (
<CollapsiblePrimitive.CollapsibleTrigger
data-slot="collapsible-trigger"
{...props}
/>
)
}
function CollapsibleContent({
className,
...props
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
return (
<CollapsiblePrimitive.CollapsibleContent
data-slot="collapsible-content"
// Radix publishes the measured height as
// `--radix-collapsible-content-height`; the collapsible-down/up keyframes
// interpolate against it for a real slide open/close.
className={cn(
"overflow-hidden data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up",
className
)}
{...props}
/>
)
}
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
Update the import paths to match your project setup.
Usage#
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible"<Collapsible>
<CollapsibleTrigger>Can I use this in my project?</CollapsibleTrigger>
<CollapsibleContent>
Yes. Free to use for personal and commercial projects. No attribution
required.
</CollapsibleContent>
</Collapsible>Composition#
Use the following composition to build a Collapsible:
Collapsible
├── CollapsibleTrigger
└── CollapsibleContentControlled State#
Use the open and onOpenChange props to control the state.
import * as React from "react"
export function Example() {
const [open, setOpen] = React.useState(false)
return (
<Collapsible open={open} onOpenChange={setOpen}>
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
<CollapsibleContent>Content</CollapsibleContent>
</Collapsible>
)
}Examples#
Basic#
import { ChevronDownIcon } from "@/registry/icons/__lucide__"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"Settings Panel#
Use a trigger button to reveal additional settings.
"use client"
import * as React from "react"File Tree#
Use nested collapsibles to build a file tree.
import { ChevronRightIcon, FileIcon, FolderIcon } from "lucide-react"
import { Button } from "@/components/ui/button"RTL#
To enable RTL support in Neobrutalism.com, see the RTL configuration guide.
"use client"
import * as React from "react"Accessibility#
The collapsible follows the WAI-ARIA Disclosure pattern: the trigger is a real button wired with aria-expanded and aria-controls, so screen readers announce whether the panel is open.
Keyboard interactions:
| Key | Action |
|---|---|
Tab / Shift + Tab | Move focus to and from the trigger |
Space / Enter | Toggle the panel |
API Reference#
See the Base UI documentation for more information.