Библиотека aria-query предоставляет средства для работы с ARIA-ролями, свойствами и состояниями, а также их соответствием HTML-элементам. Одним из ключевых аспектов её использования является возможность расширять и настраивать существующие определения, чтобы адаптировать их под специфические задачи веб-разработки или создавать собственные карты соответствий.
В aria-query все определения хранятся в виде immutable maps, что обеспечивает их неизменяемость и предсказуемость поведения. Основные объекты:
Каждая роль содержит следующую информацию:
{
name: 'button',
baseConcepts: [{ name: 'button', attributes: [] }],
requiredProps: [],
props: new Map([['aria-pressed', 'tristate']]),
superClass: ['widget', 'command'],
}
Для расширения ролей используется функция mergeRoles.
Она позволяет добавлять новые свойства, изменять базовые
элементы и добавлять новые роли-потомки.
Пример расширения роли button:
import { roles, mergeRoles } from 'aria-query';
import { Map } from 'immutable';
// Создание кастомного свойства
const customProps = new Map([
['data-custom', 'boolean']
]);
// Объединение существующей роли с новыми свойствами
const extendedRoles = mergeRoles(
roles,
new Map([
['button', {
props: customProps,
baseConcepts: [{ name: 'button', attributes: [{ name: 'data-role', value: 'custom' }] }]
}]
])
);
Результат — роль button теперь поддерживает
пользовательское свойство data-custom и новые атрибуты
базовой концепции.
aria-query позволяет модифицировать elements, чтобы связать HTML-теги с новыми или изменёнными ARIA-ролями:
import { elements, mergeElements } from 'aria-query';
import { Map } from 'immutable';
const extendedElements = mergeElements(
elements,
new Map([
['div', [{ name: 'button', attributes: [{ name: 'role', value: 'button' }] }]]
])
);
Теперь любой <div> с атрибутом
role="button" будет корректно распознаваться как кнопка в
соответствии с расширенной картой ролей.
Свойства и состояния ARIA можно расширять через
mergeProperties:
import { properties, mergeProperties } from 'aria-query';
import { Map } from 'immutable';
const customProperties = new Map([
['aria-custom-state', {
type: 'string',
values: ['active', 'inactive', 'pending']
}]
]);
const extendedProperties = mergeProperties(properties, customProperties);
Теперь новая карта свойств поддерживает
aria-custom-state с ограниченным набором значений.
superClass, чтобы не нарушить логическую
структуру ARIA.Расширенные определения можно использовать с библиотеками типа eslint-plugin-jsx-a11y или собственными тестами на доступность. Пример проверки наличия пользовательских свойств в JSX:
import { extendedRoles } from './customAriaQuery';
import { JSXElement } from 'eslint';
function validateAriaProps(node: JSXElement) {
const role = node.attributes.role;
if (role && extendedRoles.has(role)) {
const props = extendedRoles.get(role).props;
node.attributes.forEach(attr => {
if (!props.has(attr.name)) {
console.warn(`Свойство ${attr.name} не разрешено для роли ${role}`);
}
});
}
}
Это позволяет поддерживать строгий контроль доступности даже при использовании кастомных ARIA-расширений.
Расширение определений в aria-query обеспечивает
гибкость при работе с ARIA. С помощью mergeRoles,
mergeElements и mergeProperties можно:
Тщательная настройка этих объектов повышает семантическую корректность интерфейсов и расширяет возможности автоматизированной валидации.