Détail du package

badger-accordion

stuartjnelson11.8kMIT1.2.4

An accessible vanilla JS accordion with extensible API.

accordion, accessible, accessible, accordion

readme

Badger Accordion

Badger Accordion logo
An accessible light weight, vanilla JavaScript accordion with an extensible API. Just 8.71kb and Gzipped 2.6kb!



Contents

The idea

  • To make an accessible, animated, accordion with an extensible API.
  • Make it using just plain vanilla JavaScript.
  • Ensure that it has just plain simple css. Enough to get it to work. Not too much that you have to spend ages overwriting it.
  • Ensure that it is accessible as possible.

Key terminologies

  • panel - The section of the accordion than opens and closes
  • header - The button that opens an accordion panel

Basic setup

Download plugin

You can download the plugin using NPM or direct download from Github

You'll need to import the plugin and create a new instance so you can use it. There is a working example in the example directory (shock horror!) if you'd like something to reference.

  1. Create your markup
  2. Include the basic styles (which are in dist/badger-accordion.css or dist/badger-accordion.css)
  3. Import badger-accordion.js
  4. Create new instance of the accordion

Markup

There is no fixed structure required for your markup, in my examples I have used a dl (as the WAI-ARIA Authoring Practices guide used it in their example). You will need to add 5 selectors for the plugin to work. The selectors listed below are the default selectors but can all be over written using the plugins options.

  1. The containing element, dl, .js-badger-accordion
  2. The header element, button, .js-badger-accordion-header
  3. The panel element, dd, .js-badger-accordion-panel
  4. The panel inner element, div, .js-badger-accordion-panel-inner
  5. The panel element for targeting with CSS, div, .badger-accordion__panel .

While you could use the selector from point 3 I would not recommend doing this. For keeping everything nice and separated best to use a different selector for targeting with CSS & JS.

<dl class="js-badger-accordion">
    <dt>
        <button class="js-badger-accordion-header">
            Header Content
        </button>
    </dt>
    <dd class="badger-accordion__panel js-badger-accordion-panel">
        <div class="js-badger-accordion-panel-inner">
            Panel Content
        </div>
    </dd>
</dl>

Styles

I have created some simple CSS styles to help you with creating an accordion which are in dist/badger-accordion-demo.css or dist/badger-accordion-demo.scss. If you'd like some additional styles checkout the example dir.

.badger-accordion__panel {
    max-height: 75vh;
    overflow: hidden;
}

.badger-accordion__panel.-ba-is-hidden {
    max-height: 0 !important;
    visibility: hidden;
}

.badger-accordion--initialized .badger-accordion__panel {
    transition: all ease-in-out 0.2s;
}

Create new instance of Badger Accordion

You just import Badger Accordion. Then you can either pass in a DOM node or CSS Selector. Passing in a DOM node as in the first example below is the best way to create a new instance.

Please note that currently the Array.from polyfill is being included as standard (but wrapped in a conditional check). If this is an issue for you or you have an awesome idea of how to include it please get in touch.

import BadgerAccordion from 'badger-accordion';

// Creating a new instance of the accordion
const accordionDomNode = document.querySelector('.js-badger-accordion');

const accordion = new BadgerAccordion(accordionDomNode);

Create multiple instances of Badger Accordion

If you want to have multiple instances of the accordion in the same document you could do it like this by looping over the collection of DOM nodes.

<!-- HTML -->
<dl class="badger-accordion js-badger-accordion">
    <!-- Your markup -->
</dl>

<dl class="badger-accordion js-badger-accordion">
    <!-- Your markup -->
</dl>

<dl class="badger-accordion js-badger-accordion">
    <!-- Your markup -->
</dl>
// Importing accordion
import BadgerAccordion from 'dist/badger-accordion';

const accordions = document.querySelectorAll('.js-badger-accordion');

Array.from(accordions).forEach((accordion) => {
    const ba = new BadgerAccordion(accordion);

    // console.log(ba.getState([0]));
});

Create a nested accordion

With release 1.2.0 you can now created nested accordions. You don't need to do anything for this to work. Currently is you close a parent accordion then the child accordion will retain the previous state. Eg. if your child accordion has it's second item open, you close the parent then reopen the child accordion again it will have it's second item still open.

Options

The accordion has a selection of options that you can overwrite. For example if you wanted to open the first and 4th panel when the accordion is initialized;

new BadgerAccordion('.js-badger-accordion', {
    openHeadersOnLoad: [0, 3],
    roles: {
        region: true
    }    
});
Option Type Default Description
headerClass String .js-badger-accordion-header Class for panel's header
panelClass String .js-badger-accordion-panel Class for panel
panelInnerClass String .js-badger-accordion-panel-inner Class for panel inner container
hiddenClass String -ba-is-hidden Class added to panels that are hidden
initializedClass String badger-accordion--initialized Class add to accordion when it has initialized
headerDataAttr String data-badger-accordion-header-id Data attribute on each header
openMultiplePanels Boolean false Give you the ability to have mutiple panels open at one time. By default this is disabled
roles Boolean or Object true Controls setting presentation role on the container element & region on the panel. By using a boolean value you will set both attributes. By settings this as an object you will be explicitly setting only that role. Any roles not included in the object will not be set. In the example above only the region role will be set.
addListenersOnInit Boolean false If set to true EventListeners will not be added to each accordion header on initialization
hidenClass @Deprecated @Deprecated This was a spelling mistake and has been deprecated. If you have used in from version < 1.0.29 then hiddenClass is now equal to hidenClass
headerOpenLabel @Deprecated @Deprecated Aria lable has been removed see Changelog.md 1.1.5
headerCloseLabel @Deprecated @Deprecated Aria lable has been removed see Changelog.md 1.1.5

Methods

The accordion has a series of methods allowing you to have full control over extending the plugin. For example if you wanted to close all your accordion's panels;

accordion.closeAll();
Method Arguments Description Example
init() Fires off all methods needed to initialise the accordion. Can be used again after to re-initialise
getState() headerId/s - array Returns the state of a panel/s by passing in the node item index/s as an array. Getting a single Id. accordion.getState([0]).
Getting multiple header's state accordion.getState([0, 1, 2])
open() headerIndex Opens a given panel using its headerIndex. Eg; accordion.open( 0 );
close() headerIndex Closes a given panel using its headerIndex. Eg; accordion.close( 0 );
togglePanel() animationAction, headerIndex Toggles panel into opening or closing. animationAction is either open or closed
openAll() Opens all accordion panels
closeAll() Closes all accordion panels
calculatePanelHeight() Calculates and sets a single panels height
calculateAllPanelsHeight() Calculates and sets all panels height

Sponsors

A massive thanks to BrowserStack for supporting me by allowing me to use their platform for free. BrowserStack is a cloud based testing tool that lets you test websites on a wide range web browsers and real mobiles devices. This removes all the hassle of installing chunky VM's. BrowserStack has some great tools such as automated testing, testing local sites (via a browser extension) and taking screenshots. BrowserStack logo

Contributors

I've had some awesome people help me out building the accordion. I worked in part on this while working at Mr B & Friends big shout out to the digital team there. This wouldn't be anywhere near as good if it wasn't for the wise words of Dave Smith. Finally my favourite digital designer Taavi Kelle who created the AWESOME logo and gave my demo styles some love Steve Richardson™.

Also to the following awesome people who have submitted PR's

Roadmap

  • General performance & naming review
  • Create some mixins to help making custom themes quicker & easier
  • Create option for callback methods on each public method
  • Export an IE9 safe version in the repo
  • Create horizontal accordion option

changelog

Change Log

All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning.

For more information about keeping good change logs please refer to keep a changelog.

Changelog

[1.2.3] - 2019-5-7

UPDATED

  • Security issue with tar package

ADDED

  • Option addListenersOnInit. See PR 26 for more info

[1.2.2] - 2019-2-12

Fixed

  • Running NPM audit to fix vulnerabilities

[1.2.1] - 2019-2-9

Fixed

  • Issue#24: Fixing setting for hiddenClass and initializedClass

[1.2.0] - 2019-1-29

Fixed

  • Issue#16: Properly hiding accordion content for all users
  • Issue#17: Removed aria-label and deprecated headerOpenLabel & headerCloseLabel
  • Merged in PR from @micmania1 for the correct spelling of aria-labelledby

Updated

  • Made NPM scripts bit nicer by calling each other. Also now compiling .css

Added

  • Created the ability to have nested accordions. For this to happen I needed to change how a single accordion instance selected its headers & panels. Now the headers & panels selected are only 1 level deep.

[1.1.4] - 2018-12-2

Updated

  • Spelling of initializedClass so it is the American spelling

[1.1.3] - 2018-11-27

Fixed

  • Fixing demo styles

  • Issue #14: seanjhulse created a PR and patched this so openAll/closeAll works.

