В Chakra UI управление фокусом реализуется через механизмы
FocusLock и встроенные свойства компонентов оверлеев,
таких как Modal, Drawer, Popover
и AlertDialog. Основная цель — предотвратить потерю фокуса
пользователем при взаимодействии с модальными окнами и обеспечить
корректную навигацию с клавиатуры.
Компоненты оверлеев в Chakra UI автоматически устанавливают фокус на
первый интерактивный элемент внутри при открытии. Для Modal
это свойство initialFocusRef:
import { useRef } from "react";
import { Modal, ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalCloseButton, Button } from "@chakra-ui/react";
function ExampleModal({ isOpen, onClose }) {
const initialRef = useRef();
return (
<Modal isOpen={isOpen} onCl ose={onClose} initialFocusRef={initialRef}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Пример модального окна</ModalHeader>
<ModalCloseButton />
<ModalBody>
<input ref={initialRef} placeholder="Фокус сюда при открытии" />
<Button mt={4}>Подтвердить</Button>
</ModalBody>
</ModalContent>
</Modal>
);
}
Ключевые моменты:
initialFocusRef позволяет точно указать элемент,
который получит фокус при открытии.initialFocusRef не задан, Chakra UI установит
фокус на первый доступный интерактивный элемент внутри оверлея.После закрытия модального окна полезно вернуть фокус к элементу,
который его инициировал. Для этого используется свойство
finalFocusRef:
const btnRef = useRef();
<Button ref={btnRef} onCl ick={onOpen}>Открыть модал</Button>
<Modal
isOpen={isOpen}
onCl ose={onClose}
initialFocusRef={initialRef}
finalFocusRef={btnRef}
>
{/* Содержимое модала */}
</Modal>
Принцип работы: Chakra UI автоматически переносит
фокус обратно к finalFocusRef после закрытия оверлея, что
повышает удобство навигации для пользователей клавиатуры.
Chakra UI использует библиотеку react-focus-lock, чтобы
запирать фокус внутри модального окна. Это
предотвращает выход фокуса наружу и улучшает доступность.
Особенности работы FocusLock:
Tab и
Shift+Tab.Popover и Drawer этот
механизм также активен по умолчанию.Иногда требуется переназначить фокус динамически, например, при
условных рендерах или асинхронной загрузке контента. Для этого можно
использовать эффект useEffect:
import { useEffect, useRef } from "react";
const dynamicRef = useRef();
useEffect(() => {
if (isOpen && dynamicRef.current) {
dynamicRef.current.focus();
}
}, [isOpen]);
Рекомендации:
ref.current
перед установкой фокуса.tabIndex={-1} для элементов, которые
должны получать фокус программно, но не участвуют в обычной
таб-навигации.Chakra UI следует стандартам WAI-ARIA. Для модальных оверлеев:
aria-modal="true".Для Popover и Menu также поддерживается
автоматическая фокусировка и правильный порядок табуляции:
<Menu>
<MenuButton as={Button}>Открыть меню</MenuButton>
<MenuList>
<MenuItem>Пункт 1</MenuItem>
<MenuItem>Пункт 2</MenuItem>
</MenuList>
</Menu>
Пользователь может перемещаться между пунктами меню с помощью стрелок, а фокус остается внутри компонента до его закрытия.
Иногда требуется разрешить взаимодействие с элементами вне оверлея,
например, с уведомлениями. Для этого можно отключить фокус-замок через
trapFocus={false}:
<Drawer isOpen={isOpen} onCl ose={onClose} trapFocus={false}>
{/* Контент */}
</Drawer>
Использование этой опции должно быть обоснованным, так как нарушение фокус-замка может ухудшить доступность.
initialFocusRef и
finalFocusRef, чтобы управление фокусом было
предсказуемым.ref для динамических
элементов, чтобы гарантировать правильное перемещение
фокуса.Управление фокусом в Chakra UI обеспечивает безопасное и удобное взаимодействие с оверлеями, минимизируя ошибки навигации и повышая доступность интерфейсов.