PettyUI/.firecrawl/kobalte.dev-docs-core-components-number-field.md
2026-03-31 21:42:28 +07:00

15 KiB

Number Field

A number input that allow users to input custom number entries with a keyboard.

Import

Copyts
import { NumberField } from "@kobalte/core/number-field";
// or
import { Root, Label, ... } from "@kobalte/core/number-field";
// or (deprecated)
import { NumberField } from "@kobalte/core";
Copyts
import { NumberField } from "@kobalte/core/number-field";
// or
import { Root, Label, ... } from "@kobalte/core/number-field";
// or (deprecated)
import { NumberField } from "@kobalte/core";

Features

  • Follows the WAI ARIA Spinbutton design pattern.
  • Built with a native <input> element.
  • Visual and ARIA labeling support.
  • Required and invalid states exposed to assistive technology via ARIA.
  • Support for description and error message help text linked to the input via ARIA.
  • Syncs with form reset events.
  • Can be controlled or uncontrolled.
  • Supports increment and decrement buttons.
  • Format and localize input number and raw input.
  • Supports mouse wheel event and all keyboard events.
  • Supports browser autofill.

Anatomy

The number field consists of:

  • NumberField: The root container for the number field.
  • NumberField.Label: The label that gives the user information on the number field.
  • NumberField.Input: The native HTML input of the number field, used for display number.
  • NumberField.HiddenInput: The native HTML input of the number field, used for raw number form submition.
  • NumberField.IncrementTrigger: The increment button of the number field.
  • NumberField.DecrementTrigger: The increment button of the number field.
  • NumberField.Description: The description that gives the user more information on the number field.
  • NumberField.ErrorMessage: The error message that gives the user information about how to fix a validation error on number field.
Copytsx
<NumberField>
	<NumberField.Label />
	<NumberField.Input />
	<NumberField.HiddenInput />
	<NumberField.IncrementTrigger />
	<NumberField.DecrementTrigger />
	<NumberField.Description />
	<NumberField.ErrorMessage />
</NumberField>
Copytsx
<NumberField>
	<NumberField.Label />
	<NumberField.Input />
	<NumberField.HiddenInput />
	<NumberField.IncrementTrigger />
	<NumberField.DecrementTrigger />
	<NumberField.Description />
	<NumberField.ErrorMessage />
</NumberField>

Example

Quantity

ArrowArrow

index.tsxstyle.css

Copytsx
import { NumberField } from "@kobalte/core/number-field";
import "./style.css";

function App() {
  return (
    <NumberField class="number-field">
      <NumberField.Label class="number-field__label">
        Quantity
      </NumberField.Label>
      <div class="number-field__group">
        <NumberField.Input class="number-field__input" />
        <NumberField.IncrementTrigger aria-label="Increment" class="number-field__increment"><ArrowUpIcon/></NumberField.IncrementTrigger>
        <NumberField.DecrementTrigger aria-label="Decrement" class="number-field__decrement"><ArrowDownIcon/></NumberField.DecrementTrigger>
      </div>
    </NumberField>
  );
}
Copytsx
import { NumberField } from "@kobalte/core/number-field";
import "./style.css";

function App() {
  return (
    <NumberField class="number-field">
      <NumberField.Label class="number-field__label">
        Quantity
      </NumberField.Label>
      <div class="number-field__group">
        <NumberField.Input class="number-field__input" />
        <NumberField.IncrementTrigger aria-label="Increment" class="number-field__increment"><ArrowUpIcon/></NumberField.IncrementTrigger>
        <NumberField.DecrementTrigger aria-label="Decrement" class="number-field__decrement"><ArrowDownIcon/></NumberField.DecrementTrigger>
      </div>
    </NumberField>
  );
}

Usage

Default value

An initial, uncontrolled value can be provided using the defaultValue prop.

Quantity

ArrowArrow

Copytsx
<NumberField defaultValue={40}>
	<NumberField.Label>Quantity</NumberField.Label>
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
</NumberField>
Copytsx
<NumberField defaultValue={40}>
	<NumberField.Label>Quantity</NumberField.Label>
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
</NumberField>

Controlled value

The value and rawValue props can be used to make the value controlled. It is recommended to only use the rawValue as it is of type number. The onChange event is fired when the user type into the input and receive the new value. The onRawValueChange prop is called when the value changes and receives a number.

Quantity

ArrowArrow

Quantity: 40. Raw: 40.

Copytsx
import { createSignal } from "solid-js";

