Skip to main content
NumberField is a form component that allows users to enter numeric values with optional increment/decrement buttons. It extends TextField with number-specific features.

Basic usage

import { NumberField } from 'reshaped';

function Example() {
  return (
    <NumberField
      name="quantity"
      increaseAriaLabel="Increase quantity"
      decreaseAriaLabel="Decrease quantity"
    />
  );
}

Controlled component

import { useState } from 'react';
import { NumberField } from 'reshaped';

function ControlledExample() {
  const [value, setValue] = useState(0);

  return (
    <NumberField
      name="quantity"
      value={value}
      onChange={({ value }) => setValue(value)}
      increaseAriaLabel="Increase"
      decreaseAriaLabel="Decrease"
    />
  );
}

Uncontrolled component

import { NumberField } from 'reshaped';

function UncontrolledExample() {
  return (
    <NumberField
      name="count"
      defaultValue={10}
      onChange={({ name, value }) => console.log(name, value)}
      increaseAriaLabel="Increase count"
      decreaseAriaLabel="Decrease count"
    />
  );
}

With min and max

import { NumberField } from 'reshaped';

<NumberField
  name="age"
  min={0}
  max={120}
  defaultValue={25}
  increaseAriaLabel="Increase age"
  decreaseAriaLabel="Decrease age"
/>

With step

import { NumberField } from 'reshaped';

<NumberField
  name="price"
  step={0.01}
  min={0}
  defaultValue={9.99}
  prefix="$"
  increaseAriaLabel="Increase price"
  decreaseAriaLabel="Decrease price"
/>

With FormControl

import { FormControl, NumberField } from 'reshaped';

function FormExample() {
  return (
    <FormControl>
      <FormControl.Label>Quantity</FormControl.Label>
      <NumberField
        name="quantity"
        min={1}
        max={99}
        defaultValue={1}
        increaseAriaLabel="Increase quantity"
        decreaseAriaLabel="Decrease quantity"
      />
      <FormControl.Helper>
        Select a quantity between 1 and 99.
      </FormControl.Helper>
    </FormControl>
  );
}

Validation

import { FormControl, NumberField } from 'reshaped';
import { useState } from 'react';

function ValidationExample() {
  const [value, setValue] = useState(null);
  const hasError = value !== null && (value < 1 || value > 10);

  return (
    <FormControl hasError={hasError}>
      <FormControl.Label>Team size</FormControl.Label>
      <NumberField
        name="teamSize"
        value={value}
        onChange={({ value }) => setValue(value)}
        min={1}
        max={10}
        increaseAriaLabel="Increase team size"
        decreaseAriaLabel="Decrease team size"
      />
      <FormControl.Error>
        Team size must be between 1 and 10.
      </FormControl.Error>
    </FormControl>
  );
}

Sizes and variants

import { NumberField } from 'reshaped';

<NumberField
  size="small"
  name="small"
  increaseAriaLabel="Increase"
  decreaseAriaLabel="Decrease"
/>

<NumberField
  variant="faded"
  name="faded"
  increaseAriaLabel="Increase"
  decreaseAriaLabel="Decrease"
/>

Currency input

import { NumberField } from 'reshaped';
import { useState } from 'react';

function CurrencyExample() {
  const [value, setValue] = useState(0);

  return (
    <NumberField
      name="budget"
      value={value}
      onChange={({ value }) => setValue(value)}
      min={0}
      step={0.01}
      prefix="$"
      suffix="USD"
      increaseAriaLabel="Increase budget"
      decreaseAriaLabel="Decrease budget"
    />
  );
}

Accessibility

NumberField follows accessibility best practices:
  • Uses semantic HTML number input
  • Increment/decrement buttons have required ARIA labels
  • Keyboard accessible (Arrow up/down to adjust)
  • Screen reader announces current value and constraints
  • Works with FormControl for proper label associations

Props

name
string
required
Name of the number field input element
increaseAriaLabel
string
required
aria-label attribute for the increase button
decreaseAriaLabel
string
required
aria-label attribute for the decrease button
id
string
Unique identifier for the number field
value
number | null
Value of the form field, enables controlled mode
defaultValue
number
Default value of the form field, enables uncontrolled mode
min
number
Minimum value supported in the form field
max
number
Maximum value supported in the form field
step
number
Step at which the value will increase or decrease when clicking the button controls
placeholder
string
Placeholder text when there is no value
size
'small' | 'medium' | 'large' | 'xlarge'
default:"medium"
Component size. Supports responsive values.
variant
'outline' | 'faded' | 'ghost' | 'headless'
default:"outline"
Component render variant
disabled
boolean
Disable the number field user interaction
focused
boolean
Render in the focused state
hasError
boolean
Show an error state. Automatically inherited when used inside FormControl.
icon
React.ComponentType
Icon of the number field at the start position
prefix
React.ReactNode
Node for inserting text content before the number field value
suffix
React.ReactNode
Node for inserting text content after the number field value
startSlot
React.ReactNode
Node for inserting content before the number field value
startSlotPadding
number
Padding inline end, base unit token number multiplier
onChange
(args: { name: string, value: number }) => void
Callback when the component value is changed
onFocus
(e: React.FocusEvent<HTMLInputElement>) => void
Callback when the number field is focused
onBlur
(e: React.FocusEvent<HTMLInputElement>) => void
Callback when the number field is blurred
className
string
Additional classname for the root element
attributes
object
Additional attributes for the root element
inputAttributes
object
Additional attributes for the input element. Use for ARIA attributes.

Build docs developers (and LLMs) love