Number Field
Web/MobileA labeled number field with icons, stepper arrows, description, and error. inputMode is locked to numeric; values always display as Persian digits.
Installation
pnpm dlx cubix-ui@latest add number-field --base ariaUsage
import {
NumberField,
NumberFieldControl,
NumberFieldDescription,
NumberFieldInput,
NumberFieldLabel,
NumberFieldStepper,
} from "@/components/cubix/number-field"
<NumberField className="w-full max-w-sm">
<NumberFieldLabel>تعداد</NumberFieldLabel>
<NumberFieldControl>
<Icon data-icon="inline-start" />
<NumberFieldInput defaultValue="۱۲" placeholder="۰" />
<NumberFieldStepper />
</NumberFieldControl>
<NumberFieldDescription>
فقط عدد وارد کنید. با فلشها مقدار را کم یا زیاد کنید.
</NumberFieldDescription>
</NumberField>
Composition
Same composition as Text Field. Place NumberFieldStepper inside the control for up and down arrows that change the value. NumberFieldInput uses inputMode="numeric" with type="text" so values always display as Persian digits; Latin and Arabic-Indic digits are converted as they are typed or pasted.
NumberField
├── NumberFieldLabel
├── NumberFieldControl
│ ├── Icon data-icon="inline-start" | "inline-end"
│ ├── NumberFieldInput
│ └── NumberFieldStepper
├── NumberFieldDescription
└── NumberFieldErrorAccessibility
ArrowUp and ArrowDown on the input step the value by step and respect min and max, so the stepper buttons stay out of the tab order without losing keyboard access. The buttons are named by incrementLabel and decrementLabel. NumberFieldDescription and NumberFieldError are announced through aria-describedby.
Examples
Stepper
NumberFieldStepper renders up and down arrows that increase or decrease the value. Set min, max, and step on the input to bound both the arrows and the keyboard.
Description
Add helper text below the input for format hints or guidance.
Invalid
Set invalid on the root to apply destructive styles and show NumberFieldError.
Disabled
Disable the field to block the input and stepper. The control uses a muted fill; label and description stay readable.
Sizes
Two heights ship by default: default (40px) and lg (48px). Use className for any other size.
Icons
Place icons inside NumberFieldControl with data-icon like Button so spacing follows the reading direction.
In a form
Set name on the root so the value is submitted with the form, and pair the field with Cubix Button.
Custom styling
Every part accepts a className merged with the shipped cn helper. Here the field uses a filled surface instead of the default outline.
API Reference
Note: Parts render data-slot attributes (number-field, number-field-label, number-field-control, number-field-input, number-field-stepper, number-field-increment, number-field-decrement, number-field-description, number-field-error) for targeting in tests and parent selectors. Use the same props on Base UI, React Aria, and Radix.
NumberField
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "default" | "lg" | "default" | Height for the input: default 40px, lg 48px. Inherited by NumberFieldInput and NumberFieldControl unless overridden. Use className for other heights. |
| disabled | boolean | false | Disables the field and prevents interaction. Forwarded to the control on every base. |
| invalid | boolean | false | Marks the field as invalid and shows NumberFieldError when present. |
| name | string | - | Identifies the field when a form is submitted. Forwarded to the input on every base. |
| className | string | - | Additional Tailwind classes merged with the root styles (last one wins). |
NumberFieldControl
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "default" | "lg" | - | Overrides the size from NumberField. Icon inset and height match the default and lg sizes. |
| children | React.ReactNode | - | Wrap NumberFieldInput with icons marked data-icon="inline-start" or "inline-end" (same as Button), and optionally NumberFieldStepper. |
| className | string | - | Additional Tailwind classes merged with the control styles (last one wins). |
NumberFieldInput
| Prop | Type | Default | Description |
|---|---|---|---|
| type | "text" | "text" | Always displays Persian digits (۰-۹). Latin or Arabic-Indic digits typed or pasted are converted. inputMode is always numeric and spellCheck is always false. |
| size | "default" | "lg" | - | Overrides the size from NumberField. Default 40px, lg 48px. Use className for other heights. |
| inputMode | "numeric" | "numeric" | Locked to numeric so mobile keyboards show a number pad. |
| min | number | string | - | Minimum value used by NumberFieldStepper when decreasing. |
| max | number | string | - | Maximum value used by NumberFieldStepper when increasing. |
| step | number | string | 1 | Step size used by ArrowUp / ArrowDown on the input and by NumberFieldStepper unless the stepper overrides it. |
| placeholder | string | - | Hint text shown when the input is empty. |
| className | string | - | Additional Tailwind classes merged with the input styles (last one wins). |
| ...props | Omit<React.ComponentProps<'input'>, 'type' | 'inputMode' | 'spellCheck'> | - | Native input attributes (value, onChange, name, required, ...) are forwarded. type, inputMode, and spellCheck stay locked for numeric entry. |
NumberFieldStepper
| Prop | Type | Default | Description |
|---|---|---|---|
| step | number | - | Overrides the input step attribute for the arrow buttons only. Set step on NumberFieldInput to keep keyboard and buttons in sync. Defaults to 1 when neither is set. |
| incrementLabel | string | "افزایش" | Accessible name for the increase button. |
| decrementLabel | string | "کاهش" | Accessible name for the decrease button. |
| className | string | - | Additional Tailwind classes merged with the stepper styles (last one wins). |
NumberFieldLabel / Description / Error
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional Tailwind classes merged with the part styles (last one wins). |
| ...props | HTML attributes | - | Native attributes for the rendered element are forwarded. |