ARIA (Accessible Rich Internet Applications) — это набор атрибутов, позволяющих улучшить доступность веб-компонентов для пользователей с особыми потребностями. В контексте SkateJS использование ARIA-атрибутов особенно важно, так как библиотека ориентирована на создание кастомных элементов, которые не всегда автоматически поддерживаются технологиями вспомогательного доступа.
SkateJS строится на основе Custom Elements API и
поддерживает реактивное обновление свойств через props и
observedAttributes. Это позволяет динамически связывать
ARIA-атрибуты с внутренним состоянием компонента:
import { define, Component, h } from 'skatejs';
class AccessibleButton extends Component {
static get props() {
return {
disabled: { type: Boolean, reflect: true },
pressed: { type: Boolean, reflect: true }
};
}
render() {
return h('button', {
'aria-pressed': this.pressed,
'aria-disabled': this.disabled
}, 'Нажми меня');
}
}
define('accessible-button', AccessibleButton);
Ключевой момент: свойства компонента могут
автоматически отражаться в атрибутах DOM через
reflect: true. Это упрощает синхронизацию с ARIA-атрибутами
и минимизирует необходимость ручного управления DOM.
true, false или mixed.true или false.button, menu, dialog).SkateJS позволяет реактивно обновлять ARIA-атрибуты при изменении состояния. Рассмотрим пример с кастомным переключателем:
class ToggleSwitch extends Component {
static get props() {
return {
active: { type: Boolean, reflect: true }
};
}
render() {
return h('div', {
role: 'switch',
'aria-checked': this.active,
tabindex: 0,
onclick: () => this.active = !this.active,
onkeydown: (event) => {
if (event.key === 'Enter' || event.key === ' ') {
this.active = !this.active;
event.preventDefault();
}
}
}, `Состояние: ${this.active ? 'Включено' : 'Выключено'}`);
}
}
define('toggle-switch', ToggleSwitch);
В этом примере:
active.keydown,
что важно для доступности.SkateJS позволяет вычислять значения ARIA-атрибутов динамически, исходя из состояния компонента или его детей:
class AccordionPanel extends Component {
static get props() {
return {
open: { type: Boolean, reflect: true }
};
}
render() {
return h('section', {
role: 'region',
'aria-hidden': !this.open
}, [
h('h3', {
id: 'panel-title',
onclick: () => this.open = !this.open
}, 'Заголовок панели'),
h('div', {
'aria-labelledby': 'panel-title',
hidden: !this.open
}, 'Содержимое панели')
]);
}
}
define('accordion-panel', AccordionPanel);
Здесь aria-hidden динамически управляется через
свойство open, а aria-labelledby связывает
контент с заголовком, обеспечивая корректное восприятие вспомогательными
технологиями.
reflect: true для свойств, влияющих на состояние
ARIA-атрибутов.keydown, keypress) для
интерактивных элементов.role для кастомных элементов, которые заменяют стандартные
HTML-теги.Использование ARIA-атрибутов в SkateJS обеспечивает:
Такой подход позволяет создавать современные интерактивные интерфейсы, где кастомные элементы не теряют семантической и функциональной ценности для всех пользователей.