UNPKG

a11y-accordion-component

Version:
1 lines 4.66 kB
const Accordions=(()=>{const t={enter:13,space:32,pageUp:33,pageDown:34,end:35,home:36,up:38,down:40};class e{constructor(t){this.accordion=t.accordion,this.triggers=this.queryFilter(this.accordion.querySelectorAll("[data-controls]")),[this.firstTrigger]=this.triggers,this.lastTrigger=this.triggers[this.triggers.length-1],this.state=[],this.currentFocusedIndex=null,this.isMultiSelectable=t.isMultiSelectable,this.isCollapsible=t.isCollapsible,this.onFocus=this.onFocus.bind(this),this.onClick=this.onClick.bind(this),this.onKeydown=this.onKeydown.bind(this)}queryFilter(t){const e=[];let i;return t.forEach(t=>{for(i=t.parentNode;i!==this.accordion;){if(i.dataset.component===this.accordion.dataset.component)return;i=i.parentNode}e.push(t)}),e}setState(t){this.state.forEach(e=>{t.currentTarget===e.trigger?this.isCollapsible?e.isExpanded=!e.isExpanded:(e.isDisabled=!0,e.isExpanded=!0):(this.isMultiSelectable||(e.isExpanded=!1),this.isCollapsible||(e.isDisabled=!1))}),this.updateAttributes(t)}onFocus(t){this.state.forEach((e,i)=>{t.target===e.trigger&&(this.currentFocusedIndex=i)})}setFocus(e){e.target.hasAttribute("data-controls")?(e.preventDefault(),e.stopPropagation(),e.which!==t.up&&e.which!==t.pageUp||this.state[this.currentFocusedIndex].prevTrigger.focus(),e.which!==t.down&&e.which!==t.pageDown||this.state[this.currentFocusedIndex].nextTrigger.focus(),e.which===t.home&&this.firstTrigger.focus(),e.which===t.end&&this.lastTrigger.focus()):(e.which!==t.pageUp&&e.which!==t.pageDown||(e.preventDefault(),e.stopPropagation()),e.which===t.pageUp&&this.state[this.currentFocusedIndex].trigger.focus(),e.which===t.pageDown&&this.state[this.currentFocusedIndex].nextTrigger.focus())}addAttributes(){this.accordion.setAttribute("role","presentation"),this.state.forEach(t=>{t.trigger.setAttribute("role","button"),t.trigger.setAttribute("tabindex",0),t.trigger.setAttribute("aria-controls",t.trigger.dataset.controls),t.panel.setAttribute("role","region"),t.panel.setAttribute("tabindex",-1),t.panel.setAttribute("aria-labelledby",t.trigger.id)})}updateAttributes(t){t&&t.preventDefault(),this.state.forEach(t=>{t.trigger.setAttribute("aria-expanded",t.isExpanded),t.trigger.setAttribute("aria-disabled",t.isDisabled),t.panel.setAttribute("aria-hidden",!t.isExpanded)})}removeAttributes(){delete this.accordion.dataset.component,this.accordion.removeAttribute("role"),this.state.forEach(t=>{t.trigger.removeAttribute("role"),t.trigger.removeAttribute("tabindex"),t.trigger.removeAttribute("aria-controls"),t.trigger.removeAttribute("aria-expanded"),t.trigger.removeAttribute("aria-disabled"),t.panel.removeAttribute("role"),t.panel.removeAttribute("tabindex"),t.panel.removeAttribute("aria-hidden"),t.panel.removeAttribute("aria-labelledby")})}onClick(t){this.setState(t)}onKeydown(e){e.which===t.enter&&e.target.hasAttribute("data-controls")&&this.setState(e),e.which===t.space&&e.target.hasAttribute("data-controls")&&this.setState(e),e.which===t.up&&this.setFocus(e),e.which===t.down&&this.setFocus(e),e.which===t.home&&this.setFocus(e),e.which===t.end&&this.setFocus(e),e.which===t.pageUp&&this.setFocus(e),e.which===t.pageDown&&this.setFocus(e)}addEventListeners(t,e){t.addEventListener("focus",this.onFocus),t.addEventListener("click",this.onClick),t.addEventListener("keydown",this.onKeydown),e.addEventListener("keydown",this.onKeydown)}removeEventListeners(t,e){t.removeEventListener("focus",this.onFocus),t.removeEventListener("click",this.onClick),t.removeEventListener("keydown",this.onKeydown),e.removeEventListener("keydown",this.onKeydown)}destroy(){this.state.forEach(t=>{this.removeEventListeners(t.trigger,t.panel)}),this.removeAttributes()}render(){let t,e;this.triggers.forEach((i,s)=>{t=document.getElementById(i.dataset.controls),(e="true"===i.dataset.open)&&(this.currentFocusedIndex=s),this.state.push({trigger:i,prevTrigger:this.triggers[s-1]||this.lastTrigger,nextTrigger:this.triggers[s+1]||this.firstTrigger,panel:t,isExpanded:e,isDisabled:!this.isCollapsible&&e}),this.addEventListeners(i,t)}),this.addAttributes(),this.updateAttributes()}}const i=[];return{render:(t,{isMultiSelectable:s=!0,isCollapsible:r=!0}={})=>{const o=document.getElementById(t),a={accordion:o,isMultiSelectable:s,isCollapsible:r};o.dataset.component="accordion";const n=new e(a);n.render(),i.push(n)},destroy:t=>{i.forEach((e,s)=>{t===e.accordion.id&&(e.destroy(),i.splice(s,1))})},init:()=>{const t={};document.querySelectorAll('[data-component="accordion"]').forEach(i=>{t.accordion=i,t.isMultiSelectable="false"!==i.dataset.multiselectable,t.isCollapsible="false"!==i.dataset.collapsible,new e(t).render()})}}})();export default Accordions;