diff --git a/v2/.eslintignore b/v2/.eslintignore index 365ffcbdb5..6798faba6d 100644 --- a/v2/.eslintignore +++ b/v2/.eslintignore @@ -2,3 +2,4 @@ generated __fixtures__ dist node_modules +build diff --git a/v2/lib/core/App.js b/v2/lib/core/App.js index 556a1a75ae..eeb4b66667 100644 --- a/v2/lib/core/App.js +++ b/v2/lib/core/App.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import React from 'react'; import {renderRoutes} from 'react-router-config'; import routes from '@generated/routes'; // eslint-disable-line @@ -15,12 +16,34 @@ import docsSidebars from '@generated/docsSidebars'; // eslint-disable-line import pagesMetadatas from '@generated/pagesMetadatas'; // eslint-disable-line import siteConfig from '@generated/siteConfig'; //eslint-disable-line -export default () => - renderRoutes(routes, { - blogMetadatas, - docsMetadatas, - docsSidebars, - env, - pagesMetadatas, - siteConfig, - }); +import DocusaurusContext from '@docusaurus/context'; + +const data = { + blogMetadatas, + docsMetadatas, + docsSidebars, + env, + pagesMetadatas, + siteConfig, +}; + +class App extends React.Component { + constructor(props) { + super(props); + this.state = { + setContext: context => { + this.setState(context); + }, + }; + } + + render() { + return ( + + {renderRoutes(routes)} + + ); + } +} + +export default App; diff --git a/v2/lib/docusaurus/context.js b/v2/lib/docusaurus/context.js new file mode 100644 index 0000000000..631d5ec442 --- /dev/null +++ b/v2/lib/docusaurus/context.js @@ -0,0 +1,12 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; + +const DocusaurusContext = React.createContext({}); + +export default DocusaurusContext; diff --git a/v2/lib/docusaurus/head.js b/v2/lib/docusaurus/head.js new file mode 100644 index 0000000000..6c88246ac7 --- /dev/null +++ b/v2/lib/docusaurus/head.js @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import Helmet from 'react-helmet'; + +function Head(props) { + return ; +} + +export default Head; diff --git a/v2/lib/load/routes.js b/v2/lib/load/routes.js index cafd575a24..bd11232753 100644 --- a/v2/lib/load/routes.js +++ b/v2/lib/load/routes.js @@ -6,43 +6,51 @@ */ async function genRoutesConfig({ + siteConfig = {}, docsMetadatas = {}, pagesMetadatas = [], blogMetadatas = [], }) { + const {docsUrl, baseUrl} = siteConfig; function genDocsRoute(metadata) { const {permalink, source} = metadata; return ` - { - path: ${JSON.stringify(permalink)}, - exact: true, - component: Loadable({ - loader: () => import(/* webpackPrefetch: true */ ${JSON.stringify( - source, - )}), - loading: Loading, - render(loaded, props) { - let Content = loaded.default; - return ( - - - - ); - } - }) - }`; + { + path: '${permalink}', + exact: true, + component: Loadable({ + loader: () => import(/* webpackPrefetch: true */ '${source}'), + loading: Loading, + render(loaded, props) { + let Content = loaded.default; + return ( + + + + ); + } + }) + }`; } + const rootDocsUrl = baseUrl + docsUrl; + const docsRoutes = ` + { + path: '${rootDocsUrl}', + component: Doc, + routes: [${Object.values(docsMetadatas) + .map(genDocsRoute) + .join(',')}], + }`; + function genPagesRoute(metadata) { const {permalink, source} = metadata; return ` { - path: ${JSON.stringify(permalink)}, + path: '${permalink}', exact: true, component: Loadable({ - loader: () => import(/* webpackPrefetch: true */ ${JSON.stringify( - source, - )}), + loader: () => import(/* webpackPrefetch: true */ '${source}'), loading: Loading, render(loaded, props) { let Content = loaded.default; @@ -62,16 +70,16 @@ async function genRoutesConfig({ const {posts} = metadata; return ` { - path: ${JSON.stringify(permalink)}, + path: '${permalink}', exact: true, component: Loadable.Map({ loader: { ${posts .map( (p, i) => - `post${i}: () => import(/* webpackPrefetch: true */ ${JSON.stringify( - p.source, - )})`, + `post${i}: () => import(/* webpackPrefetch: true */ '${ + p.source + }')`, ) .join(',\n\t\t\t\t')} }, @@ -92,12 +100,10 @@ async function genRoutesConfig({ return ` { - path: ${JSON.stringify(permalink)}, + path: '${permalink}', exact: true, component: Loadable({ - loader: () => import(/* webpackPrefetch: true */ ${JSON.stringify( - source, - )}), + loader: () => import(/* webpackPrefetch: true */ '${source}'), loading: Loading, render(loaded, props) { let MarkdownContent = loaded.default; @@ -111,30 +117,26 @@ async function genRoutesConfig({ }`; } - const notFoundRoute = `, + const notFoundRoute = ` { path: '*', - component: NotFound + component: NotFound, }`; - const docsRoutes = Object.values(docsMetadatas) - .map(genDocsRoute) - .join(','); - return ( `import React from 'react';\n` + `import Loadable from 'react-loadable';\n` + `import Loading from '@theme/Loading';\n` + `import Doc from '@theme/Doc';\n` + + `import DocBody from '@theme/DocBody';\n` + `import BlogPost from '@theme/BlogPost';\n` + `import BlogPage from '@theme/BlogPage';\n` + `import Pages from '@theme/Pages';\n` + `import NotFound from '@theme/NotFound';\n` + - `const routes = [${docsRoutes},${pagesMetadatas - .map(genPagesRoute) - .join(',')},${blogMetadatas - .map(genBlogRoute) - .join(',')}${notFoundRoute}\n];\n` + + `const routes = [${docsRoutes}, + ${pagesMetadatas.map(genPagesRoute).join(',')}, + ${blogMetadatas.map(genBlogRoute).join(',')}, + ${notFoundRoute}\n];\n` + `export default routes;\n` ); } diff --git a/v2/lib/theme/BlogPage/index.js b/v2/lib/theme/BlogPage/index.js index faf083d0fb..898f7ee25e 100644 --- a/v2/lib/theme/BlogPage/index.js +++ b/v2/lib/theme/BlogPage/index.js @@ -5,46 +5,39 @@ * LICENSE file in the root directory of this source tree. */ -/* eslint-disable */ -import React from 'react'; +import React, {useContext} from 'react'; import {Link} from 'react-router-dom'; -import Helmet from 'react-helmet'; -import Loadable from 'react-loadable'; +import Head from '@docusaurus/head'; import Layout from '@theme/Layout'; // eslint-disable-line import BlogPost from '@theme/BlogPost'; // eslint-disable-line -import Loading from '@theme/Loading'; -export default class BlogPage extends React.Component { - render() { - const { - metadata, - blogMetadatas, - language, - children, - siteConfig = {}, - } = this.props; - const {posts} = metadata; +import DocusaurusContext from '@docusaurus/context'; - const {baseUrl, favicon} = siteConfig; - return ( - - - {'Blog'} - {favicon && } - {language && } - {language && } - -
-
    - {blogMetadatas.map(metadata => ( -
  • - {metadata.permalink} -
  • - ))} -
