CoreUI is in beta - APIs and components may change.
CoreUI
Base Components

Accordion

Allows you to display content in a collapsible manner, making it easy for users to access information while conserving screen space.


Installation

Install the following dependencies:

npm install @radix-ui/react-accordion

Create a accordion.tsx file and paste the following code into it.

components/ui/accordion.tsx
// CoreUI Accordion v0.0.0'use client';import * as React from 'react';import * as AccordionPrimitive from '@radix-ui/react-accordion';import { RiAddLine, RiSubtractLine } from '@remixicon/react';import { cn } from '@/utils/cn';import type { PolymorphicComponentProps } from '@/utils/polymorphic';const ACCORDION_ITEM_NAME = 'AccordionItem';const ACCORDION_ICON_NAME = 'AccordionIcon';const ACCORDION_ARROW_NAME = 'AccordionArrow';const ACCORDION_TRIGGER_NAME = 'AccordionTrigger';const ACCORDION_CONTENT_NAME = 'AccordionContent';const AccordionRoot = AccordionPrimitive.Root;const AccordionHeader = AccordionPrimitive.Header;const AccordionItem = React.forwardRef<  React.ComponentRef<typeof AccordionPrimitive.Item>,  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>>(({ className, ...rest }, forwardedRef) => {  return (    <AccordionPrimitive.Item      ref={forwardedRef}      className={cn(        // base        'group/accordion',        'rounded-10 bg-bg-white-0 p-3.5 ring-1 ring-inset ring-stroke-soft-200',        'transition duration-200 ease-out',        // hover        'hover:bg-bg-weak-50 hover:ring-transparent',        // has-focus-visible        'has-[:focus-visible]:bg-bg-weak-50 has-[:focus-visible]:ring-transparent',        // open        'data-[state=open]:bg-bg-weak-50 data-[state=open]:ring-transparent',        className,      )}      {...rest}    />  );});AccordionItem.displayName = ACCORDION_ITEM_NAME;const AccordionTrigger = React.forwardRef<  React.ComponentRef<typeof AccordionPrimitive.Trigger>,  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>>(({ children, className, ...rest }, forwardedRef) => {  return (    <AccordionPrimitive.Trigger      ref={forwardedRef}      className={cn(        // base        'w-[calc(100%+theme(space.7))] text-left text-label-sm text-text-strong-950',        'grid auto-cols-auto grid-flow-col grid-cols-[auto_minmax(0,1fr)] items-center gap-2.5',        '-m-3.5 p-3.5 outline-none',        // focus        'focus:outline-none',        className,      )}      {...rest}    >      {children}    </AccordionPrimitive.Trigger>  );});AccordionTrigger.displayName = ACCORDION_TRIGGER_NAME;function AccordionIcon<T extends React.ElementType>({  className,  as,  ...rest}: PolymorphicComponentProps<T>) {  const Component = as || 'div';  return (    <Component      className={cn('size-5 text-text-sub-600', className)}      {...rest}    />  );}AccordionIcon.displayName = ACCORDION_ICON_NAME;type AccordionArrowProps = React.HTMLAttributes<HTMLDivElement> & {  openIcon?: React.ElementType;  closeIcon?: React.ElementType;};// open/closefunction AccordionArrow({  className,  openIcon: OpenIcon = RiAddLine,  closeIcon: CloseIcon = RiSubtractLine,  ...rest}: AccordionArrowProps) {  return (    <>      <OpenIcon        className={cn(          'size-5 text-text-soft-400',          'transition duration-200 ease-out',          // hover          'group-hover/accordion:text-text-sub-600',          // open          'group-data-[state=open]/accordion:hidden',          className,        )}        {...rest}      />      <CloseIcon        className={cn(          'size-5 text-text-sub-600',          // close          'hidden group-data-[state=open]/accordion:block',          className,        )}        {...rest}      />    </>  );}AccordionArrow.displayName = ACCORDION_ARROW_NAME;const AccordionContent = React.forwardRef<  React.ComponentRef<typeof AccordionPrimitive.Content>,  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>>(({ children, className, ...rest }, forwardedRef) => {  return (    <AccordionPrimitive.Content      ref={forwardedRef}      className='overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down'      {...rest}    >      <div        className={cn('pt-1.5 text-paragraph-sm text-text-sub-600', className)}      >        {children}      </div>    </AccordionPrimitive.Content>  );});AccordionContent.displayName = ACCORDION_CONTENT_NAME;export {  AccordionRoot as Root,  AccordionHeader as Header,  AccordionItem as Item,  AccordionTrigger as Trigger,  AccordionIcon as Icon,  AccordionArrow as Arrow,  AccordionContent as Content,};

Examples

Arrow Position

API Reference

This component is based on the Radix UI Accordion primitives. Refer to their documentation for the API reference.

Accordion.Root

This component is based on the Accordion.Root primitive.

Accordion.Item

This component is based on the Accordion.Item primitive.

Accordion.Header

This component is based on the Accordion.Header primitive.

Accordion.Trigger

This component is based on the Accordion.Trigger primitive.

Accordion.Content

This component is based on the Accordion.Content primitive.

Accordion.Icon

This component is polymorphic, allowing you to change the underlying HTML element using the as prop.

PropTypeDefault
asReact.ElementTypediv

Accordion.Arrow

The Accordion.Arrow component displays an icon that toggles between an open and closed state based on the accordion's state.

PropTypeDefault
openIconReact.ElementTypeRiAddLine
closeIconReact.ElementTypeRiSubtractLine

On this page