React Aria предоставляет мощный инструмент для создания доступных компонентов пользовательского интерфейса, включая детальное управление различными состояниями: hover, focus, pressed, selected, disabled и другими. Стилизация этих состояний важна для обеспечения понятной визуальной обратной связи пользователю и соответствия стандартам доступности.
Библиотека основана на хуках, которые предоставляют доступ к состояниям компонента и атрибутам для правильного взаимодействия с DOM.
useButton управляет состоянием кнопки, включая фокус,
нажатие и отключение:
import {useButton} from '@react-aria/button';
import {useRef} from 'react';
function Button(props) {
let ref = useRef();
let {buttonProps, isPressed} = useButton(props, ref);
return (
<button
{...buttonProps}
ref={ref}
style={{
backgroundColor: isPressed ? 'darkblue' : 'blue',
color: 'white',
padding: '8px 16px',
border: 'none',
borderRadius: '4px',
cursor: props.isDisabled ? 'not-allowed' : 'pointer',
opacity: props.isDisabled ? 0.5 : 1
}}
>
{props.children}
</button>
);
}
Ключевые моменты:
isPressed позволяет менять стили при удержании
кнопки.buttonProps содержит атрибуты для доступности
(aria-disabled, обработчики событий).isDisabled автоматически блокирует
интерактивность.Для визуального отображения состояния наведения применяется хук
useHover:
import {useHover} from '@react-aria/interactions';
import {useState, useRef} from 'react';
function HoverableDiv() {
let ref = useRef();
let {hoverProps, isHovered} = useHover({ref});
return (
<div
{...hoverProps}
ref={ref}
style={{
padding: '20px',
backgroundColor: isHovered ? 'lightgray' : 'white',
border: '1px solid black',
borderRadius: '4px',
transition: 'background-color 0.2s'
}}
>
Наведи курсор сюда
</div>
);
}
Особенности:
isHovered позволяет динамически менять цвет фона или
другие стили.Состояние фокуса критично для доступности:
import {useFocus} from '@react-aria/interactions';
import {useRef, useState} from 'react';
function FocusableInput() {
let ref = useRef();
let {focusProps, isFocused} = useFocus({ref});
return (
<input
{...focusProps}
ref={ref}
style={{
padding: '8px',
border: '2px solid',
borderColor: isFocused ? 'blue' : 'gray',
borderRadius: '4px',
outline: 'none'
}}
/>
);
}
Примечание:
isFocused помогает выделять элемент при клавиатурной
навигации.focusProps содержит обработчики onFocus и
onBlur с поддержкой доступности.React Aria позволяет комбинировать несколько состояний одновременно. Например, кнопка может быть hovered, pressed и disabled:
import {useButton} from '@react-aria/button';
import {useHover} from '@react-aria/interactions';
import {useRef} from 'react';
function InteractiveButton(props) {
let ref = useRef();
let {buttonProps, isPressed} = useButton(props, ref);
let {hoverProps, isHovered} = useHover({ref});
return (
<button
{...buttonProps}
{...hoverProps}
ref={ref}
style={{
backgroundColor: isPressed ? 'darkblue' : isHovered ? 'lightblue' : 'blue',
color: 'white',
padding: '8px 16px',
border: 'none',
borderRadius: '4px',
cursor: props.isDisabled ? 'not-allowed' : 'pointer',
opacity: props.isDisabled ? 0.5 : 1,
transition: 'background-color 0.2s'
}}
>
{props.children}
</button>
);
}
Особенности композиции:
Для компонентов выбора (Checkbox, Switch)
важно управлять состоянием выбора:
import {useToggleState} from '@react-stately/toggle';
import {useCheckbox} from '@react-aria/checkbox';
import {useRef} from 'react';
function Checkbox(props) {
let state = useToggleState(props);
let ref = useRef();
let {inputProps} = useCheckbox(props, state, ref);
return (
<label style={{display: 'flex', alignItems: 'center', gap: '8px'}}>
<input {...inputProps} ref={ref} />
<span style={{fontWeight: state.isSelected ? 'bold' : 'normal'}}>
{props.children}
</span>
</label>
);
}
Состояния:
state.isSelected управляет стилями выбранного
элемента.aria-checked встроена в
inputProps.Часто удобнее управлять классами вместо inline-стилей:
function getButtonClass({isHovered, isPressed, isDisabled}) {
if (isDisabled) return 'btn disabled';
if (isPressed) return 'btn pressed';
if (isHovered) return 'btn hovered';
return 'btn';
}
CSS пример:
.btn { background-color: blue; color: white; padding: 8px 16px; border-radius: 4px; }
.btn.hovered { background-color: lightblue; }
.btn.pressed { background-color: darkblue; }
.btn.disabled { opacity: 0.5; cursor: not-allowed; }
Такой подход облегчает поддержку и масштабирование стилей, особенно при сложных компонентах с множеством состояний.
React Aria позволяет создавать полностью доступные и визуально динамичные компоненты, где каждое состояние тщательно контролируется и легко стилизуется. Управление hover, focus, pressed и selected состояниями становится интуитивным благодаря единообразным хукам и интеграции с ARIA-атрибутами.