Keyboard navigation

Навигация с помощью клавиатуры — это ключевой аспект доступности веб-приложений. В фреймворке Stencil для реализации такой функциональности используется стандартный подход с обработкой событий клавиш и созданием интерфейсов, которые могут быть полностью использованы без мыши. В этой статье рассмотрены основные подходы к созданию навигации с клавиатуры в компонентах Stencil.

Основные принципы клавиатурной навигации

Stencil предоставляет все необходимые инструменты для создания компонент, поддерживающих навигацию с клавиатуры. Главное правило — интерфейсы должны быть интуитивно понятными и удобными для пользователей с ограниченными возможностями. Включение клавиш для навигации, таких как Tab, стрелки и Enter, помогает пользователю взаимодействовать с элементами, не полагаясь на мышь.

Для правильной работы клавиатурной навигации нужно учитывать несколько важных аспектов:

  • Фокусировка. Элементы, доступные для взаимодействия, должны быть доступны для фокуса с помощью клавиши Tab.
  • Обработка событий клавиш. Нужно обрабатывать нажатие клавиш, таких как стрелки, Enter, Esc и другие, в зависимости от контекста.
  • Актуальность фокуса. После выполнения действия с элементом фокус должен оставаться в логическом порядке.

Поддержка клавиш Tab и Shift+Tab

Клавиша Tab используется для перемещения фокуса по элементам страницы, а Shift+Tab — для перемещения в обратном порядке. В компонентах Stencil необходимо гарантировать, что все интерактивные элементы (кнопки, ссылки, формы) могут быть фокусированы, а их порядок соответствовал логике пользовательского интерфейса.

Чтобы элемент становился доступным для фокуса, необходимо добавить атрибут tabindex. Стандартные элементы, такие как ссылки и кнопки, уже поддерживают эту функциональность, но для кастомных компонентов необходимо вручную задать значение атрибута tabindex.

// Пример компонента Stencil с элементами, доступными для клавиатуры
@Component({
  tag: 'keyboard-nav-example',
  styleUrl: 'keyboard-nav-example.css',
  shadow: true,
})
export class KeyboardNavExample {
  render() {
    return (
      <div>
        <button tabindex="0">Кнопка 1</button>
        <button tabindex="0">Кнопка 2</button>
        <button tabindex="0">Кнопка 3</button>
      </div>
    );
  }
}

Каждый элемент в данном примере доступен для фокуса с помощью клавиши Tab.

Обработка стрелок для навигации

Для реализации более сложной навигации, например, перемещения по спискам или каруселям, может понадобиться поддержка клавиш стрелок. В таком случае для каждого элемента нужно добавить обработчики событий клавиш, чтобы перемещать фокус по элементам при нажатии стрелок.

@Component({
  tag: 'arrow-key-navigation',
  styleUrl: 'arrow-key-navigation.css',
  shadow: true,
})
export class ArrowKeyNavigation {
  @State() activeIndex: number = 0;

  handleKeydown(event: KeyboardEvent) {
    if (event.key === 'ArrowDown') {
      this.activeIndex = Math.min(this.activeIndex + 1, 2); // Ограниечение от 0 до 2
    } else if (event.key === 'ArrowUp') {
      this.activeIndex = Math.max(this.activeIndex - 1, 0); // Ограниечение от 0 до 2
    }
  }

  render() {
    return (
      <div onKeyD own={(e) => this.handleKeydown(e)}>
        <div class={{ 'active': this.activeIndex === 0 }}>Элемент 1</div>
        <div class={{ 'active': this.activeIndex === 1 }}>Элемент 2</div>
        <div class={{ 'active': this.activeIndex === 2 }}>Элемент 3</div>
      </div>
    );
  }
}

В этом примере для навигации по элементам используются стрелки вверх и вниз. Обработчик событий обновляет активный элемент в зависимости от нажатой клавиши.

Поддержка клавиши Enter и Esc

Для некоторых компонентов, таких как диалоги, выпадающие меню или аккордеоны, клавиша Enter обычно используется для выполнения действия, а клавиша Esc — для закрытия или отмены действия. В компонентах Stencil такие клавиши можно обрабатывать через события keydown или keyup.

@Component({
  tag: 'dialog-component',
  styleUrl: 'dialog-component.css',
  shadow: true,
})
export class DialogComponent {
  @State() isOpen: boolean = false;

  toggleDialog() {
    this.isOpen = !this.isOpen;
  }

  handleKeydown(event: KeyboardEvent) {
    if (event.key === 'Enter' && this.isOpen) {
      // Действие при нажатии Enter
      console.log('Действие выполнено');
    } else if (event.key === 'Escape' && this.isOpen) {
      // Закрытие окна при нажатии Escape
      this.toggleDialog();
    }
  }

  render() {
    return (
      <div onKeyD own={(e) => this.handleKeydown(e)} tabindex="0">
        {this.isOpen ? (
          <div class="dialog">
            <h2>Диалоговое окно</h2>
            <button onCl ick={() => this.toggleDialog()}>Закрыть</button>
          </div>
        ) : (
          <button onCl ick={() => this.toggleDialog()}>Открыть диалог</button>
        )}
      </div>
    );
  }
}

В данном примере при открытом диалоговом окне клавиша Enter выполняет действие, а клавиша Esc — закрывает его.

Обработка клавиш с помощью keyCode

Вместо использования строковых значений клавиш, можно работать с числовыми кодами клавиш с помощью keyCode. Однако данный подход устарел, и рекомендуется использовать строковые значения для лучшей совместимости с современными браузерами.

handleKeydown(event: KeyboardEvent) {
  if (event.keyCode === 13) { // 13 — это код для клавиши Enter
    console.log('Клавиша Enter нажата');
  }
}

Использование ARIA-атрибутов

Для улучшения доступности компонентов важно использовать атрибуты ARIA, такие как aria-label, aria-expanded, aria-controls и другие, которые помогают пользователям с ограничениями в восприятии информации или с нарушениями движения понять, что именно они выбирают или активируют.

@Component({
  tag: 'accessible-button',
  styleUrl: 'accessible-button.css',
  shadow: true,
})
export class AccessibleButton {
  render() {
    return (
      <button aria-label="Открыть меню">Меню</button>
    );
  }
}

Заключение

Навигация с клавиатуры — это важная часть доступности в любом веб-приложении. В Stencil есть все возможности для того, чтобы реализовать клавиатурную навигацию, от базового управления фокусом до сложных взаимодействий с клавишами стрелок, Enter и Esc. Важно помнить о необходимости тестировать функциональность с клавиатуры и следить за правильным использованием ARIA-атрибутов для повышения доступности вашего приложения.