Поддержка ARIA атрибутов

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

Основная задача ARIA в контексте Awesomplete заключается в синхронизации состояния списка подсказок с текстовым полем ввода. Это включает передачу информации о том, открыт ли список, какой элемент активен и какие элементы доступны для выбора.

Связывание поля ввода и списка

Ключевым элементом доступности является связь input-элемента с выпадающим списком. Awesomplete автоматически добавляет набор атрибутов:

  • aria-autocomplete="list" — указывает тип автодополнения
  • aria-expanded — отражает состояние раскрытия списка
  • aria-owns — связывает input с контейнером списка
  • aria-activedescendant — указывает текущий активный элемент

Пример базовой разметки с активированным Awesomplete:

<input id="city" class="awesomplete" />

После инициализации библиотека динамически расширяет DOM:

<input id="city"
       class="awesomplete"
       aria-autocomplete="list"
       aria-expanded="false"
       aria-owns="awesomplete_list_1"
       aria-activedescendant="">

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

Управление состоянием раскрытия

Атрибут aria-expanded является одним из ключевых индикаторов состояния компонента. Awesomplete обновляет его при каждом изменении состояния списка:

  • false — список скрыт
  • true — список отображается

Это состояние синхронизируется с открытием и закрытием popup-элемента. При этом изменение происходит не только визуально, но и семантически, что критично для корректного чтения экранными дикторами.

input.addEventListener("awesomplete-open", function () {
    console.log("Список открыт");
});

input.addEventListener("awesomplete-close", function () {
    console.log("Список закрыт");
});

Хотя события не относятся напрямую к ARIA, они отражают моменты обновления aria-expanded.

Активный элемент и aria-activedescendant

Одним из наиболее важных механизмов является управление активным элементом списка. Awesomplete не переносит фокус на элементы списка. Вместо этого используется модель aria-activedescendant.

Это означает, что фокус остается в input, а активный элемент определяется через идентификатор:

<input aria-activedescendant="awesomplete_list_1_item_3">

Такой подход обеспечивает:

  • стабильность фокуса ввода
  • отсутствие потери контекста при навигации
  • корректную работу экранных дикторов

Каждый элемент списка получает уникальный id, который формируется библиотекой автоматически.

Семантика списка подсказок

Контейнер списка оформляется как ARIA-совместимый элемент:

  • role="listbox" — контейнер предложений
  • role="option" — отдельные элементы списка

Пример структуры:

<ul id="awesomplete_list_1" role="listbox">
    <li id="awesomplete_list_1_item_0" role="option">Almaty</li>
    <li id="awesomplete_list_1_item_1" role="option">Astana</li>
</ul>

Awesomplete обновляет эти атрибуты при каждой перерисовке списка. Это позволяет сохранять корректную семантику даже при динамической фильтрации данных.

Поддержка клавиатурной навигации

ARIA-атрибуты тесно связаны с управлением клавиатурой. Навигация реализуется через стандартные клавиши:

  • ArrowDown — переход к следующему элементу
  • ArrowUp — переход к предыдущему
  • Enter — выбор элемента
  • Escape — закрытие списка

При перемещении по элементам обновляется aria-activedescendant, что позволяет вспомогательным технологиям отслеживать текущую позицию без изменения фокуса.

input.addEventListener("keydown", function (e) {
    if (e.key === "ArrowDown") {
        // перемещение по списку
    }
});

Динамическое обновление ARIA-структуры

Awesomplete работает с динамическими данными, поэтому ARIA-атрибуты пересоздаются при каждом изменении набора подсказок. Это включает:

  • генерацию новых id для элементов
  • обновление aria-owns при пересоздании списка
  • сброс aria-activedescendant при закрытии

Особое внимание уделяется состоянию пустого списка. В этом случае:

  • aria-expanded устанавливается в false
  • aria-activedescendant очищается
  • список скрывается из дерева доступности

Обработка пользовательского ввода и доступность

Каждое изменение значения input приводит к пересчету предложений и синхронному обновлению ARIA-состояния. Это обеспечивает соответствие между визуальным интерфейсом и доступной моделью документа.

Ключевой момент заключается в том, что Awesomplete не разделяет визуальное и доступное состояние — они всегда изменяются одновременно.

input.addEventListener("input", function () {
    // пересчет списка
    // обновление ARIA состояния выполняется автоматически
});

Интеграция с кастомными шаблонами

При использовании пользовательских шаблонов элементов важно сохранять ARIA-структуру. Любое изменение DOM внутри списка должно учитывать:

  • сохранение role="option"
  • уникальность id
  • корректное обновление активного элемента

Нарушение этих правил приводит к рассинхронизации между визуальным интерфейсом и доступной моделью.

Поведение при отключенных подсказках

Awesomplete допускает сценарии, в которых список может быть полностью отключен. В этом случае:

  • aria-expanded всегда false
  • aria-owns может быть удален
  • атрибут aria-autocomplete сохраняется, но не активируется

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

Совместимость с вспомогательными технологиями

Реализация ARIA в Awesomplete ориентирована на:

  • экранные дикторы (NVDA, JAWS, VoiceOver)
  • навигацию с клавиатуры
  • режимы увеличения и альтернативного ввода

Корректное использование ARIA-атрибутов позволяет сохранять предсказуемое поведение интерфейса независимо от платформы и способа взаимодействия с пользователем.