React input component that accepts mask patterns for formatted text input
npx @tessl/cli install tessl/npm-react-text-mask@5.5.00
# React Text Mask
1
2
React Text Mask is a React input component that provides text masking functionality, allowing developers to create formatted input fields for phone numbers, dates, currency, zip codes, and other structured data types. It offers a flexible mask API that supports both static patterns and dynamic functions, with real-time input formatting and full compatibility with standard HTML input props.
3
4
## Package Information
5
6
- **Package Name**: react-text-mask
7
- **Package Type**: npm
8
- **Language**: JavaScript (with PropTypes)
9
- **Installation**: `npm install react-text-mask`
10
11
## Core Imports
12
13
```javascript
14
import MaskedInput from "react-text-mask";
15
```
16
17
For the utility function:
18
19
```javascript
20
import MaskedInput, { conformToMask } from "react-text-mask";
21
```
22
23
CommonJS:
24
25
```javascript
26
const MaskedInput = require("react-text-mask");
27
const { conformToMask } = require("react-text-mask");
28
```
29
30
## Basic Usage
31
32
```javascript
33
import React from "react";
34
import MaskedInput from "react-text-mask";
35
36
export default function PhoneForm() {
37
return (
38
<div>
39
<MaskedInput
40
mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
41
className="form-control"
42
placeholder="Enter a phone number"
43
guide={false}
44
onBlur={() => {}}
45
onChange={() => {}}
46
/>
47
</div>
48
);
49
}
50
```
51
52
**Important**: React Text Mask only supports input types: `text`, `tel`, `url`, `password`, and `search`. Other types like `email` or `number` are not supported due to browser API limitations.
53
54
## Architecture
55
56
React Text Mask is built around several key concepts:
57
58
- **MaskedInput Component**: Main React component that wraps input elements with masking functionality
59
- **Mask Patterns**: Flexible definition system using arrays of strings and regex patterns
60
- **Conforming Engine**: Core text transformation engine that applies masks to user input
61
- **Input Element Wrapping**: Works with any input-like element through render prop pattern
62
- **Real-time Processing**: Handles user input, paste operations, and auto-fill scenarios
63
64
### Component Lifecycle
65
66
The MaskedInput component has specific behavior during its lifecycle:
67
68
- **componentDidMount**: Initializes the text mask when the component first mounts by calling `initTextMask()`
69
- **componentDidUpdate**: Reinitializes the mask when relevant props change (comparison logic detailed):
70
- `mask` pattern changes (string comparison: `mask.toString() !== prevProps.mask.toString()`)
71
- `pipe` function changes (function string comparison for functions, null/undefined state changes)
72
- Settings changes: `guide`, `placeholderChar`, `showMask` (shallow object comparison)
73
- Input `value` differs from actual input element value (`value !== this.inputElement.value`)
74
- Only reinitializes if any of these conditions are true (`isValueChanged || isSettingChanged`)
75
- **Optimization**: Uses React.PureComponent for automatic shallow comparison of props to prevent unnecessary re-renders
76
77
## Capabilities
78
79
### MaskedInput Component
80
81
Main React component that wraps input elements with text masking functionality.
82
83
```javascript { .api }
84
/**
85
* React component for masked input functionality
86
* Extends React.PureComponent with text masking capabilities
87
*/
88
class MaskedInput extends React.PureComponent {
89
constructor(props: MaskedInputProps);
90
91
/** Internal methods (advanced usage) */
92
setRef(inputElement: HTMLInputElement): void;
93
initTextMask(): void;
94
onChange(event: Event): void;
95
onBlur(event: Event): void;
96
}
97
98
interface MaskedInputProps {
99
/** Mask pattern definition (required) */
100
mask: MaskPattern | MaskFunction | boolean | MaskObject;
101
/** Shows placeholder characters when true (default: true) */
102
guide?: boolean;
103
/** Controlled input value */
104
value?: string | number;
105
/** Post-processing function for conformed values */
106
pipe?: PipeFunction;
107
/** Character for fillable spots (default: '_') */
108
placeholderChar?: string;
109
/** Prevents character position changes (default: false) */
110
keepCharPositions?: boolean;
111
/** Shows mask as placeholder when input empty (default: false) */
112
showMask?: boolean;
113
/** Custom render prop for input element (default: renders standard <input>) */
114
render?: RenderFunction;
115
/** Standard HTML input event handlers */
116
onBlur?: (event: Event) => void;
117
onChange?: (event: Event) => void;
118
/** All other standard HTML input props are supported */
119
[key: string]: any;
120
}
121
122
type MaskPattern = (string | RegExp)[];
123
124
type MaskFunction = (rawValue: string, config: MaskConfig) => MaskPattern | false;
125
126
interface MaskObject {
127
mask: MaskPattern | MaskFunction;
128
pipe: PipeFunction;
129
}
130
131
interface MaskConfig {
132
currentCaretPosition: number;
133
previousConformedValue: string;
134
placeholderChar: string;
135
}
136
137
type PipeFunction = (
138
conformedValue: string,
139
config: PipeConfig
140
) => false | string | PipeResult;
141
142
interface PipeConfig extends MaskConfig {
143
rawValue: string;
144
guide: boolean;
145
placeholderChar: string;
146
pipe: PipeFunction;
147
placeholder: string;
148
keepCharPositions: boolean;
149
}
150
151
interface PipeResult {
152
value: string;
153
indexesOfPipedChars: number[];
154
}
155
156
type RenderFunction = (
157
ref: (element: HTMLInputElement) => void,
158
props: InputProps
159
) => React.ReactElement;
160
161
interface InputProps {
162
onBlur: (event: Event) => void;
163
onChange: (event: Event) => void;
164
defaultValue: string | number;
165
[key: string]: any;
166
}
167
168
/** Default render function when none provided */
169
const defaultRender: RenderFunction = (ref, props) => <input ref={ref} {...props} />;
170
```
171
172
**Usage Examples:**
173
174
```javascript
175
import React from "react";
176
import MaskedInput from "react-text-mask";
177
178
// Basic phone number mask
179
<MaskedInput
180
mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
181
placeholder="Enter phone number"
182
/>
183
184
// Currency mask with pipe function
185
<MaskedInput
186
mask={[/\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/]}
187
pipe={(conformedValue) => {
188
const numericValue = conformedValue.replace(/\D/g, '');
189
return '$' + numericValue;
190
}}
191
/>
192
193
// Dynamic mask using function
194
<MaskedInput
195
mask={(rawValue) => {
196
if (rawValue.startsWith('1')) {
197
// US phone format
198
return ['1', ' ', '(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
199
} else {
200
// Regular phone format
201
return ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
202
}
203
}}
204
/>
205
206
// Custom render with styled-components
207
<MaskedInput
208
mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
209
render={(ref, props) => (
210
<MyStyledInput innerRef={ref} {...props} />
211
)}
212
/>
213
214
// Disabled masking
215
<MaskedInput mask={false} />
216
```
217
218
### Mask Patterns
219
220
Mask patterns define how user input will be formatted and can be static arrays or dynamic functions.
221
222
#### Static Array Masks
223
224
```javascript { .api }
225
/**
226
* Static mask pattern using array of strings and regular expressions
227
* - Strings represent literal characters that appear in the formatted output
228
* - RegExp patterns define validation rules for user input at that position
229
*/
230
type MaskPattern = (string | RegExp)[];
231
```
232
233
**Examples:**
234
235
```javascript
236
// Phone number: (555) 123-4567
237
const phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
238
239
// Date: MM/DD/YYYY
240
const dateMask = [/[01]/, /\d/, '/', /[0-3]/, /\d/, '/', /[12]/, /\d/, /\d/, /\d/];
241
242
// ZIP code: 12345 or 12345-6789
243
const zipMask = [/\d/, /\d/, /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
244
```
245
246
#### Dynamic Function Masks
247
248
```javascript { .api }
249
/**
250
* Dynamic mask function for variable-length or conditional formatting
251
* @param rawValue - Current unformatted input value
252
* @param config - Configuration object with caret position and previous value
253
* @returns Mask pattern array or false to disable masking
254
*/
255
type MaskFunction = (rawValue: string, config: MaskConfig) => MaskPattern | false;
256
257
interface MaskConfig {
258
currentCaretPosition: number;
259
previousConformedValue: string;
260
placeholderChar: string;
261
}
262
```
263
264
**Usage Example:**
265
266
```javascript
267
// Email-like mask that grows with input
268
const emailMask = (rawValue) => {
269
const atIndex = rawValue.indexOf('@');
270
if (atIndex === -1) {
271
// Before @ symbol
272
return Array(rawValue.length).fill(/[a-zA-Z0-9]/);
273
} else {
274
// After @ symbol, add domain pattern
275
const beforeAt = Array(atIndex).fill(/[a-zA-Z0-9]/);
276
const afterAt = ['@'].concat(Array(rawValue.length - atIndex - 1).fill(/[a-zA-Z0-9.]/));
277
return beforeAt.concat(afterAt);
278
}
279
};
280
```
281
282
### Pipe Functions
283
284
Post-processing functions that modify the conformed value before display.
285
286
```javascript { .api }
287
/**
288
* Pipe function for post-processing conformed values
289
* @param conformedValue - Value after mask has been applied
290
* @param config - Configuration object with input context
291
* @returns false to reject, string for simple modification, or object for complex changes
292
*/
293
type PipeFunction = (
294
conformedValue: string,
295
config: PipeConfig
296
) => false | string | PipeResult;
297
298
interface PipeConfig extends MaskConfig {
299
rawValue: string;
300
guide: boolean;
301
placeholderChar: string;
302
pipe: PipeFunction;
303
placeholder: string;
304
keepCharPositions: boolean;
305
}
306
307
interface PipeResult {
308
/** The modified value */
309
value: string;
310
/** Indexes of characters added by the pipe function */
311
indexesOfPipedChars: number[];
312
}
313
```
314
315
**Usage Examples:**
316
317
```javascript
318
// Simple uppercase transformation
319
const uppercasePipe = (conformedValue) => {
320
return conformedValue.toUpperCase();
321
};
322
323
// Currency formatting with dollar sign
324
const currencyPipe = (conformedValue) => {
325
const numericValue = conformedValue.replace(/\D/g, '');
326
if (!numericValue) return '';
327
328
return {
329
value: '$' + numericValue,
330
indexesOfPipedChars: [0] // Dollar sign added at index 0
331
};
332
};
333
334
// Validation pipe that rejects invalid input
335
const validationPipe = (conformedValue) => {
336
if (conformedValue.includes('000')) {
337
return false; // Reject values containing '000'
338
}
339
return conformedValue;
340
};
341
```
342
343
### Conform To Mask Utility
344
345
Standalone utility function for applying masks to text without React components.
346
347
```javascript { .api }
348
/**
349
* Utility function to transform text according to mask pattern
350
* @param text - Input text to conform
351
* @param mask - Mask pattern array
352
* @param config - Optional configuration object
353
* @returns Object with conformed value and metadata
354
*/
355
function conformToMask(
356
text: string,
357
mask: MaskPattern,
358
config?: ConformConfig
359
): ConformResult;
360
361
interface ConformConfig {
362
/** Guide mode setting (default: true) */
363
guide?: boolean;
364
/** Previous conformed value for comparison */
365
previousConformedValue?: string;
366
/** Placeholder character (default: '_') */
367
placeholderChar?: string;
368
/** Full placeholder string */
369
placeholder?: string;
370
/** Current cursor position */
371
currentCaretPosition?: number;
372
/** Keep character positions setting */
373
keepCharPositions?: boolean;
374
}
375
376
interface ConformResult {
377
/** The text after applying mask */
378
conformedValue: string;
379
/** Metadata about the operation */
380
meta: {
381
/** Whether any input characters were rejected */
382
someCharsRejected: boolean;
383
};
384
}
385
```
386
387
**Usage Examples:**
388
389
```javascript
390
import { conformToMask } from "react-text-mask";
391
392
// Basic usage
393
const phoneNumber = '5551234444';
394
const phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
395
396
const result = conformToMask(phoneNumber, phoneMask, { guide: false });
397
console.log(result.conformedValue); // "(555) 123-4444"
398
console.log(result.meta.someCharsRejected); // false
399
400
// With configuration
401
const partialResult = conformToMask('555', phoneMask, {
402
guide: true,
403
placeholderChar: '*'
404
});
405
console.log(partialResult.conformedValue); // "(555) ***-****"
406
```
407
408
## Input Type Support
409
410
React Text Mask supports the following HTML input types:
411
412
- `text` (default and recommended)
413
- `tel`
414
- `url`
415
- `password`
416
- `search`
417
418
**Note**: Other input types like `email` or `number` are not supported due to browser API limitations. Use `type="text"` with appropriate masks for these scenarios.
419
420
## Common Patterns
421
422
### Phone Numbers
423
424
```javascript
425
// US phone number: (555) 123-4567
426
const usMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
427
428
// International format: +1 (555) 123-4567
429
const internationalMask = ['+', /\d/, ' ', '(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
430
```
431
432
### Dates
433
434
```javascript
435
// MM/DD/YYYY
436
const dateMask = [/[01]/, /\d/, '/', /[0-3]/, /\d/, '/', /[12]/, /\d/, /\d/, /\d/];
437
438
// DD-MM-YYYY
439
const europeanDateMask = [/[0-3]/, /\d/, '-', /[01]/, /\d/, '-', /[12]/, /\d/, /\d/, /\d/];
440
```
441
442
### Credit Cards
443
444
```javascript
445
// 4-4-4-4 format
446
const creditCardMask = [
447
/\d/, /\d/, /\d/, /\d/, '-',
448
/\d/, /\d/, /\d/, /\d/, '-',
449
/\d/, /\d/, /\d/, /\d/, '-',
450
/\d/, /\d/, /\d/, /\d/
451
];
452
```
453
454
### Social Security Numbers
455
456
```javascript
457
// XXX-XX-XXXX
458
const ssnMask = [/\d/, /\d/, /\d/, '-', /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
459
```