From 24c34dd6ed1765e8a9f54b27fe26311ffd9a11cb Mon Sep 17 00:00:00 2001 From: c9s Date: Sun, 24 Jan 2021 14:32:52 +0800 Subject: [PATCH] add integrate next js with material ui --- frontend/pages/_app.tsx | 38 ++++++++++++++++-- frontend/pages/_document.js | 71 +++++++++++++++++++++++++++++++++ frontend/pages/index.tsx | 78 +++++++++---------------------------- frontend/src/theme.js | 22 +++++++++++ 4 files changed, 146 insertions(+), 63 deletions(-) create mode 100644 frontend/pages/_document.js create mode 100644 frontend/src/theme.js diff --git a/frontend/pages/_app.tsx b/frontend/pages/_app.tsx index 1e1cec924..1c188a08a 100644 --- a/frontend/pages/_app.tsx +++ b/frontend/pages/_app.tsx @@ -1,7 +1,39 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Head from 'next/head'; +import { ThemeProvider } from '@material-ui/core/styles'; +import CssBaseline from '@material-ui/core/CssBaseline'; + +import theme from '../src/theme'; import '../styles/globals.css' -function MyApp({ Component, pageProps }) { - return +export default function MyApp(props) { + const { Component, pageProps } = props; + + React.useEffect(() => { + // Remove the server-side injected CSS. + const jssStyles = document.querySelector('#jss-server-side'); + if (jssStyles) { + jssStyles.parentElement.removeChild(jssStyles); + } + }, []); + + return ( + + + My page + + + + {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */} + + + + + ); } -export default MyApp +MyApp.propTypes = { + Component: PropTypes.elementType.isRequired, + pageProps: PropTypes.object.isRequired, +}; diff --git a/frontend/pages/_document.js b/frontend/pages/_document.js new file mode 100644 index 000000000..f6d4f4aa4 --- /dev/null +++ b/frontend/pages/_document.js @@ -0,0 +1,71 @@ +/* eslint-disable react/jsx-filename-extension */ +import React from 'react'; +import Document, { + Html, Main, NextScript, +} from 'next/document'; +import { ServerStyleSheets } from '@material-ui/core/styles'; +import theme from '../src/theme'; + +export default class MyDocument extends Document { + render() { + return ( + + + {/* PWA primary color */} + + + + +
+ + + + ); + } +} + +// `getInitialProps` belongs to `_document` (instead of `_app`), +// it's compatible with server-side generation (SSG). +MyDocument.getInitialProps = async (ctx) => { + // Resolution order + // + // On the server: + // 1. app.getInitialProps + // 2. page.getInitialProps + // 3. document.getInitialProps + // 4. app.render + // 5. page.render + // 6. document.render + // + // On the server with error: + // 1. document.getInitialProps + // 2. app.render + // 3. page.render + // 4. document.render + // + // On the client + // 1. app.getInitialProps + // 2. page.getInitialProps + // 3. app.render + // 4. page.render + + // Render app and page and get the context of the page with collected side effects. + const sheets = new ServerStyleSheets(); + const originalRenderPage = ctx.renderPage; + + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => (props) => sheets.collect(), + }); + + const initialProps = await Document.getInitialProps(ctx); + + return { + ...initialProps, + // Styles fragment is rendered after the app and page rendering finish. + styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()], + }; +}; diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx index 43956d912..0d2aa1459 100644 --- a/frontend/pages/index.tsx +++ b/frontend/pages/index.tsx @@ -1,65 +1,23 @@ -import Head from 'next/head' +import React from 'react'; +import Container from '@material-ui/core/Container'; +import Typography from '@material-ui/core/Typography'; +import Box from '@material-ui/core/Box'; +import Link from '@material-ui/core/Link'; + import styles from '../styles/Home.module.css' export default function Home() { return ( - - ) + + + + Next.js example + + + Go to the about page + + + + ); } + diff --git a/frontend/src/theme.js b/frontend/src/theme.js new file mode 100644 index 000000000..21af17c75 --- /dev/null +++ b/frontend/src/theme.js @@ -0,0 +1,22 @@ +import { createMuiTheme } from '@material-ui/core/styles'; +import { red } from '@material-ui/core/colors'; + +// Create a theme instance. +const theme = createMuiTheme({ + palette: { + primary: { + main: '#556cd6', + }, + secondary: { + main: '#19857b', + }, + error: { + main: red.A400, + }, + background: { + default: '#fff', + }, + }, +}); + +export default theme;