Components / Inputs

PhoneInput

A phone field with a country picker, formatting as you type, and E.164 output.

Install

npx shadcn@latest add https://irisui.dev/r/phone-input.json
import { PhoneInput } from "@/components/iris/phone-input/phone-input";
Registry item phone-inputBrings in foundationRegistry JSON

Preview

PhoneInput

A phone number field with a searchable country picker, formatting as you type, and E.164 output.

When to use

  • Collecting a contact or verification number, such as the number an OpsisID phone check sends its one-time code to.
  • When the backend expects E.164 (+302100000000) and people type in local formats.
  • Not for free-form text that might contain extensions or notes; use Input.

Usage

import { PhoneInput } from "@/components/iris/phone-input/phone-input";

const [phone, setPhone] = useState("");
h(PhoneInput, {
  label: "Phone number",
  name: "phone",
  value: phone,
  onValueChange: (value, details) => setPhone(value), // details: { country, formatted, status, valid }
  defaultCountry: "GR",
  preferredCountries: ["GR", "PL", "DE"],
});

Props

Prop Type Default Description
label string required Field label.
hideLabel boolean false Label for screen readers only.
value / defaultValue string – E.164 number; an empty string clears.
onValueChange (value, details) => void – Every edit, with E.164 (empty when no digits) and parsed details.
country / defaultCountry string – / "US" Controlled or initial ISO country code.
onCountryChange (iso) => void – Fires on country change, including from pasted numbers.
countries string[] all 49 Limit the picker to these ISO codes.
preferredCountries string[] ["US", "CA", "GB"] Pinned under "Suggested".
description string – Hint under the field.
error string – Replaces the built-in validation message.
validate boolean true Show a length message after blur when incomplete.
disabled / required boolean – Field state.
name string – Hidden input carrying the E.164 value.
id / className / onBlur – – Forwarded; ref goes to the number input.

Notes

  • Keyboard: typing + opens the picker with calling-code search; on the country button, arrows or a letter open it; Enter selects and returns focus to the number; Escape closes; Backspace over a separator removes the adjacent digit.
  • The number input is type="tel" with autocomplete="tel"; errors link via aria-describedby and appear with role="alert" after blur. Country changes and valid numbers are announced politely.
  • Countries show emoji flags, which render with the platform's emoji font.
  • Reduced motion snaps the picker to size and turns the slides into short fades.
  • Styled with the theme's surface, line-strong, ink, red (error), green (valid tick), rounded-control (field) and rounded-button (country and clear buttons); the open list uses shadow-floating.