- 🎯 Simple API
- 💎 Works like a charm with Next.js
- ✨ Compatible with React Hook Form
- 🏁 Compatible with React Final Form
npm i use-mask-input
import React from 'react'
import { withMask } from 'use-mask-input';
const App = () => {
return (
<input type="text" ref={withMask('9999-9999')} />
)
}
import React from 'react';
import { useForm } from 'react-hook-form';
import { useHookFormMask } from 'use-mask-input';
function App() {
const { register, handleSubmit } = useForm();
const registerWithMask = useHookFormMask(register);
...
return (
<form onSubmit={onSubmit}>
<input
{...registerWithMask("phone", ['99 9999-9999', '99999-9999'], {
required: true
})}
type="text"
/>
<button type="submit">Submit</button>
</form>
);
}
Just use withMask
normaly.
import React from 'react';
import { Form, Field } from 'react-final-form';
import { withMask } from 'use-mask-input';
function App() {
...
return (
<Form
onSubmit={onSubmit}
render={({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<Field
name="phone"
render={({ input, meta }) => (
<input ref={withMask('9999-9999')} {...input} />
)}
/>
<button type="submit">Submit</button>
</form>
)}
/>
);
}
The mask
params can be
These are the very basics of masking. The mask is defined and will not change during the input.
<input
{...registerWithMask("phone", '99 9999-9999')}
type="text"
/>
It is possible to define some parts in the mask as optional. This is done by using [ ]
. By example:
<input
{...registerWithMask("phone", '99 [9]9999-9999')}
type="text"
/>
This mask will allow input like (99) 99999-9999 or (99) 9999-9999.
Dynamic masks can change during input. To define a dynamic part use { }.
{n} => n repeats {n|j} => n repeats, with j jitmasking {n,m} => from n to m repeats {n,m|j} => from n to m repeats, with j jitmasking
Also {+} and {} is allowed. + start from 1 and start from 0.
By example:
//static mask with dynamic syntax
<input
{...registerWithMask("phone", "aa-9{4}")}
type="text"
/>
// dynamic mask ~ the 9 def can be occur 1 to 4 times
<input
{...registerWithMask("phone", "aa-9{4}")}
type="text"
/>
// dynamic mask ~ email
<input
{...registerWithMask("phone", "*{1,20}[.*{1,20}][.*{1,20}][.*{1,20}]@*{1,20}[.*{2,6}][.*{1,2}]")}
type="text"
/>
A Lot of common default "aliases" presets, you can use like that:
<input // the alias
{...registerWithMask("date", "datetime", {
inputFormat: "yyyy-mm-dd",
})}
type="text"
/>
You can use together with options like inputFormat
, prefix
, suffix
, etc. Checkout API docs
The avaliable ones is:
datetime
email
ip
datetime
cpf
email
numeric
currency
decimal
integer
percentage
url
ip
mac
ssn
The alternator syntax is like an OR statement. The mask can be one of the 3 choices specified in the alternator.
To define an alternator use the |. ex: "a|9" => a or 9 "(aaa)|(999)" => aaa or 999 "(aaa|999|9AA)" => aaa or 999 or 9AA "aaaa|9999" => aaa a or 9 999
<input
{...registerWithMask("phone", "9999-9999|99999-9999")}
type="text"
/>
// or just passing an array
<input
{...registerWithMask("phone", ["9999-9999", "99999-9999"])}
type="text"
/>
You can define the mask as a function that can allow you to preprocess the resulting mask. Example sorting for multiple masks or retrieving mask definitions dynamically through ajax. The preprocessing fn should return a valid mask definition.
<input
{...registerWithMask("phone", function () {
/* do stuff */ return ["[1-]AAA-999", "[1-]999-AAA"];
})}
type="text"
/>
Attach a mask to an input via a ref
:
const attach = withMask('999-9999', { clearIncomplete: true });
<input ref={attach} />;
- mask:
string
|string[]
|(opts: Options) => string \| string[]
- options:
Options
(see below)
Integrate masking with React-Hook-Form’s register
:
const maskedRegister = useHookFormMask(register);
<input {...maskedRegister('phone', '999-9999', { showMaskOnFocus: true })} />;
Option | Description | Type | Default |
---|---|---|---|
mask |
Static mask, array of masks, or function returning mask(s) | string | string[] | fn |
— |
regex |
Treat the mask as a regular expression | string |
— |
placeholder |
Character shown for empty slots | string |
"_" |
optionalmarker |
Delimiters for optional sections | { start: string; end: string } |
{ start: "[", end: "]" } |
quantifiermarker |
Delimiters for repetition ranges | { start: string; end: string } |
{ start: "{", end: "}" } |
groupmarker |
Delimiters for grouping | { start: string; end: string } |
{ start: "(", end: ")" } |
alternatormarker |
Character separating alternator options | string |
`" |
escapeChar |
Character to escape mask meta-symbols | string |
"\\" |
definitions |
Custom symbol→validator mappings | Record<string,Definition> |
— |
alias |
Built-in preset (“datetime”, “currency”, etc.) | string |
— |
inputFormat |
Format string for datetime alias | string |
— |
outputFormat |
Format of unmasked datetime value | string |
— |
displayFormat |
Visual format when losing focus (datetime alias) | string |
— |
clearMaskOnLostFocus |
Trim placeholders on blur | boolean |
true |
showMaskOnFocus |
Show full mask when focused | boolean |
true |
showMaskOnHover |
Show mask when hovering | boolean |
true |
clearIncomplete |
Clear input if not fully filled on blur | boolean |
false |
removeMaskOnSubmit |
Strip mask chars on form submit | boolean |
false |
autoUnmask |
Always return unmasked value | boolean |
false |
jitMasking |
Just-in-time masking (only show entered chars) | boolean |
false |
nullable |
Return "" if no input |
boolean |
true |
noValuePatching |
Disable .value patching hacks |
boolean |
false |
insertMode |
Insert vs overwrite | boolean |
true |
insertModeVisual |
Highlight caret in overwrite mode | boolean |
true |
positionCaretOnClick |
Caret placement on click: "none" , "lvp" , "radixFocus" , "select" , "ignore" |
string |
"lvp" |
positionCaretOnTab |
Move caret to last valid position on Tab | boolean |
true |
tabThrough |
Tab between mask sections | boolean |
false |
skipOptionalPartCharacter |
Character to skip optional blocks | string |
" " |
numericInput |
Keep caret at end for numeric | boolean |
false |
rightAlign |
Right-align numeric | boolean |
true |
radixPoint |
Decimal separator | string |
"" |
groupSeparator |
Thousands separator | string |
"" |
digits |
Fractional digits count or range | number | string |
"*" |
digitsOptional |
Allow skipping fractional digits | boolean |
true |
enforceDigitsOnBlur |
Force show fractional digits on blur | boolean |
false |
allowMinus |
Permit minus sign | boolean |
true |
negationSymbol |
Symbols for negative (e.g. { front: "-", back: "" } ) |
object |
{ front: "-", back: "" } |
prefix |
Static text prepended | string |
"" |
suffix |
Static text appended | string |
"" |
SetMaxOnOverflow |
Clamp value at max if exceeded |
boolean |
false |
min |
Minimum allowed (numeric/datetime) | string | number |
— |
max |
Maximum allowed (numeric/datetime) | string | number |
— |
step |
Ctrl+↑/↓ increment step (numeric) |
number |
1 |
repeat |
Repeat mask N times or "*" for infinite |
number | string |
0 |
greedy |
Greedy vs non-greedy repeat | boolean |
false |
keepStatic |
Delay switching in alternator/multi-mask scenarios | boolean | null |
(multi-mask: true ) |
importDataAttributes |
Read HTML data-inputmask-* attrs |
boolean |
true |
supportsInputType |
Allow masking on specified inputmode types |
string[] |
["text","tel","url", "password","search"] |
ignorables |
Key codes to ignore | number[] |
— |
prefillYear |
Pre-fill century in datetime alias | boolean |
true |
casing |
Force letter casing: "upper" , "lower" , "title" |
string |
— |
inputmode |
Hint for on-screen keyboards (HTML inputmode ) |
string |
"verbatim" |