@mshafiqyajid/react-number-input
Headless number input hook and styled component. Decimal, currency, and percent modes via Intl.NumberFormat. Step, min, max, keyboard navigation.
Playground #
Props
TSX
import { NumberInputStyled } from "@mshafiqyajid/react-number-input/styled";
import "@mshafiqyajid/react-number-input/styles.css";
<NumberInputStyled
value={value}
onChange={setValue}
/>Install #
npm install @mshafiqyajid/react-number-input Quick start #
import { NumberInputStyled } from "@mshafiqyajid/react-number-input/styled";
import "@mshafiqyajid/react-number-input/styles.css";
const [price, setPrice] = useState<number | undefined>(0);
<NumberInputStyled
value={price}
onChange={setPrice}
format="currency"
currency="MYR"
min={0}
label="Price"
tone="primary"
/>
// Prefix/suffix
<NumberInputStyled value={weight} onChange={setWeight} suffix="kg" />
<NumberInputStyled value={amount} onChange={setAmount} prefix="RM" /> API #
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | undefined | — | Controlled value |
| defaultValue | number | — | Uncontrolled initial value |
| onChange | (v) => void | — | Called on change |
| min | number | — | Minimum value |
| max | number | — | Maximum value |
| step | number | 1 | Increment step |
| format | "decimal" | "currency" | "percent" | "decimal" | Display format |
| currency | string | "USD" | ISO currency code (format="currency") |
| locale | string | "en-US" | Intl locale for formatting |
| label | string | — | Visible label |
| hint | string | — | Helper text below input |
| error | string | — | Error message (overrides hint) |
| size | "sm" | "md" | "lg" | "md" | Input size |
| tone | "neutral" | "primary" | "success" | "danger" | "neutral" | Color tone |
| disabled | boolean | false | Disable interaction |
| showStepper | boolean | true | Show +/− increment buttons |
| onBlur | FocusEventHandler | — | Blur callback |
| onFocus | FocusEventHandler | — | Focus callback |
| prefix | string | — | Text before value (e.g. "RM") |
| suffix | string | — | Text after value (e.g. "kg") |
| clampOnBlur | boolean | true | Snap to min/max on blur |