-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(elements): Loading states #2669
feat(elements): Loading states #2669
Conversation
|
|
||
<CustomSubmit>Sign In</CustomSubmit> | ||
<CustomSubmit> | ||
<SignInLoading fallback={<>Submitting...</>}>Sign In</SignInLoading> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example usage for rendering based on the global loading state. For further focusing we could do something like:
<SignInLoading context="oauth_github">
Ideally we can make this a non-flow-specific component, though it's hard if we rely on state node tags.
@@ -323,7 +340,7 @@ export const SignInMachine = setup({ | |||
always: [ | |||
{ | |||
description: 'If the current factor is not password, prepare the factor', | |||
guard: not('isCurrentFactorPassword'), | |||
guard: and([not('isCurrentFactorPassword'), { type: 'isCurrentPath', params: { path: '/continue' } }]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensures prepare only fires once we're on the right path
@@ -101,7 +100,7 @@ const OTPInputSegmented = forwardRef<HTMLInputElement, Required<Pick<OTPInputPro | |||
}} | |||
> | |||
{Array.from({ length: maxLength }).map((_, i) => ( | |||
<Slot key={i}> | |||
<Fragment key={`${String(props.value)[i]}-i`}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes key error
return state.matches('AuthenticatingWithRedirect') || | ||
state.matches('Start') || | ||
(router?.match(undefined, true) && state.matches('Init')) ? ( | ||
<Form flowActor={actorRef}>{children}</Form> | ||
) : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allows the view to continue to render so we can render a loading/pending state. Also tweak the conditions here to ensure the initial start view can get SSR'd.
setLoadingContext: assign(({ event }) => { | ||
if (event.type === 'SET_LOADING_CONTEXT') { | ||
return { | ||
loadingContext: event.name, | ||
}; | ||
} | ||
return {}; | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's likely a more elegant way we can store an identifier for whatever action / element triggered the loading state, this was my first stab at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels best handled when AUTHENTICATE.OAUTH
/AUTHENTICATE.[...]
are called, rather than their own events, unless I'm missing something.
packages/elements/src/internals/machines/sign-in/sign-in.machine.ts
Outdated
Show resolved
Hide resolved
@@ -40,22 +40,24 @@ const useFieldContext = () => useContext(FieldContext); | |||
*/ | |||
const useForm = ({ flowActor }: { flowActor?: BaseActorRef<{ type: 'SUBMIT' }> }) => { | |||
const error = useFormSelector(globalErrorsSelector); | |||
const [isPending, startTransition] = useTransition(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing using React's native transitions. Not sure if it provides value beyond the loading state tracking within the state machine.
@@ -2,10 +2,11 @@ | |||
|
|||
import { GlobalError, Submit } from '@clerk/elements'; | |||
import { | |||
SignIn, | |||
Root as SignIn, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align exports with our current docs
Closing in favor of #2751 for now. That PR is only a temporary thing, we'll revisit the proper implementation later. |
Description
Introduce support for loading states. Specific state nodes are tagged with
loading
, and aloadingContext
context value has been introduced to provide more granular hints for what action triggered the loading state. This allows rendering a spinner within a social provider button on click, for example.Checklist
npm test
runs as expected.npm run build
runs as expected.Type of change
Packages affected
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/clerk-expo
@clerk/fastify
gatsby-plugin-clerk
@clerk/localizations
@clerk/nextjs
@clerk/clerk-react
@clerk/remix
@clerk/clerk-sdk-node
@clerk/shared
@clerk/themes
@clerk/types
build/tooling/chore