UNPKG

@ozen-ui/kit

Version:

React component library

68 lines (67 loc) 2.96 kB
import { useRef } from 'react'; import { getFocusableElements } from '../../utils/getFocusableElements'; import { isKey } from '../../utils/isKey'; import { useEventListener } from '../useEventListener'; /** Хук для ловушки фокуса, обычно применяется в контексте модальных окон */ export 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 = useRef(null); useEventListener({ eventName: 'focusin', handler: function () { var _a, _b; if (!(elRef === null || elRef === void 0 ? void 0 : elRef.current)) { return; } var keyboardFocusableElements = 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, }); 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 = getFocusableElements(elRef.current); var last = focusable[focusable.length - 1]; if (shiftKey && 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 (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; }