šŸ“ Sign Up | šŸ” Log In

← Root | ↑ Up

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ šŸ“„ shadcn/directory/sadmann7/diceui/components/mask-input │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

╔══════════════════════════════════════════════════════════════════════════════════════════════╗
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘

title: Mask Input description: An input component that formats user input with predefined patterns like phone numbers, dates, and credit cards. preview: true links: api: /docs/components/mask-input#api-reference

<ComponentTabs name="mask-input-demo" />

Installation

CLI

npx shadcn@latest add "https://diceui.com/r/mask-input"

Manual

<Steps> <Step> Install the following dependencies:
 ```package-install
 @radix-ui/react-slot
 ```
</Step> <Step> Copy the refs composition utilities into your `lib/compose-refs.ts` file.
<ComponentSource name="compose-refs" />
</Step> <Step> Copy and paste the following code into your project.
<ComponentSource name="mask-input" />
</Step> </Steps>

Layout

Import and use the component directly.

import { MaskInput } from "@/components/ui/mask-input";

<MaskInput 
  mask="phone" 
  placeholder="Enter phone number"
  maskPlaceholder="(___) ___-____"
  onValueChange={(masked, unmasked) => {
    console.log('Masked:', masked);     // "(555) 123-4567"
    console.log('Unmasked:', unmasked); // "5551234567"
  }}
/>

Features

  • Smart cursor positioning - Cursor stays in the correct position during typing and pasting
  • Paste support - Intelligently handles pasted content with proper formatting
  • Built-in patterns - Common formats like phone, SSN, date, credit card, etc.
  • Custom patterns - Create your own mask patterns with validation
  • Optional mask placeholders - Control when mask format hints are shown with maskPlaceholder
  • TypeScript support - Full type safety with IntelliSense
  • Accessibility - ARIA attributes and keyboard navigation
  • Form integration - Works seamlessly with form libraries
  • Composition support - Use asChild prop to render as a different component using Radix Slot

Examples

With custom patterns

Create custom mask patterns for specific formatting needs.

<ComponentTabs name="mask-input-custom-pattern-demo" />

With validation modes

Control when validation occurs with different validation modes, similar to react-hook-form.

<ComponentTabs name="mask-input-validation-modes-demo" />

Card information

Card information with credit card number, expiry date, and CVC fields.

<ComponentTabs name="mask-input-card-information-demo" />

With form

Integrate masked inputs with form validation using react-hook-form.

<ComponentTabs name="mask-input-form-demo" />

Built-in Mask Patterns

The component includes several predefined mask patterns:

| Pattern | Format | Example | Description | |---------|--------|---------|-------------| | phone | (###) ###-#### | (555) 123-4567 | US phone number | | ssn | ###-##-#### | 123-45-6789 | Social Security Number | | date | ##/##/#### | 12/25/2023 | Date (MM/DD/YYYY) | | time | ##:## | 14:30 | Time (HH:MM) | | creditCard | #### #### #### #### | 1234 5678 9012 3456 | Credit card number | | creditCardExpiry | ##/## | 12/25 | Credit card expiry date (MM/YY) | | zipCode | ##### | 12345 | US ZIP code | | zipCodeExtended | #####-#### | 12345-6789 | US ZIP+4 code | | currency | Dynamic | $1,234.56 | Currency formatting using Intl.NumberFormat | | percentage | ##.##% | 12.34% | Percentage with decimals | | licensePlate | ###-### | ABC-123 | License plate format | | ipv4 | ###.###.###.### | 192.168.1.1 | IPv4 address | | macAddress | ##:##:##:##:##:## | 00:1B:44:11:3A:B7 | MAC address | | isbn | ###-#-###-#####-# | 978-0-123-45678-9 | ISBN-13 book identifier | | ein | ##-####### | 12-3456789 | Employer Identification Number |

Custom Mask Patterns

Create custom patterns using the MaskPattern interface:

const customPattern: MaskPattern = {
  pattern: "###-###-####",
  transform: (value, opts) => value.replace(/[^A-Z0-9]/gi, "").toUpperCase(),
  validate: (value, opts) => value.length === 10,
};

<MaskInput 
  mask={customPattern} 
  placeholder="Enter license plate"
  maskPlaceholder="ABC-1234"
/>

Currency Formatting

The currency mask uses the Intl.NumberFormat API for localization and currency formatting.

// Default USD formatting
<MaskInput mask="currency" />

// Euro formatting with German locale
<MaskInput 
  mask="currency" 
  currency="EUR" 
  locale="de-DE" 
/>

// Japanese Yen formatting
<MaskInput 
  mask="currency" 
  currency="JPY" 
  locale="ja-JP" 
/>

// British Pound formatting
<MaskInput 
  mask="currency" 
  currency="GBP" 
  locale="en-GB" 
/>

Mask Placeholders

Use the maskPlaceholder prop to control when mask format hints are shown. The mask placeholder only appears when the input is focused and the prop is provided.

// Shows mask placeholder when focused
<MaskInput 
  mask="phone" 
  placeholder="Enter phone number"
  maskPlaceholder="(___) ___-____"
/>

// No mask placeholder - just regular placeholder behavior
<MaskInput 
  mask="phone" 
  placeholder="Enter phone number"
/>

API Reference

MaskInput

The main masked input component that handles formatting and user input.

<AutoTypeTable path="./types/docs/mask-input.ts" name="MaskInputProps" />

MaskPattern

Interface for creating custom mask patterns.

<AutoTypeTable path="./types/docs/mask-input.ts" name="MaskPattern" />

MaskPatternKey

Predefined mask pattern keys for common input formats.

| Pattern | Description | |---------|-------------| | phone | US phone number | | ssn | Social Security Number | | date | Date (MM/DD/YYYY) | | time | Time (HH:MM) | | creditCard | Credit card number | | creditCardExpiry | Credit card expiry date (MM/YY) | | zipCode | US ZIP code | | zipCodeExtended | US ZIP+4 code | | currency | Currency formatting using Intl.NumberFormat | | percentage | Percentage with decimals | | licensePlate | License plate format | | ipv4 | IPv4 address | | macAddress | MAC address | | isbn | ISBN-13 book identifier | | ein | Employer Identification Number |

TransformOptions

Options passed to the transform function for advanced formatting.

<AutoTypeTable path="./types/docs/mask-input.ts" name="TransformOptions" />

ValidateOptions

Options passed to the validate function for enhanced validation.

<AutoTypeTable path="./types/docs/mask-input.ts" name="ValidateOptions" />

Data Attributes

<DataAttributesTable attributes={[ { title: "[data-disabled]", value: "Present when the input is disabled.", }, { title: "[data-invalid]", value: "Present when the input has validation errors.", }, { title: "[data-readonly]", value: "Present when the input is read-only.", }, { title: "[data-required]", value: "Present when the input is required.", }, ]} />

Accessibility

Keyboard Interactions

<KeyboardShortcutsTable shortcuts={[ { keys: ["Tab"], description: "Moves focus to or away from the input.", }, { keys: ["Shift + Tab"], description: "Moves focus to the previous focusable element.", }, { keys: ["Backspace"], description: "Removes the previous character, intelligently handling mask characters.", }, { keys: ["Delete"], description: "Removes the next character.", }, { keys: ["Ctrl + V", "Cmd + V"], description: "Pastes content with intelligent mask formatting.", }, { keys: ["Ctrl + A", "Cmd + A"], description: "Selects all input content.", }, ]} />

ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•‘
ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•

← Root | ↑ Up