Accordion Component

Accessible, flexible accordion with uncontrolled & controlled modes, multiple-open support, disabled items and custom headers.

Single Open (Default)

By default, only one item can be open at a time. Clicking a new item closes the previously open one.

Multiple Open Allowed

Add multiple to allow several items to stay open at the same time.

Pre-opened Items

Use defaultOpenIds for uncontrolled initial state.

Custom Headers, Disabled Items & Styling

Titles can be any ReactNode, items can be disabled, and you can style items via className on each item or itemClassName on the accordion.

Controlled Usage

Control the open state from outside using openIds and onOpenChange. This is useful when syncing with URL state, forms or other UI.

Currently open IDs: item1

Usage Examples

Basic Accordion

import { Accordion } from "@/components/accordion";

const items = [
  {
    id: "item1",
    title: "Title 1",
    content: <div>Content 1</div>,
  },
  {
    id: "item2",
    title: "Title 2",
    content: <div>Content 2</div>,
  },
];

<Accordion items={items} />;

Accordion with Multiple Open

<Accordion items={items} multiple />;

Accordion with Default Open Items (Uncontrolled)

<Accordion
  items={items}
  defaultOpenIds={["item1", "item2"]}
/>;

Disabled Item & Custom Header

const items = [
  {
    id: "item1",
    title: (
      <div className="flex items-center gap-2">
        <Info className="h-4 w-4" />
        <span>Title with icon</span>
      </div>
    ),
    content: <div>Content 1</div>,
  },
  {
    id: "item2",
    title: "Disabled item",
    disabled: true,
    content: <div>Disabled content</div>,
  },
];

<Accordion items={items} />;

Controlled Accordion (openIds & onOpenChange)

const [openIds, setOpenIds] = useState<string[]>(["item1"]);

<Accordion
  items={items}
  multiple
  openIds={openIds}
  onOpenChange={setOpenIds}
/>;