FocusScope и изоляция фокуса

В библиотеке React Aria управление фокусом является ключевым аспектом создания доступных пользовательских интерфейсов. Компонент FocusScope позволяет изолировать фокус внутри определённого участка интерфейса, гарантируя правильное поведение клавиатурной навигации и улучшая взаимодействие с ассистивными технологиями.


Основные принципы FocusScope

FocusScope обеспечивает следующие возможности:

  • Автоматическая изоляция фокуса: при активации фокус остаётся внутри указанного блока, предотвращая переход на элементы вне этого блока.
  • Фокусировка при монтировании: можно настроить автоматический перевод фокуса на первый или последний элемент внутри области при её рендеринге.
  • Возврат фокуса: после размонтирования области фокус возвращается к элементу, который был активен до открытия FocusScope.
  • Клавиатурная навигация: стрелки, Tab и Shift+Tab корректно перемещают фокус по элементам внутри области.

Использование FocusScope критически важно для модальных окон, выпадающих меню, панели и других компонентов, где важно удерживать пользователя внутри интерфейсного блока.


Импорт и базовое использование

Для использования FocusScope необходимо импортировать соответствующие хуки из React Aria:

import { FocusScope } from "@react-aria/focus";

Простейший пример:

function Modal({ isOpen, onClose }) {
  if (!isOpen) return null;

  return (
    <FocusScope contain restoreFocus autoFocus>
      <div role="dialog" aria-modal="true">
        <button onCl ick={onClose}>Закрыть</button>
        <input type="text" placeholder="Имя" />
        <button>Отправить</button>
      </div>
    </FocusScope>
  );
}

Разбор параметров FocusScope:

  • contain — включает изоляцию фокуса, предотвращая выход за пределы блока.
  • restoreFocus — возвращает фокус к элементу, активному до открытия области.
  • autoFocus — автоматически ставит фокус на первый фокусируемый элемент внутри блока при монтировании.

Поддержка сложных сценариев

FocusScope корректно работает с динамическими элементами и вложенными областями:

<FocusScope contain restoreFocus autoFocus>
  <div>
    <button>Первый</button>
    <FocusScope contain>
      <div>
        <input placeholder="Вложенный ввод" />
        <button>Вложенный</button>
      </div>
    </FocusScope>
    <button>Последний</button>
  </div>
</FocusScope>

Вложенные FocusScope позволяют создавать многоуровневые интерфейсы, где каждая подобласть может изолировать фокус локально. При этом внешний FocusScope продолжает корректно управлять фокусом после закрытия внутреннего.


Управление автофокусом

React Aria предоставляет гибкий контроль над тем, какой элемент получает фокус. Параметр autoFocus может принимать:

  • boolean — автоматически фокусирует первый элемент.
  • selector — CSS-селектор для точного указания элемента.
  • ref — React Ref, указывающий элемент для фокусировки.

Пример использования селектора:

<FocusScope autoFocus="[data-autofocus]">
  <input data-autofocus placeholder="Фокус сюда" />
  <input placeholder="Следующий" />
</FocusScope>

Возврат фокуса и взаимодействие с ассистивными технологиями

Параметр restoreFocus обеспечивает корректный возврат фокуса после закрытия модального окна или панели. Это критично для пользователей, работающих с экранными читалками или клавиатурой:

function Dropdown({ isOpen }) {
  const buttonRef = React.useRef();

  return (
    <>
      <button ref={buttonRef}>Открыть меню</button>
      {isOpen && (
        <FocusScope contain restoreFocus autoFocus>
          <ul role="menu">
            <li role="menuitem">Элемент 1</li>
            <li role="menuitem">Элемент 2</li>
          </ul>
        </FocusScope>
      )}
    </>
  );
}

При закрытии меню фокус возвращается на кнопку, что делает взаимодействие предсказуемым и доступным.


Особенности работы с клавишами

FocusScope корректно обрабатывает:

  • Tab / Shift+Tab — циклическая навигация внутри области.
  • Arrow keys — для элементов, поддерживающих стрелочную навигацию, таких как меню и списки.

Это позволяет создавать сложные интерактивные компоненты без дополнительного ручного контроля за фокусом.


Практические рекомендации

  1. Использовать FocusScope для всех модальных компонентов и всплывающих панелей.
  2. Настраивать autoFocus для первого важного интерактивного элемента.
  3. Всегда включать restoreFocus, чтобы пользователи не теряли контекст.
  4. Для сложных интерфейсов с вложенными областями применять несколько уровней FocusScope.
  5. Совмещать FocusScope с семантическими атрибутами ARIA (role="dialog", aria-modal) для полной доступности.

Взаимодействие с другими хуками React Aria

FocusScope часто используется совместно с:

  • useOverlay — для управления открытием и закрытием модальных элементов.
  • useButton — для кнопок, управляющих фокусируемыми областями.
  • useListBox — для списков с клавиатурной навигацией внутри FocusScope.

Такое сочетание обеспечивает комплексное управление доступностью и фокусом без лишнего кода.