# NumberField
**Category**: react
**URL**: https://www.heroui.com/docs/react/components/number-field
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(forms)/number-field.mdx
> Number input fields with increment/decrement buttons, validation, and internationalized formatting
***
## Import
```tsx
import { NumberField } from '@heroui/react';
```
### Usage
```tsx
import {Label, NumberField} from "@heroui/react";
export function Basic() {
return (
);
}
```
### Anatomy
```tsx
import {NumberField, Label, Description, FieldError} from '@heroui/react';
export default () => (
)
```
> **NumberField** allows users to enter numeric values with optional increment/decrement buttons. It supports internationalized formatting, validation, and keyboard navigation.
### With Description
```tsx
import {Description, Label, NumberField} from "@heroui/react";
export function WithDescription() {
return (
Enter the width in pixelsValue must be between 0 and 100
);
}
```
### Required Field
```tsx
import {Description, Label, NumberField} from "@heroui/react";
export function Required() {
return (
Rate from 1 to 10
);
}
```
### Validation
Use `isInvalid` together with `FieldError` to surface validation messages.
```tsx
import {FieldError, Label, NumberField} from "@heroui/react";
export function Validation() {
return (
Quantity must be greater than or equal to 0Percentage must be between 0 and 100
);
}
```
### Controlled
Control the value to synchronize with other components or perform custom formatting.
```tsx
"use client";
import {Button, Description, Label, NumberField} from "@heroui/react";
import React from "react";
export function Controlled() {
const [value, setValue] = React.useState(1024);
return (
Current value: {value}
);
}
```
### With Validation
Implement custom validation logic with controlled values.
```tsx
"use client";
import {Description, FieldError, Label, NumberField} from "@heroui/react";
import React from "react";
export function WithValidation() {
const [value, setValue] = React.useState(undefined);
const isInvalid = value !== undefined && (value < 0 || value > 100);
return (
{isInvalid ? (
Percentage must be between 0 and 100
) : (
Enter a value between 0 and 100
)}
);
}
```
### Step Values
Configure increment/decrement step values for precise control.
```tsx
import {Description, Label, NumberField} from "@heroui/react";
export function WithStep() {
return (
Increments by 1Increments by 5Increments by 10
);
}
```
### Format Options
Format numbers as currency, percentages, decimals, or units with internationalization support.
```tsx
import {Description, Label, NumberField} from "@heroui/react";
export function WithFormatOptions() {
return (
Accounting format with EUR currencyStandard USD currency formatPercentage format (0-1, where 0.5 = 50%)Decimal format with 2 decimal placesUnit format with kilograms
);
}
```
### Custom Icons
Customize the increment and decrement button icons.
```tsx
import {Description, Label, NumberField} from "@heroui/react";
export function CustomIcons() {
return (
Custom icon children
);
}
```
### With Chevrons
Use chevron icons in a vertical layout for a different visual style.
```tsx
import {Label, NumberField} from "@heroui/react";
export function WithChevrons() {
return (
);
}
```
### Disabled State
```tsx
import {Description, Label, NumberField} from "@heroui/react";
export function Disabled() {
return (
Enter the width in pixelsValue must be between 0 and 100
);
}
```
### Full Width
```tsx
import {Label, NumberField} from "@heroui/react";
export function FullWidth() {
return (
);
}
```
### Variants
The NumberField component supports two visual variants:
- **`primary`** (default) - Standard styling with shadow, suitable for most use cases
- **`secondary`** - Lower emphasis variant without shadow, suitable for use in Surface components
```tsx
import {Label, NumberField} from "@heroui/react";
export function Variants() {
return (
);
}
```
### In Surface
When used inside a [Surface](/docs/components/surface) component, use `variant="secondary"` to apply the lower emphasis variant suitable for surface backgrounds.
```tsx
import {Description, Label, NumberField, Surface} from "@heroui/react";
export function OnSurface() {
return (
Enter the width in pixelsValue must be between 0 and 100
);
}
```
### Form Example
Complete form integration with validation and submission handling.
```tsx
"use client";
import {Button, Description, FieldError, Form, Label, NumberField, Spinner} from "@heroui/react";
import React from "react";
export function FormExample() {
const [value, setValue] = React.useState(undefined);
const [isSubmitting, setIsSubmitting] = React.useState(false);
const STOCK_AVAILABLE = 3;
const isOutOfStock = value !== undefined && value > STOCK_AVAILABLE;
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (value === undefined || value === null || value < 1 || value > STOCK_AVAILABLE) {
return;
}
setIsSubmitting(true);
// Simulate API call
setTimeout(() => {
console.log("Order submitted:", {quantity: value});
setValue(undefined);
setIsSubmitting(false);
}, 1500);
};
return (
);
}
```
## Related Components
- **Label**: Accessible label for form controls
- **Description**: Helper text for form fields
- **FieldError**: Inline validation messages for form fields
### Custom Render Function
```tsx
"use client";
import {Label, NumberField} from "@heroui/react";
export function CustomRenderFunction() {
return (
}
>
);
}
```
## Styling
### Passing Tailwind CSS classes
```tsx
import {NumberField, Label} from '@heroui/react';
function CustomNumberField() {
return (
);
}
```
### Customizing the component classes
NumberField uses CSS classes that can be customized. Override the component classes to match your design system.
```css
@layer components {
.number-field {
@apply flex flex-col gap-1;
}
/* When invalid, the description is hidden automatically */
.number-field[data-invalid="true"] [data-slot="description"],
.number-field[aria-invalid="true"] [data-slot="description"] {
@apply hidden;
}
.number-field__group {
@apply bg-field text-field-foreground shadow-field rounded-field inline-flex h-9 items-center overflow-hidden border;
}
.number-field__input {
@apply flex-1 rounded-none border-0 bg-transparent px-3 py-2 tabular-nums;
}
.number-field__increment-button,
.number-field__decrement-button {
@apply flex h-full w-10 items-center justify-center rounded-none bg-transparent;
}
}
```
### CSS Classes
- `.number-field` – Root container with minimal styling (`flex flex-col gap-1`)
- `.number-field__group` – Container for input and buttons with border and background styling
- `.number-field__input` – The numeric input field
- `.number-field__increment-button` – Button to increment the value
- `.number-field__decrement-button` – Button to decrement the value
- `.number-field--primary` – Primary variant with shadow (default)
- `.number-field--secondary` – Secondary variant without shadow, suitable for use in surfaces
> **Note:** Child components ([Label](/docs/components/label), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options.
### Interactive States
NumberField automatically manages these data attributes based on its state:
- **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid
- **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true
- **Focus Within**: `[data-focus-within="true"]` - Applied when the input or buttons are focused
- **Focus Visible**: `[data-focus-visible="true"]` - Applied when focus is visible (keyboard navigation)
- **Hovered**: `[data-hovered="true"]` - Applied when hovering over buttons
Additional attributes are available through render props (see NumberFieldRenderProps below).
## API Reference
### NumberField Props
NumberField inherits all props from React Aria's [NumberField](https://react-spectrum.adobe.com/react-aria/NumberField.html) component.
#### Base Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode \| (values: NumberFieldRenderProps) => React.ReactNode` | - | Child components (Label, Group, Input, etc.) or render function. |
| `className` | `string \| (values: NumberFieldRenderProps) => string` | - | CSS classes for styling, supports render props. |
| `style` | `React.CSSProperties \| (values: NumberFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. |
| `fullWidth` | `boolean` | `false` | Whether the number field should take full width of its container |
| `id` | `string` | - | The element's unique identifier. |
| `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the component. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. |
| `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function.|
#### Value Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `number` | - | Current value (controlled). |
| `defaultValue` | `number` | - | Default value (uncontrolled). |
| `onChange` | `(value: number \| undefined) => void` | - | Handler called when the value changes. |
#### Formatting Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `formatOptions` | `Intl.NumberFormatOptions` | - | Options for formatting numbers (currency, percent, decimal, unit). |
| `locale` | `string` | - | Locale for number formatting. |
#### Validation Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isRequired` | `boolean` | `false` | Whether user input is required before form submission. |
| `isInvalid` | `boolean` | - | Whether the value is invalid. |
| `validate` | `(value: number) => ValidationError \| true \| null \| undefined` | - | Custom validation function. |
| `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. |
| `validationErrors` | `string[]` | - | Server-side validation errors. |
#### Range Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `minValue` | `number` | - | Minimum allowed value. |
| `maxValue` | `number` | - | Maximum allowed value. |
| `step` | `number` | `1` | Step value for increment/decrement operations. |
#### State Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isDisabled` | `boolean` | - | Whether the input is disabled. |
| `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. |
#### Form Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `name` | `string` | - | Name of the input element, for HTML form submission. |
| `autoFocus` | `boolean` | - | Whether the element should receive focus on render. |
#### Accessibility Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `aria-label` | `string` | - | Accessibility label when no visible label is present. |
| `aria-labelledby` | `string` | - | ID of elements that label this field. |
| `aria-describedby` | `string` | - | ID of elements that describe this field. |
| `aria-details` | `string` | - | ID of elements with additional details. |
### Composition Components
NumberField works with these separate components that should be imported and used directly:
- **NumberField.Group** - Container for input and buttons
- **NumberField.Input** - The numeric input field
- **NumberField.IncrementButton** - Button to increment the value
- **NumberField.DecrementButton** - Button to decrement the value
- **Label** - Field label component from `@heroui/react`
- **Description** - Helper text component from `@heroui/react`
- **FieldError** - Validation error message from `@heroui/react`
Each of these components has its own props API. Use them directly within NumberField for composition:
```tsx
Enter a value between 0 and 100Value must be between 0 and 100
```
#### NumberField.Group Props
NumberField.Group inherits props from React Aria's [Group](https://react-spectrum.adobe.com/react-aria/Group.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode \| (values: GroupRenderProps) => React.ReactNode` | - | Child components (Input, Buttons) or render function. |
| `className` | `string \| (values: GroupRenderProps) => string` | - | CSS classes for styling. |
#### NumberField.Input Props
NumberField.Input inherits props from React Aria's [Input](https://react-spectrum.adobe.com/react-aria/Input.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | CSS classes for styling. |
| `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the input. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. |
#### NumberField.IncrementButton Props
NumberField.IncrementButton inherits props from React Aria's [Button](https://react-spectrum.adobe.com/react-aria/Button.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode` | `` | Icon or content for the button. Defaults to plus icon. |
| `className` | `string` | - | CSS classes for styling. |
| `slot` | `"increment"` | `"increment"` | Must be set to "increment" (automatically set). |
#### NumberField.DecrementButton Props
NumberField.DecrementButton inherits props from React Aria's [Button](https://react-spectrum.adobe.com/react-aria/Button.html) component.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `children` | `React.ReactNode` | `` | Icon or content for the button. Defaults to minus icon. |
| `className` | `string` | - | CSS classes for styling. |
| `slot` | `"decrement"` | `"decrement"` | Must be set to "decrement" (automatically set). |
### NumberFieldRenderProps
When using render props with `className`, `style`, or `children`, these values are available:
| Prop | Type | Description |
|------|------|-------------|
| `isDisabled` | `boolean` | Whether the field is disabled. |
| `isInvalid` | `boolean` | Whether the field is currently invalid. |
| `isReadOnly` | `boolean` | Whether the field is read-only. |
| `isRequired` | `boolean` | Whether the field is required. |
| `isFocused` | `boolean` | Whether the field is currently focused (DEPRECATED - use `isFocusWithin`). |
| `isFocusWithin` | `boolean` | Whether any child element is focused. |
| `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). |
| `value` | `number \| undefined` | Current value. |
| `minValue` | `number \| undefined` | Minimum allowed value. |
| `maxValue` | `number \| undefined` | Maximum allowed value. |
| `step` | `number` | Step value for increment/decrement. |