React input-number component with step controls, validation, and formatting features
npx @tessl/cli install tessl/npm-rc-input-number@8.6.0RC Input Number is a React component that provides a comprehensive numeric input field with built-in increment/decrement controls, validation, formatting, and accessibility features. It supports both controlled and uncontrolled usage patterns with extensive customization options for styling and behavior.
npm install rc-input-numberimport InputNumber from "rc-input-number";
import type { InputNumberProps, ValueType } from "rc-input-number";For CommonJS:
const InputNumber = require("rc-input-number");import React from "react";
import InputNumber from "rc-input-number";
// Simple usage
function SimpleExample() {
return <InputNumber defaultValue={10} />;
}
// Controlled component with constraints
function ControlledExample() {
const [value, setValue] = React.useState<number | null>(5);
return (
<InputNumber
min={0}
max={100}
step={1}
value={value}
onChange={(val) => setValue(val)}
precision={2}
/>
);
}
// With custom formatting
function FormattedExample() {
return (
<InputNumber
defaultValue={1000}
formatter={(value) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
parser={(value) => value?.replace(/\$\s?|(,*)/g, '') || ''}
/>
);
}The main InputNumber component provides a complete numeric input solution with step controls and validation.
const InputNumber: <T extends ValueType = ValueType>(
props: React.PropsWithChildren<InputNumberProps<T>> & {
ref?: React.Ref<HTMLInputElement>;
}
) => React.ReactElement;
type ValueType = string | number;Complete props interface for the InputNumber component.
interface InputNumberProps<T extends ValueType = ValueType>
extends Omit<React.InputHTMLAttributes<HTMLInputElement>,
'value' | 'defaultValue' | 'onInput' | 'onChange' | 'prefix' | 'suffix'> {
// Value Management
/** Controlled value of the input */
value?: T | null;
/** Initial uncontrolled value */
defaultValue?: T;
/** Whether to return string values instead of numbers */
stringMode?: boolean;
// Numeric Constraints
/** Minimum allowed value */
min?: T;
/** Maximum allowed value */
max?: T;
/** Step increment value (default: 1) */
step?: ValueType;
/** Number of decimal places to display */
precision?: number;
// Styling & Layout
/** CSS class prefix (default: 'rc-input-number') */
prefixCls?: string;
/** Additional CSS classes */
className?: string;
/** Inline styles */
style?: React.CSSProperties;
/** Granular class names for sub-components */
classNames?: BaseInputProps['classNames'] & {
input?: string;
};
// Content Decorators
/** Element before the input */
prefix?: React.ReactNode;
/** Element after the input */
suffix?: React.ReactNode;
/** Element before the entire control */
addonBefore?: React.ReactNode;
/** Element after the entire control */
addonAfter?: React.ReactNode;
// Step Controls
/** Whether to show up/down buttons (default: true) */
controls?: boolean;
/** Custom up button element */
upHandler?: React.ReactNode;
/** Custom down button element */
downHandler?: React.ReactNode;
// Input Processing
/** Format value for display */
formatter?: (value: T | undefined, info: { userTyping: boolean; input: string }) => string;
/** Parse display value to actual value */
parser?: (displayValue: string | undefined) => T;
/** Custom decimal separator character */
decimalSeparator?: string;
/** Regex pattern for input validation (useful for iOS number pad) */
pattern?: string;
/** Input mode attribute for mobile keyboards */
inputMode?: string;
// Interaction Controls
/** Enable keyboard arrow key controls */
keyboard?: boolean;
/** Enable mouse wheel value changes */
wheel?: boolean;
/** Whether to trigger onChange on blur (default: true) */
changeOnBlur?: boolean;
/** Disable the input */
disabled?: boolean;
/** Make input read-only */
readOnly?: boolean;
/** Required field validation */
required?: boolean;
/** Auto focus the input on mount */
autoFocus?: boolean;
/** Tab index for keyboard navigation */
tabIndex?: number;
/** HTML name attribute */
name?: string;
/** HTML id attribute */
id?: string;
/** Placeholder text */
placeholder?: string;
// Event Handlers
/** Value change callback */
onChange?: (value: T | null) => void;
/** Input text change callback */
onInput?: (text: string) => void;
/** Enter key press handler */
onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;
/** Focus event handler */
onFocus?: React.FocusEventHandler<HTMLInputElement>;
/** Blur event handler */
onBlur?: React.FocusEventHandler<HTMLInputElement>;
/** Click event handler */
onClick?: React.MouseEventHandler<HTMLInputElement>;
/** Step button interaction callback */
onStep?: (value: T, info: { offset: ValueType; type: 'up' | 'down' }) => void;
}Union type representing acceptable numeric value types.
type ValueType = string | number;
// From rc-input BaseInputProps interface
interface BaseInputProps {
classNames?: {
affixWrapper?: string;
prefix?: string;
suffix?: string;
groupWrapper?: string;
wrapper?: string;
};
}// Currency input with precise decimal handling
<InputNumber
defaultValue={99.99}
precision={2}
step={0.01}
formatter={(value) => `$ ${value}`}
parser={(value) => value?.replace(/\$\s?/g, '') || ''}
min={0}
/>
// Percentage input
<InputNumber
defaultValue={50}
min={0}
max={100}
formatter={(value) => `${value}%`}
parser={(value) => value?.replace('%', '') || ''}
/>// Using string mode for very large or precise numbers
<InputNumber
stringMode
defaultValue="123456789012345678901234567890.123456789"
precision={9}
onChange={(value) => {
// value is string in stringMode
console.log(typeof value); // "string"
}}
/>function CustomStepExample() {
const [value, setValue] = React.useState<number>(0);
const handleStep = (newValue: number, info: { offset: ValueType; type: 'up' | 'down' }) => {
console.log(`Stepped ${info.type} by ${info.offset}`);
// Custom validation logic
if (newValue >= 0 && newValue <= 1000) {
setValue(newValue);
}
};
return (
<InputNumber
value={value}
onChange={setValue}
onStep={handleStep}
min={0}
max={1000}
step={10}
upHandler={<span>⬆️</span>}
downHandler={<span>⬇️</span>}
/>
);
}// Disable mouse wheel, enable keyboard with custom behavior
<InputNumber
defaultValue={50}
wheel={false}
keyboard={true}
onKeyDown={(e) => {
// Ctrl/Cmd + Arrow keys for larger steps
if (e.ctrlKey || e.metaKey) {
e.preventDefault();
// Custom large step handling
}
}}
/>// Example with React Hook Form
import { Controller, useForm } from "react-hook-form";
function FormExample() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<Controller
name="quantity"
control={control}
defaultValue={1}
rules={{
required: "Quantity is required",
min: { value: 1, message: "Minimum quantity is 1" },
max: { value: 100, message: "Maximum quantity is 100" }
}}
render={({ field }) => (
<InputNumber
{...field}
min={1}
max={100}
step={1}
placeholder="Enter quantity"
/>
)}
/>
</form>
);
}RC Input Number provides comprehensive keyboard support for value manipulation:
step amount10 * step (large increments)0.1 * step (small increments)onPressEnter callback and validates current inputWhen wheel prop is enabled (default: true):
step amount10 * step (large increments)