UNPKG

deep-focus-trap

Version:

A focus trap library that pierces that shadow dom. So you can use it with native web components. Deep Focus Trap is a lightweight library written in vanilla js with only one dependency (that is tree-shakable if not in use).

3 lines (2 loc) 2.79 kB
class e{constructor(e){this.TAB=9,this.ESC=27,this.FOCUSABLE_ELEMENT_SELECTORS='a[href], area[href], input:not([disabled]):not([hidden]):not([hidden="true"]):not([tabindex="-1"]), textarea:not([disabled]), button:not([disabled]), iframe, object, [tabindex="0"], button:not([tabindex="-1"]) [contenteditable]',this.el="string"==typeof e.el?document.querySelector(e.el):e.el,this.focusElement=e.focusElement,this.returnFocus=e.returnFocus??!0,this.escCallback=e.escCallback,this.listener=this.listener.bind(this),this.includeActiveElement=e.includeActiveElement??!1,this.unordered=!(!e.unordered&&!this.includeActiveElement),this.active=!1,this.unordered&&(this.index=1,this.lastFocusedIndex=0)}get elements(){return this.focusableElements}setReturnFocusEl(e){let t=document.activeElement;t=t.shadowRoot?t.shadowRoot.activeElement:t,this.previousFocusedEl=e??t}updateElements(e){this.setElements(e)}setElements(e){this.focusableElements=e??this.el.querySelectorAll(this.FOCUSABLE_ELEMENT_SELECTORS),this.firstFocusableEl=this.focusableElements[0],this.lastFocusableEl=this.focusableElements[this.focusableElements.length-1],this.elementToFocus=this.focusElement?this.focusElement:this.firstFocusableEl,this.setReturnFocusEl()}listener(e){let t=document.activeElement;t.shadowRoot&&(t=t.shadowRoot.activeElement),e.keyCode===this.TAB?this.unordered?(e.preventDefault(),this.handleUnorderedFocus(e)):e.shiftKey&&t===this.firstFocusableEl?(e.preventDefault(),this.lastFocusableEl.focus()):e.shiftKey||t!==this.lastFocusableEl||(e.preventDefault(),this.firstFocusableEl.focus()):e.keyCode===this.ESC&&this.escCallback&&(this.escCallback(),this.deactivate())}activate(){if(this.setElements(),this.focusableElements.length>0){if(this.active=!0,this.includeActiveElement){const e=document.activeElement,t=e.shadowRoot?e.shadowRoot.activeElement:e;this.setElements([...this.elements,t])}this.elementToFocus.focus(),this.unordered?window.addEventListener("keydown",this.listener):this.el.addEventListener("keydown",this.listener)}}deactivate(){this.active=!1,this.unordered?window.removeEventListener("keydown",this.listener):this.el.removeEventListener("keydown",this.listener),this.returnFocus&&void 0!==this.previousFocusedEl&&this.previousFocusedEl.focus()}handleUnorderedFocus(e){e.shiftKey?(this.index=this.index<0?this.focusableElements.length+1:this.index,this.index>=this.lastFocusedIndex&&(this.index-=2),this.focusableElements[this.index].focus(),this.lastFocusedIndex=this.index,this.index-=1):(this.index=this.index===this.focusableElements.length?0:this.index,0!==this.index&&this.index<=this.lastFocusedIndex&&(this.index+=2),this.focusableElements[this.index].focus(),this.lastFocusedIndex=this.index,this.index+=1)}}export{e as focusTrap}; //# sourceMappingURL=focus-trap.esm.min.js.map