Components
Accordion
A collapsible accordion component with filled, stroke, and connected list variants. Built on Radix Accordion for full accessibility.
Installation
bunx @happlyui/cli@latest add accordion
Dependencies
npm packages
@radix-ui/react-accordion@remixicon/react
Registry dependencies
These are automatically installed when you add this component.
tvpolymorphichapply-ui-utils
Usage
import * as Accordion from "@/components/ui/accordion"
<Accordion.Root type="single" collapsible>
<Accordion.Item value="a">
<Accordion.Trigger>
<Accordion.Icon as={Icon} />
Title
<Accordion.Arrow />
</Accordion.Trigger>
<Accordion.Content>Content</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
Examples
Default (Filled)
Default filled variant with icons. Items fill with a background color when open.
<Accordion.Root type='single' collapsible className='space-y-6'>
<Accordion.Item value='a'>
<Accordion.Trigger>
<Accordion.Icon as={RiAccountCircleLine} />
How do I update my account information?
<Accordion.Arrow />
</Accordion.Trigger>
<Accordion.Content className='px-[30px]'>
Insert the accordion description here.
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
Arrow Start
Arrow positioned at the start of the trigger instead of the end.
<Accordion.Root type='single' collapsible className='space-y-6'>
<Accordion.Item value='a'>
<Accordion.Trigger>
<Accordion.Arrow />
Insert your accordion title here
</Accordion.Trigger>
<Accordion.Content className='pl-[30px]'>
Insert the accordion description here.
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
Stroke Variant
Stroke variant keeps a visible border when open instead of filling with background color.
<Accordion.Root type='single' collapsible className='space-y-6'>
<Accordion.Item value='a' variant='stroke'>
<Accordion.Trigger>
<Accordion.Icon as={RiAccountCircleLine} />
Title
<Accordion.Arrow />
</Accordion.Trigger>
<Accordion.Content className='px-[30px]'>
Content
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
Stroke with Arrow Start
Stroke variant with arrow positioned at the start.
<Accordion.Root type='single' collapsible className='space-y-6'>
<Accordion.Item value='a' variant='stroke'>
<Accordion.Trigger>
<Accordion.Arrow />
Insert your accordion title here
</Accordion.Trigger>
<Accordion.Content className='pl-[30px]'>
Content
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
List (Connected)
Connected list variant. Items are joined inside one bordered container, separated by top dividers, with a chevron-in-a-button arrow that rotates open. The container styling lives on Accordion.Root, the list variant on each Accordion.Item.
<Accordion.Root
type='single'
collapsible
className='overflow-hidden rounded-2xl border border-stroke-soft-200 bg-bg-white-0 shadow-regular-xs'
>
<Accordion.Item value='a' variant='list'>
<Accordion.Trigger className='py-4 pr-3 pl-5'>
<Accordion.Icon as={RiUser3Line} />
Business profile
<Accordion.Chevron />
</Accordion.Trigger>
<Accordion.Content className='px-5 pt-0 pb-4 pl-[50px]'>
Manage your company details shown across the platform.
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
Group (Composed)
Composed group component with items as props and arrow at end.
const items = [
{ value: 'a', title: 'Account info', content: 'Details...', icon: RiAccountCircleLine },
{ value: 'b', title: 'Payments', content: 'Details...', icon: RiQuestionLine },
];
<Accordion.Group type='single' collapsible items={items} />
Group with Arrow Start
Composed group with arrow positioned at the start.
<Accordion.Group type='single' collapsible items={items} arrowPosition='start' />
Group Stroke
Composed group with stroke variant.
<Accordion.Group type='single' collapsible items={items} variant='stroke' />
Group Stroke Arrow Start
Composed group with stroke variant and arrow at start.
<Accordion.Group type='single' collapsible items={items} variant='stroke' arrowPosition='start' />
Group List (Connected)
Composed group with the connected list variant. The container, dividers, chevron arrow, and content padding are all handled automatically.
<Accordion.Group type='single' collapsible items={items} variant='list' />
API Reference
Accordion.Root
The root container. Wraps Radix Accordion.Root.
| Prop | Type | Default | Description |
|---|---|---|---|
type | 'single' | 'multiple' | - | Whether one or multiple items can be open at a time |
collapsible | boolean | false | When type is 'single', allows closing all items |
Accordion.Item
An individual collapsible section.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | Unique value for this item |
variant | 'filled' | 'stroke' | 'list' | 'filled' | Visual style. Filled fills with background on open, stroke keeps a border, list joins items into a connected, divider-separated container (container styling applied on Accordion.Root) |
Accordion.Trigger
The clickable header that toggles the content.
| Prop | Type | Default | Description |
|---|
Accordion.Icon
Polymorphic icon slot for the trigger. Renders any icon component via the `as` prop.
| Prop | Type | Default | Description |
|---|---|---|---|
as | React.ElementType | - | The icon component to render |
Accordion.Arrow
Toggle indicator that shows +/- icons based on open state.
| Prop | Type | Default | Description |
|---|---|---|---|
openIcon | React.ElementType | RiAddLine | Icon shown when the item is closed |
closeIcon | React.ElementType | RiSubtractLine | Icon shown when the item is open |
Accordion.Chevron
Toggle indicator used by the list variant. Renders a chevron inside a bordered button box that rotates 180° when the item is open.
| Prop | Type | Default | Description |
|---|---|---|---|
icon | React.ElementType | RiArrowDownSLine | The chevron icon component to render |
Accordion.Content
The collapsible content area with slide animation.
| Prop | Type | Default | Description |
|---|
Accordion.Group
Composed accordion that renders items from props. Handles arrow placement and content padding automatically.
| Prop | Type | Default | Description |
|---|---|---|---|
items | AccordionGroupItem[] | - | Array of items with value, title, content, and optional icon |
variant | 'filled' | 'stroke' | 'list' | 'filled' | Visual style applied to all items. The list variant renders a connected container with a chevron arrow |
arrowPosition | 'start' | 'end' | 'end' | Position of the +/- toggle arrow |
type | 'single' | 'multiple' | - | Whether one or multiple items can be open at a time |
collapsible | boolean | false | When type is 'single', allows closing all items |