Giter Club home page Giter Club logo

react-accessible-accordion's Introduction

Demo

Try a demo now.

Usage

First, grab the package from npm:

npm install --save react-accessible-accordion

Then, import the editor and use it in your code. Here is a basic example:

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:

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

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 uuids of the currently expanded AccordionItems.


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

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

react-accessible-accordion's People

Contributors

bugaro avatar catepalmer avatar dependabot[bot] avatar epotockiy avatar gavinhenderson avatar georgewl avatar janzenz avatar joris-rotteveel avatar liamjohnston avatar lionelb avatar olleolleolle avatar ryami333 avatar samanthaksanders avatar schne324 avatar smontlouis avatar storytellercz avatar synecdokey avatar thibaudcolas avatar ushamacdonald avatar vincentaudebert avatar vvyomjjain avatar yuzima avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-accessible-accordion's Issues

CSS Missing

IMO, it would be a good idea to provide a .css in the distribution. When you use npm to install this, there is no .css installed. This forces the user to look into the demo sources and its .css and to basically clone it in the project's css.

Ideally, you'd include the react-accessible-accordion/dist/accordion.min.css (or whatever) and then expand on the default rules with project specific ones.

Missing prop

Given the actual behavior of the accordion still missing a prop to expand only from the arrow button since is required to put some buttons in the header

Warning: Accessing PropTypes

I get a warning

Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.

I checked all my components and figured out that error occurred after adding this accordion component.

Could you fix this?

TypeError: Cannot read property 'props' of null

Hello!

I tried to create dynamically accordion with condition.

But I got an ERROR:

accordion.js?96e3:69 Uncaught TypeError: Cannot read property 'props' of null
at eval (accordion.js?96e3:69)
at mapSingleChildIntoContext (react.development.js?99ee:914)
at traverseAllChildrenImpl (react.development.js?99ee:787)
at traverseAllChildrenImpl (react.development.js?99ee:803)
at traverseAllChildren (react.development.js?99ee:858)
at mapIntoWithKeyPrefixInternal (react.development.js?99ee:934)
at Object.mapChildren [as map] (react.development.js?99ee:956)
at Accordion.preExpandedItems (accordion.js?96e3:68)
at new Accordion (accordion.js?96e3:40)
at constructClassInstance (react-dom.development.js?cada:9760)

The example of my code:

const isCompany = false;

<Accordion>
  <AccordionItem>
    <AccordionItemTitle className={styles.item}>
      <div className={styles.accordionArrow} role="presentation" />
      <h3 className={styles.itemHeader}>
        Accordion Header 1
      </h3>
    </AccordionItemTitle>
    <AccordionItemBody>
      <p>
        Accordion Body Content 1
      </p>
    </AccordionItemBody>
  </AccordionItem>
  
  {isCompany && (<AccordionItem>
    <AccordionItemTitle className={styles.item}>
      <div className={styles.accordionArrow} role="presentation" />
      <h3 className={styles.itemHeader}>
        Accordion Header 2
      </h3>
    </AccordionItemTitle>
    <AccordionItemBody>
      <p>
        Accordion Body Content 2
      </p>
    </AccordionItemBody>
  </AccordionItem>)}
</Accordion>

Could you please help me to resolve this problem?

Isomorphic / Server Side Rendering - Prop `id` did not match

When using react-accessible-accordion in combination with Next.js I get the following warning on occasion Prop 'id' did not match. Server: "accordion__title-X" Client: "accordion__title-X". I have multiple pages with different react-accessible-accordions, and this is what causes the issue I believe. The server uuid is mismatched with the client uuid.

Would it be possible to add a ResetIdCounter similar to react-tabs? Or is there already a solution I am unaware of?

Upgrading to 2.3.0 breaks build

I am using React V16.3.1 from a create-react-app and the version 2.3.0 release causes the build to break with the error: babelhelpers is not defined

