commit d87f9f589bfd14cfce37f3cb84605c59a65a1188
parent 5b00b0a8d03ac8d489e5e3dffb58405c9c450bce
Author: Konstantin Tarkus <koistya@gmail.com>
Date: Tue, 8 Dec 2015 02:47:59 +0300
Merge pull request #335 from koistya/style-guide
Update the style guide
Diffstat:
3 files changed, 113 insertions(+), 98 deletions(-)
diff --git a/README.md b/README.md
@@ -12,20 +12,13 @@
> Helping you to stay productive following the best practices. A solid starting
> point for both professionals and newcomers to the industry.
-Demo: http://demo.reactstarterkit.com |
-Join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom on Gitter to stay up to date.
+See [demo](http://demo.reactstarterkit.com) |
+[docs](https://github.com/kriasoft/react-starter-kit/tree/master/docs) |
+[bugs & feature requests](https://waffle.io/kriasoft/react-starter-kit) |
+join [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) chatroom to stay up to date
-### Documentation
-
- * **General**
- - [React Style Guide](./docs/react-style-guide.md)
- - [How to configure text editors and IDEs](./docs/how-to-configure-text-editors.md)
- * **Questions**
- - [Which module bundler should I use?](https://github.com/kriasoft/react-starter-kit/issues/3)
- - [Which Flux implementation should I use?](https://github.com/kriasoft/react-starter-kit/issues/22)
- * **Recipes**
- - [How to Implement Routing and Navigation](./docs/recipes/how-to-implement-routing.md)
- - [How to Integrate Disqus](./docs/recipes/how-to-integrate-disqus.md)
+[](https://rollbar.com/?utm_source=reactstartkit(github)&utm_medium=link&utm_campaign=reactstartkit(github))
+[](https://localizejs.com/)
### Directory Layout
@@ -126,11 +119,6 @@ $ npm test
Test any javascript module by creating a `__tests__/` directory where
the file is. Append `-test.js` to the filename and [Jest](https://facebook.github.io/jest/) will do the rest.
-### Our Sponsors
-
-[](https://rollbar.com/?utm_source=reactstartkit(github)&utm_medium=link&utm_campaign=reactstartkit(github))
-[](http://www.makersacademy.com/?utm_source=ReactStarterKit&utm_medium=link&utm_campaign=ReactStarterKitGithub)
-
### Related Projects
* [React Static Boilerplate](https://github.com/koistya/react-static-boilerplate) — Generates static websites from React components
@@ -152,8 +140,8 @@ the file is. Append `-test.js` to the filename and [Jest](https://facebook.githu
### Support
* [#react-starter-kit](https://gitter.im/kriasoft/react-starter-kit) on Gitter — Feedback, feature requests, Q&A
- * [@koistya](https://www.codementor.io/koistya) on Codementor — Mentorship, code reviews
- * support@kriasoft.com — Customization requests, help with GraphQL/Relay back-ends etc.
+ * [@koistya](https://www.codementor.io/koistya) on Codementor — Mentorship, pair coding, code reviews
+ * support@kriasoft.com — Customization requests, help with GraphQL/Relay, database design etc.
### License
diff --git a/docs/README.md b/docs/README.md
@@ -0,0 +1,16 @@
+## Documentation
+
+### General
+
+* [React Style Guide](./react-style-guide.md)
+* [How to configure text editors and IDEs](./how-to-configure-text-editors.md)
+
+### Questions
+
+* [Which module bundler should I use?](https://github.com/kriasoft/react-starter-kit/issues/3)
+* [Which Flux implementation should I use?](https://github.com/kriasoft/react-starter-kit/issues/22)
+
+### Recipes
+
+* [How to Implement Routing and Navigation](./docs/recipes/how-to-implement-routing.md)
+* [How to Integrate Disqus](./docs/recipes/how-to-integrate-disqus.md)
diff --git a/docs/react-style-guide.md b/docs/react-style-guide.md
@@ -1,45 +1,82 @@
## React Style Guide
-### Core Principles
+> This style guide comes as an addition to [Airbnb React/JSX Guide](https://github.com/airbnb/javascript/tree/master/react).
+> Feel free to modify it to suite your project's needs.
-- Place each component in a separate folder
-- Avoid having shared resources between components (CSS, images etc.)
-- Avoid deeply nested folder structures
-- Prefer using class selectors in CSS (see [BEM](https://bem.info/))
-- Avoid nested CSS selectors (see [BEM](https://bem.info/))
-- Keep CSS simple and declarative, avoid loops, mixins etc.
+### Table of Contents
-##### File structure per component example:
+* [Separate folder per UI component](#separate-folder-per-ui-component)
+* [Prefer using functional components](#prefer-using-functional-components)
+* [Use CSS Modules](#use-css-modules)
+* [Use higher-order components](#use-higher-order-components)
+
+### Separate folder per UI component
+
+* Place each major UI component along with its resources in a separate folder<br>
+ This will make it easier to find related resources for any particular UI
+ element (CSS, images, unit tests, localization files etc.). Removing such
+ components during refactorings should also be easy.
+* Avoid having CSS, images and other resource files shared between multiple components.<br>
+ This will make your code more maintainable, easy to refactor.
+* Add `package.json` file into each component's folder.<br>
+ This will allow to easily reference such components from other places in
+ your code.<br>
+ `import Nav from '../Nav'` vs `import Nav from '../Nav/Nav.js'`
+
+```
+/components/Navigation/icon.svg
+/components/Navigation/Navigation.css
+/components/Navigation/Navigation.js
+/components/Navigation/Navigation.test.js
+/components/Navigation/Navigation.ru-RU.css
+/components/Navigation/package.json
+```
```
-/src/components/Navigation/icon.svg
-/src/components/Navigation/Navigation.css
-/src/components/Navigation/Navigation.js
-/src/components/Navigation/Navigation.test.js
-/src/components/Navigation/Navigation.ru-RU.css
-/src/components/Navigation/package.json
+// components/Navigation/package.json
+{
+ "name:": "Navigation",
+ "main": "./Navigation.js"
+}
```
For more information google for [component-based UI development](https://google.com/search?q=component-based+ui+development).
-##### CSS styling example:
+### Prefer using functional components
+
+* Prefer using stateless functional components whenever possible.<br>
+ Components that don't use state are better to be written as simple pure functions.
```jsx
-// JSX
-<nav className={cx(s.root, this.props.className)}>
- <ul className={s.items}>
- <li className={cx(s.item, s.selected)}>
- <a className={s.link} href="/products">Products</a>
- </li>
- <li className={s.item}>
- <a className={s.link} href="/services">Services</a>
- </li>
- </ul>
-</nav>
+// Bad
+class Navigation extends Component {
+ static propTypes = { items: PropTypes.array.isRequired };
+ render() {
+ return <nav><ul>{this.props.items.map(x => <li>{x.text}</li>}</ul></nav>;
+ }
+}
+
+// Better
+function Navigation({ items }) {
+ return (
+ <nav><ul>{items.map(x => <li>{x.text}</li>}</ul></nav>;
+ );
+}
+Navigation.propTypes = { items: PropTypes.array.isRequired };
```
+### Use CSS Modules
+
+* Use CSS Modules<br>
+ This will allow using short CSS class names and at the same time avoid conflicts.
+* Keep CSS simple and declarative. Avoid loops, mixins etc.
+* Feel free to use variables in CSS via [precss](https://github.com/jonathantneal/precss) plugin for [PostCSS](https://github.com/postcss/postcss)
+* Prefer CSS class selectors instead of element and `id` selectors (see [BEM](https://bem.info/))
+* Avoid nested CSS selectors (see [BEM](https://bem.info/))
+* When in doubt, use `.root { }` class name for the root elements of your components
+
```scss
-// CSS
+// Navigation.scss
@import '../variables.scss';
.root {
@@ -80,64 +117,36 @@ For more information google for [component-based UI development](https://google.
}
```
-### React Components
-
-- Use [Babel](https://babeljs.io/docs/learn-es6/) transpiler for your source code
-- Use [ES6 classes](https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#es6-classes) for creating new React components
-- Use higher-order components to extend the functionality of existing components
-
-##### React component example:
-
-```js
-import React, { Component, PropTypes } from 'react';
-import cx from 'classnames';
-import s from './SampleComponent.css';
+```jsx
+// Navigation.js
+import React, { PropTypes } from 'react';
+import s from './Navigation.scss';
import withStyles from '../../decorators/withStyles';
-@withStyles(s)
-class SampleComponent extends Component {
-
- static propTypes = { ... };
-
- static defaultProps = { ... };
-
- state = { ... };
-
- constructor() {
- super();
- // componentWillMount handler
- }
-
- componentDidMount() {
- // ...
- }
-
- componentWillUnmount() {
- // ...
- }
-
- shouldComponentUpdate() {
- // ...
- }
-
- handleClick = (event) => { ... };
-
- render() {
- return (
- <div className={cx(s.root, this.props.className)} onClick={this.handleClick}>
- ...
- </div>
- );
- }
-
+function Navigation() {
+ return (
+ <nav className={[s.root, this.props.className]}>
+ <ul className={s.items}>
+ <li className={[s.item, s.selected]}>
+ <a className={s.link} href="/products">Products</a>
+ </li>
+ <li className={s.item}>
+ <a className={s.link} href="/services">Services</a>
+ </li>
+ </ul>
+ </nav>
+ );
}
-export default SampleComponent;
+Navigation.propTypes = { className: PropTypes.string };
+
+export default withStyles(s)(Navigation);
```
-Put custom methods and properties between React API methods and the `render()` method at the bottom.
+### Use higher-order components
-##### Higher-order React component example:
+* Use higher-order components (HOC) to extend existing Rect components.<br>
+ Here is an example:
```js
// withViewport.js
@@ -196,3 +205,5 @@ class MyComponent {
export default MyComponent;
```
+
+**[⬆ back to top](#table-of-contents)**