Formatters
Input formatters for SSN, EIN, phone, currency, dates, and more — one page per formatter
Formatters
Formatters reshape field values as the user types or when the field loses focus — SSN and EIN masks, country-aware phone numbers, currency, dates, times, and configurable trimming. Everything is controlled per field through the format config, so each input decides what to format and when (onChange, onBlur, or both).
The format config
validationSchema: {
ssn: { format: "ssn" }, // string shorthand
name: { format: trimFn }, // custom function
tin: { format: { type: "tin", options: { mask: "XX-XXXXXXX" } } },
phone: {
format: {
type: "phone",
trigger: "onChange", // "onChange" (default) | "onBlur"
options: { country: "US", ext: true },
},
},
price: { format: { type: "currency", trigger: "onBlur" } },
name2: {
format: [ // multiple steps run in order
{ type: "trim", trigger: "onBlur", options: { mode: "both" } },
"upperCase", // runs on its default trigger
],
},
}| Part | Type | Default | Description |
|---|---|---|---|
type | string | FormatterFn | — | Built-in name or custom (value, options) => value |
trigger | "onChange" | "onBlur" | "onChange" | Apply while typing or on blur. Use two steps for both |
options | Record<string, unknown> | — | Passed to the formatter (country, mask, mode, …) |
Formatting runs before validation, so errors always match what the user sees. Values are also formatted on submit, so onSubmit receives clean data. To apply on both change and blur, add two steps:
format: [
{ type: "trim", trigger: "onChange" },
{ type: "trim", trigger: "onBlur" },
]Formatter pages
Trimming
- trim — strip whitespace from the start, end, or both (on change or blur)
Tax identifiers
- ssn —
123-45-6789 - ein —
12-3456789 - itin —
123-45-6789 - tin — custom letter-based mask (
XX-XXXXXXX) - mask — generic digit-based mask (
###-###-####)
Contact & payments
- phone — country-aware phone numbers with optional extension
- zip —
12345/12345-6789 - credit-card —
4242 4242 4242 4242
Numbers, dates & times
Case & cleanup
- upper-case — uppercase conversion
- lower-case — lowercase conversion
- digits-only — keep digits only
Custom
- custom — write your own formatter or register one by name
Interaction with normalization
normalize and format compose: normalization runs on change, then the format chain applies. Typical split:
normalize: "trim"— keep the value clean while typingformat: { type: "upperCase", trigger: "onBlur" }— polish on blur
To disable formatting for a field, omit format (or override the built-in format plugin by passing a plugin named "format").