ARIA атрибуты в контроллерах

Stimulus — это минималистичный JavaScript-фреймворк, который ориентирован на привязку поведения к HTML через контроллеры, позволяя создавать динамичные интерфейсы без сложной архитектуры. Одной из ключевых задач при разработке интерактивных компонентов является обеспечение доступности, где важную роль играют ARIA атрибуты. Эти атрибуты позволяют вспомогательным технологиям (например, экранным читалкам) корректно интерпретировать поведение элементов интерфейса.

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


Связывание ARIA с состоянием контроллера

Основной подход заключается в том, что состояние контроллера напрямую отражается в ARIA атрибутах элементов. Например, для кнопки, открывающей модальное окно:

<button data-controller="modal"
        data-action="click->modal#toggle"
        aria-expanded="false"
        aria-controls="modalPanel">
  Открыть модальное окно
</button>

<div id="modalPanel" role="dialog" aria-hidden="true">
  <p>Содержимое модального окна</p>
</div>

Контроллер modal будет управлять состоянием видимости модального окна и обновлять соответствующие ARIA атрибуты:

import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  static targets = ["panel"];

  toggle() {
    const expanded = this.element.getAttribute("aria-expanded") === "true";
    this.element.setAttribute("aria-expanded", String(!expanded));
    this.panelTarget.setAttribute("aria-hidden", String(expanded));
  }
}

Ключевые моменты:

  • aria-expanded отражает текущее состояние кнопки (открыто/закрыто).
  • aria-hidden показывает, видим ли контент для вспомогательных технологий.
  • Привязка через targets обеспечивает прямой доступ к связанным элементам.

Использование ARIA ролей

Роли (role) играют важную роль в обеспечении семантики компонентов интерфейса:

  • role="dialog" для модальных окон
  • role="tablist" и role="tab" для вкладок
  • role="alert" для уведомлений

В Stimulus управление ролями особенно полезно при динамическом создании элементов. Например, добавление вкладки:

addTab(label, content) {
  const tab = document.createElement("button");
  tab.setAttribute("role", "tab");
  tab.setAttribute("aria-selected", "false");
  tab.textContent = label;

  const panel = document.createElement("div");
  panel.setAttribute("role", "tabpanel");
  panel.setAttribute("aria-hidden", "true");
  panel.textContent = content;

  this.element.appendChild(tab);
  this.element.appendChild(panel);
}

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


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

Stimulus позволяет реагировать на события и обновлять ARIA атрибуты без ручного поиска элементов:

static targets = ["menuItem"];

activate(event) {
  this.menuItemTargets.forEach(item => {
    item.setAttribute("aria-current", "false");
  });
  event.currentTarget.setAttribute("aria-current", "true");
}

Этот пример иллюстрирует управление текущей выбранной позицией меню с помощью aria-current, что повышает доступность навигации.


ARIA и состояния компонентов

При разработке интерактивных компонентов часто требуется поддерживать несколько состояний, например:

  • aria-pressed для переключателей и кнопок
  • aria-checked для чекбоксов и радиокнопок
  • aria-disabled для элементов, временно недоступных для взаимодействия

Stimulus контроллеры позволяют связать эти атрибуты с логикой состояния:

toggleSwitch() {
  const pressed = this.element.getAttribute("aria-pressed") === "true";
  this.element.setAttribute("aria-pressed", String(!pressed));
}

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


Связывание ARIA с классами и анимацией

Часто визуальное состояние компонента сопровождается изменением классов CSS. Для согласованности с ARIA атрибутами:

toggle() {
  const open = this.element.classList.toggle("is-open");
  this.element.setAttribute("aria-expanded", String(open));
  this.panelTarget.setAttribute("aria-hidden", String(!open));
}

Здесь класс is-open синхронизирован с ARIA атрибутами, что упрощает поддержку интерфейса и делает код более предсказуемым.


Итоговые принципы использования ARIA в Stimulus

  1. Состояние контроллера = состояние ARIA. Любое изменение логики должно отражаться в атрибутах.
  2. Использовать роли для семантики. Они обеспечивают понятное поведение для вспомогательных технологий.
  3. Динамическое обновление атрибутов через targets и методы контроллера.
  4. Согласованность с визуальными классами и анимацией.

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