mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
fix(ui): fix react-hook-form issues
fix react-hook-form integration issues
This commit is contained in:
parent
d4182efc8b
commit
31d7539d6f
5 changed files with 86 additions and 51 deletions
|
@ -16,7 +16,7 @@ import { getInputHtmlProps } from './utils';
|
|||
|
||||
export type { IdentifierInputType, EnabledIdentifierTypes } from './use-smart-input-field';
|
||||
|
||||
type Props = Omit<HTMLProps<HTMLInputElement>, 'onChange' | 'prefix'> & {
|
||||
type Props = Omit<HTMLProps<HTMLInputElement>, 'onChange' | 'prefix' | 'value'> & {
|
||||
className?: string;
|
||||
errorMessage?: string;
|
||||
isDanger?: boolean;
|
||||
|
@ -24,12 +24,12 @@ type Props = Omit<HTMLProps<HTMLInputElement>, 'onChange' | 'prefix'> & {
|
|||
enabledTypes?: EnabledIdentifierTypes;
|
||||
currentType?: IdentifierInputType;
|
||||
onTypeChange?: (type: IdentifierInputType) => void;
|
||||
value?: string;
|
||||
onChange?: (value: string) => void;
|
||||
};
|
||||
|
||||
const SmartInputField = (
|
||||
{
|
||||
value,
|
||||
onChange,
|
||||
currentType = SignInIdentifier.Username,
|
||||
enabledTypes = [currentType],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { SignInIdentifier } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
|
@ -36,13 +36,12 @@ const IdentifierRegisterForm = ({ className, autoFocus, signUpMethods }: Props)
|
|||
const { errorMessage, clearErrorMessage, onSubmit } = useOnSubmit();
|
||||
|
||||
const {
|
||||
register,
|
||||
setValue,
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitted },
|
||||
control,
|
||||
} = useForm<FormState>({
|
||||
reValidateMode: 'onChange',
|
||||
defaultValues: { identifier: '' },
|
||||
});
|
||||
|
||||
const onSubmitHandler = useCallback(
|
||||
|
@ -62,17 +61,10 @@ const IdentifierRegisterForm = ({ className, autoFocus, signUpMethods }: Props)
|
|||
|
||||
return (
|
||||
<form className={classNames(styles.form, className)} onSubmit={onSubmitHandler}>
|
||||
<SmartInputField
|
||||
required
|
||||
autoComplete="new-identifier"
|
||||
autoFocus={autoFocus}
|
||||
className={styles.inputField}
|
||||
currentType={inputType}
|
||||
isDanger={!!errors.identifier || !!errorMessage}
|
||||
errorMessage={errors.identifier?.message}
|
||||
enabledTypes={signUpMethods}
|
||||
onTypeChange={setInputType}
|
||||
{...register('identifier', {
|
||||
<Controller
|
||||
control={control}
|
||||
name="identifier"
|
||||
rules={{
|
||||
required: getGeneralIdentifierErrorMessage(signUpMethods, 'required'),
|
||||
validate: (value) => {
|
||||
const errorMessage = validateIdentifierField(inputType, value);
|
||||
|
@ -85,11 +77,24 @@ const IdentifierRegisterForm = ({ className, autoFocus, signUpMethods }: Props)
|
|||
|
||||
return true;
|
||||
},
|
||||
})}
|
||||
/* Overwrite default input onChange handler */
|
||||
onChange={(value) => {
|
||||
setValue('identifier', value, { shouldValidate: isSubmitted, shouldDirty: true });
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<SmartInputField
|
||||
autoComplete="new-identifier"
|
||||
autoFocus={autoFocus}
|
||||
className={styles.inputField}
|
||||
{...field}
|
||||
currentType={inputType}
|
||||
isDanger={!!errors.identifier || !!errorMessage}
|
||||
errorMessage={errors.identifier?.message}
|
||||
enabledTypes={signUpMethods}
|
||||
onTypeChange={setInputType}
|
||||
/* Overwrite default input onChange handler */
|
||||
onChange={(value) => {
|
||||
setValue('identifier', value, { shouldValidate: isSubmitted, shouldDirty: true });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{errorMessage && <ErrorMessage className={styles.formErrors}>{errorMessage}</ErrorMessage>}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { SignInIdentifier } from '@logto/schemas';
|
|||
import type { SignIn } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import ErrorMessage from '@/components/ErrorMessage';
|
||||
|
@ -40,9 +40,9 @@ const IdentifierSignInForm = ({ className, autoFocus, signInMethods }: Props) =>
|
|||
);
|
||||
|
||||
const {
|
||||
register,
|
||||
setValue,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors, isSubmitted },
|
||||
} = useForm<FormState>({
|
||||
reValidateMode: 'onChange',
|
||||
|
@ -68,16 +68,10 @@ const IdentifierSignInForm = ({ className, autoFocus, signInMethods }: Props) =>
|
|||
|
||||
return (
|
||||
<form className={classNames(styles.form, className)} onSubmit={onSubmitHandler}>
|
||||
<SmartInputField
|
||||
autoComplete="new-identifier"
|
||||
autoFocus={autoFocus}
|
||||
className={styles.inputField}
|
||||
currentType={inputType}
|
||||
isDanger={!!errors.identifier || !!errorMessage}
|
||||
errorMessage={errors.identifier?.message}
|
||||
enabledTypes={enabledSignInMethods}
|
||||
onTypeChange={setInputType}
|
||||
{...register('identifier', {
|
||||
<Controller
|
||||
control={control}
|
||||
name="identifier"
|
||||
rules={{
|
||||
required: getGeneralIdentifierErrorMessage(enabledSignInMethods, 'required'),
|
||||
validate: (value) => {
|
||||
const errorMessage = validateIdentifierField(inputType, value);
|
||||
|
@ -86,11 +80,24 @@ const IdentifierSignInForm = ({ className, autoFocus, signInMethods }: Props) =>
|
|||
? getGeneralIdentifierErrorMessage(enabledSignInMethods, 'invalid')
|
||||
: true;
|
||||
},
|
||||
})}
|
||||
/* Overwrite default input onChange handler */
|
||||
onChange={(value) => {
|
||||
setValue('identifier', value, { shouldValidate: isSubmitted, shouldDirty: true });
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<SmartInputField
|
||||
autoComplete="identifier"
|
||||
autoFocus={autoFocus}
|
||||
className={styles.inputField}
|
||||
{...field}
|
||||
currentType={inputType}
|
||||
isDanger={!!errors.identifier || !!errorMessage}
|
||||
errorMessage={errors.identifier?.message}
|
||||
enabledTypes={enabledSignInMethods}
|
||||
onTypeChange={setInputType}
|
||||
/* Overwrite default input onChange handler */
|
||||
onChange={(value) => {
|
||||
setValue('identifier', value, { shouldValidate: isSubmitted, shouldDirty: true });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{errorMessage && <ErrorMessage className={styles.formErrors}>{errorMessage}</ErrorMessage>}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { SignInIdentifier } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
|
@ -46,6 +46,7 @@ const PasswordSignInForm = ({ className, autoFocus, signInMethods }: Props) => {
|
|||
register,
|
||||
setValue,
|
||||
handleSubmit,
|
||||
control,
|
||||
formState: { errors, isSubmitted },
|
||||
} = useForm<FormState>({
|
||||
reValidateMode: 'onChange',
|
||||
|
@ -72,27 +73,34 @@ const PasswordSignInForm = ({ className, autoFocus, signInMethods }: Props) => {
|
|||
|
||||
return (
|
||||
<form className={classNames(styles.form, className)} onSubmit={onSubmitHandler}>
|
||||
<SmartInputField
|
||||
autoComplete="identifier"
|
||||
autoFocus={autoFocus}
|
||||
className={styles.inputField}
|
||||
currentType={inputType}
|
||||
isDanger={!!errors.identifier}
|
||||
errorMessage={errors.identifier?.message}
|
||||
enabledTypes={signInMethods}
|
||||
onTypeChange={setInputType}
|
||||
{...register('identifier', {
|
||||
<Controller
|
||||
control={control}
|
||||
name="identifier"
|
||||
rules={{
|
||||
required: getGeneralIdentifierErrorMessage(signInMethods, 'required'),
|
||||
validate: (value) => {
|
||||
const errorMessage = validateIdentifierField(inputType, value);
|
||||
|
||||
return errorMessage ? getGeneralIdentifierErrorMessage(signInMethods, 'invalid') : true;
|
||||
},
|
||||
})}
|
||||
/* Overwrite default input onChange handler */
|
||||
onChange={(value) => {
|
||||
setValue('identifier', value, { shouldValidate: isSubmitted, shouldDirty: true });
|
||||
}}
|
||||
render={({ field }) => (
|
||||
<SmartInputField
|
||||
autoComplete="identifier"
|
||||
autoFocus={autoFocus}
|
||||
className={styles.inputField}
|
||||
{...field}
|
||||
currentType={inputType}
|
||||
isDanger={!!errors.identifier}
|
||||
errorMessage={errors.identifier?.message}
|
||||
enabledTypes={signInMethods}
|
||||
onTypeChange={setInputType}
|
||||
/* Overwrite default input onChange handler */
|
||||
onChange={(value) => {
|
||||
setValue('identifier', value, { shouldValidate: isSubmitted, shouldDirty: true });
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<PasswordInputField
|
||||
|
|
|
@ -97,3 +97,18 @@ export const formatPhoneNumberWithCountryCallingCode = (number: string) => {
|
|||
return number;
|
||||
}
|
||||
};
|
||||
|
||||
export const parsePhoneNumber = (value: string) => {
|
||||
try {
|
||||
const phoneNumber = parsePhoneNumberWithError(parseE164Number(value));
|
||||
|
||||
return {
|
||||
countryCallingCode: phoneNumber.countryCallingCode,
|
||||
nationalNumber: phoneNumber.nationalNumber,
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
nationalNumber: value,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue