CSS-классы для состояний

При инициализации Inputmask на DOM-элемент библиотека добавляет базовый CSS-класс inputmask, который служит маркером того, что поле находится под управлением маски. Этот класс используется как точка входа для стилизации всех элементов, на которые навешана маска, независимо от её типа (числовая, дата, телефон, произвольный шаблон).

Типичная структура:

<input class="inputmask" />

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


Состояние заполнения: полное и неполное значение

Одной из ключевых задач при работе с масками является отслеживание состояния заполненности поля. Inputmask сам по себе не навязывает строгую систему классов для всех состояний, но предоставляет механизмы, через которые эти состояния удобно реализуются.

Неполное значение

Неполное заполнение определяется как состояние, при котором пользователь ввёл лишь часть обязательных символов маски. Например, при маске телефона:

+7 (999) 999-99-99

значение вида:

+7 (705) 12

является неполным.

Такое состояние обычно отражается добавлением кастомного CSS-класса через колбэк:

Inputmask({
  mask: "+7 (999) 999-99-99",
  onincomplete: function () {
    this.classList.add("is-incomplete");
    this.classList.remove("is-complete");
  }
}).mask(document.querySelector("input"));

Полное значение

Полное заполнение фиксируется, когда все обязательные позиции маски заполнены корректными символами.

Inputmask({
  mask: "+7 (999) 999-99-99",
  oncomplete: function () {
    this.classList.add("is-complete");
    this.classList.remove("is-incomplete");
  }
}).mask(document.querySelector("input"));

Состояние is-complete часто используется для визуального подтверждения валидного ввода, особенно в формах с многошаговой валидацией.


Состояние пустого поля и очистки

Inputmask предоставляет поведение очистки значения, связанное с опцией clearIncomplete. При её включении неполностью заполненное поле может автоматически очищаться при потере фокуса.

Inputmask({
  mask: "99/99/9999",
  clearIncomplete: true
}).mask(input);

В этом сценарии удобно вводить отдельный класс состояния:

oncleared: function () {
  this.classList.add("is-empty");
  this.classList.remove("is-incomplete");
  this.classList.remove("is-complete");
}

Состояние is-empty применяется не только к реально пустому значению, но и к очищенному Inputmask значению после сброса.


Фокус и активное взаимодействие

Хотя Inputmask не управляет фокусом напрямую, сочетание с событиями focus и blur позволяет синхронизировать CSS-состояния поля с пользовательским взаимодействием.

const el = document.querySelector("input");

el.addEventListener("focus", function () {
  this.classList.add("is-focused");
});

el.addEventListener("blur", function () {
  this.classList.remove("is-focused");
});

Часто фокус комбинируется с состоянием заполнения, формируя более детализированную визуальную модель:

  • is-focused + is-empty — активное пустое поле
  • is-focused + is-incomplete — редактируемое незавершённое значение
  • is-focused + is-complete — корректно заполненное поле

Ошибки и некорректный ввод

Inputmask не является полноценной системой валидации, однако при некорректном вводе (например, нарушении шаблона или попытке вставки неподходящих символов) часто используется внешний слой валидации.

Типовой подход — связка Inputmask с пользовательской логикой проверки:

function setErrorState(el, hasError) {
  el.classList.toggle("is-error", hasError);
}

Состояние is-error обычно управляется не самой библиотекой, а логикой формы:

  • серверная валидация
  • HTML5 validation API
  • сторонние валидаторы

Системы визуальной индикации через CSS-классы

CSS-классы в контексте Inputmask выполняют роль слоя представления поверх логики маскирования. Основные состояния формируются комбинацией:

  • базового класса inputmask
  • пользовательских классов состояния
  • классов, добавляемых фреймворками (React/Vue/Angular интеграции)

Пример типовой системы:

.inputmask {
  border: 1px solid #ccc;
}

.inputmask.is-focused {
  border-color: #4a90e2;
}

.inputmask.is-incomplete {
  border-color: #e67e22;
}

.inputmask.is-complete {
  border-color: #2ecc71;
}

.inputmask.is-error {
  border-color: #e74c3c;
}

Такое разделение позволяет отделить:

  • логику ввода (Inputmask)
  • визуальную индикацию (CSS)
  • бизнес-правила (валидация формы)

Управление классами через события Inputmask

Библиотека предоставляет набор событий, которые удобно использовать для синхронизации состояния DOM:

  • oncomplete — маска полностью заполнена
  • onincomplete — значение не завершено
  • oncleared — значение очищено
  • onKeyValidation — контроль ввода символов
  • onBeforePaste — обработка вставки

Пример централизованного управления состояниями:

Inputmask({
  mask: "9999-9999",
  oncomplete: function () {
    updateState(this, "complete");
  },
  onincomplete: function () {
    updateState(this, "incomplete");
  },
  oncleared: function () {
    updateState(this, "empty");
  }
}).mask(input);

function updateState(el, state) {
  el.classList.remove("is-complete", "is-incomplete", "is-empty");
  el.classList.add(`is-${state}`);
}

Такой подход предотвращает конфликт классов и обеспечивает единое управление состояниями.


Интеграция с внешними системами валидации

В сложных формах Inputmask часто используется вместе с валидаторами, где CSS-классы становятся связующим слоем между различными системами проверки.

Типовая архитектура:

  • Inputmask управляет форматом ввода
  • валидатор определяет бизнес-корректность
  • CSS отражает агрегированное состояние

Пример логики:

function validateField(el) {
  const value = el.value;

  const isValid = value.length > 0 && !value.includes("_");

  el.classList.toggle("is-error", !isValid);
}

Приоритет состояний и конфликт классов

При одновременном наличии нескольких состояний требуется явная система приоритетов:

  1. is-error — максимальный приоритет
  2. is-complete
  3. is-incomplete
  4. is-empty
  5. is-focused — модификатор, не конкурирующий с основными состояниями

Такая иерархия предотвращает визуальные конфликты, например, когда поле одновременно подсвечивается как корректное и ошибочное.


Паттерн атомарных классов состояния

На практике часто применяется атомарный подход, при котором каждое состояние строго взаимоисключающее:

<input class="inputmask state-complete" />
const states = ["state-empty", "state-incomplete", "state-complete", "state-error"];

function setState(el, newState) {
  el.classList.remove(...states);
  el.classList.add(`state-${newState}`);
}

Такой подход упрощает поддержку интерфейса при большом количестве маскированных полей и снижает вероятность накопления конфликтующих классов.