Skip to content
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

Closed

Conversation

BRKalow
Copy link
Member

@BRKalow BRKalow commented Jan 26, 2024

Description

Introduce support for loading states. Specific state nodes are tagged with loading, and a loadingContext 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.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

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

Copy link

changeset-bot bot commented Jan 26, 2024

⚠️ No Changeset found

Latest commit: 2028534

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR


<CustomSubmit>Sign In</CustomSubmit>
<CustomSubmit>
<SignInLoading fallback={<>Submitting...</>}>Sign In</SignInLoading>
Copy link
Member Author

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' } }]),
Copy link
Member Author

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`}>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes key error

Comment on lines +88 to +92
return state.matches('AuthenticatingWithRedirect') ||
state.matches('Start') ||
(router?.match(undefined, true) && state.matches('Init')) ? (
<Form flowActor={actorRef}>{children}</Form>
) : null;
Copy link
Member Author

@BRKalow BRKalow Jan 26, 2024

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.

Comment on lines +145 to +152
setLoadingContext: assign(({ event }) => {
if (event.type === 'SET_LOADING_CONTEXT') {
return {
loadingContext: event.name,
};
}
return {};
}),
Copy link
Member Author

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.

Copy link
Member

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.

@@ -40,22 +40,24 @@ const useFieldContext = () => useContext(FieldContext);
*/
const useForm = ({ flowActor }: { flowActor?: BaseActorRef<{ type: 'SUBMIT' }> }) => {
const error = useFormSelector(globalErrorsSelector);
const [isPending, startTransition] = useTransition();
Copy link
Member Author

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,
Copy link
Member Author

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

@LekoArts
Copy link
Member

LekoArts commented Feb 7, 2024

Closing in favor of #2751 for now. That PR is only a temporary thing, we'll revisit the proper implementation later.

@LekoArts LekoArts closed this Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants