PhoneInput

The PhoneInput component provides a flexible way to capture telephone numbers with built-in masking and formatting.

Basics

Controlled PhoneInput example that surfaces both raw digits and the formatted display.

Loading demo…

import { useState } from 'react'; import { Block, PhoneInput, Text } from '@plocks/ui'; export function Demo() { const [raw, setRaw] = useState(''); const [formatted, setFormatted] = useState(''); return ( <Block fullWidth> <PhoneInput label="Phone number" value={raw} onChange={(rawDigits, formattedDisplay) => { setRaw(rawDigits); setFormatted(formattedDisplay); }} /> <Text size="sm"> Raw: {raw || '—'} · Formatted: {formatted || '—'} </Text> </Block> ); }

International

With autoDetect, typing or pasting a + dial code switches the country and mask to match. The second field uses the catch-all country="INTL" format instead.

Loading demo…

import { Block, PhoneInput } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <PhoneInput label="Auto-detect from a + prefix" autoDetect placeholder="Try +447911123456 or +33123456789" /> <PhoneInput label="Manual international" country="INTL" placeholder="Enter any international number" /> </Block> ); }

Variants

Compare the default, filled, outline, and unstyled field shells on PhoneInput.

Loading demo…

import { Column, PhoneInput } from '@plocks/ui'; const variants = ['default', 'filled', 'outline', 'unstyled'] as const; export function Demo() { return ( <Column gap="md" fullWidth> {variants.map(variant => ( <PhoneInput key={variant} variant={variant} label={`${variant} variant`} placeholder="(555) 123-4567" /> ))} </Column> ); }

Country Picker

Set selectableCountry to turn the dial-code prefix into a country picker. Switching country remasks the digits already entered instead of clearing them.

Loading demo…

import { Block, PhoneInput } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <PhoneInput label="Phone number" selectableCountry defaultValue="5551234567" /> </Block> ); }

Country Formats

Pass country to format against a built-in preset, each with its own localized mask and dial code.

Loading demo…

import { Block, PhoneInput } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <PhoneInput label="United States" country="US" /> <PhoneInput label="United Kingdom" country="GB" /> <PhoneInput label="France" country="FR" /> <PhoneInput label="Brazil" country="BR" /> </Block> ); }

Mask Visibility

Set showCountryCode={false} to hide the dial-code prefix; the raw digits reported by onChange stay the same.

Loading demo…

import { Block, PhoneInput } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <PhoneInput label="With country code" /> <PhoneInput label="Without country code" showCountryCode={false} /> </Block> ); }

Validation

Length-based validation for US and international formats with inline messaging.

Loading demo…

import { useState } from 'react'; import { Block, PhoneInput } from '@plocks/ui'; export function Demo() { const [usRaw, setUsRaw] = useState(''); const [internationalRaw, setInternationalRaw] = useState(''); const isValidUs = usRaw.length === 10; const isValidInternational = internationalRaw.length >= 7 && internationalRaw.length <= 15; return ( <Block fullWidth> <PhoneInput label="US phone (10 digits required)" value={usRaw} onChange={(raw) => setUsRaw(raw)} error={usRaw.length > 0 && !isValidUs ? 'Enter a 10-digit US phone number' : undefined} /> <PhoneInput label="International phone (7-15 digits)" country="INTL" value={internationalRaw} onChange={(raw) => setInternationalRaw(raw)} error={ internationalRaw.length > 0 && !isValidInternational ? 'International numbers should be 7-15 digits' : undefined } /> </Block> ); }

Advanced Masking

Custom mask patterns for international formats and extension fields.

Loading demo…

import { Block, PhoneInput } from '@plocks/ui'; export function Demo() { return ( <Block fullWidth> <PhoneInput label="International format" mask="+00 (000) 000-0000" showCountryCode={false} placeholder="+44 (791) 112-3456" /> <PhoneInput label="North America with extension" mask="000-000-0000 x0000" showCountryCode={false} placeholder="555-123-4567 x1234" /> </Block> ); }
Scan to open this page on your phoneplocks.dev/ui/PhoneInput