Accordion

Accordion is a stacked list of expandable items that users can open and close to reveal or hide content. It helps organize information efficiently.

The accordion can be built using the following component,

  • AccordionItem – The container for each item / section.
  • AccordionHeader – The clickable element that toggles visibility.
  • AccordionPanel – The content area that expands or collapses.

Available from eds-core/1.20.0

Quick Start

Installation
npm install @adaptavant/eds-core
Import
import { Accordion } from '@adaptavant/eds-core';

Usage

Each AccordionItem has its own props to manage the header and content panel. By default, it behaves as an uncontrolled component as it manages its own internal state.

<AccordionItem>
	<AccordionHeader>What is Accordion?</AccordionHeader>
	<AccordionPanel>
		Accordion is a component that allows you to show or hide content. 
		It is useful when you want to display a large amount of information 
		but don't want to overwhelm the user.
	</AccordionPanel>
</AccordionItem>
<AccordionItem>
	<AccordionHeader>Is it accessible?</AccordionHeader>
	<AccordionPanel>
		Yes, the Accordion component is accessible by default.
	</AccordionPanel>
</AccordionItem>

Open By Default

Use isDefaultOpen prop in AccordionItem to have any item open by default.

Accordion is a component that allows you to show or hide content. It is useful when you want to display a large amount of information but don't want to overwhelm the user.

<AccordionItem isDefaultOpen={true}>
	<AccordionHeader>What is Accordion?</AccordionHeader>
	<AccordionPanel>
		Accordion is a component that allows you to show or hide content. 
		It is useful when you want to display a large amount of information 
		but don't want to overwhelm the user.
	</AccordionPanel>
</AccordionItem>
<AccordionItem>
	<AccordionHeader>Is it accessible?</AccordionHeader>
	<AccordionPanel>
		Yes, the Accordion component is accessible by default. It also supports ARIA attributes and roles for improved accessibility.
	</AccordionPanel>
</AccordionItem>

Controlled

If you want full control over the accordion behaviour, you can manage it manually using the id, isOpen and onToggle props.

  • Assign a unique id to each item.
  • Use the isOpen prop to control whether the item is expanded.
  • Use the onToggle callback to update the item's state when it's toggled.

const [openItemsId, setOpenItemsId] = React.useState([]);
const handleToggle = ({ id, isOpen }) => {
    setOpenItemsId((prev) => {
        if (prev) {
            return isOpen ? [...prev, id] : prev.filter((openId) => openId !== id);
        } else {
            return isOpen ? [id] : [];
        }
    });
};

return (
    <React.Fragment>
        <AccordionItem
            id="item-1"
            isOpen={openItemsId?.includes('item-1')}
            onToggle={handleToggle}
        >
            <AccordionHeader>What is Accordion?</AccordionHeader>
            <AccordionPanel>
                Accordion is a component that allows you to show or hide content. It
                is useful when you want to display a large amount of information but
                don't want to overwhelm the user.
            </AccordionPanel>
        </AccordionItem>
        <AccordionItem
            id="item-2"
            isOpen={openItemsId?.includes('item-2')}
            onToggle={handleToggle}
        >
            <AccordionHeader>Is it accessible?</AccordionHeader>
            <AccordionPanel>
                Yes, the Accordion component is accessible by default.
            </AccordionPanel>
        </AccordionItem>
    </React.Fragment>
);

Open one at a time

If you need only one accordion item to be open at a time, you can handle it by storing the currently open item's id (like openId) in your local state.

const [openId, setOpenId] = React.useState(""); // add item id, to have an accordion item open by default.

const handleToggle = (id) => {
    if (openId === id) {
        setOpenId(undefined);
    } else {
        setOpenId(id);
    }
};

return (
    <React.Fragment>
        <AccordionItem
            id="item-1"
            isOpen={openId === 'item-1'}
            onToggle={({ id }) => {
                handleToggle(id);
            }}
        >
            <AccordionHeader>What is Accordion?</AccordionHeader>
            <AccordionPanel>
                Accordion is a component that allows you to show or hide content. It
                is useful when you want to display a large amount of information but
                don't want to overwhelm the user.
            </AccordionPanel>
        </AccordionItem>
        <AccordionItem
            id="item-2"
            isOpen={openId === 'item-2'}
            onToggle={({ id }) => {
                handleToggle(id);
            }}
        >
            <AccordionHeader>Is it accessible?</AccordionHeader>
            <AccordionPanel>
                Yes, the Accordion component is accessible by default.
            </AccordionPanel>
        </AccordionItem>
    </React.Fragment>
);

