Accordion

A vertically stacked set of interactive headings that each reveal a section of content.

Installation

Install the following dependencies:

npm install @radix-ui/react-accordion lucide-react

Copy and paste the following code into your project.

'use client';
 
import * as AccordionPrimitive from '@radix-ui/react-accordion';
import clsx from 'clsx';
import { ChevronDown } from 'lucide-react';
import { ComponentPropsWithoutRef, ElementRef, forwardRef } from 'react';
import styles from './styles.module.scss';
 
const Accordion = AccordionPrimitive.Root;
 
const AccordionItem = forwardRef<
    ElementRef<typeof AccordionPrimitive.Item>,
    ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
    <AccordionPrimitive.Item ref={ref} className={clsx(styles.item, className)} {...props} />
));
AccordionItem.displayName = 'AccordionItem';
 
const AccordionTrigger = forwardRef<
    ElementRef<typeof AccordionPrimitive.Trigger>,
    ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
    <AccordionPrimitive.Header className={styles.header}>
        <AccordionPrimitive.Trigger ref={ref} className={clsx(styles.trigger, className)} {...props}>
            {children}
            <ChevronDown className={styles.chevron} />
        </AccordionPrimitive.Trigger>
    </AccordionPrimitive.Header>
));
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
 
const AccordionContent = forwardRef<
    ElementRef<typeof AccordionPrimitive.Content>,
    ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => (
    <AccordionPrimitive.Content ref={ref} className={styles.content} {...props}>
        <div className={clsx(styles.content__inner, className)}>{children}</div>
    </AccordionPrimitive.Content>
));
 
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
 
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };

Update the import paths to match your project setup.

Usage

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion';
<Accordion type='single' collapsible>
    <AccordionItem value='item-1'>
        <AccordionTrigger>Is it accessible?</AccordionTrigger>
        <AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent>
    </AccordionItem>
</Accordion>