number-input.tsx
Overview
number-input.tsx defines a reusable React functional component named NumberInput. This component provides a user interface for numeric input with increment (+) and decrement (-) buttons flanking a central text input field. It allows users to adjust numeric values either by clicking the buttons or typing directly into the input box, while enforcing numeric-only input. The component supports controlled and uncontrolled usage patterns and customizable styling, including height and additional CSS classes.
This component is typically used in forms or interactive UI elements where numeric input with quick increment/decrement controls is required, such as quantity selectors, rating inputs, or numeric filters.
Component: NumberInput
Signature
const NumberInput: React.FC<NumberInputProps>
Props: NumberInputProps
Prop | Type | Optional | Description |
|---|---|---|---|
|
| Yes | Additional CSS classes to apply to the root container for styling. |
|
| Yes | Initial or controlled numeric value of the input. |
|
| Yes | Callback invoked whenever the numeric value changes. |
|
| Yes | Custom height for the input and buttons, supports px or numeric. |
State
value: number— Holds the current numeric value displayed in the input. Initialized fromprops.valueor defaults to 0.
Behavior and Methods
useEffect
Synchronizes internal state
valuewith externalinitialValueprop changes to support controlled usage.
handleDecrement(): void
Decrements the current value by 1 if the value is greater than 0.
Calls the
onChangecallback with the new decremented value.Prevents the value from going below zero.
handleIncrement(): void
Increments the current value by 1.
Calls the
onChangecallback with the new incremented value.
handleChange(e: React.ChangeEvent<HTMLInputElement>): void
Parses the input text value as a number.
If valid numeric, updates internal
valueand callsonChange.Allows direct manual input of numbers.
handleInput(e: React.ChangeEvent<HTMLInputElement>): void
Prevents any non-numeric characters from being entered by testing the input against a regex
/^\d*$/.This ensures only digits can be typed.
style: React.CSSProperties
Memoized style object controlling the height of the component elements.
Converts numeric
heightprops to pixel string.Defaults to
'auto'height if no prop provided.
Render Structure
A container
<div>with flex layout, fixed width (150px), border, rounded corners, and spacing.Left button: decrement button with a minus icon.
Center input: text input showing the numeric value, centered text, transparent background.
Right button: increment button with a plus icon.
Each button and the input share the same height style for uniform appearance.
Usage Example
import NumberInput from './number-input';
function QuantitySelector() {
const [quantity, setQuantity] = React.useState(3);
return (
<NumberInput
value={quantity}
onChange={(val) => setQuantity(val)}
height={40}
className="my-custom-class"
/>
);
}
Important Implementation Details
Controlled vs Uncontrolled: The component supports controlled mode by accepting a
valueprop and syncing internal state with it viauseEffect. If novalueprop is provided, it initializes to 0 and manages state internally.Input Validation: The
handleInputprevents invalid characters at input time, whilehandleChangeparses and synchronizes the numeric value on change events.Accessibility: Buttons use
type="button"and icons havearia-hidden="true"to ensure screen readers ignore decorative icons.Styling: The component uses Tailwind CSS classes (e.g.,
flex,border-[1px],rounded-lg,focus:outline-none) for layout and styling. The height is dynamically applied via inline styles.Icons: Uses
MinusIconandPlusIconfromlucide-reactfor consistent, scalable vector icons.
Interaction with Other Parts of the System
Icon Library: Depends on the
lucide-reacticon set, so must be installed and available.Styling Framework: Tailwind CSS classes imply that Tailwind must be configured in the project.
Parent Components: Typically used inside forms or UI widgets that manage numeric values. Parent components can control the value by passing
valueandonChangeprops.No External State Management: State is local unless controlled externally, making it flexible for various integration patterns.
Visual Diagram: Component Structure and Data Flow
componentDiagram
component NumberInput {
+className?: string
+value?: number
+onChange?: (number) => void
+height?: number|string
}
component DecrementButton
component NumericInput
component IncrementButton
NumberInput --> DecrementButton : onClick handleDecrement
NumberInput --> NumericInput : value, onChange handleChange, onInput handleInput
NumberInput --> IncrementButton : onClick handleIncrement
NumberInput <.. ParentComponent : props.value, props.onChange
Summary
number-input.tsx implements a clean, accessible, and reusable numeric input React component with increment and decrement buttons and direct numeric input support. It is customizable in styling and supports flexible usage modes, making it ideal for quantity selectors and similar numeric UI elements. The component leverages React state hooks, controlled input patterns, and input validation to deliver a robust user experience.