- {children} -
-
- ); - } +function BlogPage(props) { + const context = useContext(DocusaurusContext); + const {blogMetadatas, language, siteConfig = {}} = context; + const {baseUrl, favicon} = siteConfig; + + return ( + + + Blog + {favicon && } + {language && } + {language && } + +
+
    + {blogMetadatas.map(metadata => ( +
  • + {metadata.permalink} +
  • + ))} +
+ {props.children} +
+
+ ); } + +export default BlogPage; diff --git a/v2/lib/theme/BlogPost/index.js b/v2/lib/theme/BlogPost/index.js index 975ab06a82..89531e99cd 100644 --- a/v2/lib/theme/BlogPost/index.js +++ b/v2/lib/theme/BlogPost/index.js @@ -5,18 +5,23 @@ * LICENSE file in the root directory of this source tree. */ -/* eslint-disable */ import React from 'react'; import {Link} from 'react-router-dom'; -import Helmet from 'react-helmet'; +import Head from '@docusaurus/head'; import classnames from 'classnames'; import Layout from '@theme/Layout'; // eslint-disable-line +import DocusaurusContext from '@docusaurus/context'; + import styles from './styles.module.css'; -export default class BlogPost extends React.Component { + +class BlogPost extends React.Component { renderPostHeader() { - const {metadata, siteConfig} = this.props; - const {baseUrl} = siteConfig; + const {metadata} = this.context; + if (!metadata) { + return null; + } + const { date, author, @@ -80,19 +85,23 @@ export default class BlogPost extends React.Component { } render() { - const {metadata, children, siteConfig = {}} = this.props; + const {metadata = {}, siteConfig = {}} = this.context; const {baseUrl, favicon} = siteConfig; const {language, title} = metadata; return ( - - + + {title && {title}} {favicon && } {language && } - + {this.renderPostHeader()} - {children} + {this.props.children} ); } } + +BlogPost.contextType = DocusaurusContext; + +export default BlogPost; diff --git a/v2/lib/theme/Doc/index.js b/v2/lib/theme/Doc/index.js index 91cb1e1f77..5d1146af28 100644 --- a/v2/lib/theme/Doc/index.js +++ b/v2/lib/theme/Doc/index.js @@ -5,74 +5,41 @@ * LICENSE file in the root directory of this source tree. */ -/* eslint-disable */ -import React from 'react'; -import {Link} from 'react-router-dom'; -import Helmet from 'react-helmet'; +import React, {useContext} from 'react'; +import {renderRoutes} from 'react-router-config'; +import Head from '@docusaurus/head'; -import DocsPaginator from '@theme/DocsPaginator'; // eslint-disable-line import Footer from '@theme/Footer'; // eslint-disable-line import Navbar from '@theme/Navbar'; // eslint-disable-line import Sidebar from '@theme/Sidebar'; // eslint-disable-line +import DocusaurusContext from '@docusaurus/context'; + import styles from './styles.module.css'; -class Doc extends React.Component { - render() { - const { - docsMetadatas, - docsSidebars, - env, - location, - metadata, - pagesMetadatas, - siteConfig = {}, - route, - } = this.props; - const {language, version} = metadata; - const {baseUrl, favicon} = siteConfig; - return ( -
- - {(metadata && metadata.title) || siteConfig.title} - {favicon && } - {language && } - {language && } - {version && } - - - -
-
-
-

