https://github.com/accessible-ui/accordion
🅰 An accessible and versatile accordion for React with keyboard navigation and labeling features taught in w3.org's WAI-ARIA accordion best practices example
https://github.com/accessible-ui/accordion
a11y a11y-accordion accessibility accessible accessible-accordion accessible-react accordion accordion-component aria aria-accordion focus-management react-accessibility react-accordion
Last synced: 4 months ago
JSON representation
🅰 An accessible and versatile accordion for React with keyboard navigation and labeling features taught in w3.org's WAI-ARIA accordion best practices example
- Host: GitHub
- URL: https://github.com/accessible-ui/accordion
- Owner: accessible-ui
- License: mit
- Created: 2019-12-26T22:11:40.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T02:22:58.000Z (over 2 years ago)
- Last Synced: 2025-01-12T20:18:58.447Z (5 months ago)
- Topics: a11y, a11y-accordion, accessibility, accessible, accessible-accordion, accessible-react, accordion, accordion-component, aria, aria-accordion, focus-management, react-accessibility, react-accordion
- Language: TypeScript
- Homepage: https://codesandbox.io/s/accessibleaccordion-example-7ylck
- Size: 2.02 MB
- Stars: 7
- Watchers: 2
- Forks: 0
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
<Accordion>
npm i @accessible/accordion
An accessible and versatile accordion for React with keyboard navigation and labeling features taught in
[w3.org's WAI-ARIA accordion best practices example](https://www.w3.org/TR/wai-aria-practices/examples/accordion/accordion.html).## Features
- **Style-agnostic** You can use this component with the styling library of your choice. It
works with CSS-in-JS, SASS, plain CSS, plain `style` objects, anything!
- **a11y/aria-compliant** This component works with screen readers out of the box and manages
focus for you.## Quick Start
[Check out the example on CodeSandbox](https://codesandbox.io/s/accessibleaccordion-example-7ylck)
```jsx harmony
import {Accordion, Section, Trigger, Panel} from '@accessible/accordion'const Component = () => (
Section 1
Section 1 content
Section 2
Section 2 content
)
```## API
### Components
| Component | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [``](#accordion) | This component creates the context for your accordion section and contains some configuration options. |
| [``](#section) | This component creates the context for the accordion panel and trigger contained in this section. It must be a direct descendent of [``](#accordion). |
| [``](#trigger) | This component clones any React element and turns it into a accordion trigger that controls the visible state of the panel. |
| [``](#panel) | This component clones any React element and turns it into a accordion panel. |
| [``](#close) | This is a convenience component that clones any React element and adds an onClick handler to close its parent panel. | |### Hooks
| Hook | Description |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| [`useAccordion()`](#useaccordion) | This hook returns the value of the accordion's [AccordionContext object](#accordioncontextvalue). |
| [`useSection()`](#usesection) | This hook returns the value of the accordion [``'s](#section) [SectionContext object](#sectioncontextvalue). |
| [`useControls()`](#usecontrols) | This hook returns the accordion [``'s](#section) `open`, `close`, and `toggle` functions. |
| [`useDisabled()`](#usedisabled) | This hook returns the accordion [``'s](#section) `disabled` value. |
| [`useIsOpen()`](#useisopen) | This hook returns the accordion [``'s](#section) `isOpen` value. |### ``
This component creates the context for your accordion section and contains some configuration options.
[``s](#section) are the only type of children allowed.#### Props
| Prop | Type | Default | Required? | Description |
| ----------------- | ----------------------------------------------------- | ----------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| defaultOpen |number | number[]
| `undefined` | No | The section by index (or sections if `allowMultipleOpen`) you want opened by default. |
| open |number | number[]
| `undefined` | No | Makes this a controlled component where `open`, `close`, `toggle`, controls have no effect. The sections defined here are always the ones that are open. |
| allowMultipleOpen | `boolean` | `false` | No | Allows multiple sections to be opened at one time. |
| allowAllClosed | `boolean` | `false` | No | Allows all of the sections to be closed. If `false`, you must define either the `open` or `defaultOpen` property. |
| onChange |(opened: number | number[]) => void
| `undefined` | No | Called each time the open sections change. If `allowMultipleOpen`, the argument will be an array, otherwise a single number. The number corresponds to the open section's index. |
| children | `React.ReactElement[]` | `undefined` | Yes | The only children allowed by this component are [``s](#section). |### ``
This component creates the context for the accordion panel and trigger contained in this section. It must be a direct
descendent of [``](#accordion).#### Props
| Prop | Type | Default | Required? | Description |
| -------- | --------------------------------------------------------------------------------------- | ----------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| id | `string` | `undefined` | No | Overrides the ID that is auto-generated by this component. |
| disabled | `boolean` | `false` | No | `true` if the section should not be allowed to have its `open` state changed. |
| children |React.ReactNode | ((context: SectionContextValue) => React.ReactNode)
| `undefined` | Yes | Sections must include a [``](#trigger) and a [`Panel`](#panel) in addition to anything else you'd like. |### ``
This component clones any React element and turns it into a accordion trigger that controls the visible state of
the [``](#panel). It must be a child of [``](#section).#### Props
| Prop | Type | Default | Required? | Description |
| ----------- | --------------------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| openClass | `string` | `undefined` | No | This class name will be applied to the child element when the section is `open`. |
| closedClass | `string` | `undefined` | No | This class name will be applied to the child element when the section is `closed`. |
| openStyle | `React.CSSProperties` | `undefined` | No | These styles will be applied to the child element when the section is `open`. |
| closedStyle | `React.CSSProperties` | `undefined` | No | These styles will be applied to the child element when the section is `closed`. |
| children | `React.ReactElement` | `undefined` | Yes | The child is cloned by this component and has aria attributes injected into its props as well as keyboard events for opening the section with `space` and `enter` keys and navigating between sections. |### ``
This component clones any React element and turns it into a accordion section panel. It must be
a child of [``](#section).#### Props
| Prop | Type | Default | Required? | Description |
| ----------- | --------------------- | ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| openClass | `string` | `undefined` | No | This class name will be applied to the child element when the section is `open`. |
| closedClass | `string` | `undefined` | No | This class name will be applied to the child element when the section is `closed`. |
| openStyle | `React.CSSProperties` | `undefined` | No | These styles will be applied to the child element when the section is `open`. |
| closedStyle | `React.CSSProperties` | `undefined` | No | These styles will be applied to the child element when the section is `closed`. |
| children | `React.ReactElement` | `undefined` | Yes | The child is cloned by this component and has aria attributes injected into its props as well as keyboard events for closing the section with the `escape` key. |### ``
This is a convenience component that clones any React element and adds an onClick handler to close its parent panel. It
must be a child of [``](#section).#### Props
| Prop | Type | Default | Required? | Description |
| -------- | -------------------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| children | `React.ReactElement` | `undefined` | Yes | The child is cloned by this component and has aria attributes injected into its props as keyboard events to ensure it acts like a button even if it isn't a native ``. |### `useAccordion()`
This hook returns the value of the accordion's [AccordionContext object](#accordioncontextvalue). This hook
must be within a child of [``](#accordion).### `AccordionContextValue`
```typescript jsx
interface AccordionContextValue {
// DOM references to the accordion sections
sections: (HTMLElement | undefined)[]
// Registers a new accordion section
registerSection: (index: number, trigger: HTMLElement) => () => void
// The indexes of the open sections
opened: number[]
// Opens a section
open: (section: number | undefined) => void
// Closes a section
close: (section: number | undefined) => void
// Returns true if a section is open
isOpen: (section: number | undefined) => boolean
// Does the accordion allow all of its sections to be closed?
allowAllClosed: boolean
}
```### `useSection()`
This hook returns the value of the accordion sections's [SectionContextValue object](#sectioncontextvalue). This hook
must be within a child of [``](#section).### `SectionContextValue`
```typescript jsx
interface SectionContextValue {
// Is this section open?
isOpen: boolean
// Opens this section if not disabled
open: () => void
// Closes this section if possible
close: () => void
// Toggles the visible state of this section if possible
toggle: () => void
// The id of this section
id?: string
// The index of this section
index: number
// Is the section disabled?
disabled: boolean
// The DOM reference to the section's
triggerRef: React.MutableRefObject
}
```### `useControls()`
This hook returns the accordion sections's `open`, `close`, and `toggle` functions. This hook
must be within a child of [``](#section).### `useDisabled()`
This hook returns the accordion sections's `disabled` value. This hook
must be within a child of [``](#section).### `useIsOpen()`
This hook returns the accordion sections's `isOpen` value. This hook
must be within a child of [``](#section).## LICENSE
MIT