Workaround: roll back to 2.2.1 due to this error

babelHelpers is not define error:

1034 |
1035 | var createReactContext = unwrapExports(lib);
1036 |

1037 | var _typeof = typeof Symbol === "function" && babelHelpers.typeof(Symbol.iterator) === "symbol" ? function (obj) {
1038 | return typeof obj === 'undefined' ? 'undefined' : babelHelpers.typeof(obj);
1039 | } : function (obj) {
1040 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj === 'undefined' ? 'undefined' : babelHelpers.typeof(obj);

Add ability to expand "AccordionItem" programmatically

Now we can expand AccordionItem only on first render, after this we can't control item expand process via props or methods.
Could you please add functionality (prop on Accordion or AccorionItem) which will allow to change expand state of AccordionItem

This components doesn't need any state management library!

Looking at #43

I have fear that this PR will be merged.
I think this component should be as "dump" as possible.
And guy who will use these components should decide what state management to use. Redux, Mobx, mobx-state-tree or other flux like library. And wrap this into HoC

Error on conditional child component on AccordionItem

When adding a conditional component under <AccordionItem/> component I'm getting this error:

Warning: Failed prop type: Invalid prop `children[2]` of type `boolean` supplied to `AccordionItem`, expected a single ReactElement.

EDIT

@vincentaudebert sorry my description was hurried yesterday. Basically what I'm trying to do was add a conditional component inside the <AccordionItem> component. However when I try to do so I get an error as per the Warning message above.

So here's my use-case, I wanted to add a conditional child component, for example a <div/> tag inside the <AccordionItem>, like so:

<AccordionItem>
  {showDiv === true && <div/>}
</AccordionItem>

I believe the problem is because this statement {showDiv === true && <div/>} returns a boolean if showDiv === true is falsy. I could try the following:

{showDiv === true ? <div/> : null}

However, this throws error as well as null isn't the expected type of <AccordionItem/> so our workaround in the ACC project is to enclose everything inside a parent component.

<AccordionItem>
  <div className="parent-component">
    {showDiv === true && <div />}
  </div>
</AccordionItem>

I think the fix for this is to allow a mixed child type for the AccordionItem component. But I'm not sure if it's a thing this library is keen to support.

Open/Close with keyboard causes page to scroll down

Hello,

I'm using the 1.0.2 version of the accordion and I'm doing some testing using the keyboard (mac) only and when I open and close the accordion with my space bar the page seems to scroll down further each time. Is there any way to stop the page from scrolling when opening/closing the accordion with the keyboard?

I'm noticing the same behavior on your sample page. https://springload.github.io/react-accessible-accordion/

I see the same behavior in Chrome, FireFox and Safari....haven't tried IE yet.

Thanks,

Dave

Not able to find module react-accessible-accordion in .net core react Js

I am trying to use react-accessible-accordion in .net core react js when i define packagein package.json file its not finding the module in my page.
please find the below details
Package.json file:
"dependencies": {
"react-accessible-accordion": "^2.4.1"
}
Home.tsx file:

import {
Accordion,
AccordionItem,
AccordionItemTitle,
AccordionItemBody,
} from 'react-accessible-accordion';

Iam getting the following error

NodeInvocationException: Prerendering failed because of error: ReferenceError: regeneratorRuntime is not defined

Please help to resolve the error.

Accordions render unpredictable `id` attributes.

Eg. accordion__body-86700606-2479-457f-bf7b-129f806c918a. Unfortunately this means that during snapshot testing, RAA elements will render different ids on every run (which makes tests fail).

For internal testing purposes, we're mocking the uuid module such that it just returns the same string every time. At the very least, I think we should document this approach in our Readme so that our users can do the same.

Alternatively, we could replace the uuid package with the consecutive module. That way, id's will always be both unique and predictable.

Make structure more flexible?

At the moment the structure has to be:

Accordion
  AccordionItem
     AccordionTitle
     AccordionBody

It would be great to allow some other elements like div or anything in between.

At least between Accordion and the items as you might need to wrap items into another component.
For instance in my case I would like to wrap the Item into a FormSection from redux-form.

Support TypeScript

Following #93 it would be great to support TypeScript typing.

This is an issue to be picked by someone outside the core crew as we don't have enough experience with TypeScript.

How to add onClick without overriding the existing click events?

I use the accordion version where only 1 item can be expanded at a time. I also want to add an onClick event on the tabs(that are the AccordionItemTitle tags i presume) that changes the state to something else. if i add the onclick event, the expand on click event is not working anymore.

Where can i add my custom onClick event to go together with the existing ones from this component? Thanks :)

