Skip to content

Commit 1d5918e

Browse files
committed
add 404 page
1 parent 451ac67 commit 1d5918e

File tree

5 files changed

+66
-25
lines changed

5 files changed

+66
-25
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Error from '../src/Error';
2+
import {Layout} from '../src/Layout';
3+
export default Layout;
4+
5+
import docs from 'docs:@react-spectrum/s2';
6+
7+
<Error />

packages/dev/s2-docs/pages/s2/Accordion.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import {style} from '@react-spectrum/s2/style' with {type: 'macro'};
2828

2929
## Expanding
3030

31+
As described in the docs for [CalendarDate](aweawg.html)
32+
3133
Use the `defaultExpandedKeys` or `expandedKeys` prop to set the expanded items, and `onExpandedChange` to handle user interactions. The expanded keys correspond to the `id` prop of each `<Disclosure>`.
3234

3335
```tsx render

packages/dev/s2-docs/src/Error.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use client';
2+
3+
// eslint-disable-next-line monorepo/no-internal-import
4+
import BrowserError from '@react-spectrum/s2/illustrations/linear/BrowserError';
5+
import {Content, Heading, IllustratedMessage} from '@react-spectrum/s2';
6+
7+
export default function Error() {
8+
return (
9+
<div style={{display: 'flex', alignItems: 'center', height: '50vh', justifyContent: 'center', flexDirection: 'row'}}>
10+
<IllustratedMessage>
11+
<BrowserError />
12+
<Heading>Error 404: Page not found</Heading>
13+
<Content>This page isn't available. Try checking the URL or visit a different page.</Content>
14+
</IllustratedMessage>
15+
</div>
16+
);
17+
}

packages/dev/s2-docs/src/Layout.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,19 @@ const getDescription = (currentPage: Page): string => {
7474
return library ? `Documentation for ${pageTitle} in ${library}.` : `Documentation for ${pageTitle}.`;
7575
};
7676

77+
let articleStyles = style({
78+
maxWidth: {
79+
default: 'none',
80+
isWithToC: 768
81+
},
82+
width: 'full',
83+
height: 'fit'
84+
});
85+
86+
7787
export function Layout(props: PageProps & {children: ReactElement<any>}) {
7888
let {pages, currentPage, children} = props;
89+
let hasToC = currentPage.tableOfContents?.[0]?.children && currentPage.tableOfContents[0].children.length > 0;
7990
return (
8091
<Provider elementType="html" locale="en" background="layer-1" styles={style({scrollPaddingTop: {default: 64, lg: 0}})}>
8192
<head>
@@ -156,11 +167,7 @@ export function Layout(props: PageProps & {children: ReactElement<any>}) {
156167
}
157168
})}>
158169
<article
159-
className={style({
160-
maxWidth: 768,
161-
width: 'full',
162-
height: 'fit'
163-
})}>
170+
className={articleStyles({isWithToC: hasToC})}>
164171
{React.cloneElement(children, {components})}
165172
</article>
166173
<aside
@@ -177,10 +184,10 @@ export function Layout(props: PageProps & {children: ReactElement<any>}) {
177184
lg: 'block'
178185
}
179186
})}>
180-
{currentPage.tableOfContents?.[0]?.children && currentPage.tableOfContents[0].children.length > 0 && (
187+
{hasToC && (
181188
<div className={style({font: 'title', minHeight: 32, paddingX: 12, display: 'flex', alignItems: 'center'})}>Contents</div>
182189
)}
183-
<Toc toc={currentPage.tableOfContents?.[0]?.children ?? []} />
190+
<Toc toc={currentPage.tableOfContents?.[0]?.children ?? []} />
184191
</aside>
185192
</main>
186193
</div>

packages/dev/s2-docs/src/client.tsx

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,35 @@ let updateRoot = hydrate({
1515
// and in a React transition, stream in the new page. Once complete, we'll pushState to
1616
// update the URL in the browser.
1717
async function navigate(pathname: string, push = false) {
18-
let res = fetchRSC<ReactElement>(pathname.replace('.html', '.rsc'));
19-
let currentPath = location.pathname;
20-
let [newBasePath, newPathAnchor] = pathname.split('#');
18+
try {
19+
let res = await fetchRSC<ReactElement>(pathname.replace('.html', '.rsc'));
20+
let currentPath = location.pathname;
21+
let [newBasePath, newPathAnchor] = pathname.split('#');
2122

22-
updateRoot(res, () => {
23-
if (push) {
24-
history.pushState(null, '', pathname);
25-
push = false;
26-
}
23+
updateRoot(res, () => {
24+
if (push) {
25+
history.pushState(null, '', pathname);
26+
push = false;
27+
}
2728

28-
// Reset scroll if navigating to a different page without an anchor, primarily for the mobile case.
29-
// Otherwise, make sure to scroll the anchor into view if any
30-
if (currentPath !== newBasePath && !newPathAnchor) {
31-
window.scrollTo(0, 0);
32-
} else if (newPathAnchor) {
33-
let element = document.getElementById(newPathAnchor);
34-
if (element) {
35-
element.scrollIntoView();
29+
// Reset scroll if navigating to a different page without an anchor
30+
if (currentPath !== newBasePath && !newPathAnchor) {
31+
window.scrollTo(0, 0);
32+
} else if (newPathAnchor) {
33+
let element = document.getElementById(newPathAnchor);
34+
if (element) {
35+
element.scrollIntoView();
36+
}
37+
}
38+
});
39+
} catch {
40+
let errorRes = await fetchRSC<ReactElement>('/error.rsc');
41+
updateRoot(errorRes, () => {
42+
if (push) {
43+
history.pushState(null, '', '/error.html');
3644
}
37-
}
38-
});
45+
});
46+
}
3947
}
4048

4149
// Intercept link clicks to perform RSC navigation.

0 commit comments

Comments
 (0)