Accordion
Allow users to reveal or hide grouped content, reducing scrolling when multiple sections are on a single page
#Examples
The Accordion component is based on the Card component, where the Card.Header is converted into a button. The heading functions as a control that enable users to reveal or hide the associated section of content.
Terms for understanding accordions include:
- Accordion Header: Label for or thumbnail representing a section of content that also serves as a control for showing and hiding the section of content.
- Accordion Content: Section of content associated with an accordion header.
#Basic Usage
In its simplest form, the Accordion just needs the header content being set with the Accordion.Content subcomponent and the content being set with Accordion.Body subcomponent.
<Accordion>
	<Accordion.Header>Accordion header</Accordion.Header>
	<Accordion.Body>
		<Content>Accordion content goes here</Content>
	</Accordion.Body>
</Accordion>#Header Usage
The Accordion takes props for the heading but alignment, tooltipText, and tooltipPlacement has been omitted since they are conflicting with accordion styling.
<Accordion>
	<Accordion.Header level="h1" lookalike="h3" lineHeight="multi-line">
		Accordion header content
	</Accordion.Header>
	<Accordion.Body>
		<Content>Accordion content goes here</Content>
	</Accordion.Body>
</Accordion>Accordion.Header can also be used with custom elements.
<Accordion>
	<Accordion.Header>
		<div>
			<H2>Accordion header content</H2>
			<Paragraph tone="subtle">Accordion header description</Paragraph>
		</div>
	</Accordion.Header>
	<Accordion.Body>
		<Content>Accordion content goes here</Content>
	</Accordion.Body>
</Accordion>#Footer Usage
The Accordion needs the footer being set with the Accordion.Footer subcomponent.
<Accordion>
	<Accordion.Header>Accordion header</Accordion.Header>
	<Accordion.Body>
		<Content>Accordion content goes here</Content>
	</Accordion.Body>
	<Accordion.Footer>
		<Content>Accordion footer</Content>
	</Accordion.Footer>
</Accordion>#Expand Usage
The Accordion can be expanded/collapsed from outside the component. The component keeps the state itself whether it's expanded or not, but it will update it if the expanded prop changes. This can also be used to expand the Accordion by default by setting expanded={true}
const [expanded, setExpanded] = useState(true);
return (
	<>
		<Button onClick={() => setExpanded(!expanded)}>Toggle accordion</Button>
		<Accordion expanded={expanded}>
			<Accordion.Header>Accordion header</Accordion.Header>
			<Accordion.Body>
				<Content>Accordion content goes here</Content>
			</Accordion.Body>
		</Accordion>
	</>
);#Expand Callback Usage
The callback method onSetExpanded can be used to trigger code whenever the Accordion is toggled.
return (
	<Accordion onSetExpanded={(expanded) => console.log("Accordion expanded:", expanded)}>
		<Accordion.Header>Accordion header</Accordion.Header>
		<Accordion.Body>
			<Content>Accordion content goes here</Content>
		</Accordion.Body>
	</Accordion>
);#Illustration Usage
Both the header and content takes a ReactNode so they can both just be an illustration. But remember alt text!
<Accordion>
	<Accordion.Header>
		<Illustration
			src={
				props.theme === "agentic-ai-2025" ? IllustrationPromoteAgenticAi2025 : IllustrationPromote
			}
			alt="Promote content"
			size="small"
		/>
	</Accordion.Header>
	<Accordion.Body>
		<Illustration
			src={
				props.theme === "agentic-ai-2025"
					? IllustrationInitiateAgenticAi2025
					: IllustrationInitiate
			}
			alt="Initiate content"
		/>
	</Accordion.Body>
</Accordion>#Table Usage
const [items, setItems] = useState(someData);
const [sort, setSort] = useState<SortField<typeof items[0]>>({
	property: "title",
	direction: "asc",
});
const [loading, setLoading] = useState(true);
useEffect(() => {
	setItems(sortItems(items, sort));
	setLoading(false);
}, [sort]);
return (
	<Accordion>
		<Accordion.Header>Table</Accordion.Header>
		<Accordion.Body>
			<Table
				columns={[
					{
						header: {
							property: "title",
							content: "Dish",
							defaultSortDirection: "asc",
							"data-observe-key": "table-header-dish",
						},
						render: (dto) => dto.title,
						options: {
							isKeyColumn: true,
						},
					},
					{
						header: {
							content: "Cook Time",
							tooltip: "in minutes",
							"data-observe-key": "table-header-cook-time",
						},
						render: (dto) => dto.cookTime,
					},
					{
						header: {
							property: "servings",
							content: "Servings",
							tooltip: "in persons",
							notSortable: true,
							"data-observe-key": "table-header-servings",
						},
						render: (dto) => dto.servings,
					},
				]}
				items={items}
				sort={sort}
				setSort={(property, direction) => {
					setLoading(true);
					setSort({
						property: property,
						direction: property === sort.property ? invertDirection(sort.direction) : direction,
					});
				}}
				loading={loading}
				caption="Basic usage table"
			/>
		</Accordion.Body>
	</Accordion>
);#Menu Usage
<Accordion>
	<Accordion.Header>Accordion header</Accordion.Header>
	<Accordion.Body>
		<ActionList
			items={[
				{ text: "Actionbutton", onClick: () => console.log("clicked") },
				{ text: "ActionLink", href: "https://www.google.com", openNew: true },
				ActionList.divider,
				{
					text: "Disabled actionbutton",
					onClick: () => console.log("clicked"),
					disabled: true,
				},
				{
					text: "ActionLink",
					href: "https://www.google.com",
					openNew: true,
				},
				ActionList.divider,
				{
					text: "Actionbutton",
					onClick: () => console.log("clicked"),
				},
			]}
		/>
	</Accordion.Body>
</Accordion>#Menu With Custom Render
const items = [
	{
		text: "First link",
		href: "#first",
		count: 1,
	},
	{
		text: "Second link",
		href: "#second",
		count: 2,
	},
];
return (
	<Accordion style={{ width: "300px" }}>
		<Accordion.Header>Accordion header</Accordion.Header>
		<Accordion.Body>
			<ActionList
				items={items}
				itemRenderer={(props) => {
					const item = props.item as LinkItem & { count: number };
					return (
						<LinkContainer
							tabIndex={-1}
							href={item.href}
							style={{
								width: "100%",
								padding: "10px",
								display: "flex",
								justifyContent: "space-between",
							}}
						>
							<LinkContainer.LinkText>{item.text}</LinkContainer.LinkText>
							<Badge>{item.count}</Badge>
						</LinkContainer>
					);
				}}
			/>
		</Accordion.Body>
	</Accordion>
);#Properties
| Property | Description | Defined | Value | 
|---|---|---|---|
| childrenOptional | element | ||
| expandedOptional | boolean | ||
| onSetExpandedOptional | function | ||
| data-componentOptional | stringName of the component. Should only be set by components since it needs to stable. Used to track component usage | ||
| classNameOptional | stringCustom className that's applied to the outermost element (only intended for special cases) | ||
| styleOptional | objectStyle object to apply custom inline styles (only intended for special cases) | ||
| data-observe-keyOptional | stringUnique string, used by external script e.g. for event tracking | 
#Guidelines
#Best practices
#Do not use when
#Accessibility
Explore detailed guidelines for this component: Accessibility Specifications