armandsalle / my-site

My small website
https://www.armand-salle.fr/
41 stars 3 forks source link

Not issue - using it inside react hook form #5

Open saver711 opened 1 week ago

saver711 commented 1 week ago

Not issue - Do you have any snippet for using it inside react hook form ?

armandsalle commented 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 ✌️

saver711 commented 1 week ago

@armandsalle Thanx for ur respone i mean your shadcn phone input component i really love it but i need to use it inside rhf

saver711 commented 1 week ago

@armandsalle Is it applicable?

armandsalle commented 1 week ago

Yes it is, I try to create an example this evening, it is pretty simple.

armandsalle commented 1 week ago

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>)
}
saver711 commented 6 days ago

@armandsalle Thanx sooo much <3 i have one last question sometimes flags are shown like this i don't know what is wrong image

armandsalle commented 6 days ago

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.