Theme
Customize appearance
Components
Accordion
Reveal related sections without leaving the page.
View component source ↗Preview
A minimal example to get started.
Installation
Install this component and its dependencies in a project initialized with shadcn.
pnpm dlx shadcn@latest add https://ui.hyunjoon.net/r/accordion.jsonUsage
This is the basic example. Use the Code tab above for the selected example. Adjust import aliases to match your project.
import {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionContent,
} from "@/components/ui/accordion";
export default function Example() {
return (
<Accordion className="w-full max-w-sm">
<AccordionItem value="source">
<AccordionTrigger>Can I customize the source?</AccordionTrigger>
<AccordionContent>Yes. The installed files belong to your project.</AccordionContent>
</AccordionItem>
<AccordionItem value="theme">
<AccordionTrigger>Does it support theming?</AccordionTrigger>
<AccordionContent>Use your shared Tailwind and CSS variable tokens.</AccordionContent>
</AccordionItem>
</Accordion>
);
}
API reference
Derived from the installed component types. Native DOM props are also supported where applicable. A dash means no explicit default is documented. Some props depend on the selected mode.
Accordion
| Prop | Type | Default | Description |
|---|---|---|---|
value | AccordionValue<any> | undefinedAccordionValue<any> | undefined | — | The controlled value of the item(s) that should be expanded. To render an uncontrolled accordion, use the `defaultValue` prop instead. |
defaultValue | AccordionValue<any> | undefinedAccordionValue<any> | undefined | — | The uncontrolled value of the item(s) that should be initially expanded. To render a controlled accordion, use the `value` prop instead. |
disabled | boolean | undefinedboolean | undefined | false | Whether the component should ignore user interaction. |
hiddenUntilFound | boolean | undefinedboolean | undefined | false | Allows the browser's built-in page search to find and expand the panel contents. Overrides the `keepMounted` prop and uses `hidden="until-found"` to hide the element without removing it from the DOM. |
keepMounted | boolean | undefinedboolean | undefined | false | Whether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. |
loopFocus | boolean | undefinedboolean | undefined | true | Whether to loop keyboard focus back to the first item when the end of the list is reached while using the arrow keys. |
onValueChange | ((value: AccordionValue<any>, eventDetails: AccordionRootChangeEventDetails) => void) | un…((value: AccordionValue<any>, eventDetails: AccordionRootChangeEventDetails) => void) | undefined | — | Event handler called when an accordion item is expanded or collapsed. Provides the new value as an argument. |
multiple | boolean | undefinedboolean | undefined | false | Whether multiple items can be open at the same time. |
orientation | Orientation | undefinedOrientation | undefined | 'vertical' | The visual orientation of the accordion. Controls whether roving focus uses left/right or up/down arrow keys. |
ref | React.Ref<HTMLDivElement> | undefinedReact.Ref<HTMLDivElement> | undefined | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
id | string | undefinedstring | undefined | — | Unique identifier used to associate labels and descriptions. |
children | React.ReactNodeReact.ReactNode | — | Content rendered inside this component. |
onFocus | ((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the control receives focus. |
onBlur | ((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the control loses focus. |
onChange | ((event: BaseUIEvent<React.ChangeEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.ChangeEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the underlying form control changes; inspect the event for its value. |
onKeyDown | ((event: BaseUIEvent<React.KeyboardEvent<HTMLDivElement>>) => void) | undefined((event: BaseUIEvent<React.KeyboardEvent<HTMLDivElement>>) => void) | undefined | — | Called when a key is pressed while this element is focused. |
onClick | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | undefined((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | undefined | — | Called when the element is activated. |
className | string | ((state: AccordionPrimitive.Root.State<any>) => string | undefined) | undefinedstring | ((state: AccordionPrimitive.Root.State<any>) => string | undefined) | undefined | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
render | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn…React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionPrimitive.Root.State<any>> | undefined | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | React.CSSProperties | ((state: AccordionPrimitive.Root.State<any>) => React.CSSProperties …React.CSSProperties | ((state: AccordionPrimitive.Root.State<any>) => React.CSSProperties | undefined) | undefined | — | Style applied to the element, or a function that returns a style object based on the component's state. |
AccordionItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | anyany | — | A unique value that identifies this accordion item. If no value is provided, a unique ID will be generated automatically. Use when controlling the accordion programmatically, or to set an initial open state. |
onOpenChange | ((open: boolean, eventDetails: AccordionPrimitive.Item.ChangeEventDetails) => void) | unde…((open: boolean, eventDetails: AccordionPrimitive.Item.ChangeEventDetails) => void) | undefined | — | Event handler called when the panel is opened or closed. |
ref | React.Ref<HTMLDivElement> | undefinedReact.Ref<HTMLDivElement> | undefined | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
id | string | undefinedstring | undefined | — | Unique identifier used to associate labels and descriptions. |
children | React.ReactNodeReact.ReactNode | — | Content rendered inside this component. |
onFocus | ((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the control receives focus. |
onBlur | ((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the control loses focus. |
onChange | ((event: BaseUIEvent<React.ChangeEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.ChangeEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the underlying form control changes; inspect the event for its value. |
onKeyDown | ((event: BaseUIEvent<React.KeyboardEvent<HTMLDivElement>>) => void) | undefined((event: BaseUIEvent<React.KeyboardEvent<HTMLDivElement>>) => void) | undefined | — | Called when a key is pressed while this element is focused. |
onClick | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | undefined((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | undefined | — | Called when the element is activated. |
className | string | ((state: AccordionItemState) => string | undefined) | undefinedstring | ((state: AccordionItemState) => string | undefined) | undefined | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
render | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn…React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionItemState> | undefined | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | React.CSSProperties | ((state: AccordionItemState) => React.CSSProperties | undefined) | u…React.CSSProperties | ((state: AccordionItemState) => React.CSSProperties | undefined) | undefined | — | Style applied to the element, or a function that returns a style object based on the component's state. |
disabled | boolean | undefinedboolean | undefined | false | Whether the component should ignore user interaction. |
AccordionTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
nativeButton | boolean | undefinedboolean | undefined | true | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). |
ref | React.Ref<HTMLButtonElement> | undefinedReact.Ref<HTMLButtonElement> | undefined | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
id | string | undefinedstring | undefined | — | Unique identifier used to associate labels and descriptions. |
children | React.ReactNodeReact.ReactNode | — | Content rendered inside this component. |
onFocus | ((event: BaseUIEvent<React.FocusEvent<HTMLButtonElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLButtonElement, Element>>) => void) | undefined | — | Called when the control receives focus. |
onBlur | ((event: BaseUIEvent<React.FocusEvent<HTMLButtonElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLButtonElement, Element>>) => void) | undefined | — | Called when the control loses focus. |
onChange | ((event: BaseUIEvent<React.ChangeEvent<HTMLButtonElement, Element>>) => void) | undefined((event: BaseUIEvent<React.ChangeEvent<HTMLButtonElement, Element>>) => void) | undefined | — | Called when the underlying form control changes; inspect the event for its value. |
onKeyDown | ((event: BaseUIEvent<React.KeyboardEvent<HTMLButtonElement>>) => void) | undefined((event: BaseUIEvent<React.KeyboardEvent<HTMLButtonElement>>) => void) | undefined | — | Called when a key is pressed while this element is focused. |
onClick | ((event: BaseUIEvent<React.MouseEvent<HTMLButtonElement, MouseEvent>>) => void) | undefine…((event: BaseUIEvent<React.MouseEvent<HTMLButtonElement, MouseEvent>>) => void) | undefined | — | Called when the element is activated. |
disabled | boolean | undefinedboolean | undefined | — | Prevents user interaction. |
name | string | undefinedstring | undefined | — | Field name used in form data. |
type | "button" | "submit" | "reset" | undefined"button" | "submit" | "reset" | undefined | — | The native input or button behavior. |
value | string | number | readonly string[] | undefinedstring | number | readonly string[] | undefined | — | The current value when controlled by the application. |
className | string | ((state: AccordionTriggerState) => string | undefined) | undefinedstring | ((state: AccordionTriggerState) => string | undefined) | undefined | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
render | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn…React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionTriggerState> | undefined | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | React.CSSProperties | ((state: AccordionTriggerState) => React.CSSProperties | undefined) …React.CSSProperties | ((state: AccordionTriggerState) => React.CSSProperties | undefined) | undefined | — | Style applied to the element, or a function that returns a style object based on the component's state. |
AccordionContent
| Prop | Type | Default | Description |
|---|---|---|---|
ref | React.Ref<HTMLDivElement> | undefinedReact.Ref<HTMLDivElement> | undefined | — | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). |
id | string | undefinedstring | undefined | — | Unique identifier used to associate labels and descriptions. |
children | React.ReactNodeReact.ReactNode | — | Content rendered inside this component. |
onFocus | ((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the control receives focus. |
onBlur | ((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.FocusEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the control loses focus. |
onChange | ((event: BaseUIEvent<React.ChangeEvent<HTMLDivElement, Element>>) => void) | undefined((event: BaseUIEvent<React.ChangeEvent<HTMLDivElement, Element>>) => void) | undefined | — | Called when the underlying form control changes; inspect the event for its value. |
onKeyDown | ((event: BaseUIEvent<React.KeyboardEvent<HTMLDivElement>>) => void) | undefined((event: BaseUIEvent<React.KeyboardEvent<HTMLDivElement>>) => void) | undefined | — | Called when a key is pressed while this element is focused. |
onClick | ((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | undefined((event: BaseUIEvent<React.MouseEvent<HTMLDivElement, MouseEvent>>) => void) | undefined | — | Called when the element is activated. |
className | string | ((state: AccordionPanelState) => string | undefined) | undefinedstring | ((state: AccordionPanelState) => string | undefined) | undefined | — | CSS class applied to the element, or a function that returns a class based on the component's state. |
render | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn…React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, AccordionPanelState> | undefined | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
style | React.CSSProperties | ((state: AccordionPanelState) => React.CSSProperties | undefined) | …React.CSSProperties | ((state: AccordionPanelState) => React.CSSProperties | undefined) | undefined | — | Style applied to the element, or a function that returns a style object based on the component's state. |
hiddenUntilFound | boolean | undefinedboolean | undefined | false | Allows the browser's built-in page search to find and expand the panel contents. Overrides the `keepMounted` prop and uses `hidden="until-found"` to hide the element without removing it from the DOM. |
keepMounted | boolean | undefinedboolean | undefined | false | Whether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. |
Usage notes
Compose one AccordionItem per section with a stable value. Use defaultValue for an initially open section.