react-hook-form-bound numeric field. Renders the @uxf/ui/text-input primitive with type="number" and stores a parsed number, managing the input's value, isInvalid, and helperText from form state.
Use @uxf/form/number-input for a numeric field inside a @uxf/form form when the form value must be a number (not a string). It normalizes typed input (comma → dot decimal separator, strips spaces/thousands separators), blocks non-numeric keystrokes, and optionally clamps decimal places. There is no same-named @uxf/ui twin; for a plain text field use @uxf/ui/text-input.
import { Form } from "@uxf/form/form";
import { NumberInput } from "@uxf/form/number-input";
import { useForm } from "react-hook-form";
interface FormData {
amount: number | null;
}
function Example() {
const formApi = useForm<FormData>({ defaultValues: { amount: null } });
return (
<Form formApi={formApi} id="example" onSubmit={(values) => console.log(values)}>
<NumberInput control={formApi.control} decimalPlaces={2} label="Amount" max={50} name="amount" />
</Form>
);
}
Value is number | null (NumberInputValue) — empty/unparseable input becomes null.
NumberInputProps<FormData> = ControlProps<FormData> + the visual props of the @uxf/ui/text-input twin (minus the ones this field manages: inputMode, isFocused, isInvalid, maxLength, minLength, name, onChange, value, type) + the props below.
| Prop | Type | Default | Description |
|---|---|---|---|
control |
Control<FormData> |
— | Required. The control from useForm. |
name |
FieldPath<FormData> |
— | Required. Field path in the form values. |
rules |
RegisterOptions |
— | Extra react-hook-form rules; merged with the built-in validation below. |
shouldUnregister |
boolean |
— | Unregister the field (drop its value) on unmount. |
decimalPlaces |
number |
— | Max fraction digits. Set: parses with parseFloat, trims extra decimals while typing, rounds on paste, sets inputMode="decimal" and a matching step. Unset: parses with parseInt (integers only), inputMode="numeric". |
min / max |
number |
— | Bounds enforced by the built-in validMinNumber / validMaxNumber validators; also forwarded to the twin. |
minMessage / maxMessage |
string |
localized | Override the min / max validation messages. |
isRequired |
boolean |
false |
Adds a required rule and the required indicator. |
requiredMessage |
string |
localized | Message for the required rule. |
onChange |
(value: number | null, event) => void |
— | Called after the field value updates. |
All other props (label, placeholder, size, variant, helperText, leftAddon/rightAddon/leftElement/rightElement, step, autoComplete, …) are forwarded to the twin — see @uxf/ui/text-input.
isRequired adds a required rule (requiredMessage to override; key uxf-form-number-input:validation.required).min / max add value-bound checks; messages (uxf-form-number-input:validation.min-value / max-value) interpolate {{min}}/{{max}} and are overridable via minMessage / maxMessage.rules (a function validate is merged in under the custom key); the field-level error is shown as the twin's helperText and sets isInvalid.Form — it reads the form context (formId, and inherits isDisabled / isReadOnly) and needs a react-hook-form control.@uxf/ui/text-input, so include that component's stylesheet(s) and the @uxf/ui token layer — see @uxf/ui/text-input.@uxf/ui/text-input