Money input
All copy is placeholder. Real strings come from the i18n layer.
Default, focused, error, read-only
Tab into the currency — the ring is raised so the input beside it cannot clip it.
That is not an amount in EUR. Digits and one separator.
Read from the linked expense. Change it in Money and this follows.
The invalid field keeps what was typed. Clearing it to "fix" it loses the
only copy of what they meant.
The digit count comes from the currency
Never a constant. The same stored integer is three different amounts.
| Currency | Minor digits | Stored | Shown |
|---|---|---|---|
| JPY | 0 | 12000 | ¥12,000 |
| EUR | 2 | 12000 | €120.00 |
| KWD | 3 | 12000 | KD12.000 |
Changing the currency must re-validate the amount, not just relabel it:
12.5 is valid in EUR and not in JPY.
And the separators come from the locale
| Typed | In English | In Turkish |
|---|---|---|
1.234,50 | malformed | one thousand two hundred and thirty-four fifty |
1,234.50 | one thousand two hundred and thirty-four fifty | malformed |
The same keystrokes are two different numbers in the two languages this product ships.
A component that hardcodes
. as the decimal point is wrong for half its users
on day one — ADR-0014.
Never type="number"
Spinners are meaningless for money, the scroll wheel changes values by accident, and
browsers disagree about what a comma does in one.
inputmode="decimal" gets
the numeric keypad on a phone without any of that.