Masked input component for React with format characters, cursor management, and advanced configuration
npx @tessl/cli install tessl/npm-react-input-mask@2.0.00
# React Input Mask
1
2
React Input Mask is a masked input component for React that enables developers to create input fields with predefined formatting patterns (masks) for common data types like phone numbers, dates, ZIP codes, and other structured text formats.
3
4
## Package Information
5
6
- **Package Name**: react-input-mask
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES6+ with Babel transpilation)
9
- **Installation**: `npm install react-input-mask`
10
11
## Core Imports
12
13
```javascript
14
import InputMask from "react-input-mask";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const InputMask = require("react-input-mask");
21
```
22
23
UMD (browser global):
24
25
```html
26
<script src="https://unpkg.com/react-input-mask/dist/react-input-mask.min.js"></script>
27
<!-- Available as window.ReactInputMask -->
28
```
29
30
## Basic Usage
31
32
```javascript
33
import React from "react";
34
import InputMask from "react-input-mask";
35
36
function PhoneInput() {
37
const [value, setValue] = React.useState("");
38
39
return (
40
<InputMask
41
mask="+1 (999) 999-9999"
42
value={value}
43
onChange={(e) => setValue(e.target.value)}
44
placeholder="Enter phone number"
45
/>
46
);
47
}
48
49
// Date input with custom mask character
50
function DateInput() {
51
return (
52
<InputMask
53
mask="99/99/9999"
54
maskChar=" "
55
placeholder="MM/DD/YYYY"
56
/>
57
);
58
}
59
```
60
61
## Architecture
62
63
React Input Mask consists of a single React component that wraps standard HTML input elements:
64
65
- **InputElement Component**: Main component that handles all masking logic
66
- **Mask Parser**: Converts mask strings into structured mask options
67
- **String Utilities**: Functions for formatting, validation, and cursor management
68
- **Event Handling**: Comprehensive input event processing with masking application
69
- **Browser Compatibility**: Cross-browser support including IE8+ with autofill detection
70
71
## Capabilities
72
73
### Basic Masking
74
75
Create input fields with predefined format patterns using format characters.
76
77
```javascript { .api }
78
/**
79
* React Input Mask Component - Main export
80
* @param props - Component props including mask, value, and standard input props
81
* @returns React element with masked input functionality
82
*/
83
function InputMask(props: InputMaskProps): React.ReactElement;
84
85
interface InputMaskProps {
86
/** Mask pattern string using format characters (9, a, *) */
87
mask?: string;
88
/** Character to show in unfilled mask positions (default: '_') */
89
maskChar?: string | null;
90
/** Custom format character definitions */
91
formatChars?: { [key: string]: string };
92
/** Show mask when input is empty and unfocused */
93
alwaysShowMask?: boolean;
94
/** Ref callback for accessing input DOM node */
95
inputRef?: (ref: HTMLInputElement) => void;
96
/** Advanced callback for custom masking logic (experimental) */
97
beforeMaskedValueChange?: BeforeMaskedValueChangeHandler;
98
/** Render prop for custom input components (experimental) */
99
children?: (inputProps: any) => React.ReactElement;
100
101
// Standard HTML input props
102
value?: string;
103
defaultValue?: string;
104
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
105
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
106
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
107
onPaste?: (event: React.ClipboardEvent<HTMLInputElement>) => void;
108
onMouseDown?: (event: React.MouseEvent<HTMLInputElement>) => void;
109
disabled?: boolean;
110
readOnly?: boolean;
111
placeholder?: string;
112
className?: string;
113
style?: React.CSSProperties;
114
[key: string]: any; // All other HTML input attributes
115
}
116
```
117
118
**Usage Examples:**
119
120
```javascript
121
// Phone number mask
122
<InputMask mask="+1 (999) 999-9999" />
123
124
// Date mask
125
<InputMask mask="99/99/9999" />
126
127
// Social Security Number
128
<InputMask mask="999-99-9999" />
129
130
// Credit Card
131
<InputMask mask="9999 9999 9999 9999" />
132
133
// Custom format with letters and numbers
134
<InputMask mask="aa-999-aa" />
135
```
136
137
### Format Characters
138
139
Define input patterns using built-in format characters or create custom ones.
140
141
```javascript { .api }
142
/**
143
* Default format characters for common input patterns
144
*/
145
interface DefaultFormatChars {
146
/** Digits 0-9 */
147
'9': '[0-9]';
148
/** Letters A-Z, a-z */
149
'a': '[A-Za-z]';
150
/** Alphanumeric A-Z, a-z, 0-9 */
151
'*': '[A-Za-z0-9]';
152
}
153
154
/**
155
* Custom format character definitions
156
* Keys are format characters, values are RegExp strings
157
*/
158
interface FormatChars {
159
[formatChar: string]: string;
160
}
161
```
162
163
**Usage Examples:**
164
165
```javascript
166
// Using default format characters
167
<InputMask mask="999-aaa-***" />
168
169
// Custom format characters
170
<InputMask
171
mask="yyy-xxx"
172
formatChars={{
173
'y': '[0-9A-F]', // Hexadecimal
174
'x': '[AEIOU]' // Vowels only
175
}}
176
/>
177
```
178
179
### Mask Character Customization
180
181
Control the appearance of unfilled mask positions.
182
183
```javascript { .api }
184
/**
185
* Mask character options for unfilled positions
186
*/
187
type MaskChar = string | null;
188
```
189
190
**Usage Examples:**
191
192
```javascript
193
// Default underscore mask character
194
<InputMask mask="999-999-9999" />
195
// Shows: ___-___-____
196
197
// Custom mask character
198
<InputMask mask="999-999-9999" maskChar=" " />
199
// Shows: - -
200
201
// No mask character (empty spaces)
202
<InputMask mask="999-999-9999" maskChar={null} />
203
// Shows:
204
205
// Always show mask even when empty
206
<InputMask mask="999-999-9999" alwaysShowMask />
207
```
208
209
### Escape Characters
210
211
Include literal characters in masks that would otherwise be interpreted as format characters.
212
213
**Usage Examples:**
214
215
```javascript
216
// German phone with literal +49 prefix
217
<InputMask mask="+4\\9 99 999 99" />
218
219
// Email-like pattern with literal @ and .
220
<InputMask mask="aaa\\@aaa\\.aaa" />
221
```
222
223
### Advanced Masking Logic
224
225
Implement complex masking behavior with the beforeMaskedValueChange callback.
226
227
```javascript { .api }
228
/**
229
* Advanced masking callback for custom logic (experimental)
230
* @param newState - New input state with value and selection
231
* @param oldState - Previous input state
232
* @param userInput - Raw user input string (null for non-user changes)
233
* @param maskOptions - Current mask configuration
234
* @returns Modified state with value and selection
235
*/
236
type BeforeMaskedValueChangeHandler = (
237
newState: MaskedValueChangeState,
238
oldState: MaskedValueChangeState,
239
userInput: string | null,
240
maskOptions: MaskOptions
241
) => MaskedValueChangeState;
242
243
interface MaskedValueChangeState {
244
/** Current input value */
245
value: string;
246
/** Current selection (null on blur or before mount) */
247
selection: { start: number; end: number } | null;
248
}
249
250
interface MaskOptions {
251
/** Parsed mask string */
252
mask: string;
253
/** Current mask character */
254
maskChar: string;
255
/** Whether to always show mask */
256
alwaysShowMask: boolean;
257
/** Format character definitions */
258
formatChars: { [key: string]: string };
259
/** Array of permanent character positions */
260
permanents: number[];
261
}
262
```
263
264
**Usage Examples:**
265
266
```javascript
267
// ZIP code with conditional dash
268
function ZipCodeInput() {
269
const beforeMaskedValueChange = (newState, oldState, userInput) => {
270
let { value } = newState;
271
let { selection } = newState;
272
273
// Remove trailing dash if not entered by user
274
if (value.endsWith('-') && userInput !== '-' && !oldState.value.endsWith('-')) {
275
if (selection && selection.start === value.length) {
276
selection = { start: selection.start - 1, end: selection.start - 1 };
277
}
278
value = value.slice(0, -1);
279
}
280
281
return { value, selection };
282
};
283
284
return (
285
<InputMask
286
mask="99999-9999"
287
maskChar={null}
288
beforeMaskedValueChange={beforeMaskedValueChange}
289
/>
290
);
291
}
292
```
293
294
### Custom Input Components
295
296
Use custom input components with render props pattern.
297
298
```javascript { .api }
299
/**
300
* Render prop function for custom input components (experimental)
301
* @param inputProps - Props to spread onto custom input component
302
* @returns Custom input element
303
*/
304
type ChildrenRenderProp = (inputProps: InputProps) => React.ReactElement;
305
306
interface InputProps {
307
// All props except controlled ones (onChange, onPaste, etc.)
308
[key: string]: any;
309
}
310
```
311
312
**Usage Examples:**
313
314
```javascript
315
import { TextField } from '@mui/material';
316
317
// Material-UI integration
318
function MaterialPhoneInput() {
319
return (
320
<InputMask mask="+1 (999) 999-9999" value={value} onChange={onChange}>
321
{(inputProps) => (
322
<TextField
323
{...inputProps}
324
label="Phone Number"
325
variant="outlined"
326
/>
327
)}
328
</InputMask>
329
);
330
}
331
332
// Custom styled input
333
function StyledInput() {
334
return (
335
<InputMask mask="99/99/9999">
336
{(inputProps) => (
337
<input
338
{...inputProps}
339
className="custom-date-input"
340
style={{ border: '2px solid blue' }}
341
/>
342
)}
343
</InputMask>
344
);
345
}
346
```
347
348
### Input Reference Management
349
350
Access the underlying input DOM node for focus, selection, and other operations.
351
352
```javascript { .api }
353
/**
354
* Input reference callback
355
* @param ref - HTML input element reference
356
*/
357
type InputRefCallback = (ref: HTMLInputElement | null) => void;
358
```
359
360
**Usage Examples:**
361
362
```javascript
363
function FocusableInput() {
364
const inputRef = React.useRef(null);
365
366
const focusInput = () => {
367
if (inputRef.current) {
368
inputRef.current.focus();
369
}
370
};
371
372
return (
373
<div>
374
<InputMask
375
mask="999-999-9999"
376
inputRef={(ref) => { inputRef.current = ref; }}
377
/>
378
<button onClick={focusInput}>Focus Input</button>
379
</div>
380
);
381
}
382
```
383
384
## Type Definitions
385
386
```javascript { .api }
387
/**
388
* Main InputMask component props interface
389
*/
390
interface InputMaskProps {
391
mask?: string;
392
maskChar?: string | null;
393
formatChars?: { [key: string]: string };
394
alwaysShowMask?: boolean;
395
inputRef?: (ref: HTMLInputElement | null) => void;
396
beforeMaskedValueChange?: BeforeMaskedValueChangeHandler;
397
children?: (inputProps: any) => React.ReactElement;
398
value?: string;
399
defaultValue?: string;
400
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
401
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
402
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
403
onPaste?: (event: React.ClipboardEvent<HTMLInputElement>) => void;
404
onMouseDown?: (event: React.MouseEvent<HTMLInputElement>) => void;
405
disabled?: boolean;
406
readOnly?: boolean;
407
placeholder?: string;
408
className?: string;
409
style?: React.CSSProperties;
410
[key: string]: any;
411
}
412
413
/**
414
* State object for beforeMaskedValueChange callback
415
*/
416
interface MaskedValueChangeState {
417
value: string;
418
selection: { start: number; end: number } | null;
419
}
420
421
/**
422
* Mask configuration options
423
*/
424
interface MaskOptions {
425
mask: string;
426
maskChar: string;
427
alwaysShowMask: boolean;
428
formatChars: { [key: string]: string };
429
permanents: number[];
430
}
431
432
/**
433
* Handler for advanced masking logic
434
*/
435
type BeforeMaskedValueChangeHandler = (
436
newState: MaskedValueChangeState,
437
oldState: MaskedValueChangeState,
438
userInput: string | null,
439
maskOptions: MaskOptions
440
) => MaskedValueChangeState;
441
442
/**
443
* Default format character definitions
444
*/
445
interface DefaultFormatChars {
446
'9': '[0-9]';
447
'a': '[A-Za-z]';
448
'*': '[A-Za-z0-9]';
449
}
450
```
451
452
## Common Use Cases
453
454
### Phone Numbers
455
456
```javascript
457
// US phone number
458
<InputMask mask="+1 (999) 999-9999" />
459
460
// International format
461
<InputMask mask="+99 999 999 9999" />
462
463
// Simple format
464
<InputMask mask="999-999-9999" />
465
```
466
467
### Dates
468
469
```javascript
470
// US date format
471
<InputMask mask="99/99/9999" placeholder="MM/DD/YYYY" />
472
473
// European date format
474
<InputMask mask="99.99.9999" placeholder="DD.MM.YYYY" />
475
476
// ISO date format
477
<InputMask mask="9999-99-99" placeholder="YYYY-MM-DD" />
478
```
479
480
### Identification Numbers
481
482
```javascript
483
// Social Security Number
484
<InputMask mask="999-99-9999" />
485
486
// Credit Card
487
<InputMask mask="9999 9999 9999 9999" />
488
489
// ZIP Code
490
<InputMask mask="99999" />
491
492
// ZIP+4
493
<InputMask mask="99999-9999" />
494
```
495
496
### Custom Patterns
497
498
```javascript
499
// License plate (letters and numbers)
500
<InputMask mask="aaa-999" />
501
502
// Product code
503
<InputMask mask="***-***-***" />
504
505
// Custom format with specific characters
506
<InputMask
507
mask="HH:MM"
508
formatChars={{
509
'H': '[0-2]',
510
'M': '[0-5]'
511
}}
512
/>
513
```
514
515
## Browser Compatibility
516
517
- **Modern Browsers**: Full feature support
518
- **Internet Explorer**: 8+ with polyfills
519
- **Mobile Browsers**: iOS Safari, Android Chrome with touch-specific optimizations
520
- **Autofill**: Browser autofill detection and compatibility
521
- **Accessibility**: Screen reader and keyboard navigation support
522
523
## Dependencies
524
525
- **react**: >=0.14.0 (peer dependency)
526
- **react-dom**: >=0.14.0 (peer dependency)
527
- **invariant**: ^2.2.4 (runtime assertions)
528
- **warning**: ^4.0.2 (development warnings)