Skip to content

Commit

Permalink
Merge branch 'main' into elef/sdk-1772-2fa-phone-selection-screen-sho…
Browse files Browse the repository at this point in the history
…uld-re-show-on-cancel
  • Loading branch information
panteliselef authored May 31, 2024
2 parents c83133a + be88436 commit 65c2faf
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-mirrors-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/elements': patch
---

Fix forms unable to submit upon re-mounting
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import * as Clerk from '@clerk/elements/common';
import * as SignUp from '@clerk/elements/sign-up';
import Link from 'next/link';
import type { ComponentProps } from 'react';

import { H1, HR as Hr, P } from '@/components/design';
Expand Down Expand Up @@ -42,6 +43,16 @@ export default function SignUpPage() {
<div className='flex flex-col items-center justify-center gap-12'>
<H1>Sign Up</H1>

<p className='text-base text-zinc-400'>
Have an account?{' '}
<Link
href='/sign-in'
className='no-underline hover:underline'
>
Sign In
</Link>
</p>

<div className='flex flex-col items-stretch justify-center gap-2'>
<Clerk.Connection
name='github'
Expand Down Expand Up @@ -105,6 +116,16 @@ export default function SignUpPage() {
<div className='flex flex-col items-center justify-center gap-12'>
<H1>Sign Up</H1>

<p className='text-base text-zinc-400'>
Have an account?{' '}
<Link
href='/sign-in'
className='no-underline hover:underline'
>
Sign In
</Link>
</p>

<div className='flex flex-col items-stretch justify-center gap-2'>
<Clerk.Connection
name='github'
Expand Down
27 changes: 27 additions & 0 deletions packages/elements/src/internals/machines/sign-in/router.machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ export const SignInRouterMachine = setup({
params: { strategy: 'saml' },
}),
},
'FORM.ATTACH': {
description: 'Attach/re-attach the form to the router.',
actions: enqueueActions(({ enqueue, event }) => {
enqueue.assign({
formRef: event.formRef,
});

// Reset the current step, to reset the form reference.
enqueue.raise({ type: 'RESET.STEP' });
}),
},
'NAVIGATE.PREVIOUS': '.Hist',
'NAVIGATE.START': '.Start',
LOADING: {
Expand Down Expand Up @@ -292,6 +303,10 @@ export const SignInRouterMachine = setup({
},
},
on: {
'RESET.STEP': {
target: 'Start',
reenter: true,
},
NEXT: [
{
guard: 'isComplete',
Expand Down Expand Up @@ -329,6 +344,10 @@ export const SignInRouterMachine = setup({
},
},
on: {
'RESET.STEP': {
target: 'FirstFactor',
reenter: true,
},
NEXT: [
{
guard: 'isComplete',
Expand Down Expand Up @@ -399,6 +418,10 @@ export const SignInRouterMachine = setup({
},
},
on: {
'RESET.STEP': {
target: 'SecondFactor',
reenter: true,
},
NEXT: [
{
guard: 'isComplete',
Expand Down Expand Up @@ -426,6 +449,10 @@ export const SignInRouterMachine = setup({
},
},
on: {
'RESET.STEP': {
target: 'ResetPassword',
reenter: true,
},
NEXT: [
{
guard: 'isComplete',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import type { TFormMachine } from '~/internals/machines/form';
import type {
BaseRouterContext,
BaseRouterErrorEvent,
BaseRouterFormAttachEvent,
BaseRouterInput,
BaseRouterLoadingEvent,
BaseRouterNextEvent,
BaseRouterPrevEvent,
BaseRouterRedirectEvent,
BaseRouterResetEvent,
BaseRouterResetStepEvent,
BaseRouterSetClerkEvent,
BaseRouterStartEvent,
BaseRouterTransferEvent,
Expand Down Expand Up @@ -47,6 +49,7 @@ export type SignInRouterSystemId = keyof typeof SignInRouterSystemId;

// ---------------------------------- Events ---------------------------------- //

export type SignInRouterFormAttachEvent = BaseRouterFormAttachEvent;
export type SignInRouterNextEvent = BaseRouterNextEvent<SignInResource>;
export type SignInRouterStartEvent = BaseRouterStartEvent;
export type SignInRouterPrevEvent = BaseRouterPrevEvent;
Expand All @@ -56,6 +59,7 @@ export type SignInRouterErrorEvent = BaseRouterErrorEvent;
export type SignInRouterTransferEvent = BaseRouterTransferEvent;
export type SignInRouterRedirectEvent = BaseRouterRedirectEvent;
export type SignInRouterResetEvent = BaseRouterResetEvent;
export type SignInRouterResetStepEvent = BaseRouterResetStepEvent;
export type SignInRouterLoadingEvent = BaseRouterLoadingEvent<'start' | 'verifications' | 'reset-password'>;
export type SignInRouterSetClerkEvent = BaseRouterSetClerkEvent;
export type SignInRouterSubmitEvent = { type: 'SUBMIT' };
Expand All @@ -73,13 +77,15 @@ export type SignInRouterNavigationEvents =
| SignInRouterPrevEvent;

export type SignInRouterEvents =
| SignInRouterFormAttachEvent
| SignInRouterInitEvent
| SignInRouterNextEvent
| SignInRouterNavigationEvents
| SignInRouterErrorEvent
| SignInRouterTransferEvent
| SignInRouterRedirectEvent
| SignInRouterResetEvent
| SignInRouterResetStepEvent
| SignInVerificationFactorUpdateEvent
| SignInRouterLoadingEvent
| SignInRouterSetClerkEvent
Expand Down
23 changes: 23 additions & 0 deletions packages/elements/src/internals/machines/sign-up/router.machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ export const SignUpRouterMachine = setup({
params: { strategy: 'saml' },
}),
},
'FORM.ATTACH': {
description: 'Attach/re-attach the form to the router.',
actions: enqueueActions(({ enqueue, event }) => {
enqueue.assign({
formRef: event.formRef,
});

// Reset the current step, to reset the form reference.
enqueue.raise({ type: 'RESET.STEP' });
}),
},
'NAVIGATE.PREVIOUS': '.Hist',
'NAVIGATE.START': '.Start',
LOADING: {
Expand Down Expand Up @@ -274,6 +285,10 @@ export const SignUpRouterMachine = setup({
},
},
on: {
'RESET.STEP': {
target: 'Start',
reenter: true,
},
NEXT: [
{
guard: 'isStatusComplete',
Expand Down Expand Up @@ -307,6 +322,10 @@ export const SignUpRouterMachine = setup({
},
},
on: {
'RESET.STEP': {
target: 'Continue',
reenter: true,
},
NEXT: [
{
guard: 'isStatusComplete',
Expand Down Expand Up @@ -355,6 +374,10 @@ export const SignUpRouterMachine = setup({
},
],
on: {
'RESET.STEP': {
target: 'Verification',
reenter: true,
},
NEXT: [
{
guard: 'isStatusComplete',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import type { TFormMachine } from '~/internals/machines/form';
import type {
BaseRouterContext,
BaseRouterErrorEvent,
BaseRouterFormAttachEvent,
BaseRouterInput,
BaseRouterLoadingEvent,
BaseRouterNextEvent,
BaseRouterPrevEvent,
BaseRouterRedirectEvent,
BaseRouterResetEvent,
BaseRouterResetStepEvent,
BaseRouterSetClerkEvent,
BaseRouterStartEvent,
BaseRouterTransferEvent,
Expand Down Expand Up @@ -41,13 +43,15 @@ export type SignUpRouterSystemId = keyof typeof SignUpRouterSystemId;

// ---------------------------------- Events ---------------------------------- //

export type SignUpRouterFormAttachEvent = BaseRouterFormAttachEvent;
export type SignUpRouterNextEvent = BaseRouterNextEvent<SignUpResource>;
export type SignUpRouterStartEvent = BaseRouterStartEvent;
export type SignUpRouterPrevEvent = BaseRouterPrevEvent;
export type SignUpRouterErrorEvent = BaseRouterErrorEvent;
export type SignUpRouterTransferEvent = BaseRouterTransferEvent;
export type SignUpRouterRedirectEvent = BaseRouterRedirectEvent;
export type SignUpRouterResetEvent = BaseRouterResetEvent;
export type SignUpRouterResetStepEvent = BaseRouterResetStepEvent;
export type SignUpRouterLoadingEvent = BaseRouterLoadingEvent<'start' | 'verifications' | 'continue'>;
export type SignUpRouterSetClerkEvent = BaseRouterSetClerkEvent;

Expand All @@ -60,13 +64,15 @@ export interface SignUpRouterInitEvent extends BaseRouterInput {
export type SignUpRouterNavigationEvents = SignUpRouterStartEvent | SignUpRouterPrevEvent;

export type SignUpRouterEvents =
| SignUpRouterFormAttachEvent
| SignUpRouterInitEvent
| SignUpRouterNextEvent
| SignUpRouterNavigationEvents
| SignUpRouterErrorEvent
| SignUpRouterTransferEvent
| SignUpRouterRedirectEvent
| SignUpRouterResetEvent
| SignUpRouterResetStepEvent
| SignUpRouterLoadingEvent
| SignUpRouterSetClerkEvent;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ import type {
SignInStrategy,
Web3Strategy,
} from '@clerk/types';
import type { ActorRefFrom } from 'xstate';

import type { ClerkElementsError } from '~/internals/errors';
import type { TFormMachine } from '~/internals/machines/form';
import type { ClerkRouter } from '~/react/router';

// ---------------------------------- Events ---------------------------------- //

export type BaseRouterLoadingStep = 'start' | 'verifications' | 'continue' | 'reset-password';

export type BaseRouterNextEvent<T extends ClerkResource> = { type: 'NEXT'; resource?: T };
export type BaseRouterFormAttachEvent = { type: 'FORM.ATTACH'; formRef: ActorRefFrom<TFormMachine> };
export type BaseRouterPrevEvent = { type: 'NAVIGATE.PREVIOUS' };
export type BaseRouterStartEvent = { type: 'NAVIGATE.START' };
export type BaseRouterResetEvent = { type: 'RESET' };
export type BaseRouterResetStepEvent = { type: 'RESET.STEP' };
export type BaseRouterErrorEvent = { type: 'ERROR'; error: Error };
export type BaseRouterTransferEvent = { type: 'TRANSFER' };
export type BaseRouterLoadingEvent<TSteps extends BaseRouterLoadingStep> = (
Expand Down
8 changes: 8 additions & 0 deletions packages/elements/src/react/sign-in/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ function SignInFlowProvider({ children, exampleMode }: SignInFlowProviderProps)
}
});

// Ensure that the latest instantiated formRef is attached to the router
if (formRef && actor.getSnapshot().can({ type: 'RESET.STEP' })) {
actor.send({
type: 'FORM.ATTACH',
formRef,
});
}

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [clerk, exampleMode, formRef?.id, !!router]);

Expand Down
18 changes: 13 additions & 5 deletions packages/elements/src/react/sign-up/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ type SignUpFlowProviderProps = {
};

const actor = createActor(SignUpRouterMachine, { inspect });
const ref = actor.start();
actor.start();

function SignUpFlowProvider({ children, exampleMode }: SignUpFlowProviderProps) {
const clerk = useClerk();
const router = useClerkRouter();
const formRef = useFormStore();
const isReady = useSelector(ref, state => state.value !== 'Idle');
const isReady = useSelector(actor, state => state.value !== 'Idle');

useEffect(() => {
if (!clerk || !router) return;
Expand All @@ -42,14 +42,22 @@ function SignUpFlowProvider({ children, exampleMode }: SignUpFlowProviderProps)
signInPath: SIGN_IN_DEFAULT_BASE_PATH,
};

if (ref.getSnapshot().can(evt)) {
ref.send(evt);
if (actor.getSnapshot().can(evt)) {
actor.send(evt);
}

// Ensure that the latest instantiated formRef is attached to the router
if (formRef && actor.getSnapshot().can({ type: 'RESET.STEP' })) {
actor.send({
type: 'FORM.ATTACH',
formRef,
});
}
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [clerk, exampleMode, formRef?.id, !!router]);

return isReady ? <SignUpRouterCtx.Provider actorRef={ref}>{children}</SignUpRouterCtx.Provider> : null;
return isReady ? <SignUpRouterCtx.Provider actorRef={actor}>{children}</SignUpRouterCtx.Provider> : null;
}

export type SignUpRootProps = SignUpFlowProviderProps & {
Expand Down

0 comments on commit 65c2faf

Please sign in to comment.