Skip to content

Commit

Permalink
[examples] Add a Gatsby example
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Jan 7, 2018
1 parent 964535a commit aebf477
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 2 deletions.
2 changes: 2 additions & 0 deletions examples/gatsby/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/public/
/.cache/
21 changes: 21 additions & 0 deletions examples/gatsby/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Gatsby example

## How to use

Download the example [or clone the repo](https://github.com/mui-org/material-ui):

```bash
curl https://codeload.github.com/mui-org/material-ui/tar.gz/v1-beta | tar -xz --strip=2 material-ui-1-beta/examples/nextjs
cd nextjs
```

Install it and run:

```bash
npm install
npm run develop
```

## The idea behind the example

[Gatsby](https://github.com/gatsbyjs/gatsby) is a static site generator for React.
6 changes: 6 additions & 0 deletions examples/gatsby/gatsby-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
siteMetadata: {
title: 'Gatsby Default Starter',
},
plugins: ['gatsby-plugin-with-styles'],
};
18 changes: 18 additions & 0 deletions examples/gatsby/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "gatsby",
"version": "1.0.0",
"private": true,
"dependencies": {
"gatsby": "latest",
"jss": "latest",
"material-ui": "next",
"prop-types": "latest",
"react": "latest",
"react-dom": "latest",
"react-jss": "latest"
},
"scripts": {
"develop": "gatsby develop",
"build": "gatsby build"
}
}
32 changes: 32 additions & 0 deletions examples/gatsby/plugins/gatsby-plugin-with-styles/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable react/no-danger */

import React from 'react';
import { renderToString } from 'react-dom/server';
import { JssProvider } from 'react-jss';
import getPageContext from '../../src/getPageContext';

exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString, setHeadComponents }) => {
// Get the context of the page to collected side effects.
const pageContext = getPageContext();

const bodyHTML = renderToString(
<JssProvider
registry={pageContext.sheetsRegistry}
generateClassName={pageContext.generateClassName}
>
{React.cloneElement(bodyComponent, {
pageContext,
})}
</JssProvider>,
);

replaceBodyHTMLString(bodyHTML);
setHeadComponents([
<style
type="text/css"
id="server-side-jss"
key="server-side-jss"
dangerouslySetInnerHTML={{ __html: pageContext.sheetsRegistry.toString() }}
/>,
]);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
42 changes: 42 additions & 0 deletions examples/gatsby/src/getPageContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable no-underscore-dangle */

import { SheetsRegistry } from 'jss';
import { createMuiTheme, createGenerateClassName } from 'material-ui/styles';
import purple from 'material-ui/colors/purple';
import green from 'material-ui/colors/green';

// A theme with custom primary and secondary color.
// It's optional.
const theme = createMuiTheme({
palette: {
primary: purple,
secondary: green,
},
});

function createPageContext() {
return {
theme,
// This is needed in order to deduplicate the injection of CSS in the page.
sheetsManager: new Map(),
// This is needed in order to inject the critical CSS.
sheetsRegistry: new SheetsRegistry(),
// The standard class name generator.
generateClassName: createGenerateClassName(),
};
}

export default function getPageContext() {
// Make sure to create a new context for every server-side request so that data
// isn't shared between connections (which would be bad).
if (!process.browser) {
return createPageContext();
}

// Reuse context on the client-side.
if (!global.__INIT_MATERIAL_UI__) {
global.__INIT_MATERIAL_UI__ = createPageContext();
}

return global.__INIT_MATERIAL_UI__;
}
73 changes: 73 additions & 0 deletions examples/gatsby/src/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';
import PropTypes from 'prop-types';
import Button from 'material-ui/Button';
import Dialog, {
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
} from 'material-ui/Dialog';
import Typography from 'material-ui/Typography';
import { withStyles } from 'material-ui/styles';
import withRoot from '../withRoot';

const styles = theme => ({
root: {
textAlign: 'center',
paddingTop: theme.spacing.unit * 20,
},
});

class Index extends React.Component {
state = {
open: false,
};

handleClose = () => {
this.setState({
open: false,
});
};

handleClick = () => {
this.setState({
open: true,
});
};

render() {
const { classes } = this.props;
const { open } = this.state;

return (
<div className={classes.root}>
<Dialog open={open} onClose={this.handleClose}>
<DialogTitle>Super Secret Password</DialogTitle>
<DialogContent>
<DialogContentText>1-2-3-4-5</DialogContentText>
</DialogContent>
<DialogActions>
<Button color="primary" onClick={this.handleClose}>
OK
</Button>
</DialogActions>
</Dialog>
<Typography type="display1" gutterBottom>
Material-UI
</Typography>
<Typography type="subheading" gutterBottom>
example project
</Typography>
<Button raised color="accent" onClick={this.handleClick}>
Super Secret Password
</Button>
</div>
);
}
}

Index.propTypes = {
classes: PropTypes.object.isRequired,
};

export default withRoot(withStyles(styles)(Index));
45 changes: 45 additions & 0 deletions examples/gatsby/src/withRoot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import PropTypes from 'prop-types';
import { MuiThemeProvider } from 'material-ui/styles';
import Reboot from 'material-ui/Reboot';
import getPageContext from './getPageContext';

function withRoot(Component) {
class WithRoot extends React.Component {
componentWillMount() {
this.pageContext = this.props.pageContext || getPageContext();
}

componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles && jssStyles.parentNode) {
jssStyles.parentNode.removeChild(jssStyles);
}
}

pageContext = null;

render() {
// MuiThemeProvider makes the theme available down the React tree thanks to React context.
return (
<MuiThemeProvider
theme={this.pageContext.theme}
sheetsManager={this.pageContext.sheetsManager}
>
{/* Reboot kickstart an elegant, consistent, and simple baseline to build upon. */}
<Reboot />
<Component {...this.props} />
</MuiThemeProvider>
);
}
}

WithRoot.propTypes = {
pageContext: PropTypes.object,
};

return WithRoot;
}

export default withRoot;
2 changes: 0 additions & 2 deletions examples/nextjs/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/mui-org/material-ui/tree/v1-beta/examples/nextjs)

# Next.js example

## How to use
Expand Down

0 comments on commit aebf477

Please sign in to comment.