CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-text-mask

React input component that accepts mask patterns for formatted text input

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

React Text Mask

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.

Package Information

  • Package Name: react-text-mask
  • Package Type: npm
  • Language: JavaScript (with PropTypes)
  • Installation: npm install react-text-mask

Core Imports

import MaskedInput from "react-text-mask";

For the utility function:

import MaskedInput, { conformToMask } from "react-text-mask";

CommonJS:

const MaskedInput = require("react-text-mask");
const { conformToMask } = require("react-text-mask");

Basic Usage

import React from "react";
import MaskedInput from "react-text-mask";

export default function PhoneForm() {
  return (
    <div>
      <MaskedInput
        mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
        className="form-control"
        placeholder="Enter a phone number"
        guide={false}
        onBlur={() => {}}
        onChange={() => {}}
      />
    </div>
  );
}

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.

Architecture

React Text Mask is built around several key concepts:

  • MaskedInput Component: Main React component that wraps input elements with masking functionality
  • Mask Patterns: Flexible definition system using arrays of strings and regex patterns
  • Conforming Engine: Core text transformation engine that applies masks to user input
  • Input Element Wrapping: Works with any input-like element through render prop pattern
  • Real-time Processing: Handles user input, paste operations, and auto-fill scenarios

Component Lifecycle

The MaskedInput component has specific behavior during its lifecycle:

  • componentDidMount: Initializes the text mask when the component first mounts by calling initTextMask()
  • componentDidUpdate: Reinitializes the mask when relevant props change (comparison logic detailed):
    • mask pattern changes (string comparison: mask.toString() !== prevProps.mask.toString())
    • pipe function changes (function string comparison for functions, null/undefined state changes)
    • Settings changes: guide, placeholderChar, showMask (shallow object comparison)
    • Input value differs from actual input element value (value !== this.inputElement.value)
    • Only reinitializes if any of these conditions are true (isValueChanged || isSettingChanged)
  • Optimization: Uses React.PureComponent for automatic shallow comparison of props to prevent unnecessary re-renders

Capabilities

MaskedInput Component

Main React component that wraps input elements with text masking functionality.

/**
 * React component for masked input functionality
 * Extends React.PureComponent with text masking capabilities
 */
class MaskedInput extends React.PureComponent {
  constructor(props: MaskedInputProps);
  
  /** Internal methods (advanced usage) */
  setRef(inputElement: HTMLInputElement): void;
  initTextMask(): void;
  onChange(event: Event): void;
  onBlur(event: Event): void;
}

interface MaskedInputProps {
  /** Mask pattern definition (required) */
  mask: MaskPattern | MaskFunction | boolean | MaskObject;
  /** Shows placeholder characters when true (default: true) */
  guide?: boolean;
  /** Controlled input value */
  value?: string | number;
  /** Post-processing function for conformed values */
  pipe?: PipeFunction;
  /** Character for fillable spots (default: '_') */
  placeholderChar?: string;
  /** Prevents character position changes (default: false) */
  keepCharPositions?: boolean;
  /** Shows mask as placeholder when input empty (default: false) */
  showMask?: boolean;
  /** Custom render prop for input element (default: renders standard <input>) */
  render?: RenderFunction;
  /** Standard HTML input event handlers */
  onBlur?: (event: Event) => void;
  onChange?: (event: Event) => void;
  /** All other standard HTML input props are supported */
  [key: string]: any;
}

type MaskPattern = (string | RegExp)[];

type MaskFunction = (rawValue: string, config: MaskConfig) => MaskPattern | false;

interface MaskObject {
  mask: MaskPattern | MaskFunction;
  pipe: PipeFunction;
}

interface MaskConfig {
  currentCaretPosition: number;
  previousConformedValue: string;
  placeholderChar: string;
}

type PipeFunction = (
  conformedValue: string,
  config: PipeConfig
) => false | string | PipeResult;

interface PipeConfig extends MaskConfig {
  rawValue: string;
  guide: boolean;
  placeholderChar: string;
  pipe: PipeFunction;
  placeholder: string;
  keepCharPositions: boolean;
}

interface PipeResult {
  value: string;
  indexesOfPipedChars: number[];
}

type RenderFunction = (
  ref: (element: HTMLInputElement) => void,
  props: InputProps
) => React.ReactElement;

interface InputProps {
  onBlur: (event: Event) => void;
  onChange: (event: Event) => void;
  defaultValue: string | number;
  [key: string]: any;
}

/** Default render function when none provided */
const defaultRender: RenderFunction = (ref, props) => <input ref={ref} {...props} />;

Usage Examples:

import React from "react";
import MaskedInput from "react-text-mask";

// Basic phone number mask
<MaskedInput
  mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
  placeholder="Enter phone number"
/>

// Currency mask with pipe function
<MaskedInput
  mask={[/\d/, /\d/, /\d/, /\d/, /\d/, /\d/, /\d/]}
  pipe={(conformedValue) => {
    const numericValue = conformedValue.replace(/\D/g, '');
    return '$' + numericValue;
  }}
/>

// Dynamic mask using function
<MaskedInput
  mask={(rawValue) => {
    if (rawValue.startsWith('1')) {
      // US phone format
      return ['1', ' ', '(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
    } else {
      // Regular phone format
      return ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
    }
  }}
/>

// Custom render with styled-components
<MaskedInput
  mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
  render={(ref, props) => (
    <MyStyledInput innerRef={ref} {...props} />
  )}
/>

// Disabled masking
<MaskedInput mask={false} />

Mask Patterns

Mask patterns define how user input will be formatted and can be static arrays or dynamic functions.

Static Array Masks

/**
 * Static mask pattern using array of strings and regular expressions
 * - Strings represent literal characters that appear in the formatted output
 * - RegExp patterns define validation rules for user input at that position
 */
type MaskPattern = (string | RegExp)[];

Examples:

// Phone number: (555) 123-4567
const phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];

