Numpad
● Stable · v0.1A large on-screen number pad for entering amounts — a cash count, a payment, a price — without the OS keyboard. Big, fixed-position keys a first-time owner can hit one-handed in a busy market: no typing, no tiny targets.
In context
Try it
Calculator mode
Set mode="calculator" to turn the pad into a working calculator — + − × ÷, %, decimal, AC, backspace, and =, with the live expression and running subtotal shown above the keys. It's there for real shop maths: total a few items, take a discount off, split a bill. It manages the running calculation itself, emits the current display via onChange, and the final result via onResult when = is pressed.
<Numpadmode="calculator"value={value}onChange={setValue} // live display (subtotal as you go)onResult={(total) => setValue(total)} // fired on '='/>
Purpose
Money entry is the most repeated, highest-stakes input in the app, and the OS keyboard is the wrong tool for it: it's small, it covers half the screen, and a numeric layout still shows letters our users don't need. The Numpad replaces it with a fixed, oversized grid that stays in one place — the user looks down once, learns where the keys are, and never hunts again.
It is controlled and presentational: you own the value string and the component edits it, emitting the next string on every press. It does not format or display the number — pair it with your own amount label above (as in the examples).
Anatomy
- Keys — the familiar phone grid:
1–9, a configurable bottom-left key,0, and backspace. Each key is at least the comfortable 48–56dp touch target. - Bottom-left key —
00/000for fast round amounts (default), or a decimal point whenallowDecimalis set. - Backspace — deletes the last character; long-press clears the whole amount to
0.
Code
import { Numpad } from '@daytwo/components'const [amount, setAmount] = useState('0')// You render the amount; the Numpad only edits the string.<Text>฿ {Number(amount).toLocaleString()}</Text><Numpadvalue={amount}onChange={setAmount}zerosKey="000" // fast round amounts/>
For decimals (a price, a weight), turn on allowDecimal — the bottom-left key becomes . and decimalScale caps the fractional digits:
<Numpad value={price} onChange={setPrice} allowDecimal decimalScale={2} />
The pure edit function is exported too, so a custom keypad layout can share the exact same behaviour:
import { applyNumpadKey } from '@daytwo/components'const next = applyNumpadKey(value, '7', { maxLength: 9 })
When to use
- For entering an amount of money — counting cash, recording a sale or expense, a loan or a payment.
- Any full-screen or bottom-sheet flow whose main job is a number, where a dedicated pad is faster and clearer than the OS keyboard.
When NOT to use
- For text (a name, a note) — that's an Input with the keyboard.
- For a short, incidental number buried in a long form — a numeric Input keeps the field inline; a full pad would dominate the screen.
- To display the amount — the Numpad edits the value; show it yourself in a big label above the pad.
The correct scenario
The "Count cash" sheet shows the running total in a large ฿ figure, with the Numpad fixed below it. The owner taps 9 · 3 · 00, watches ฿9,300 build up in place, and hits Confirm — the same pad they'll use for every payment and sale, so it's muscle memory by the second use.
Anti-patterns
The Numpad never renders the number — it only edits the string. Always pair it with a large, legible amount display so the user sees what they're typing.
Edge cases
'0', shown quiet (tertiary)007 should become 7, not stay paddedmaxLength (default 9) ignores further presses'0'allowDecimal adds .; decimalScale caps the fractionfontFamily for Burmese/Thai surroundings