Added

  • Issue #9 Active class to the open header & panel

Changed

  • Deprecating setPanelHeight() in favour better name This method was “private” and not named great for it being used after the initialisation IMO. I have now called it calculateAllPanelsHeight() which I feel is more descriptive. Also created a method to calculate a single panel’s height calculatePanelHeight(). Also updated the docs.
  • Issue #8: Setting the roles. By default both the presentation role on the container element & region on the panel will be set. You can now using turn them both off roles: false or explicitly set one or both of the roles to be set.

      roles: {
        region: true
      }
  • Issue #10 - Moved packages to devDependencies and cleaned up package.json

[1.1.3] - 2018-11-26

Updated

  • _openHeadersOnLoad() updates state with method
  • Updated NPM scripts

Fixed

  • Issue#20: Open() & Close() methods were not correctly updating state and therefore if fired upon start the whole state object was incorrect and using the accordion was impossible.

[1.1.2] - 2018-8-7

Updated

  • Discarding some temporary changes

[1.1.1] - 2018-6-12

Updated

  • LICENSE so its correct...

[1.1.0] - 2018-4-30

Updated

  • Plugin so can now pass in a DOM node
  • README & example files
  • Tweaking minor Firefox CSS bug with the demo

[1.0.30] - 2018-4-4

Updated

  • NPM version

[1.0.29] - 2018-4-4

Updated

  • Deprecated hidenClass option. This was a spelling mistake and has been deprecated. If you have used in from version < 1.0.28 then hiddenClass is now equal to hidenClass
  • Compiled assets and updated readme

[1.0.28] - 2018-4-4

Updated

  • Updated default transition to be more specific

[1.0.27] - 2018-4-4

Updated

  • Improving SCSS comment
  • Updated rollup so default example styles are copied by rollup

[1.0.26] - 2018-3-22

Updated

  • NPM version

[1.0.25] - 2018-4-4

Updated

  • Dependancies
  • Updated essential SCSS/CSS. Renamed default hidden class. Removed some old unnecessary css.
  • Updated example SCSS
  • Ignored .sass-cache
  • Compiled assets

[1.0.24] - 2018-3-22

Updated

  • And this time updated .babelrc's preset

[1.0.23] - 2018-3-22

Updated

  • Bable setup so it follows the latest standard as well as all dependencies. This should fix Issue #4

[1.0.22] - 2018-3-21

Changed

  • Adding pre-pubish npm script. This is a safty net to stop issues with .esm file that the npm example script was causing before publishing the plugin

[1.0.21] - 2018-3-21

Fixed

  • Fixing typo in package.json for module
  • Error with npm run example from inserting code don't want into dist/northern-badger.esm.js

Added

  • Added rollup-plugin-copy to copy style files

[1.0.20] - 2018-2-08

Fixed

  • Fixed link to demo site in Readme

[1.0.19] - 2018-1-31

Updated

  • NPM version

[1.0.18] - 2018-1-31

Added

  • Added rol=“region” to accordion panel
  • Added rol=“presentation” to accordion

Updated

  • Updated README
  • Compiled assets
  • Moved setAttributes method up

[1.0.17] - 2018-1-1

Updated

  • Importing array.from polyfill by default
  • Updated copy with new file size!

[1.0.16] - 2018-1-1

Updated

  • Tweaked example demo markup and styles
  • Updated packages for Rollup. Now have umd & esm versions transpiled

Added

  • Created .esm files

[1.0.15] - 2017-12-16

Updated

  • Improving readme

[1.0.14] - 2017-12-13

Fixed

  • Fixed IE11 bug with object assign

Updated

  • Babel plugins to fix IE11 bug
  • Updated README.md with download info

[1.0.13] - 2017-12-12

Fixed

  • Updated transitionEnd JS to ensure that Object.defineProperty is writable

Updated

  • Updated issue template

[1.0.12] - 2017-12-11

Fixed

  • Issue #1: Conflict with jQuery as raised here. After some investigation I found this thread - I updated the “transitionEnd” functions. This appears to have fixed the issue.

Added

  • Main dist/badger-accordion.js is now not minifed and added a minifed version in dist directory.

Updated

  • rollup.config.js so that srcmaps aren't included with complied JS files.

[1.0.0] to [1.0.11] - 2017-12-11

Added/Updated/Fixed

  • Just added this change log. Wont detail whats happened until now. Released the plugin and updated a bunch of things.