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

Управление фокусом в Carbon Components Svelte играет ключевую роль для доступности интерфейсов и удобства навигации с клавиатуры. В библиотеке предусмотрены встроенные механизмы работы с фокусом, которые упрощают создание доступных компонентов.


Автоматическая установка фокуса

Многие компоненты Carbon автоматически устанавливают фокус на важные элементы после их рендеринга. Например, модальные окна (Modal) при открытии помещают фокус на первый интерактивный элемент внутри окна:

<script>
  import { Modal, Button } from 'carbon-components-svelte';
  let open = false;
</script>

<Button on:click={() => open = true}>Открыть модальное окно</Button>

<Modal bind:open={open} modalLabel="Пример фокуса">
  <Button>Первый элемент</Button>
  <Button>Второй элемент</Button>
</Modal>

В этом примере фокус будет автоматически установлен на первый <Button> внутри Modal, что соответствует принципам доступности.


Управление фокусом вручную

Для компонентов, где автоматического управления нет, можно использовать свойство bind:this для прямого обращения к элементу:

<script>
  import { Button } from 'carbon-components-svelte';
  let myButton;
</script>

<Button bind:this={myButton} on:click={() => myButton.focus()}>Установить фокус</Button>

Метод focus() позволяет программно направлять внимание пользователя на необходимый элемент интерфейса.


Фокус при навигации с клавиатуры

Carbon Components Svelte поддерживает клавиатурную навигацию через атрибуты tabindex и обработку событий клавиатуры. Для создания доступного интерфейса следует:

  • Использовать tabindex="0" для элементов, которые должны получать фокус.
  • Использовать tabindex="-1" для элементов, которые временно не должны участвовать в последовательности фокуса.
  • Обрабатывать события keydown для управления поведением при нажатии клавиш Enter, Space, Arrow и Escape.

Пример для кастомного списка с управлением фокусом стрелками:

<script>
  let items = ["Элемент 1", "Элемент 2", "Элемент 3"];
  let focusedIndex = 0;

  function handleKeyDown(event) {
    if(event.key === "ArrowDown") {
      focusedIndex = (focusedIndex + 1) % items.length;
    } else if(event.key === "ArrowUp") {
      focusedIndex = (focusedIndex - 1 + items.length) % items.length;
    }
  }
</script>

<ul on:keydown={handleKeyDown}>
  {#each items as item, i}
    <li tabindex={i === focusedIndex ? 0 : -1}>{item}</li>
  {/each}
</ul>

В этом примере стрелками ArrowUp и ArrowDown можно перемещать фокус между элементами списка, обеспечивая доступность для клавиатурного управления.


Использование FocusTrap

Для модальных окон и выпадающих меню, где фокус должен оставаться внутри компонента, применяется механизм Focus Trap. В Svelte это можно реализовать с помощью Carbon:

<script>
  import { Modal, Button } from 'carbon-components-svelte';
  let open = false;
</script>

<Button on:click={() => open = true}>Открыть окно с Focus Trap</Button>

<Modal bind:open={open} focusTrap={true}>
  <Button>Первый элемент</Button>
  <Button>Второй элемент</Button>
</Modal>

focusTrap={true} предотвращает выход фокуса за пределы модального окна при навигации клавишами Tab и Shift+Tab.


Управление фокусом в интерактивных компонентах

Некоторые компоненты, такие как Dropdown, Tooltip, DatePicker, имеют встроенную логику фокусировки. Основные моменты:

  • Dropdown: фокус автоматически перемещается на выбранный элемент при открытии.
  • DatePicker: фокус ставится на активную дату или поле ввода.
  • Tooltip: для доступности следует связывать с триггером через aria-describedby и управлять фокусом на триггере.

Пример Dropdown с программным фокусом на открытие:

<script>
  import { Dropdown } from 'carbon-components-svelte';
  let selected;
  let dropdownRef;
</script>

<Dropdown
  bind:this={dropdownRef}
  bind:selected={selected}
  items={["Опция 1", "Опция 2", "Опция 3"]}
  placeholder="Выберите опцию"
  on:open={() => dropdownRef.focus()}
/>

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

  • Использовать автоматический фокус там, где это предусмотрено компонентами Carbon.
  • Для кастомных компонентов реализовывать логику focus() и tabindex.
  • Всегда проверять доступность с клавиатурой и скринридерами.
  • Применять FocusTrap для модальных окон и выпадающих элементов, чтобы фокус не покидал интерактивную область.

Управление фокусом является ключевым аспектом доступности интерфейсов и делает работу с библиотекой Carbon Components Svelte более предсказуемой и безопасной для пользователей с различными потребностями.