apps/mantine.dev/src/pages/hooks/use-mask.mdx
import { UseMaskDemos } from '@docs/demos'; import { Layout } from '@/layout'; import { MDX_DATA } from '@/mdx';
export default Layout(MDX_DATA.useMask);
useMask attaches real-time input masking to any <input> element via a ref callback.
It formats user input against a defined pattern and exposes both the masked display value
and the raw unmasked value. If you need a ready-made input component, use MaskInput
which wraps this hook with all standard input props.
Use isComplete to check whether all required mask slots are filled — for example, to control
a submit button. The slotChar option accepts a multi-character string to show positional
hints for each slot. The transform option converts each character before validation —
this example uses it to auto-uppercase input so the A token ([A-Z]) accepts lowercase letters:
Use the modify option to change the mask based on the current input value.
This example switches between standard and American Express credit card formats:
Override or extend the built-in token map with the tokens option:
Prefix a token character with \ to treat it as a literal.
In this example, A would normally be an uppercase letter token,
but \A makes it a literal character:
For complex masks where built-in tokens are not enough, pass an array of
string literals and RegExp objects. This example creates a time input where
the first digit is restricted to 0-2 and the minute tens digit to 0-5:
Use the reset function returned by the hook to programmatically clear
the input value:
The mask string defines the expected format. Each character is either a token (editable slot) or a literal (fixed character inserted automatically).
9 – any single digit ([0-9])a – any single letter ([A-Za-z])A – any uppercase letter ([A-Z])* – any alphanumeric character ([A-Za-z0-9])# – digit or sign ([-+0-9])Append ? after the last required character to mark remaining slots as optional:
useMask({ mask: '(999) 999-9999? x9999' }) // Extension is optional
The following pure functions are exported alongside the hook:
formatMask(raw, options) – apply a mask to a raw value stringunformatMask(masked, options) – strip all mask literals from a masked valueisMaskComplete(masked, options) – check if all required slots are filledgeneratePattern(mode, options) – generate a regex string for HTML pattern attributeimport { formatMask, unformatMask, isMaskComplete } from '@mantine/hooks';
const options = { mask: '(999) 999-9999' };
formatMask('1234567890', options); // "(123) 456-7890"
unformatMask('(123) 456-7890', options); // "1234567890"
isMaskComplete('(123) 456-7890', options); // true
interface UseMaskOptions {
// Mask pattern string or array of string literals and RegExp objects
mask: string | Array<string | RegExp>;
// Override or extend the default token map
tokens?: Record<string, RegExp>;
// Called on each keystroke, can return overrides for mask, tokens, or slotChar
modify?: (value: string) => Partial<Pick<UseMaskOptions, 'mask' | 'tokens' | 'slotChar'>> | undefined;
// Transform each character before validation and insertion
transform?: (char: string) => string;
// Character displayed in unfilled slots, "_" by default
slotChar?: string | null;
// Show mask pattern even when the field is empty and unfocused
alwaysShowMask?: boolean;
// Show mask placeholder on focus, true by default
showMaskOnFocus?: boolean;
// Clear value on blur when mask is incomplete, false by default
autoClear?: boolean;
// Sets aria-invalid on the input
invalid?: boolean;
// Called on every change with raw and masked values
onChangeRaw?: (rawValue: string, maskedValue: string) => void;
// Called when all required mask slots are filled
onComplete?: (maskedValue: string, rawValue: string) => void;
}
interface UseMaskReturnValue {
// Ref callback to attach to the input element
ref: React.RefCallback<HTMLInputElement>;
// Current masked display value
value: string;
// Current raw unmasked value
rawValue: string;
// Whether all required mask slots are filled
isComplete: boolean;
// Clear the input value and reset state
reset: () => void;
}
function useMask(options: UseMaskOptions): UseMaskReturnValue;
The UseMaskOptions and UseMaskReturnValue types are exported from the @mantine/hooks package;
you can import them in your application:
import type { UseMaskOptions, UseMaskReturnValue } from '@mantine/hooks';