Skip to content

Commit

Permalink
feat(clerk-react): Support for fallback prop (#4723)
Browse files Browse the repository at this point in the history
Co-authored-by: Alex Carpenter <alex.carpenter@clerk.dev>
  • Loading branch information
BRKalow and alexcarpenter authored Dec 20, 2024
1 parent 8ad1866 commit b5eb15b
Show file tree
Hide file tree
Showing 32 changed files with 768 additions and 246 deletions.
10 changes: 10 additions & 0 deletions .changeset/serious-stingrays-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@clerk/clerk-react': minor
---

Adds support for a `fallback` prop on Clerk's components. This allows rendering of a placeholder element while Clerk's components are mounting. Use this to help mitigate layout shift when using Clerk's components. Example usage:


```tsx
<SignIn fallback={<LoadingSkeleton />} />
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CreateOrganization } from '@clerk/nextjs';

export default function Page() {
return (
<div>
<CreateOrganization fallback={<>Loading create organization</>} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { OrganizationList } from '@clerk/nextjs';

export default function Page() {
return (
<div>
<OrganizationList fallback={<>Loading organization list</>} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { OrganizationProfile } from '@clerk/nextjs';

export default function Page() {
return (
<div>
<OrganizationProfile
routing='hash'
fallback={<>Loading organization profile</>}
/>
</div>
);
}
5 changes: 3 additions & 2 deletions integration/templates/next-app-router/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { SignedIn, SignedOut, SignIn, UserButton, Protect } from '@clerk/nextjs';
import { SignedIn, SignedOut, SignIn, UserButton, Protect, OrganizationSwitcher } from '@clerk/nextjs';
import Link from 'next/link';
import { ClientId } from './client-id';

export default function Home() {
return (
<main>
<UserButton />
<UserButton fallback={<>Loading user button</>} />
<OrganizationSwitcher fallback={<>Loading organization switcher</>} />
<ClientId />
<SignedIn>SignedIn</SignedIn>
<SignedOut>SignedOut</SignedOut>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function Page() {
routing={'path'}
path={'/sign-in'}
signUpUrl={'/sign-up'}
fallback={<>Loading sign in</>}
__experimental={{
combinedProps: {},
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default function Page() {
routing={'path'}
path={'/sign-up'}
signInUrl={'/sign-in'}
fallback={<>Loading sign up</>}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { OrganizationSwitcher } from '@clerk/nextjs';

export default function Page() {
return <OrganizationSwitcher hidePersonal={true} />;
return (
<OrganizationSwitcher
hidePersonal={true}
fallback={<>Loading organization switcher</>}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { UserButton } from '@clerk/nextjs';

export default function Page() {
return (
<div>
<UserButton fallback={<>Loading user button</>} />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UserProfile } from '@clerk/nextjs';
export default function Page() {
return (
<div>
<UserProfile />
<UserProfile fallback={<>Loading user profile</>} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Waitlist } from '@clerk/nextjs';

export default function Page() {
return (
<div>
<Waitlist fallback={<>Loading waitlist</>} />
</div>
);
}
2 changes: 1 addition & 1 deletion integration/templates/react-vite/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function App() {
return (
<main>
<UserButton afterSignOutUrl={'/'} />
<OrganizationSwitcher />
<OrganizationSwitcher fallback={<>Loading organization switcher</>} />
<ClientId />
<SignedOut>SignedOut</SignedOut>
<SignedIn>SignedIn</SignedIn>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { CreateOrganization } from '@clerk/clerk-react';

export default function Page() {
return (
<div>
<CreateOrganization fallback={<>Loading create organization</>} />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function Page1() {
export default function Page() {
return (
<PageContextProvider>
<UserButton>
<UserButton fallback={<>Loading user button</>}>
<UserButton.UserProfilePage
label={'Page 1'}
labelIcon={<p data-label-icon={'page-1'}>🙃</p>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ function Page1() {
export default function Page() {
return (
<PageContextProvider>
<UserProfile path={'/custom-user-profile'}>
<UserProfile
fallback={<>Loading user profile</>}
path={'/custom-user-profile'}
>
<UserProfile.Page
label={'Page 1'}
labelIcon={<p data-label-icon={'page-1'}>🙃</p>}
Expand Down
25 changes: 25 additions & 0 deletions integration/templates/react-vite/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import UserProfile from './user';
import UserProfileCustom from './custom-user-profile';
import UserButtonCustom from './custom-user-button';
import UserButtonCustomTrigger from './custom-user-button-trigger';
import UserButton from './user-button';
import Waitlist from './waitlist';
import OrganizationProfile from './organization-profile';
import OrganizationList from './organization-list';
import CreateOrganization from './create-organization';

const Root = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -53,6 +58,10 @@ const router = createBrowserRouter([
path: '/user/*',
element: <UserProfile />,
},
{
path: '/user-button',
element: <UserButton />,
},
{
path: '/protected',
element: <Protected />,
Expand All @@ -69,6 +78,22 @@ const router = createBrowserRouter([
path: '/custom-user-button-trigger',
element: <UserButtonCustomTrigger />,
},
{
path: '/waitlist',
element: <Waitlist />,
},
{
path: '/organization-profile',
element: <OrganizationProfile />,
},
{
path: '/organization-list',
element: <OrganizationList />,
},
{
path: '/create-organization',
element: <CreateOrganization />,
},
],
},
]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { OrganizationList } from '@clerk/clerk-react';

export default function Page() {
return (
<div>
<OrganizationList fallback={<>Loading organization list</>} />
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { OrganizationProfile } from '@clerk/clerk-react';

export default function Page() {
return (
<div>
<OrganizationProfile
routing='hash'
fallback={<>Loading organization profile</>}
/>
</div>
);
}
1 change: 1 addition & 0 deletions integration/templates/react-vite/src/sign-in/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default function Page() {
<SignIn
path={'/sign-in'}
signUpUrl={'/sign-up'}
fallback={<>Loading sign in</>}
/>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions integration/templates/react-vite/src/sign-up/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default function Page() {
<SignUp
path={'/sign-up'}
signInUrl={'/sign-in'}
fallback={<>Loading sign up</>}
/>
</div>
);
Expand Down
9 changes: 9 additions & 0 deletions integration/templates/react-vite/src/user-button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { UserButton } from '@clerk/clerk-react';

export default function Page() {
return (
<div>
<UserButton fallback={<>Loading user button</>} />
</div>
);
}
5 changes: 4 additions & 1 deletion integration/templates/react-vite/src/user/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { UserProfile } from '@clerk/clerk-react';
export default function Page() {
return (
<div>
<UserProfile path={'/user'} />
<UserProfile
path={'/user'}
fallback={<>Loading user profile</>}
/>
</div>
);
}
9 changes: 9 additions & 0 deletions integration/templates/react-vite/src/waitlist/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Waitlist } from '@clerk/clerk-react';

export default function Page() {
return (
<div>
<Waitlist fallback={<>Loading waitlist</>} />
</div>
);
}
4 changes: 2 additions & 2 deletions integration/testUtils/appPageObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const createAppPageObject = (testArgs: { page: Page }, app: Application)
// do not fail the test if interstitial is returned (401)
}
},
goToRelative: (path: string, opts: { searchParams?: URLSearchParams; timeout?: number } = {}) => {
goToRelative: (path: string, opts: { waitUntil?: any; searchParams?: URLSearchParams; timeout?: number } = {}) => {
let url: URL;

try {
Expand All @@ -35,7 +35,7 @@ export const createAppPageObject = (testArgs: { page: Page }, app: Application)
if (opts.searchParams) {
url.search = opts.searchParams.toString();
}
return page.goto(url.toString(), { timeout: opts.timeout ?? 20000 });
return page.goto(url.toString(), { timeout: opts.timeout ?? 20000, waitUntil: opts.waitUntil });
},
waitForClerkJsLoaded: async () => {
return page.waitForFunction(() => {
Expand Down
Loading

0 comments on commit b5eb15b

Please sign in to comment.