Number Input
A field that allows user input of numeric values.
A field that allows user input of numeric values.
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.
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
const FractionDigits = () => (
<NumberInput.Root
formatOptions={{ minimumFractionDigits: 2, maximumFractionDigits: 4 }}
value="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>
)
<script setup lang="ts">
null
</script>
<template>
<NumberInput.Root
:formatOptions="{ minimumFractionDigits: 2, maximumFractionDigits: 3 }"
model-value="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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
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>
)
import { NumberInput } from '@ark-ui/solid'
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>
)
<script setup lang="ts">
null
</script>
<template>
<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>
</template>
Prop | Type | Default |
---|---|---|
allowMouseWheel Whether to allow mouse wheel to change the value | boolean | |
allowOverflow Whether to allow the value overflow the min/max range | boolean | true |
asChild Render as a different element type. | boolean | |
clampValueOnBlur Whether to clamp the value when the input loses focus (blur) | boolean | true |
defaultValue The initial value of the number input. | string | |
dir The document's text/writing direction. | 'ltr' | 'rtl' | "ltr" |
disabled Whether the number input is disabled. | boolean | |
focusInputOnChange Whether to focus input when the value changes | boolean | true |
form The associate form of the input element. | string | |
formatOptions The options to pass to the `Intl.NumberFormat` constructor | NumberFormatOptions | |
getRootNode A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
id The unique identifier of the machine. | string | |
ids The ids of the elements in the number input. Useful for composition. | Partial<{
root: string
label: string
input: string
incrementTrigger: string
decrementTrigger: string
scrubber: string
}> | |
inputMode Hints at the type of data that might be entered by the user. It also determines the type of keyboard shown to the user on mobile devices | InputMode | "decimal" |
invalid Whether the number input value is invalid. | boolean | |
locale The current locale. Based on the BCP 47 definition. | string | "en-US" |
max The maximum value of the number input | number | |
min The minimum value of the number input | number | |
name The name attribute of the number input. Useful for form submission. | string | |
onFocusChange Function invoked when the number input is focused | (details: FocusChangeDetails) => void | |
onValueChange Function invoked when the value changes | (details: ValueChangeDetails) => void | |
onValueInvalid Function invoked when the value overflows or underflows the min/max range | (details: ValueInvalidDetails) => void | |
pattern The pattern used to check the <input> element's value against | string | "[0-9]*(.[0-9]+)?" |
readOnly Whether the number input is readonly | boolean | |
spinOnPress Whether to spin the value when the increment/decrement button is pressed | boolean | |
step The amount to increment or decrement the value by | number | |
translations Specifies the localized strings that identifies the accessibility elements and their states | IntlTranslations | |
value The value of the input | string |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Previous
Nested MenuNext
Pagination