{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "phone-input",
  "title": "Phone Input",
  "description": "Phone Input from the Get IT Done design system.",
  "dependencies": [
    "libphonenumber-js@^1.11.3",
    "lucide-react@^0.379.0"
  ],
  "registryDependencies": [
    "https://zero-design.itdone.de/r/button.json",
    "https://zero-design.itdone.de/r/command.json",
    "https://zero-design.itdone.de/r/input.json",
    "https://zero-design.itdone.de/r/labels-context.json",
    "https://zero-design.itdone.de/r/popover.json",
    "https://zero-design.itdone.de/r/scroll-area.json",
    "https://zero-design.itdone.de/r/utils.json",
    "https://zero-design.itdone.de/r/theme.json"
  ],
  "files": [
    {
      "path": "registry/ui/phone-input/countries.ts",
      "content": "// Generated from libphonenumber-js calling codes and Intl region names, restricted to the bundled flag set.\nexport const countries = [\n  { iso2: 'AF', name: 'Afghanistan', phone_code: '93' },\n  { iso2: 'AX', name: 'Åland Islands', phone_code: '358' },\n  { iso2: 'AL', name: 'Albania', phone_code: '355' },\n  { iso2: 'DZ', name: 'Algeria', phone_code: '213' },\n  { iso2: 'AS', name: 'American Samoa', phone_code: '1' },\n  { iso2: 'AD', name: 'Andorra', phone_code: '376' },\n  { iso2: 'AO', name: 'Angola', phone_code: '244' },\n  { iso2: 'AI', name: 'Anguilla', phone_code: '1' },\n  { iso2: 'AG', name: 'Antigua & Barbuda', phone_code: '1' },\n  { iso2: 'AR', name: 'Argentina', phone_code: '54' },\n  { iso2: 'AM', name: 'Armenia', phone_code: '374' },\n  { iso2: 'AW', name: 'Aruba', phone_code: '297' },\n  { iso2: 'AU', name: 'Australia', phone_code: '61' },\n  { iso2: 'AT', name: 'Austria', phone_code: '43' },\n  { iso2: 'AZ', name: 'Azerbaijan', phone_code: '994' },\n  { iso2: 'BS', name: 'Bahamas', phone_code: '1' },\n  { iso2: 'BH', name: 'Bahrain', phone_code: '973' },\n  { iso2: 'BD', name: 'Bangladesh', phone_code: '880' },\n  { iso2: 'BB', name: 'Barbados', phone_code: '1' },\n  { iso2: 'BY', name: 'Belarus', phone_code: '375' },\n  { iso2: 'BE', name: 'Belgium', phone_code: '32' },\n  { iso2: 'BZ', name: 'Belize', phone_code: '501' },\n  { iso2: 'BJ', name: 'Benin', phone_code: '229' },\n  { iso2: 'BM', name: 'Bermuda', phone_code: '1' },\n  { iso2: 'BT', name: 'Bhutan', phone_code: '975' },\n  { iso2: 'BO', name: 'Bolivia', phone_code: '591' },\n  { iso2: 'BA', name: 'Bosnia & Herzegovina', phone_code: '387' },\n  { iso2: 'BW', name: 'Botswana', phone_code: '267' },\n  { iso2: 'BR', name: 'Brazil', phone_code: '55' },\n  { iso2: 'IO', name: 'British Indian Ocean Territory', phone_code: '246' },\n  { iso2: 'VG', name: 'British Virgin Islands', phone_code: '1' },\n  { iso2: 'BN', name: 'Brunei', phone_code: '673' },\n  { iso2: 'BG', name: 'Bulgaria', phone_code: '359' },\n  { iso2: 'BF', name: 'Burkina Faso', phone_code: '226' },\n  { iso2: 'BI', name: 'Burundi', phone_code: '257' },\n  { iso2: 'KH', name: 'Cambodia', phone_code: '855' },\n  { iso2: 'CM', name: 'Cameroon', phone_code: '237' },\n  { iso2: 'CA', name: 'Canada', phone_code: '1' },\n  { iso2: 'CV', name: 'Cape Verde', phone_code: '238' },\n  { iso2: 'BQ', name: 'Caribbean Netherlands', phone_code: '599' },\n  { iso2: 'KY', name: 'Cayman Islands', phone_code: '1' },\n  { iso2: 'CF', name: 'Central African Republic', phone_code: '236' },\n  { iso2: 'TD', name: 'Chad', phone_code: '235' },\n  { iso2: 'CL', name: 'Chile', phone_code: '56' },\n  { iso2: 'CN', name: 'China', phone_code: '86' },\n  { iso2: 'CX', name: 'Christmas Island', phone_code: '61' },\n  { iso2: 'CC', name: 'Cocos (Keeling) Islands', phone_code: '61' },\n  { iso2: 'CO', name: 'Colombia', phone_code: '57' },\n  { iso2: 'KM', name: 'Comoros', phone_code: '269' },\n  { iso2: 'CG', name: 'Congo - Brazzaville', phone_code: '242' },\n  { iso2: 'CD', name: 'Congo - Kinshasa', phone_code: '243' },\n  { iso2: 'CK', name: 'Cook Islands', phone_code: '682' },\n  { iso2: 'CR', name: 'Costa Rica', phone_code: '506' },\n  { iso2: 'CI', name: 'Côte d’Ivoire', phone_code: '225' },\n  { iso2: 'HR', name: 'Croatia', phone_code: '385' },\n  { iso2: 'CU', name: 'Cuba', phone_code: '53' },\n  { iso2: 'CW', name: 'Curaçao', phone_code: '599' },\n  { iso2: 'CY', name: 'Cyprus', phone_code: '357' },\n  { iso2: 'CZ', name: 'Czechia', phone_code: '420' },\n  { iso2: 'DK', name: 'Denmark', phone_code: '45' },\n  { iso2: 'DJ', name: 'Djibouti', phone_code: '253' },\n  { iso2: 'DM', name: 'Dominica', phone_code: '1' },\n  { iso2: 'DO', name: 'Dominican Republic', phone_code: '1' },\n  { iso2: 'EC', name: 'Ecuador', phone_code: '593' },\n  { iso2: 'EG', name: 'Egypt', phone_code: '20' },\n  { iso2: 'SV', name: 'El Salvador', phone_code: '503' },\n  { iso2: 'GQ', name: 'Equatorial Guinea', phone_code: '240' },\n  { iso2: 'ER', name: 'Eritrea', phone_code: '291' },\n  { iso2: 'EE', name: 'Estonia', phone_code: '372' },\n  { iso2: 'SZ', name: 'Eswatini', phone_code: '268' },\n  { iso2: 'ET', name: 'Ethiopia', phone_code: '251' },\n  { iso2: 'FK', name: 'Falkland Islands', phone_code: '500' },\n  { iso2: 'FO', name: 'Faroe Islands', phone_code: '298' },\n  { iso2: 'FJ', name: 'Fiji', phone_code: '679' },\n  { iso2: 'FI', name: 'Finland', phone_code: '358' },\n  { iso2: 'FR', name: 'France', phone_code: '33' },\n  { iso2: 'GF', name: 'French Guiana', phone_code: '594' },\n  { iso2: 'PF', name: 'French Polynesia', phone_code: '689' },\n  { iso2: 'GA', name: 'Gabon', phone_code: '241' },\n  { iso2: 'GM', name: 'Gambia', phone_code: '220' },\n  { iso2: 'GE', name: 'Georgia', phone_code: '995' },\n  { iso2: 'DE', name: 'Germany', phone_code: '49' },\n  { iso2: 'GH', name: 'Ghana', phone_code: '233' },\n  { iso2: 'GI', name: 'Gibraltar', phone_code: '350' },\n  { iso2: 'GR', name: 'Greece', phone_code: '30' },\n  { iso2: 'GL', name: 'Greenland', phone_code: '299' },\n  { iso2: 'GD', name: 'Grenada', phone_code: '1' },\n  { iso2: 'GP', name: 'Guadeloupe', phone_code: '590' },\n  { iso2: 'GU', name: 'Guam', phone_code: '1' },\n  { iso2: 'GT', name: 'Guatemala', phone_code: '502' },\n  { iso2: 'GG', name: 'Guernsey', phone_code: '44' },\n  { iso2: 'GN', name: 'Guinea', phone_code: '224' },\n  { iso2: 'GW', name: 'Guinea-Bissau', phone_code: '245' },\n  { iso2: 'GY', name: 'Guyana', phone_code: '592' },\n  { iso2: 'HT', name: 'Haiti', phone_code: '509' },\n  { iso2: 'HN', name: 'Honduras', phone_code: '504' },\n  { iso2: 'HK', name: 'Hong Kong SAR China', phone_code: '852' },\n  { iso2: 'HU', name: 'Hungary', phone_code: '36' },\n  { iso2: 'IS', name: 'Iceland', phone_code: '354' },\n  { iso2: 'IN', name: 'India', phone_code: '91' },\n  { iso2: 'ID', name: 'Indonesia', phone_code: '62' },\n  { iso2: 'IR', name: 'Iran', phone_code: '98' },\n  { iso2: 'IQ', name: 'Iraq', phone_code: '964' },\n  { iso2: 'IE', name: 'Ireland', phone_code: '353' },\n  { iso2: 'IM', name: 'Isle of Man', phone_code: '44' },\n  { iso2: 'IL', name: 'Israel', phone_code: '972' },\n  { iso2: 'IT', name: 'Italy', phone_code: '39' },\n  { iso2: 'JM', name: 'Jamaica', phone_code: '1' },\n  { iso2: 'JP', name: 'Japan', phone_code: '81' },\n  { iso2: 'JE', name: 'Jersey', phone_code: '44' },\n  { iso2: 'JO', name: 'Jordan', phone_code: '962' },\n  { iso2: 'KZ', name: 'Kazakhstan', phone_code: '7' },\n  { iso2: 'KE', name: 'Kenya', phone_code: '254' },\n  { iso2: 'KI', name: 'Kiribati', phone_code: '686' },\n  { iso2: 'XK', name: 'Kosovo', phone_code: '383' },\n  { iso2: 'KW', name: 'Kuwait', phone_code: '965' },\n  { iso2: 'KG', name: 'Kyrgyzstan', phone_code: '996' },\n  { iso2: 'LA', name: 'Laos', phone_code: '856' },\n  { iso2: 'LV', name: 'Latvia', phone_code: '371' },\n  { iso2: 'LB', name: 'Lebanon', phone_code: '961' },\n  { iso2: 'LS', name: 'Lesotho', phone_code: '266' },\n  { iso2: 'LR', name: 'Liberia', phone_code: '231' },\n  { iso2: 'LY', name: 'Libya', phone_code: '218' },\n  { iso2: 'LI', name: 'Liechtenstein', phone_code: '423' },\n  { iso2: 'LT', name: 'Lithuania', phone_code: '370' },\n  { iso2: 'LU', name: 'Luxembourg', phone_code: '352' },\n  { iso2: 'MO', name: 'Macao SAR China', phone_code: '853' },\n  { iso2: 'MG', name: 'Madagascar', phone_code: '261' },\n  { iso2: 'MW', name: 'Malawi', phone_code: '265' },\n  { iso2: 'MY', name: 'Malaysia', phone_code: '60' },\n  { iso2: 'MV', name: 'Maldives', phone_code: '960' },\n  { iso2: 'ML', name: 'Mali', phone_code: '223' },\n  { iso2: 'MT', name: 'Malta', phone_code: '356' },\n  { iso2: 'MH', name: 'Marshall Islands', phone_code: '692' },\n  { iso2: 'MQ', name: 'Martinique', phone_code: '596' },\n  { iso2: 'MR', name: 'Mauritania', phone_code: '222' },\n  { iso2: 'MU', name: 'Mauritius', phone_code: '230' },\n  { iso2: 'YT', name: 'Mayotte', phone_code: '262' },\n  { iso2: 'MX', name: 'Mexico', phone_code: '52' },\n  { iso2: 'FM', name: 'Micronesia', phone_code: '691' },\n  { iso2: 'MD', name: 'Moldova', phone_code: '373' },\n  { iso2: 'MC', name: 'Monaco', phone_code: '377' },\n  { iso2: 'MN', name: 'Mongolia', phone_code: '976' },\n  { iso2: 'ME', name: 'Montenegro', phone_code: '382' },\n  { iso2: 'MS', name: 'Montserrat', phone_code: '1' },\n  { iso2: 'MA', name: 'Morocco', phone_code: '212' },\n  { iso2: 'MZ', name: 'Mozambique', phone_code: '258' },\n  { iso2: 'MM', name: 'Myanmar (Burma)', phone_code: '95' },\n  { iso2: 'NA', name: 'Namibia', phone_code: '264' },\n  { iso2: 'NR', name: 'Nauru', phone_code: '674' },\n  { iso2: 'NP', name: 'Nepal', phone_code: '977' },\n  { iso2: 'NL', name: 'Netherlands', phone_code: '31' },\n  { iso2: 'NC', name: 'New Caledonia', phone_code: '687' },\n  { iso2: 'NZ', name: 'New Zealand', phone_code: '64' },\n  { iso2: 'NI', name: 'Nicaragua', phone_code: '505' },\n  { iso2: 'NE', name: 'Niger', phone_code: '227' },\n  { iso2: 'NG', name: 'Nigeria', phone_code: '234' },\n  { iso2: 'NU', name: 'Niue', phone_code: '683' },\n  { iso2: 'NF', name: 'Norfolk Island', phone_code: '672' },\n  { iso2: 'KP', name: 'North Korea', phone_code: '850' },\n  { iso2: 'MK', name: 'North Macedonia', phone_code: '389' },\n  { iso2: 'MP', name: 'Northern Mariana Islands', phone_code: '1' },\n  { iso2: 'NO', name: 'Norway', phone_code: '47' },\n  { iso2: 'OM', name: 'Oman', phone_code: '968' },\n  { iso2: 'PK', name: 'Pakistan', phone_code: '92' },\n  { iso2: 'PW', name: 'Palau', phone_code: '680' },\n  { iso2: 'PS', name: 'Palestinian Territories', phone_code: '970' },\n  { iso2: 'PA', name: 'Panama', phone_code: '507' },\n  { iso2: 'PG', name: 'Papua New Guinea', phone_code: '675' },\n  { iso2: 'PY', name: 'Paraguay', phone_code: '595' },\n  { iso2: 'PE', name: 'Peru', phone_code: '51' },\n  { iso2: 'PH', name: 'Philippines', phone_code: '63' },\n  { iso2: 'PL', name: 'Poland', phone_code: '48' },\n  { iso2: 'PT', name: 'Portugal', phone_code: '351' },\n  { iso2: 'PR', name: 'Puerto Rico', phone_code: '1' },\n  { iso2: 'QA', name: 'Qatar', phone_code: '974' },\n  { iso2: 'RE', name: 'Réunion', phone_code: '262' },\n  { iso2: 'RO', name: 'Romania', phone_code: '40' },\n  { iso2: 'RU', name: 'Russia', phone_code: '7' },\n  { iso2: 'RW', name: 'Rwanda', phone_code: '250' },\n  { iso2: 'WS', name: 'Samoa', phone_code: '685' },\n  { iso2: 'SM', name: 'San Marino', phone_code: '378' },\n  { iso2: 'ST', name: 'São Tomé & Príncipe', phone_code: '239' },\n  { iso2: 'SA', name: 'Saudi Arabia', phone_code: '966' },\n  { iso2: 'SN', name: 'Senegal', phone_code: '221' },\n  { iso2: 'RS', name: 'Serbia', phone_code: '381' },\n  { iso2: 'SC', name: 'Seychelles', phone_code: '248' },\n  { iso2: 'SL', name: 'Sierra Leone', phone_code: '232' },\n  { iso2: 'SG', name: 'Singapore', phone_code: '65' },\n  { iso2: 'SX', name: 'Sint Maarten', phone_code: '1' },\n  { iso2: 'SK', name: 'Slovakia', phone_code: '421' },\n  { iso2: 'SI', name: 'Slovenia', phone_code: '386' },\n  { iso2: 'SB', name: 'Solomon Islands', phone_code: '677' },\n  { iso2: 'SO', name: 'Somalia', phone_code: '252' },\n  { iso2: 'ZA', name: 'South Africa', phone_code: '27' },\n  { iso2: 'KR', name: 'South Korea', phone_code: '82' },\n  { iso2: 'SS', name: 'South Sudan', phone_code: '211' },\n  { iso2: 'ES', name: 'Spain', phone_code: '34' },\n  { iso2: 'LK', name: 'Sri Lanka', phone_code: '94' },\n  { iso2: 'BL', name: 'St. Barthélemy', phone_code: '590' },\n  { iso2: 'SH', name: 'St. Helena', phone_code: '290' },\n  { iso2: 'KN', name: 'St. Kitts & Nevis', phone_code: '1' },\n  { iso2: 'LC', name: 'St. Lucia', phone_code: '1' },\n  { iso2: 'MF', name: 'St. Martin', phone_code: '590' },\n  { iso2: 'PM', name: 'St. Pierre & Miquelon', phone_code: '508' },\n  { iso2: 'VC', name: 'St. Vincent & Grenadines', phone_code: '1' },\n  { iso2: 'SD', name: 'Sudan', phone_code: '249' },\n  { iso2: 'SR', name: 'Suriname', phone_code: '597' },\n  { iso2: 'SJ', name: 'Svalbard & Jan Mayen', phone_code: '47' },\n  { iso2: 'SE', name: 'Sweden', phone_code: '46' },\n  { iso2: 'CH', name: 'Switzerland', phone_code: '41' },\n  { iso2: 'SY', name: 'Syria', phone_code: '963' },\n  { iso2: 'TW', name: 'Taiwan', phone_code: '886' },\n  { iso2: 'TJ', name: 'Tajikistan', phone_code: '992' },\n  { iso2: 'TZ', name: 'Tanzania', phone_code: '255' },\n  { iso2: 'TH', name: 'Thailand', phone_code: '66' },\n  { iso2: 'TL', name: 'Timor-Leste', phone_code: '670' },\n  { iso2: 'TG', name: 'Togo', phone_code: '228' },\n  { iso2: 'TK', name: 'Tokelau', phone_code: '690' },\n  { iso2: 'TO', name: 'Tonga', phone_code: '676' },\n  { iso2: 'TT', name: 'Trinidad & Tobago', phone_code: '1' },\n  { iso2: 'TN', name: 'Tunisia', phone_code: '216' },\n  { iso2: 'TR', name: 'Türkiye', phone_code: '90' },\n  { iso2: 'TM', name: 'Turkmenistan', phone_code: '993' },\n  { iso2: 'TC', name: 'Turks & Caicos Islands', phone_code: '1' },\n  { iso2: 'TV', name: 'Tuvalu', phone_code: '688' },\n  { iso2: 'VI', name: 'U.S. Virgin Islands', phone_code: '1' },\n  { iso2: 'UG', name: 'Uganda', phone_code: '256' },\n  { iso2: 'UA', name: 'Ukraine', phone_code: '380' },\n  { iso2: 'AE', name: 'United Arab Emirates', phone_code: '971' },\n  { iso2: 'GB', name: 'United Kingdom', phone_code: '44' },\n  { iso2: 'US', name: 'United States', phone_code: '1' },\n  { iso2: 'UY', name: 'Uruguay', phone_code: '598' },\n  { iso2: 'UZ', name: 'Uzbekistan', phone_code: '998' },\n  { iso2: 'VU', name: 'Vanuatu', phone_code: '678' },\n  { iso2: 'VA', name: 'Vatican City', phone_code: '39' },\n  { iso2: 'VE', name: 'Venezuela', phone_code: '58' },\n  { iso2: 'VN', name: 'Vietnam', phone_code: '84' },\n  { iso2: 'WF', name: 'Wallis & Futuna', phone_code: '681' },\n  { iso2: 'EH', name: 'Western Sahara', phone_code: '212' },\n  { iso2: 'YE', name: 'Yemen', phone_code: '967' },\n  { iso2: 'ZM', name: 'Zambia', phone_code: '260' },\n  { iso2: 'ZW', name: 'Zimbabwe', phone_code: '263' },\n];\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/ui/phone-input/index.tsx",
      "content": "'use client';\n\nimport parsePhoneNumberFromString, {\n  AsYouType,\n  type CarrierCode,\n  type CountryCallingCode,\n  type CountryCode,\n  type E164Number,\n  type NationalNumber,\n  type NumberType,\n} from 'libphonenumber-js';\nimport { Check, ChevronsUpDown } from 'lucide-react';\nimport { ClipboardEvent, ComponentPropsWithoutRef, FC, FormEvent, KeyboardEvent, useRef, useState } from 'react';\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';\nimport { Input } from '@/components/ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { countries } from './countries';\nimport { useStateHistory } from './use-state-history';\nimport { useLabels } from '@/components/ui/labels-context';\n\nexport type Country = (typeof countries)[number];\n\nexport type PhoneData = {\n  phoneNumber?: E164Number;\n  countryCode?: CountryCode;\n  countryCallingCode?: CountryCallingCode;\n  carrierCode?: CarrierCode;\n  nationalNumber?: NationalNumber;\n  internationalNumber?: string;\n  possibleCountries?: string;\n  isValid?: boolean;\n  isPossible?: boolean;\n  uri?: string;\n  type?: NumberType;\n};\n\nexport interface PhoneInputProps extends ComponentPropsWithoutRef<'input'> {\n  value?: string;\n  defaultCountry?: CountryCode;\n  // Folder that serves the flag SVGs (the `flags` folder of the package). Flags that fail to load are hidden instead of showing a broken image.\n  flagBasePath?: string;\n}\n\nexport function getPhoneData(phone: string): PhoneData {\n  const asYouType = new AsYouType();\n  asYouType.input(phone);\n  const number = asYouType.getNumber();\n  return {\n    phoneNumber: number?.number,\n    countryCode: number?.country,\n    countryCallingCode: number?.countryCallingCode,\n    carrierCode: number?.carrierCode,\n    nationalNumber: number?.nationalNumber,\n    internationalNumber: number?.formatInternational(),\n    possibleCountries: number?.getPossibleCountries().join(', '),\n    isValid: number?.isValid(),\n    isPossible: number?.isPossible(),\n    uri: number?.getURI(),\n    type: number?.getType(),\n  };\n}\n\nexport const PhoneInput: FC<PhoneInputProps> = ({\n  value: valueProp,\n  defaultCountry = 'US',\n  flagBasePath = '/flags',\n  className,\n  id,\n  required = true,\n  ...rest\n}: PhoneInputProps) => {\n  const l = useLabels();\n  const asYouType = new AsYouType();\n\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  const [value, handlers, history] = useStateHistory(valueProp);\n\n  if (value && value.length > 0) {\n    defaultCountry = parsePhoneNumberFromString(value)?.getPossibleCountries()[0] || defaultCountry;\n  }\n\n  const [openCommand, setOpenCommand] = useState(false);\n  const [countryCode, setCountryCode] = useState<CountryCode>(defaultCountry);\n\n  const selectedCountry = countries.find((country) => country.iso2 === countryCode);\n\n  const initializeDefaultValue = () => {\n    if (value) {\n      return value;\n    }\n\n    return `+${selectedCountry?.phone_code}`;\n  };\n\n  const handleOnInput = (event: FormEvent<HTMLInputElement>) => {\n    asYouType.reset();\n\n    let value = event.currentTarget.value;\n    if (!value.startsWith('+')) {\n      value = `+${value}`;\n    }\n\n    const formattedValue = asYouType.input(value);\n    const number = asYouType.getNumber();\n    setCountryCode(number?.country || defaultCountry);\n    event.currentTarget.value = formattedValue;\n    handlers.set(formattedValue);\n  };\n\n  const handleOnPaste = (event: ClipboardEvent<HTMLInputElement>) => {\n    event.preventDefault();\n    asYouType.reset();\n\n    const clipboardData = event.clipboardData;\n\n    if (clipboardData) {\n      const pastedData = clipboardData.getData('text/plain');\n      const formattedValue = asYouType.input(pastedData);\n      const number = asYouType.getNumber();\n      setCountryCode(number?.country || defaultCountry);\n      event.currentTarget.value = formattedValue;\n      handlers.set(formattedValue);\n    }\n  };\n\n  const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n    if ((event.metaKey || event.ctrlKey) && event.key === 'z') {\n      handlers.back();\n      if (inputRef.current && history.current > 0 && history.history[history.current - 1] !== undefined) {\n        event.preventDefault();\n        inputRef.current.value = history.history[history.current - 1] || '';\n      }\n    }\n  };\n\n  return (\n    <div className={cn('flex gap-2', className)}>\n      <Popover open={openCommand} onOpenChange={setOpenCommand} modal={true}>\n        <PopoverTrigger asChild>\n          <Button\n            type=\"button\"\n            variant=\"outline\"\n            role=\"combobox\"\n            aria-expanded={openCommand}\n            // Name = action + current value, so the visible code stays part of the accessible name.\n            aria-label={selectedCountry?.name ? `${l.selectCountry}: ${selectedCountry.iso2} +${selectedCountry.phone_code}` : l.selectCountry}\n            className=\"w-max items-center justify-between whitespace-nowrap\"\n          >\n            {selectedCountry?.name ? (\n              <span data-phone-country-code=\"\" className=\"tabular-nums\">\n                {selectedCountry.iso2} +{selectedCountry.phone_code}\n              </span>\n            ) : (\n              l.selectCountry\n            )}\n            <ChevronsUpDown className=\"ml-2 size-4 shrink-0 opacity-50\" />\n          </Button>\n        </PopoverTrigger>\n        <PopoverContent className=\"p-0 w-max\" align=\"start\">\n          <Command>\n            <CommandInput placeholder={l.searchCountry} />\n            <CommandList>\n              <CommandEmpty>{l.noCountryFound}</CommandEmpty>\n              <ScrollArea className={'[&>[data-radix-scroll-area-viewport]]:max-h-[300px]'}>\n                <CommandGroup>\n                  {countries.map((country) => {\n                    return (\n                      <CommandItem\n                        key={country.iso2}\n                        value={`${country.name} (+${country.phone_code})`}\n                        onSelect={() => {\n                          if (inputRef.current) {\n                            inputRef.current.value = `+${country.phone_code}`;\n                            handlers.set(`+${country.phone_code}`);\n                            inputRef.current.focus();\n                          }\n                          setCountryCode(country.iso2 as CountryCode);\n                          setOpenCommand(false);\n                        }}\n                      >\n                        <Check className={cn('mr-2 size-4', countryCode === country.iso2 ? '' : 'opacity-[0]')} />\n                        <img\n                          src={`${flagBasePath}/${country.iso2.toLowerCase()}.svg`}\n                          onError={(event) => {\n                            event.currentTarget.style.display = 'none';\n                          }}\n                          className=\"relative top-[2px] mr-2 w-4 h-3 object-cover\"\n                          title={country.name}\n                          alt=\"\"\n                          aria-hidden=\"true\"\n                        />\n                        {country.name}\n                        <span className=\"ml-1 text-text-subtle\">(+{country.phone_code})</span>\n                      </CommandItem>\n                    );\n                  })}\n                </CommandGroup>\n              </ScrollArea>\n            </CommandList>\n          </Command>\n        </PopoverContent>\n      </Popover>\n      <Input\n        ref={inputRef}\n        type=\"text\"\n        pattern=\"^(\\+)?[0-9\\s]*$\"\n        name=\"phone\"\n        id={id}\n        placeholder={l.phone}\n        defaultValue={initializeDefaultValue()}\n        onInput={handleOnInput}\n        onPaste={handleOnPaste}\n        onKeyDown={handleKeyDown}\n        required={required}\n        aria-required={required}\n        {...rest}\n      />\n    </div>\n  );\n};\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/ui/phone-input/use-state-history.ts",
      "content": "'use client';\n\nimport { useCallback, useMemo, useState } from 'react';\n\nexport interface UseStateHistoryHandlers<T> {\n  set: (value: T) => void;\n  back: (steps?: number) => void;\n  forward: (steps?: number) => void;\n}\n\nexport interface StateHistory<T> {\n  history: T[];\n  current: number;\n}\n\nexport function useStateHistory<T>(initialValue: T): [T, UseStateHistoryHandlers<T>, StateHistory<T>] {\n  const [state, setState] = useState<StateHistory<T>>({\n    history: [initialValue],\n    current: 0,\n  });\n\n  const set = useCallback(\n    (val: T) =>\n      setState((currentState) => {\n        const nextState = [...currentState.history.slice(0, currentState.current + 1), val];\n        return {\n          history: nextState,\n          current: nextState.length - 1,\n        };\n      }),\n    [],\n  );\n\n  const back = useCallback(\n    (steps = 1) =>\n      setState((currentState) => ({\n        history: currentState.history,\n        current: Math.max(0, currentState.current - steps),\n      })),\n    [],\n  );\n\n  const forward = useCallback(\n    (steps = 1) =>\n      setState((currentState) => ({\n        history: currentState.history,\n        current: Math.min(currentState.history.length - 1, currentState.current + steps),\n      })),\n    [],\n  );\n\n  const handlers = useMemo(() => ({ set, forward, back }), [set, forward, back]);\n\n  return [state.history[state.current], handlers, state];\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}