Masked Input
A text input with built-in mask formatting for phone numbers, dates, and custom patterns. Includes an optional date-picker popover.
Demo
Installation
pnpm dlx shadcn@latest add @turbopills-ui/masked-inputnpx shadcn@latest add @turbopills-ui/masked-inputyarn dlx shadcn@latest add @turbopills-ui/masked-inputbunx shadcn@latest add @turbopills-ui/masked-inputUsage
tsx1import { MaskedInput } from "@/components/turbopills/ui/masked-input"
tsx1export function PhoneField() {2 const [value, setValue] = React.useState("")34 return (5 <MaskedInput6 title="Phone number"7 preset="tel"8 value={value}9 onChange={setValue}10 />11 )12}
Examples
Date Preset
The "date" preset provides MM/DD/YYYY formatting and a calendar popover for quick date selection:
Custom Mask
Use preset="custom" with your own mask and replacement pattern:
Error State
Pass errorMessage to display validation feedback:
Please enter a complete phone number
Small Size
A compact variant for inline or toolbar usage:
Props
MaskedInputProps
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | — | Optional heading displayed above the input. |
hint | string | — | Optional hint text shown below the title. |
size | "md" | "sm" | "md" | Controls the height and text size of the input. |
suffix | React.ReactNode | — | Content rendered to the right of the input value. Ignored when preset="date" (calendar icon is shown instead). |
errorMessage | string | — | When set, shows a red border and displays the error text below the input. |
disabled | boolean | false | Disables the input. |
value | string | — | Controlled input value. |
onChange | (value: string) => void | — | Callback fired when the value changes. |
preset | "tel" | "date" | "custom" | "custom" | Built-in mask preset. "tel" formats as (___) ___-____, "date" formats as MM/DD/YYYY with a calendar popover. Use "custom" with your own mask and replacement. |
mask | string | — | Mask pattern string (e.g. "AAA-0000"). Overrides preset mask when provided. |
replacement | Record<string, RegExp> | — | Map of mask characters to allowed input patterns. Overrides preset replacement. |
separate | boolean | — | When true, each mask segment is treated independently. Automatically enabled for "tel" preset. |
showMask | boolean | true | Whether to display the mask placeholder while the input is empty or partially filled. |
calendarCaptionLayout | "label" | "dropdown" | "dropdown-months" | "dropdown-years" | "dropdown" | Caption layout for the date-picker calendar (only applies when preset="date"). |
placeholder | string | — | Placeholder text. Defaults to the preset's placeholder when not provided. |
wrapperClassName | string | — | Additional class names for the outer wrapper element. |
className | string | — | Additional class names for the <input> element itself. |
The component also accepts all standard React.InputHTMLAttributes<HTMLInputElement> props (except size, onChange, and value, which are replaced by the custom props above).