Ship-It Designv0.0.20

GitHub

PhoneInput

Country-code Select plus a national-number Input. Emits an E.164 string (+CC<NSN>). Used for booking-phone verification and any consumer signup.

Default#

Loading…

With existing value#

The component parses incoming E.164 values back into country + national number, so it round-trips cleanly with server state.

Loading…

Props#

Props for PhoneInput
PropTypeDefaultDescription
valuestring | undefinedE.164 value (controlled), e.g. `+14155550100`.
defaultValuestring | undefinedDefault E.164 value (uncontrolled).
onValueChange((value: string) => void) | undefinedFires with the new E.164 value. Empty national number → empty string.
countriesreadonly PhoneCountry[] | undefined[ { code: 'US', name: 'United States', dialCode: '1', flag: '🇺🇸' }, { code: 'CA', name: 'Canada', dialCode: '1', flag: '🇨🇦' }, { code: 'MX', name: 'Mexico', dialCode: '52', flag: '🇲🇽' }, { code: 'GB', name: 'United Kingdom', dialCode: '44', flag: '🇬🇧' }, { code: 'IE', name: 'Ireland', dialCode: '353', flag: '🇮🇪' }, { code: 'DE', name: 'Germany', dialCode: '49', flag: '🇩🇪' }, { code: 'FR', name: 'France', dialCode: '33', flag: '🇫🇷' }, { code: 'ES', name: 'Spain', dialCode: '34', flag: '🇪🇸' }, { code: 'IT', name: 'Italy', dialCode: '39', flag: '🇮🇹' }, { code: 'PT', name: 'Portugal', dialCode: '351', flag: '🇵🇹' }, { code: 'NL', name: 'Netherlands', dialCode: '31', flag: '🇳🇱' }, { code: 'BE', name: 'Belgium', dialCode: '32', flag: '🇧🇪' }, { code: 'CH', name: 'Switzerland', dialCode: '41', flag: '🇨🇭' }, { code: 'AT', name: 'Austria', dialCode: '43', flag: '🇦🇹' }, { code: 'SE', name: 'Sweden', dialCode: '46', flag: '🇸🇪' }, { code: 'NO', name: 'Norway', dialCode: '47', flag: '🇳🇴' }, { code: 'DK', name: 'Denmark', dialCode: '45', flag: '🇩🇰' }, { code: 'FI', name: 'Finland', dialCode: '358', flag: '🇫🇮' }, { code: 'PL', name: 'Poland', dialCode: '48', flag: '🇵🇱' }, { code: 'CZ', name: 'Czechia', dialCode: '420', flag: '🇨🇿' }, { code: 'GR', name: 'Greece', dialCode: '30', flag: '🇬🇷' }, { code: 'TR', name: 'Turkey', dialCode: '90', flag: '🇹🇷' }, { code: 'IL', name: 'Israel', dialCode: '972', flag: '🇮🇱' }, { code: 'AE', name: 'UAE', dialCode: '971', flag: '🇦🇪' }, { code: 'SA', name: 'Saudi Arabia', dialCode: '966', flag: '🇸🇦' }, { code: 'IN', name: 'India', dialCode: '91', flag: '🇮🇳' }, { code: 'CN', name: 'China', dialCode: '86', flag: '🇨🇳' }, { code: 'JP', name: 'Japan', dialCode: '81', flag: '🇯🇵' }, { code: 'KR', name: 'South Korea', dialCode: '82', flag: '🇰🇷' }, { code: 'SG', name: 'Singapore', dialCode: '65', flag: '🇸🇬' }, { code: 'AU', name: 'Australia', dialCode: '61', flag: '🇦🇺' }, { code: 'NZ', name: 'New Zealand', dialCode: '64', flag: '🇳🇿' }, { code: 'BR', name: 'Brazil', dialCode: '55', flag: '🇧🇷' }, { code: 'AR', name: 'Argentina', dialCode: '54', flag: '🇦🇷' }, { code: 'CL', name: 'Chile', dialCode: '56', flag: '🇨🇱' }, { code: 'CO', name: 'Colombia', dialCode: '57', flag: '🇨🇴' }, { code: 'ZA', name: 'South Africa', dialCode: '27', flag: '🇿🇦' }, ]Custom country list. Defaults to the bundled subset.
defaultCountrystring | undefinedUSDefault selected country code. Default `'US'`.
placeholderstring | undefinedPhone number
disabledboolean | undefined
idstring | undefined`id` for the national-number `<input>` so an external `<label htmlFor>` (or a `Field` render-prop's generated id) can target it.
aria-labelstring | undefinedPhone numberAccessible label for the national-number input.
aria-describedbystring | undefinedForwarded to the national-number input — e.g. a `Field`'s describedby id.
aria-invalidboolean | undefinedForwarded to the national-number input — e.g. a `Field`'s invalid flag.

Country list#

The component ships with a curated subset of common origins (~35 countries). For a production deployment in many markets, pass a countries prop sourced from libphonenumber-js or world-countries:

tsx
import { getCountries, getCountryCallingCode } from 'libphonenumber-js';
const countries = getCountries().map((code) => ({
  code,
  name: code,
  dialCode: getCountryCallingCode(code),
  flag: codeToFlag(code),
}));
<PhoneInput countries={countries} />;

Accessibility#

  • Country select has aria-label="Country"; national input has its own aria-label (override via aria-label prop).
  • type="tel" + inputMode="tel" give mobile keyboards the dial pad.
  • autoComplete="tel-national" works with iOS / Android contact autofill.