For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Collapsible

An interactive section that expands and collapses to show or hide content.

@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

PropTypeDefaultDescription
openboolean—Controlled open state
defaultOpenbooleanfalseInitial open state (uncontrolled)
onOpenChange(open: boolean) => void—Callback when open state changes
disabledbooleanfalsePrevents toggling
soundsbooleanfalsePlays audio feedback on expand/collapse
classNamestring—Additional CSS classes

CollapsibleTrigger

PropTypeDefaultDescription
asChildbooleanfalseRender as child element
classNamestring—Additional CSS classes

CollapsibleContent

PropTypeDefaultDescription
classNamestring—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 internally

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/collapsible