usePatternFormatAdapter
Returns adapter props for wiring react-number-format's PatternFormat masks (phone numbers, card numbers, codes) to React Hook Form.
usePatternFormatAdapter connects a field to React Hook Form and returns props you spread onto PatternFormat from react-number-format. It's what PatternFormatElement uses internally. It calls useNumberFormatBaseAdapter with the same props; this page covers what matters for masked input.
Use the element for one-off fields. Reach for the hook when the same mask and its completeness rules appear in several forms, for example a phone or card number field you want to define once.
Import
import { usePatternFormatAdapter } from "@piplup/rhf-adapters/react-number-format";Usage
This UsPhoneField shows +1 (###) ###-#### and only accepts a complete number with a valid area code. Submit a partial number, or one starting with 0, to see the errors. The alert shows that only the digits are stored.
"use client";import Stack from "@mui/material/Stack";import TextField from "@mui/material/TextField";import { MuiButtonElement } from "@piplup/rhf-adapters/mui-material";import { usePatternFormatAdapter } from "@piplup/rhf-adapters/react-number-format";import { type Control, useForm } from "react-hook-form";import { PatternFormat } from "react-number-format";type FormValues = { phone: string };// The form stores only the 10 typed digits, so the rules below// run against "2125550100", not "+1 (212) 555-0100".function UsPhoneField({ control }: { control: Control<FormValues> }) { const adapter = usePatternFormatAdapter<string, FormValues, "phone">({ control, name: "phone", required: true, composeHelperText: true, pattern: /^\d{10}$/, messages: { required: "Enter a phone number", pattern: "Enter all 10 digits", }, rules: { validate: (value) => !/^[01]/.test(value) || "Area codes can't start with 0 or 1", }, }); return ( <PatternFormat customInput={TextField} label="Mobile number" format="+1 (###) ###-####" mask="_" {...adapter} /> );}export default function Page() { const { control, handleSubmit } = useForm<FormValues>({ defaultValues: { phone: "" }, }); return ( <form noValidate onSubmit={handleSubmit((values) => alert(JSON.stringify(values, null, 2)))} > <Stack direction="column" spacing={2}> <UsPhoneField control={control} /> <div> <MuiButtonElement control={control} variant="contained" type="submit"> Submit </MuiButtonElement> </div> </Stack> </form> );}How it works
Stored value is the raw input. The form receives values.value: only the characters typed into # slots. Literal characters from format (including the +1 above) and mask placeholders are dropped. With format="(###) ###-####", the display (212) 555-0100 is stored as "2125550100", and a half-typed (212) 55_-____ as "21255".
To keep the formatted text instead, pass transform.output: (values) => values.formattedValue. Note that a partly filled field then still contains the mask characters.
Default values. Use the same raw form for defaultValues. PatternFormat formats a digits-only string like "4085551212" into (408) 555-1212 on first render.
Checking for a complete value. A partly filled mask is not empty, so required alone accepts it. Because the stored string holds only the typed characters, its length tells you how much is filled in:
pattern: /^\d{10}$/(as in the demo) orminLength: 10rejects incomplete numbers.rules.validatecan check parts of the value, such as the area code.
| Key | Default message |
|---|---|
required | Please fill out this field. |
pattern | Please match the requested format. |
minLength | Please lengthen this text to n characters or more |
maxLength | Please shorten this text to n characters or less. |
The default length message talks about "text", which reads oddly for a phone or card number, so set messages for these.
Errors and helper text. Set composeHelperText: true when rendering through customInput={TextField} to receive error and a helperText that switches to the error message. Without it, neither prop is returned. With customInput, the field ref is attached to the TextField root, so focus-on-error does not reach the input.
Props
Prop
Type
Return value
Prop
Type