npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xsolla/xui-input-phone

v0.175.0

Published

A cross-platform phone-number input with an integrated, searchable country selector (flags and dial codes); ships with a `usePhoneNumber` hook for formatting and country detection. <!-- BEGIN:xui-mcp-instructions:input-phone --> A specialised input for en

Downloads

11,930

Readme

InputPhone

A cross-platform phone-number input with an integrated, searchable country selector (flags and dial codes); ships with a usePhoneNumber hook for formatting and country detection.

A specialised input for entering a phone number. Combines a Select (country/region picker) with a text field for the number itself. Used whenever the product requires a valid, internationally formatted phone number from the user.

When to use

  • Registration and account setup forms requiring a phone number
  • Two-factor authentication (2FA) enrollment flows
  • Payment and billing forms where a contact number is required
  • Any context where the phone number must include a country code

When not to use

When a simple freeform text field is sufficient and international formatting is not required — use a plain Input instead

When the phone number does not need country selection (e.g. a single-country product with a fixed dial code)

Do not use for non-phone numeric fields (e.g. zip codes, card numbers) — use Input with appropriatetype

Content guidelines

Placeholder mask should show the expected format for the selected country (e.g. (000) 000-0000 for US, 00 0000 0000 for AU). Update it dynamically when the country changes.

Dial code (e.g. +1) should be displayed as a non-editable prefix, not typed by the user.

Error messages should be specific: "Enter a valid phone number", not just "Invalid input". If the format is wrong, indicate the expected format.

Country selector label — use the flag icon as the primary identifier; always include the country name in the dropdown list for accessibility.

Behaviour guidelines

Auto-format the number as the user types, applying the mask for the selected country (e.g. spaces, dashes, parentheses). This reduces input errors and improves readability.

Auto-detect country from the number if the user pastes a full international number with a + prefix — update the flag and dial code accordingly.

Strip non-numeric characters on submit; store the number in E.164 format (e.g. +14155551234) regardless of display format.

Preserve the country selection when the user clears the number field with the Remove button — only the number should be cleared, not the country.

Validate on blur, not on every keystroke, to avoid showing errors before the user has finished typing.

Country list should be searchable when it contains more than ~20 entries. Prioritise common countries at the top (e.g. based on locale or previous selection).

Accessibility

The country selector must have an accessible name (e.g. aria-label="Select country") — flag icons alone are not sufficient for screen readers.

The dial code prefix must be announced as part of the field context, either via aria-label on the input or by including it in a visible label.

The phone input should use type="tel" to trigger the numeric keyboard on mobile.

The input should have autocomplete="tel" to support autofill.

Error messages must be linked via aria-describedby so screen readers announce them on focus.

Ensure the country selector and number field are reachable and operable via keyboard alone.

Installation

npm install @xsolla/xui-input-phone

Imports

import {
  InputPhone,
  usePhoneNumber,
  allCountries,
  defaultCountries,
  getCountryByCode,
  getCountryByDialCode,
  getFlag,
} from '@xsolla/xui-input-phone';
import type {
  InputPhoneProps,
  Country,
  UsePhoneNumberOptions,
  UsePhoneNumberReturn,
} from '@xsolla/xui-input-phone';

Quick start

const [phone, setPhone] = useState('');

<InputPhone
  value={phone}
  onChangeText={setPhone}
  placeholder="+1 (000) 000-0000"
/>;

API Reference

<InputPhone>

| Prop | Type | Default | Description | | --- | --- | --- | --- | | value | string | — | Controlled value. | | placeholder | string | — | Placeholder shown when empty. | | onChange | (e: ChangeEvent<HTMLInputElement>) => void | — | Native change handler. | | onChangeText | (text: string) => void | — | Simplified change handler. | | size | 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' | 'md' | Control size. | | name | string | — | Form field name. | | disabled | boolean | false | Disable the control. | | error | boolean | false | Apply error styling. | | errorMessage | string | — | Error message; also marks the control invalid. | | countries | Country[] | allCountries | Countries available in the dropdown. | | selectedCountry | Country | — | Currently selected country. | | onCountryChange | (country: Country) => void | — | Fired when the country changes. | | extraClear | boolean | false | Show a clear button when the input has a value. | | onRemove | () => void | — | Fired when the clear button is pressed. | | checked | boolean | false | Show a success indicator (suppressed when errorMessage is set). | | checkedIcon | ReactNode | <CheckCr /> | Override the checked icon. | | id | string | auto | HTML id. | | aria-label | string | — | Accessible label when no visible label is present. | | testID | string | — | Test identifier. |

