{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input-phone",
  "title": "Phone input",
  "description": "An international phone input with country selection, E.164 values and Familis form styling.",
  "dependencies": [
    "react-phone-number-input@^3.4.18",
    "cn@^0.4.0"
  ],
  "registryDependencies": [
    "Familis-co/registry/input",
    "Familis-co/registry/native-select"
  ],
  "files": [
    {
      "path": "registry/familis/ui/input-phone.tsx",
      "content": "\"use client\"\n\nimport {\n  forwardRef,\n  type ComponentProps,\n  type ForwardRefExoticComponent,\n  type RefAttributes,\n} from \"react\"\nimport PhoneInput, {\n  getCountryCallingCode,\n  type Country,\n  type Props,\n  type Value,\n} from \"react-phone-number-input\"\nimport { cn } from \"cn\"\nimport { Input } from \"@/registry/familis/ui/input\"\nimport { NativeSelect, NativeSelectOption } from \"@/registry/familis/ui/native-select\"\n\n/** Countries offered when `countries` is not provided: Benelux, neighbours and common destinations. */\nexport const DEFAULT_PHONE_COUNTRIES: Country[] = [\n  \"BE\",\n  \"NL\",\n  \"LU\",\n  \"FR\",\n  \"DE\",\n  \"GB\",\n  \"ES\",\n  \"IT\",\n  \"CH\",\n  \"US\",\n]\n\n/**\n * Converts an ISO 3166-1 alpha-2 country code into its flag emoji.\n *\n * Flags are pairs of regional indicator symbols, offset from the ASCII letters of the code.\n * Native `<option>` elements only render text, so emoji are the only way to show a flag there.\n *\n * @param {Country} [country] - The country code, or undefined for the international option.\n * @returns {string} The flag emoji, or a globe for the international option.\n */\nfunction getFlagEmoji(country?: Country): string {\n  if (!country) return \"🌐\"\n  return String.fromCodePoint(...[...country].map((letter) => 0x1f1a5 + letter.charCodeAt(0)))\n}\n\n// The package forwards its ref to the input at runtime, but declares a class ref.\nconst PhoneInputWithRef = PhoneInput as unknown as ForwardRefExoticComponent<\n  Props<ComponentProps<\"input\">> & RefAttributes<HTMLInputElement>\n>\n\nexport type InputPhoneProps = Omit<\n  Props<ComponentProps<\"input\">>,\n  | \"onChange\"\n  | \"inputComponent\"\n  | \"countrySelectComponent\"\n  | \"countrySelectProps\"\n  | \"containerComponent\"\n  | \"containerComponentProps\"\n> & {\n  /** E.164 value, or an empty string when cleared. Partial numbers are not necessarily valid. */\n  onChange: (value: Value | \"\") => void\n  countryLabel?: string\n  ref?: React.Ref<HTMLInputElement>\n}\n\ntype CountrySelectProps = {\n  value?: Country\n  onChange: (country?: Country) => void\n  options: { value?: Country; label: string; divider?: boolean }[]\n  disabled?: boolean\n  readOnly?: boolean\n  \"aria-label\"?: string\n}\n\n/**\n * Renders the country picker as a native select with a flag and calling code per option.\n *\n * @param {CountrySelectProps} props - Selected country, change handler and options from the phone input.\n * @param {React.ForwardedRef<HTMLSelectElement>} ref - Ref forwarded to the underlying select.\n * @returns {React.ReactElement} The country select.\n */\nconst CountrySelect = forwardRef<HTMLSelectElement, CountrySelectProps>(function CountrySelect(\n  { value, onChange, options, disabled, readOnly, \"aria-label\": label },\n  ref,\n) {\n  return (\n    <NativeSelect\n      ref={ref}\n      aria-label={label ?? \"Country\"}\n      value={value ?? \"\"}\n      disabled={disabled || readOnly}\n      onChange={(event) => onChange((event.target.value || undefined) as Country | undefined)}\n    >\n      {options\n        .filter((option) => !option.divider)\n        .map((option) => (\n          <NativeSelectOption key={option.value ?? \"international\"} value={option.value ?? \"\"}>\n            {getFlagEmoji(option.value)} {option.label}\n            {option.value ? ` (+${getCountryCallingCode(option.value)})` : \"\"}\n          </NativeSelectOption>\n        ))}\n    </NativeSelect>\n  )\n})\n\n/**\n * An international phone input with a flagged country select that emits E.164 values.\n *\n * Every default (`defaultCountry`, `countries`, `addInternationalOption`, `autoComplete`,\n * `countryLabel`) can be overridden through its prop. Labels default to English; localize them\n * with `labels` (e.g. `react-phone-number-input/locale/fr`), `locales` and `countryLabel`.\n *\n * @param {InputPhoneProps} props - Phone input props, forwarded to `react-phone-number-input`.\n * @returns {React.ReactElement} The phone input.\n */\nexport function InputPhone({\n  className,\n  onChange,\n  countryLabel = \"Country\",\n  defaultCountry = \"BE\",\n  countries = DEFAULT_PHONE_COUNTRIES,\n  addInternationalOption = false,\n  autoComplete = \"tel\",\n  ref,\n  ...props\n}: InputPhoneProps) {\n  return (\n    <PhoneInputWithRef\n      {...props}\n      ref={ref}\n      defaultCountry={defaultCountry}\n      countries={countries}\n      addInternationalOption={addInternationalOption}\n      autoComplete={autoComplete}\n      className={cn(\n        \"flex min-w-0 items-center gap-2 [&>input]:flex-1 [&_[data-slot=native-select-wrapper]]:max-w-[45%]\",\n        className,\n      )}\n      inputComponent={Input}\n      countrySelectComponent={CountrySelect}\n      countrySelectProps={{ \"aria-label\": countryLabel }}\n      onChange={(value) => onChange(value ?? \"\")}\n    />\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "meta": {
    "base": "base",
    "storybookId": "ui-phone-input--default"
  },
  "type": "registry:ui"
}