Focus Lock — это механизм управления фокусом внутри
интерактивных компонентов, который предотвращает случайное выход за
пределы определённой области интерфейса. В Chakra UI он реализован через
компонент FocusLock и тесно интегрирован с модальными
окнами, выпадающими меню и тултипами. Основная цель — обеспечить
доступность и корректное взаимодействие с клавиатурой,
особенно для пользователей, полагающихся на навигацию с помощью клавиш
Tab и Shift+Tab.
Chakra UI предоставляет FocusLock через пакет
@chakra-ui/react. Для использования необходимо обернуть
интерактивный компонент в <FocusLock>:
import { Button, Box } from "@chakra-ui/react";
import FocusLock from "react-focus-lock";
function Example() {
return (
<FocusLock>
<Box p={4} border="1px solid gray">
<Button colorScheme="blue" mr={2}>Кнопка 1</Button>
<Button colorScheme="green">Кнопка 2</Button>
</Box>
</FocusLock>
);
}
В этом примере фокус остаётся внутри контейнера, и
пользователь не сможет переключиться на элементы за пределами
Box с помощью клавиши Tab.
disabled — отключает блокировку
фокуса. Полезно, если блокировка должна активироваться динамически.<FocusLock disabled={true}>
{/* Содержимое */}
</FocusLock>
returnFocus — автоматически возвращает
фокус к элементу, который был активен до активации FocusLock, при его
размонтировании. По умолчанию включено (true).<FocusLock returnFocus={false}>
{/* Содержимое */}
</FocusLock>
persistentFocus — заставляет фокус
оставаться внутри контейнера даже при кликах вне его. Используется в
сложных модальных интерфейсах.<FocusLock persistentFocus={true}>
{/* Содержимое */}
</FocusLock>
autoFocus — автоматически фокусирует
первый доступный интерактивный элемент при монтировании. Полезно для
модальных окон.<FocusLock autoFocus={true}>
<Button>Первая кнопка</Button>
</FocusLock>
Модальные окна Chakra UI (Modal) уже используют
FocusLock под капотом через ModalContent. Это
обеспечивает доступность и корректное управление клавиатурой без
дополнительной конфигурации. Пример модального окна:
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalCloseButton,
ModalBody,
ModalFooter,
Button,
useDisclosure
} from "@chakra-ui/react";
function ModalExample() {
const { isOpen, onOpen, onClose } = useDisclosure();
return (
<>
<Button onCl ick={onOpen}>Открыть модальное окно</Button>
<Modal isOpen={isOpen} onCl ose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Заголовок</ModalHeader>
<ModalCloseButton />
<ModalBody>
<Button colorScheme="blue" mr={2}>Кнопка 1</Button>
<Button colorScheme="green">Кнопка 2</Button>
</ModalBody>
<ModalFooter>
<Button onCl ick={onClose}>Закрыть</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
);
}
Фокус при открытии автоматически переходит на первый интерактивный
элемент (Button) внутри модального окна, а при закрытии
возвращается к кнопке, которая его открывала.
Использование FocusLock критически важно для
доступности (a11y):
render conditional) важно использовать
autoFocus и returnFocus, чтобы не терять
управление фокусом.Portal и
Drawer, чтобы обеспечить корректное управление фокусом даже
при рендеринге элементов вне обычного DOM-потока.Использование Focus Lock в Chakra UI позволяет создавать доступные, предсказуемые и управляемые интерфейсы, где фокус всегда остаётся в пределах интерактивного блока. Это особенно важно для модальных окон, дропдаунов и других всплывающих компонентов, где нарушение порядка фокуса может приводить к проблемам с навигацией и доступностью.