Component
Accordion

Accordion

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

Installation

Install the following dependencies

npm i @radix-ui/react-accordion

Copy and paste the following code into your project

components/ui/accordion/index.tsx
'use client'
 
import * as React from 'react'
import * as AccordionPrimitive from '@radix-ui/react-accordion'
import { ChevronDown } from 'lucide-react'
import { createStyleContext } from '@shadow-panda/style-context'
import { styled } from '@shadow-panda/styled-system/jsx'
import { accordion } from '@shadow-panda/styled-system/recipes'
 
const { withProvider, withContext } = createStyleContext(accordion)
 
const Header = withContext(styled(AccordionPrimitive.Header), 'header')
 
const Trigger = React.forwardRef<
  React.ElementRef<typeof AccordionPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ children, ...props }, ref) => (
  <Header>
    <AccordionPrimitive.Trigger ref={ref} {...props}>
      {children}
      <ChevronDown />
    </AccordionPrimitive.Trigger>
  </Header>
))
Trigger.displayName = AccordionPrimitive.Trigger.displayName
 
const Content = React.forwardRef<
  React.ElementRef<typeof AccordionPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ children, ...props }, ref) => (
  <AccordionPrimitive.Content ref={ref} {...props}>
    <div>{children}</div>
  </AccordionPrimitive.Content>
))
Content.displayName = AccordionPrimitive.Content.displayName
 
export const Accordion = withProvider(styled(AccordionPrimitive.Root), 'root')
export const AccordionItem = withContext(styled(AccordionPrimitive.Item), 'item')
export const AccordionTrigger = withContext(styled(Trigger), 'trigger')
export const AccordionContent = withContext(styled(Content), 'content')

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>