diff --git a/.changeset/forty-kings-roll.md b/.changeset/forty-kings-roll.md new file mode 100644 index 00000000000..6a8a0517efb --- /dev/null +++ b/.changeset/forty-kings-roll.md @@ -0,0 +1,5 @@ +--- +"@clerk/elements": patch +--- + +Refactors sign-up loading logic to be in-line with sign-in diff --git a/packages/elements/src/internals/machines/sign-up/router.machine.ts b/packages/elements/src/internals/machines/sign-up/router.machine.ts index 7fa4ec7ad6b..4bc353e5345 100644 --- a/packages/elements/src/internals/machines/sign-up/router.machine.ts +++ b/packages/elements/src/internals/machines/sign-up/router.machine.ts @@ -284,7 +284,7 @@ export const SignUpRouterMachine = setup({ ], }, Start: { - tags: 'route:start', + tags: ['step:start'], exit: 'clearFormErrors', invoke: { id: 'start', @@ -322,7 +322,7 @@ export const SignUpRouterMachine = setup({ }, }, Continue: { - tags: 'route:continue', + tags: ['step:continue'], invoke: { id: 'continue', src: 'continueMachine', @@ -354,7 +354,7 @@ export const SignUpRouterMachine = setup({ }, }, Verification: { - tags: 'route:verification', + tags: ['step:verification'], invoke: { id: 'verification', src: 'verificationMachine', @@ -406,7 +406,7 @@ export const SignUpRouterMachine = setup({ }, }, Callback: { - tags: 'route:callback', + tags: ['step:callback'], entry: sendTo(ThirdPartyMachineId, { type: 'CALLBACK' }), on: { NEXT: [ @@ -437,7 +437,7 @@ export const SignUpRouterMachine = setup({ }, }, Error: { - tags: 'route:error', + tags: ['step:error'], on: { NEXT: { target: 'Start', diff --git a/packages/elements/src/internals/machines/sign-up/router.types.ts b/packages/elements/src/internals/machines/sign-up/router.types.ts index cd0b69a8bd6..7614f02ee00 100644 --- a/packages/elements/src/internals/machines/sign-up/router.types.ts +++ b/packages/elements/src/internals/machines/sign-up/router.types.ts @@ -20,16 +20,16 @@ import type { // ---------------------------------- Tags ---------------------------------- // -export const SignUpRouterRoutes = { - start: 'route:start', - continue: 'route:continue', - verification: 'route:verification', - callback: 'route:callback', - error: 'route:error', +export const SignUpRouterSteps = { + start: 'step:start', + continue: 'step:continue', + verification: 'step:verification', + callback: 'step:callback', + error: 'step:error', } as const; -export type SignUpRouterRoutes = keyof typeof SignUpRouterRoutes; -export type SignUpRouterTags = (typeof SignUpRouterRoutes)[keyof typeof SignUpRouterRoutes]; +export type SignUpRouterSteps = keyof typeof SignUpRouterSteps; +export type SignUpRouterTags = (typeof SignUpRouterSteps)[keyof typeof SignUpRouterSteps]; // ---------------------------------- Children ---------------------------------- // diff --git a/packages/elements/src/react/common/loading.tsx b/packages/elements/src/react/common/loading.tsx index 7893f271de2..a0a4d55626a 100644 --- a/packages/elements/src/react/common/loading.tsx +++ b/packages/elements/src/react/common/loading.tsx @@ -11,11 +11,8 @@ import { SignInRouterCtx } from '~/react/sign-in/context'; import type { TSignInStep } from '~/react/sign-in/step'; import { SIGN_IN_STEPS } from '~/react/sign-in/step'; import { SignUpRouterCtx } from '~/react/sign-up/context'; -import { SignUpContinueCtx } from '~/react/sign-up/continue'; -import { SignUpStartCtx } from '~/react/sign-up/start'; import type { TSignUpStep } from '~/react/sign-up/step'; import { SIGN_UP_STEPS } from '~/react/sign-up/step'; -import { SignUpVerificationCtx } from '~/react/sign-up/verifications'; import { isProviderStrategyScope, mapScopeToStrategy } from '~/react/utils/map-scope-to-strategy'; type Strategy = OAuthProvider | SamlStrategy | 'metamask'; @@ -175,54 +172,26 @@ type SignUpLoadingProps = { function SignUpLoading({ children, scope, routerRef }: SignUpLoadingProps) { const [isLoading, { step: loadingStep, strategy }] = useLoading(routerRef); + const tags = useSelector(routerRef, s => s.tags); - let computedScope: LoadingScope; - - // Figure out if the component is inside a `` component - const startCtx = SignUpStartCtx.useActorRef(true); - const continueCtx = SignUpContinueCtx.useActorRef(true); - const verificationsCtx = SignUpVerificationCtx.useActorRef(true); + const isStepLoading = (step: TSignUpStep) => isLoading && loadingStep === step; + const isInferredStepLoading = (step: TSignUpStep) => tags.has(`step:${step}`) && isStepLoading(step); - if (scope) { - computedScope = scope; - } else { - let inferredScope: LoadingScope; - - if (startCtx) { - inferredScope = `step:start`; - } else if (continueCtx) { - inferredScope = `step:continue`; - } else if (verificationsCtx) { - inferredScope = `step:verifications`; - } else { - inferredScope = `global`; - } - - computedScope = inferredScope; - } + let loadingResult = false; - // Determine loading states based on the step - const isStartLoading = isLoading && loadingStep === 'start'; - const isVerificationsLoading = isLoading && loadingStep === 'verifications'; - const isContinueLoading = isLoading && loadingStep === 'continue'; - const isStrategyLoading = isLoading && loadingStep === undefined && strategy !== undefined; - - let returnValue: boolean; - - if (computedScope === 'global') { - returnValue = isLoading; - } else if (computedScope === 'step:start') { - returnValue = isStartLoading; - } else if (computedScope === 'step:verifications') { - returnValue = isVerificationsLoading; - } else if (computedScope === 'step:continue') { - returnValue = isContinueLoading; - } else if (computedScope.startsWith('provider:')) { - const computedStrategy = mapScopeToStrategy(computedScope); - returnValue = isStrategyLoading && strategy === computedStrategy; + if (scope === 'global') { + // Global Loading Scope + loadingResult = isLoading; + } else if (scope && isProviderStrategyScope(scope)) { + // Provider-Specific Loading Scope + loadingResult = isLoading && loadingStep === undefined && strategy === mapScopeToStrategy(scope); + } else if (scope) { + loadingResult = isStepLoading(scope.replace('step:', '') as TSignUpStep); } else { - throw new ClerkElementsRuntimeError(`Invalid scope "${computedScope}" used for `); + // Inferred Loading Scope + loadingResult = + isInferredStepLoading('start') || isInferredStepLoading('continue') || isInferredStepLoading('verifications'); } - return children(returnValue); + return children(loadingResult); } diff --git a/packages/elements/src/react/sign-up/continue.tsx b/packages/elements/src/react/sign-up/continue.tsx index b1d101dc1d5..2fa3b1dc854 100644 --- a/packages/elements/src/react/sign-up/continue.tsx +++ b/packages/elements/src/react/sign-up/continue.tsx @@ -11,7 +11,7 @@ export const SignUpContinueCtx = createContextFromActorRef : null; } diff --git a/packages/elements/src/react/sign-up/start.tsx b/packages/elements/src/react/sign-up/start.tsx index dfbbe47e266..eb6525f575c 100644 --- a/packages/elements/src/react/sign-up/start.tsx +++ b/packages/elements/src/react/sign-up/start.tsx @@ -11,7 +11,7 @@ export const SignUpStartCtx = createContextFromActorRef('Si export function SignUpStart(props: SignUpStartProps) { const routerRef = SignUpRouterCtx.useActorRef(); - const activeState = useActiveTags(routerRef, 'route:start'); + const activeState = useActiveTags(routerRef, 'step:start'); return activeState ? : null; } diff --git a/packages/elements/src/react/sign-up/verifications.tsx b/packages/elements/src/react/sign-up/verifications.tsx index cbfbe912934..0fbcbc1e06d 100644 --- a/packages/elements/src/react/sign-up/verifications.tsx +++ b/packages/elements/src/react/sign-up/verifications.tsx @@ -31,7 +31,7 @@ export const SignUpVerificationCtx = createContextFromActorRef : null; }