/** * Event payload for `useMask` value/complete callbacks. */ export interface UseMaskValueChangeEvent { /** * The DOM event that triggered the change, or `null` for programmatic * updates (`setValue`, `reset`). */ originalEvent: Event | null; /** * Masked value (e.g. `"12/05/2026"`). Always in masked form. */ value: string; /** * Unmasked (raw) value (e.g. `"12052026"`). Separators and placeholder * characters are stripped. */ rawValue: string; /** * Whether all required slots are filled. */ isComplete: boolean; } /** * Options for the `useMask` hook. */ export interface UseMaskOptions { /** * Mask pattern. Built-in tokens: * - `9` → [0-9] * - `a` → [A-Za-z] * - `A` → [A-Z] * - `*` → [A-Za-z0-9] * Append `?` to mark the remainder of the mask as optional. Extend with * the `tokens` option. */ mask: string; /** * Custom token map merged on top of the built-in tokens. Each token * character is matched against the supplied RegExp. * @example { '#': /[0-9]/, H: /[A-Fa-f0-9]/ } */ tokens?: Record; /** * Controlled masked value. When provided, the hook operates in * controlled mode. */ value?: string; /** * Initial masked value for uncontrolled mode. Ignored when `value` is * provided. */ defaultValue?: string; /** * Fires whenever the value changes (typing, paste, programmatic). */ onValueChange?: (event: UseMaskValueChangeEvent) => void; /** * Fires when the value transitions to complete (all required slots * filled). Re-fires if the value becomes incomplete and is completed * again. */ onComplete?: (event: UseMaskValueChangeEvent) => void; /** * Placeholder character for empty slots. Pass `null` to skip filling * empty slots visually. * @default '_' */ slotChar?: string | null; /** * Whether to render the mask skeleton on focus. * @default false */ showMaskOnFocus?: boolean; /** * Always render the mask skeleton, regardless of focus state. * @default false */ alwaysShowMask?: boolean; /** * Clear an incomplete value on blur. * @default true */ autoClear?: boolean; /** * Transform every character before token validation (e.g. uppercase). */ transform?: (char: string) => string; /** * Read-only mode. Typing is blocked; programmatic `setValue` still * works. * @default false */ readOnly?: boolean; } /** * Return type of the `useMask` hook. */ export interface UseMaskReturn { /** * Ref callback for the target `` (or `