Number Input

A field that allows user input of numeric values.

Anatomy

To set up the number input correctly, you’ll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the NumberInput component in your project. Let’s take a look at the most basic example:

import { NumberInput } from '@ark-ui/react'

const Basic = () => (
  <NumberInput.Root>
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Setting a minimum and maximum value

Pass the min prop or max prop to set an upper and lower limit for the input. By default, the input will restrict the value to stay within the specified range.

import { NumberInput } from '@ark-ui/react'

const MinMax = () => (
  <NumberInput.Root min={0} max={10}>
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Adjusting the precision of the value

In some cases, you might need the value to be rounded to specific decimal points. Set the formatOptions and provide Intl.NumberFormatOptions such as maximumFractionDigits or minimumFractionDigits.

import { NumberInput } from '@ark-ui/react'

const FractionDigits = () => (
  <NumberInput.Root
    formatOptions={{ minimumFractionDigits: 2, maximumFractionDigits: 3 }}
    defaultValue="1.00"
  >
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Scrubbing the input value

The NumberInput supports the scrubber interaction pattern. To use this pattern, render the Number.InputScrubber component. It uses the Pointer lock API and tracks the pointer movement. It also renders a virtual cursor which mimics the real cursor’s pointer.

import { NumberInput } from '@ark-ui/react'

const Scrubber = () => (
  <NumberInput.Root>
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Using the mousewheel to change value

The NumberInput exposes a way to increment/decrement the value using the mouse wheel event. To activate this, set the allowMouseWheel prop to true.

import { NumberInput } from '@ark-ui/react'

const MouseWheel = () => (
  <NumberInput.Root allowMouseWheel>
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Clamp value when user blurs the input

In most cases, users can type custom values in the input field. If the typed value is greater than the max, the value is reset to max when the user blur out of the input.

To disable this behavior, pass clampValueOnBlur and set to false.

import { NumberInput } from '@ark-ui/react'

const NoClamp = () => (
  <NumberInput.Root clampValueOnBlur={false}>
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Usage within forms

To use the number input within forms, set the name prop.

import { NumberInput } from '@ark-ui/react'

const FormUsage = () => (
  <NumberInput.Root name="quantity">
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

Format and parse value

To apply custom formatting to the input’s value, set the formatOptions and provide Intl.NumberFormatOptions such as style and currency.

import { NumberInput } from '@ark-ui/react'

const Formatted = () => (
  <NumberInput.Root
    formatOptions={{
      style: 'currency',
      currency: 'USD',
    }}
  >
    <NumberInput.Scrubber />
    <NumberInput.Label>Label</NumberInput.Label>
    <NumberInput.Input />
    <NumberInput.Control>
      <NumberInput.DecrementTrigger>-1</NumberInput.DecrementTrigger>
      <NumberInput.IncrementTrigger>+1</NumberInput.IncrementTrigger>
    </NumberInput.Control>
  </NumberInput.Root>
)

API Reference

Root

PropTypeDefault
allowMouseWheel
boolean
allowOverflow
booleantrue
asChild
boolean
clampValueOnBlur
booleantrue
defaultValue
string
dir
'ltr' | 'rtl'"ltr"
disabled
boolean
focusInputOnChange
booleantrue
form
string
formatOptions
NumberFormatOptions
getRootNode
() => Node | ShadowRoot | Document
id
string
ids
Partial<{ root: string label: string input: string incrementTrigger: string decrementTrigger: string scrubber: string }>
inputMode
InputMode"decimal"
invalid
boolean
locale
string"en-US"
max
number
min
number
name
string
onFocusChange
(details: FocusChangeDetails) => void
onValueChange
(details: ValueChangeDetails) => void
onValueInvalid
(details: ValueInvalidDetails) => void
pattern
string"[0-9]*(.[0-9]+)?"
readOnly
boolean
spinOnPress
boolean
step
number
translations
IntlTranslations
value
string

Input

PropTypeDefault
asChild
boolean

Label

PropTypeDefault
asChild
boolean

Control

PropTypeDefault
asChild
boolean

Scrubber

PropTypeDefault
asChild
boolean

DecrementTrigger

PropTypeDefault
asChild
boolean

IncrementTrigger

PropTypeDefault
asChild
boolean