UNPKG

@gravityforms/utils

Version:
84 lines (81 loc) 2.27 kB
import getFocusable from '../dom/get-focusable'; /** * @module focusLoop * @description Loop through focusable els inside a container. Bound to a keydown listener usually. * * @since 1.0.0 * * @param {KeyboardEvent} e The event object from the keyDown/keyUp listener using this. * @param {HTMLElement} trigger The trigger that the user clicked to launch the element using focus loop. * @param {HTMLElement} container The container the trigger focused. * @param {Function} onEscape The function to call if the esc key is used. * * @requires getFocusable * * @return {void} * * @example * import { focusLoop } from "@gravityforms/utils"; * * const exampleContainer = document.getElementById( 'example-container' ); * const exampleTrigger = document.getElementById( 'example-trigger' ); * * closeExample = () => { * // close the container. * } * * handleKeyEvents = ( e ) => * focusLoop( * e, * exampleTrigger, * exampleContainer, * closeExample * ); * * bindEvents = () => { * exampleContainer.addEventListener( 'keydown', handleKeyEvents ); * }; * * bindEvents(); * */ export default function focusLoop( e = {}, trigger = null, container = null, onEscape = () => {} ) { if ( ! container || ! trigger ) { console.error( 'You need to pass a container and trigger node to focusLoop.' ); return; } // esc key, refocus the settings trigger in the editor preview for the active field if ( e.keyCode === 27 ) { trigger.focus(); onEscape(); return; } // not tab key, exit if ( e.keyCode !== 9 ) { return; } // get visible focusable items const focusable = getFocusable( container ); // store first and last visible item const firstFocusableEl = focusable[ 0 ]; const lastFocusableEl = focusable[ focusable.length - 1 ]; // shiftkey was involved, we're going backwards, focus last el if we are leaving first if ( e.shiftKey ) { /* shift + tab */ if ( document.activeElement === firstFocusableEl ) { lastFocusableEl.focus(); e.preventDefault(); } // regular tabbing direction, bring us back to first el at reaching end } /* tab */ else if ( document.activeElement === lastFocusableEl ) { firstFocusableEl.focus(); e.preventDefault(); } }