Навигация с клавиатуры

MDX (Markdown + JSX) позволяет объединять разметку Markdown с компонентами React, что создаёт мощный инструмент для документирования и построения интерфейсов. Навигация с клавиатуры — ключевой аспект доступности и удобства использования приложений на основе MDX, особенно если контент содержит интерактивные компоненты.


Фокус и управление им

Для управления фокусом в MDX-компонентах используется стандартный подход React:

import { useRef, useEffect } from 'react';

function FocusableButton() {
  const buttonRef = useRef(null);

  useEffect(() => {
    buttonRef.current.focus();
  }, []);

  return ;
}

Ключевые моменты:

  • useRef создаёт ссылку на DOM-элемент.
  • useEffect позволяет автоматически устанавливать фокус после рендеринга.
  • Такой подход критически важен для интерактивных виджетов в MDX-документации, где навигация с клавиатуры должна быть предсказуемой.

Управление клавишами

Для обработки нажатий клавиш используется событие onKeyDown или onKeyUp. Это позволяет реализовать кастомное поведение при использовании стрелок, Enter, Tab и других клавиш.

function KeyNavigator() {
  const handleKeyDown = (e) => {
    switch (e.key) {
      case 'ArrowDown':
        console.log('Перемещаемся вниз');
        break;
      case 'ArrowUp':
        console.log('Перемещаемся вверх');
        break;
      case 'Enter':
        console.log('Активируем элемент');
        break;
    }
  };

  return 
Навигация с клавиатуры
; }

Особенности:

  • tabIndex={0} делает div фокусируемым.
  • Перехват клавиш позволяет создавать пользовательские меню и списки с поддержкой клавиатуры.
  • Важно всегда учитывать стандартное поведение клавиш, чтобы не нарушать ожидаемую доступность.

Работа с tabIndex

Навигация по MDX-контенту зависит от правильного использования атрибута tabIndex:

  • tabIndex="0" — элемент включается в естественный порядок табуляции.
  • tabIndex="-1" — элемент можно сфокусировать программно, но не через Tab.
  • tabIndex="1,2,...n" — явная последовательность фокуса (редко рекомендуется).

Пример:

Пункт 1
Пункт 2
Пункт 3

Такой подход обеспечивает предсказуемый порядок навигации по интерактивным элементам.


Контролируемые списки и меню

MDX часто используется для документации компонентов UI. Навигация в списках требует управления фокусом и состояния выделенного элемента:

import { useState } from 'react';

function Menu() {
  const [activeIndex, setActiveIndex] = useState(0);
  const items = ['Пункт A', 'Пункт B', 'Пункт C'];

  const handleKeyDown = (e) => {
    if (e.key === 'ArrowDown') {
      setActiveIndex((prev) => (prev + 1) % items.length);
    } else if (e.key === 'ArrowUp') {
      setActiveIndex((prev) => (prev - 1 + items.length) % items.length);
    }
  };

  return (
    
    {items.map((item, index) => (
  • {item}
  • ))}
); }

Особенности:

  • Использование useState для хранения активного индекса.
  • Навигация с клавиатуры циклична.
  • Визуальная подсветка активного элемента улучшает восприятие.

Интеграция с интерактивными компонентами MDX

MDX позволяет вставлять любые React-компоненты. При создании интерактивных элементов необходимо соблюдать следующие принципы:

  1. Фокусируемость: каждый интерактивный элемент должен быть доступен через Tab.
  2. Явные обработчики клавиш: использовать onKeyDown для реализации логики навигации.
  3. Контроль состояния: подсветка, выделение и открытие/закрытие элементов должны зависеть от состояния React.
  4. ARIA-атрибуты: для улучшения доступности использовать role, aria-selected, aria-expanded и другие.

Пример для вкладок:

function Tabs({ tabs }) {
  const [active, setActive] = useState(0);

  const handleKeyDown = (e) => {
    if (e.key === 'ArrowRight') setActive((prev) => (prev + 1) % tabs.length);
    if (e.key === 'ArrowLeft') setActive((prev) => (prev - 1 + tabs.length) % tabs.length);
  };

  return (
    
{tabs.map((tab, index) => ( ))}
{tabs[active].content}
); }

Принципы:

  • Использование role и aria-* делает вкладки доступными для скринридеров.
  • tabIndex обеспечивает правильный порядок навигации.
  • Обработка стрелок создает привычное поведение для пользователей клавиатуры.

Поддержка сложных структур MDX

MDX-документы часто содержат смешанный контент: текст, списки, таблицы, формы. Важно учитывать:

  • Фокусируемые элементы: кнопки, ссылки, интерактивные виджеты.
  • Последовательность Tab: логическая, отражающая визуальный порядок.
  • Обработка клавиш внутри форм и таблиц: стрелки для перемещения между ячейками, Enter для активации элементов.
Заголовок 1 Заголовок 2
Ячейка A1 Ячейка A2
Ячейка B1 Ячейка B2
  • Таблица становится полностью доступной для клавиатурной навигации.
  • Можно добавить обработку стрелок для перемещения между ячейками, если требуется более сложное поведение.