InputPhone also accepts the standard InputHTMLAttributes (excluding size and onChange).

Inherits ThemeOverrideProps (themeMode, themeProductContext).

Hooks

usePhoneNumber(options?)

Manages a phone-number value with normalisation, formatting (via libphonenumber-js) and automatic country detection.

| Option | Type | Description | | --- | --- | --- | | initialCountry | string | ISO 3166-1 alpha-2 code (e.g. 'US'). | | initialValue | string | Initial phone-number value. | | onChange | (phoneNumber: string) => void | Fired when the phone number changes. | | onCountryChange | (country: Country \| undefined) => void | Fired when the country changes. |

Returns:

| Field | Type | Description | | --- | --- | --- | | phoneNumber | string | Raw phone number (with country code). | | formattedPhoneNumber | string | Display-formatted phone number. | | country | Country \| undefined | Detected/selected country. | | countries | Country[] | All available countries (allCountries). | | handlePhoneChange | (value: string) => void | Handle phone input change. | | handleCountryChange | (country: Country) => void | Handle country selection. | | setPhoneNumber | (value: string) => void | Set the phone number programmatically. |

allCountries

Country[] — full list of supported countries.

defaultCountries

Country[] — curated default subset.

getCountryByCode

(code: string) => Country | undefined — look up by ISO alpha-2 code.

getCountryByDialCode

(dialCode: string) => Country | undefined — look up by dial code (e.g. '+44').

getFlag

(code: string) => ReactNode — get the flag icon for a country code.

Types

interface Country {
  code: string;       // ISO 3166-1 alpha-2 (e.g. "US")
  name: string;
  dialCode: string;   // e.g. "+1"
  flag?: ReactNode;
}

Examples

With country selection

const [phone, setPhone] = useState('');
const [country, setCountry] = useState<Country | undefined>();

<InputPhone
  value={phone}
  onChangeText={setPhone}
  selectedCountry={country}
  onCountryChange={setCountry}
/>;

Using usePhoneNumber

Reach for the hook when you want normalisation, formatting (via libphonenumber-js) and automatic country detection bundled together; reach for the imperative selectedCountry/onCountryChange API when you already manage the value and only need a controlled country selector.

const { phoneNumber, country, handlePhoneChange, handleCountryChange } =
  usePhoneNumber({ initialCountry: 'MY' });

<InputPhone
  value={phoneNumber}
  onChangeText={handlePhoneChange}
  selectedCountry={country}
  onCountryChange={handleCountryChange}
/>;

Custom countries

const countries: Country[] = [
  { code: 'US', name: 'United States', dialCode: '+1' },
  { code: 'GB', name: 'United Kingdom', dialCode: '+44' },
  { code: 'DE', name: 'Germany', dialCode: '+49' },
];

<InputPhone countries={countries} />;

Sizes

<InputPhone size="xs" placeholder="Extra small" />
<InputPhone size="sm" placeholder="Small" />
<InputPhone size="md" placeholder="Medium" />
<InputPhone size="lg" placeholder="Large" />
<InputPhone size="xl" placeholder="Extra large" />

Error state

<InputPhone
  value="123"
  error
  errorMessage="Please enter a valid phone number"
/>

Accessibility

  • The country selector uses role="combobox"; the list uses role="listbox" with role="option" items, linked via aria-controls.
  • The phone field uses type="tel" and inputMode="tel".
  • Keyboard: ArrowDown opens / advances; ArrowUp moves up; Enter selects; Escape closes the dropdown.
  • errorMessage is linked via aria-describedby and marks the input invalid.