Skip to content

NumberInput

Segmented numeric input — [ − ][ value ][ + ] — with locale-aware parsing via React Aria's NumberField.

  • stable
  • since v0.1.0
  • 1.1 kB
  • forms
  • input

Built on React Aria NumberField — keyboard support for ↑/↓, PageUp/PageDown, Home/End and wheel; min/max are announced.

A segmented numeric control — a tinted track wrapping three raised segments, [ − ][ value ][ + ]. The centre segment is a real, editable field (type into it, or use the keyboard), and the large / + buttons give touch-friendly targets (~44px tall at md). Parsing, formatting, clamping, and keyboard behaviour come from React Aria’s NumberField.

Preview
Open
tsx

variant tints the track without changing the segmented structure: outline (default — light well + hairline border), filled (deeper solid tint, no border), and ghost (no well; segments stay flat until hover).

Preview
Open
tsx

Three sizes are available: sm, md (default), and lg.

Preview
Open
tsx

Use minValue, maxValue, and step to constrain the input. Stepper buttons disable at bounds.

Preview
Open
tsx

Use prefix and suffix to inline currency, units, or other muted affixes.

Preview
Open
tsx

Pass formatOptions (forwarded to React Aria) to render currency, percent, or a fixed precision.

Preview
Open
tsx
Preview
Open
tsx
  • Hold to repeat. Press and hold / + to step continuously — it waits a short delay, then repeats on an accelerating interval, and stops at the min/max bound. This is React Aria’s built-in press-and-hold, so it works for mouse, touch, and pen.
  • Pressed feedback. The / + segments visibly depress into the accent colour on press.
  • Long-press to clear. Opt in with clearOnLongPress — a ~500ms long-press on the value segment clears it to minValue (or empty when no minimum is set). Off by default.
Preview
Open
tsx
PropTypeDefaultDescription
size
"sm"|"md"|"lg"
"md"
Control size.
variant
"outline"|"filled"|"ghost"
"outline"
Visual treatment. Tints the track; the segmented layout is constant.
invalid
boolean
Mirrors React Aria's `isInvalid` for parity with other Cynosure controls.
className
string
style
CSSProperties
prefix
ReactNode
Muted inline content before the value (e.g. `$`, `€`, `#`).
suffix
ReactNode
Muted inline content after the value (e.g. `px`, `%`, `kg`).
incrementLabel
string
Custom `aria-label` for the increment button. Overrides the localized default.
decrementLabel
string
Custom `aria-label` for the decrement button. Overrides the localized default.
clearOnLongPress
boolean
false
Long-press the value segment (~500ms) to clear it — to `minValue` if set, otherwise empty. Pointer-only; distinct from the −/+ hold-to-repeat.
  • Built on React Aria NumberField — values are parsed locale-correctly and clamped to minValue/maxValue.
  • Keyboard: ArrowUp/ArrowDown step, PageUp/PageDown step by a larger amount, Home/End jump to bounds. Hold-to-repeat is pointer-only; keyboard repeat is the OS key-repeat as before.
  • The editable value is a real role="spinbutton" input with aria-valuenow/min/max. The / + segments are real buttons with localized labels (incrementLabel / decrementLabel); affixes are decorative (aria-hidden).
  • aria-invalid is mirrored from invalid (or isInvalid) on the underlying input.
  • The focus ring is drawn on the track and honours :focus-visible; the acceleration / press transitions respect prefers-reduced-motion.
  • Use formatOptions={{ style: "currency", currency: "USD" }} for money fields — React Aria handles parsing and display.
  • Pass step together with minValue/maxValue to bound the field and ensure the steppers disable at the bounds.
  • Provide incrementLabel/decrementLabel to localize the stepper announcement.
  • Enable clearOnLongPress for touch-first quantity fields where a quick reset to the minimum is handy.