Skip to content

Commit

Permalink
Allow to provide rich object props to StylesProvider (#27)
Browse files Browse the repository at this point in the history
* chore: squashing commits

feat: Added ability to define custom insertion point

closes #19

feat: added ability to inject style tags at custom point in head

also updated README to explain how it is done

closes #19

fix: add option to specify jss config

closes #19

.gitignore fix

fix: changed config to match stylesProvider props

.gitignore fix

feat: added ability to inject style tags at custom point in head

also updated README to explain how it is done

closes #19

fix: add option to specify jss config

closes #19

.gitignore fix

fix: changed config to match stylesProvider props

* feat: added ability to set custom insertion point

* fix: deleted package-lock (using yarn)

* fix: adding server config, fixing tests and lint

1. fixed unit tests with jest virtual mocking
2. Made sure all quotations use backtick (single ticks for imports)
3. Made sure the style sheet generated with gatsby-ssr.js are passed the same options as the style sheet added by gatsby-browser.js

* fix: fix test, modify conditional in ssr and browser

* fix: remove .cache with gitignore

* docs: fix readme

* docs: README change

* docs: fix readme

* issue: some error is now occuring when running gatsby develop in development-runtime

* continuation

* hupe1980 review
  • Loading branch information
oliviertassinari authored and hupe1980 committed Jun 26, 2019
1 parent 221e1e6 commit 1b5b387
Show file tree
Hide file tree
Showing 17 changed files with 180 additions and 86 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ module.exports = {
},
},
],
}
};
16 changes: 2 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
# gatsby-plugin-material-ui

