Summary
International phone input with searchable country picker, local circle flags, libphonenumber validation, and structured state (country, national, e164).
Basic usage
array
cast. Its country key is a code such as PL or DE, never the country label.
Country names, flag URLs and dropdown descriptions are not persisted. Saving only
E.164 is optional, using the dehydration callback above.
State format
On hydrate and dehydrate,
normalizeState() runs automatically. A plain string state (e.g. +48 512 345 678) is parsed on hydrate. Default national stays NATIONAL-formatted for BC; use digits-only or e164 when you need machine-friendly values.
Validation
Do not combinemobileOnly()andfixedLineOnly()on the same field — throwsInvalidArgumentException. PreferallowTypes()for multi-type rules.
Configuration API
variant(string|Closure $variant)
Visual style shared with FlexTextInput. Values: primary (default), secondary, flat, soft.
size(string|ControlSize|Closure $size)
Control height. See Control size. Default: md.
defaultCountry(string|Closure $countryCode)
ISO country code when no country is selected. Default: PL. Falls back to first allowed country or US.
countries(array|Closure|null $countries)
Whitelist of ISO codes. null = all countries (minus exceptCountries).
exceptCountries(array|Closure $countries)
Blacklist applied after the whitelist. Default: [].
searchable(bool|Closure $condition = true)
Show search input in the country dropdown. Default: true.
suffixIcon(string|BackedEnum|Htmlable|Closure|bool|null $icon = null)
Trailing icon. Pass false to hide. Pass an icon name to set a custom icon. Default: config filament-flex-fields.ui.phone_suffix_icon or GravityIcon::Smartphone.
internationalPrefix(bool|Closure $condition = true)
Show dial code prefix next to the national input. Default: true.
mobileOnly(bool|Closure $condition = true)
Restrict to mobile numbers.
fixedLineOnly(bool|Closure $condition = true)
Restrict to fixed-line numbers.
browserLocaleDefault(bool|Closure $condition = true)
When enabled and national number is empty, pre-select country from Accept-Language / browser locale.
browserLocaleSortFirst(bool|Closure $condition = true)
Sort country list with browser locale country first.
locale(string|Closure|null $locale)
Language for country names in the picker (en → Poland, pl → Polska). Defaults to app()->getLocale(). CountryField and PhoneField share the same translation resolver: package overrides first, then PHP ICU regional names, then English fallback. Names are identical on the initial render and in the dropdown.
placeholder(string|Closure|null $placeholder)
Inherited from Filament HasPlaceholder. When omitted, the field uses a libphonenumber national example for the default country (and mobile/fixed type when constrained), otherwise the package language string.
allowTypes(array|Closure|null $types)
Restrict accepted libphonenumber number types (PhoneNumberType cases or names like MOBILE, VOIP). When set, overrides mobileOnly() / fixedLineOnly() sugar.
strictTypes(bool|Closure $condition = true)
Do not auto-accept FIXED_LINE_OR_MOBILE alongside MOBILE / FIXED_LINE.
validateForRegion(bool|Closure $condition = true)
Require isValidNumberForRegion() for the selected country (stricter than global isValidNumber).
nationalFormat(PhoneNationalFormat|string|Closure $format) / nationalDigitsOnly()
Default national (BC). Digits-only is opt-in:
includeFormats(array|Closure $formats)
Add international and/or rfc3966 keys to dehydrated state (valid numbers only).
includeMetadata(array|Closure $metadata)
Add PHP-side carrier, geo, timezones, and/or type keys (valid numbers only). No JS / phone-lib budget impact.
readOnly(bool|Closure $condition = true)
Inherited from Filament CanBeReadOnly.
focusOutline(bool|Closure $condition = true)
Inherited from HasFieldFocusOutline.
Public helper methods
FlexField schema config
CSS classes
Shares FlexTextInput shell classes (
fff-flex-text-input-field, variant modifiers).
Implementation notes
- Country dropdown uses
x-teleport="body"to avoid overflow clipping. - Depends on
giggsey/libphonenumber-for-phpfor parsing and validation. - Empty national number dehydrates to
e164: ''regardless of partial dial prefix.
Playground
Slug:phone-field
/admin/flex-fields/phone-field — see Playground.
Related components
Country catalog and local flags
The country picker follows libphonenumber’s supported telephone regions, includingAC, TA and XK. It is intentionally separate from CountryField’s default 249-entry
ISO address catalog: some ISO territories do not have a supported calling-code region.
The exact telephone list follows the installed libphonenumber metadata version.
countries() and exceptCountries() constrain both selection and locale detection.
Both pickers share one country-flags asset publication. All supported flags are
materialized local SVG files, including territories whose upstream files are aliases.
No external flag CDN is contacted. Publish them through the standard installation steps:
+1.
The prefix displayed by PhoneField follows the selected region.
Submitted state and server validation
Save through Filament’s validatedgetState() result. Validation rejects unknown
or excluded region codes, country labels, structured country values, non-string
national numbers, unsupported characters and excessive input. Malformed state
can be rendered safely without raising a server error, but cannot pass validation.
required() also rejects an empty national number.
The server derives E.164 from country and national; a forged client-side e164
cannot override it. Unrequested keys such as labels, flag URLs or enrichment are
removed on dehydration. Enabled includeFormats() / includeMetadata() values
are computed on the server and retained; submitted enrichment is never trusted.
validateForRegion() additionally requires the parsed number to be valid for the
selected region. This remains optional because several regions share calling codes.