commit 976003e9870c4307703266f58c28339f46b4fdc1
parent 6b266ca5b0318d068339769b7c013403aef5a85b
Author: Konstantin Tarkus <hello@tarkus.me>
Date: Fri, 3 Apr 2015 14:54:53 +0300
Add a style guide for creating React components
Diffstat:
3 files changed, 137 insertions(+), 19 deletions(-)
diff --git a/README.md b/README.md
@@ -12,22 +12,8 @@
> it to quickly bootstrap your web application projects. All the parts of this
> project template are easily replaceable.
-[](https://github.com/kriasoft/react-starter-kit)
-
**Demo**: http://reactjs.kriasoft.com
-### Architecture
-
-This project uses the original [Flux](facebook.github.io/flux/) architecture
-utilizing a unidirectional data flow.
-
-<img src="https://github.com/facebook/flux/raw/master/docs/img/flux-diagram-white-background.png" style="width: 100%;" />
-
- * [Flux for Stupid People](http://blog.andrewray.me/flux-for-stupid-people/) by [Andrew Ray](https://github.com/DelvarWorld)
- * [What is Flux?](http://fluxxor.com/what-is-flux.html) by [Brandon Tilley](https://github.com/BinaryMuse/)
- * [Rethinking Web App Development at Facebook](http://www.youtube.com/watch?v=nYkdrAPrdcw) by [Pete Hunt](https://github.com/petehunt)
- * [The State of Flux](https://reactjsnews.com/the-state-of-flux/) by [David Chang](http://davidandsuzi.com/)
-
### Directory Layout
```
@@ -64,6 +50,10 @@ $ npm install -g gulp # Install Gulp task runner globally
$ npm install # Install Node.js components listed in ./package.json
```
+### Documentation
+
+- [React Style Guide](./docs/react-style-guide.md)
+
### How to Build
```shell
diff --git a/docs/FAQ.md b/docs/FAQ.md
@@ -1,4 +0,0 @@
-FAQ
-===
-
-...
-\ No newline at end of file
diff --git a/docs/react-style-guide.md b/docs/react-style-guide.md
@@ -0,0 +1,133 @@
+## React Style Guide
+
+### Folder Structure
+
+- Place each component in a separate folder
+- Avoid having shared resources between components (css, images etc.)
+- Keep all components' folders in the same parent folder (avoid nesting)
+
+A sample file structure per component:
+
+```
+/src/components/Navigation/Navigation.js
+/src/components/Navigation/Navigation-test.js
+/src/components/Navigation/Navigation.less
+/src/components/Navigation/Navigation.ru-RU.less
+/src/components/Navigation/icon.svg
+/src/components/Navigation/package.json
+```
+
+For more information google for [component-based UI development](google.com/search?q=component-based+ui+development).
+
+### CSS Class Names
+
+Use [BEM](https://bem.info/) approach for naming CSS classes.
+
+```css
+.ComponentName { }
+.ComponentName--modifier { }
+.ComponentName-elementName { }
+.ComponentName-elementName--modifier { }
+```
+
+See [SUIT CSS](https://suitcss.github.io/) for inspiration.
+
+### 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
+
+A sample component class:
+
+```js
+'use strict';
+
+import './SampleComponent.less';
+import { Component } from 'react';
+
+class SampleComponent extends Component {
+
+ static propTypes = { ... };
+
+ static defaultProps = { ... };
+
+ constructor() {
+ super();
+ this.state = { ... };
+ }
+
+ componentDidMount() {
+ // ...
+ }
+
+ componentWillUnmount() {
+ // ...
+ }
+
+ shouldComponentUpdate() {
+ // ...
+ }
+
+ render() {
+ return (
+ <div className="SampleComponent">
+ </div>
+ );
+ }
+
+}
+
+export default SampleComponent;
+```
+
+Put custom methods and properties at the bottom of the file, after the render() method.
+
+A sample higher-order component:
+
+```js
+'use strict';
+
+import React, { Component } from 'react';
+import { canUseDOM } from 'react/lib/ExecutionEnvironment';
+
+function setViewport(ComposedComponent) {
+ return class Viewport extends Component {
+
+ constructor() {
+ super();
+
+ this.state = {
+ viewport: canUseDOM ?
+ {width: window.innerWidth, height: window.innerHeight} :
+ {width: 1366, height: 768} // Default size for server-side rendering
+ };
+
+ this.handleResize = () => {
+ let viewport = {width: window.innerWidth, height: window.innerHeight};
+ if (this.state.viewport.width !== viewport.width ||
+ this.state.viewport.height !== viewport.height) {
+ this.setState({viewport: viewport});
+ }
+ };
+ }
+
+ componentDidMount() {
+ window.addEventListener('resize', this.handleResize);
+ window.addEventListener('orientationchange', this.handleResize);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this.handleResize);
+ window.removeEventListener('orientationchange', this.handleResize);
+ }
+
+ render() {
+ return <ComposedComponent {...this.props} viewport={this.state.viewport}/>;
+ }
+
+ };
+};
+
+export default setViewport;
+```