input-number

An accessible React number input component with precision control, custom formatting, and keyboard/wheel stepping.

Library
npm
v9.5.0
323stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
73/100Good
Development Activity68
Maintenance56
Community88
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture78
Code Quality82
Innovation62
Learning Curve80

rc-input-number is the number-input primitive behind Ant Design’s InputNumber component, built by the react-component ecosystem team that also maintains rc-select, rc-picker, and rc-dialog. It renders a controlled or uncontrolled numeric input with configurable min/max bounds, step size, and decimal precision, and exposes both an input mode and a spinner mode with increment/decrement controls.

Under the hood it delegates precision-sensitive math to @rc-component/mini-decimal so values with many decimal places don’t suffer from floating-point rounding errors, and supports stringMode so very large or very precise numbers can be represented as strings rather than JS numbers. Formatting and parsing are fully pluggable via formatter/parser props, which is how consumers add currency symbols, thousands separators, or unit suffixes without forking the component.

Beyond mouse and keyboard interaction, it wires up mouse-wheel stepping (opt-in via changeOnWheel), Shift/Ctrl modifier steps, and cursor-position preservation while typing, along with an imperative ref (focus/blur/nativeElement) for integration with form libraries that need direct DOM access.

What You Get

  • Controlled and uncontrolled numeric input modes with value/defaultValue
  • Decimal-safe math via @rc-component/mini-decimal, avoiding floating-point precision bugs
  • Pluggable formatter/parser for currency, units, or custom display formats
  • Keyboard stepping with Shift (10x step) and Ctrl/Cmd (0.1x step) modifiers
  • Optional mouse-wheel stepping and input/spinner render modes with custom up/down controls
  • Imperative ref API (focus, blur, nativeElement) plus semantic classNames/styles slots for styling

Common Use Cases

  • Quantity, price, or percentage fields in checkout and admin forms
  • Building a design system’s numeric input primitive (as Ant Design does internally)
  • Settings/config UIs needing bounded numeric steppers (min/max/step)
  • High-precision financial or scientific inputs where floating-point rounding is unacceptable
  • Custom currency inputs that need a formatter/parser pair for symbols and separators

Under The Hood

Architecture The component is a single-responsibility input built around InputNumber.tsx (~790 lines), which owns all state (raw text, decimal value, cursor position, composition state) and composes two focused collaborators: StepHandler.tsx renders the up/down spinner buttons and delegates stepping back to the parent via callbacks, and useCursor/useFrame hooks isolate cursor-position restoration and requestAnimationFrame-based batching from the main render path. Numeric correctness is delegated entirely to the sibling @rc-component/mini-decimal package rather than reimplemented inline, so InputNumber.tsx itself only orchestrates user input, formatting/parsing, and step math — a clean single-purpose core with no internal layering to speak of, appropriate for a component this narrowly scoped.

Tech Stack Written in TypeScript against React with @rc-component/mini-decimal for arbitrary-precision decimal handling, @rc-component/util for small shared React helpers (focus proxying, layout-effect timing), and clsx for conditional class composition. The build pipeline uses father (the react-component ecosystem’s build tool) to produce ESM/CJs/lib outputs plus a Less-compiled stylesheet, with dumi powering the documentation/demo site and @rc-component/np handling the publish flow.

Code Quality Tests live under tests/ and are organized by concern rather than by file — keyboard.test.tsx, wheel.test.tsx, precision.test.tsx, decimal.test.tsx, cursor.test.tsx, formatter.test.tsx, longPress.test.tsx, and more — run via rc-test (a Jest wrapper shared across react-component packages) with @testing-library/react. This gives comprehensive behavioral coverage of the trickiest parts of a number input (precision edge cases, cursor jumps, wheel/keyboard modifiers) rather than just snapshot tests. ESLint and Prettier are configured with lint-staged/husky pre-commit hooks, and tsc --noEmit runs as a dedicated CI-style check, indicating a typed, linted, and tested codebase.

API Design The public API is small and consistent with the rest of the react-component family: value/defaultValue/onChange follow standard React controlled-component conventions, formatter/parser are a symmetric pair rather than a single ad-hoc callback, and semantic classNames/styles objects give consumers fine-grained styling hooks without prop explosion. Getting started requires zero configuration beyond min/max/defaultValue, and the documented ref API (focus/blur/nativeElement) covers the one case (imperative focus management) that controlled props can’t.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search