Фокус менеджмент

Архитектура фокусного состояния

В основе механизма управления фокусом в Tom Select лежит разделение на несколько логических узлов интерфейса: исходный <select>-элемент, контейнер управления (control), поле ввода (input) и выпадающий список (dropdown). Фокусное состояние не закрепляется за одним DOM-элементом, а динамически перемещается между компонентами в зависимости от состояния компонента.

Контейнер управления выступает основным точечным получателем фокуса. Он эмулирует поведение нативного элемента формы, сохраняя при этом возможность взаимодействия через клавиатуру и программный API.


Инициализация фокусного поведения

При создании экземпляра Tom Select исходный элемент <select> скрывается, а на его месте формируется интерактивная структура. Фокус, первоначально принадлежащий нативному элементу, переопределяется через tabindex у контейнера управления.

Ключевые элементы инициализации:

  • установка tabindex="0" для контейнера управления
  • синхронизация состояния фокуса между оригинальным элементом и кастомным UI
  • привязка обработчиков focus и blur к контейнеру

Событие focus на исходном элементе перенаправляется на кастомный контейнер, обеспечивая единое поведение независимо от способа активации.


Перехват и удержание фокуса при активации компонента

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

Поведение включает:

  • перевод фокуса в input при включённой опции поиска
  • удержание фокуса внутри компонента при взаимодействии с dropdown
  • предотвращение потери фокуса при кликах внутри списка опций

В момент открытия списка активное состояние фиксируется, а навигация клавиатурой перенаправляется на элементы опций.


Перемещение фокуса между input и control

В режиме поиска фокус динамически переключается между двумя узлами:

  • control — основной контейнер взаимодействия
  • input — поле ввода фильтрации

При активации ввода фокус смещается в input, при завершении ввода или выборе значения может возвращаться в control.

Состояния переключения:

  • открытие dropdown → фокус в input
  • выбор элемента → возврат фокуса в control
  • закрытие dropdown без выбора → восстановление предыдущего состояния фокуса

Такое разделение позволяет поддерживать непрерывный ввод без потери контекста интерфейса.


Порядок табуляции и взаимодействие с клавиатурой

Фокусное поведение интегрируется в общий tab order документа через управление tabindex.

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

  • контейнер управления участвует в последовательной табуляции
  • внутренние элементы dropdown исключаются из глобального tab order
  • навигация внутри списка опций реализуется через стрелочные клавиши без изменения DOM-фокуса

При использовании клавиши Tab происходит выход из компонента с фиксацией выбранного значения или состояния ввода.


Поведение при потере фокуса

Событие blur обрабатывается с учётом структуры компонента. Потеря фокуса не всегда означает завершение взаимодействия, поскольку dropdown может оставаться активным.

Учитываются следующие сценарии:

  • переход фокуса внутри компонентов Tom Select не инициирует закрытие
  • клик по опции не вызывает немедленный blur до завершения выбора
  • переход на внешний элемент приводит к закрытию dropdown при отсутствии закреплённого состояния

Логика проверки осуществляется через анализ relatedTarget и принадлежности элемента к DOM-структуре компонента.


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

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

Поведение при открытии:

  • установка активного состояния контейнера
  • перенос фокуса в input (если доступен)
  • активация навигации по списку опций

Поведение при закрытии:

  • восстановление фокуса на control
  • очистка состояния активной навигации
  • синхронизация выбранного значения с оригинальным select

Закрытие может происходить как через выбор значения, так и через внешнее действие (например, blur или нажатие Escape).


Обработка множественного выбора и фокус

В режиме множественного выбора (multiple) фокусная модель усложняется за счёт наличия токенов выбранных значений.

Особенности:

  • фокус остаётся в input при добавлении новых значений
  • переход между токенами осуществляется через клавиши навигации
  • удаление элемента может происходить без смены фокуса

Удалённые элементы не требуют возврата фокуса на control, если сохраняется активный input.


Интеграция с формами и нативным поведением

Фокусное поведение синхронизируется с состоянием формы через скрытый <select>-элемент. Несмотря на кастомный UI, состояние фокуса не нарушает стандартную модель HTML-форм.

Особенности интеграции:

  • отправка формы не зависит от состояния dropdown
  • фокус не блокирует нативную валидацию формы
  • переключение между полями формы учитывает кастомный tabindex

Edge-case сценарии фокусного поведения

Некоторые состояния требуют дополнительной обработки фокуса:

Отключённое состояние

  • при disabled фокус не может быть установлен на control
  • tabindex динамически исключается из последовательности

Readonly режим

  • фокус устанавливается, но ввод блокируется
  • навигация по опциям может оставаться активной

Программное управление

  • вызовы API открытия/закрытия dropdown не всегда изменяют DOM-фокус
  • требуется синхронизация состояния вручную через методы компонента

Событийная модель фокуса

Фокусное поведение сопровождается набором событий, отражающих изменения состояния:

  • onFocus — активация control
  • onBlur — потеря фокуса компонентом
  • onDropdownOpen — открытие списка
  • onDropdownClose — закрытие списка

Эти события формируют основу для синхронизации состояния интерфейса и управления логикой взаимодействия, не нарушая внутреннюю модель фокусировки.