Last active
May 12, 2016 21:42
-
-
Save busypeoples/03219349cf662492b536a3383e426ea3 to your computer and use it in GitHub Desktop.
Devcards for React - initial ideas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { render } from 'react-dom'; | |
const DevCards = require('./DevCardsIndex').DevCards; | |
import foobar from './SomeComponent'; | |
import StateBar from './SomeStatefulComponent'; | |
const dc = DevCards(); | |
dc.test('do something', foobar, { name: 'foo', model: 1 }, 'Testdrive. Stateless Yes.foo1'); | |
dc.card(StateBar, { left: 20 }, 'test .stateful component!'); | |
dc.card(foobar, { name: 'foobar', model: 1 }, 'some state...'); | |
dc.card(foobar, { name: 'foobar', model: 2 }, 'some state...'); | |
dc.mount(window.app); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PropTypes, Component } from 'react'; | |
import { createStore, combineReducers } from 'redux'; | |
import { render } from 'react-dom'; | |
let devCardTest = require('./DevCardsTest.js').default; | |
const devCardStyle = { | |
background: '#eee', | |
padding: '20px', | |
marginBottom: '10px' | |
}; | |
class DevCardApp extends Component { | |
render() { | |
const { cards } = this.props; | |
return ( | |
<div> | |
{cards.map((c, index) => { | |
const { Component, props, headline } = c; | |
return ( | |
<div key={`component-${index}`} > | |
<h5>Dev Card {headline? headline : null}</h5> | |
<div style={devCardStyle}> | |
<Component key={`components-${index}`} {...props} /> | |
</div> | |
</div> | |
) | |
})} | |
</div> | |
); | |
} | |
} | |
const TestResult = ({ results }) => { | |
const hasError = results.filter((r) => { | |
return!( typeof r.ok === 'undefined' || r.ok); | |
}); | |
const style = hasError.length > 0? {color: 'red'} : {color: 'green'}; | |
return <div style={style}> | |
{ results.map((r,i) => { | |
return <div key={`component-test-${i}`}>{ r.name }</div> | |
})} | |
</div> | |
}; | |
export function DevCards() { | |
const cards = []; | |
const card = (Component, props, headline) => { | |
cards.push({Component, props, headline}) | |
}; | |
const devTest = devCardTest(function(results) { | |
card(TestResult, { results: results }, 'Testing Component'); | |
mount(window.app); | |
}); | |
const mount = (mountNode) => { | |
return render(<DevCardApp cards={cards}/>, mountNode); | |
} | |
return { | |
card: card, | |
test(headline, Component, props, expected) { | |
devTest(headline, Component, props, expected); | |
}, | |
mount: mount, | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import test from 'tape'; | |
import React from 'react'; | |
import { shallow } from 'enzyme'; | |
function devCardTest(cb) { | |
return function(title, Component, props, expected) { | |
let results = []; | |
const tapeStream = test.createStream({objectMode: true}) | |
const tapeStream1 = test.createStream({objectMode: true}) | |
function callback() { | |
cb(results); | |
results = []; | |
test.getHarness()._results.removeAllListeners() | |
} | |
function addRow(row) { | |
results.push(row); | |
} | |
tapeStream.on('data', addRow); | |
tapeStream1.on('end', callback); | |
test(title, (assert) => { | |
const wrapper = shallow(<Component {...props}/>); | |
assert.equal(wrapper.text(), expected); | |
}); | |
} | |
} | |
export default devCardTest; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Example</title> | |
<style> | |
.inactive { | |
text-decoration: line-through; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let dev = require('./devcards.js'); | |
module.hot.accept('./devcards.js', function() { | |
dev = require('./devcards.js'); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "dev-cards-example", | |
"main": "index.js", | |
"scripts": { | |
"start": "webpack-dev-server --hot", | |
"build": "webpack --config webpack.config.js", | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"dependencies": { | |
"react": "^0.14.8", | |
"react-dom": "^0.14.8", | |
"redux": "^3.5.2" | |
}, | |
"devDependencies": { | |
"babel-core": "^6.7.4", | |
"babel-loader": "^6.2.4", | |
"babel-preset-es2015": "^6.6.0", | |
"babel-preset-react": "^6.5.0", | |
"babel-preset-react-hmre": "^1.1.1", | |
"enzyme": "^2.2.0", | |
"html-webpack-plugin": "^2.16.1", | |
"react-addons-test-utils": "^0.14", | |
"react-hot-loader": "^1.3.0", | |
"tape": "^4.5.1", | |
"webpack": "^1.12", | |
"webpack-dev-server": "^1.14" | |
}, | |
"babel": { | |
"presets": [ | |
"es2015", | |
"react" | |
] | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { PropTypes } from 'react'; | |
const foobar = (props) => ( | |
<div> | |
<h3>Testdrive. Stateless Yes.</h3> | |
<div>{props.name}</div> | |
<div>{props.model}</div> | |
</div> | |
); | |
foobar.propTypes = { | |
name: PropTypes.string.isRequired, | |
model: PropTypes.number.isRequired, | |
}; | |
export default foobar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
export default class SomeStatefulComponent extends Component { | |
constructor(props) { | |
super(props); | |
this.state = {ticked: 0, left: 0}; | |
this.tick = null; | |
} | |
componentDidMount() { | |
this.transition(this.props); | |
} | |
componentWillReceiveProps(nextProps) { | |
//this.transition(nextProps); | |
} | |
transition(nextProps) { | |
// some random and quick transition example... | |
this.tick = setInterval(function() { | |
let ticked = this.state.ticked + 1; | |
let left = this.state.left; | |
if (left < nextProps.left) { | |
left += 1; | |
} else if (nextProps.left < left) { | |
left -= 1; | |
} else { | |
clearInterval(this.tick); | |
} | |
this.setState({ticked: ticked, left: left }); | |
}.bind(this), Math.abs(nextProps.left - this.state.left)/1000); | |
} | |
componentWillUnmount() { | |
clearInterval(this.tick); | |
} | |
render() { | |
const left = this.state.left; | |
return <div> | |
<div style={{ paddingLeft: `${left}px` }}>Some Other Box | |
..</div> | |
</div> | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const path = require('path'); | |
const Webpack = require('webpack'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const PORT = 8080; | |
const ASSETS_PATH = path.resolve(__dirname, 'build'); | |
const NAME = 'index.js'; | |
const SERVER_URL = 'http://localhost:' + PORT; | |
module.exports = { | |
debug: true, | |
devtool: 'eval-source-map', | |
entry: [ | |
'./' + NAME | |
], | |
output: { | |
path: ASSETS_PATH, | |
filename: NAME, | |
publicPath: SERVER_URL + '/', | |
}, | |
module: { | |
loaders: [ | |
{ test: /\.js$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ }, | |
], | |
}, | |
plugins: [ | |
new Webpack.NoErrorsPlugin(), | |
new HtmlWebpackPlugin({ template: './index.html', inject: 'body' }), | |
], | |
devServer: { | |
port: PORT, | |
contentBase: ASSETS_PATH, | |
hot: true, | |
quiet: false, | |
noInfo: false, | |
inline: true, | |
colors: true, | |
historyApiFallback: true | |
}, | |
node: { | |
fs: "empty" | |
}, | |
externals: { | |
"cheerio": "window", | |
"react/addons": true, | |
"react/lib/ExecutionEnvironment": true, | |
"react/lib/ReactContext": true | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment