Open saver711 opened 1 week ago
What component do you want to use with rhf? You can achieve this with a a Controller component.
<Controller
control={control}
name="whatever"
render={ ({ field }) => (
<MyComponent {...field} onValueChange={field.onChange}>...<MyComponent/>
)}
/>
Give me more details and I will do my best to create a demo ✌️
@armandsalle Thanx for ur respone i mean your shadcn phone input component i really love it but i need to use it inside rhf
@armandsalle Is it applicable?
Yes it is, I try to create an example this evening, it is pretty simple.
You can do it this way
import { isValidPhoneNumber } from "react-phone-number-input"
import { getExampleNumber } from "libphonenumber-js"
import examples from "libphonenumber-js/mobile/examples"
import { registerLocale } from "i18n-iso-countries"
import frCountries from "i18n-iso-countries/langs/fr.json"
import PhoneInput, { Country, Value } from "react-phone-number-input/input"
registerLocale(frCountries) // Or what country you want
const schema = z.object({
ownerPhone: z
.string({
required_error: "phone required",
})
.refine((value) => {
return isValidPhoneNumber(value)
}, "Invalid phone number")
})
const options = getCountriesOptions()
function Comp() {
const defaultCountry = "FR" // Or whatever
const defaultCountryOption = options.find((option) => option.value === defaultCountry)
const [country, setCountry] = useState<CountryOption>(defaultCountryOption)
const { control } = useForm(schema, {
mode: "onTouched"
})
const phoneError = formState.errors.ownerPhone?.message
// Get example phone number for selected country for placeholder
const placeholder = replaceNumbersWithZeros(
getExampleNumber(country.value, examples)!.formatInternational()
)
const onCountryChange = (value: CountryOption) => {
setCountry(value)
setValue("owner_phone", "", {
shouldValidate: formState.isSubmitted,
})
}
return (
<form onSubmit={...}>
<InputWrapper>
<Label>Phone numer</Label>
<Combobox
value={country}
onValueChange={onCountryChange}
options={options}
renderOption={({ option }) => `${isoToEmoji(option.value)} ${option.label}`}
renderValue={(option) => option.label}
>
{({ selectedOption, isOpen }) => (
<Button
variant="tertiary"
role="combobox"
aria-expanded={isOpen}
>
{country ? (
<div>
<div>{selectedOption ? isoToEmoji(selectedOption?.value) : null}</div>
</div>
) : (
"Select a country"
)}
<ChevronDown />
</Button>
)}
</Combobox>
<Controller
control={control}
name="ownerPhone"
render={({ field }) => (
<PhoneInput
international
withCountryCallingCode
country={country.value.toUpperCase() as Country}
value={field.value}
inputComponent={Input}
variant={phoneError ? "error" : "default"}
RightIcon={<Phone />}
onChange={(value) => {
setValue("owner_phone", value as Value, { shouldValidate: true })
}}
/>
)}
/>
{phoneError ? <ErrorHint>{phoneError}</ErrorHint> : null}
</InputWrapper>
</form>)
}
@armandsalle Thanx sooo much <3
i have one last question
sometimes flags are shown like this
i don't know what is wrong
Yes this is because I use mac Emojis to render the flag, you can use your own icons or use a lib that export every flag as icons.
Not issue - Do you have any snippet for using it inside react hook form ?