NumberField

Collects numeric values with arrow-key stepping, label scrubbing and optional units.

import { NumberField } from "@usefragments/ui";Source

Preview

<Field>
  <Field.Label>Width</Field.Label>
  <NumberField defaultValue={320} min={0} max={1440} unit="px" />
</Field>

Usage

Use when

  • Quantities, dimensions, percentages and other bounded numbers
  • Values people nudge more than they type: the arrow keys and the scrub label
  • A number that carries a unit

Avoid when

  • Codes that look like numbers: postcodes, card numbers, phone numbers (use Input)
  • Picking a value on a continuous range by eye (use Slider)
  • Choosing from a short fixed set of numbers (use Select)

Implementation notes

  • Wrap in a Field for the label, description and error
  • Set min and max whenever the value has bounds; steps and scrubs clamp to them
  • Keep the scrub label to one or two characters: W, H, X, Y
  • Put the unit in unit, not in the label, so it is read with the value
  • Use onValueCommitted for work that should wait until the value settles

Installation

pnpm add @usefragments/ui

Import styles once from @usefragments/ui/styles. See the installation guide for framework and theme setup.

Examples

Scrub label

Drag the W to scrub; the arrow keys still step.

<Field>
  <Field.Label>Width</Field.Label>
  <NumberField defaultValue={240} min={0} scrub="W" unit="px" size="sm" />
</Field>

Invalid

The danger edge with the reason under the field.

<Field invalid>
  <Field.Label>Seats</Field.Label>
  <NumberField defaultValue={0} min={0} invalid />
  <Field.Error match>Add at least one seat.</Field.Error>
</Field>

API reference

Component props
Prop
Type
Default
Description
defaultValuenumber | undefinedNot setInitial value for uncontrolled use
disabledboolean | undefinedNot setDims the field and blocks input
formstring | undefinedNot set—
formatIntl.NumberFormatOptions | undefinedNot setIntl.NumberFormat options for the shown value
invalidboolean | undefinedfalseThe danger edge and aria-invalid; say why in a Field.Error
largeStepnumber | undefined10The Shift + arrow step
maxnumber | undefinedNot setHighest value; steps and scrubs clamp to it
minnumber | undefinedNot setLowest value; steps and scrubs clamp to it
namestring | undefinedNot setForm field name
onValueChange((value: number | null) => void) | undefinedNot setCalled with the new value as it changes; null when cleared
onValueCommitted((value: number | null) => void) | undefinedNot setCalled once the value settles: on blur, Enter, a step or the end of a scrub
readOnlyboolean | undefinedNot setShows the value without letting it change
requiredboolean | undefinedNot setMarks the field required for form validation
scrubReact.ReactNodeNot setA short label at the start that scrubs the value when dragged
sizeNumberFieldSize | undefinedxssmmdlg"md"Field height on the shared control track: 24, 28, 32 or 40
stepnumber | undefined1The arrow-key step
unitstring | undefinedNot setA unit shown after the figures and read with the value
valuenumber | null | undefinedNot setControlled value; null is empty

Accessibility

  • The input keeps the text role with a numeric keyboard and a number role description
  • Arrow keys step by step, Shift + arrow by largeStep, Home and End jump to min and max
  • The scrub label is hidden from assistive tech; the keyboard does the same job
  • The unit is added to the input's description
  • FieldparentField supplies the label, description and error
  • InputalternativeUse Input for number-like codes that never step
  • SlideralternativeUse Slider to pick a value on a range by eye

Next steps