GitHub

Collapsible

A lightweight disclosure for revealing supporting content without an accordion-style container.

Background/tokens/bg
Foreground/tokens/fg
Border/tokens/border

Collapsible reveals supporting content without forcing a full accordion layout. It is built on Radix UI, so the trigger exposes the expected disclosure semantics and keeps keyboard interaction intact while matching the rest of the glass component set.

Use it when you need one independent disclosure with a compact, button-like trigger and content that appears directly underneath. If you need stacked, coordinated sections, use Accordion instead.

Installation

npx @glass-ui-kit/cli add collapsible

Usage

import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
export default function App() {
return (
<Collapsible className="w-full max-w-sm" defaultOpen>
<CollapsibleTrigger>Primary</CollapsibleTrigger>
<CollapsibleContent>
<div className="rounded-glass-sm border border-glass-border/50 bg-white/5 p-3">
Keep related rows available without wrapping them in a heavy card.
</div>
</CollapsibleContent>
</Collapsible>
)
}

Examples

Sizes

Use the size prop to match the trigger to surrounding button density.

Variants

Use the variant prop to tune trigger emphasis without changing the lightweight layout.

Disabled

Use disabled when the disclosure should stay visible but not interactive.

Active disclosures reveal supporting rows directly under the trigger.

Controlled

Use open and onOpenChange when another part of the interface needs to coordinate the disclosure state.

import { useState } from "react"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
export default function ControlledCollapsible() {
const [open, setOpen] = useState(false)
return (
<Collapsible open={open} onOpenChange={setOpen} className="max-w-sm">
<CollapsibleTrigger>Project notes</CollapsibleTrigger>
<CollapsibleContent>
<div className="rounded-glass-sm border border-glass-border/50 bg-white/5 p-3">
This panel stays in sync with surrounding state.
</div>
</CollapsibleContent>
</Collapsible>
)
}

asChild

Use asChild when another interactive element should become the trigger. In that mode, Radix forwards disclosure state and ARIA props to your child, and you are responsible for rendering the label, layout, and any chevron/icon yourself.

import { Button } from "@/components/ui/button"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
export default function CustomTriggerCollapsible() {
return (
<Collapsible className="max-w-sm">
<CollapsibleTrigger asChild>
<Button variant="strong" className="w-full justify-between">
<span>Project notes</span>
<span aria-hidden="true"></span>
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
<div className="rounded-glass-sm border border-glass-border/50 bg-white/5 p-3">
Bring your own trigger content when composing with another component.
</div>
</CollapsibleContent>
</Collapsible>
)
}

Styling

Collapsible follows a prop-first API, but unlike Accordion it does not ship as a framed item container. Reach for variant to adjust trigger depth, then use className for local layout changes such as width constraints or extra spacing around the revealed content.

/* Surface variants */
<Collapsible variant="default" />
<Collapsible variant="soft" />
<Collapsible variant="strong" />
/* Trigger sizes */
<CollapsibleTrigger size="sm" />
<CollapsibleTrigger size="md" />
<CollapsibleTrigger size="lg" />
/* Controlled state */
<Collapsible open={open} onOpenChange={setOpen} />
/* Escape hatches */
<Collapsible className="max-w-md" />
<CollapsibleTrigger className="tracking-wide" />
<CollapsibleContent className="pl-3" />

API Reference

Collapsible

Accepts all Radix Collapsible.Root props.

PropType
defaultOpenboolean
openboolean
onOpenChange(open: boolean) => void
disabledboolean
variant"default" | "soft" | "strong"
classNamestring

variant changes the trigger surface emphasis only. Content remains layout-light so you can compose your own rows, lists, or small token groups underneath.

CollapsibleTrigger

PropType
disabledboolean
asChildboolean
size"sm" | "md" | "lg"
classNamestring

size mirrors the density of Button. In the default trigger mode, CollapsibleTrigger renders the built-in chevron and wraps its children in the compact disclosure layout. When asChild is set, Radix applies trigger props and classes to your child, and your child owns the visible content, spacing, and chevron/icon.

CollapsibleContent

PropType
forceMountboolean
classNamestring