soff-mask

v0.2.7~0.5KB Core

Input masking for forms - Phone numbers, documents, credit cards, dates and more.

Live Demo - Try it!

Masked Value

Raw Value

Status

Incomplete

Pattern: (###) ### ####

Masking Examples

mask("3001234567", phoneCO)

(300) 123 4567

mask("12345678909", cpf)

123.456.789-09

mask("4111111111111111", creditCard)

4111 1111 1111 1111

unmask("(300) 123 4567")

3001234567

getPlaceholder(phoneCO)

(___) ___ ____

extractRaw("(300) 123-4567", 'digits')

3001234567

Installation

npm install soff-mask

Quick Start

import { mask, unmask, maskWithResult, getPlaceholder, isValidFormat, extractRaw } from 'soff-mask';
import { phoneCO, cpf, creditCard } from 'soff-mask';

// Apply a mask
mask('3001234567', phoneCO);        // '(300) 123 4567'
mask('12345678909', cpf);            // '123.456.789-09'

// Remove mask
unmask('(300) 123 4567', phoneCO);   // '3001234567'

// Get detailed result
maskWithResult('300123', phoneCO);
// { value: '(300) 123', raw: '300123', complete: false, cursorPosition: 9 }

// Get placeholder (for input hints)
getPlaceholder(phoneCO);             // '(___) ___ ____'
getPlaceholder('##/##/####', '*');   // '**/**/****'

// Validate format
isValidFormat('(300) 123 4567', phoneCO);  // true
isValidFormat('300123', phoneCO);           // false (incomplete)

// Extract characters
extractRaw('(300) 123-4567', 'digits');     // '3001234567'
extractRaw('ABC-123', 'letters');           // 'ABC'

// Custom pattern
mask('ABC123', 'AAA-###');           // 'ABC-123'

Pattern Tokens

TokenDescriptionExample
#Any digit (0-9)###-#### → 123-4567
AAny letter (a-z, A-Z)AAA → ABC
SAny alphanumericSSS → A1B
*Any character*** → @#!
\Escape next character\## → #1

Pre-built Masks

phoneCO(300) 123 4567
phoneMX(55) 1234 5678
phoneUS(555) 123-4567
phoneBR(11) 91234-5678
phoneAR(11) 1234-5678

DOM Integration

import { maskInput, createMaskController } from 'soff-mask';
import { phoneCO } from 'soff-mask';

// Vanilla JS - Apply to an input element
const input = document.querySelector('input');
const controller = maskInput(input, { pattern: phoneCO });

// Get raw value
controller.getRawValue();  // '3001234567'

// Cleanup
controller.destroy();

// React usage (controlled)
function PhoneInput() {
  const [value, setValue] = useState('');
  
  const handleChange = (e) => {
    setValue(mask(e.target.value, phoneCO));
  };
  
  return <input value={value} onChange={handleChange} />;
}

API Reference

// Core functions
mask(value: string, pattern: string, options?: MaskOptions): string
unmask(value: string, pattern: string): string
maskWithResult(value: string, pattern: string): MaskResult

// Utilities
parsePattern(pattern: string): MaskToken[]
isComplete(value: string, pattern: string): boolean
getPatternLength(pattern: string): number

// NEW in v0.2.0
getPlaceholder(pattern: string, placeholder?: string): string
isValidFormat(value: string, pattern: string): boolean
getNextCursorPosition(value: string, pattern: string, cursorPosition: number): number
extractRaw(value: string, type?: 'digits' | 'letters' | 'alphanumeric' | 'all'): string

// Dynamic masks
createDynamicMask(rules: DynamicMaskRule[]): (value: string) => string

// DOM
maskInput(element: HTMLInputElement, options: MaskInputOptions): MaskController

interface MaskResult {
  value: string;      // Masked value
  raw: string;        // Raw value without mask
  complete: boolean;  // True if all positions filled
  cursorPosition: number;
}