Skip to content

Commit 65c2faf

Browse files
authored
Merge branch 'main' into elef/sdk-1772-2fa-phone-selection-screen-should-re-show-on-cancel
2 parents c83133a + be88436 commit 65c2faf

File tree

9 files changed

+113
-5
lines changed

9 files changed

+113
-5
lines changed

.changeset/itchy-mirrors-decide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/elements': patch
3+
---
4+
5+
Fix forms unable to submit upon re-mounting

packages/elements/examples/nextjs/app/sign-up/[[...sign-up]]/page.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

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

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

46+
<p className='text-base text-zinc-400'>
47+
Have an account?{' '}
48+
<Link
49+
href='/sign-in'
50+
className='no-underline hover:underline'
51+
>
52+
Sign In
53+
</Link>
54+
</p>
55+
4556
<div className='flex flex-col items-stretch justify-center gap-2'>
4657
<Clerk.Connection
4758
name='github'
@@ -105,6 +116,16 @@ export default function SignUpPage() {
105116
<div className='flex flex-col items-center justify-center gap-12'>
106117
<H1>Sign Up</H1>
107118

119+
<p className='text-base text-zinc-400'>
120+
Have an account?{' '}
121+
<Link
122+
href='/sign-in'
123+
className='no-underline hover:underline'
124+
>
125+
Sign In
126+
</Link>
127+
</p>
128+
108129
<div className='flex flex-col items-stretch justify-center gap-2'>
109130
<Clerk.Connection
110131
name='github'

packages/elements/src/internals/machines/sign-in/router.machine.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ export const SignInRouterMachine = setup({
182182
params: { strategy: 'saml' },
183183
}),
184184
},
185+
'FORM.ATTACH': {
186+
description: 'Attach/re-attach the form to the router.',
187+
actions: enqueueActions(({ enqueue, event }) => {
188+
enqueue.assign({
189+
formRef: event.formRef,
190+
});
191+
192+
// Reset the current step, to reset the form reference.
193+
enqueue.raise({ type: 'RESET.STEP' });
194+
}),
195+
},
185196
'NAVIGATE.PREVIOUS': '.Hist',
186197
'NAVIGATE.START': '.Start',
187198
LOADING: {
@@ -292,6 +303,10 @@ export const SignInRouterMachine = setup({
292303
},
293304
},
294305
on: {
306+
'RESET.STEP': {
307+
target: 'Start',
308+
reenter: true,
309+
},
295310
NEXT: [
296311
{
297312
guard: 'isComplete',
@@ -329,6 +344,10 @@ export const SignInRouterMachine = setup({
329344
},
330345
},
331346
on: {
347+
'RESET.STEP': {
348+
target: 'FirstFactor',
349+
reenter: true,
350+
},
332351
NEXT: [
333352
{
334353
guard: 'isComplete',
@@ -399,6 +418,10 @@ export const SignInRouterMachine = setup({
399418
},
400419
},
401420
on: {
421+
'RESET.STEP': {
422+
target: 'SecondFactor',
423+
reenter: true,
424+
},
402425
NEXT: [
403426
{
404427
guard: 'isComplete',
@@ -426,6 +449,10 @@ export const SignInRouterMachine = setup({
426449
},
427450
},
428451
on: {
452+
'RESET.STEP': {
453+
target: 'ResetPassword',
454+
reenter: true,
455+
},
429456
NEXT: [
430457
{
431458
guard: 'isComplete',

packages/elements/src/internals/machines/sign-in/router.types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import type { TFormMachine } from '~/internals/machines/form';
55
import type {
66
BaseRouterContext,
77
BaseRouterErrorEvent,
8+
BaseRouterFormAttachEvent,
89
BaseRouterInput,
910
BaseRouterLoadingEvent,
1011
BaseRouterNextEvent,
1112
BaseRouterPrevEvent,
1213
BaseRouterRedirectEvent,
1314
BaseRouterResetEvent,
15+
BaseRouterResetStepEvent,
1416
BaseRouterSetClerkEvent,
1517
BaseRouterStartEvent,
1618
BaseRouterTransferEvent,
@@ -47,6 +49,7 @@ export type SignInRouterSystemId = keyof typeof SignInRouterSystemId;
4749

4850
// ---------------------------------- Events ---------------------------------- //
4951

52+
export type SignInRouterFormAttachEvent = BaseRouterFormAttachEvent;
5053
export type SignInRouterNextEvent = BaseRouterNextEvent<SignInResource>;
5154
export type SignInRouterStartEvent = BaseRouterStartEvent;
5255
export type SignInRouterPrevEvent = BaseRouterPrevEvent;
@@ -56,6 +59,7 @@ export type SignInRouterErrorEvent = BaseRouterErrorEvent;
5659
export type SignInRouterTransferEvent = BaseRouterTransferEvent;
5760
export type SignInRouterRedirectEvent = BaseRouterRedirectEvent;
5861
export type SignInRouterResetEvent = BaseRouterResetEvent;
62+
export type SignInRouterResetStepEvent = BaseRouterResetStepEvent;
5963
export type SignInRouterLoadingEvent = BaseRouterLoadingEvent<'start' | 'verifications' | 'reset-password'>;
6064
export type SignInRouterSetClerkEvent = BaseRouterSetClerkEvent;
6165
export type SignInRouterSubmitEvent = { type: 'SUBMIT' };
@@ -73,13 +77,15 @@ export type SignInRouterNavigationEvents =
7377
| SignInRouterPrevEvent;
7478

7579
export type SignInRouterEvents =
80+
| SignInRouterFormAttachEvent
7681
| SignInRouterInitEvent
7782
| SignInRouterNextEvent
7883
| SignInRouterNavigationEvents
7984
| SignInRouterErrorEvent
8085
| SignInRouterTransferEvent
8186
| SignInRouterRedirectEvent
8287
| SignInRouterResetEvent
88+
| SignInRouterResetStepEvent
8389
| SignInVerificationFactorUpdateEvent
8490
| SignInRouterLoadingEvent
8591
| SignInRouterSetClerkEvent

packages/elements/src/internals/machines/sign-up/router.machine.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,17 @@ export const SignUpRouterMachine = setup({
181181
params: { strategy: 'saml' },
182182
}),
183183
},
184+
'FORM.ATTACH': {
185+
description: 'Attach/re-attach the form to the router.',
186+
actions: enqueueActions(({ enqueue, event }) => {
187+
enqueue.assign({
188+
formRef: event.formRef,
189+
});
190+
191+
// Reset the current step, to reset the form reference.
192+
enqueue.raise({ type: 'RESET.STEP' });
193+
}),
194+
},
184195
'NAVIGATE.PREVIOUS': '.Hist',
185196
'NAVIGATE.START': '.Start',
186197
LOADING: {
@@ -274,6 +285,10 @@ export const SignUpRouterMachine = setup({
274285
},
275286
},
276287
on: {
288+
'RESET.STEP': {
289+
target: 'Start',
290+
reenter: true,
291+
},
277292
NEXT: [
278293
{
279294
guard: 'isStatusComplete',
@@ -307,6 +322,10 @@ export const SignUpRouterMachine = setup({
307322
},
308323
},
309324
on: {
325+
'RESET.STEP': {
326+
target: 'Continue',
327+
reenter: true,
328+
},
310329
NEXT: [
311330
{
312331
guard: 'isStatusComplete',
@@ -355,6 +374,10 @@ export const SignUpRouterMachine = setup({
355374
},
356375
],
357376
on: {
377+
'RESET.STEP': {
378+
target: 'Verification',
379+
reenter: true,
380+
},
358381
NEXT: [
359382
{
360383
guard: 'isStatusComplete',

packages/elements/src/internals/machines/sign-up/router.types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import type { TFormMachine } from '~/internals/machines/form';
55
import type {
66
BaseRouterContext,
77
BaseRouterErrorEvent,
8+
BaseRouterFormAttachEvent,
89
BaseRouterInput,
910
BaseRouterLoadingEvent,
1011
BaseRouterNextEvent,
1112
BaseRouterPrevEvent,
1213
BaseRouterRedirectEvent,
1314
BaseRouterResetEvent,
15+
BaseRouterResetStepEvent,
1416
BaseRouterSetClerkEvent,
1517
BaseRouterStartEvent,
1618
BaseRouterTransferEvent,
@@ -41,13 +43,15 @@ export type SignUpRouterSystemId = keyof typeof SignUpRouterSystemId;
4143

4244
// ---------------------------------- Events ---------------------------------- //
4345

46+
export type SignUpRouterFormAttachEvent = BaseRouterFormAttachEvent;
4447
export type SignUpRouterNextEvent = BaseRouterNextEvent<SignUpResource>;
4548
export type SignUpRouterStartEvent = BaseRouterStartEvent;
4649
export type SignUpRouterPrevEvent = BaseRouterPrevEvent;
4750
export type SignUpRouterErrorEvent = BaseRouterErrorEvent;
4851
export type SignUpRouterTransferEvent = BaseRouterTransferEvent;
4952
export type SignUpRouterRedirectEvent = BaseRouterRedirectEvent;
5053
export type SignUpRouterResetEvent = BaseRouterResetEvent;
54+
export type SignUpRouterResetStepEvent = BaseRouterResetStepEvent;
5155
export type SignUpRouterLoadingEvent = BaseRouterLoadingEvent<'start' | 'verifications' | 'continue'>;
5256
export type SignUpRouterSetClerkEvent = BaseRouterSetClerkEvent;
5357

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

6266
export type SignUpRouterEvents =
67+
| SignUpRouterFormAttachEvent
6368
| SignUpRouterInitEvent
6469
| SignUpRouterNextEvent
6570
| SignUpRouterNavigationEvents
6671
| SignUpRouterErrorEvent
6772
| SignUpRouterTransferEvent
6873
| SignUpRouterRedirectEvent
6974
| SignUpRouterResetEvent
75+
| SignUpRouterResetStepEvent
7076
| SignUpRouterLoadingEvent
7177
| SignUpRouterSetClerkEvent;
7278

packages/elements/src/internals/machines/types/router.types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ import type {
66
SignInStrategy,
77
Web3Strategy,
88
} from '@clerk/types';
9+
import type { ActorRefFrom } from 'xstate';
910

1011
import type { ClerkElementsError } from '~/internals/errors';
12+
import type { TFormMachine } from '~/internals/machines/form';
1113
import type { ClerkRouter } from '~/react/router';
1214

1315
// ---------------------------------- Events ---------------------------------- //
1416

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

1719
export type BaseRouterNextEvent<T extends ClerkResource> = { type: 'NEXT'; resource?: T };
20+
export type BaseRouterFormAttachEvent = { type: 'FORM.ATTACH'; formRef: ActorRefFrom<TFormMachine> };
1821
export type BaseRouterPrevEvent = { type: 'NAVIGATE.PREVIOUS' };
1922
export type BaseRouterStartEvent = { type: 'NAVIGATE.START' };
2023
export type BaseRouterResetEvent = { type: 'RESET' };
24+
export type BaseRouterResetStepEvent = { type: 'RESET.STEP' };
2125
export type BaseRouterErrorEvent = { type: 'ERROR'; error: Error };
2226
export type BaseRouterTransferEvent = { type: 'TRANSFER' };
2327
export type BaseRouterLoadingEvent<TSteps extends BaseRouterLoadingStep> = (

packages/elements/src/react/sign-in/root.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ function SignInFlowProvider({ children, exampleMode }: SignInFlowProviderProps)
4545
}
4646
});
4747

48+
// Ensure that the latest instantiated formRef is attached to the router
49+
if (formRef && actor.getSnapshot().can({ type: 'RESET.STEP' })) {
50+
actor.send({
51+
type: 'FORM.ATTACH',
52+
formRef,
53+
});
54+
}
55+
4856
// eslint-disable-next-line react-hooks/exhaustive-deps
4957
}, [clerk, exampleMode, formRef?.id, !!router]);
5058

packages/elements/src/react/sign-up/root.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ type SignUpFlowProviderProps = {
2020
};
2121

2222
const actor = createActor(SignUpRouterMachine, { inspect });
23-
const ref = actor.start();
23+
actor.start();
2424

2525
function SignUpFlowProvider({ children, exampleMode }: SignUpFlowProviderProps) {
2626
const clerk = useClerk();
2727
const router = useClerkRouter();
2828
const formRef = useFormStore();
29-
const isReady = useSelector(ref, state => state.value !== 'Idle');
29+
const isReady = useSelector(actor, state => state.value !== 'Idle');
3030

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

45-
if (ref.getSnapshot().can(evt)) {
46-
ref.send(evt);
45+
if (actor.getSnapshot().can(evt)) {
46+
actor.send(evt);
47+
}
48+
49+
// Ensure that the latest instantiated formRef is attached to the router
50+
if (formRef && actor.getSnapshot().can({ type: 'RESET.STEP' })) {
51+
actor.send({
52+
type: 'FORM.ATTACH',
53+
formRef,
54+
});
4755
}
4856
});
4957
// eslint-disable-next-line react-hooks/exhaustive-deps
5058
}, [clerk, exampleMode, formRef?.id, !!router]);
5159

52-
return isReady ? <SignUpRouterCtx.Provider actorRef={ref}>{children}</SignUpRouterCtx.Provider> : null;
60+
return isReady ? <SignUpRouterCtx.Provider actorRef={actor}>{children}</SignUpRouterCtx.Provider> : null;
5361
}
5462

5563
export type SignUpRootProps = SignUpFlowProviderProps & {

0 commit comments

Comments
 (0)