function ControlledExample() {
	const [value, setValue] = createSignal("40");
	const [rawValue, setRawValue] = createSignal<number>();

	return (
		<>
			<NumberField
				value={value()}
				onChange={setValue}
				rawValue={rawValue()}
				onRawValueChange={setRawValue}
			>
				<NumberField.Label>Quantity</NumberField.Label>
				<div>
					<NumberField.Input />
					<NumberField.IncrementTrigger />
					<NumberField.DecrementTrigger />
				</div>
			</NumberField>
			<p>
				Quantity: {value()}. Raw: {rawValue()}.
			</p>
		</>
	);
}
Copytsx
import { createSignal } from "solid-js";

function ControlledExample() {
	const [value, setValue] = createSignal("40");
	const [rawValue, setRawValue] = createSignal<number>();

	return (
		<>
			<NumberField
				value={value()}
				onChange={setValue}
				rawValue={rawValue()}
				onRawValueChange={setRawValue}
			>
				<NumberField.Label>Quantity</NumberField.Label>
				<div>
					<NumberField.Input />
					<NumberField.IncrementTrigger />
					<NumberField.DecrementTrigger />
				</div>
			</NumberField>
			<p>
				Quantity: {value()}. Raw: {rawValue()}.
			</p>
		</>
	);
}

Description

The NumberField.Description component can be used to associate additional help text with a number field.

Quantity

ArrowArrow

Choose a quantity.

Copytsx
<NumberField>
	<NumberField.Label>Quantity</NumberField.Label>
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
	<NumberField.Description>Choose a quantity.</NumberField.Description>
</NumberField>
Copytsx
<NumberField>
	<NumberField.Label>Quantity</NumberField.Label>
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
	<NumberField.Description>Choose a quantity.</NumberField.Description>
</NumberField>

Error message

The NumberField.ErrorMessage component can be used to help the user fix a validation error. It should be combined with the validationState prop to semantically mark the text field as invalid for assistive technologies.

By default, it will render only when the validationState prop is set to invalid, use the forceMount prop to always render the error message (ex: for usage with animation libraries).

Quantity

ArrowArrow

Hmm, I prefer 40.

Copytsx
import { createSignal } from "solid-js";

function ErrorMessageExample() {
	const [rawValue, setRawValue] = createSignal<number>();

	return (
		<NumberField
			onRawValueChange={setRawValue}
			validationState={rawValue() !== 40 ? "invalid" : "valid"}
		>
			<NumberField.Label>Quantity</NumberField.Label>
			<div>
				<NumberField.Input />
				<NumberField.IncrementTrigger />
				<NumberField.DecrementTrigger />
			</div>
			<NumberField.ErrorMessage>Hmm, I prefer 40.</NumberField.ErrorMessage>
		</NumberField>
	);
}
Copytsx
import { createSignal } from "solid-js";

function ErrorMessageExample() {
	const [rawValue, setRawValue] = createSignal<number>();

	return (
		<NumberField
			onRawValueChange={setRawValue}
			validationState={rawValue() !== 40 ? "invalid" : "valid"}
		>
			<NumberField.Label>Quantity</NumberField.Label>
			<div>
				<NumberField.Input />
				<NumberField.IncrementTrigger />
				<NumberField.DecrementTrigger />
			</div>
			<NumberField.ErrorMessage>Hmm, I prefer 40.</NumberField.ErrorMessage>
		</NumberField>
	);
}

HTML forms

The number field name prop along with <NumberField.HiddenInput/> can be used for integration with HTML forms. Only the raw value is passed to the form.

If the formatted value is wanted (unrecommended) set the name attribute on <NumberField.Input/>.

Quantity

ArrowArrow

ResetSubmit

Copytsx
function HTMLFormExample() {
	const onSubmit = (e: SubmitEvent) => {
		// handle form submission.
	};

	return (
		<form onSubmit={onSubmit}>
			<NumberField name="quantity">
				<NumberField.Label>Quantity</NumberField.Label>
				<NumberField.HiddenInput />
				<div>
					<NumberField.Input />
					<NumberField.IncrementTrigger />
					<NumberField.DecrementTrigger />
				</div>
			</NumberField>
			<div>
				<button type="reset">Reset</button>
				<button type="submit">Submit</button>
			</div>
		</form>
	);
}
Copytsx
function HTMLFormExample() {
	const onSubmit = (e: SubmitEvent) => {
		// handle form submission.
	};

	return (
		<form onSubmit={onSubmit}>
			<NumberField name="quantity">
				<NumberField.Label>Quantity</NumberField.Label>
				<NumberField.HiddenInput />
				<div>
					<NumberField.Input />
					<NumberField.IncrementTrigger />
					<NumberField.DecrementTrigger />
				</div>
			</NumberField>
			<div>
				<button type="reset">Reset</button>
				<button type="submit">Submit</button>
			</div>
		</form>
	);
}

