React Aria предоставляет набор хуков и утилит для создания доступных интерфейсов с поддержкой клавиатурной навигации. Основная цель — обеспечить возможность управления элементами интерфейса с помощью клавиатуры, сохраняя совместимость с ARIA-атрибутами и стандартами доступности.
useFocusRing — позволяет определить, находится ли элемент в фокусе и применить визуальное выделение. Используется для контроля стилей при навигации с клавиатуры:
import { useFocusRing } from '@react-aria/focus';
function FocusableButton(props) {
const { isFocusVisible, focusProps } = useFocusRing();
return (
<button {...focusProps} style={{ outline: isFocusVisible ? '2px solid blue' : 'none' }}>
{props.children}
</button>
);
}
isFocusVisible — булевый флаг, указывающий, активен ли
фокус для текущего элемента.focusProps — набор пропсов, которые необходимо передать
элементу для корректного управления фокусом.useKeyboard — предоставляет возможность реагировать на нажатия клавиш:
import { useKeyboard } from '@react-aria/interactions';
function KeyboardHandler() {
const { keyboardProps } = useKeyboard({
onKeyDown: (e) => {
if (e.key === 'Enter') {
console.log('Нажата клавиша Enter');
}
}
});
return <div {...keyboardProps} tabIndex={0}>Нажмите Enter</div>;
}
keydown, keyup,
keypress.tabIndex, чтобы элемент был
фокусируемым.В React Aria часто используется tabIndex для
управления последовательностью фокусируемых элементов. Хук
useFocusable автоматизирует работу с фокусом:
import { useFocusable } from '@react-aria/focus';
function FocusableItem(props) {
const { focusableProps } = useFocusable(props);
return <div {...focusableProps}>{props.children}</div>;
}
focusableProps включает все необходимые атрибуты ARIA и
tabIndex.useFocusRing для визуального отображения
текущего фокуса.Для компонентов типа списков, меню или табов важна поддержка
стрелок клавиатуры. Хук
useListKeyboardNavigation обеспечивает простую
навигацию:
import { useListKeyboardNavigation } from '@react-aria/selection';
import { useState } from 'react';
function ListNavigation({ items }) {
const [selectedIndex, setSelectedIndex] = useState(0);
const { keyboardProps } = useListKeyboardNavigation({
selectedKey: selectedIndex,
onSelectionChange: setSelectedIndex,
collection: items
});
return (
<ul {...keyboardProps}>
{items.map((item, index) => (
<li key={index} style={{ background: index === selectedIndex ? 'lightgray' : 'white' }}>
{item}
</li>
))}
</ul>
);
}
Home,
End.Клавиатурная навигация в модальных компонентах требует trap focus, чтобы фокус оставался внутри окна:
import { useDialog } from '@react-aria/dialog';
import { useOverlay } from '@react-aria/overlays';
function Modal({ isOpen, onClose }) {
const ref = React.useRef();
const { dialogProps } = useDialog({}, ref);
const { overlayProps } = useOverlay({ isOpen, onClose }, ref);
return isOpen ? (
<div {...overlayProps} ref={ref} style={{ position: 'fixed', top: 0, left: 0 }}>
<div {...dialogProps} style={{ background: 'white', padding: 20 }}>
Модальное окно
</div>
</div>
) : null;
}
useDialog добавляет необходимые ARIA-атрибуты.useOverlay управляет фокусом и закрытием по
Escape.React Aria рекомендует разделять интерфейсную логику и
состояние. Например, useSelectableCollection
позволяет поддерживать клавиатурную навигацию и выделение элементов, при
этом состояние можно хранить снаружи:
import { useSelectableCollection } from '@react-aria/selection';
import { useState } from 'react';
function SelectableList({ items }) {
const [selectedKeys, setSelectedKeys] = useState(new Set());
const { collectionProps, selectionManager } = useSelectableCollection({
items,
selectionMode: 'single',
selectedKeys,
onSelectionChange: setSelectedKeys
});
return (
<ul {...collectionProps}>
{items.map(item => (
<li key={item.key} style={{ background: selectedKeys.has(item.key) ? 'lightblue' : 'white' }}>
{item.name}
</li>
))}
</ul>
);
}
selectionManager управляет логикой выделения и
навигации.single, multiple,
none.ArrowUp, ArrowDown, Enter).useFocusRing с useKeyboard для
полной поддержки визуальной и функциональной доступности.useSelectableCollection или
useListKeyboardNavigation вместо собственных реализаций
стрелочной навигации.useDialog + useOverlay для корректного
управления фокусом и клавиатурным закрытием.Эти инструменты обеспечивают комплексную поддержку клавиатурной навигации, сохраняя соответствие стандартам ARIA и улучшая доступность интерфейсов в React-приложениях.