UNPKG

react-accessible-accordion

Version:
262 lines (180 loc) 9.06 kB
[react-accessible-accordion](https://springload.github.io/react-accessible-accordion/) [![npm](https://img.shields.io/npm/v/react-accessible-accordion.svg?style=flat-square)](https://www.npmjs.com/package/react-accessible-accordion) [![Accessibility status](https://img.shields.io/badge/a11y-tested-brightgreen.svg)](http://wave.webaim.org/report#/https://springload.github.io/react-accessible-accordion/) ========= ## ⚠️ Project status In most cases, you no longer need a JS library like this to render fully functional, accessible accordions. For that reason, **this project is no longer maintained**. This is because native [HTML Disclosure](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/summary) (aka `<details>`/`<summary`>) elements are now [widely supported](https://caniuse.com/details). Native disclosures offer several advantages over any JS-based solutions. For instance: - Because there is no JS to download/parse, they are far more performant. - They are framework-agnostic, and will work the same way whether you're using React, [other framework], or plain old HTML. - Collapsed content can still be found via find-on-page (<key>ctrl</key>/<key>command</key>+<key>f</key>) in supporting browsers, including Chrome. ## Demo [Try a demo now](https://springload.github.io/react-accessible-accordion/). ## Usage First, grab the package from npm: ```sh npm install --save react-accessible-accordion ``` Then, import the editor and use it in your code. Here is a [basic example](https://springload.github.io/react-accessible-accordion/): ```jsx import React from 'react'; import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemButton, AccordionItemPanel, } from 'react-accessible-accordion'; // Demo styles, see 'Styles' section below for some notes on use. import 'react-accessible-accordion/dist/fancy-example.css'; export default function Example() { return ( <Accordion> <AccordionItem> <AccordionItemHeading> <AccordionItemButton> What harsh truths do you prefer to ignore? </AccordionItemButton> </AccordionItemHeading> <AccordionItemPanel> <p> Exercitation in fugiat est ut ad ea cupidatat ut in cupidatat occaecat ut occaecat consequat est minim minim esse tempor laborum consequat esse adipisicing eu reprehenderit enim. </p> </AccordionItemPanel> </AccordionItem> <AccordionItem> <AccordionItemHeading> <AccordionItemButton> Is free will real or just an illusion? </AccordionItemButton> </AccordionItemHeading> <AccordionItemPanel> <p> In ad velit in ex nostrud dolore cupidatat consectetur ea in ut nostrud velit in irure cillum tempor laboris sed adipisicing eu esse duis nulla non. </p> </AccordionItemPanel> </AccordionItem> </Accordion> ); } ``` ### Styles We strongly encourage you to write your own styles for your accordions, but we've published the styles used on our demo page to help you get up and running: ```js import 'react-accessible-accordion/dist/fancy-example.css'; ``` We recommend that you copy them into your own app and modify them to suit your needs, particularly if you're using your own `className`s. ## Component API ### Accordion #### allowMultipleExpanded : `boolean` [*optional*, default: `false`] Don't autocollapse items when expanding other items. #### allowZeroExpanded : `boolean` [*optional*, default: `false`] Allow the only remaining expanded item to be collapsed. #### preExpanded: `string[]` [_optional_, default: `[]`] Accepts an array of strings and any `AccordionItem` whose `uuid` prop matches any one of these strings will be expanded on mount. #### className : `string` [*optional*, default: `'accordion'`] Class(es) to apply to element. #### onChange : `(string[]) => void` [*optional*] Callback which is invoked when items are expanded or collapsed. Gets passed `uuid`s of the currently expanded `AccordionItem`s. --- ### AccordionItem #### className : `string` [*optional*, default: `accordion__item`] Class(es) to apply to element. #### uuid : `string|number` [*optional*] Recommended for use with `onChange`. Will be auto-generated if not provided. #### dangerouslySetExpanded: `boolean` [*optional*] Enables external control of the expansion. > Warning: This may impact accessibility negatively, use at your own risk --- ### AccordionItemHeading #### className : `string` [*optional*, default: `'accordion__heading'`] Class(es) to apply to the 'heading' element. #### aria-level : `number` [*optional*, default: `3`] Semantics to apply to the 'heading' element. A value of `1` would make your heading element hierarchically equivalent to an `<h1>` tag, and likewise a value of `6` would make it equivalent to an `<h6>` tag. ### AccordionItemButton #### className : `string` [*optional*, default: `'accordion__button'`] Class(es) to apply to the 'button' element. --- ### AccordionItemPanel #### className : `string` [*optional*, default: `'accordion__panel'`] Class(es) to apply to element. #### region: `boolean` Make the element have a region role. --- ### AccordionItemState #### children : `({ expanded: boolean, disabled: boolean }): JSX.Element` [**required**] --- ## Helpers ### resetNextUuid : `(): void` Resets the internal counter for Accordion items' identifiers (including `id` attributes). For use in test suites and isomorphic frameworks. --- ## Accessibility Best-Practice Authoring an 'accordion' component to the [WAI ARIA spec](https://www.w3.org/TR/wai-aria-practices-1.1/#accordion) can be complex, but `React Accessible Accordion` does most of the heavy lifting for you, including: - Applying appropriate aria attributes (`aria-expanded`, `aria-controls`, `aria-disabled`, `aria-hidden` and `aria-labelledby`). - Applying appropriate `role` attributes (`button`, `heading`, `region`). - Applying appropriate `tabindex` attributes. - Applying keyboard interactivity ('space', 'end', 'tab', 'up', 'down', 'home' and 'end' keys). However, there's still a couple of things you need to keep in mind to remain spec-compliant: - Only ever use [phrasing content](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Phrasing_content) inside of your `AccordionItemHeading` component. If in doubt, use text only. - Always provide an `aria-level` prop to your `AccordionItemHeading` component, _especially_ if you are nesting accordions. This attribute is a signal used by assistive technologies (eg. screenreaders) to determine which heading level (ie. `h1`-`h6`) to treat your heading as. If you have any questions about your implementation, then please don't be afraid to get in touch via our [issues](https://github.com/springload/react-accessible-accordion/issues). ## FAQs ### React 18? RAA supports React 18, and the new out-of-order streaming feature. See the CHANGELOG for details. ### Which design patterns does this component aim to solve? Those described by the WAI ARIA spec's description of an 'accordion': > An accordion is a vertically stacked set of interactive headings that each > contain a title, content snippet, or thumbnail representing a section of > content. The headings function as controls that enable users to reveal or hide > their associated sections of content. Accordions are commonly used to reduce > the need to scroll when presenting multiple sections of content on a single > page. ### Which design patterns does this component NOT aim to solve? Components which are "accordion-like" but do not match the WAI ARIA spec's description, as written above. By "accordion-like", we mean components which have collapsible items but require bespoke interactive mechanisms in order to expand, collapse and 'disable' them. This includes (but is not limited to) multi-step forms, like those seen in many cart/checkout flows, which we believe require (other) complex markup in order to be considered 'accessible'. This also includes disclosure widgets. ### How do I disable an item? See "Which design patterns does this component NOT aim to solve?". ## Browser Support **Supported browser / device versions:** | Browser | Device/OS | Version | | ------------- | --------- | ------- | | Mobile Safari | iOS | latest | | Chrome | Android | latest | | IE | Windows | 11 | | MS Edge | Windows | latest | | Chrome | Desktop | latest | | Firefox | Desktop | latest | | Safari | OSX | latest |