apps/mantine.dev/src/pages/core/number-input.mdx
import { NumberInputDemos } from '@docs/demos'; import { Layout } from '@/layout'; import { MDX_DATA } from '@/mdx';
export default Layout(MDX_DATA.NumberInput);
NumberInput is based on react-number-format.
It supports most of the props from the NumericFormat component in the original package.
Set loading prop to display a loading indicator. By default, the loader is displayed on the right side of the input.
You can change the position with the loadingPosition prop to 'left' or 'right'. This is useful for async operations like API calls, searches, or validations:
import { useState } from 'react';
import { NumberInput } from '@mantine/core';
function Demo() {
const [value, setValue] = useState<string | number>('');
return <NumberInput value={value} onChange={setValue} />;
}
NumberInput can be used with uncontrolled forms the same way as a native input[type="number"].
Set the name attribute to include number input value in FormData object on form submission.
To control the initial value in uncontrolled forms, use the defaultValue prop.
Example usage of uncontrolled NumberInput with FormData:
import { NumberInput } from '@mantine/core';
function Demo() {
return (
<form
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
console.log('Number input value:', formData.get('quantity'));
}}
>
<NumberInput
label="Enter quantity"
name="quantity"
defaultValue="1"
min="1"
max="100"
/>
<button type="submit">Submit</button>
</form>
);
}
The value, defaultValue, and onChange props can be either string or number. In all cases
when the NumberInput value can be represented as a number, the onChange function is called
with a number (for example 55, 1.28, -100, etc.). But there are several cases when
it is not possible to represent the value as a number:
'''-'Number.MAX_SAFE_INTEGER - 1 or smaller than Number.MIN_SAFE_INTEGER + 1 are represented as strings – '90071992547409910''0.', '0.0', '-0.00', etc.NumberInput also supports bigint values. BigInt mode is inferred from value or defaultValue:
value/defaultValue can be bigint | stringonChange receives bigint | stringmin, max, step, and startValue support bigintallowDecimal/decimal formatting props do not enable decimal parsing)string is still used as a fallback for intermediate states (for example '' or '-').
NumberInput provides two callback props for handling value changes:
onChange: Receives a simplified value (number | string in default mode, bigint | string in BigInt mode). This is the recommended callback for most use cases. The value is a number/bigint when possible, and a string in edge cases (empty input, very large numbers, trailing decimals, intermediate BigInt input states).
onValueChange: Receives the full payload from react-number-format, which includes:
floatValue: The numeric value (or undefined)formattedValue: The formatted string value (with prefix/suffix/separators)value: The raw unformatted string valueUse onValueChange when you need access to the formatted value or metadata about the change (e.g., whether it came from user typing, increment/decrement buttons, or programmatic changes). For simple form handling, onChange is sufficient.
import { NumberInput } from '@mantine/core';
function Demo() {
return (
<NumberInput
prefix="$"
thousandSeparator=","
// onChange receives: 1234
onChange={(value) => console.log('Simple value:', value)}
// onValueChange receives: { floatValue: 1234, formattedValue: '$1,234', value: '1234' }
onValueChange={(payload) => console.log('Full payload:', payload)}
/>
);
}
Set the min and max props to limit the input value:
By default, the value is clamped when the input is blurred. If you set clampBehavior="strict",
it will not be possible to enter a value outside of the min/max range. Note that this option
may cause issues if you have tight min and max, for example min={10} and max={20}.
If you need to disable value clamping entirely, set clampBehavior="none".
Use onMinReached and onMaxReached to call a function when the value hits the min or max boundary.
These callbacks are triggered when the user attempts to increment beyond max or decrement below min
using the controls or keyboard arrows.
import { NumberInput } from '@mantine/core';
function Demo() {
return (
<NumberInput
min={0}
max={100}
onMinReached={() => console.log('Minimum value reached')}
onMaxReached={() => console.log('Maximum value reached')}
/>
);
}
Set selectAllOnFocus to automatically select the entire input value when the field receives focus.
This is useful when you expect users to replace the value rather than edit it:
import { NumberInput } from '@mantine/core';
function Demo() {
return <NumberInput selectAllOnFocus defaultValue={100} />;
}
Set the prefix and suffix props to add a given string to the start or end of the input value:
By default, negative numbers are allowed. Set allowNegative={false} to allow only positive numbers.
By default, decimal numbers are allowed. Set allowDecimal={false} to allow only integers.
The decimalScale controls how many decimal places are allowed:
Set fixedDecimalScale to always display a fixed number of decimal places:
Set decimalSeparator to change the decimal separator character:
Set the thousandSeparator prop to separate thousands with a character. You can control
the grouping logic with thousandsGroupStyle, which accepts: thousand, lakh, wan, none values.
By default, leading zeros are removed when the input loses focus (e.g., 00100 becomes 100).
You can disable this behavior by setting trimLeadingZeroesOnBlur={false}:
By default, the right section is occupied by increment and decrement buttons.
To hide them, set the hideControls prop. You can also use the rightSection prop to render anything
in the right section to replace the default controls.
Set the stepHoldDelay and stepHoldInterval props to define behavior when increment/decrement controls are clicked and held:
You can get a ref with increment and decrement functions to create custom controls: