Mosmox UI
Current version
GitHubnpmjs.com
Forms & Inputs

Input Mask

Structured text input with token validation, formatting, and completion callbacks.

InputMask guides users through structured values such as phone numbers, dates, card numbers, account codes, and serial numbers while preserving a normal accessible text input.

Basic usage

The mask uses tokens for editable positions and literal characters for separators.

import { InputMask } from '@mosmox/ui';

<InputMask label="Phone number" mask="+1 (999) 999-9999" inputMode="tel" />
<InputMask label="Date" mask="99/99/9999" inputMode="numeric" />

Preset masks

Use preset when the format is common. Presets provide the mask, recommended mobile keyboard, and a useful placeholder.

<InputMask label="Phone" preset="phone" />
<InputMask label="International phone" preset="internationalPhone" />
<InputMask label="Date" preset="date" />
<InputMask label="Credit card" preset="creditCard" />
<InputMask label="Expiration" preset="expiry" />
<InputMask label="IBAN" preset="iban" />

Available presets are listed below. They set the mask, input mode, and placeholder; you can still override these values with explicit props.

PresetMaskInput modeExample / placeholder
phone(999) 999-9999tel(555) 123-4567
internationalPhone+99 999 999 9999tel+38 067 123 4567
date99/99/9999numericDD/MM/YYYY
time99:99numericHH:MM
dateTime99/99/9999 99:99numericDD/MM/YYYY HH:MM
creditCard9999 9999 9999 9999numeric0000 0000 0000 0000
expiry99/99numericMM/YY
cvv999numericCVV
postalCodeAA9 9AAtextSW1A 1AA
zipCode99999-9999numeric12345-6789
ibanAA99 9999 9999 9999 9999 9999textUA00 0000 0000 0000 0000 0000
sortCode99-99-99numeric20-00-00
routingNumber999999999numeric021000021
otp999999numeric000000
hexColorHAAAAAAtext#FFFFFF (H accepts #)
ipv4999.999.999.999numeric192.168.001.001
slug********************textmy-project-slug
licensePlateAA-9999-AAtextAA-1234-AA

Import inputMaskPresets when you need to inspect or reuse the definitions in your own form controls. A custom preset object supports mask, inputMode, placeholder, guide, maskPlaceholder, and formatChars; explicit component props take precedence over the corresponding preset values.

Built-in tokens are:

  • 9 — a digit;
  • A — a letter;
  • * — an alphanumeric character;
  • # — a hexadecimal character.

The * token accepts letters and digits, while # accepts hexadecimal characters (0-9, a-f, A-F). Token matching is case-sensitive according to the supplied regular expression.

Literal characters such as +, spaces, parentheses, slashes, and dashes are inserted automatically.

Controlled values and raw values

Use value and onChange for controlled forms. The callback receives both the formatted value and the raw token value.

const [phone, setPhone] = useState('');

<InputMask
  mask="+1 (999) 999-9999"
  value={phone}
  onChange={(formatted, raw) => {
    setPhone(formatted);
    console.log(raw); // only the digits
  }}
/>

Use defaultValue for uncontrolled input. onComplete fires once all token positions are valid.

Guide and placeholder modes

Set showMask or guide to display placeholders for unfilled positions. maskPlaceholder customizes the placeholder character.

<InputMask mask="9999 9999" showMask maskPlaceholder="_" />
<InputMask mask="AA-9999" guide maskPlaceholder="•" />

Without guide mode, the field stays compact and only renders the part already entered.

Custom tokens

formatChars extends or replaces token definitions for domain-specific formats.

<InputMask
  label="Serial number"
  mask="SS-999-XX"
  formatChars={{
    S: /[A-Z]/,
    X: /[0-9A-F]/,
  }}
/>

Custom token keys are any single-character mask symbols not used as literals.

Validation, errors, and states

required reports a required error after blur when no token value exists. Pass error for application validation. onValidityChange reports whether all mask positions are complete.

<InputMask
  label="Expiration"
  mask="99/99"
  required
  onValidityChange={(valid) => setValid(valid)}
  error={serverError}
  helperText="MM/YY"
/>

disabled prevents editing. readOnly keeps the formatted value visible without allowing changes. clearable adds a clear action.

The component preserves the caret while inserting, selecting, pasting, and deleting masked characters. Backspace and Delete remove token values without trapping the cursor on literal separators.

Sizes and browser integration

size accepts xs (extra small), sm (small), and default; variant accepts outline and filled. The component follows the same control tokens and slot model as Input, including leadingIcon, prefix, suffix, trailingIcon, loading, clearable, fullWidth, and description. Forward name, id, autoComplete, and inputMode for form integration and mobile keyboard selection. To make a trailing icon actionable, provide onTrailingIconClick and an accessible trailingIconLabel.

<InputMask
  name="postalCode"
  autoComplete="postal-code"
  inputMode="numeric"
  size="xs"
  mask="99999"
/>
<InputMask
  label="Phone"
  preset="phone"
  trailingIcon={<span aria-hidden="true">✓</span>}
  trailingIconLabel="Verify phone"
  onTrailingIconClick={() => alert('Phone verified')}
/>

Use a custom preset object when a reusable format needs a local definition:

const employeeCode = {
  mask: 'AA-999-XX',
  inputMode: 'text' as const,
  placeholder: 'AB-123-FF',
};

<InputMask label="Employee code" preset={employeeCode} />

Accessibility

The component renders a native text input, associates label with the input, exposes aria-invalid for errors, and supports normal browser editing, selection, paste, and keyboard behavior. Provide aria-label when no visible label is present.

API

PropTypeDefaultDescription
maskstring—Mask pattern with token and literal characters.
presetInputMaskPresetName | InputMaskPreset—Built-in or custom reusable mask definition. preset.mask overrides mask.
valuestring—Controlled formatted value.
defaultValuestring''Initial uncontrolled value.
onChange(value, rawValue) => void—Called with formatted and raw values.
onComplete(value, rawValue) => void—Called when every token is filled.
onValidityChange(valid) => void—Called after input validity changes.
formatCharsRecord<string, RegExp>built-insCustom token definitions.
maskPlaceholderstring_Character used by guide mode.
showMaskbooleanfalseDisplays the mask placeholders.
guidebooleanfalseKeeps placeholders visible while typing.
labelReactNode—Visible field label.
descriptionReactNode—Supporting text associated with the input.
placeholderstringmaskNative placeholder override.
helperTextReactNode—Supporting text.
errorReactNode—Validation error content.
requiredbooleanfalseRequires at least one token.
clearablebooleanfalseShows a clear action.
disabledbooleanfalseDisables editing.
readOnlybooleanfalsePrevents editing.
sizexs | sm | defaultdefaultField density: extra small, small, or default.
variantoutline | filledoutlineVisual style matching Input.
fullWidthbooleanfalseExpands the field to its container width.
leadingIcon, prefixReactNode—Content before the input.
suffix, trailingIconReactNode—Content after the input.
onTrailingIconClick() => void—Makes the trailing icon a keyboard-accessible button and handles clicks.
trailingIconLabelstringInput actionAccessible label for the trailing icon button.
loadingbooleanfalseShows a loader and prevents editing.
inputModetext | numeric | decimal | tel | email | url—Preferred mobile keyboard.
aria-labelstring—Accessible name when no visible label is provided.
name, idstring—Native form name and stable input id.
autoCompletestring—Native autocomplete hint.
onFocus, onBlurnative input callbacks—Native focus lifecycle callbacks.
classNamestring—Class applied to the outer field wrapper.
styleCSSProperties—Inline styles applied to the outer field wrapper.

All other standard text-input attributes from InputHTMLAttributes<HTMLInputElement> are forwarded to the native input, except size, value, defaultValue, onChange, and placeholder, which use the mask-specific API above.