{metadata.title}

- {this.props.children} -
-
- -
-
-
-
+function Doc(props) { + const {metadata = {}, siteConfig = {}} = useContext(DocusaurusContext); + const {route} = props; + const {language, version} = metadata; + const {baseUrl, favicon} = siteConfig; + + return ( +
+ + {(metadata && metadata.title) || siteConfig.title} + {favicon && } + {language && } + {language && } + {version && } + + + +
+
{renderRoutes(route.routes)}
+
- ); - } +
+ ); } export default Doc; diff --git a/v2/lib/theme/Doc/styles.module.css b/v2/lib/theme/Doc/styles.module.css index ebb8b17400..c482bbe465 100644 --- a/v2/lib/theme/Doc/styles.module.css +++ b/v2/lib/theme/Doc/styles.module.css @@ -13,11 +13,3 @@ flex-grow: 1; padding: 0 40px; } - -.docContent { - margin-bottom: 48px; -} - -.paginatorContainer { - margin: 48px 0; -} diff --git a/v2/lib/theme/DocBody/index.js b/v2/lib/theme/DocBody/index.js new file mode 100644 index 0000000000..bceb04a1d8 --- /dev/null +++ b/v2/lib/theme/DocBody/index.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React, {useContext, useEffect} from 'react'; + +import DocsPaginator from '@theme/DocsPaginator'; // eslint-disable-line +import DocusaurusContext from '@docusaurus/context'; + +import styles from './styles.module.css'; + +function DocBody(props) { + const {children, metadata} = props; + const context = useContext(DocusaurusContext); + useEffect(() => { + context.setContext({ + metadata, + }); + }, []); + + return ( +
+
+

{metadata.title}

+ {children} +
+
+ +
+
+ ); +} + +export default DocBody; diff --git a/v2/lib/theme/DocBody/styles.module.css b/v2/lib/theme/DocBody/styles.module.css new file mode 100644 index 0000000000..d91fe67964 --- /dev/null +++ b/v2/lib/theme/DocBody/styles.module.css @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +.docContent { + margin-bottom: 48px; + min-height: calc(100vh - 50px); +} + +.paginatorContainer { + margin: 48px 0; +} diff --git a/v2/lib/theme/DocsPaginator/index.js b/v2/lib/theme/DocsPaginator/index.js index d266f9fd78..0b9cef0286 100644 --- a/v2/lib/theme/DocsPaginator/index.js +++ b/v2/lib/theme/DocsPaginator/index.js @@ -5,49 +5,56 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {useContext} from 'react'; import {Link} from 'react-router-dom'; +import DocusaurusContext from '@docusaurus/context'; + import styles from './styles.module.css'; -export default class DocsPaginator extends React.Component { - render() { - const {docsMetadatas, metadata} = this.props; - return ( -
-
- {metadata.previous && - docsMetadatas[metadata.previous] && ( - - - - - - - {' '} - {metadata.previous_title} - - )} -
-
- {metadata.next && - docsMetadatas[metadata.next] && ( - - {metadata.next_title}{' '} - - - - - - - - )} -
-
- ); +function DocsPaginator() { + const context = useContext(DocusaurusContext); + const {docsMetadatas, metadata} = context; + if (!metadata) { + return null; } + + return ( +
+
+ {metadata.previous && + docsMetadatas[metadata.previous] && ( + + + + + + + {' '} + {metadata.previous_title} + + )} +
+
+ {metadata.next && + docsMetadatas[metadata.next] && ( + + {metadata.next_title}{' '} + + + + + + + + )} +
+
+ ); } + +export default DocsPaginator; diff --git a/v2/lib/theme/Footer/index.js b/v2/lib/theme/Footer/index.js index 943019a1ed..c70908c7d8 100644 --- a/v2/lib/theme/Footer/index.js +++ b/v2/lib/theme/Footer/index.js @@ -5,12 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {useContext} from 'react'; import {Link} from 'react-router-dom'; +import DocusaurusContext from '@docusaurus/context'; + import styles from './styles.module.css'; -function Footer(props) { +function Footer() { + const context = useContext(DocusaurusContext); + const {pagesMetadatas} = context; + return (