Atomico — современная библиотека для создания веб-компонентов с реактивным подходом, предоставляющая удобные инструменты для управления состоянием и событиями. Одной из ключевых задач в пользовательских интерфейсах является обеспечение навигации с клавиатуры. Это особенно важно для доступности и улучшения UX, позволяя пользователю перемещаться по элементам без мыши.
Навигация с клавиатуры строится вокруг следующих ключевых концепций:
Фокусируемость элементов Любой элемент, по
которому пользователь должен перемещаться с клавиатуры, должен
поддерживать фокус. В HTML это достигается с помощью атрибута
tabindex. Например:
<div tabindex="0">Элемент 1</div>
<div tabindex="0">Элемент 2</div>
В Atomico можно управлять этим через JSX и реактивные свойства:
import { c, useRef } from "atomico";
const Item = c(() => {
const ref = useRef();
return <div ref={ref} tabindex="0">Навигационный элемент</div>;
});Обработка событий клавиатуры Для отслеживания
нажатий клавиш используется событие keydown. В Atomico
можно привязать его через JSX:
const handleKeyDown = (event) => {
if (event.key === "ArrowDown") {
// Действие при стрелке вниз
}
};
return <div onKeyD own={handleKeyDown} tabindex="0">Навигация</div>;
Важно предотвращать стандартное поведение при необходимости, например:
event.preventDefault();Atomico поддерживает реактивные ссылки на элементы
через useRef. Это позволяет программно управлять
фокусом:
import { c, useRef } from "atomico";
const List = c(() => {
const items = [useRef(), useRef(), useRef()];
const handleKeyDown = (event, index) => {
if (event.key === "ArrowDown") {
items[(index + 1) % items.length].current.focus();
}
if (event.key === "ArrowUp") {
items[(index - 1 + items.length) % items.length].current.focus();
}
};
return (
<div>
{items.map((ref, i) => (
<div
key={i}
ref={ref}
tabindex="0"
onKeyD own={(e) => handleKeyDown(e, i)}
>
Элемент {i + 1}
</div>
))}
</div>
);
});
Особенности подхода:
useRef для всех фокусируемых
элементов.Для полноценной поддержки клавиатуры важно использовать атрибуты ARIA. Примеры:
<div role="listbox" aria-activedescendant="item-1">
<div id="item-1" role="option" tabindex="0">Элемент 1</div>
<div id="item-2" role="option" tabindex="-1">Элемент 2</div>
</div>
Рекомендации:
role="listbox" у контейнера с элементами.role="option" у каждого элемента списка.aria-activedescendant указывает текущий активный
элемент.tabindex="-1" на всех неактивных элементах, чтобы фокус
перемещался только через программное управление.Atomico позволяет создавать обработку сложных комбинаций:
const handleKeyDown = (event) => {
if (event.ctrlKey && event.key === "ArrowDown") {
console.log("Ctrl + стрелка вниз");
}
};
Это полезно для реализации функционала, например, выделения нескольких элементов или переключения режимов.
div:focus {
outline: 2px solid #007aff;
}
useEffect для установки начального фокуса
или динамического добавления элементов.import { useEffect } from "atomico";
useEffect(() => {
items[0].current.focus();
}, []);
В Atomico навигация с клавиатуры строится на реактивных ссылках,
управлении фокусом через tabindex, обработке событий
keydown и правильном использовании ARIA-атрибутов. Такой
подход обеспечивает:
Этот метод позволяет создавать интерфейсы, полностью управляемые с клавиатуры, с сохранением реактивности и масштабируемости компонентов.