Кастомизация через tabbableOptions

Библиотека Focus-trap в JavaScript используется для управления фокусом внутри определённой области интерфейса, например, модальных окон, всплывающих панелей или кастомных виджетов. Одним из ключевых инструментов для гибкой настройки поведения является объект tabbableOptions, который позволяет управлять тем, какие элементы считаются доступными для фокуса при навигации с помощью клавиши Tab.

Основная идея tabbableOptions

По умолчанию Focus-trap использует внутреннюю библиотеку tabbable для определения элементов, которые можно фокусировать. В tabbableOptions можно передать параметры, которые изменяют этот процесс. Это позволяет исключать определённые элементы из цикла фокуса, включать нестандартные элементы и тонко настраивать взаимодействие с DOM.

const trap = createFocusTrap('#modal', {
  tabbableOptions: {
    displayCheck: 'none',
    tabbable: element => !element.classList.contains('skip-focus')
  }
});

В этом примере:

  • displayCheck: 'none' — заставляет Focus-trap игнорировать проверку видимости элемента через CSS-свойство display.
  • tabbable — кастомная функция, которая позволяет исключать элементы с определённым классом из цикла фокуса.

Ключевые свойства tabbableOptions

  1. includeContainer Булево значение, указывающее, считать ли контейнер фокусируемым. По умолчанию false. Если выставлено true, контейнер будет включён в список элементов для табуляции.

    tabbableOptions: {
      includeContainer: true
    }
  2. displayCheck Определяет, как проверяется видимость элементов. Возможные значения:

    • 'full' — элементы скрытые через display: none или visibility: hidden исключаются.
    • 'legacy-full' — устаревший режим с дополнительной проверкой размеров.
    • 'none' — полностью игнорирует проверку видимости.

    Используется в ситуациях, когда фокус должен оставаться на элементах, которые временно скрыты.

  3. getShadowRoot Функция, возвращающая shadow root для элементов, чтобы библиотека корректно определяла фокусируемые элементы внутри Shadow DOM.

    tabbableOptions: {
      getShadowRoot: element => element.shadowRoot
    }
  4. tabbable Функция, принимающая элемент и возвращающая булево значение. Позволяет программно исключать или включать элементы в цикл табуляции. Очень удобно для динамических интерфейсов с условиями показа/скрытия элементов.

  5. normalizeTabIndex Булево значение. Если установлено в true, библиотека автоматически корректирует отрицательные значения tabindex на корректные для правильной навигации.

Примеры кастомизации

Исключение кнопок с определённым классом:

const trap = createFocusTrap('#dialog', {
  tabbableOptions: {
    tabbable: el => !el.classList.contains('ignore-tab')
  }
});

Фокусировка элементов в Shadow DOM:

const trap = createFocusTrap('#custom-widget', {
  tabbableOptions: {
    getShadowRoot: el => el.shadowRoot
  }
});

Игнорирование видимости для элементов с display: none:

const trap = createFocusTrap('#menu', {
  tabbableOptions: {
    displayCheck: 'none'
  }
});

Взаимодействие с динамическим DOM

Использование tabbableOptions критично для интерфейсов, где элементы появляются и исчезают динамически. Например, при открытии подсказок или кастомных селекторов, некоторые элементы могут быть скрыты через CSS или удалены из DOM. Настройка displayCheck и tabbable обеспечивает стабильное поведение фокуса, предотвращая зацикливание или потерю фокуса.

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

  • Для модальных окон рекомендуется includeContainer: true, если контейнер сам является интерактивным элементом.
  • Использование кастомной функции tabbable даёт полный контроль над исключениями и условиями включения элементов.
  • Проверка displayCheck: 'none' может быть полезна для анимаций, когда элемент визуально скрыт, но должен оставаться доступным для клавиатуры.
  • Shadow DOM требует явного указания getShadowRoot, иначе Focus-trap не увидит внутренние элементы.

Использование tabbableOptions позволяет создавать гибкие, адаптивные интерфейсы с корректной клавиатурной навигацией и полной поддержкой современных веб-технологий, включая Shadow DOM, динамически добавляемые элементы и кастомные интерактивные компоненты.