Skip to content

Commit

Permalink
Fix progressive sign up ticket flow
Browse files Browse the repository at this point in the history
  • Loading branch information
brkalow committed Oct 11, 2024
1 parent 6ef3ec6 commit 4766abc
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export const FormMachine = setup({

if (field) {
field.checked = event.field.checked;
field.disabled = event.field.disabled || false;
field.disabled = event.field.disabled ?? field.disabled;
field.value = event.field.value;

context.fields.set(event.field.name, field);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
SignUpContinueContext,
SignUpContinueEvents,
SignUpStartContext,
SignUpStartRedirectEvent,
SignUpStartEvents,
SignUpVerificationContext,
SignUpVerificationEvents,
} from '~/internals/machines/sign-up';
Expand All @@ -33,7 +33,7 @@ type SendToLoadingProps = {
| SignInVerificationEvents
| SignInResetPasswordEvents
| ThirdPartyMachineEvent
| SignUpStartRedirectEvent
| SignUpStartEvents
| SignUpContinueEvents
| SignUpVerificationEvents;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import type {
SignInStrategy,
} from '@clerk/types';
import type { SetRequired, Simplify } from 'type-fest';
import type { ActorRefFrom } from 'xstate';

import type { FormMachine } from '../form';

export type WithClerk<T = Record<string, unknown>> = { clerk: LoadedClerk } & T;
export type WithClient<T = Record<string, unknown>> = { client: LoadedClerk['client'] } & T;
Expand Down Expand Up @@ -33,3 +36,5 @@ export type AuthenticateWithRedirectSamlParams = Simplify<
// ================= Strategies ================= //

export type SignInStrategyName = SignInStrategy | 'oauth' | 'web3';

export type SetFormEvent = { type: 'SET_FORM'; formRef: ActorRefFrom<typeof FormMachine> };
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ClerkElementsError, ClerkElementsRuntimeError } from '~/internals/error
import { ThirdPartyMachine, ThirdPartyMachineId } from '~/internals/machines/third-party';
import { shouldUseVirtualRouting } from '~/internals/machines/utils/next';

import { SignInStartMachineId } from '../sign-in';
import { SignUpContinueMachine } from './continue.machine';
import type {
SignUpRouterContext,
Expand Down Expand Up @@ -329,7 +330,7 @@ export const SignUpRouterMachine = setup({
tags: ['step:start'],
exit: 'clearFormErrors',
invoke: {
id: 'start',
id: SignInStartMachineId,
src: 'startMachine',
input: ({ context, self }) => ({
basePath: context.router?.basePath,
Expand All @@ -343,8 +344,10 @@ export const SignUpRouterMachine = setup({
},
on: {
'RESET.STEP': {
target: 'Start',
reenter: true,
actions: enqueueActions(({ enqueue, context }) => {
enqueue('clearFormErrors');
enqueue.sendTo(SignInStartMachineId, { type: 'SET_FORM', formRef: context.formRef });
}),
},
NEXT: [
{
Expand All @@ -355,6 +358,7 @@ export const SignUpRouterMachine = setup({
guard: and(['hasTicket', 'statusNeedsContinue']),
actions: { type: 'navigateInternal', params: { path: '/' } },
target: 'Start',
reenter: true,
},
{
guard: 'statusNeedsVerification',
Expand Down
23 changes: 21 additions & 2 deletions packages/elements/src/internals/machines/sign-up/start.machine.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { SignUpResource, Web3Strategy } from '@clerk/types';
import { assertEvent, enqueueActions, fromPromise, not, sendTo, setup } from 'xstate';
import type { DoneActorEvent } from 'xstate';
import { and, assertEvent, assign, enqueueActions, fromPromise, not, sendTo, setup } from 'xstate';

import { SIGN_UP_DEFAULT_BASE_PATH } from '~/internals/constants';
import { ClerkElementsRuntimeError } from '~/internals/errors';
import type { FormFields } from '~/internals/machines/form';
import type { SetFormEvent } from '~/internals/machines/shared';
import { sendToLoading } from '~/internals/machines/shared';
import { fieldsToSignUpParams } from '~/internals/machines/sign-up/utils';
import { ThirdPartyMachine } from '~/internals/machines/third-party';
Expand Down Expand Up @@ -48,8 +50,14 @@ export const SignUpStartMachine = setup({
thirdParty: ThirdPartyMachine,
},
actions: {
sendToNext: ({ context }) => context.parent.send({ type: 'NEXT' }),
sendToNext: ({ context, event }) =>
context.parent.send({ type: 'NEXT', resource: (event as unknown as DoneActorEvent<SignUpResource>).output }),
sendToLoading,
setFormRef: assign(({ event }) => {
return {
formRef: (event as unknown as SetFormEvent).formRef,
};
}),
setFormDisabledTicketFields: enqueueActions(({ context, enqueue }) => {
if (!context.ticket) {
return;
Expand Down Expand Up @@ -90,6 +98,8 @@ export const SignUpStartMachine = setup({
},
},
guards: {
isMissingRequirements: ({ context }) =>
context.parent.getSnapshot().context.clerk?.client?.signUp?.status === 'missing_requirements',
hasTicket: ({ context }) => Boolean(context.ticket),
isExampleMode: ({ context }) => Boolean(context.parent.getSnapshot().context.exampleMode),
},
Expand All @@ -105,11 +115,20 @@ export const SignUpStartMachine = setup({
}),
entry: 'setDefaultFormValues',
initial: 'Init',
on: {
SET_FORM: {
actions: 'setFormRef',
},
},
states: {
Init: {
description:
'Handle ticket, if present; Else, default to Pending state. Per tickets, `Attempting` makes a `signUp.create` request allowing for an incomplete sign up to contain progressively filled fields on the Start step.',
always: [
{
guard: and(['hasTicket', 'isMissingRequirements']),
target: 'Pending',
},
{
guard: 'hasTicket',
target: 'Attempting',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { ActorRefFrom, ErrorActorEvent } from 'xstate';

import type { FormMachine } from '~/internals/machines/form';

import type { SetFormEvent } from '../shared';
import type { SignInRouterMachineActorRef } from './router.types';

// ---------------------------------- Tags ---------------------------------- //
Expand All @@ -24,7 +25,7 @@ export type SignUpStartRedirectEvent =
| SignUpStartRedirectSamlEvent
| SignUpStartRedirectWeb3Event;

export type SignUpStartEvents = ErrorActorEvent | SignUpStartSubmitEvent | SignUpStartRedirectEvent;
export type SignUpStartEvents = ErrorActorEvent | SignUpStartSubmitEvent | SignUpStartRedirectEvent | SetFormEvent;

// ---------------------------------- Input ---------------------------------- //

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { ActorRefFrom, AnyActorRef, AnyStateMachine, SnapshotFrom } from 'xstate';

import { SignInStartMachineId } from '~/internals/machines/sign-in';
import type {
TSignUpContinueMachine,
TSignUpRouterMachine,
Expand All @@ -16,6 +17,6 @@ function useSignUpStep<M extends AnyStateMachine, T = ActorRefFrom<M>>(name: str
return SignUpRouterCtx.useSelector(state => state.children[name] as AnyActorRef) as T;
}

export const useSignUpStartStep = () => useSignUpStep<TSignUpStartMachine>('start');
export const useSignUpStartStep = () => useSignUpStep<TSignUpStartMachine>(SignInStartMachineId);
export const useSignUpContinueStep = () => useSignUpStep<TSignUpContinueMachine>('continue');
export const useSignUpVerificationStep = () => useSignUpStep<TSignUpVerificationMachine>('verification');

0 comments on commit 4766abc

Please sign in to comment.