Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not issue - using it inside react hook form #5

Open
saver711 opened this issue Jul 7, 2024 · 7 comments
Open

Not issue - using it inside react hook form #5

saver711 opened this issue Jul 7, 2024 · 7 comments

Comments

@saver711
Copy link

saver711 commented Jul 7, 2024

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

@armandsalle
Copy link
Owner

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
Copy link
Author

saver711 commented Jul 7, 2024

@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
Copy link
Author

saver711 commented Jul 9, 2024

@armandsalle
Is it applicable?

@armandsalle
Copy link
Owner

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

@armandsalle
Copy link
Owner

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
Copy link
Author

@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
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants