Хук useNumberField предоставляет полностью доступный и
настраиваемый способ управления числовыми полями ввода в приложениях на
React. Он обеспечивает корректное взаимодействие с
клавиатурой, поддержку экранных считывателей и обработку локализации
чисел. Основное назначение — создание числовых инпутов с поддержкой
управления стрелками, шагов, минимальных и максимальных значений, а
также форматирования.
import { useNumberField } from '@react-aria/numberfield';
import { useNumberFieldState } from '@react-stately/numberfield';
import { useLocale } from '@react-aria/i18n';
import React, { useRef } from 'react';
function NumberInput() {
const { locale } = useLocale();
const state = useNumberFieldState({ locale, minValue: 0, maxValue: 100, step: 1 });
const ref = useRef();
const { labelProps, inputProps, incrementButtonProps, decrementButtonProps } = useNumberField({
minValue: 0,
maxValue: 100,
step: 1,
value: state.value,
onChange: state.setValue,
formatOptions: { style: 'decimal', maximumFractionDigits: 2 }
}, state, ref);
return (
<div>
<label {...labelProps}>Количество</label>
<div>
<button {...decrementButtonProps}>-</button>
<input {...inputProps} ref={ref} />
<button {...incrementButtonProps}>+</button>
</div>
</div>
);
}
Ключевые моменты:
useNumberFieldState отвечает за внутреннее состояние
значения, управление шагами, ограничениями и форматированием.useNumberField возвращает свойства для
label, input и кнопок управления, полностью
совместимые с ARIA.ref необходим для корректной работы фокуса и управления
клавиатурой.useNumberField позволяет задать минимальное и
максимальное значение, а также шаг инкремента/декремента. Это
делает числовой ввод полностью контролируемым.
const state = useNumberFieldState({
minValue: 0,
maxValue: 50,
step: 5,
});
При нажатии кнопок + и - значение
увеличивается или уменьшается на шаг, при этом автоматически соблюдается
ограничение по минимальному и максимальному значению.
Библиотека поддерживает форматирование чисел согласно локали
пользователя через Intl.NumberFormat.
const { inputProps } = useNumberField({
value: state.value,
onChange: state.setValue,
formatOptions: { style: 'currency', currency: 'USD' }
}, state, ref);
Особенности:
style может быть 'decimal',
'currency', 'percent'.currency используется при валютном формате.useNumberField поддерживает стандартные комбинации
клавиш:
Это полностью соответствует рекомендациям WAI-ARIA и обеспечивает доступность для пользователей, использующих клавиатуру.
Возвращаемые incrementButtonProps и
decrementButtonProps позволяют легко создавать кнопки для
изменения значения:
<button {...incrementButtonProps}>+</button>
<button {...decrementButtonProps}>-</button>
Особенности:
disabled), когда значение достигает границы
диапазона.useNumberFieldState умеет корректно обрабатывать пустое
поле, некорректный ввод и частично введённые числа. Например, ввод
"12." или "-0" не приведёт к ошибкам и
сохранит совместимость с форматированием и локалью.
const state = useNumberFieldState({
minValue: 0,
maxValue: 100,
step: 1,
value: '', // допускается пустое значение
});
Можно динамически менять форматирование без потери состояния:
const [currency, setCurrency] = React.useState('USD');
const { inputProps } = useNumberField({
value: state.value,
onChange: state.setValue,
formatOptions: { style: 'currency', currency }
}, state, ref);
Это полезно для финансовых приложений, где пользователь может выбирать валюту и получать корректное отображение.
useNumberField автоматически добавляет следующие
атрибуты для обеспечения доступности:
role="spinbutton" на <input>aria-valuemin, aria-valuemax,
aria-valuenow для текущего значения<label> через
aria-labelledbyБиблиотека снимает необходимость ручной реализации ARIA для числовых полей, что уменьшает вероятность ошибок и повышает доступность приложения.
Использование useNumberField в связке с
useNumberFieldState позволяет создавать мощные, доступные и
локализованные числовые поля в React-приложениях. Управление шагами,
диапазонами, клавиатурой, форматированием и кнопками
инкремента/декремента реализуется легко и соответствует стандартам
ARIA. Такой подход гарантирует корректное поведение на
всех устройствах и в разных локалях, избавляя от необходимости писать
сложную логику с нуля.