React Aria предоставляет мощный инструмент для создания доступных и
интерактивных компонентов, управляя их состояниями без необходимости
вручную отслеживать низкоуровневые события. Два ключевых состояния, с
которыми часто приходится работать при разработке кнопок, чекбоксов,
переключателей и других интерактивных элементов, — это
pressed и disabled.
pressedСостояние pressed отражает факт активного взаимодействия
пользователя с элементом. Оно особенно актуально для кнопок и элементов,
поддерживающих режим «toggle» (переключатель). React Aria предоставляет
хук usePress, который упрощает обработку всех событий
нажатия и касания, а также управления фокусом и доступностью.
usePress:onPressStart,
onPressEnd, onPress и
onPressChange.Пример использования usePress для кнопки:
import { usePress } from '@react-aria/interactions';
import { useRef, useState } from 'react';
function PressableButton(props) {
const ref = useRef();
const [isPressed, setIsPressed] = useState(false);
const { pressProps } = usePress({
onPressStart: () => setIsPressed(true),
onPressEnd: () => setIsPressed(false),
onPress: () => console.log('Кнопка нажата')
}, ref);
return (
<button
{...pressProps}
ref={ref}
style={{
background: isPressed ? 'darkblue' : 'blue',
color: 'white',
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
{isPressed ? 'Нажата' : 'Нажми меня'}
</button>
);
}
В этом примере isPressed автоматически обновляется при
взаимодействии пользователя, и элемент получает визуальное подтверждение
нажатия.
Ключевой момент: usePress не только
управляет визуальным состоянием, но и обеспечивает правильную работу с
клавиатурой и вспомогательными устройствами ввода, что важно для
доступности.
disabledСостояние disabled делает элемент недоступным для
взаимодействия. В React Aria оно реализуется через хуки, такие как
useButton или useToggleButton, которые
автоматически добавляют атрибут aria-disabled и
предотвращают вызов событий нажатия.
disabled:import { useButton } from '@react-aria/button';
import { useRef } from 'react';
function DisabledButton({ isDisabled }) {
const ref = useRef();
const { buttonProps } = useButton({ isDisabled }, ref);
return (
<button
{...buttonProps}
ref={ref}
style={{
background: isDisabled ? 'gray' : 'green',
color: 'white',
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: isDisabled ? 'not-allowed' : 'pointer'
}}
>
{isDisabled ? 'Отключено' : 'Активно'}
</button>
);
}
Здесь useButton автоматически управляет:
aria-disabled для поддержки вспомогательных
технологий.pressed и disabledПри разработке интерактивных элементов часто требуется учитывать оба
состояния одновременно. React Aria позволяет комбинировать хуки
usePress и useButton для обработки этих
случаев без конфликтов.
import { useButton } from '@react-aria/button';
import { usePress } from '@react-aria/interactions';
import { useRef, useState } from 'react';
function InteractiveButton({ isDisabled }) {
const ref = useRef();
const [isPressed, setIsPressed] = useState(false);
const { buttonProps } = useButton({ isDisabled }, ref);
const { pressProps } = usePress({
onPressStart: () => setIsPressed(true),
onPressEnd: () => setIsPressed(false)
}, ref);
return (
<button
{...buttonProps}
{...pressProps}
ref={ref}
style={{
background: isDisabled ? 'gray' : isPressed ? 'darkred' : 'red',
color: 'white',
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: isDisabled ? 'not-allowed' : 'pointer'
}}
>
{isDisabled ? 'Отключено' : isPressed ? 'Нажато' : 'Нажми меня'}
</button>
);
}
В этой конструкции:
isDisabled полностью блокирует взаимодействие и
визуально сигнализирует пользователю, что кнопка неактивна.isPressed отслеживает активное взаимодействие при
условии, что элемент доступен.buttonProps и pressProps
гарантирует корректную обработку всех событий и доступность.aria-pressed и
aria-disabled вместо ручного добавления атрибутов, чтобы
обеспечить совместимость со скринридерами.pressed и disabled должны быть отчетливо
видимы для всех пользователей. Контраст, тень или цвет — эффективные
способы сигнализировать состояние.Enter и Space,
поэтому элементы остаются доступными при использовании клавиатуры.usePress и useButton можно использовать
совместно для синхронизации состояний и управления доступностью.Эффективное использование состояний pressed и
disabled в React Aria позволяет создавать интерактивные
элементы, полностью соответствующие современным стандартам доступности,
без ручной реализации сложной логики событий и управления фокусом.