Skip to content

Commit

Permalink
feat(elements): <Loading> component (#3002)
Browse files Browse the repository at this point in the history
* chore(repo): Update lock file

* fix(elements): WIP

* chore(elements): WIP

* chore(elements): WIP

* feat(elements): First sendParent

* chore(elements): Add debug script to example

* feat(elements): Get logic working

* chore(elements): WIP

* fix(elements): Remove unstable isLoading hook

* fix(elements): Types

* feat(elements): Make Loading component work

* chore(elements): Stuff

* feat(elements): More stuff

* chore(elements): Revert formatting change

* chore(elements): Add loading component to sign-up page

* chore(elements): Export step types

* feat(elements): Add Loading component for sign-up

* feat(elements): Add shared sendToLoading action

* chore(elements): Add sendToLoading test

* fix(elements): Remove unintended change

* chore(elements): Add JSDoc comments

* chore(elements): Bump version

* chore(repo): Update lock file

* chore(elements): Bump version

* feat(elements): Change isLoading function prop to be boolean, not object

* chore(elements): Use Spinner in example

* chore(elements): Bump version

* fix(elements): Create scopeStrategy helper

* feat(elements): Infer scope inside step

* fix(elements): Add displayName

* chore(elements): Bump version
  • Loading branch information
LekoArts authored Mar 20, 2024
1 parent f60829c commit d54e42d
Show file tree
Hide file tree
Showing 39 changed files with 909 additions and 210 deletions.
2 changes: 2 additions & 0 deletions .changeset/violet-windows-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
190 changes: 124 additions & 66 deletions packages/elements/examples/nextjs/app/sign-in/[[...sign-in]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { Field, FieldError, GlobalError, Input, Label } from '@clerk/elements/common';
import {
Action,
Loading,
Provider,
ProviderIcon,
SafeIdentifier,
Expand All @@ -17,6 +18,7 @@ import { type ComponentProps, useState } from 'react';

import { H1, H3, P } from '@/components/design';
import { CustomField } from '@/components/form';
import { Spinner } from '@/components/spinner';

function CustomProvider({
children,
Expand All @@ -26,15 +28,28 @@ function CustomProvider({
provider: ComponentProps<typeof Provider>['name'];
}) {
return (
<Provider
name={provider}
className='text-[rgb(243,243,243)] border-[rgb(37,37,37)] hover:border-[rgb(50,50,50)] [&>img]:opacity-80 [&>img]:hover:opacity-100 [&>img]:grayscale [&>img]:hover:grayscale-0 relative flex h-14 w-full cursor-pointer items-center justify-center rounded-lg border bg-[rgb(22,22,22)] hover:bg-[rgb(22,22,30)] text-sm transition-all duration-150'
>
<ProviderIcon
className={`absolute left-4 transition-all duration-200${provider === 'github' ? ' invert' : ''}`}
/>
<span className='leading-loose'>{children}</span>
</Provider>
<Loading scope={`provider:${provider}`}>
{isLoading => (
<Provider
name={provider}
className='text-[rgb(243,243,243)] border-[rgb(37,37,37)] hover:border-[rgb(50,50,50)] [&>img]:opacity-80 [&>img]:hover:opacity-100 [&>img]:grayscale [&>img]:hover:grayscale-0 relative flex h-14 w-full cursor-pointer items-center justify-center rounded-lg border bg-[rgb(22,22,22)] hover:bg-[rgb(22,22,30)] text-sm transition-all duration-150'
disabled={isLoading}
>
<ProviderIcon
className={`absolute left-4 transition-all duration-200${provider === 'github' ? ' invert' : ''}`}
/>
<span className='leading-loose inline-flex justify-center items-center'>
{isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
children
)}
</span>
</Provider>
)}
</Loading>
);
}

Expand Down Expand Up @@ -65,7 +80,7 @@ function Button({ children, ...props }: ComponentProps<'button'>) {
function CustomSubmit({ children }: ComponentProps<'button'>) {
return (
<Action
className='px-7 py-3 justify-center transition rounded-lg focus:outline-none border items-center disabled:bg-[rgb(12,12,12)] focus:text-[rgb(255,255,255)] w-full duration-300 focus:!border-[rgb(37,37,37)] text-sm space-x-1.5 text-[rgb(160,160,160)] hover:text-[rgb(243,243,243)] disabled:text-[rgb(100,100,100)] select-none bg-[rgb(22,22,22)] hover:bg-[rgb(22,22,30)] border-[rgb(37,37,37)] hover:border-[rgb(50,50,50)]'
className='inline-flex px-7 py-3 justify-center transition rounded-lg focus:outline-none border items-center disabled:bg-[rgb(12,12,12)] focus:text-[rgb(255,255,255)] w-full duration-300 focus:!border-[rgb(37,37,37)] text-sm space-x-1.5 text-[rgb(160,160,160)] hover:text-[rgb(243,243,243)] disabled:text-[rgb(100,100,100)] select-none bg-[rgb(22,22,22)] hover:bg-[rgb(22,22,30)] border-[rgb(37,37,37)] hover:border-[rgb(50,50,50)]'
submit
>
{children}
Expand All @@ -91,6 +106,9 @@ export default function SignInPage() {
</Link>
</p>
</div>
<div className='absolute top-4 right-4'>
<Loading>{isLoading => <span>Loading: {JSON.stringify(isLoading, null, 2)}</span>}</Loading>
</div>

<Step name='start'>
<div className='flex flex-col items-center gap-12 w-96'>
Expand All @@ -116,7 +134,19 @@ export default function SignInPage() {
<FieldError className='block text-red-400 font-mono w-full' />
</Field>

<CustomSubmit>Sign in with Email</CustomSubmit>
<CustomSubmit>
<Loading>
{isLoading =>
isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Sign in with Email'
)
}
</Loading>
</CustomSubmit>
</>
) : (
<TextButton onClick={() => setContinueWithEmail(true)}>Continue with Email</TextButton>
Expand Down Expand Up @@ -170,62 +200,90 @@ export default function SignInPage() {
</Step>

<Step name='verifications'>
<div className='flex gap-6 flex-col'>
<GlobalError className='block text-red-400 font-mono' />
<Loading>
{isLoading => (
<div className='flex gap-6 flex-col'>
<GlobalError className='block text-red-400 font-mono' />

<Strategy name='password'>
<P className='text-sm'>
Welcome back <Salutation />!
</P>

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

<Strategy name='password'>
<P className='text-sm'>
Welcome back <Salutation />!
</P>

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

<CustomSubmit>Verify</CustomSubmit>
</Strategy>

<Strategy name='email_code'>
<P className='text-sm'>
Welcome back! We&apos;ve sent a temporary code to <SafeIdentifier />
</P>

<CustomField
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
autoSubmit
label='Email Code'
name='code'
/>

<CustomSubmit>Verify</CustomSubmit>
</Strategy>

<Strategy name='phone_code'>
<P className='text-sm'>
Welcome back! We&apos;ve sent a temporary code to <SafeIdentifier />
</P>

<CustomField
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
autoSubmit
label='Phone Code'
name='code'
/>

<CustomSubmit>Verify</CustomSubmit>
</Strategy>

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

<P className='text-sm'>
We&apos;ve sent a verification code to <SafeIdentifier />.
</P>
</Strategy>
</div>
<CustomSubmit>
{isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Verify'
)}
</CustomSubmit>
</Strategy>

<Strategy name='email_code'>
<P className='text-sm'>
Welcome back! We&apos;ve sent a temporary code to <SafeIdentifier />
</P>

<CustomField
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
autoSubmit
label='Email Code'
name='code'
/>

<CustomSubmit>
{isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Verify'
)}
</CustomSubmit>
</Strategy>

<Strategy name='phone_code'>
<P className='text-sm'>
Welcome back! We&apos;ve sent a temporary code to <SafeIdentifier />
</P>

<CustomField
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus
autoSubmit
label='Phone Code'
name='code'
/>

<CustomSubmit>
{isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Verify'
)}
</CustomSubmit>
</Strategy>

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

<P className='text-sm'>
We&apos;ve sent a verification code to <SafeIdentifier />.
</P>
</Strategy>
</div>
)}
</Loading>

<Action
asChild
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
'use client';

import { GlobalError } from '@clerk/elements/common';
import { Action, Provider, ProviderIcon, SignUp, Step, Strategy } from '@clerk/elements/sign-up';
import { Action, Loading, Provider, ProviderIcon, SignUp, Step, Strategy } from '@clerk/elements/sign-up';
import type { ComponentProps } from 'react';

import { H1, HR as Hr } from '@/components/design';
import { CustomField } from '@/components/form';
import { Spinner } from '@/components/spinner';

function CustomSubmit({ children }: ComponentProps<'button'>) {
return (
<Action
className='px-7 py-3 justify-center transition rounded-lg focus:outline-none border items-center disabled:bg-[rgb(12,12,12)] focus:text-[rgb(255,255,255)] w-full duration-300 focus:!border-[rgb(37,37,37)] text-sm space-x-1.5 text-[rgb(160,160,160)] hover:text-[rgb(243,243,243)] disabled:text-[rgb(100,100,100)] select-none bg-[rgb(22,22,22)] hover:bg-[rgb(22,22,30)] border-[rgb(37,37,37)] hover:border-[rgb(50,50,50)]'
className='inline-flex px-7 py-3 justify-center transition rounded-lg focus:outline-none border items-center disabled:bg-[rgb(12,12,12)] focus:text-[rgb(255,255,255)] w-full duration-300 focus:!border-[rgb(37,37,37)] text-sm space-x-1.5 text-[rgb(160,160,160)] hover:text-[rgb(243,243,243)] disabled:text-[rgb(100,100,100)] select-none bg-[rgb(22,22,22)] hover:bg-[rgb(22,22,30)] border-[rgb(37,37,37)] hover:border-[rgb(50,50,50)]'
submit
>
{children}
Expand Down Expand Up @@ -66,7 +67,19 @@ export default function SignUpPage() {
label='Phone Number'
name='phoneNumber'
/>
<CustomSubmit>Sign Up</CustomSubmit>
<CustomSubmit>
<Loading>
{isLoading =>
isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Sign Up'
)
}
</Loading>
</CustomSubmit>
</div>
</div>
</Step>
Expand All @@ -87,7 +100,19 @@ export default function SignUpPage() {
name='phoneNumber'
/>

<CustomSubmit>Sign Up</CustomSubmit>
<CustomSubmit>
<Loading>
{isLoading =>
isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Sign Up'
)
}
</Loading>
</CustomSubmit>
</Step>

<Step name='verifications'>
Expand All @@ -101,7 +126,19 @@ export default function SignUpPage() {
name='code'
/>

<CustomSubmit>Verify</CustomSubmit>
<CustomSubmit>
<Loading>
{isLoading =>
isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Verify'
)
}
</Loading>
</CustomSubmit>
</Strategy>

<Strategy name='email_code'>
Expand All @@ -110,7 +147,19 @@ export default function SignUpPage() {
name='code'
/>

<CustomSubmit>Verify</CustomSubmit>
<CustomSubmit>
<Loading>
{isLoading =>
isLoading ? (
<>
<Spinner /> Loading...
</>
) : (
'Verify'
)
}
</Loading>
</CustomSubmit>
</Strategy>

<Strategy name='email_link'>Please check your email for a link to verify your account.</Strategy>
Expand Down
Loading

0 comments on commit d54e42d

Please sign in to comment.