From ccf8576ab40919c3fd4928ea329897e95e4e00b2 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 4 Sep 2022 23:18:03 +0100 Subject: [PATCH] [Beta] Refactor Layouts (#4975) * [Beta] Refactor Layouts * TypeScript * oops * Make it work for all pages --- beta/plugins/md-layout-loader.js | 16 +-- beta/src/components/Layout/LayoutAPI.tsx | 26 ----- beta/src/components/Layout/LayoutHome.tsx | 26 ----- beta/src/components/Layout/LayoutLearn.tsx | 24 ---- beta/src/components/Layout/LayoutPost.tsx | 120 -------------------- beta/src/components/Layout/MarkdownPage.tsx | 4 +- beta/src/components/Layout/Page.tsx | 4 +- beta/src/pages/500.md | 9 ++ beta/src/pages/_app.tsx | 36 +++--- beta/src/pages/blog/all.tsx | 71 ------------ beta/src/pages/blog/index.tsx | 95 ---------------- 11 files changed, 41 insertions(+), 390 deletions(-) delete mode 100644 beta/src/components/Layout/LayoutAPI.tsx delete mode 100644 beta/src/components/Layout/LayoutHome.tsx delete mode 100644 beta/src/components/Layout/LayoutLearn.tsx delete mode 100644 beta/src/components/Layout/LayoutPost.tsx create mode 100644 beta/src/pages/500.md delete mode 100644 beta/src/pages/blog/all.tsx delete mode 100644 beta/src/pages/blog/index.tsx diff --git a/beta/plugins/md-layout-loader.js b/beta/plugins/md-layout-loader.js index 25383925..7e4bbf8a 100644 --- a/beta/plugins/md-layout-loader.js +++ b/beta/plugins/md-layout-loader.js @@ -20,19 +20,11 @@ module.exports = async function (src) { .dirname(path.relative('./src/pages', this.resourcePath)) .split(path.sep) .shift(); - const layoutMap = { - blog: 'Post', - learn: 'Learn', - apis: 'API', - }; - const layout = layoutMap[pageParentDir] || 'Home'; const code = - `import withLayout from 'components/Layout/Layout${layout}'; - -export default withLayout(${JSON.stringify(data)}) - - + `export const layout = { + section: '${pageParentDir}', + meta: ${JSON.stringify(data)} +};\n ` + content; - return callback(null, code); }; diff --git a/beta/src/components/Layout/LayoutAPI.tsx b/beta/src/components/Layout/LayoutAPI.tsx deleted file mode 100644 index ceebaa32..00000000 --- a/beta/src/components/Layout/LayoutAPI.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - */ - -import * as React from 'react'; -import sidebarReference from 'sidebarReference.json'; -import {MarkdownPage, MarkdownProps} from './MarkdownPage'; -import {Page} from './Page'; -import {RouteItem} from './useRouteMeta'; - -interface PageFrontmatter { - title: string; - status: string; -} - -export default function withAPI(p: PageFrontmatter) { - function LayoutAPI(props: MarkdownProps) { - return ; - } - LayoutAPI.appShell = AppShell; - return LayoutAPI; -} - -function AppShell(props: {children: React.ReactNode}) { - return ; -} diff --git a/beta/src/components/Layout/LayoutHome.tsx b/beta/src/components/Layout/LayoutHome.tsx deleted file mode 100644 index 162ad7e5..00000000 --- a/beta/src/components/Layout/LayoutHome.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - */ - -import * as React from 'react'; -import sidebarHome from 'sidebarHome.json'; -import {MarkdownPage, MarkdownProps} from './MarkdownPage'; -import {Page} from './Page'; -import {RouteItem} from './useRouteMeta'; - -interface PageFrontmatter { - title: string; - status: string; -} - -export default function withDocs(p: PageFrontmatter) { - function LayoutHome(props: MarkdownProps) { - return ; - } - LayoutHome.appShell = AppShell; - return LayoutHome; -} - -function AppShell(props: {children: React.ReactNode}) { - return ; -} diff --git a/beta/src/components/Layout/LayoutLearn.tsx b/beta/src/components/Layout/LayoutLearn.tsx deleted file mode 100644 index 9441b49d..00000000 --- a/beta/src/components/Layout/LayoutLearn.tsx +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - */ - -import * as React from 'react'; -import {MarkdownPage, MarkdownProps} from './MarkdownPage'; -import {RouteItem} from 'components/Layout/useRouteMeta'; -import {Page} from './Page'; -import sidebarLearn from '../../sidebarLearn.json'; -interface PageFrontmatter { - title: string; -} - -export default function withLearn(meta: PageFrontmatter) { - function LayoutLearn(props: MarkdownProps) { - return ; - } - LayoutLearn.appShell = AppShell; - return LayoutLearn; -} - -function AppShell(props: {children: React.ReactNode}) { - return ; -} diff --git a/beta/src/components/Layout/LayoutPost.tsx b/beta/src/components/Layout/LayoutPost.tsx deleted file mode 100644 index 789c7543..00000000 --- a/beta/src/components/Layout/LayoutPost.tsx +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - */ - -// @ts-ignore -import {MDXContext} from '@mdx-js/react'; -import recentPostsRouteTree from 'blogIndexRecent.json'; -import {DocsPageFooter} from 'components/DocsFooter'; -import {ExternalLink} from 'components/ExternalLink'; -import {MDXComponents} from 'components/MDX/MDXComponents'; -import {Seo} from 'components/Seo'; -import {Toc} from 'components/Layout/Toc'; -import format from 'date-fns/format'; -import {useRouter} from 'next/router'; -import * as React from 'react'; -import {getAuthor} from 'utils/getAuthor'; -import toCommaSeparatedList from 'utils/toCommaSeparatedList'; -import {Page} from './Page'; -import {RouteItem, useRouteMeta} from './useRouteMeta'; -import {useTwitter} from './useTwitter'; - -interface PageFrontmatter { - id?: string; - title: string; - author: string[]; - date?: string; -} - -interface LayoutPostProps { - /** Sidebar/Nav */ - routes: RouteItem[]; - /** Markdown frontmatter */ - meta: PageFrontmatter; - /** The mdx */ - children: React.ReactNode; -} - -/** Return the date of the current post given the path */ -function getDateFromPath(path: string) { - // All paths are /blog/year/month/day/title - const [year, month, day] = path - .substr(1) // first `/` - .split('/') // make an array - .slice(1) // ignore blog - .map((i) => parseInt(i, 10)); // convert to numbers - - return { - date: format(new Date(year, month, day), 'MMMM dd, yyyy'), - dateTime: [year, month, day].join('-'), - }; -} - -function LayoutPost({meta, children}: LayoutPostProps) { - const {pathname} = useRouter(); - const {date, dateTime} = getDateFromPath(pathname); - const {route, nextRoute, prevRoute} = useRouteMeta(); - const anchors = React.Children.toArray(children) - .filter( - (child: any) => - child.props?.mdxType && ['h2', 'h3'].includes(child.props.mdxType) - ) - .map((child: any) => ({ - url: '#' + child.props.id, - depth: parseInt(child.props.mdxType.replace('h', ''), 0), - text: child.props.children, - })); - useTwitter(); - return ( - <> -
-
- -

- {meta.title} -

-

- By{' '} - {toCommaSeparatedList(meta.author, (author) => ( - - {getAuthor(author).name} - - ))} - · - - - -

- - - {children} - - -
-
-
- -
- - ); -} - -function AppShell(props: {children: React.ReactNode}) { - return ; -} - -export default function withLayoutPost(meta: any) { - function LayoutPostWrapper(props: LayoutPostProps) { - return ; - } - - LayoutPostWrapper.appShell = AppShell; - - return LayoutPostWrapper; -} diff --git a/beta/src/components/Layout/MarkdownPage.tsx b/beta/src/components/Layout/MarkdownPage.tsx index 746efe99..e155cb6f 100644 --- a/beta/src/components/Layout/MarkdownPage.tsx +++ b/beta/src/components/Layout/MarkdownPage.tsx @@ -116,7 +116,7 @@ export function MarkdownPage< flushWrapper('last'); return ( -
+ <>
{!isHomePage && ( @@ -142,6 +142,6 @@ export function MarkdownPage<
{!isHomePage && anchors.length > 0 && }
-
+ ); } diff --git a/beta/src/components/Layout/Page.tsx b/beta/src/components/Layout/Page.tsx index 777a711f..4df8a496 100644 --- a/beta/src/components/Layout/Page.tsx +++ b/beta/src/components/Layout/Page.tsx @@ -31,7 +31,9 @@ export function Page({routeTree, children}: PageProps) {
- {children} +
+ {children} +
diff --git a/beta/src/pages/500.md b/beta/src/pages/500.md new file mode 100644 index 00000000..20fd493c --- /dev/null +++ b/beta/src/pages/500.md @@ -0,0 +1,9 @@ +--- +title: Server Error +--- + +Something went very wrong. + +Sorry about that! + +You can file a bug [here.](https://github.com/reactjs/reactjs.org/issues/new) diff --git a/beta/src/pages/_app.tsx b/beta/src/pages/_app.tsx index fa99018f..0c67811a 100644 --- a/beta/src/pages/_app.tsx +++ b/beta/src/pages/_app.tsx @@ -5,17 +5,20 @@ import * as React from 'react'; import {AppProps} from 'next/app'; import {useRouter} from 'next/router'; +import {MarkdownPage} from 'components/Layout/MarkdownPage'; +import {Page} from 'components/Layout/Page'; import {ga} from '../utils/analytics'; +import type {RouteItem} from 'components/Layout/useRouteMeta'; +import sidebarHome from '../sidebarHome.json'; +import sidebarLearn from '../sidebarLearn.json'; +import sidebarReference from '../sidebarReference.json'; + import '@docsearch/css'; import '../styles/algolia.css'; import '../styles/index.css'; import '../styles/sandpack.css'; import '@codesandbox/sandpack-react/dist/index.css'; -const EmptyAppShell = ({children}: {children: React.ReactNode}) => ( - <>{children} -); - if (typeof window !== 'undefined') { if (process.env.NODE_ENV === 'production') { ga('create', process.env.NEXT_PUBLIC_GA_TRACKING_ID, 'auto'); @@ -39,16 +42,23 @@ export default function MyApp({Component, pageProps}: AppProps) { }; }, [router.events]); - let AppShell = (Component as any).appShell || EmptyAppShell; - // In order to make sidebar scrolling between pages work as expected - // we need to access the underlying MDX component. + let routeTree = sidebarHome as RouteItem; + let content = ; if ((Component as any).isMDXComponent) { - AppShell = (Component as any)({}).props.originalType.appShell; + const mdxContent = (Component as any)({}); // HACK: Extract MDX out of the generated wrapper + const {section, meta} = mdxContent.props.layout; // Injected by md-layout-loader.js + switch (section) { + case 'apis': + routeTree = sidebarReference as RouteItem; + break; + case 'learn': + routeTree = sidebarLearn as RouteItem; + break; + } + content = ( + {mdxContent.props.children} + ); } - return ( - - - - ); + return {content}; } diff --git a/beta/src/pages/blog/all.tsx b/beta/src/pages/blog/all.tsx deleted file mode 100644 index a981ff5c..00000000 --- a/beta/src/pages/blog/all.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import blogIndex from 'blogIndex.json'; -import blogIndexRecentRouteTree from 'blogIndexRecent.json'; -import {ExternalLink} from 'components/ExternalLink'; -import {IconRss} from 'components/Icon/IconRss'; -import {Page} from 'components/Layout/Page'; -import format from 'date-fns/format'; -import parseISO from 'date-fns/parseISO'; -import Link from 'next/link'; -import * as React from 'react'; -import {getAuthor} from 'utils/getAuthor'; -import {removeFromLast} from 'utils/removeFromLast'; -import toCommaSeparatedList from 'utils/toCommaSeparatedList'; - -export default function Archive() { - return ( -
-
-
-

Blog Archive

- - - RSS - -
-

- Historical archive of React news, announcements, and release notes. -

-
-
- {blogIndex.routes.map((post) => ( -
-

- - {post.title} - -

-
-
-

- By{' '} - {toCommaSeparatedList(post.author, (author) => ( - - {getAuthor(author).name} - - ))} -

-
- - · - {post.readingTime} -
-
-
-
- ))} -
-
- ); -} - -Archive.displayName = 'Index'; - -Archive.appShell = function AppShell(props: {children: React.ReactNode}) { - return ; -}; diff --git a/beta/src/pages/blog/index.tsx b/beta/src/pages/blog/index.tsx deleted file mode 100644 index 30f83a14..00000000 --- a/beta/src/pages/blog/index.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import blogIndexRecentRouteTree from 'blogIndexRecent.json'; -import {ExternalLink} from 'components/ExternalLink'; -import {IconRss} from 'components/Icon/IconRss'; -import {Page} from 'components/Layout/Page'; -import styles from 'components/MDX/MDXComponents.module.css'; -import {Seo} from 'components/Seo'; -import format from 'date-fns/format'; -import parseISO from 'date-fns/parseISO'; -import Link from 'next/link'; -import * as React from 'react'; -import {getAuthor} from 'utils/getAuthor'; -import {removeFromLast} from 'utils/removeFromLast'; -import toCommaSeparatedList from 'utils/toCommaSeparatedList'; - -export default function RecentPosts() { - return ( - <> -
-
-
-
- -

- Blog -

- - - RSS - -
-

- Offical React.js news, announcements, and release notes. -

-
-
- {blogIndexRecentRouteTree.routes.map((post) => ( -
-

- - {post.title} - -

-
-
-
-

- By{' '} - {toCommaSeparatedList(post.author, (author) => ( - - {getAuthor(author).name} - - ))} -

-
- - · - {post.readingTime} -
-
-
-
- ))} - -
-
-
- -
- - ); -} - -RecentPosts.displayName = 'Index'; - -RecentPosts.appShell = function AppShell(props: {children: React.ReactNode}) { - return ; -};