Stimulus — это минималистичный JavaScript-фреймворк, который ориентирован на привязку поведения к HTML через контроллеры, позволяя создавать динамичные интерфейсы без сложной архитектуры. Одной из ключевых задач при разработке интерактивных компонентов является обеспечение доступности, где важную роль играют ARIA атрибуты. Эти атрибуты позволяют вспомогательным технологиям (например, экранным читалкам) корректно интерпретировать поведение элементов интерфейса.
Использование ARIA в Stimulus строится на принципе манипуляции DOM через контроллеры. В контроллере можно программно устанавливать, обновлять или удалять атрибуты, чтобы интерфейс оставался доступным при любом взаимодействии пользователя.
Основной подход заключается в том, что состояние контроллера напрямую отражается в 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 обеспечивает прямой доступ к
связанным элементам.Роли (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 для синхронизации состояния интерфейса и
вспомогательных технологий.
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-pressed для переключателей и кнопокaria-checked для чекбоксов и радиокнопокaria-disabled для элементов, временно недоступных для
взаимодействияStimulus контроллеры позволяют связать эти атрибуты с логикой состояния:
toggleSwitch() {
const pressed = this.element.getAttribute("aria-pressed") === "true";
this.element.setAttribute("aria-pressed", String(!pressed));
}
Использование таких подходов делает интерфейс не только интерактивным, но и доступным для всех категорий пользователей.
Часто визуальное состояние компонента сопровождается изменением классов 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
атрибутами, что упрощает поддержку интерфейса и делает код
более предсказуемым.
Применение этих принципов позволяет создавать доступные, динамичные и поддерживаемые интерфейсы, полностью используя возможности фреймворка Stimulus.