Skip to content

Commit

Permalink
feat(elements): Add temporary useIsLoading hook (#2751)
Browse files Browse the repository at this point in the history
* feat(elements): Add loading tags

* feat(elements): Add unstable useIsLoading hook

* chore(elements): Use new hook in example sign-in

* chore(elements): Bump package version

* chore(repo): Add empty changeset

* chore(elements): Revert some stuff to main

* chore(elements): Adjust logger to be more concise

* fix(elements): Adjust loader and hook

* chore(elements): Adjust example page

* chore(elements): Revert unnecessary change

* fix(elements): Review comments

Co-authored-by: Tom Milewski <[email protected]>

---------

Co-authored-by: Tom Milewski <[email protected]>
  • Loading branch information
LekoArts and tmilewski authored Feb 14, 2024
1 parent 893c149 commit dc3dcc6
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 43 deletions.
2 changes: 2 additions & 0 deletions .changeset/hip-monkeys-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { SignIn, SocialProvider, SocialProviderIcon, Start, Verification, Verify

import { H1, H3, HR as Hr, P } from '@/components/design';
import { CustomField, CustomSubmit } from '@/components/form';
import { Loading } from '@/components/loader';

export default function SignInPage() {
return (
Expand Down Expand Up @@ -45,10 +46,12 @@ export default function SignInPage() {
<Hr />

<div className='flex gap-6 flex-col'>
<CustomField
label='Email'
name='identifier'
/>
<Loading>
<CustomField
label='Email'
name='identifier'
/>
</Loading>

{/* <Hr />
Expand All @@ -68,44 +71,46 @@ export default function SignInPage() {

<GlobalError className='block text-red-400 font-mono' />

<Verification name='password'>
<CustomField
label='Password'
name='password'
/>

<CustomSubmit>Sign In</CustomSubmit>
</Verification>

<Verification name='email_code'>
<CustomField
label='Email Code'
name='code'
/>

<CustomSubmit>Sign In</CustomSubmit>
</Verification>

<Verification name='phone_code'>
<CustomField
label='Phone Code'
name='code'
/>

<Submit className='px-4 py-2 b-1 bg-blue-950 bg-opacity-20 hover:bg-opacity-10 active:bg-opacity-5 rounded-md dark:bg-opacity-100 dark:hover:bg-opacity-80 dark:active:bg-opacity-50 transition'>
Sign In
</Submit>
</Verification>

<Verification name='reset_password_email_code'>
<H3>Verify your email</H3>

<P>Please check your email for a verification code...</P>

<Submit className='px-4 py-2 b-1 bg-blue-950 bg-opacity-20 hover:bg-opacity-10 active:bg-opacity-5 rounded-md dark:bg-opacity-100 dark:hover:bg-opacity-80 dark:active:bg-opacity-50 transition'>
Verify
</Submit>
</Verification>
<Loading>
<Verification name='password'>
<CustomField
label='Password'
name='password'
/>

<CustomSubmit>Sign In</CustomSubmit>
</Verification>

<Verification name='email_code'>
<CustomField
label='Email Code'
name='code'
/>

<CustomSubmit>Sign In</CustomSubmit>
</Verification>

<Verification name='phone_code'>
<CustomField
label='Phone Code'
name='code'
/>

<Submit className='px-4 py-2 b-1 bg-blue-950 bg-opacity-20 hover:bg-opacity-10 active:bg-opacity-5 rounded-md dark:bg-opacity-100 dark:hover:bg-opacity-80 dark:active:bg-opacity-50 transition'>
Sign In
</Submit>
</Verification>

<Verification name='reset_password_email_code'>
<H3>Verify your email</H3>

<P>Please check your email for a verification code...</P>

<Submit className='px-4 py-2 b-1 bg-blue-950 bg-opacity-20 hover:bg-opacity-10 active:bg-opacity-5 rounded-md dark:bg-opacity-100 dark:hover:bg-opacity-80 dark:active:bg-opacity-50 transition'>
Verify
</Submit>
</Verification>
</Loading>
</div>
</Verify>
</div>
Expand Down
64 changes: 64 additions & 0 deletions packages/elements/examples/nextjs/components/loader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use client';
import { useIsLoading_unstable } from '@clerk/elements/sign-in';
import { motion } from 'framer-motion';

const colors = ['#22238f', '#6b45fa', '#ca3286', '#fe2b49', '#fe652d'];

const containerVariants = {
initial: {},
animate: {
transition: {
when: 'beforeChildren',
staggerChildren: 0.1,
},
},
};

const dotVariants = {
initial: {},
animate: {
height: [20, 40, 20],
transition: {
repeat: Infinity,
},
},
};

const Loader = ({ count = 5 }) => {
return (
<motion.div
variants={containerVariants}
initial='initial'
animate='animate'
style={{
display: 'flex',
gap: 10,
height: 40,
alignItems: 'center',
}}
>
{Array(count)
.fill(null)
.map((_, index) => {
return (
<motion.div
key={index}
variants={dotVariants}
style={{
height: 20,
width: 20,
backgroundColor: colors[index % colors.length],
borderRadius: 20,
}}
/>
);
})}
</motion.div>
);
};

export function Loading({ children }: { children: React.ReactNode }) {
const [isLoading] = useIsLoading_unstable();

return isLoading ? <Loader /> : children;
}
33 changes: 33 additions & 0 deletions packages/elements/src/react/sign-in/hooks/use-loading.hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { useActiveTags } from '~/react/hooks/use-active-tags.hook';
import { SignInStartCtx } from '~/react/sign-in/start';
import { SignInFirstFactorCtx, SignInSecondFactorCtx } from '~/react/sign-in/verifications';

/**
* Caution: This hook is unstable and may disappear in the future.
* This is a temporary hook until the actual loading API is explored and implemented.
*/
export const useIsLoading_unstable = () => {
let startLoading = false;
let firstFactorLoading = false;
let secondFactorLoading = false;

const startRef = SignInStartCtx.useActorRef(true);
if (startRef) {
startLoading = useActiveTags(startRef, 'state:loading');
}

const firstFactorRef = SignInFirstFactorCtx.useActorRef(true);
if (firstFactorRef) {
firstFactorLoading = useActiveTags(firstFactorRef, 'state:loading');
}

const secondFactorRef = SignInSecondFactorCtx.useActorRef(true);
if (secondFactorRef) {
secondFactorLoading = useActiveTags(secondFactorRef, 'state:loading');
}

const isGlobalLoading = startLoading || firstFactorLoading || secondFactorLoading;

return [isGlobalLoading, { start: startLoading, firstFactor: firstFactorLoading, secondFactor: secondFactorLoading }];
};
2 changes: 2 additions & 0 deletions packages/elements/src/react/sign-in/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export {
SignInVerify as Verify,
} from './verifications';

export { useIsLoading_unstable } from './hooks/use-loading.hook';

/** @internal Internal use only */
export const useSignInActorRef_internal = SignInRouterCtx.useActorRef;

Expand Down
2 changes: 1 addition & 1 deletion packages/elements/src/react/utils/xstate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export function createConsoleInspector(): Observer<InspectionEvent> {
}
}

const defaults = 'font-weight: bold; line-height: 2; border-radius: 8px; padding: 6px 10px;';
const defaults = 'font-weight: bold; line-height: 1.5; border-radius: 8px; padding: 4px 10px;';
const reset = 'color: inherit;';

const Styles = {
Expand Down

0 comments on commit dc3dcc6

Please sign in to comment.