@magik_io/maskit-dom
v1.0.0
Published
DOM integration layer for Maskit. Binds the headless `@magik_io/maskit-core` engine to `<input>` elements with full keyboard, clipboard, caret, and form event handling.
Readme
@magik_io/maskit-dom
DOM integration layer for Maskit. Binds the headless @magik_io/maskit-core engine to <input> elements with full keyboard, clipboard, caret, and form event handling.
Installation
npm install @magik_io/maskit-dom @magik_io/maskit-core
# or
pnpm add @magik_io/maskit-dom @magik_io/maskit-coreUsage
mask() — Apply a Mask to an Input
import { mask } from "@magik_io/maskit-dom";
const input = document.querySelector<HTMLInputElement>("#phone");
const controller = mask(input, { mask: "(999) 999-9999" });
// Read values
controller.value(); // → "(123) 456-7890"
controller.unmaskedValue(); // → "1234567890"
// Set values programmatically
controller.setValue("9876543210");
// Access the underlying engine
controller.engine.isComplete(); // → true
// Remove mask and clean up
controller.destroy();MaskController
| Method | Returns | Description |
|--------|---------|-------------|
| value() | string | Current masked value |
| unmaskedValue() | string | Current unmasked (raw) value |
| setValue(value) | void | Set a new value programmatically |
| destroy() | void | Remove mask, unbind events, restore input |
| engine | MaskEngine | Access to the underlying headless engine |
unmask() — Remove a Mask
import { unmask } from "@magik_io/maskit-dom";
unmask(input); // unbinds events, restores value property, removes stateAuto-init via Data Attributes
<input data-maskit="(999) 999-9999" />
<input data-maskit="99/99/9999" data-maskit-placeholder="#" />
<input data-maskit-alias="email" />import { autoInit } from "@magik_io/maskit-dom";
// Scan document for [data-maskit] elements
autoInit();
// Or scan a specific container
autoInit(document.querySelector("#form-container"));Supported attributes:
| Attribute | Description |
|-----------|-------------|
| data-maskit | Mask pattern string |
| data-maskit-alias | Alias name |
| data-maskit-placeholder | Placeholder character |
How It Works
Value Interception
When a mask is applied, @magik_io/maskit-dom intercepts the input's .value property via Object.defineProperty on the element instance:
- Getter: Returns the unmasked value if
autoUnmaskis enabled, or the masked value otherwise. Returns""for nullable empty masks. - Setter: Pipes the new value through the mask engine before writing to the DOM.
This means frameworks and form libraries that read input.value get the correct value transparently.
Event Handling
The DOM package handles these events automatically:
| Event | Behavior |
|-------|----------|
| keydown | Processes Backspace, Delete, Escape (undo), Insert (toggle mode), Tab, Home/End |
| input | Handles IME composition, mobile keyboards, insertText, deleteContent |
| paste | Processes clipboard data through onBeforePaste hook |
| cut | Copies selection to clipboard, processes delete |
| focus | Shows mask template (if showMaskOnFocus), positions caret |
| blur | Clears mask template (if clearMaskOnLostFocus), validates completeness |
| click | Positions caret based on positionCaretOnClick strategy |
| mouseenter/leave | Shows/hides mask template (if showMaskOnHover) |
| submit | Handles removeMaskOnSubmit / autoUnmask |
| reset | Resets engine and buffer |
State Management
All per-element state is stored in WeakMaps — no properties are added to DOM elements:
import { getState, hasState } from "@magik_io/maskit-dom";
if (hasState(input)) {
const state = getState(input);
console.log(state.engine.getValue());
}DOM-Specific Options
These options are relevant when using @magik_io/maskit-dom (they have no effect in headless mode):
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| showMaskOnFocus | boolean | true | Show mask template when input gains focus |
| showMaskOnHover | boolean | true | Show mask template on mouse hover |
| clearMaskOnLostFocus | boolean | true | Clear template text on blur if empty |
| clearIncomplete | boolean | false | Clear value on blur if mask is not complete |
| removeMaskOnSubmit | boolean | false | Strip mask from value on form submission |
| autoUnmask | boolean | false | .value getter returns unmasked value |
| positionCaretOnClick | string | "lvp" | Caret strategy: "lvp", "radixFocus", "select", "ignore", "none" |
| positionCaretOnTab | boolean | true | Position caret on Tab focus |
| undoOnEscape | boolean | true | Restore previous value on Escape |
| tabThrough | boolean | false | Allow Tab to advance through mask sections |
Caret Utilities
import { getCaret, setCaret } from "@magik_io/maskit-dom";
const { begin, end } = getCaret(input);
setCaret(input, 5); // move caret to position 5
setCaret(input, 2, 8); // select positions 2–8License
MIT
