IMask.js

IMask.js представляет собой высокопроизводительную библиотеку для создания масок ввода, ориентированную на гибкость, расширяемость и интеграцию с современными фронтенд-стеками. Архитектура построена вокруг модели потоковой обработки ввода, где каждый символ проходит через цепочку преобразований и валидаторов, формируя предсказуемое поведение поля.

Основой работы IMask.js является разделение логики на несколько уровней:

  • слой парсинга маски
  • слой состояния значения
  • слой отображения (presentation layer)
  • слой событий ввода

Каждое введённое значение не записывается напрямую в input, а проходит через внутреннюю модель состояния, которая хранит:

  • текущую позицию курсора
  • валидные символы
  • необязательные сегменты
  • литералы маски

Такая модель исключает необходимость ручной синхронизации DOM и состояния, что критически важно при сложных масках.

Базовые типы масок

В IMask.js маска может быть задана несколькими способами:

Строковая маска

Статическая строка определяет фиксированный формат:

const mask = IMask(element, {
  mask: '+{7}(000)000-00-00'
});

Символ 0 обозначает обязательную цифру, литералы (скобки, дефисы) интерпретируются как фиксированные элементы.

Маска на основе регулярного выражения

const mask = IMask(element, {
  mask: /^[1-9]\d{0,9}$/
});

Регулярные выражения позволяют задавать строгие правила валидации без структурной сегментации.

Функциональные и динамические маски

Маска может вычисляться динамически:

const maskOptions = {
  mask: function (value) {
    return value.length > 10
      ? '+{7}(000)000-00-00'
      : '0000000000';
  }
};

Это позволяет адаптировать формат ввода к контексту данных.

Сегментированная структура маски

Ключевая особенность IMask.js заключается в работе с сегментами:

  • фиксированные символы
  • изменяемые блоки
  • опциональные группы
  • повторяющиеся секции

Пример конфигурации с блоками:

const mask = IMask(element, {
  mask: {
    mask: '000-AAA',
    definitions: {
      'A': /[A-Z]/
    }
  }
});

Определения символов позволяют расширять стандартную систему токенов.

Динамические и составные маски

Составные маски применяются при необходимости переключения формата в зависимости от вводимого значения:

const mask = IMask(element, {
  mask: [
    {
      mask: '+{7}(000)000-00-00',
    },
    {
      mask: /^\d{10}$/
    }
  ]
});

Система автоматически выбирает подходящий вариант, анализируя ввод.

Работа с курсором и редактированием

Одним из сложных аспектов маскирования является управление курсором. IMask.js реализует следующие механизмы:

  • автоматический сдвиг курсора при вставке литералов
  • предотвращение попадания курсора в недопустимые позиции
  • корректировка позиции при удалении символов
  • нормализация вставки (paste handling)

При вставке строки библиотека разбивает её на токены и распределяет по доступным слотам маски.

Токены и определения символов

Система токенов позволяет гибко описывать правила:

  • 0 — цифра (обязательная)
  • 9 — цифра (опциональная)
  • # — любая цифра с дополнительной логикой
  • A — буква
  • * — любой символ

Пользовательские токены:

IMask.createMask({
  mask: '000-AAA',
  definitions: {
    'A': /[A-Z]/,
    '0': /[0-9]/
  }
});

Такой подход расширяет базовый синтаксис без изменения ядра.

Обработка событий

IMask.js предоставляет событийную модель:

  • accept — вызывается при каждом валидном изменении
  • complete — срабатывает при полном заполнении маски
  • reject — при попытке ввести недопустимый символ

Пример:

mask.on('accept', () => {
  console.log(mask.value);
});

mask.on('complete', () => {
  console.log('готово');
});

События позволяют строить реактивные формы без дополнительной логики проверки.

Работа с raw и formatted значениями

Библиотека разделяет:

  • value — отформатированное значение
  • unmaskedValue — «сырое» значение без литералов
  • typedValue — значение с приведением типа

Пример:

mask.unmaskedValue; // "79001234567"
mask.value;         // "+7(900)123-45-67"

Это разделение важно при интеграции с API и базами данных.

Маскирование чисел и валют

Отдельный тип масок предназначен для числовых значений:

const numberMask = IMask(element, {
  mask: Number,
  scale: 2,
  thousandsSeparator: ' ',
  radix: '.'
});

Поддерживаются:

  • фиксированная точность
  • разделители тысяч
  • ограничения диапазона
  • отрицательные числа

Маски для дат

Работа с датами включает в себя не только форматирование, но и валидацию календарных значений:

const dateMask = IMask(element, {
  mask: Date,
  pattern: 'Y-`m-`d',
  blocks: {
    d: { mask: IMask.MaskedRange, from: 1, to: 31 },
    m: { mask: IMask.MaskedRange, from: 1, to: 12 },
    Y: { mask: IMask.MaskedRange, from: 1900, to: 2100 }
  }
});

Такой подход предотвращает ввод несуществующих дат на уровне маски.

Интеграция с UI-фреймворками

IMask.js используется в связке с современными библиотеками интерфейса:

  • React через refs и эффекты
  • Vue через директивы
  • Angular через сервисы и биндинги

Общая схема интеграции сводится к привязке экземпляра маски к DOM-элементу и синхронизации состояния через события.

Производительность и оптимизация

Производительность достигается за счёт:

  • отсутствия полной перерисовки DOM
  • ленивой обработки ввода
  • кэширования состояния маски
  • минимизации regex-операций

Даже при сложных составных масках библиотека сохраняет предсказуемое время обработки каждого события ввода.

Сравнительные особенности относительно Inputmask

Inputmask ориентирована на конфигурационные маски с большим количеством готовых шаблонов и плагинов, тогда как IMask.js делает упор на:

  • программируемую архитектуру
  • расширяемые блоки
  • более строгую модель состояния
  • меньшую зависимость от шаблонов «из коробки»

В сложных интерфейсах с динамическими правилами ввода подход IMask.js обеспечивает более предсказуемое поведение, тогда как Inputmask часто выигрывает в скорости внедрения стандартных форматов.

Поведение при вставке и автокоррекции

При вставке текста алгоритм выполняет:

  • разбиение строки на символы
  • фильтрацию по правилам маски
  • распределение по доступным слотам
  • корректировку курсора

Автокоррекция применяется к частично введённым данным, приводя их к максимально допустимому состоянию без потери валидных сегментов.

Расширяемость и кастомные маски

Механизм создания кастомных масок позволяет определять:

  • собственные валидаторы
  • динамические диапазоны
  • контекстные правила
  • условные сегменты

Это превращает библиотеку из инструмента форматирования в полноценный движок обработки ввода.