Индетерминантное состояние (indeterminate state) является ключевым понятием при работе с компонентами пользовательского интерфейса, такими как чекбоксы и переключатели, особенно когда требуется отображать промежуточное состояние выбора. В React Aria оно реализуется через свойства и хуки, которые обеспечивают доступность и согласованность поведения компонента с ARIA-стандартами.
Индетерминантное состояние обозначает частичное или неопределённое состояние выбора. Классический пример — чекбокс, связанный с группой элементов, где не все элементы выбраны:
[ ] Выбрать все
[x] Элемент 1
[ ] Элемент 2
[x] Элемент 3
В этом случае верхний чекбокс будет находиться в indeterminate состоянии, показывая пользователю, что выбор группы частично активен.
Ключевые моменты:
indeterminate не равен ни true, ни
false.aria-checked="mixed".useCheckbox с индетерминантным состояниемВ React Aria для работы с чекбоксами используется хук
useCheckbox. Для задания индетерминантного состояния
необходимо использовать свойство isIndeterminate.
Пример:
import { useCheckbox } from '@react-aria/checkbox';
import { useRef } from 'react';
function Checkbox({ isIndeterminate, ...props }) {
let ref = useRef();
let { inputProps } = useCheckbox({ ...props, isIndeterminate }, ref);
return <input {...inputProps} ref={ref} />;
}
Особенности:
isIndeterminate можно вычислять на основе состояния группы
дочерних чекбоксов.Часто требуется контролировать состояние всей группы через верхний чекбокс:
checked = true.checked = false.isIndeterminate = true.Пример реализации:
import { useState } from 'react';
import { useCheckboxGroup, useCheckbox } from '@react-aria/checkbox';
function CheckboxGroup({ items }) {
const [selected, setSelected] = useState([]);
const toggleItem = (item) => {
setSelected((prev) =>
prev.includes(item)
? prev.filter(i => i !== item)
: [...prev, item]
);
};
const allSelected = selected.length === items.length;
const someSelected = selected.length > 0 && selected.length < items.length;
return (
<div>
<Checkbox
isIndeterminate={someSelected}
isSelected={allSelected}
onCha nge={() =>
allSelected ? setSelected([]) : setSelected([...items])
}
>
Выбрать все
</Checkbox>
{items.map(item => (
<Checkbox
key={item}
isSelected={selected.includes(item)}
onCha nge={() => toggleItem(item)}
>
{item}
</Checkbox>
))}
</div>
);
}
Выводы по использованию:
aria-checked атрибуты.Для корректного отображения индетерминантного состояния нужно учитывать два аспекта:
<input
type="checkbox"
checked={checked}
ref={ref}
aria-checked={isIndeterminate ? 'mixed' : checked}
/>
aria-checked="mixed" позволяет экранным читалкам
корректно озвучивать промежуточное состояние.input[type="checkbox"]:indeterminate {
background-color: #666;
}
Важно помнить, что HTML не поддерживает установку
indeterminate через атрибуты напрямую. Нужно использовать
свойство DOM:
ref.current.indeterminate = isIndeterminate;
React Aria автоматически синхронизирует этот атрибут при
использовании useCheckbox.
Индетерминантное состояние применимо не только к чекбоксам:
aria-checked="mixed" при
indeterminate.Эта практика обеспечивает удобный, понятный и доступный интерфейс, полностью соответствующий стандартам WAI-ARIA и рекомендациям по доступности.