Ecology allows you to write markdown documentation for React components that includes interactive playground sections and auto-generated propType
specifications.
See the demo app for a complete example:
# Runs the demo component documentation dev-server
# and open it in your default browser.
$ npm run dev && npm run open-demo
- Your component should be created using
React.createClass()
orclass Foo extends React.Component
. - Your component should define
propTypes
in thecreateClass
object literal or as a static property of the class. - Your component may define default props as
getDefaultProps
method (React.createClass()
syntax), or as adefaultProps
static property of the class. - You should add a JSDoc-style comment block for each prop, with a description and optional
@examples
.
// createClass() example
const MyComponent = React.createClass({
propTypes: {
/**
* A test prop
* @examples "Test", "More Test", "Yep"
*/
testProp: React.PropTypes.string
},
render() {
return <div>Sample</div>;
}
});
// class declaration example
// NOTE: Requires `babel-preset-stage-1`
class MyComponent extends React.Component {
static propTypes = {
/**
* A test prop
* @examples "Test", "More Test", "Yep"
*/
testProp: React.PropTypes.string
};
render() {
return <div>Sample</div>;
}
}
Create these files according to the below examples:
docs/docs.jsx
docs/ecology.md
docs/index.html
docs/webpack.config.js
- Create
docs/docs.jsx
// docs.jsx
import React from "react";
import ReactDOM from "react-dom";
import Ecology from "ecology";
import * as docgen from "react-docgen";
import MyComponent from "../src/my-component";
class Docs extends React.Component {
render() {
return (
<div className="demo">
<Ecology
// This loads up your markdown documentation.
overview={require("!!raw!./ecology.md")}
// This loads up your component source so Ecology can inject the `propType` table.
source={docgen.parse(require("!!raw!../src/my-component"))}
// The `scope` prop is used by Component Playground to render live code snippets.
// It needs React, ReactDOM, and your component.
// See https://github.com/FormidableLabs/component-playground#scope
scope={{ React, ReactDOM, MyComponent }}
playgroundtheme="blackboard"
/>
</div>
);
}
}
ReactDOM.render(<Docs/>, document.getElementById("content"));
-
Create
docs/ecology.md
:// ecology.md Interactive Docs for My Component ================================= PlayGround ---------- A `playground` triple-backtick snippet will render your component for you. This is useful for quick interactive component demos without the need to add boilerplate. ```playground <MyComponent /> ``` NoRender Playground ------------------- A `playground_norender` triple-backtick snippet will not do automatic rendering of your component; you have to manually call `ReactDom.render`. Useful for examples of using your component in context. ```playground_norender var App = React.createClass({ render() { return ( <MyComponent /> ); } }) ReactDOM.render(<App/>, mountNode); ``` ## Prop Types Ecology will inject a `propTypes` table at the bottom of your component docs. This is generated from the component `propTypes` definition, and takes into account JSDoc style comments for each `propType`
-
Create
docs/index.html
// index.html
// Minimal example. See `demo/index.html` for an example with fallbacks for older browsers.
<!doctype html>
<html>
<head>
<title>Ecology Demo</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.0.0/codemirror.min.css"/>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.0.0/theme/blackboard.min.css"/>
</head>
<body>
<div id="content"></div>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.0.0/codemirror.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/codemirror/5.0.0/mode/javascript/javascript.min.js"></script>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
- Create
docs/webpack.config.js
// webpack.config.js
module.exports = {
devServer: {
contentBase: __dirname,
noInfo: false
},
output: {
path: __dirname,
filename: "main.js",
publicPath: "/"
},
devtool: "source-map",
entry: {
app: ["./docs/docs.jsx"]
},
resolve: {
extensions: ["", ".js", ".jsx"]
},
module: {
loaders: [
{
test: /\.jsx?$/,
loader: "babel-loader",
query: {
presets: ["es2015", "react"]
},
exclude: /node_modules/
}
]
}
};
- Install dependencies and run
webpack-dev-server
$ npm install -S babel babel-core babel-preset-es2015 babel-preset-react babel-loader raw-loader ecology react react-dom react-docgen webpack webpack-dev-server
$ node_modules/.bin/webpack-dev-server --port 3000 --config docs/webpack.config.js --watch --content-base docs
- Overview - Markdown documentation file in raw/string format
- Source - React class source file in parsed
react-docgen
format - Scope - Scope for
component-playground
components. Used by Component Playground to render live code snippets. It needs React, ReactDOM, and your component.
- customRenderers - Pass an object with custom marked renderer methods. ex
link: function(href, title, text) {return href}
. A list of available elements is available here. Note: Method must return a string. - exportGist - Adds a button to export the playground source as an anonymous Gist on Github. Enabling this adds a
Toolbar
component to the markup, with aButton-GistExport
component andToolbar-Message
area for displaying error messages. - copyToClipboard - Adds a button to copy the playground source to the clipboard. Enabling this adds a
Toolbar
component to the markup, with aButton-Clipboard
component.
Help us write this documentation! FormidableLabs#20
Please see DEVELOPMENT
Please see CONTRIBUTING