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>

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 Parts

Description

button

The clickable element that toggles the accordion panel.

buttonLabel

The text content of the accordion header.

iconEnd

The 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.