UNPKG

a11y-tabs

Version:

A lightweight JavaScript package to facilitate a11y-compliant tabbed interfaces

3 lines (2 loc) 2.56 kB
/*! a11y-tabs 0.1.1 — © 2021 by Rob Levin */ class e{tabs=[];tabItems=null;panels=null;currentIndex=-1;isVerticalOrientation=!1;constructor(e,t,s){const i=s||0;this.tabItems=document.querySelectorAll(`${e} [role="tab"]`),this.panels=document.querySelectorAll(t);const n=document.querySelector(e).getAttribute("aria-orientation");this.isVerticalOrientation=!(!n||"vertical"!==n),this.currentIndex=i,this.selectTab=this.selectTab.bind(this),this.deselectTabs=this.deselectTabs.bind(this),this.resetPanels=this.resetPanels.bind(this),this.handleClick=this.handleClick.bind(this),this.handleKeydown=this.handleKeydown.bind(this),this.initTabs()}initTabs(){this.resetPanels(),this.deselectTabs();for(let e=0;e<this.tabItems.length;e++){const t=this.tabItems[e];this.tabs[e]=t,this.tabs[e].index=e,t.addEventListener("click",this.handleClick),t.addEventListener("keydown",this.handleKeydown),e===this.currentIndex&&this._selectTab(t)}}activatePanel(e){document.querySelector(`#${e}`).removeAttribute("hidden"),document.querySelector(`#${e}`).setAttribute("aria-expanded",!0)}deselectTabs(){for(let e=0;e<this.tabItems.length;e++){const t=this.tabItems[e];t.classList.remove("active"),t.setAttribute("tabindex","-1"),t.setAttribute("aria-selected",!1)}}resetPanels(){for(let e=0;e<this.panels.length;e++){const t=this.panels[e];t.setAttribute("hidden",!0),t.setAttribute("aria-expanded",!1),t.setAttribute("tabindex","0")}}selectTab(e){this.deselectTabs(),this.resetPanels(),this._selectTab(e)}_selectTab(e){e.classList.add("active"),e.setAttribute("aria-selected","true"),e.removeAttribute("tabindex"),this.activatePanel(e.getAttribute("aria-controls"))}handleClick(e){this.selectTab(e.target)}decrementIndex(){this.currentIndex--,this.currentIndex<0&&(this.currentIndex=this.tabItems.length-1)}incrementIndex(){this.currentIndex++,this.currentIndex>=this.tabItems.length&&(this.currentIndex=0)}handleKeydown(e){switch(e.key){case"Up":case"ArrowUp":if(this.isVerticalOrientation){this.decrementIndex();break}case"Down":case"ArrowDown":if(this.isVerticalOrientation){this.incrementIndex();break}case"Left":case"ArrowLeft":if(!this.isVerticalOrientation){this.decrementIndex();break}case"Right":case"ArrowRight":if(!this.isVerticalOrientation){this.incrementIndex();break}case"Home":case"ArrowHome":this.currentIndex=0;break;case"End":case"ArrowEnd":this.currentIndex=this.tabItems.length-1;break;case"Enter":case"Space":this.selectTab(e.target),e.target.focus();break;default:return}e.preventDefault(),this.tabs[this.currentIndex].focus()}}export{e as default};