UNPKG

@ozen-ui/kit

Version:

React component library

71 lines (70 loc) 3.21 kB
"use strict"; 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; }