Unify component naming schema

We have an inconsistent file naming schema. Some are kebab-case, and some are camel-case. I think we should update the former to match the latter.

Automatically closed when setState of input that inside of AccordionItemBody

handleConfigChange(e){
    let {name, value} = e.target;
    this.setState({[name]: value})
}
<Accordion>
  <AccordionItem>
    <AccordionItemTitle>
      <h3>
        Title
        <i className="icon-Arrow-Asset-41 pull-right"></i>
      </h3>
    </AccordionItemTitle>
    <AccordionItemBody>
      <div className="leads-custom-form form-option-config">
        <div className="form-group">
          <input name="title" className="form-control" placeholder="Title" defaultValue={title}
                 onChange={this.handleConfigChange}/>
        </div>
      </div>
      <div className="leads-custom-form">
        <div className="form-group">
          <label>Text Color:</label>
          <input type="color" name="title_color" className="form-control" defaultValue=
            {title_color} onChange={this.handleConfigChange}/>
        </div>
      </div>
    </AccordionItemBody>
  </AccordionItem>
</Accordion>

AccordionItem "expanded" props are not working as expected

When i create dynamic AccordioItem by using map method, "expanded" props are not working.

Ex:

renderAccordian(list) {
const accordianData = list.map((update, index) => {
   let accorClassName = false;
   if(index === 1 )
     accorClassName = true;
  return (<AccordionItem  expanded={accorClassName }>
            <AccordionItemTitle>
                <h3>Simple title</h3>
            </AccordionItemTitle>
            <AccordionItemBody>
                <p>
                    Body content
                </p>
            </AccordionItemBody>
        </AccordionItem>
        );
   }
  return accordianData ;
}
render(){
const showAccordian = this.renderAccordian(this.props.portalUpdates);
<Accordion onChange={this.onAccordionChange} >
        {showAccordian}
 </Accordion>
}

Add role on node

To fully respect accessbility contraintes, i have to add some properties on nodes :

  • Accordion -> role="tablist"
  • AccordionItemTitle -> aria-selected="true" when element is selected
  • AccordionItemTitle -> aria-selected="false" otherwise
  • AccordionItemBody -> aria-labelledby="[ID_tab]"
    Is it possible to add that please ?

Replace placeholder Lorem Ipsum with real-world content in the demo

Springload has a "no lorem ipsum" policy. While I wouldn't mind a quick dose of lorem in development, for the online demo it's a missed opportunity to make the accordions look more realistic by using real-world content.

I would suggest replacing the lorem with descriptions on how to use the accordion ("eat your own dog food"), potentially with code snippets powered by Prism.js.

Edit: here is a very basic example

react-accessible-accordion

"onChange" action doesn't informative

onChange function get only one parameter uuid which doesn't informative for outside components, could you replace it by an accordion item index or add this index as the second parameter of the onChange function

When re-rendered, the expanded failure

First of all, please forgive me for bad English, I have a problem.
This is my code.
When re-rendered, the expanded failure.
I want first accordion-item is actived.
Thank you.

import React,{Component} from 'react';
import ReactDOM from 'react-dom';
import {
    Accordion,
    AccordionItem,
    AccordionItemTitle,
    AccordionItemBody,
} from 'react-accessible-accordion';

class MainPanel extends Component{
    constructor(){
        super();
        this.state = {
            list:[],
        };
    }

    getData(){
        let {status,list} = {
            "status": "ok",
            "list": [{
                "p": [{
                    "text": "111111"
                },{
                    "text": "222222"
                }],
                "title": 100
            }, {
                "p": [{
                    "text": "33333"
                }],
                "title": 200
            },{
                "p": [{
                    "text": "444444"
                }],
                "title": 300
            }]
        };
        if(status === 'ok'){
            this.setState({list});
        }
    }

    render(){
        const {list} = this.state;
        let node = list.map(({p,title},i)=>{
            let p_node = p.map((d,j)=>{
                return <div key={j}>
                    {d.text}
                </div>
            });
            return <AccordionItem key={i} expanded={true}>
                <AccordionItemTitle>
                    <div className="u-position-relative">
                        <span className="am-text-success"><strong>{title}</strong></span>
                        <div className="am-fr am-text-success">
                            <i className="accordion__arrow" role="presentation"/>
                        </div>
                    </div>
                </AccordionItemTitle>
                <AccordionItemBody>
                    <div className="am-g">
                        {p_node}
                    </div>
                </AccordionItemBody>
            </AccordionItem>
            });
        return <div className="page">
            <form className="form">
                <div className="form-cell">
                    <div className="form-cell__bd">
                        <input type="tel" pattern="[0-9]*" maxLength="11" className="form-input" placeholder="Please Enter......"
                           onChange={this.getData.bind(this)}/>
                    </div>
                </div>
            </form>

            <div className="product">
                <Accordion>{node}</Accordion>
            </div>
        </div>
    }
}

Controlled accordion

It's currently not possible to use this component with complete control over which items are expanded, which is a pretty common use case in a lot of React components. This line below, with the use of activeItems and onChange causes onChange to be called twice if a title is clicked.

nextProps.onChange(nextProps.accordion ? newActiveItems[0] : newActiveItems);

Why would you need to inform the parent that the items have changed, when the parent component is giving you activeItems?

Solution: Make a ControlledAccordion component that uses props.activeItems to render expanded items, so there's no regression if anybody is using this functionality for a different use case.

v1.0.1 - Can't resolve 'uuid' in AccordionItem

I upgraded from 0.5.0 to 1.0.1 this morning and I am getting this message.

./node_modules/react-accessible-accordion/dist/AccordionItem/accordion-item.js

Module not found: Can't resolve 'uuid' in '/test/node_modules/react-accessible-accordion/dist/AccordionItem'

Address linting errors in title and body tests

These linting errors were revealed by installing the enzyme Flow definitions. What this has actually uncovered though is that those two tests are actually invalid, so need to be refactored/rewritten. Also begs the question: shouldn't we have some merge protection against linting errors?

Fix coveralls command

npm run coveralls is broken at the moment

npm run coveralls

> [email protected] coveralls /Users/vincentspringload/Development/sites/react-accessible-accordion
> cat ./coverage/lcov.info | coveralls


/Users/vincentspringload/Development/sites/react-accessible-accordion/node_modules/coveralls/bin/coveralls.js:18
        throw err;
        ^
Bad response: 422 {"message":"Couldn't find a repository matching this job.","error":true}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] coveralls: `cat ./coverage/lcov.info | coveralls`
npm ERR! Exit status 1

Start of investigation: lemurheavy/coveralls-public#703

Update devDependencies

As that lovely badge on our Readme is saying... our devDeps our out of date. Time for an upgrade.

Feature request - propagate arbitrary props

When I import { AccordionItem } from 'react-accessible-accordion for example, and I want the resulting div to have an arbitrary data attribute for example, RAA currently swallows this instead of propagating it to the resulting div.

Eg.

<AccordionItem data-foo="bar">

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.