NumberField Components
The NumberField namespace exports headless compound components that handle all
wiring internally via React Context. No prop drilling, no ref management.
import { NumberField } from "raqam";Component tree
Section titled âComponent treeâ<NumberField.Root ...> {/* context provider + state */} <NumberField.Label /> {/* <label> */} <NumberField.Group> {/* <div role="group"> */} <NumberField.Decrement /> {/* <button> */} <NumberField.Input /> {/* <input type="text"> */} <NumberField.Increment /> {/* <button> */} </NumberField.Group> <NumberField.ScrubArea> {/* drag-to-change wrapper */} <NumberField.ScrubAreaCursor /> {/* custom pointer cursor */} </NumberField.ScrubArea> <NumberField.Formatted /> {/* read-only formatted display */} <NumberField.Description /> {/* helper text */} <NumberField.ErrorMessage /> {/* validation error */} <NumberField.HiddenInput /> {/* form submission value */}</NumberField.Root>Only Root and Input are required. All others are optional.
NumberField.Root
Section titled âNumberField.RootâContext provider. Accepts all UseNumberFieldStateOptions props plus:
| Prop | Type | Description |
|---|---|---|
locale | string | BCP 47 locale. Defaults to the current runtime locale. |
formatOptions | Intl.NumberFormatOptions | Number format configuration. |
value / defaultValue | number | null | Controlled/uncontrolled value. |
onChange | (v: number | null) => void | Called whenever the parsed numeric value changes. |
onValueChange | (v, details) => void | Like onChange, plus { reason, formattedValue }. |
minValue / maxValue | number | Constraints. |
step / largeStep / smallStep | number | Step sizes. |
validate | (v: number | null) => boolean | string | Custom validator. |
disabled / readOnly | boolean | Interaction state. |
required | boolean | Marks the field as required. |
allowNegative / allowDecimal | boolean | Input constraints. |
prefix / suffix | string | Affixes. |
name | string | Generates hidden input props for native form submission. |
allowMouseWheel | boolean | Enable wheel-based increment/decrement. |
copyBehavior | "formatted" | "raw" | "number" | Clipboard behaviour. |
allowOutOfRange | boolean | Skip clamping; show aria-invalid instead. |
Data attributes set on the root element:
| Attribute | Set when |
|---|---|
data-focused | Input is focused |
data-invalid | Value is invalid |
data-disabled | disabled is true |
data-readonly | readOnly is true |
data-required | required is true |
data-scrubbing | A scrub interaction is active |
If you only care about commit-time analytics, use onValueChange and check the
reason field ("blur", "keyboard", "increment", "decrement", "wheel",
"paste", "input", "clear", or "scrub").
NumberField.Input
Section titled âNumberField.InputâThe text input. Accepts all standard <input> props except type (always "text").
| Prop | Type | Description |
|---|---|---|
render | RenderProp<"input"> | Swap the element (e.g. a styled component). |
NumberField.Label
Section titled âNumberField.Labelâ<NumberField.Label>Price</NumberField.Label>Renders a <label> with htmlFor wired to the input id. Accepts all
<label> props.
NumberField.Group
Section titled âNumberField.GroupâWraps the input and stepper buttons. Renders <div role="group">. Accepts all
<div> props.
NumberField.Increment / NumberField.Decrement
Section titled âNumberField.Increment / NumberField.DecrementâStepper buttons. Accepts all <button> props.
<NumberField.Decrement>â</NumberField.Decrement><NumberField.Increment>+</NumberField.Increment>Buttons are automatically disabled when at minValue/maxValue or when the
field is disabled or readOnly.
Press-and-hold acceleration: hold for stepHoldDelay ms â interval fires at
stepHoldInterval ms.
NumberField.ScrubArea
Section titled âNumberField.ScrubAreaâWraps any element; dragging over it adjusts the value via Pointer Lock API.
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "horizontal" | "vertical" | "both" | "horizontal" | Drag axis. |
pixelSensitivity | number | 4 | Pixels dragged per step. |
render | RenderProp | â | Custom element. |
<NumberField.ScrubArea direction="horizontal" pixelSensitivity={2}> Drag to adjust</NumberField.ScrubArea>data-scrubbing is set on the element while dragging.
NumberField.ScrubAreaCursor
Section titled âNumberField.ScrubAreaCursorâOptional. Renders only while scrubbing so you can show custom visual feedback
next to the active scrub handle. Accepts <span> props.
<NumberField.ScrubArea> <span>Drag me</span> <NumberField.ScrubAreaCursor> â </NumberField.ScrubAreaCursor></NumberField.ScrubArea>NumberField.Formatted
Section titled âNumberField.FormattedâA <span> (or custom element) that displays the current formatted value as
read-only text. Useful for dual-display UIs (edit + display side by side).
<NumberField.Formatted />{/* Renders: "$1,234.56" */}NumberField.Description
Section titled âNumberField.DescriptionâHelper text. Automatically wired to aria-describedby on the input.
<NumberField.Description> Enter a value between 0 and 100.</NumberField.Description>NumberField.ErrorMessage
Section titled âNumberField.ErrorMessageâDisplays validation errors. Has role="alert" and is only shown when the field
is invalid.
If you pass no children, it renders state.validationError automatically:
<NumberField.ErrorMessage />{/* Renders: "Must be a positive number" */}Or supply your own content:
<NumberField.ErrorMessage> Custom error text.</NumberField.ErrorMessage>NumberField.HiddenInput
Section titled âNumberField.HiddenInputâAn <input type="hidden"> for HTML form submission. Its value is always the
raw number (no formatting). To enable it, pass name to NumberField.Root.
<NumberField.Root locale="en-US" name="price"> <NumberField.Input /> <NumberField.HiddenInput /></NumberField.Root>render prop
Section titled ârender propâThe visual building blocks (Label, Group, Input, Increment,
Decrement, ScrubArea, ScrubAreaCursor, and Formatted) accept a
render prop for element replacement (no asChild peer deps required):
<NumberField.Input render={(props) => <MyStyledInput {...props} />}/>