// Date: MM/DD/YYYY
const dateMask = [/[01]/, /\d/, '/', /[0-3]/, /\d/, '/', /[12]/, /\d/, /\d/, /\d/];

// ZIP code: 12345 or 12345-6789
const zipMask = [/\d/, /\d/, /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];

Dynamic Function Masks

/**
 * Dynamic mask function for variable-length or conditional formatting
 * @param rawValue - Current unformatted input value
 * @param config - Configuration object with caret position and previous value
 * @returns Mask pattern array or false to disable masking
 */
type MaskFunction = (rawValue: string, config: MaskConfig) => MaskPattern | false;

interface MaskConfig {
  currentCaretPosition: number;
  previousConformedValue: string;
  placeholderChar: string;
}

Usage Example:

// Email-like mask that grows with input
const emailMask = (rawValue) => {
  const atIndex = rawValue.indexOf('@');
  if (atIndex === -1) {
    // Before @ symbol
    return Array(rawValue.length).fill(/[a-zA-Z0-9]/);
  } else {
    // After @ symbol, add domain pattern
    const beforeAt = Array(atIndex).fill(/[a-zA-Z0-9]/);
    const afterAt = ['@'].concat(Array(rawValue.length - atIndex - 1).fill(/[a-zA-Z0-9.]/));
    return beforeAt.concat(afterAt);
  }
};

Pipe Functions

Post-processing functions that modify the conformed value before display.

/**
 * Pipe function for post-processing conformed values
 * @param conformedValue - Value after mask has been applied
 * @param config - Configuration object with input context
 * @returns false to reject, string for simple modification, or object for complex changes
 */
type PipeFunction = (
  conformedValue: string,
  config: PipeConfig
) => false | string | PipeResult;

interface PipeConfig extends MaskConfig {
  rawValue: string;
  guide: boolean;
  placeholderChar: string;
  pipe: PipeFunction;
  placeholder: string;
  keepCharPositions: boolean;
}

interface PipeResult {
  /** The modified value */
  value: string;
  /** Indexes of characters added by the pipe function */
  indexesOfPipedChars: number[];
}

Usage Examples:

// Simple uppercase transformation
const uppercasePipe = (conformedValue) => {
  return conformedValue.toUpperCase();
};

// Currency formatting with dollar sign
const currencyPipe = (conformedValue) => {
  const numericValue = conformedValue.replace(/\D/g, '');
  if (!numericValue) return '';
  
  return {
    value: '$' + numericValue,
    indexesOfPipedChars: [0] // Dollar sign added at index 0
  };
};

// Validation pipe that rejects invalid input
const validationPipe = (conformedValue) => {
  if (conformedValue.includes('000')) {
    return false; // Reject values containing '000'
  }
  return conformedValue;
};

Conform To Mask Utility

Standalone utility function for applying masks to text without React components.

/**
 * Utility function to transform text according to mask pattern
 * @param text - Input text to conform
 * @param mask - Mask pattern array
 * @param config - Optional configuration object
 * @returns Object with conformed value and metadata
 */
function conformToMask(
  text: string,
  mask: MaskPattern,
  config?: ConformConfig
): ConformResult;

interface ConformConfig {
  /** Guide mode setting (default: true) */
  guide?: boolean;
  /** Previous conformed value for comparison */
  previousConformedValue?: string;
  /** Placeholder character (default: '_') */
  placeholderChar?: string;
  /** Full placeholder string */
  placeholder?: string;
  /** Current cursor position */
  currentCaretPosition?: number;
  /** Keep character positions setting */
  keepCharPositions?: boolean;
}

interface ConformResult {
  /** The text after applying mask */
  conformedValue: string;
  /** Metadata about the operation */
  meta: {
    /** Whether any input characters were rejected */
    someCharsRejected: boolean;
  };
}

Usage Examples:

import { conformToMask } from "react-text-mask";

// Basic usage
const phoneNumber = '5551234444';
const phoneMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];

const result = conformToMask(phoneNumber, phoneMask, { guide: false });
console.log(result.conformedValue); // "(555) 123-4444"
console.log(result.meta.someCharsRejected); // false

// With configuration
const partialResult = conformToMask('555', phoneMask, {
  guide: true,
  placeholderChar: '*'
});
console.log(partialResult.conformedValue); // "(555) ***-****"

Input Type Support

React Text Mask supports the following HTML input types:

  • text (default and recommended)
  • tel
  • url
  • password
  • search

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.

Common Patterns

Phone Numbers

// US phone number: (555) 123-4567
const usMask = ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];

// International format: +1 (555) 123-4567
const internationalMask = ['+', /\d/, ' ', '(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];

Dates

// MM/DD/YYYY
const dateMask = [/[01]/, /\d/, '/', /[0-3]/, /\d/, '/', /[12]/, /\d/, /\d/, /\d/];

// DD-MM-YYYY
const europeanDateMask = [/[0-3]/, /\d/, '-', /[01]/, /\d/, '-', /[12]/, /\d/, /\d/, /\d/];

Credit Cards

// 4-4-4-4 format
const creditCardMask = [
  /\d/, /\d/, /\d/, /\d/, '-', 
  /\d/, /\d/, /\d/, /\d/, '-', 
  /\d/, /\d/, /\d/, /\d/, '-', 
  /\d/, /\d/, /\d/, /\d/
];

Social Security Numbers

// XXX-XX-XXXX
const ssnMask = [/\d/, /\d/, /\d/, '-', /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/];
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-text-mask@5.5.x
Publish Source
CLI
Badge
tessl/npm-react-text-mask badge