Unmount Panel

Use unMountOnClose prop on AccordionPanel to completely remove the content from the DOM when it's not visible.

By default, it is set to false considering SEO and server-side rendering. Enable it only if you need to remove content from the DOM for performance.

<AccordionItem id="item-1">
	<AccordionHeader>What is Accordion?</AccordionHeader>
	<AccordionPanel unMountOnClose={true}>
		Accordion is a component that allows you to show or hide content. 
		It is useful when you want to display a large amount of information 
		but don't want to overwhelm the user.
	</AccordionPanel>
</AccordionItem>
<AccordionItem id="item-2">
	<AccordionHeader>Is it accessible?</AccordionHeader>
	<AccordionPanel unMountOnClose={true}>
		Yes, the Accordion component is accessible by default. It also supports ARIA attributes and roles for improved accessibility.
	</AccordionPanel>
</AccordionItem>

API Reference

AccordionHeader

PropsTypeDescriptionDefault
childrenReact.ReactNodeThe content of the accordion header._
as?'h2' | 'h3' | 'h4' | 'h5' | 'h6'The HTML heading level / tag to use for the headerh3
onClick?functionCallback function that is called when the header is clicked._
buttonRef?React.RefObject<HTMLButtonElement>Used to set the ref of the button element._

AccordionItem

PropsTypeDescriptionDefault
childrenReact.ReactNodeThe content of the accordion item._
id?stringThe unique id of the accordion item. This id should be used to set the open/closed state of each accordion item._
isDefaultOpen?booleanUsed to set the default open state of the item when used as uncontrolled component.false
isOpen?booleanUsed to set the open state of the item when used as controlled component._
onToggle?({ isOpen, id } : { isOpen: boolean, id: string }) => voidCallback function that is called when the item is toggled. isOpen is a boolean that indicates the open state of the item. id is the unique id of the item._

AccordionPanel

PropsTypeDescriptionDefault
childrenReact.ReactNodeThe content of the accordion panel._
unMountOnClose?booleanUsed to remove the content when the item is closed.false

Style API

Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.

Please refer to the Style API documentation for more insights.

AccordionItem parts

<React.Fragment>
	<AccordionItem className="border border-input-critical" id="item-1">
		<AccordionHeader>What is Accordion?</AccordionHeader>
		<AccordionPanel>
			Accordion is a component that allows you to show or hide content.
		</AccordionPanel>
	</AccordionItem>
	<AccordionItem className="border border-input-critical" id="item-2">
		<AccordionHeader>Is it accessible?</AccordionHeader>
		<AccordionPanel>
			Yes, the Accordion component is accessible by default.
		</AccordionPanel>
	</AccordionItem>
</React.Fragment>

No parts available. Only root.

AccordionHeader parts

<React.Fragment>
	<AccordionItem id="item-1">
		<AccordionHeader
			className="bg-accent-secondary p-1"
			classNames={{
				button: 'border border-input-critical',
				buttonLabel: 'text-positive p-1 border',
				iconEnd: 'fill-critical',
			}}
		>
			What is Accordion?
		</AccordionHeader>
		<AccordionPanel>
			Accordion is a component that allows you to show or hide content.
		</AccordionPanel>
	</AccordionItem>
	<AccordionItem id="item-2">
		<AccordionHeader
			className="bg-accent-secondary p-1"
			classNames={{
				button: 'border border-input-critical',
				buttonLabel: 'text-positive p-1 border',
				iconEnd: 'fill-critical',
			}}
		>
			Is it accessible?
		</AccordionHeader>
		<AccordionPanel>
			Yes, the Accordion component is accessible by default.
		</AccordionPanel>
	</AccordionItem>
</React.Fragment>
Stylable PartsDescription
buttonThe clickable element that toggles the accordion panel.
buttonLabelThe text content of the accordion header.
iconEndThe icon displayed at the end.

AccordionPanel parts

Accordion is a component that allows you to show or hide content.

<React.Fragment>
	<AccordionItem id="item-1" isDefaultOpen={true}>
		<AccordionHeader>What is Accordion?</AccordionHeader>
		<AccordionPanel className="bg-accent-secondary-pressed">
			Accordion is a component that allows you to show or hide content.
		</AccordionPanel>
	</AccordionItem>
	<AccordionItem id="item-2">
		<AccordionHeader>Is it accessible?</AccordionHeader>
		<AccordionPanel className="bg-accent-secondary-pressed">
			Yes, the Accordion component is accessible by default.
		</AccordionPanel>
	</AccordionItem>
</React.Fragment>

No parts available. Only root.