Обертки для частых задач

Библиотека Aria-query в JavaScript предназначена для работы с ARIA-атрибутами и семантическими ролями элементов в веб-приложениях. Она предоставляет структурированные карты соответствий ролей, состояний и свойств, а также позволяет проверять корректность использования ARIA в DOM. Основные объекты библиотеки — это roles, states, properties и функции для проверки их совместимости.


Роли элементов

Объект roles содержит полную информацию о поддерживаемых ARIA-ролях. Каждая роль описывается следующими параметрами:

  • name — человекочитаемое имя роли.
  • abstract — булевое значение, показывающее, является ли роль абстрактной (не применяется напрямую к элементу).
  • superClass — массив родительских ролей, определяющих наследование свойств.
  • requiredProps — свойства, которые должны присутствовать на элементе с этой ролью.
  • requiredContextRoles — контекстные роли, в которых допустимо использовать данную роль.

Пример обращения к роли button:

import { roles } from 'aria-query';

const buttonRole = roles.get('button');

console.log(buttonRole.requiredProps); // Массив обязательных свойств
console.log(buttonRole.superClass);    // Родительские роли

Использование ролей позволяет проводить автоматическую проверку корректности структуры DOM, выявлять нарушения семантики и обеспечивать соответствие стандартам доступности.


Состояния и свойства

Объект states содержит динамические состояния элементов, такие как aria-checked, aria-expanded, aria-hidden. Эти состояния могут быть триггерными (меняются пользователем) или описательными (информируют о состоянии элемента).

Объект properties хранит статические ARIA-свойства, например aria-label, aria-labelledby, которые обеспечивают описание элементов для ассистивных технологий.

Пример проверки поддержки состояния:

import { states, properties } from 'aria-query';

console.log(states.has('aria-checked'));  // true
console.log(properties.has('aria-label')); // true

Совместимость ролей и состояний

Aria-query предоставляет возможность определить, какие состояния и свойства применимы к конкретной роли:

import { roles } from 'aria-query';

const checkboxRole = roles.get('checkbox');

console.log(checkboxRole.props); // Список разрешённых ARIA-свойств для роли

Важно учитывать, что не все свойства и состояния могут применяться ко всем ролям. Например, aria-checked подходит для checkbox, radio и switch, но не для button.


Применение в тестах доступности

Aria-query активно используется в тестах для проверки доступности интерфейса. Например, в связке с eslint-plugin-jsx-a11y можно автоматизировать контроль корректного использования ARIA в React-компонентах:

import { roles, states } from 'aria-query';

function validateRole(element) {
  const role = element.getAttribute('role');
  if (!roles.has(role)) {
    return `Неизвестная роль: ${role}`;
  }
  const roleInfo = roles.get(role);
  roleInfo.requiredProps.forEach(prop => {
    if (!element.hasAttribute(prop)) {
      console.warn(`Отсутствует обязательное свойство: ${prop}`);
    }
  });
}

Такой подход позволяет выявлять ошибки на раннем этапе разработки и минимизировать проблемы доступности для пользователей с особыми потребностями.


Обертки для частых задач

Создание оберток позволяет упростить работу с Aria-query и снизить вероятность ошибок:

  1. Проверка роли и обязательных свойств:
function checkRole(element) {
  const roleName = element.getAttribute('role');
  if (!roles.has(roleName)) return false;
  const role = roles.get(roleName);
  return role.requiredProps.every(prop => element.hasAttribute(prop));
}
  1. Получение разрешённых свойств для роли:
function getAllowedProps(roleName) {
  if (!roles.has(roleName)) return [];
  return Array.from(roles.get(roleName).props.keys());
}
  1. Проверка состояния элемента:
function checkState(element, stateName) {
  return states.has(stateName) && element.hasAttribute(stateName);
}
  1. Автоматическое создание aria-атрибутов:
function applyAriaProps(element, roleName, props) {
  if (!roles.has(roleName)) return;
  const allowedProps = getAllowedProps(roleName);
  Object.keys(props).forEach(key => {
    if (allowedProps.includes(key)) {
      element.setAttribute(key, props[key]);
    }
  });
  element.setAttribute('role', roleName);
}

Использование таких оберток стандартизирует код, делает его более читаемым и снижает вероятность ошибок, связанных с некорректным использованием ARIA.


Интеграция с TypeScript

Для проектов на TypeScript рекомендуется использовать строгие типы для ARIA-ролей и свойств:

import { roles, states } from 'aria-query';

type AriaRole = keyof typeof roles;
type AriaState = keyof typeof states;

function setAriaState(element: HTMLElement, state: AriaState, value: string | boolean) {
  element.setAttribute(state, String(value));
}

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


Работа с DOM-деревом

Aria-query можно применять для обхода DOM и анализа соответствия ARIA:

function auditDom(root) {
  const elements = root.querySelectorAll('[role]');
  elements.forEach(el => {
    checkRole(el);
    // Дополнительно проверять состояния
    Array.from(states.keys()).forEach(state => checkState(el, state));
  });
}

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


Применение в библиотеках UI

UI-библиотеки используют Aria-query для автоматической генерации ARIA-атрибутов в компонентах:

  • React — проверка и автоматическое применение ролей в JSX.
  • Vue — директивы для валидации ARIA-свойств.
  • Vanilla JS — утилиты для динамического добавления состояний и ролей.

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