diff --git a/.changeset/warm-phones-ring.md b/.changeset/warm-phones-ring.md new file mode 100644 index 000000000..948694879 --- /dev/null +++ b/.changeset/warm-phones-ring.md @@ -0,0 +1,6 @@ +--- +'@asgardeo/javascript': patch +'@asgardeo/react': patch +--- + +Add rendering support for PHONE_INPUT and OTP_INPUT component types in the embedded flow diff --git a/packages/javascript/src/models/field.ts b/packages/javascript/src/models/field.ts index 850cf98f7..472bc55b1 100644 --- a/packages/javascript/src/models/field.ts +++ b/packages/javascript/src/models/field.ts @@ -25,6 +25,7 @@ export enum FieldType { Password = 'PASSWORD', Radio = 'RADIO', Select = 'SELECT', + Tel = 'TEL', Text = 'TEXT', Textarea = 'TEXTAREA', Time = 'TIME', diff --git a/packages/react/src/components/factories/FieldFactory.tsx b/packages/react/src/components/factories/FieldFactory.tsx index cd12896d6..b31d1d029 100644 --- a/packages/react/src/components/factories/FieldFactory.tsx +++ b/packages/react/src/components/factories/FieldFactory.tsx @@ -187,6 +187,15 @@ export const createField = (config: FieldConfig): ReactElement => { autoComplete="email" /> ); + case FieldType.Tel: + return ( + ): void => onChange(e.target.value)} + autoComplete="tel" + /> + ); case FieldType.Date: return ( ): void => onChange(e.target.value)} /> diff --git a/packages/react/src/components/presentation/auth/AcceptInvite/v2/BaseAcceptInvite.tsx b/packages/react/src/components/presentation/auth/AcceptInvite/v2/BaseAcceptInvite.tsx index fd2f3dc82..cb33e4385 100644 --- a/packages/react/src/components/presentation/auth/AcceptInvite/v2/BaseAcceptInvite.tsx +++ b/packages/react/src/components/presentation/auth/AcceptInvite/v2/BaseAcceptInvite.tsx @@ -402,7 +402,7 @@ const BaseAcceptInvite: FC = ({ const validateComponents = (comps: any[]): any => { comps.forEach((comp: any) => { if ( - (comp.type === 'PASSWORD_INPUT' || comp.type === 'TEXT_INPUT' || comp.type === 'EMAIL_INPUT') && + (comp.type === 'PASSWORD_INPUT' || comp.type === 'TEXT_INPUT' || comp.type === 'EMAIL_INPUT' || comp.type === 'PHONE_INPUT' || comp.type === 'OTP_INPUT') && comp.required && comp.ref ) { diff --git a/packages/react/src/components/presentation/auth/AuthOptionFactory.tsx b/packages/react/src/components/presentation/auth/AuthOptionFactory.tsx index 210904ea7..4634c74b3 100644 --- a/packages/react/src/components/presentation/auth/AuthOptionFactory.tsx +++ b/packages/react/src/components/presentation/auth/AuthOptionFactory.tsx @@ -110,6 +110,8 @@ const getFieldType = (variant: EmbeddedFlowComponentType): FieldType => { switch (variant) { case EmbeddedFlowComponentType.EmailInput: return FieldType.Email; + case EmbeddedFlowComponentType.PhoneInput: + return FieldType.Tel; case EmbeddedFlowComponentType.PasswordInput: return FieldType.Password; case EmbeddedFlowComponentType.TextInput: @@ -224,7 +226,8 @@ const createAuthComponentFromFlow = ( switch (component.type) { case EmbeddedFlowComponentType.TextInput: case EmbeddedFlowComponentType.PasswordInput: - case EmbeddedFlowComponentType.EmailInput: { + case EmbeddedFlowComponentType.EmailInput: + case EmbeddedFlowComponentType.PhoneInput: { const identifier: string = component.ref; const value: string = formValues[identifier] || ''; const isTouched: boolean = touchedFields[identifier] || false; @@ -247,6 +250,28 @@ const createAuthComponentFromFlow = ( return cloneElement(field, {key}); } + case EmbeddedFlowComponentType.OtpInput: { + const identifier: string = component.ref; + const value: string = formValues[identifier] || ''; + const isTouched: boolean = touchedFields[identifier] || false; + const error: string = isTouched ? formErrors[identifier] : undefined; + + const field: any = createField({ + className: options.inputClassName, + error, + label: resolve(component.label) || '', + name: identifier, + onBlur: () => options.onInputBlur?.(identifier), + onChange: (newValue: string) => onInputChange(identifier, newValue), + placeholder: resolve(component.placeholder) || '', + required: component.required || false, + type: FieldType.Otp, + value, + }); + + return cloneElement(field, {key}); + } + case EmbeddedFlowComponentType.Action: { const actionId: string = component.id; const eventType: string = (component.eventType as string) || ''; diff --git a/packages/react/src/components/presentation/auth/InviteUser/v2/BaseInviteUser.tsx b/packages/react/src/components/presentation/auth/InviteUser/v2/BaseInviteUser.tsx index 4626f69c8..64d8a6087 100644 --- a/packages/react/src/components/presentation/auth/InviteUser/v2/BaseInviteUser.tsx +++ b/packages/react/src/components/presentation/auth/InviteUser/v2/BaseInviteUser.tsx @@ -343,7 +343,7 @@ const BaseInviteUser: FC = ({ const validateComponents = (comps: any[]): any => { comps.forEach((comp: any) => { if ( - (comp.type === 'TEXT_INPUT' || comp.type === 'EMAIL_INPUT' || comp.type === 'SELECT') && + (comp.type === 'TEXT_INPUT' || comp.type === 'EMAIL_INPUT' || comp.type === 'SELECT' || comp.type === 'PHONE_INPUT' || comp.type === 'OTP_INPUT') && comp.required && comp.ref ) { diff --git a/packages/react/src/components/presentation/auth/SignIn/v2/BaseSignIn.tsx b/packages/react/src/components/presentation/auth/SignIn/v2/BaseSignIn.tsx index fac015267..5dc43135d 100644 --- a/packages/react/src/components/presentation/auth/SignIn/v2/BaseSignIn.tsx +++ b/packages/react/src/components/presentation/auth/SignIn/v2/BaseSignIn.tsx @@ -281,7 +281,9 @@ const BaseSignInContent: FC = ({ if ( component.type === 'TEXT_INPUT' || component.type === 'PASSWORD_INPUT' || - component.type === 'EMAIL_INPUT' + component.type === 'EMAIL_INPUT' || + component.type === 'PHONE_INPUT' || + component.type === 'OTP_INPUT' ) { const identifier: string = component.ref; fields.push({