Accordion

A collapsible content component built with Radix UI.

Import

import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@/components/ui';

Basic Usage

<Accordion type="single" collapsible>
  <AccordionItem value="item-1">
    <AccordionTrigger>Is this accessible?</AccordionTrigger>
    <AccordionContent>
      Yes. It adheres to the WAI-ARIA design pattern.
    </AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2">
    <AccordionTrigger>Is it styled?</AccordionTrigger>
    <AccordionContent>
      Yes. It comes with default styles that match your design system.
    </AccordionContent>
  </AccordionItem>
</Accordion>

Props

Accordion (Root)

Prop Type Default Description
type 'single' | 'multiple' required Single or multiple items open
collapsible boolean false Allow collapsing all (single mode)
defaultValue string | string[] - Initially open item(s)

AccordionItem

Prop Type Default Description
value string required Unique identifier

Single vs Multiple

Single (One at a time)

<Accordion type="single" collapsible>
  <AccordionItem value="1">...</AccordionItem>
  <AccordionItem value="2">...</AccordionItem>
</Accordion>

Multiple (Many open)

<Accordion type="multiple">
  <AccordionItem value="1">...</AccordionItem>
  <AccordionItem value="2">...</AccordionItem>
</Accordion>

Default Open

{/* Single - open item-1 by default */}
<Accordion type="single" defaultValue="item-1">
  ...
</Accordion>

{/* Multiple - open multiple by default */}
<Accordion type="multiple" defaultValue={['item-1', 'item-3']}>
  ...
</Accordion>

FAQ Example

const faqs = [
  {
    question: 'What payment methods do you accept?',
    answer: 'We accept all major credit cards, PayPal, and bank transfers.',
  },
  {
    question: 'Can I cancel my subscription?',
    answer: 'Yes, you can cancel anytime from your account settings.',
  },
  {
    question: 'Do you offer refunds?',
    answer: 'We offer a 30-day money-back guarantee on all plans.',
  },
];

export function FAQ() {
  return (
    <Accordion type="single" collapsible className="w-full">
      {faqs.map((faq, index) => (
        <AccordionItem key={index} value={`item-${index}`}>
          <AccordionTrigger>{faq.question}</AccordionTrigger>
          <AccordionContent>{faq.answer}</AccordionContent>
        </AccordionItem>
      ))}
    </Accordion>
  );
}

Settings Panel

export function SettingsAccordion() {
  return (
    <Accordion type="multiple" defaultValue={['general']}>
      <AccordionItem value="general">
        <AccordionTrigger>General Settings</AccordionTrigger>
        <AccordionContent>
          <div className="space-y-4">
            <Input label="Site Name" />
            <Select label="Language">
              <option value="en">English</option>
              <option value="es">Spanish</option>
            </Select>
          </div>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="notifications">
        <AccordionTrigger>Notifications</AccordionTrigger>
        <AccordionContent>
          <div className="space-y-4">
            <Switch label="Email notifications" checked />
            <Switch label="Push notifications" checked={false} />
          </div>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="security">
        <AccordionTrigger>Security</AccordionTrigger>
        <AccordionContent>
          <div className="space-y-4">
            <Switch label="Two-factor authentication" checked />
            <Button outline>Change Password</Button>
          </div>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  );
}

Features