Number field
A compact stepper with decrement and increment buttons
import {
NumberField,
NumberFieldDecrement,
NumberFieldGroup,
NumberFieldIncrement,
NumberFieldInput,
} from "@nyte-ai/ui/number-field";For a small bounded value, such as a font size.
Usage
- Both value callbacks receive
nullwhen the input is cleared. - Save in
onValueCommitted. It fires when the user leaves the input, releases a button, or presses an arrow key, not on every keystroke. - The buttons default to "−" and "+". Pass children to replace them.
Anatomy
<NumberField>
<NumberFieldGroup>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldGroup>
</NumberField>Examples
<NumberField defaultValue={13} min={12} max={16}>
<NumberFieldGroup>
<NumberFieldDecrement />
<NumberFieldInput aria-label="UI font size" />
<NumberFieldIncrement />
</NumberFieldGroup>
</NumberField><NumberField
defaultValue={settings.uiFontSize}
min={12}
max={16}
onValueCommitted={(uiFontSize) => {
if (uiFontSize !== null) save({ uiFontSize });
}}
>
…
</NumberField>Props
Styled parts add xstyle, and their className and style take plain values, not functions of
state. See Theming. Each sets data-slot to its kebab-case name,
such as number-field-input. NumberField passes through Base UI.
The reference tables below come from Base UI, MIT, © Material-UI SAS.
NumberField
Groups all parts of the number field and manages its state.
Renders a <div> element.
Root Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | - | Identifies the field when a form is submitted. |
| defaultValue | number | - | The uncontrolled value of the field when it's initially rendered. To render a controlled number field, use the value prop instead. |
| value | number | null | - | The raw numeric value of the field. |
| onValueChange | ((value: number | null, eventDetails: NumberField.Root.ChangeEventDetails) => void) | - | Callback fired when the number value changes. The eventDetails.reason indicates what triggered the change: 'input-change' for parseable typing or programmatic text updates'input-clear' when the field becomes empty'input-blur' when formatting (and clamping, if enabled) occurs on blur'input-paste' for paste interactions'keyboard' for arrow-key/Home/End stepping (typing digits uses 'input-change'/'input-clear')'increment-press' / 'decrement-press' for button presses on the increment and decrement controls'wheel' for wheel-based scrubbing'scrub' for scrub area drags |
| onValueCommitted | ((value: number | null, eventDetails: NumberField.Root.CommitEventDetails) => void) | - | Callback function that is fired when the value is committed.
It runs later than onValueChange, when: The input is blurred after typing a value.The pointer is released after scrubbing or pressing the increment/decrement buttons. It runs simultaneously with onValueChange when interacting with the keyboard or the
mouse wheel. Warning: This is a generic event not a change event. |
| allowOutOfRange | boolean | false | When true, direct text entry may be outside the min/max range without clamping,
so native range underflow/overflow validation can occur.
Step-based interactions (keyboard arrows, buttons, wheel, scrub) still clamp. |
| form | string | - | Identifies the form that owns the hidden input. Useful when the number field is rendered outside the form. |
| locale | Intl.LocalesArgument | - | The locale of the input element. Defaults to the user's runtime locale. |
| snapOnStep | boolean | false | Whether the value should snap to the nearest step when incrementing or decrementing. |
| step | number | 'any' | 1 | Amount to increment and decrement with the buttons and arrow keys, or to scrub with pointer movement in the scrub area.
To always enable step validation on form submission, specify the min prop explicitly in conjunction with this prop.
Specify step="any" to always disable step validation; interactive stepping then uses a base amount of 1, while the alt and shift keys still step by smallStep and largeStep. |
| smallStep | number | 0.1 | The small step value of the input element when incrementing while the alt key is held.
Snaps to multiples of this value when snapOnStep is enabled. |
| largeStep | number | 10 | The large step value of the input element when incrementing while the shift key is held.
Snaps to multiples of this value when snapOnStep is enabled. |
| min | number | - | The minimum value of the input element. |
| max | number | - | The maximum value of the input element. |
| allowWheelScrub | boolean | false | Whether to allow the user to scrub the input value with the mouse wheel while focused and hovering over the input. |
| format | Intl.NumberFormatOptions | - | Options to format the input value. |
| disabled | boolean | false | Whether the component should ignore user interaction. |
| readOnly | boolean | false | Whether the user should be unable to change the field value. |
| required | boolean | false | Whether the user must enter a value before submitting a form. |
| inputRef | React.Ref<HTMLInputElement> | - | A ref to access the hidden input element. |
| id | string | - | The id of the input element. |
| className | string | ((state: NumberField.Root.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: NumberField.Root.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: NumberField.Root.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Root Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-disabled | - | Present when the number field is disabled. |
| data-readonly | - | Present when the number field is readonly. |
| data-required | - | Present when the number field is required. |
| data-valid | - | Present when the number field is in a valid state (when wrapped in Field.Root). |
| data-invalid | - | Present when the number field is in an invalid state (when wrapped in Field.Root). |
| data-dirty | - | Present when the number field's value has changed (when wrapped in Field.Root). |
| data-touched | - | Present when the number field has been touched (when wrapped in Field.Root). |
| data-filled | - | Present when the number field is filled (when wrapped in Field.Root). |
| data-focused | - | Present when the number field is focused (when wrapped in Field.Root). |
| data-scrubbing | - | Present while scrubbing. |
NumberFieldGroup
Groups the input with the increment and decrement buttons.
Renders a <div> element.
Group Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | ((state: NumberField.Group.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: NumberField.Group.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: NumberField.Group.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Group Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-disabled | - | Present when the number field is disabled. |
| data-readonly | - | Present when the number field is readonly. |
| data-required | - | Present when the number field is required. |
| data-valid | - | Present when the number field is in a valid state (when wrapped in Field.Root). |
| data-invalid | - | Present when the number field is in an invalid state (when wrapped in Field.Root). |
| data-dirty | - | Present when the number field's value has changed (when wrapped in Field.Root). |
| data-touched | - | Present when the number field has been touched (when wrapped in Field.Root). |
| data-filled | - | Present when the number field is filled (when wrapped in Field.Root). |
| data-focused | - | Present when the number field is focused (when wrapped in Field.Root). |
| data-scrubbing | - | Present while scrubbing. |
NumberFieldDecrement
A stepper button that decreases the field value when clicked.
Renders a <button> element.
Decrement Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| nativeButton | boolean | true | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>). |
| className | string | ((state: NumberField.Decrement.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: NumberField.Decrement.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: NumberField.Decrement.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Decrement Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-disabled | - | Present when the number field is disabled. |
| data-readonly | - | Present when the number field is readonly. |
| data-required | - | Present when the number field is required. |
| data-valid | - | Present when the number field is in a valid state (when wrapped in Field.Root). |
| data-invalid | - | Present when the number field is in an invalid state (when wrapped in Field.Root). |
| data-dirty | - | Present when the number field's value has changed (when wrapped in Field.Root). |
| data-touched | - | Present when the number field has been touched (when wrapped in Field.Root). |
| data-filled | - | Present when the number field is filled (when wrapped in Field.Root). |
| data-focused | - | Present when the number field is focused (when wrapped in Field.Root). |
| data-scrubbing | - | Present while scrubbing. |
NumberFieldInput
The native input control in the number field.
Renders an <input> element.
Input Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| aria-roledescription | string | 'Number field' | A user-friendly description of the input's role for assistive tech. This is a role
description, not an accessible name — use Field.Label or aria-label to name the control. |
| className | string | ((state: NumberField.Input.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: NumberField.Input.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, state: NumberField.Input.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Input Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-disabled | - | Present when the number field is disabled. |
| data-readonly | - | Present when the number field is readonly. |
| data-required | - | Present when the number field is required. |
| data-valid | - | Present when the number field is in a valid state (when wrapped in Field.Root). |
| data-invalid | - | Present when the number field is in an invalid state (when wrapped in Field.Root). |
| data-dirty | - | Present when the number field's value has changed (when wrapped in Field.Root). |
| data-touched | - | Present when the number field has been touched (when wrapped in Field.Root). |
| data-filled | - | Present when the number field is filled (when wrapped in Field.Root). |
| data-focused | - | Present when the number field is focused (when wrapped in Field.Root). |
| data-scrubbing | - | Present while scrubbing. |
NumberFieldIncrement
A stepper button that increases the field value when clicked.
Renders a <button> element.
Increment Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| nativeButton | boolean | true | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>). |
| className | string | ((state: NumberField.Increment.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: NumberField.Increment.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: NumberField.Increment.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Increment Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-disabled | - | Present when the number field is disabled. |
| data-readonly | - | Present when the number field is readonly. |
| data-required | - | Present when the number field is required. |
| data-valid | - | Present when the number field is in a valid state (when wrapped in Field.Root). |
| data-invalid | - | Present when the number field is in an invalid state (when wrapped in Field.Root). |
| data-dirty | - | Present when the number field's value has changed (when wrapped in Field.Root). |
| data-touched | - | Present when the number field has been touched (when wrapped in Field.Root). |
| data-filled | - | Present when the number field is filled (when wrapped in Field.Root). |
| data-focused | - | Present when the number field is focused (when wrapped in Field.Root). |
| data-scrubbing | - | Present while scrubbing. |
Accessibility
- Name
NumberFieldInputwitharia-labelor a label. - Arrow Up and Arrow Down step the value. Home and End jump to
minandmaxwhen set. - Alt with an arrow steps by
smallStep, Shift bylargeStep. - The group shows the focus outline while anything inside it has focus.