Formatted Input
FormattedInput formats phone numbers, card numbers and amounts as you type, keeping the caret in place.
format="phone" adds spaces, brackets and dashes from a mask (# is one digit; by default from the locale region: en-US "(###) ###-####", vi-VN "#### ### ###"). format="card" groups 4-4-4-4, American Express 4-6-5. format="currency" formats with Intl from locale and currency, limits the decimals to the currency's own and pads them when you leave the field. Typing, pasting or deleting in the middle keeps the caret in place; Backspace right after a separator deletes the digit before it. value / onValueChange are the raw value (digits, or a decimal like "1234.5"); with name, the form submits the raw value through a hidden input. Takes every Input prop.Import
Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.
TSX
// npm install yugen-uiimport { FormattedInput, getPhoneMask, getCardMask, applyMask } from "yugen-ui";Variants
Each tile is a standalone example: hover to copy, or press Code to see the source.
Pads the decimals when you leave the field
Currency
Follows the YugenProvider locale; JPY has no decimals.
American Express groups as 4-6-5
Card number
inputMode numeric and autoComplete "cc-number" are built in.
+44
Custom mask & country code
The country code goes in contentBefore, not in the value.
Form submit
With name, FormData holds the raw value, not the formatted text.
Usage
Do
- Store and send the raw value; the formatting is only there to make it easier to read.
- Put the country code in
contentBeforewith a fixed mask when the form only takes numbers from one country. - Check the length / validity (Luhn for card numbers, for example) on submit and show errors through
<Field>.
Don't
- Don't use FormattedInput for counts that go up and down. Use SpinButton.
- Don't put digits in the fixed part of a mask; fixed characters are only separators.
Props
| Prop · Type | Default | Description |
|---|---|---|
| format"phone" | "card" | "currency" | Default: — | Kind of formatting. |
| value / defaultValuestring | Default: — | Raw value: digits (phone, card) or a decimal like "1234.5" (currency). |
| onValueChange(value: string, details: { formatted: string }) => void | Default: — | Called when the raw value changes; details.formatted is the text on screen. |
| maskstring | Default: — | Mask for phone / card: # is one digit. Defaults by locale (phone) / card type (card). |
| currencystring | Default: "USD" | ISO 4217 currency code for currency. |
| localestring | Default: YugenProvider locale | Locale for currency and the default phone mask. |
| namestring | Default: — | Form field name; the form submits the raw value through a hidden input. |
| label / hint / validationState / validationMessage / size / appearance / contentBefore / contentAfter / rootClassName— | Default: — | As on Input. |
| refRef<HTMLInputElement> | Default: — | Points to the visible input. |
| getPhoneMask | Default: — | Default masks and the mask function, usable outside the component. |