Number Input
Used to enter a number, and increment or decrement the value using stepper buttons.
import { NumberInput } from '@saas-ui/react'
export const NumberInputBasic = () => {
return <NumberInput defaultValue="10" width="200px" />
}
Anatomy
import { NumberInput } from '@saas-ui/react/number-input'
<NumberInput name="number" />
Examples
Sizes
Use the size
prop to change the size of the number input.
import { For, Stack } from '@chakra-ui/react'
import { NumberInput } from '@saas-ui/react'
export const NumberInputWithSizes = () => {
return (
<Stack gap="5" width="200px">
<For each={['xs', 'sm', 'md', 'lg']}>
{(size) => <NumberInput size={size} key={size} defaultValue="10" />}
</For>
</Stack>
)
}
Formatting
Use the formatOptions
prop to format the number input value. The value of this
maps to Intl.NumberFormatOptions
and is applied based on the current locale.
import { Stack } from '@chakra-ui/react'
import { NumberInput } from '@saas-ui/react'
export const NumberInputWithFormatOptions = () => {
return (
<Stack gap="5" maxW="200px">
<NumberInput
defaultValue="5"
step={0.01}
formatOptions={{
style: 'percent',
}}
/>
<NumberInput
defaultValue="45"
formatOptions={{
style: 'currency',
currency: 'EUR',
currencyDisplay: 'code',
currencySign: 'accounting',
}}
/>
<NumberInput
defaultValue="4"
formatOptions={{
style: 'unit',
unit: 'inch',
unitDisplay: 'long',
}}
/>
</Stack>
)
}
Min and Max
Use the min
and max
props to set the minimum and maximum values of the
number input.
If value entered is less than min
or greater than max
, the value will be
clamped to the nearest boundary on blur, or enter key press.
import { NumberInput } from '@saas-ui/react'
export const NumberInputWithMinMax = () => {
return <NumberInput width="200px" defaultValue="10" min={5} max={50} />
}
Step
Use the step
prop to change the increment or decrement interval of the number
input.
import { NumberInput } from '@saas-ui/react'
export const NumberInputWithStep = () => {
return <NumberInput maxW="200px" defaultValue="2" step={3} />
}
Controlled
Use the value
and onValueChange
props to control the value of the number
input.
'use client'
import { useState } from 'react'
import { NumberInput } from '@saas-ui/react'
export const NumberInputControlled = () => {
const [value, setValue] = useState('10')
return (
<NumberInput
maxW="200px"
value={value}
onValueChange={(e) => setValue(e.value)}
/>
)
}
Mouse Wheel
Use the allowMouseWheel
prop to enable or disable the mouse wheel to change
import { NumberInput } from '@saas-ui/react'
export const NumberInputWithMouseWheel = () => {
return <NumberInput defaultValue="10" width="200px" allowMouseWheel />
}
Disabled
Use the disabled
prop to disable the number input.
import { NumberInput } from '@saas-ui/react'
export const NumberInputWithDisabled = () => {
return <NumberInput defaultValue="10" width="200px" disabled />
}
Invalid
Use the Field
component and pass the invalid
prop to indicate that the
number input is invalid.
import { Field, NumberInput } from '@saas-ui/react'
export const NumberInputWithInvalid = () => {
return (
<Field.Root invalid>
<Field.Label>Enter Number</Field.Label>
<NumberInput defaultValue="10" width="200px" />
<Field.ErrorText>The entry is invalid</Field.ErrorText>
</Field.Root>
)
}
Helper Text
Use the Field
component and pass the helperText
prop to add helper text to
the number input.
import { Field, NumberInput } from '@saas-ui/react'
export const NumberInputWithField = () => {
return (
<Field.Root width="200px">
<Field.Label>Enter Number</Field.Label>
<NumberInput />
<Field.HelperText>Enter a number between 1 and 10</Field.HelperText>
</Field.Root>
)
}
Hook Form
Here is an example of how to use the NumberInput
component with
react-hook-form
.
'use client'
import { Button } from '@chakra-ui/react'
import { zodResolver } from '@hookform/resolvers/zod'
import { Field, NumberInput } from '@saas-ui/react'
import { Controller, useForm } from 'react-hook-form'
import { z } from 'zod'
const formSchema = z.object({
number: z.string({ message: 'Number is required' }),
})
type FormValues = z.infer<typeof formSchema>
export const NumberInputWithHookForm = () => {
const {
control,
handleSubmit,
formState: { errors },
} = useForm<FormValues>({
resolver: zodResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
<form onSubmit={onSubmit}>
<Field.Root invalid={!!errors.number}>
<Field.Label>Number</Field.Label>
<Controller
name="number"
control={control}
render={({ field }) => (
<NumberInput
disabled={field.disabled}
name={field.name}
value={field.value}
onValueChange={({ value }) => {
field.onChange(value)
}}
onBlur={field.onBlur}
/>
)}
/>
<Field.ErrorText>{errors.number?.message}</Field.ErrorText>
</Field.Root>
<Button size="sm" type="submit" mt="4">
Submit
</Button>
</form>
)
}
Props
Root
Prop | Default | Type |
---|---|---|
allowOverflow | true | boolean Whether to allow the value overflow the min/max range |
clampValueOnBlur | true | boolean Whether to clamp the value when the input loses focus (blur) |
focusInputOnChange | true | boolean Whether to focus input when the value changes |
inputMode | '\'decimal\'' | 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 |
locale | '\'en-US\'' | string The current locale. Based on the BCP 47 definition. |
max | 'Number.MAX_SAFE_INTEGER' | number The maximum value of the number input |
min | 'Number.MIN_SAFE_INTEGER' | number The minimum value of the number input |
pattern | '\'[0-9]*(.[0-9]+)?\'' | string The pattern used to check the <input> element's value against |
spinOnPress | true | boolean Whether to spin the value when the increment/decrement button is pressed |
step | '1' | number The amount to increment or decrement the value by |
colorPalette | 'gray' | 'gray' | 'zinc' | 'neutral' | 'stone' | 'red' | 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'violet' | 'purple' | 'fuchsia' | 'pink' | 'rose' | 'presence' | 'status' | 'sidebar' | 'sidebar.accent' | 'accent' | 'slate' The color palette of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg' The size of the component |
variant | 'outline' | 'outline' | 'subtle' | 'flushed' The variant of the component |
allowMouseWheel | boolean Whether to allow mouse wheel to change the value | |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
defaultValue | string The initial value of the input when rendered. Use when you don't need to control the value of the input. | |
disabled | boolean Whether the number input is disabled. | |
form | string The associate form of the input element. | |
formatOptions | NumberFormatOptions The options to pass to the `Intl.NumberFormat` constructor | |
id | string The unique identifier of the machine. | |
ids | Partial<{
root: string
label: string
input: string
incrementTrigger: string
decrementTrigger: string
scrubber: string
}> The ids of the elements in the number input. Useful for composition. | |
invalid | boolean Whether the number input value is invalid. | |
name | string The name attribute of the number input. Useful for form submission. | |
onFocusChange | (details: FocusChangeDetails) => void Function invoked when the number input is focused | |
onValueChange | (details: ValueChangeDetails) => void Function invoked when the value changes | |
onValueInvalid | (details: ValueInvalidDetails) => void Function invoked when the value overflows or underflows the min/max range | |
readOnly | boolean Whether the number input is readonly | |
required | boolean Whether the number input is required | |
translations | IntlTranslations Specifies the localized strings that identifies the accessibility elements and their states | |
value | string The controlled value of the input | |
as | React.ElementType The underlying element to render. | |
unstyled | boolean Whether to remove the component's style. |