Библиотека 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']
Этот подход позволяет построить полную карту вложенности, что особенно актуально при разработке библиотек компонентов или систем автоматического тестирования доступности.
Использование childRoles позволяет не только изучать
спецификацию ARIA, но и валидировать фактическую структуру
DOM:
Пример проверки дочерних элементов:
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 напрямую. Их дочерние роли служат для
определения допустимых вложенных элементов.Использование свойства childRoles в связке с
roles позволяет создавать компоненты, которые
полностью соответствуют стандартам WAI-ARIA,
обеспечивая доступность и логическую структуру для вспомогательных
технологий.