NumberInput
A number input with built-in stepper buttons, min / max / step and decimal precision handling, arrow-key stepping, and native form submission.
Installation
Add component
pnpm dlx @elyri/cli@latest add number-inputExamples
Basic
Set the initial value with defaultValue; use the steppers or the up / down arrow keys.
import { NumberInput } from './components/elyri/NumberInput';
export function Example() {
return <NumberInput defaultValue={1} aria-label="Quantity" />;
}Bounds and step
Constrain values with min / max / step; the matching stepper disables at each bound.
import { NumberInput } from './components/elyri/NumberInput';
export function Example() {
return <NumberInput defaultValue={3} min={0} max={5} aria-label="Quantity" />;
}Decimal precision
A fractional step rounds to its own decimal places, avoiding floating point drift.
import { NumberInput } from './components/elyri/NumberInput';
export function Example() {
return <NumberInput defaultValue={0} step={0.1} aria-label="Amount" />;
}Prefix and suffix
Use prefix / suffix for currency symbols, units or icons; the suffix sits between the value and the steppers.
¥
kg
$USD
import { NumberInput } from './components/elyri/NumberInput';
export function Example() {
return (
<div>
<NumberInput prefix="¥" defaultValue={99} step={0.01} aria-label="Price" />
<NumberInput suffix="kg" defaultValue={5} min={0} aria-label="Weight" />
<NumberInput prefix="$" suffix="USD" defaultValue={20} aria-label="Amount" />
</div>
);
}Sizes
Three sizes matching Input: sm / md / lg.
import { NumberInput } from './components/elyri/NumberInput';
export function Example() {
return (
<div>
<NumberInput size="sm" defaultValue={1} aria-label="Small" />
<NumberInput size="lg" defaultValue={3} aria-label="Large" />
</div>
);
}Disabled and invalid
Disabled blocks interaction; invalid sets aria-invalid and a red outline.
import { NumberInput } from './components/elyri/NumberInput';
export function Example() {
return (
<div>
<NumberInput disabled defaultValue={1} aria-label="Disabled" />
<NumberInput invalid defaultValue={1} aria-label="Invalid" />
</div>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | — | Controlled value, null for empty; omit to run uncontrolled |
defaultValue | number | null | null | Initial value when uncontrolled, default null |
onValueChange | (value: number | null) => void | — | Called on change; null when cleared with allowEmpty |
min | number | — | Minimum value |
max | number | — | Maximum value |
step | number | 1 | Step for keyboard and buttons, default 1 |
allowEmpty | boolean | false | Allow clearing to null, default false (blur falls back to the last valid value) |
size | 'sm' | 'md' | 'lg' | 'md' | Size: sm / md / lg |
invalid | boolean | — | Invalid state: red outline plus aria-invalid |
prefix | ReactNode | — | Content rendered before the input |
suffix | ReactNode | — | Content rendered between the value and the steppers |
name | string | — | Form field name, submitted with a native form |
...rest | InputHTMLAttributes | — | Remaining props are forwarded to the native input |