@oruga-ui/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
68 lines (67 loc) • 2.3 kB
JavaScript
;
/*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */
function findFocusable(element) {
if (!element) return null;
return element.querySelectorAll(`a[href]:not([tabindex="-1"]),
area[href],
input:not([disabled]):not([type="hidden"]),
select:not([disabled]),
textarea:not([disabled]),
button:not([disabled]),
iframe,
object,
embed,
*[tabindex]:not([tabindex="-1"]):not([disabled]),
*[contenteditable]`);
}
function useTrapFocus() {
let onKeyDown = null;
function applyHandler(el, value) {
if (value) {
el.focus({ preventScroll: true });
if (typeof onKeyDown === "function")
el.addEventListener("keydown", onKeyDown);
} else {
if (typeof onKeyDown === "function")
el.removeEventListener("keydown", onKeyDown);
}
}
const onMounted = (el, { value }) => {
onKeyDown = (event) => {
const target = event.target;
if (!target) return;
const focusable = findFocusable(el);
if (!(focusable == null ? void 0 : focusable.length)) {
event.preventDefault();
return;
}
const firstFocusable = focusable[0];
const lastFocusable = focusable[focusable.length - 1];
if (target === firstFocusable && event.shiftKey && event.key === "Tab") {
event.preventDefault();
lastFocusable.focus();
} else if (target === lastFocusable && !event.shiftKey && event.key === "Tab") {
event.preventDefault();
firstFocusable.focus();
}
};
if (value) applyHandler(el, value);
};
const onBeforeUnmount = (el) => {
applyHandler(el, false);
onKeyDown = null;
};
const onUpdate = (el, { value, oldValue }) => {
if (value !== oldValue)
applyHandler(el, value);
};
return {
vTrapFocus: {
mounted: onMounted,
beforeUnmount: onBeforeUnmount,
updated: onUpdate
}
};
}
exports.useTrapFocus = useTrapFocus;
//# sourceMappingURL=useTrapFocus-DXSX2lWD.cjs.map