@ozen-ui/kit
Version:
React component library
71 lines (70 loc) • 3.21 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.useFocusTrap = useFocusTrap;
var react_1 = require("react");
var getFocusableElements_1 = require("../../utils/getFocusableElements");
var isKey_1 = require("../../utils/isKey");
var useEventListener_1 = require("../useEventListener");
/** Хук для ловушки фокуса, обычно применяется в контексте модальных окон */
function useFocusTrap(_a) {
var _b = _a === void 0 ? {
active: true,
focusinTrap: true,
keyDownTrap: true,
} : _a,
/** Признак активности ловушки */
_c = _b.active,
/** Признак активности ловушки */
active = _c === void 0 ? true : _c,
/** Предотвращает любые события фокуса вне контейнера ловушки */
focusinTrap = _b.focusinTrap,
/** Предотвращает переход на элементы вне контейнера ловушки через клавиши {Tab} и {Tab + Shift} */
keyDownTrap = _b.keyDownTrap;
var elRef = (0, react_1.useRef)(null);
(0, useEventListener_1.useEventListener)({
eventName: 'focusin',
handler: function () {
var _a, _b;
if (!(elRef === null || elRef === void 0 ? void 0 : elRef.current)) {
return;
}
var keyboardFocusableElements = (0, getFocusableElements_1.getFocusableElements)(elRef.current);
if (!((_a = elRef.current) === null || _a === void 0 ? void 0 : _a.contains(document.activeElement))) {
var firstEl = keyboardFocusableElements[0];
if (firstEl) {
firstEl.focus();
}
else {
(_b = elRef.current) === null || _b === void 0 ? void 0 : _b.focus();
}
}
},
active: active && focusinTrap,
});
(0, useEventListener_1.useEventListener)({
eventName: 'keydown',
handler: function (event) {
var _a, _b;
var shiftKey = event.shiftKey;
if (!(elRef === null || elRef === void 0 ? void 0 : elRef.current)) {
return;
}
var active = document.activeElement;
var focusable = (0, getFocusableElements_1.getFocusableElements)(elRef.current);
var last = focusable[focusable.length - 1];
if (shiftKey && (0, isKey_1.isKey)(event, 'Tab')) {
event.preventDefault();
var prev = (_a = focusable[(focusable.indexOf(active) - 1) % focusable.length]) !== null && _a !== void 0 ? _a : last;
prev === null || prev === void 0 ? void 0 : prev.focus();
}
else if ((0, isKey_1.isKey)(event, 'Tab')) {
if (focusable.indexOf(active) < 0 || active === last) {
event.preventDefault();
(_b = focusable[0]) === null || _b === void 0 ? void 0 : _b.focus();
}
}
},
active: active && keyDownTrap,
});
return elRef;
}
;