UNPKG

@ishitatsuyuki/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

55 lines (53 loc) 2.23 kB
const findFocusable = (element, programmatic = false) => { if (!element) { return null; } if (programmatic) { return element.querySelectorAll(`*[tabindex="-1"]`); } return element.querySelectorAll(`a[href]:not([tabindex="-1"]), area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex]:not([tabindex="-1"]), *[contenteditable]`); }; let onKeyDown; const bind = (el, { value = true }) => { if (value) { let focusable = findFocusable(el); let focusableProg = findFocusable(el, true); if (focusable && focusable.length > 0) { onKeyDown = (event) => { // Need to get focusable each time since it can change between key events // ex. changing month in a datepicker focusable = findFocusable(el); focusableProg = findFocusable(el, true); const firstFocusable = focusable[0]; const lastFocusable = focusable[focusable.length - 1]; if (event.target === firstFocusable && event.shiftKey && event.key === 'Tab') { event.preventDefault(); lastFocusable.focus(); } else if ((event.target === lastFocusable || Array.from(focusableProg).indexOf(event.target) >= 0) && !event.shiftKey && event.key === 'Tab') { event.preventDefault(); firstFocusable.focus(); } }; el.addEventListener('keydown', onKeyDown); } } }; const unbind = (el) => { el.removeEventListener('keydown', onKeyDown); }; const directive = { beforeMount: bind, beforeUnmount: unbind, }; export { directive as d };