From 87a83a5604b20550430ef4eefbcd573d309694e2 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 22 Jun 2025 10:02:50 +0200 Subject: Initial commit --- apps/web/src/components/ui/phone-input.tsx | 167 +++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 apps/web/src/components/ui/phone-input.tsx (limited to 'apps/web/src/components/ui/phone-input.tsx') diff --git a/apps/web/src/components/ui/phone-input.tsx b/apps/web/src/components/ui/phone-input.tsx new file mode 100644 index 00000000..95ad9131 --- /dev/null +++ b/apps/web/src/components/ui/phone-input.tsx @@ -0,0 +1,167 @@ +import * as React from "react"; +import { CheckIcon, ChevronsUpDown } from "lucide-react"; +import * as RPNInput from "react-phone-number-input"; +import flags from "react-phone-number-input/flags"; + +import { Button } from "./button"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "./command"; +import { Input } from "./input"; +import { Popover, PopoverContent, PopoverTrigger } from "./popover"; +import { ScrollArea } from "./scroll-area"; +import { cn } from "../../lib/utils"; + +type PhoneInputProps = Omit< + React.ComponentProps<"input">, + "onChange" | "value" | "ref" +> & + Omit, "onChange"> & { + onChange?: (value: RPNInput.Value) => void; + }; + +const PhoneInput: React.ForwardRefExoticComponent = + React.forwardRef, PhoneInputProps>( + ({ className, onChange, defaultCountry = "US", ...props }, ref) => { + return ( + onChange?.(value || ("" as RPNInput.Value))} + {...props} + /> + ); + } + ); +PhoneInput.displayName = "PhoneInput"; + +const InputComponent = React.forwardRef< + HTMLInputElement, + React.ComponentProps<"input"> +>(({ className, ...props }, ref) => ( + +)); +InputComponent.displayName = "InputComponent"; + +type CountryEntry = { label: string; value: RPNInput.Country | undefined }; + +type CountrySelectProps = { + disabled?: boolean; + value: RPNInput.Country; + options: CountryEntry[]; + onChange: (country: RPNInput.Country) => void; +}; + +const CountrySelect = ({ + disabled, + value: selectedCountry, + options: countryList, + onChange, +}: CountrySelectProps) => { + return ( + + + + + + + + + + No country found. + + {countryList.map(({ value, label }) => + value ? ( + + ) : null + )} + + + + + + + ); +}; + +interface CountrySelectOptionProps extends RPNInput.FlagProps { + selectedCountry: RPNInput.Country; + onChange: (country: RPNInput.Country) => void; +} + +const CountrySelectOption = ({ + country, + countryName, + selectedCountry, + onChange, +}: CountrySelectOptionProps) => { + return ( + onChange(country)}> + + {countryName} + {`+${RPNInput.getCountryCallingCode(country)}`} + + + ); +}; + +const FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => { + const Flag = flags[country]; + + return ( + + {Flag && } + + ); +}; + +export { PhoneInput }; -- cgit v1.3.1