elementRoles Map

Библиотека Aria-query предназначена для анализа и сопоставления ARIA-ролей с HTML-элементами. Одним из центральных объектов является карта elementRoles, которая представляет собой структуру данных, связывающую стандартные HTML-теги с поддерживаемыми ARIA-ролями. Эта карта позволяет определить, какие роли допустимы для конкретного элемента, а также какие элементы могут выступать как представители той или иной роли.


Структура elementRoles

elementRoles реализуется как Map, где ключом является строка с именем HTML-тега, а значением — объект, описывающий допустимые роли и дополнительные свойства:

import { elementRoles } from 'aria-query';

console.log(elementRoles.get('button'));

В качестве значения используется объект, который обычно содержит следующие поля:

  • roles — объект, где ключи это имена ARIA-ролей, а значения указывают на допустимость и специфику использования роли.
  • attributes — объект, описывающий ARIA-атрибуты, которые могут применяться к элементу.
  • nameRequired — флаг, указывающий на обязательность текстового содержимого или aria-label.

Пример типичного значения для кнопки:

{
  roles: {
    button: {
      requiredOwnedElements: [],
      props: {},
    }
  },
  attributes: {
    'aria-pressed': true,
    'aria-expanded': true
  },
  nameRequired: true
}

Получение всех ролей для элемента

Для извлечения всех возможных ролей, поддерживаемых HTML-элементом, используется метод get Map:

const buttonRoles = elementRoles.get('button');
console.log(Object.keys(buttonRoles.roles)); // ['button']

Особенности:

  • Некоторые элементы поддерживают несколько ролей. Например, с типом checkbox может быть связана с ролью checkbox, а с типом radio — с ролью radio.
  • Если элемент отсутствует в elementRoles, это значит, что для него не определено стандартных ARIA-ролей, и любые роли нужно использовать с осторожностью.

Проверка соответствия роли элементу

Используя elementRoles, можно динамически проверить, допустима ли роль для заданного тега:

function isRoleAllowed(tagName, role) {
  const entry = elementRoles.get(tagName);
  return entry ? role in entry.roles : false;
}

console.log(isRoleAllowed('button', 'button')); // true
console.log(isRoleAllowed('div', 'button')); // false

Это особенно полезно при разработке динамических компонентов, где ARIA-роль может зависеть от состояния интерфейса.


Взаимосвязь с ARIA-атрибутами

elementRoles позволяет узнать не только поддерживаемые роли, но и ARIA-атрибуты, которые могут быть применены к элементу:

const linkAttributes = elementRoles.get('a').attributes;
console.log(linkAttributes); 
// { 'aria-current': true, 'aria-disabled': true, ... }

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

  • Атрибуты могут быть специфичны для роли. Например, aria-pressed имеет смысл только для кнопок типа toggle.
  • Наличие атрибута в attributes не означает обязательность, а лишь допустимость.

Использование валидации

В больших проектах elementRoles часто применяется для валидаторов JSX/HTML. Например, проверка корректного применения ролей и атрибутов:

function validateRole(tagName, role, attributes = {}) {
  const entry = elementRoles.get(tagName);
  if (!entry) return false;
  if (!(role in entry.roles)) return false;
  
  const allowedAttributes = entry.attributes;
  return Object.keys(attributes).every(attr => attr in allowedAttributes);
}

validateRole('button', 'button', { 'aria-pressed': true }); // true
validateRole('button', 'link'); // false

Примеры использования в React

В React и других UI-библиотеках elementRoles можно использовать для динамического присвоения ARIA-ролей на основе типа компонента:

import { elementRoles } from 'aria-query';

function AccessibleComponent({ tag = 'div', role, ...props }) {
  const validRoles = elementRoles.get(tag)?.roles || {};
  const appliedRole = validRoles[role] ? role : undefined;

  return React.createElement(tag, { role: appliedRole, ...props });
}

Таким образом обеспечивается автоматическая валидная ARIA-разметка без ручной проверки каждого элемента.


Выводы о elementRoles

  • elementRoles является ключевым инструментом для разработки доступных интерфейсов в JS.
  • Позволяет определять допустимые роли и атрибуты для HTML-элементов.
  • Может использоваться для динамической валидации и генерации компонентов.
  • В сочетании с другими объектами Aria-query (например, roles, roleElements) предоставляет полное представление о соответствии ARIA-спецификации.