Components
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- Hover Card
- Input
- Input OTP
- Input Group
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
- New Component
Elements
Charts
Icons
@gin-design/ui
@radix-ui/react-collapsible
import { useState } from "react";
import { ChevronsUpDown } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
export const CollapsibleDemo = () => {
const [isOpen, setIsOpen] = useState(false);
return (
<Collapsible open={isOpen} onOpenChange={setIsOpen} className="w-full max-w-sm space-y-2">
<div className="flex items-center justify-between gap-4">
<h4 className="text-sm font-semibold">@gin-design/ui</h4>
<CollapsibleTrigger asChild><Button variant="ghost" size="icon" className="size-8">
<ChevronsUpDown className="size-4" />
<span className="sr-only">Toggle</span>
</Button></CollapsibleTrigger>
</div>
<div className="rounded-md border px-4 py-3 font-mono text-sm">@radix-ui/react-collapsible</div>
<CollapsibleContent className="space-y-2">
<div className="rounded-md border px-4 py-3 font-mono text-sm">@radix-ui/react-dialog</div>
<div className="rounded-md border px-4 py-3 font-mono text-sm">@radix-ui/react-dropdown-menu</div>
</CollapsibleContent>
</Collapsible>
);
};With Sound
Pass sounds to enable audio feedback on expand and collapse.
<Collapsible sounds open={isOpen} onOpenChange={setIsOpen}>
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
<CollapsibleContent>Content</CollapsibleContent>
</Collapsible>Controlled
Manage open state externally with open and onOpenChange.
"use client";
import { useState } from "react";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
export function CollapsibleControlled() {
const [isOpen, setIsOpen] = useState(false);
return (
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
<CollapsibleTrigger>
{isOpen ? "Hide" : "Show"} details
</CollapsibleTrigger>
<CollapsibleContent>
<p>Hidden content revealed on toggle.</p>
</CollapsibleContent>
</Collapsible>
);
}Uncontrolled
Use defaultOpen for uncontrolled state — no useState needed.
<Collapsible defaultOpen>
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
<CollapsibleContent>Open by default.</CollapsibleContent>
</Collapsible>Props
Collapsible
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state |
defaultOpen | boolean | false | Initial open state (uncontrolled) |
onOpenChange | (open: boolean) => void | — | Callback when open state changes |
disabled | boolean | false | Prevents toggling |
sounds | boolean | false | Plays audio feedback on expand/collapse |
className | string | — | Additional CSS classes |
CollapsibleTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Render as child element |
className | string | — | Additional CSS classes |
CollapsibleContent
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS classes |
Usage
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
// Basic
<Collapsible>
<CollapsibleTrigger>Show more</CollapsibleTrigger>
<CollapsibleContent>
<p>Hidden content</p>
</CollapsibleContent>
</Collapsible>
// Controlled with sound
const [open, setOpen] = useState(false);
<Collapsible sounds open={open} onOpenChange={setOpen}>
<CollapsibleTrigger asChild>
<Button variant="ghost">Toggle</Button>
</CollapsibleTrigger>
<CollapsibleContent>
<p>Content</p>
</CollapsibleContent>
</Collapsible>Specs
# Mint — Collapsible Specs
## Component
- name: collapsible
- file: registry/mint/collapsible.tsx
- installs to: components/ui/collapsible.tsx
- dependencies: radix-ui
- registryDependencies: none
## What is it
A low-level primitive for toggling a single content section open or closed.
Use it when you need a standalone show/hide toggle without group coordination.
Prefer Accordion when you have multiple related collapsible sections; use
Collapsible for isolated, independent toggles.
## Visual identity
Collapsible applies no visual styling of its own — it is a behaviour-only
wrapper. All colour, radius, and density comes from whatever elements you
place inside it.
## Sub-components
- Collapsible → root; manages open/closed state and sounds
- CollapsibleTrigger → button element that toggles the open state; supports asChild
- CollapsibleContent → region shown when open, hidden when closed
## States
- data-[state=open]: content is visible; trigger reflects open state
- data-[state=closed]: content is hidden; trigger reflects closed state
- data-[disabled]: toggling is prevented; set via disabled prop on root
## Conventions
- Use asChild on CollapsibleTrigger to render a Button or any custom element as the trigger
- CollapsibleContent has no default padding or animation — add className as needed
- For animated expand/collapse: apply overflow-hidden with a CSS max-height or height transition on CollapsibleContent
- Do not nest Collapsible inside Accordion — they conflict on state management
- sounds / haptic: GIN Design exclusive — pass sounds to play audio feedback (expand/collapse) on interaction; powered by useFeedback hook and @/audio/core sound definitions
- Sub-components expose data-slot="collapsible", data-slot="collapsible-trigger", and data-slot="collapsible-content" for CSS targeting
- Controlled mode: pass open + onOpenChange; uncontrolled mode: use defaultOpen and let Radix manage state internallyInstallation
$ npx shadcn add \https://gin-design.vercel.app/collapsible