ARIA grid role

Библиотека ally.js предоставляет инструменты для управления доступностью элементов на странице и проверки взаимодействия с ними через клавиатуру и вспомогательные технологии. Работа с элементами, имеющими роль grid, требует особого внимания к навигации по ячейкам, управлению фокусом и синхронизации состояния.

Роль grid обозначает комплексную структуру таблицы, где каждая ячейка (gridcell) может быть доступна для фокусировки и интерактивна. ally.js обеспечивает методы для безопасного и предсказуемого управления фокусом в таких элементах.


Выбор и идентификация grid

Для работы с grid необходимо сначала получить ссылку на корневой элемент с ролью grid. Ally.js предоставляет CSS-селектор и утилиту поиска фокуса:

import * as ally from 'ally.js';

const gridElement = document.querySelector('[role="grid"]');
const gridCells = ally.query.focusable({ context: gridElement });
  • ally.query.focusable возвращает массив элементов, которые могут получать фокус внутри указанного контекста.
  • Фокусируемые элементы внутри grid обычно имеют роль gridcell и поддерживают управление через клавиатуру.

Навигация внутри grid

ARIA определяет стандартные клавиши для перемещения по сетке:

  • Стрелки вверх/вниз/влево/вправо — перемещение между соседними gridcell.
  • Home/End — переход к первой/последней ячейке строки.
  • Ctrl + Home/End — переход к первой/последней ячейке всей сетки.

Ally.js позволяет симулировать эти события и проверять правильность обработки:

ally.focus.next({
  context: gridElement,
  cycle: true
});

ally.focus.previous({
  context: gridElement,
  cycle: true
});
  • cycle: true обеспечивает циклическую навигацию, возвращая фокус к началу при достижении конца.
  • Эти методы полезны для создания кастомной логики перемещения по grid без ручного управления DOM.

Проверка доступности grid

Ally.js включает методы для аудита доступности, включая проверку правильного применения ARIA-ролей:

const report = ally.audit({
  context: gridElement,
  includeOnly: ['tabindex', 'aria-required-attr', 'focusable']
});

console.log(report);
  • Проверяется наличие атрибутов aria-rowcount, aria-colcount, aria-selected и корректность фокусируемости каждой ячейки.
  • Любое несоответствие стандарту ARIA фиксируется в отчете, что позволяет улучшить совместимость с экранными читалками.

Управление состоянием ячеек

Ячейки внутри grid часто интерактивны (например, выбор строки или редактирование значения). Для этого применяются атрибуты:

  • aria-selected="true|false" — выделение текущей строки или ячейки.
  • aria-readonly="true|false" — блокировка редактирования ячейки.
  • tabindex="0" для активной ячейки и tabindex="-1" для остальных, чтобы управлять фокусом программно.

Пример управления выделением через ally.js:

function selectCell(cell) {
  const previouslySelected = gridElement.querySelector('[aria-selected="true"]');
  if (previouslySelected) {
    previouslySelected.setAttribute('aria-selected', 'false');
    previouslySelected.setAttribute('tabindex', '-1');
  }

  cell.setAttribute('aria-selected', 'true');
  cell.setAttribute('tabindex', '0');
  ally.focus.focus(cell);
}
  • ally.focus.focus безопасно перемещает фокус на выбранную ячейку с учетом доступности.
  • Такой подход обеспечивает полностью управляемую навигацию для пользователей клавиатуры.

Работа с вложенными элементами

Grid может содержать комплексные компоненты внутри ячеек, например кнопки или чекбоксы. В таких случаях важно различать:

  • Фокус на уровне gridcell — перемещение стрелками.
  • Фокус на вложенных интерактивных элементах — активация через Enter или Space.

Ally.js позволяет определять внутренние фокусируемые элементы:

const innerFocusables = ally.query.focusable({ context: someGridCell });

Это облегчает создание кастомной логики, где стрелочные клавиши управляют ячейкой, а Tab и Shift+Tab — вложенными элементами.


Автоматическое управление фокусом при динамическом обновлении

Grid часто изменяется динамически (добавление строк, изменение данных). Ally.js предоставляет возможность реактивного обновления фокусируемых элементов:

const updatedCells = ally.query.focusable({ context: gridElement });
ally.focus.focus(updatedCells[0]);
  • После обновления DOM рекомендуется заново получать массив фокусируемых ячеек.
  • Это предотвращает потерю фокуса и обеспечивает доступность для пользователей вспомогательных технологий.

Практические рекомендации

  • Все интерактивные элементы в grid должны иметь явно заданные tabindex.
  • Для больших таблиц полезно делать виртуализированную навигацию, используя ally.js для фокусировки элементов, находящихся в области видимости.
  • Использование aria-selected и aria-readonly повышает совместимость с экранными читалками.
  • Любая кастомная клавиатурная логика должна быть согласована с ARIA Authoring Practices Guide для grid.

Эти принципы позволяют создавать полностью доступные, предсказуемые и управляемые ARIA grid-компоненты с использованием ally.js, обеспечивая правильную работу с клавиатурой и вспомогательными технологиями.