Создание утилит поверх aria-query

Библиотека aria-query в JavaScript предназначена для работы с спецификациями WAI-ARIA, предоставляя готовые структуры данных для доступа к спискам ролей, свойств и состояний ARIA. Основными сущностями являются:

  • Roles — объект с описанием всех ARIA-ролей, их атрибутов и поддерживаемых дочерних элементов.
  • States and Properties — объект, содержащий все состояния (aria-checked, aria-expanded) и свойства (aria-label, aria-labelledby) с допустимыми значениями.
  • Element Roles Map — отображение HTML-элементов в поддерживаемые ARIA-ролей.

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

Работа с ролями

Объект Roles предоставляет методы для извлечения данных о ролях. Основные возможности:

import { roles } from 'aria-query';

// Получение информации о конкретной роли
const buttonRole = roles.get('button');
console.log(buttonRole);

Ключевые свойства роли:

  • abstract — логическая роль, не применяемая напрямую к элементу DOM.
  • requiredProps — список обязательных свойств ARIA для этой роли.
  • superClass — роли, от которых наследуется поведение.
  • supportedProps — свойства ARIA, которые может принимать роль.

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

Работа с состояниями и свойствами

Объект ariaAttributes содержит все ARIA-свойства и состояния:

import { aria } from 'aria-query';

const ariaChecked = aria.get('aria-checked');
console.log(ariaChecked);

Для каждого свойства доступны:

  • type — тип значения (boolean, tristate, string, idref).
  • values — допустимые варианты для перечислений (true, false, mixed).
  • requiredForRoles — роли, для которых это свойство обязательно.

Эта структура критична при создании валидаторов атрибутов ARIA.

Построение утилит

Валидаторы ролей

Можно создавать функции, проверяющие корректность роли на элементе:

function validateRole(element) {
  const role = element.getAttribute('role');
  if (!roles.has(role)) {
    return false;
  }
  const requiredProps = roles.get(role).requiredProps;
  return requiredProps.every(prop => element.hasAttribute(prop));
}

Эта функция проверяет существование роли и наличие обязательных атрибутов.

Проверка поддержки ARIA-свойств

Утилиты могут проверять, соответствует ли свойство элементу:

function validateAriaProp(element, propName) {
  if (!aria.has(propName)) return false;
  const role = element.getAttribute('role');
  const roleData = roles.get(role);
  return roleData?.supportedProps.has(propName);
}

Такой подход позволяет динамически оценивать корректность использования ARIA в коде.

Генерация документации и карт

aria-query можно использовать для автоматической генерации справочников по ARIA:

const roleDocs = Array.from(roles.keys()).map(role => {
  const data = roles.get(role);
  return {
    role,
    requiredProps: Array.from(data.requiredProps),
    supportedProps: Array.from(data.supportedProps)
  };
});

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

Кросс-валидация с DOM

С помощью aria-query удобно строить функции, которые анализируют HTML-страницу на соответствие ARIA-спецификациям:

function auditDomForAria(documentRoot) {
  const elements = documentRoot.querySelectorAll('[role]');
  return Array.from(elements).map(el => ({
    element: el,
    validRole: validateRole(el),
    validProps: Array.from(aria.keys()).filter(prop => validateAriaProp(el, prop))
  }));
}

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

Интеграция с тестовыми фреймворками

Утилиты на базе aria-query легко интегрировать в Jest, Mocha или Cypress. Пример для Jest:

test('Все кнопки имеют корректные роли и aria-атрибуты', () => {
  document.body.innerHTML = `<button role="button" aria-pressed="false"></button>`;
  const button = document.querySelector('button');
  expect(validateRole(button)).toBe(true);
  expect(validateAriaProp(button, 'aria-pressed')).toBe(true);
});

Такой подход гарантирует проверку доступности на уровне компонентов и DOM-элементов.

Оптимизация и кэширование

Для больших приложений рекомендуется кэшировать результаты запросов к Roles и ariaAttributes, так как объекты библиотек являются неизменяемыми, но могут занимать значительный объём при многократных итерациях.

const roleCache = new Map();

function getRoleData(role) {
  if (!roleCache.has(role)) {
    roleCache.set(role, roles.get(role));
  }
  return roleCache.get(role);
}

Кэширование повышает производительность утилит в циклических проверках DOM и генерации документации.

Расширение функциональности

На основе aria-query можно строить более сложные утилиты:

  • Автоматическое исправление недостающих атрибутов ARIA.
  • Генерация динамических подсказок для разработчиков о корректной роли и свойствах.
  • Построение визуальных карт интерфейса с указанием всех ролей и их вложенности.

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