Форматирование чисел

React Aria предоставляет набор хуков и утилит для создания доступных компонентов пользовательского интерфейса. Одной из часто используемых функций является форматирование числовых значений, которое необходимо для полей ввода чисел, отображения валюты, процентов или больших числовых массивов с разделителями.

Хук useNumberField

Основной инструмент для работы с числовыми полями — хук useNumberField. Он обеспечивает правильную работу с доступностью (ARIA) и корректное форматирование чисел при вводе и отображении.

import {useNumberField} from '@react-aria/numberfield';
import {useNumberFieldState} from '@react-stately/number';

function NumberInput(props) {
  let state = useNumberFieldState(props);
  let ref = React.useRef();
  let {labelProps, inputProps, incrementButtonProps, decrementButtonProps} = useNumberField(props, state, ref);

  return (
    <div>
      <label {...labelProps}>{props.label}</label>
      <button {...decrementButtonProps}>-</button>
      <input {...inputProps} ref={ref} />
      <button {...incrementButtonProps}>+</button>
    </div>
  );
}

Ключевые моменты:

  • useNumberFieldState управляет внутренним состоянием числа и его форматированием.
  • useNumberField обеспечивает доступность через ARIA-атрибуты.
  • Инкремент и декремент корректно обновляют форматированное значение.

Форматирование с formatOptions

React Aria использует Intl.NumberFormat под капотом для локализованного отображения чисел. Через formatOptions можно задать:

  • style'decimal', 'currency', 'percent'.
  • currency — код валюты, например 'USD' или 'EUR'.
  • minimumFractionDigits и maximumFractionDigits — контроль количества знаков после запятой.

Пример использования:

let state = useNumberFieldState({
  value: 1234.56,
  onChange: (value) => console.log(value),
  formatOptions: {
    style: 'currency',
    currency: 'USD',
    minimumFractionDigits: 2,
    maximumFractionDigits: 2
  }
});

В этом случае число будет отображаться как $1,234.56 в американской локали.

Управление локалью

React Aria позволяет передавать локаль через контекст. Это важно для правильного отображения десятичных и тысячных разделителей.

import {Provider} from '@react-aria/i18n';

<Provider locale="ru-RU">
  <NumberInput label="Сумма" />
</Provider>

Число 1234.56 в русской локали отобразится как 1 234,56, а знак валюты можно указать в formatOptions.

Особенности редактирования чисел

React Aria корректно обрабатывает ввод пользователем:

  • Поддержка отрицательных чисел и десятичных дробей.
  • Автоматическое форматирование при потере фокуса (blur).
  • Отдельные кнопки для инкремента/декремента с правильными ARIA-метками.

Пример управления шагом:

let state = useNumberFieldState({
  value: 10,
  onChange: (value) => console.log(value),
  minValue: 0,
  maxValue: 100,
  step: 5,
  formatOptions: { style: 'decimal' }
});

Кнопки увеличивают и уменьшают значение на 5, при этом соблюдается диапазон [0, 100].

Маски и отображение процентов

Для процентов используется стиль percent. Число 0.25 при style: 'percent' отображается как 25%. Можно также управлять дробной частью:

formatOptions: {
  style: 'percent',
  minimumFractionDigits: 1,
  maximumFractionDigits: 2
}

Вывод: 25,0% или 25,00% в зависимости от настроек.

Поддержка больших чисел и группировки

Опция useGrouping позволяет включить или отключить разделители тысяч:

formatOptions: {
  style: 'decimal',
  useGrouping: true
}

Пример: 12345671 234 567, а при useGrouping: false1234567.

Динамическое обновление формата

Формат можно менять в процессе работы компонента. Например, переключение между валютой и процентами:

const [format, setFormat] = React.useState('decimal');

<NumberInput 
  label="Сумма" 
  formatOptions={{style: format, currency: format === 'currency' ? 'USD' : undefined}} 
/>

<button onCl ick={() => setFormat('currency')}>Валюта</button>
<button onCl ick={() => setFormat('percent')}>Процент</button>

React Aria корректно пересчитает и отобразит число в новом формате без потери данных.

Валидация и обработка ошибок

useNumberFieldState поддерживает:

  • Проверку диапазона (minValue, maxValue).
  • Валидацию на корректность числа.
  • Состояние ошибки доступно через state.validationState и может использоваться для отображения подсказок или изменения стилей.
{state.validationState === 'invalid' && <span>Некорректное значение</span>}

Интеграция с другими компонентами

React Aria позволяет комбинировать useNumberField с DatePicker, Slider и другими контролами, где необходимо корректное числовое представление. Это гарантирует единообразие форматирования и доступности во всем приложении.


React Aria превращает работу с числами в удобный и доступный процесс, позволяя управлять локалью, стилем, шагом и валидацией без лишнего кода и вручную написанных функций форматирования.