NumberInput

Capture number input from user
Import

Usage

Radius
xs
sm
md
lg
xl
Size
xs
sm
md
lg
xl
<NumberInput
defaultValue={18}
placeholder="Your age"
label="Your age"
required
/>

Clamp on blur

Component has internal state to manage user input, when blur event is triggered internal value is clamped with given min and max values and onChange handler is called with result.

For example, if you put 123 or -20 in age input in next example, values will be clamped on blur: 123 -> 120, -20 -> 0. If you want to disable this behavior set noClampOnBlur prop:

<NumberInput noClampOnBlur />

Min, max and step

Min and max values define upper and lower value which may be entered. When user clicks controls or presses up/down arrows, value is incremented/decremented by step:

From 0 to 120, step is 1
From 0 to Infinity, step is 5
<NumberInput
label="Your age"
description="From 0 to 120, step is 1"
placeholder="Your age"
max={120}
min={0}
/>
<NumberInput
mt="md"
label="Your weight in kg"
description="From 0 to Infinity, step is 5"
defaultValue={80}
step={5}
min={0}
/>

Increment/decrement on hold

Set stepHoldDelay and stepHoldInterval props to define behavior when increment/decrement controls are clicked and hold, this will also overwrite default up and down arrows behavior:

Step the value when clicking and holding the arrows
Ste value will increase incrementally when control is hold
<NumberInput
style={{ marginTop: 15 }}
label="Step on hold"
description="Step the value when clicking and holding the arrows"
stepHoldDelay={500}
stepHoldInterval={100}
/>
<NumberInput
label="Step the value with interval function"
description="Step value will increase incrementally when control is hold"
stepHoldDelay={500}
stepHoldInterval={(t) => Math.max(1000 / t ** 2, 25)}
/>

Decimal steps

To use decimal steps set following props:

  • step – decimal number, e.g. 0.05
  • precision – amount of significant digits
<NumberInput
label="Number input with decimal steps"
defaultValue={0.05}
precision={2}
min={-1}
step={0.05}
max={1}
/>

Decimal separator

To change decimal separator set decimalSeparator prop:

<NumberInput
decimalSeparator=","
label="Number input with a custom decimal separator"
defaultValue={0.5}
precision={2}
step={0.5}
/>

Remove controls

Controls are not rendered in these cases:

  • hideControls prop is set to true
  • Input is disabled
  • variant prop is set to unstyled
<NumberInput label="By default controls are visible" />
<NumberInput
hideControls
label="Disable them with hideControls prop"
/>
<NumberInput
label="Disabled"
disabled
label="Controls also not rendered when input is disabled"
/>

Custom increment/decrement controls

NumberInput exposes increment/decrement functions with handlersRef prop. You can use it to create custom controls:

import { useState, useRef } from 'react';
import { NumberInput, Group, ActionIcon, NumberInputHandlers } from '@mantine/core';
function HandlersWrapper() {
const [value, setValue] = useState(0);
const handlers = useRef<NumberInputHandlers>();
return (
<Group spacing={5}>
<ActionIcon size={42} variant="default" onClick={() => handlers.current.decrement()}>
</ActionIcon>
<NumberInput
hideControls
value={value}
onChange={(val) => setValue(val)}
handlersRef={handlers}
max={10}
min={0}
step={2}
styles={{ input: { width: 54, textAlign: 'center' } }}
/>
<ActionIcon size={42} variant="default" onClick={() => handlers.current.increment()}>
+
</ActionIcon>
</Group>
);
}

Controlled

import { useState } from 'react';
import { NumberInput } from '@mantine/core';
function Demo() {
const [value, setValue] = useState(0);
return <NumberInput value={value} onChange={(val) => setValue(val)} />;
}

Invalid state and error

You must be at least 21
// Error as boolean – red border color
<NumberInput error />
// Error as React node – red border color and message below input
<NumberInput error="You must be at least 21" />

Disabled state

Controls to increment/decrement value are not displayed when input is disabled:

<NumberInput disabled />

With icon

<NumberInput icon={<Medal />} />

Get input ref

import { useRef } from 'react';
import { NumberInput } from '@mantine/core';
function Demo() {
const ref = useRef(null);
return <NumberInput ref={ref} />;
}

Accessibility

NumberInput renders regular input with type="text". Increment/decrement controls have aria-hidden attribute and cannot be focused – users with keyboard can increment/decrement value by step with up/down arrows.

Provide aria-label in case you use component without label for screen reader support:

<NumberInput /> // -> not ok, input is not labeled
<NumberInput label="Your age" /> // -> ok, input and label is connected
<NumberInput aria-label="Your age" /> // -> ok, label is not visible but will be announced by screen reader
Build fully functional accessible web applications faster than ever
Feedback
Your feedback is most valuable contribution to the project, please share how you use Mantine, what features are missing and what is done good
Leave feedback