Определение дочерних ролей

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

Структура данных ролей

В основе Aria-query лежит карта ролей (roles), представляющая собой объект, где ключами являются имена ARIA-ролей, а значениями — их метаданные:

import { roles } from 'aria-query';

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

Метаданные роли включают следующие свойства:

  • abstract — логическое значение, указывающее на абстрактную роль.
  • superClass — массив суперклассов роли.
  • requiredProps — свойства, обязательные для данной роли.
  • props — дополнительные свойства роли.
  • childRoles — массив ролей, которые могут быть дочерними.

Пример структуры роли:

{
  abstract: false,
  baseConcepts: [],
  requiredProps: {},
  props: { 'aria-disabled': null },
  superClass: [['roletype', 'widget']],
  nameFrom: ['author'],
  relatedConcepts: [],
  childRoles: ['menuitem', 'checkbox', 'radio']
}

Получение дочерних ролей

Для определения дочерних ролей конкретной ARIA-роли используется свойство childRoles. Оно позволяет узнать, какие роли могут логически находиться внутри текущей роли в DOM.

Пример для роли menu:

const menuRole = roles.get('menu');
console.log(menuRole.childRoles); 
// Выведет: ['menuitem', 'menuitemcheckbox', 'menuitemradio']

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

Рекурсивное определение всех потомков

Для некоторых задач важно не только получить прямых дочерних ролей, но и всех потомков на любом уровне. Aria-query предоставляет только прямые дочерние роли, поэтому для получения полной иерархии используется рекурсия:

function getAllChildRoles(roleName, rolesMap) {
  const role = rolesMap.get(roleName);
  if (!role || !role.childRoles) return [];
  let allChildren = [...role.childRoles];
  role.childRoles.forEach(child => {
    allChildren = allChildren.concat(getAllChildRoles(child, rolesMap));
  });
  return Array.from(new Set(allChildren)); // убираем дубликаты
}

const allMenuChildren = getAllChildRoles('menu', roles);
console.log(allMenuChildren);
// Выведет: ['menuitem', 'menuitemcheckbox', 'menuitemradio']

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

Валидация структуры DOM

Использование childRoles позволяет не только изучать спецификацию ARIA, но и валидировать фактическую структуру DOM:

  1. Сравнивать роли в DOM с разрешёнными дочерними ролями.
  2. Генерировать предупреждения при нарушении иерархии.
  3. Автоматически рекомендовать корректные вложенные роли.

Пример проверки дочерних элементов:

import { roles } from 'aria-query';

function validateChildren(parentRoleName, childrenRoleNames) {
  const parentRole = roles.get(parentRoleName);
  if (!parentRole) return [];
  return childrenRoleNames.filter(childRole => !parentRole.childRoles.includes(childRole));
}

const invalidChildren = validateChildren('menu', ['menuitem', 'button']);
console.log(invalidChildren); // Выведет: ['button']

Особенности и ограничения

  • Абстрактные роли (abstract: true) не должны использоваться в DOM напрямую. Их дочерние роли служат для определения допустимых вложенных элементов.
  • Смешанные суперклассы могут наследовать свойства, но дочерние роли проверяются только в рамках текущей роли.
  • Рекурсивное определение может привести к большому объёму данных при глубокой вложенности, поэтому рекомендуется кеширование результатов.

Применение в разработке компонентов

  • Создание меню, списков, деревьев с корректными дочерними элементами.
  • Автоматическое определение ARIA-деревьев для генераторов интерфейсов.
  • Интеграция с тестовыми фреймворками для контроля доступности.

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