ARIA (Accessible Rich Internet Applications) предоставляет набор атрибутов, позволяющих улучшить доступность веб-приложений для пользователей с ограниченными возможностями. В контексте библиотеки Atomico правильное использование ARIA атрибутов обеспечивает, что кастомные веб-компоненты будут корректно восприниматься вспомогательными технологиями, такими как экранные читалки.
В Atomico каждый компонент создаётся через функцию
component(), которая возвращает кастомный элемент с
реактивным состоянием и жизненным циклом. Атрибуты ARIA добавляются к
элементам внутри JSX, аналогично стандартным HTML-атрибутам:
import { c, useState } from "atomico";
function Button() {
const [pressed, setPressed] = useState(false);
return (
<button
aria-pressed={pressed}
role="button"
onCl ick={() => setPressed(!pressed)}
>
Toggle
</button>
);
}
export const button = c(Button);
В этом примере ключевое значение aria-pressed
динамически обновляется в зависимости от состояния pressed.
Атрибут role указывает вспомогательным технологиям, что
элемент является интерактивной кнопкой.
1. role Определяет семантическую роль элемента:
button, checkbox, dialog,
tab и другие. В Atomico его часто используют для кастомных
элементов, которые не имеют стандартной HTML-семантики:
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dialog-title">Диалог</h2>
</div>
2. aria-label и aria-labelledby
aria-label задаёт текстовую метку для элемента.aria-labelledby ссылается на другой элемент, который
служит меткой.Пример с полем ввода:
<input type="text" aria-label="Имя пользователя" />
Или с использованием aria-labelledby:
<label id="username-label">Имя пользователя</label>
<input type="text" aria-labelledby="username-label" />
3. aria-hidden Скрывает элемент от вспомогательных технологий:
<div aria-hidden="true">
Этот контент будет проигнорирован экранными читалками
</div>
4. aria-checked, aria-selected, aria-expanded Эти атрибуты отражают состояние элементов управления: чекбоксов, вкладок, раскрывающихся списков.
<div
role="tab"
aria-selected={activeTab === "profile"}
onCl ick={() => setActiveTab("profile")}
>
Профиль
</div>
5. aria-live Используется для динамически обновляемого контента. Атрибут сообщает экранным читалкам, что содержимое должно быть объявлено пользователю при изменении.
<div aria-live="polite">
{notifications.map(note => <p>{note}</p>)}
</div>
Одним из преимуществ Atomico является реактивность состояния. ARIA
атрибуты можно привязывать к состоянию через useState или
useRef, обеспечивая корректное взаимодействие с
пользователем:
import { c, useState } from "atomico";
function Accordion({ title, children }) {
const [expanded, setExpanded] = useState(false);
return (
<div>
<button
aria-expanded={expanded}
aria-controls="panel"
onCl ick={() => setExpanded(!expanded)}
>
{title}
</button>
<div id="panel" hidden={!expanded}>
{children}
</div>
</div>
);
}
export const accordion = c(Accordion);
В этом примере атрибуты aria-expanded и
aria-controls обеспечивают понятное состояние для экранных
читалок, а динамическое управление состоянием гарантирует синхронизацию
визуального и программного интерфейса.
Для сложных компонентов, таких как вкладки или аккордеоны, важно не только правильно выставлять атрибуты, но и использовать события для оповещения о изменении состояния:
<button
role="tab"
aria-selected={active}
onCl ick={() => {
setActive(!active);
dispatchEvent(new CustomEvent("tab-change", { detail: { active } }));
}}
>
Вкладка
</button>
Использование CustomEvent позволяет интегрировать
компонент в более крупную систему, сохраняя доступность.
role
необязательно.aria-hidden для декоративных
элементов: это улучшает работу экранных читалок.ARIA в Atomico становится особенно мощным инструментом благодаря реактивности и возможности привязывать атрибуты к состоянию компонентов, создавая полностью интерактивные и доступные веб-компоненты.