A pure Javascript module for accordion/collapse UI without jQuery.
π Demo
Using npm or yarn, install handy-collapse.
π NPM
# npm
npm install handy-collapse
# yarn
yarn add handy-collapse
Then import and init it.
import HandyCollapse from "handy-collapse";
new HandyCollapse({
//...
});
<script src="https://unpkg.com/browse/handy-collapse/dist/handy-collapse.iife.js" defer>
Then init.
new HandyCollapse({
//...
});
With minimum markup
<!--
Add data attribute, button/content element.
Control Button: data-{namespase}-control="{ID}" * multiple elements
Collapsible element: data-{namespase}-content="{ID}" * only one element
-->
<button type="button" data-hc-control="uniqContentID">Show/Hide Content</button>
<div data-hc-content="uniqContentID">Toggle Content</div>
With aria-*
attribute for accessibility
<button type="button" data-hc-control="uniqContentID" aria-expanded="false" aria-controls="theID">
Show/Hide Content
</button>
<div id="theID" data-hc-content="uniqContentID" aria-hidden="true">Toggle Content</div>
const myAccrodion = new HandyCollapse();
Option Name | Type | Default | Desc |
---|---|---|---|
nameSpace | string |
"hc" |
Set namespace both toggleButtonAttr & toggleContentAttr |
toggleButtonAttr | string |
`data-${nameSpace}-control` |
Attribute name for Controller button element |
toggleContentAttr | string |
`data-${nameSpace}-content` |
Attribute name for Content element |
activeClass | string |
"is-active" |
A class on opened element |
isAnimation | boolean |
true |
With animation Slide |
closeOthers | boolean |
true |
Close others Content |
animationSpeed | number |
400 |
CSS transition duration (ms) *only isAnimation:true |
cssEasing | string |
"ease-in-out" |
CSS transition easing *only isAnimation:true |
onSlideStart | (isOpen: boolean, contentId: string) => void |
() => void |
Callback on Open/Close Animation Start @param isOpen @param {String} contentId * Don't ID Attribute |
onSlideEnd | (isOpen: boolean, contentId: string) => void |
() => void |
Callback on Open/Close Animation End @param isOpen @param contentId * Don't ID Attribute |
Method name | type | desc |
---|---|---|
open(contentId, runCallback, isAnimation) | (contentId: string, runCallback: boolean = true, isAnimation: boolean = true) => void |
Open the content |
close(contentId, runCallback, isAnimation) | (contentId: string, runCallback: boolean = true, isAnimation: boolean = true) => void |
Close the content |
const myAccrodion = new HandyCollapse();
// Open the content with `data-${namespace}-content="contentId"` attribute.
myAccrodion.open("contentId");
// Do not hook callbacks, and no animtion.
myAccrodion.open("contentId", false, false);
//Default Options
const myAccrodion = new HandyCollapse();
//Full Options
const myAccrodionCustom = new HandyCollapse({
nameSpace: "hc", // Note: Be sure to set different names when creating multiple instances
activeClass: "is-active",
isAnimation: true,
closeOthers: true,
animationSpeed: 400,
cssEasing: "ease",
onSlideStart: (isOpen, contentID) => {
console.log(isOpen);
const buttonEl = document.querySelectorAll(`[data-hc-control='${contentID}']`);
console.log(buttonEl);
},
onSlideEnd: (isOpen, contentID) => {
console.log(isOpen);
const contentEl = document.querySelector(`[data-hc-content='${contentID}']`);
console.log(contentEl);
}
});
// Open by Js
myAccrodion.open("content01");
// Close by Js
myAccrodion.close("content01");
<!--
BUTTON : data-{namespase}-control="{ID}" * multiple element
CONTENT: data-{namespase}-content="{ID}" * only one element
-->
<!-- basic -->
<button type="button" data-hc-control="content01" aria-expanded="false" aria-controls="basicContent01">
Show/Hide Content 01
</button>
<div id="basicContent01" data-hc-content="content01" aria-hidden="true">... Content 01 ...</div>
<!-- if add activeClass(def: "is-active"), Opened on init. -->
<button
type="button"
class="is-active"
γ
data-hc-control="content02"
aria-expanded="true"
aria-controls="basicContent02"
>
Show/Hide Content 02
</button>
<div id="basicContent02" class="is-active" data-hc-content="content02" aria-hidden="false">... Content 02 ...</div>
<!-- Can use nested accordion -->
<!-- Note: the `closeOthers` parameter must be set to `false` -->
<button type="button" data-hc-control="parentContent" aria-expanded="true" aria-controls="netstedParantContent">
Show/Hide parent content
</button>
<div id="netstedParantContent" data-hc-content="parentContent" aria-hidden="true">
... parent content ...
<button type="button" γ data-hc-control="childContent" aria-expanded="true" aria-controls="netstedChiledContent">
Show/Hide child content
</button>
<div id="netstedChiledContent" data-hc-content="childContent" aria-hidden="true">... child content ...</div>
</div>