@mshafiqyajid/react-accordion
Headless accordion hook and styled component for React. Single or multiple open items, smooth CSS grid height animation, full keyboard navigation, ARIA-compliant.
Playground #
A headless component provides behaviour and accessibility without any styles, letting you bring your own UI.
Yes — all packages in this collection do nothing at import time and work with Next.js App Router, Remix, and Astro.
The styled component ships a default chevron, but you can override it via CSS or build a custom trigger with the headless hook.
Props
TSX
import { AccordionStyled } from "@mshafiqyajid/react-accordion/styled";
import "@mshafiqyajid/react-accordion/styles.css";
<AccordionStyled
items={items}
/>Install #
npm install @mshafiqyajid/react-accordion Quick start #
import { AccordionStyled } from "@mshafiqyajid/react-accordion/styled";
import "@mshafiqyajid/react-accordion/styles.css";
const items = [
{ title: "What is this?", content: "A headless accordion component." },
{ title: "Is it accessible?", content: "Yes — full ARIA and keyboard support." },
];
<AccordionStyled items={items} /> Multiple mode #
By default only one item can be open at a time. Set type="multiple" to allow several open simultaneously.
<AccordionStyled items={items} type="multiple" /> Default open #
<AccordionStyled items={items} defaultOpen={0} />
<AccordionStyled items={items} type="multiple" defaultOpen={[0, 1]} /> Headless #
import { useAccordion } from "@mshafiqyajid/react-accordion";
const ids = ["item-1", "item-2"];
const { getItemProps } = useAccordion({ items: ids, type: "single" });
{ids.map((id) => {
const { triggerProps, panelProps, isOpen } = getItemProps(id);
return (
<div key={id}>
<button {...triggerProps}>Toggle</button>
{isOpen && <div {...panelProps}>Content</div>}
</div>
);
})} API #
| Prop | Type | Default | Description |
|---|---|---|---|
| items | AccordionItem[] | — | Array of { title, content } |
| type | "single" | "multiple" | "single" | Whether multiple items can be open |
| size | "sm" | "md" | "lg" | "md" | Size variant |
| tone | "neutral" | "primary" | "neutral" | Color tone |
| defaultOpen | number | number[] | — | Index/indices open on first render |
| animated | boolean | true | Enable smooth height animation |