Overview
Get Started
Base UI is a library of high-quality unstyled React components for design systems and web apps.
import {
Accordion,
AccordionItem,
AccordionPanel,
AccordionTrigger,
} from "@/components/ui/accordion";
export function AccordionDemo() {
const items = [
{
content:
"Base UI is a library of high-quality unstyled React components for design systems and web apps.",
id: "1",
title: "What is Base UI?",
},
{
content:
"Head to the \"Quick start\" guide in the docs. If you've used unstyled libraries before, you'll feel at home.",
id: "2",
title: "How do I get started?",
},
{
content: "Of course! Base UI is free and open source.",
id: "3",
title: "Can I use it for my project?",
},
];
return (
<Accordion defaultValue={["1"]} className="max-w-md">
{items.map((item) => (
<AccordionItem key={item.id} value={item.id}>
<AccordionTrigger>{item.title}</AccordionTrigger>
<AccordionPanel>{item.content}</AccordionPanel>
</AccordionItem>
))}
</Accordion>
);
}Installation
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
import { IconChevronDown } from "@tabler/icons-react";
import { cn } from "@/lib/cn";
function Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {
return (
<AccordionPrimitive.Root data-slot="accordion" className={cn("w-full", className)} {...props} />
);
}
function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {
return (
<AccordionPrimitive.Item
data-slot="accordion-item"
className={cn("border-b last:border-b-0", className)}
{...props}
/>
);
}
function AccordionTrigger({ className, children, ...props }: AccordionPrimitive.Trigger.Props) {
return (
<AccordionPrimitive.Header data-slot="accordion-header" className="flex">
<AccordionPrimitive.Trigger
data-slot="accordion-trigger"
className={cn(
"flex flex-1 cursor-pointer items-center justify-between gap-4 py-4 text-left font-medium text-sm outline-none transition-all focus-visible:ring-3 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-panel-open:*:data-[slot=accordion-indicator]:rotate-180",
className
)}
{...props}
>
{children}
<IconChevronDown
data-slot="accordion-indicator"
className="pointer-events-none size-4 shrink-0 translate-y-0.5 opacity-80 transition-transform duration-200 ease-in-out"
/>
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
);
}
function AccordionPanel({ className, children, ...props }: AccordionPrimitive.Panel.Props) {
return (
<AccordionPrimitive.Panel
data-slot="accordion-panel"
className={cn(
"h-(--accordion-panel-height) overflow-hidden text-muted-foreground text-sm transition-[height] duration-200 ease-in-out data-ending-style:h-0 data-starting-style:h-0"
)}
{...props}
>
<div className={cn("pt-0 pb-4", className)}>{children}</div>
</AccordionPrimitive.Panel>
);
}
export {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionPanel,
AccordionPanel as AccordionContent,
};Usage
import {
Accordion,
AccordionItem,
AccordionPanel,
AccordionTrigger,
} from "@/components/ui/accordion";<Accordion>
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionPanel>Yes. It adheres to the WAI-ARIA design pattern.</AccordionPanel>
</AccordionItem>
</Accordion>Examples
Multiple items
Pass multiple prop to Accordion to allow multiple items to be expanded at the same time.
Base UI is a library of high-quality unstyled React components for design systems and web apps.
import {
Accordion,
AccordionItem,
AccordionPanel,
AccordionTrigger,
} from "@/components/ui/accordion";
export function AccordionDemo() {
const items = [
{
content:
"Base UI is a library of high-quality unstyled React components for design systems and web apps.",
id: "1",
title: "What is Base UI?",
},
{
content:
"Head to the \"Quick start\" guide in the docs. If you've used unstyled libraries before, you'll feel at home.",
id: "2",
title: "How do I get started?",
},
{
content: "Of course! Base UI is free and open source.",
id: "3",
title: "Can I use it for my project?",
},
];
return (
<Accordion defaultValue={["1"]} multiple className="max-w-md">
{items.map((item) => (
<AccordionItem key={item.id} value={item.id}>
<AccordionTrigger>{item.title}</AccordionTrigger>
<AccordionPanel>{item.content}</AccordionPanel>
</AccordionItem>
))}
</Accordion>
);
}