Installation
Complete project setup first. Your configuration
must select react/base and include your Design System ID.
pnpm exec frontfriend download number-field -f react --primitive baseReview dependencies reported by the downloader and keep your source changes in version control.
Usage
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldInput,
NumberFieldIncrement,
} from "@/components/ui/number-field";
import * as React from "react";
export default function NumberFieldExample() {
const [value, setValue] = React.useState<number | undefined>(
12,
);
return (
<NumberField
min={0} max={100} step={1} disabled={false}
value={value}
onValueChange={setValue}
className="w-48"
>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
);
} Subcomponents
NumberField— root; owns the value,min/max/stepand disabled stateNumberFieldContent— positions the input against the steppersNumberFieldInput— the spinbutton; ArrowUp/Down step, PageUp/Down step by 10, Home/End jump to the boundsNumberFieldIncrement/NumberFieldDecrement— steppers; auto-disable at the bound and repeat on press-and-hold
Examples
Default
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldInput,
NumberFieldIncrement,
} from "@/components/ui/number-field";
<NumberField defaultValue={12} className="w-40">
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>; Min Max Step
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldInput,
NumberFieldIncrement,
} from "@/components/ui/number-field";
<NumberField min={0} max={10} step={2} defaultValue={4} className="w-40">
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>; Disabled
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldInput,
NumberFieldIncrement,
} from "@/components/ui/number-field";
<NumberField defaultValue={12} disabled className="w-40">
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>; Invalid
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldInput,
NumberFieldIncrement,
} from "@/components/ui/number-field";
<NumberField defaultValue={12} className="w-40">
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput aria-invalid />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>; Formatted
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldInput,
NumberFieldIncrement,
} from "@/components/ui/number-field";
<NumberField
defaultValue={1234.5}
step={0.5}
formatOptions={{ style: "currency", currency: "EUR" }}
className="w-48"
>
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>; API reference
Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Base UI.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | number | — | |
disabled | boolean | — | |
disableWheelChange | boolean | — | |
formatOptions | Intl.NumberFormatOptions | — | |
invertWheelChange | boolean | — | |
locale | string | — | |
max | number | — | |
min | number | — | |
name | string | — | |
onValueChange | (value: number | undefined) => void | — | |
required | boolean | — | |
step | number | — | |
stepSnapping | boolean | — | |
value | number | null | — |
Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.