> A [Gatsby](https://github.com/gatsbyjs/gatsby) plugin for
> [@material-ui/styles](https://github.com/mui-org/material-ui) with
> built-in server-side rendering support.
> A [Gatsby](https://github.com/gatsbyjs/gatsby) plugin for [@material-ui/styles](https://github.com/mui-org/material-ui) with built-in server-side rendering support.
This is the plugin for Material-UI v4. The plugin for v3 can be found [here](https://github.com/hupe1980/gatsby-plugin-material-ui/tree/v1.2.5).

## Install

`npm install --save gatsby-plugin-material-ui @material-ui/styles`

## Documentation

[The documentation](/gatsby-plugin-material-ui/README.md)

## Examples

You can find an official integration example of this plugin [on Material-UI side](https://github.com/mui-org/material-ui/tree/master/examples/gatsby), then you can pick one of the [Page Layout Examples](https://material-ui.com/getting-started/page-layout-examples/).

If you want to save time with a more opinionated solution. You can start with [a premade theme](https://github.com/hupe1980/gatsby-theme-material-ui).
[Read the documentation](/gatsby-plugin-material-ui/README.md).
7 changes: 1 addition & 6 deletions e2e-tests/development-runtime/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ module.exports = {
`gatsby-plugin-top-layout`,
{
resolve: `gatsby-plugin-material-ui`,
// If you want to use styled components you should change the injection order.
options: {
// stylesProvider: {
// injectFirst: true,
// },
pathToStylesProvider: `src/styles-provider-props`,
},
},
// If you want to use styled components you should add the plugin here.
// 'gatsby-plugin-styled-components',
`gatsby-plugin-react-helmet`,
],
siteMetadata: {
Expand Down
6 changes: 3 additions & 3 deletions e2e-tests/development-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"@material-ui/core": "latest",
"@material-ui/styles": "latest",
"gatsby": "latest",
"gatsby-plugin-material-ui": "^2.0.1",
"gatsby-plugin-react-helmet": "latest",
"react": "latest",
"react-dom": "latest",
Expand All @@ -22,12 +21,13 @@
"cy:open": "cypress open",
"cy:run": "cypress run --browser chrome",
"start-server-and-test": "start-server-and-test develop http://localhost:8000 cy:run",
"test": "CYPRESS_SUPPORT=y yarn start-server-and-test "
"test": "cross-env CYPRESS_SUPPORT=y yarn start-server-and-test "
},
"devDependencies": {
"cypress": "^3.3.0",
"cypress-testing-library": "^3.0.1",
"gatsby-cypress": "^0.1.9",
"start-server-and-test": "^1.9.0"
"start-server-and-test": "^1.9.0",
"cross-env": "^5.2.0"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React from "react";
import TopLayout from "./top-layout";

export const onClientEntry = () => {
const head = document.head;
const injectFirstNode = document.createComment(`mui-inject-first`);
head.insertBefore(injectFirstNode, head.firstChild);
};

export const wrapRootElement = ({ element }) => {
return <TopLayout>{element}</TopLayout>;
};
8 changes: 8 additions & 0 deletions e2e-tests/development-runtime/src/styles-provider-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { jssPreset } from "@material-ui/styles";
import { create } from "jss";

const stylesProviderProps = {
jss: create({ ...jssPreset(), insertionPoint: `mui-inject-first` }),
};

export default stylesProviderProps;
7 changes: 1 addition & 6 deletions e2e-tests/production-runtime/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,10 @@ module.exports = {
`gatsby-plugin-top-layout`,
{
resolve: `gatsby-plugin-material-ui`,
// If you want to use styled components you should change the injection order.
options: {
// stylesProvider: {
// injectFirst: true,
// },
pathToStylesProvider: `src/styles-provider-props`,
},
},
// If you want to use styled components you should add the plugin here.
// 'gatsby-plugin-styled-components',
`gatsby-plugin-react-helmet`,
],
siteMetadata: {
Expand Down
6 changes: 3 additions & 3 deletions e2e-tests/production-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
"@material-ui/core": "latest",
"@material-ui/styles": "latest",
"gatsby": "latest",
"gatsby-plugin-material-ui": "^2.0.1",
"gatsby-plugin-react-helmet": "latest",
"react": "latest",
"react-dom": "latest",
"react-helmet": "latest"
"react-helmet": "latest",
"cross-env": "latest"
},
"license": "MIT",
"scripts": {
Expand All @@ -22,7 +22,7 @@
"cy:open": "cypress open",
"cy:run": "cypress run --browser chrome",
"start-server-and-test": "start-server-and-test serve http://localhost:9000 cy:run",
"test": "CYPRESS_SUPPORT=y yarn build && yarn start-server-and-test "
"test": "cross-env CYPRESS_SUPPORT=y yarn build && yarn start-server-and-test "
},
"devDependencies": {
"cypress": "^3.3.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import React from "react";
import TopLayout from "./top-layout";

export const onClientEntry = () => {
const head = document.head;
const injectFirstNode = document.createComment(`mui-inject-first`);
head.insertBefore(injectFirstNode, head.firstChild);
};

export const wrapRootElement = ({ element }) => {
return <TopLayout>{element}</TopLayout>;
};
8 changes: 8 additions & 0 deletions e2e-tests/production-runtime/src/styles-provider-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { jssPreset } from "@material-ui/styles";
import { create } from "jss";

const stylesProviderProps = {
jss: create({ ...jssPreset(), insertionPoint: `mui-inject-first` }),
};

export default stylesProviderProps;
2 changes: 2 additions & 0 deletions gatsby-plugin-material-ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ lib
.DS_Store

/gatsby-browser.js
/gatsby-node.js
/gatsby-ssr.js
/.cache/
83 changes: 63 additions & 20 deletions gatsby-plugin-material-ui/README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,106 @@
# gatsby-plugin-material-ui

> A [Gatsby](https://github.com/gatsbyjs/gatsby) plugin for
> [@material-ui/styles](https://github.com/mui-org/material-ui) with
> built-in server-side rendering support.
> A [Gatsby](https://github.com/gatsbyjs/gatsby) plugin for [@material-ui/styles](https://github.com/mui-org/material-ui) with built-in server-side rendering support.
This is the plugin for Material-UI v4. The plugin for v3 can be found [here](https://github.com/hupe1980/gatsby-plugin-material-ui/tree/v1.2.5).
This is the plugin for Material-UI v4.
The plugin for v3 can be found [here](https://github.com/hupe1980/gatsby-plugin-material-ui/tree/v1.2.5).

## Install

`npm install --save gatsby-plugin-material-ui @material-ui/styles`
```sh
npm install gatsby-plugin-material-ui @material-ui/styles
```

## How to use

Edit `gatsby-config.js`
The default options should be enough to cover the most common use cases.

```js
module.exports = {
plugins: [`gatsby-plugin-material-ui`],
};
```

## Usage with styled-components or else

If using Material-UI together with other styling providers (like styled-components), you should make sure Material-UI styles end up on top of `<head>` (so the other styling providers can overwrite it).

You can leverage the `injectFirst: true` prop the [`StylesProvider`](https://material-ui.com/styles/api/#stylesprovider) component:

```javascript
```js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-material-ui`,
// If you want to use styled components, in conjunction to Material-UI, you should:
// - Change the injection order
// - Add the plugin
options: {
// stylesProvider: {
// injectFirst: true,
// },
stylesProvider: {
injectFirst: true,
},
},
// 'gatsby-plugin-styled-components',
},
`gatsby-plugin-styled-components`,
],
};
```

## Autoprefixing and minification

By default, the plugin adds vendor-specific prefixes and minimizes the server-side CSS. The following options are available for deactivating:
By default, the plugin adds vendor-specific prefixes and minimizes the server-side CSS.
The following options are available for deactivating:

| Option | Default | Description |
| -------------------- | ------- | ------------------------------------ |
| disableAutoprefixing | false | Opt-out Autoprefixing (autoprefixer) |
| disableAutoprefixing | false | Opt-out autoprefixing (autoprefixer) |
| disableMinification | false | Opt-out minification (clean-css) |

```javascript

```js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-material-ui`,
options: {
disableAutoprefixing: false,
disableMinification: false,
},
},
],
};
```

## Advanced

You can use the `pathToStylesProvider` option instead of the `stylesProvider` one to provide rich object props to the [`StylesProvider`](https://material-ui.com/styles/api/#stylesprovider) component.

**gatsby-config.js.js**
```
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-material-ui`,
options: {
// disableAutoprefixing: true,
// disableMinification: true
pathToStylesProvider: `src/styles-provider-props`,
},
},
],
};
```

**src/styles-provider-props.js**
```
import { jssPreset } from "@material-ui/styles";
import { create } from "jss";
const stylesProviderProps = {
jss: create({ ...jssPreset(), insertionPoint: `mui-inject-first` }),
};
export default stylesProviderProps;
```

## Examples

You can find an official integration example of this plugin [on Material-UI side](https://github.com/mui-org/material-ui/tree/master/examples/gatsby), then you can pick one of the [Page Layout Examples](https://material-ui.com/getting-started/page-layout-examples/).

If you want to save time with a more opinionated solution. You can start with [a premade theme](https://github.com/hupe1980/gatsby-theme-material-ui).
If you want to save time with a more opinionated solution. You can start with [a premade theme](https://github.com/hupe1980/gatsby-theme-material-ui).
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { onInitialClientRender } from "../gatsby-browser";

jest.mock(`../.cache/styles-provider-props`, () => null, { virtual: true });

describe(`onInitialClientRender`, () => {
afterAll(() => {
delete process.env.BUILD_STAGE;
Expand Down
17 changes: 11 additions & 6 deletions gatsby-plugin-material-ui/src/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { StylesProvider } from "@material-ui/styles";
import stylesProviderProps from "./.cache/styles-provider-props";

export const onInitialClientRender = () => {
if (process.env.BUILD_STAGE === `develop`) {
Expand All @@ -14,13 +15,17 @@ export const onInitialClientRender = () => {
};

export const wrapRootElement = ({ element }, pluginOptions) => {
if (pluginOptions.stylesProvider) {
return (
<StylesProvider {...pluginOptions.stylesProvider}>
{element}
</StylesProvider>
const stylesProvider = stylesProviderProps || pluginOptions.stylesProvider;

if (!stylesProvider) {
return element;
}

if (stylesProviderProps && pluginOptions.stylesProvider) {
throw new Error(
`You specified both pathToStylesProvider and stylesProvider in gatsby-config.js. Remove one of them.`,
);
}

return element;
return <StylesProvider {...stylesProvider}>{element}</StylesProvider>;
};
31 changes: 31 additions & 0 deletions gatsby-plugin-material-ui/src/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require(`fs`);
const path = require(`path`);
const os = require(`os`);

// Copy and past from https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-typography

exports.onPreBootstrap = ({ store }, pluginOptions) => {
const program = store.getState().program;

let module;
if (pluginOptions.pathToStylesProvider) {
module = `module.exports = require("${
path.isAbsolute(pluginOptions.pathToStylesProvider)
? pluginOptions.pathToStylesProvider
: path.join(program.directory, pluginOptions.pathToStylesProvider)
}")`;
if (os.platform() === `win32`) {
module = module.split(`\\`).join(`\\\\`);
}
} else {
module = null;
}

const dir = `${__dirname}/.cache`;

if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}

fs.writeFileSync(`${dir}/styles-provider-props.js`, module);
};
Loading

0 comments on commit 1b5b387

Please sign in to comment.