From 9354f4b2c3b183c449e3f02d1343d40017e3a95e Mon Sep 17 00:00:00 2001 From: Alex Hisen Date: Sun, 19 Feb 2017 03:45:20 -0800 Subject: [PATCH] Update README.md for PostCSS instead of SASS (#1251) --- README.md | 209 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 136 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 52dd45d8..73278dd3 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ React Toolbox is a set of [React](http://facebook.github.io/react/) components that implement [Google's Material Design specification](https://material.google.com/). It's powered by [CSS Modules](https://github.com/css-modules/css-modules) and harmoniously integrates with your [webpack](http://webpack.github.io/) workflow, although you can use any other module bundler. You can take a tour through our documentation website and try the components live! -**Note:** ⚠️ This source code refers to the [future version](https://github.com/react-toolbox/react-toolbox/blob/dev/ROADMAP.md). To check the source for `1.x` go to `master` branch. We are currently writing a migration guide so you can start working with 2.0-beta.x now! +**Note:** ⚠️ This source code refers to the [future version](https://github.com/react-toolbox/react-toolbox/blob/dev/ROADMAP.md). To check the source for `1.x` go to `master` branch. There is a [migration guide](https://github.com/react-toolbox/react-toolbox/wiki/Migrating-from-version-1.3-to-2.0) so you can start working with 2.0-beta.x now! ## Installation @@ -17,12 +17,41 @@ $ npm install --save react-toolbox ## Prerequisites -React Toolbox uses [CSS Modules](https://github.com/css-modules/css-modules) by default to import stylesheets written in [SASS](http://sass-lang.com/). In case you want to import the components already bundled with CSS, your module bundler should be able to require these SASS modules. +React Toolbox uses [CSS Modules](https://github.com/css-modules/css-modules) by default to import stylesheets written using PostCSS/[cssnext](http://cssnext.io/) features. In case you want to import the components already bundled with CSS, your module bundler should be able to require these PostCSS modules. -Although we recommend [webpack](https://webpack.github.io/), you are free to use whatever module bundler you want as long as it can compile and require SASS files located in your `node_modules`. If you are experiencing require errors, make sure your configuration satisfies this requirement. +Although we recommend [webpack](https://webpack.github.io/), you are free to use whatever module bundler you want as long as it can compile and require PostCSS files located in your `node_modules`. If you are experiencing require errors, make sure your configuration satisfies this requirement. Of course this is a set of React components so you should be familiar with [React](https://facebook.github.io/react/). If want to customize your components via themes, you may want to take a look to [react-css-themr](https://github.com/javivelasco/react-css-themr) which is used by React Toolbox to make components easily themeable. +### Setting up PostCSS+cssnext in Webpack: + +```bash +npm install postcss-loader --save-dev +npm install postcss --save +npm install postcss-cssnext --save +``` + +Configure webpack 1.x loader for .css files to use postcss: +```js + { + test: /\.css$/, + loaders: [ + 'style-loader', + 'css-loader?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss?sourceMap&sourceComments', + ], + }, +``` +Declare plugins to be used by postcss (as part of webpack's config object): +```js + postcss: () => { + return [ + /* eslint-disable global-require */ + require('postcss-cssnext'), + /* eslint-enable global-require */ + ]; + }, +``` + ## Basic usage In this minimal example, we import a `Button` with styles already bundled: @@ -38,7 +67,7 @@ ReactDOM.render( ); ``` -Take into account that any required style will be included in the final CSS so your final would include `Button` styles in this case. It's more convenient to import components this way (or with raw imports) because if you require from the project root, every stylesheet of React Toolbox will be included, even if you don't use it. +Take into account that any required style will be included in the final CSS so your final CSS would include `Button` styles in this case. It's more efficient to import components this way (`from 'react-toolbox/lib/button'`) (or with raw imports) because if you require from the project root (i.e. `from 'react-toolbox'`), every stylesheet of React Toolbox will be included, even if you don't use it. ## Importing components @@ -47,13 +76,13 @@ First let's take a look on how the components are structured in the project. The ``` |- /app_bar |---- AppBar.js - |---- _config.scss + |---- config.css |---- index.js |---- readme.md - |---- theme.scss + |---- theme.css ``` -As you can see in the previous block, each folder includes: a Javascript file for each component/subcomponent; a README with documentation, an index Javascript file that imports and injects styles and dependencies for you, a default theme SASS stylesheet and a configuration partial with configuration variables. Depending on whether you want the styles to be directly bundled or not, you can import components in **two** different ways. +As you can see in the previous block, each folder includes: a Javascript file for each component/subcomponent; a README with documentation, an index Javascript file that imports and injects styles and dependencies for you, a default theme PostCSS/cssnext stylesheet and a config.css with configuration variables (CSS Custom Properties). Depending on whether you want the styles to be directly bundled or not, you can import components in **two** different ways. ### Bundled component @@ -73,14 +102,14 @@ import { AppBar } from 'react-toolbox/lib/app_bar/AppBar.js'; ## Customizing components -Every component accepts a `theme` property intended to provide a [CSS Module import object](https://github.com/css-modules/css-modules) that will be used by the component to assign local classnames to its DOM nodes. Therefore, each one implements a documented **classname API**. So if you want to customize a component, you just need to provide a theme object with the appropriated classname mapping. +Every component accepts a `theme` property intended to provide a [CSS Module import object](https://github.com/css-modules/css-modules) that will be used by the component to assign local classnames to its DOM nodes. Therefore, each one implements a documented **classname API**. So if you want to customize a component, you just need to provide a theme object with the appropriate classname mapping. If the component already has a theme injected, the properties you pass will be merged with the injected theme. In this way, you can **add** classnames to the nodes of a specific component and use them to add or to override styles. For example, if you want to customize the `AppBar` to be purple: ```js import React from 'react'; import { AppBar } from 'react-toolbox/lib/app_bar'; -import theme from './PurpleAppBar.scss'; +import theme from './PurpleAppBar.css'; const PurpleAppBar = (props) => ( @@ -90,97 +119,125 @@ export default PurpleAppBar; ``` -```scss +```css .appBar { background-color: #800080; } ``` -In this case we are **adding** styles to an `AppBar` component that already has some styles injected. It works because the component background by default has the same priority as the one we added. There will be cases where the original rule is more restrictive. For those cases you would need to boost priority using the same restrictions as in the original stylesheet. Feel free to take a look into the original themes or just check the selectors you want to override in DevTools. +In this case we are **adding** styles to a specific instance of an `AppBar` component that already has its default styles injected. It works because the component background by default has the same priority as the one we added. There will be cases where the original rule is more restrictive. For those cases you would need to boost priority using the same restrictions as in the original stylesheet. Feel free to take a look into the default theme.css files or just check the selectors you want to override in DevTools. -If the component has no styles injected, you should provide a theme object implementing the full API. You are free to require the CSS Module you want but take into account that every classname is there for a reason. You can either provide a theme via prop or via context as we will see later. +If the component has no styles injected, you should provide a theme object implementing the full API. You are free to require the CSS Module you want but take into account that every classname is there for a reason. You can either provide a theme via prop or via context as described in the next section. -## Theming +### Customizing all instances of a component type -You can afford theming in multiple ways. First of all, you have to understand that React Toolbox stylesheets are written in SASS and configured using the **config** files we saw earlier. Also you may want to check [colors](https://github.com/react-toolbox/react-toolbox/blob/dev/components/_colors.scss) and [globals](https://github.com/react-toolbox/react-toolbox/blob/dev/components/_globals.scss) files to get an overview on the **variables** you have to override to get the results you want. +Install [react-css-themr](https://github.com/javivelasco/react-css-themr) with `npm install react-css-themr --save` -In most scenarios you can get more customized themes by overriding those variables and compiling stylesheets with them. For example, you can create a `_theme.scss` SASS file: +Create a CSS Module theme style file for each component type, for example for `Button`: -```scss -@import "~react-toolbox/lib/colors"; +```css +# /css/button.css -$color-primary: $palette-blue-500; -$color-primary-dark: $palette-blue-700; -``` - -This file should be prepended to each stylesheet compilation which can be achieved in multiple ways. - -### Using SASS Loader - -If you are using [Webpack](http://webpack.github.io/) as module bundler, you are probably using [sass-loader](https://github.com/jtangelder/sass-loader) as well. What we want to do is to prepend to each SASS file compilation a bunch of variables to override. This can be done with the `data` option. For example: - -```js -sassLoader: { - data: '@import "' + path.resolve(__dirname, 'theme/_theme.scss') + '";' +.button { + text-transform: uppercase; } ``` -In this case we are prepending the theme import to each SASS compilation so the primary color will be changed in every single stylesheet. If you are not using webpack, maybe your loader still has a similar option. Otherwise, don't worry, there are solutions. - -### Using SASS imports and props - -Remember that you can import components without styles and provide those styles using the theme property. For example, a theme for a button customized with the previous theme file would be like: - -```scss -@import "theme.scss"; -@import "~react-toolbox/lib/button/theme"; -``` - -Then, when you use a button, you can inject the appropriate theme: +Create a theme file that imports each component's custom theme style under the special theme key listed in that widgets's documentation, i.e.: ```js -import { Button } from 'react-toolbox/lib/button/Button'; -import buttonTheme from './theme/button.scss'; +# theme.js -const ThemedButton = (props) => ( -