Библиотека Focus-trap предназначена для управления фокусом внутри заданного контейнера. Она гарантирует, что пользовательский фокус не выйдет за пределы элемента, пока активен «ловушка фокуса». Это особенно важно для модальных окон, всплывающих меню и других интерактивных компонентов, где фокус должен оставаться внутри определённой области.
Фокусировка осуществляется через контроль последовательности
элементов с атрибутами tabindex,
<button>, <input>,
<a> и других интерактивных тегов.
Focus-trap перехватывает события клавиш
Tab и Shift+Tab, создавая циклическую
навигацию внутри контейнера.
Предустановка (preset) в Focus-trap позволяет заранее определить настройки поведения ловушки фокуса, которые можно многократно использовать для разных элементов. Это упрощает код и повышает читаемость, особенно когда проект содержит несколько модальных компонентов с одинаковыми правилами фокусировки.
Для создания предустановки используется объект конфигурации:
import { createFocusTrap } from 'focus-trap';
const modalFocusTrapConfig = {
escapeDeactivates: true, // деактивация ловушки при нажатии Escape
clickOutsideDeactivates: true, // закрытие при клике вне контейнера
returnFocusOnDeactivate: true, // возврат фокуса к исходному элементу
initialFocus: '#firstInput', // фокус на конкретный элемент при активации
fallbackFocus: '#modal', // элемент для фокуса, если initialFocus отсутствует
allowOutsideClick: false // запрет клика вне контейнера без деактивации
};
После создания конфигурации можно использовать её для любого контейнера:
const modalTrap = createFocusTrap('#modal', modalFocusTrapConfig);
modalTrap.activate();
escapeDeactivates – логическое
значение, определяющее возможность деактивации ловушки клавишей
Escape. Полезно для модальных окон, которые должны
закрываться по Esc.clickOutsideDeactivates – позволяет
отключить ловушку при клике за пределами контейнера. Можно передать
функцию для условной деактивации.returnFocusOnDeactivate – возвращает
фокус на элемент, который был активен до активации ловушки.
Предотвращает потерю контекста навигации.initialFocus – селектор или функция,
возвращающая элемент, на который будет установлен фокус при активации
ловушки.fallbackFocus – элемент, на который
фокус установится, если initialFocus не найден или
недоступен.allowOutsideClick – контролирует
возможность клика вне контейнера без деактивации. Можно использовать
функцию, чтобы разрешить клик на определённые элементы.Focus-trap позволяет создавать не просто объекты конфигурации, а функции предустановок, которые возвращают готовую конфигурацию в зависимости от параметров. Это удобно для динамических модальных окон или компонентов с различными условиями активации.
Пример функции предустановки:
function createModalPreset(focusId, closeOnClick = true) {
return {
escapeDeactivates: true,
clickOutsideDeactivates: closeOnClick,
returnFocusOnDeactivate: true,
initialFocus: `#${focusId}`,
fallbackFocus: '#modal'
};
}
// Использование
const modalTrap = createFocusTrap('#modal', createModalPreset('usernameInput', false));
modalTrap.activate();
Такой подход делает код масштабируемым: при изменении логики модального окна достаточно изменить одну функцию, а не каждый объект конфигурации.
Можно создавать базовую предустановку и расширять её с помощью
spread-оператора или Object.assign, добавляя уникальные
опции для конкретных случаев:
const basePreset = {
escapeDeactivates: true,
returnFocusOnDeactivate: true,
fallbackFocus: '#modal'
};
const formModalPreset = {
...basePreset,
initialFocus: '#formInput',
clickOutsideDeactivates: false
};
const settingsModalPreset = {
...basePreset,
initialFocus: '#settingsButton',
clickOutsideDeactivates: true
};
Такой подход позволяет централизованно управлять поведением ловушек фокуса в проекте.
Focus-trap предоставляет методы activate() и
deactivate(). Предустановки влияют только на конфигурацию,
но управление активацией всегда остаётся явным:
const trap = createFocusTrap('#modal', formModalPreset);
// Открытие модального окна
document.querySelector('#openModal').addEventListener('click', () => trap.activate());
// Закрытие модального окна
document.querySelector('#closeModal').addEventListener('click', () => trap.deactivate());
Для сложных интерфейсов можно хранить массив предустановок и применять их по типу модального окна или контекста.
initialFocus до активации.allowOutsideClick только для
случаев, когда это действительно необходимо.Эта структура позволяет создавать масштабируемые и управляемые ловушки фокуса в проектах любой сложности, обеспечивая согласованное поведение модальных компонентов и интерактивных областей.