Skip to content

Commit e2a9243

Browse files
committed
Add documentation page for the lazy utility
1 parent 3b94591 commit e2a9243

File tree

5 files changed

+231
-0
lines changed

5 files changed

+231
-0
lines changed

src/pattern-library/components/PlaygroundApp.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export default function PlaygroundApp({
147147
const prototypeRoutes = getRoutes('prototype');
148148

149149
const hookRoutes = getRoutes('hooks');
150+
const utilityRoutes = getRoutes('utilities');
150151

151152
const groupKeys = Object.keys(componentGroups) as Array<
152153
keyof typeof componentGroups
@@ -204,6 +205,13 @@ export default function PlaygroundApp({
204205
))}
205206
</NavList>
206207

208+
<NavHeader>Utilities</NavHeader>
209+
<NavList>
210+
{utilityRoutes.map(route => (
211+
<NavLink key={route.title} route={route} />
212+
))}
213+
</NavList>
214+
207215
{prototypeRoutes.length > 0 && (
208216
<>
209217
<NavHeader>Prototypes</NavHeader>
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import Library from '../../Library';
2+
3+
export default function LazyPage() {
4+
return (
5+
<Library.Page
6+
title="lazy"
7+
intro={
8+
<p>
9+
The <code>lazy</code> utility creates a component which is loaded
10+
asynchronously, displaying fallback content while loading and showing
11+
an error fallback if the component fails to load.
12+
</p>
13+
}
14+
>
15+
<Library.Section title="API">
16+
<Library.SectionL2>
17+
<Library.Usage symbolName="lazy" />
18+
</Library.SectionL2>
19+
<Library.SectionL2 title="Parameters">
20+
<Library.SectionL3 title="displayName">
21+
<Library.Info>
22+
<Library.InfoItem label="description">
23+
Display name for the lazy wrapper component.
24+
</Library.InfoItem>
25+
<Library.InfoItem label="type">
26+
<code>string</code>
27+
</Library.InfoItem>
28+
</Library.Info>
29+
</Library.SectionL3>
30+
31+
<Library.SectionL3 title="load">
32+
<Library.Info>
33+
<Library.InfoItem label="description">
34+
Callback invoked on first render to load the component. This
35+
returns a promise resolving to the loaded component. A common
36+
use case is to use an <code>import(...)</code> expression to
37+
load the component.
38+
</Library.InfoItem>
39+
<Library.InfoItem label="type">
40+
<code>{'() => Promise<FunctionalComponent<P>>'}</code>
41+
</Library.InfoItem>
42+
</Library.Info>
43+
</Library.SectionL3>
44+
45+
<Library.SectionL3 title="options">
46+
<Library.Info>
47+
<Library.InfoItem label="description">
48+
Configuration for the lazy component
49+
</Library.InfoItem>
50+
<Library.InfoItem label="type">
51+
<code>LazyOptions&lt;P&gt;</code>
52+
</Library.InfoItem>
53+
</Library.Info>
54+
</Library.SectionL3>
55+
</Library.SectionL2>
56+
57+
<Library.SectionL2 title="LazyOptions">
58+
<Library.SectionL3 title="fallback">
59+
<Library.Info>
60+
<Library.InfoItem label="description">
61+
Function that returns content to display while loading
62+
</Library.InfoItem>
63+
<Library.InfoItem label="type">
64+
<code>{'(props: P) => ComponentChildren'}</code>
65+
</Library.InfoItem>
66+
</Library.Info>
67+
</Library.SectionL3>
68+
69+
<Library.SectionL3 title="errorFallback">
70+
<Library.Info>
71+
<Library.InfoItem label="description">
72+
Function that returns content to display if loading fails. If
73+
not provided a default error fallback is shown.
74+
</Library.InfoItem>
75+
<Library.InfoItem label="type">
76+
<code>
77+
{
78+
'((props: P, error: Error) => ComponentChildren) | undefined'
79+
}
80+
</code>
81+
</Library.InfoItem>
82+
<Library.InfoItem label="default">
83+
<code>undefined</code>
84+
</Library.InfoItem>
85+
</Library.Info>
86+
</Library.SectionL3>
87+
</Library.SectionL2>
88+
</Library.Section>
89+
90+
<Library.Section title="Examples">
91+
<Library.SectionL2 title="Basic usage">
92+
<p>
93+
Lazy components start loading on first render, and show a fallback
94+
while loading.
95+
</p>
96+
<Library.Demo
97+
title="Basic lazy component"
98+
exampleFile="lazy-basic"
99+
withSource
100+
/>
101+
</Library.SectionL2>
102+
103+
<Library.SectionL2 title="Error handling">
104+
<p>If a component fails to load, the error fallback is displayed:</p>
105+
<Library.Demo
106+
title="Component with error state"
107+
exampleFile="lazy-error-handling"
108+
withSource
109+
/>
110+
</Library.SectionL2>
111+
</Library.Section>
112+
</Library.Page>
113+
);
114+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Button, lazy } from '../../';
2+
3+
type ProfileProps = {
4+
name: string;
5+
description: string;
6+
};
7+
8+
function Profile({ name, description }: ProfileProps) {
9+
return (
10+
<div className="p-4 border border-green-500 rounded">
11+
<h3 className="text-green-700 font-bold">{name}</h3>
12+
<p>{description}</p>
13+
</div>
14+
);
15+
}
16+
17+
let resolve: (x: typeof Profile) => void;
18+
const promise = new Promise<typeof Profile>(resolve_ => (resolve = resolve_));
19+
20+
const LazyProfile = lazy('Profile', () => promise, {
21+
fallback: ({ name }) => (
22+
<div className="p-4 border border-gray-300 rounded">
23+
<p className="text-gray-500 mt-2">
24+
Loading {name}
25+
{"'"}s profile...
26+
</p>
27+
</div>
28+
),
29+
});
30+
31+
export default function App() {
32+
return (
33+
<div>
34+
<Button onClick={() => resolve(Profile)} variant="primary" classes="my-2">
35+
Finish loading
36+
</Button>
37+
<LazyProfile
38+
name="Bob Parr"
39+
description="Robert Parr, also known as Mr. Incredible, is the husband of Helen Parr, and the father of Violet Parr, Dash Parr, and Jack-Jack Parr."
40+
/>
41+
</div>
42+
);
43+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Button, lazy } from '../../';
2+
3+
type ProfileProps = {
4+
name: string;
5+
description: string;
6+
};
7+
8+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
9+
function Profile({ name, description }: ProfileProps) {
10+
return (
11+
<div className="p-4 border border-green-500 rounded">
12+
<h3 className="text-green-700 font-bold">{name}</h3>
13+
<p>{description}</p>
14+
</div>
15+
);
16+
}
17+
18+
let reject: (err: Error) => void;
19+
const promise = new Promise<typeof Profile>(
20+
(_resolve, reject_) => (reject = reject_),
21+
);
22+
23+
const LazyProfile = lazy('Profile', () => promise, {
24+
fallback: ({ name }) => (
25+
<div className="p-4 border border-gray-300 rounded">
26+
<p className="text-gray-500 mt-2">
27+
Loading {name}
28+
{"'"}s profile...
29+
</p>
30+
</div>
31+
),
32+
errorFallback: ({ name }, error) => (
33+
<div className="p-4 border border-red-300 rounded">
34+
<p className="text-gray-500 mt-2">
35+
Unable to load {name}
36+
{"'"}s profile: {error.message}
37+
</p>
38+
</div>
39+
),
40+
});
41+
42+
export default function App() {
43+
return (
44+
<div>
45+
<Button
46+
onClick={() => reject(new Error('Something went wrong'))}
47+
variant="primary"
48+
classes="my-2"
49+
>
50+
Trigger loading error
51+
</Button>
52+
<LazyProfile
53+
name="Bob Parr"
54+
description="Robert Parr, also known as Mr. Incredible, is the husband of Helen Parr, and the father of Violet Parr, Dash Parr, and Jack-Jack Parr."
55+
/>
56+
</div>
57+
);
58+
}

src/pattern-library/routes.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import PaginationPage from './components/patterns/navigation/PaginationPage';
3535
import PointerButtonPage from './components/patterns/navigation/PointerButtonPage';
3636
import TabPage from './components/patterns/navigation/TabPage';
3737
import SliderPage from './components/patterns/transition/SliderPage';
38+
import LazyPage from './components/patterns/utilities/LazyPage';
3839

3940
export const componentGroups = {
4041
data: 'Data Display',
@@ -53,6 +54,7 @@ export type PlaygroundRouteGroup =
5354
| 'foundations'
5455
| 'components'
5556
| 'hooks'
57+
| 'utilities'
5658
| 'prototype'
5759
| 'custom';
5860

@@ -280,6 +282,12 @@ const routes: PlaygroundRoute[] = [
280282
component: UseClickAwayPage,
281283
route: '/hooks-use-click-away',
282284
},
285+
{
286+
title: 'lazy',
287+
group: 'utilities',
288+
component: LazyPage,
289+
route: '/utilities-lazy',
290+
},
283291
];
284292

285293
/**

0 commit comments

Comments
 (0)