Closed Yokohmariam closed 1 week ago
+1
My mistake was that my editor auto imported Form component from react-hook-form when it should have been imported from @/components/ui/form. 👀
still am getting same error
Added some basic type conversion and it worked for me.
onChange={(value) => onChange?.(value || ('' as RPNInput.Value))}
still am getting same error
Did you manage to get it sorted?
still am getting same error
Did you manage to get it sorted? i have built new from scratch to use with react-hook-form
this is the phone-input component ready to use with react-hook-form
import "react-phone-number-input/style.css";
import * as RPNInput from "react-phone-number-input";
import { forwardRef, useCallback } from "react";
import { Control, FieldValues, Path } from "react-hook-form";
import flags from "react-phone-number-input/flags";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { Button } from "./ui/button";
import { CheckIcon, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/components/ui/command";
import { ScrollArea } from "./ui/scroll-area";
import { InputProps } from "./ui/input";
import {
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "./ui/form";
interface PhoneProps<TFormValues extends FieldValues> {
name: Path<TFormValues>;
control: Control<TFormValues> | undefined;
label: string;
placeholder: string;
}
const Phone = <TFormValues extends FieldValues>({
name,
control,
label,
placeholder,
}: PhoneProps<TFormValues>) => {
return (
<FormField
control={control}
name={name}
render={({ field }) => (
<FormItem>
<FormLabel className="text-kblack-text text-[16px]" htmlFor={name}>
{label}
</FormLabel>
<FormControl>
<RPNInput.default
defaultCountry="ET"
className={cn("flex")}
flagComponent={FlagComponent}
countrySelectComponent={CountrySelect}
inputComponent={InputComponent}
placeholder={placeholder}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
);
};
export default Phone;
const FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => {
const Flag = flags[country];
return (
<span className="flex h-4 w-6 overflow-hidden rounded-sm ">
{Flag && <Flag title={countryName} />}
</span>
);
};
FlagComponent.displayName = "FlagComponent";
type CountrySelectOption = { label: string; value: RPNInput.Country };
type CountrySelectProps = {
disabled?: boolean;
value: RPNInput.Country;
onChange: (value: RPNInput.Country) => void;
options: CountrySelectOption[];
};
const CountrySelect = ({
disabled,
value,
onChange,
options,
}: CountrySelectProps) => {
const handleSelect = useCallback(
(country: RPNInput.Country) => {
onChange(country);
},
[onChange]
);
return (
<Popover>
<PopoverTrigger asChild>
<Button
type="button"
variant={"outline"}
className={cn(
"flex gap-1 rounded-e-none rounded-s-lg px-3 bg-kinput-bg border-0 py-6"
)}
disabled={disabled}
>
<FlagComponent country={value} countryName={value} />
<ChevronsUpDown
className={cn(
"-mr-2 h-4 w-4 opacity-50",
disabled ? "hidden" : "opacity-100"
)}
/>
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px] p-0">
<Command>
<CommandList>
<ScrollArea className="h-72">
<CommandInput placeholder="Search country..." />
<CommandEmpty>No country found.</CommandEmpty>
<CommandGroup>
{options
.filter((x) => x.value)
.map((option) => (
<CommandItem
className="gap-2"
key={option.value}
onSelect={() => handleSelect(option.value)}
>
<FlagComponent
country={option.value}
countryName={option.label}
/>
<span className="flex-1 text-sm">{option.label}</span>
{option.value && (
<span className="text-sm text-foreground/50">
{`+${RPNInput.getCountryCallingCode(option.value)}`}
</span>
)}
<CheckIcon
className={cn(
"ml-auto h-4 w-4",
option.value === value ? "opacity-100" : "opacity-0"
)}
/>
</CommandItem>
))}
</CommandGroup>
</ScrollArea>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
};
const InputComponent = forwardRef<HTMLInputElement, InputProps>(
({ className, ...props }, ref) => (
<input
name={props.name}
className="outline-none rounded-r-md w-full px-4 py-3 bg-kinput-bg flex-initial"
placeholder="Phone number"
{...props}
ref={ref}
/>
)
);
InputComponent.displayName = "InputComponent";
so you can use it like this easly inside your component
<Phone
name={"phone"}
control={form.control}
label={"Phone Number"}
placeholder={"Phone number"}
/>
make your sure to include the phone validation
import { isValidPhoneNumber } from "react-phone-number-input";
phone: z
.string()
.refine(isValidPhoneNumber, { message: "Invalid phone number" }),
onChange={(value) =>
onChange?.(
value ||
Object.assign<"", { __tag: "E164Number" }>("", {
__tag: "E164Number",
})
)
}
I encountered the same type of error. I believe it's due to the fact that the react-phone-number-input package utilizes the latest version of libphonenumber-js, which has a different type value for E164Number.
To address this issue temporarily, I included libphonenumber-js as a dependency and specified its version as 1.10.61 to revert to the previous type value for E164Number.
@jjppsia yeah this version is supposed to solve the issue I saw the channel log on gitlab how did you manage to force react-phone-number-input 3.4.1 to use libphonenumber-js 1.10.61 ?
@jjppsia yeah this version is supposed to solve the issue I saw the channel log on gitlab how did you manage to force react-phone-number-input 3.4.1 to use libphonenumber-js 1.10.61 ?
I tried this but react-phone-number-input still uses version 1.11.1
"overrides": {
"react-phone-number-input": {
"dependencies": {
"libphonenumber-js": "1.10.61"
}
}
},
oh i npm i libphonenumber-js@1.10.61
and deleted both my node_modules
and package-lock.json
and installed them again.
@jjppsia thanks for the quick response
overrides doesn't work with yarn so I used resolutions and everything now works
"resolutions": {
"react-phone-number-input/libphonenumber-js": "1.10.61"
}
@jjppsia thanks for the quick response
overrides doesn't work with yarn so I used resolutions and everything now works
"resolutions": { "react-phone-number-input/libphonenumber-js": "1.10.61" }
does not work for me
@ezevic try deleting node modules besides the resolution
@ezevic try deleting node modules besides the resolution
I did a clean install of the project's dependencies. I also checked the libphonenumber-js package version and it is 1.10.61
@ezevic try deleting node modules besides the resolution
I did a clean install of the project's dependencies. I also checked the libphonenumber-js package version and it is 1.10.61
u checked it in your package json or in the package json of react-phone-number-input
in node_modules
?
u need to make sure that installed version of react-phone-number-input
uses libphonenumber-js 1.10.61
as it could be 1.10.61 in your package json but the react-phone-number-input uses another version behind the scenes
@ezevic try deleting node modules besides the resolution
I did a clean install of the project's dependencies. I also checked the libphonenumber-js package version and it is 1.10.61
u checked it in your package json or in the package json of
react-phone-number-input
innode_modules
? u need to make sure that installed version ofreact-phone-number-input
uses libphonenumber-js 1.10.61 as it could be 1.10.61 in your package json but the react-phone-number-input uses another version behind the scenes
I checked in the package json of react-phone-number-input
First this is awesome i love it.
But when i try to use the example code The input form is throwing this error
Type '{ onChange: (...event: any[]) => void; onBlur: Noop; value: string; disabled?: boolean | undefined; name: "phone"; ref: RefCallBack; placeholder: string; }' is not assignable to type 'Omit<Props<PhoneInputWithCountrySelectType>, "onChange">'.
Types of property 'value' are incompatible.
Type 'string' is not assignable to type 'E164Number'.ts(2322)
(alias) const PhoneInput: React.ForwardRefExoticComponent
import PhoneInput