diff --git a/examples/with-material-ui-next/README.md b/examples/with-material-ui-next/README.md new file mode 100644 index 00000000..b821d6a6 --- /dev/null +++ b/examples/with-material-ui-next/README.md @@ -0,0 +1,29 @@ +[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-material-ui-next) +# Material-UI example + +## How to use + +Download the example [or clone the repo](https://github.com/zeit/next.js): + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-material-ui-next +cd with-material-ui-next +``` + +Install it and run: + +```bash +npm install +npm run dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now +``` + +## The idea behind the example + +This example features how you use [material-ui](https://github.com/callemall/material-ui) (Material components that implement Google's Material Design) with Next.js. + diff --git a/examples/with-material-ui-next/components/App.js b/examples/with-material-ui-next/components/App.js new file mode 100644 index 00000000..a7026458 --- /dev/null +++ b/examples/with-material-ui-next/components/App.js @@ -0,0 +1,52 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { withStyles, createStyleSheet, MuiThemeProvider } from 'material-ui/styles' +import { getDefaultContext } from '../styles/createDefaultContext' + +const styleSheet = createStyleSheet('App', theme => ({ + '@global': { + html: { + background: theme.palette.background.default, + fontFamily: theme.typography.fontFamily, + WebkitFontSmoothing: 'antialiased', // Antialiasing. + MozOsxFontSmoothing: 'grayscale' // Antialiasing. + }, + body: { + margin: 0 + }, + a: { + color: 'inherit' + } + } +})) + +let AppWrapper = props => props.children + +AppWrapper = withStyles(styleSheet)(AppWrapper) + +class App extends Component { + componentDidMount () { + // Remove the server-side injected CSS. + const jssStyles = document.querySelector('#jss-server-side') + if (jssStyles && jssStyles.parentNode) { + jssStyles.parentNode.removeChild(jssStyles) + } + } + + render () { + const { styleManager, theme } = getDefaultContext() + return ( + + + {this.props.children} + + + ) + } +} + +App.propTypes = { + children: PropTypes.node.isRequired +} + +export default App diff --git a/examples/with-material-ui-next/package.json b/examples/with-material-ui-next/package.json new file mode 100644 index 00000000..0ad199a5 --- /dev/null +++ b/examples/with-material-ui-next/package.json @@ -0,0 +1,13 @@ +{ + "dependencies": { + "material-ui": "next", + "next": "latest", + "react": "^15.5.4", + "react-dom": "^15.5.4" + }, + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + } +} diff --git a/examples/with-material-ui-next/pages/_document.js b/examples/with-material-ui-next/pages/_document.js new file mode 100644 index 00000000..f4039568 --- /dev/null +++ b/examples/with-material-ui-next/pages/_document.js @@ -0,0 +1,49 @@ +import React from 'react' +import Document, { Head, Main, NextScript } from 'next/document' +import { getDefaultContext, setDefaultContext } from '../styles/createDefaultContext' + +export default class MyDocument extends Document { + static async getInitialProps (ctx) { + setDefaultContext() + const page = ctx.renderPage() + const styleContext = getDefaultContext() + return { + ...page, + styles: ( + + ) + } + } + + render () { + const styleContext = getDefaultContext() + return ( + + + My page + + {/* Use minimum-scale=1 to enable GPU rasterization */} + + {/* PWA primary color */} + + + + +
+ + + + ) + } +} diff --git a/examples/with-material-ui-next/pages/index.js b/examples/with-material-ui-next/pages/index.js new file mode 100644 index 00000000..80c0095a --- /dev/null +++ b/examples/with-material-ui-next/pages/index.js @@ -0,0 +1,64 @@ +import React, {Component} from 'react' +import Button from 'material-ui/Button' +import Dialog, { + DialogTitle, + DialogContent, + DialogContentText, + DialogActions +} from 'material-ui/Dialog' +import Typography from 'material-ui/Typography' +import App from '../components/App' + +const styles = { + container: { + textAlign: 'center', + paddingTop: 200 + } +} + +class Index extends Component { + constructor (props) { + super(props) + + this.state = { + open: false + } + } + + handleRequestClose = () => { + this.setState({ + open: false + }) + }; + + handleClick = () => { + this.setState({ + open: true + }) + }; + + render () { + return ( + +
+ + Super Secret Password + + 1-2-3-4-5 + + + + + + Material-UI + example project + +
+
+ ) + } +} + +export default Index diff --git a/examples/with-material-ui-next/styles/createDefaultContext.js b/examples/with-material-ui-next/styles/createDefaultContext.js new file mode 100644 index 00000000..0755d36a --- /dev/null +++ b/examples/with-material-ui-next/styles/createDefaultContext.js @@ -0,0 +1,38 @@ +import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider' +import createPalette from 'material-ui/styles/palette' +import createMuiTheme from 'material-ui/styles/theme' +import { purple, green } from 'material-ui/styles/colors' + +const createDefaultContext = () => + MuiThemeProvider.createDefaultContext({ + theme: createMuiTheme({ + palette: createPalette({ + primary: purple, + accent: green + }) + }) + }) + +// Singleton hack as there is no way to pass variables from _document.js to pages yet. +let context = null + +export function setDefaultContext () { + context = createDefaultContext() +} + +export function getDefaultContext () { + // Make sure to create a new store for every server-side request so that data + // isn't shared between connections (which would be bad) + if (!process.browser) { + return context + } + + // Reuse store on the client-side + if (!context) { + context = createDefaultContext() + } + + return context +} + +export default createDefaultContext diff --git a/examples/with-material-ui/pages/index.js b/examples/with-material-ui/pages/index.js index e2ffa6d9..3f9a6be5 100644 --- a/examples/with-material-ui/pages/index.js +++ b/examples/with-material-ui/pages/index.js @@ -27,7 +27,7 @@ const muiTheme = { } } -class Main extends Component { +class Index extends Component { static getInitialProps ({ req }) { // Ensures material-ui renders the correct css prefixes server-side let userAgent @@ -86,7 +86,7 @@ class Main extends Component {

example project

@@ -95,4 +95,4 @@ class Main extends Component { } } -export default Main +export default Index