Triggers

The number field supports optional increment/decrement triggers that are easily customizable.

Quantity

-+

Copytsx
<NumberField>
	<NumberField.Label>Quantity</NumberField.Label>
	<div>
		<NumberField.DecrementTrigger class="custom-trigger">-</NumberField.DecrementTrigger>
		<NumberField.Input />
		<NumberField.IncrementTrigger class="custom-trigger">+</NumberField.IncrementTrigger>
	</div>
</NumberField>
Copytsx
<NumberField>
	<NumberField.Label>Quantity</NumberField.Label>
	<div>
		<NumberField.DecrementTrigger class="custom-trigger">-</NumberField.DecrementTrigger>
		<NumberField.Input />
		<NumberField.IncrementTrigger class="custom-trigger">+</NumberField.IncrementTrigger>
	</div>
</NumberField>

Format

The value of the number field component can be formatted based on the locale with the I18NProvider and formatOptions. For more information see React Spectrum NumberField.

Price

ArrowArrow

Copytsx
<NumberField formatOptions={{ style: "currency", currency: "USD" }} defaultValue={4}>
	<NumberField.Label>Price</NumberField.Label>
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
</NumberField>
Copytsx
<NumberField formatOptions={{ style: "currency", currency: "USD" }} defaultValue={4}>
	<NumberField.Label>Price</NumberField.Label>
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
</NumberField>

Autofill

The number field supports autofill through NumberField.HiddenInput.

Copytsx
<NumberField>
	<NumberField.Label>Quantity</NumberField.Label>
	<NumberField.HiddenInput />
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
</NumberField>
Copytsx
<NumberField>
	<NumberField.Label>Quantity</NumberField.Label>
	<NumberField.HiddenInput />
	<div>
		<NumberField.Input />
		<NumberField.IncrementTrigger />
		<NumberField.DecrementTrigger />
	</div>
</NumberField>

API Reference

NumberField

NumberField is equivalent to the Root import from @kobalte/core/number-field (and deprecated NumberField.Root).

Prop Description
value `string
defaultValue `string
onChange (value: string) => void
Event handler called when the value of the NumberField changes as a formatted value.
rawValue number
The controlled raw value of the number field.
onRawValueChange (value: number) => void
Event handler called when the value of the NumberField changes as a number.
minValue number
The smallest value allowed in the number field, defaults to Number.MIN_SAFE_INTEGER.
maxValue number
The largest value allowed in the number field, defaults to Number.MAX_SAFE_INTEGER.
step number
Increment/Decrement step when using the triggers or the arrows on keyboard in the number field.
largeStep number
Increment/Decrement step when using the Page UP/Down keys in the number field, defaults 10 * step.
changeOnWheel boolean
Whether to increment/decrement on wheel scroll inside the number field.
format boolean
Whether to format the input value.
formatOptions Intl.NumberFormatOptions
Formating options for the value of the number field.
allowedInput RegExp
Allowed input characters in the number field (only prevents onInput, not paste), defaults to locale and format characters.
name string
The name of the NumberField.HiddenInput of the number field, used when submitting an HTML form. See MDN.
validationState `'valid'
required boolean
Whether the user must fill the number field before the owning form can be submitted.
disabled boolean
Whether the number field is disabled.
readOnly boolean
Whether the number field items can be selected but not changed by the user.
Data attribute Description
data-valid Present when the number field is valid according to the validation rules.
data-invalid Present when the number field is invalid according to the validation rules.
data-required Present when the user must fill the number field before the owning form can be submitted.
data-disabled Present when the number field is disabled.
data-readonly Present when the number field is read only.

NumberField.Label, NumberField.Input, NumberField.HiddenInput, NumberField.Description and NumberField.ErrorMesssage share the same data-attributes.

NumberField.ErrorMessage

Prop Description
forceMount boolean
Used to force mounting when more control is needed. Useful when controlling animation with SolidJS animation libraries.

Rendered elements

Component Default rendered element
NumberField div
NumberField.Label label
NumberField.Input input
NumberField.HiddenInput input
NumberField.IncrementTrigger button
NumberField.DecrementTrigger button
NumberField.Description div
NumberField.ErrorMessage div

Previous←Navigation MenuNextPagination→