Created
May 8, 2016 21:45
-
-
Save busypeoples/8b44732ba9b9fcbcf32aac12def32b2b 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, { PropTypes, Component } from 'react'; | |
import { createStore, combineReducers } from 'redux'; | |
import { render } from 'react-dom'; | |
import foobar from './SomeComponent'; | |
import StateBar from './SomeStatefulComponent'; | |
const devCardStyle = { | |
background: '#eee', | |
padding: '20px', | |
marginBottom: '10px' | |
}; | |
// state handling.... | |
const initialState = []; | |
const cards = (state = initialState, action) => { | |
switch (action.type) { | |
case 'ADD': | |
return [...state, action.payload]; | |
case 'UPDATE': | |
return state; | |
default: return state; | |
} | |
}; | |
const rootReducer = combineReducers({ cards }); | |
const store = createStore(rootReducer, ({ cards: []})); | |
function devCard(Component, state, headline) { | |
store.dispatch( { type: 'ADD', payload: {type: 'card', Component, state, headline}} ); | |
} | |
// not implemented... | |
function devMarkDown(text, headline) { | |
store.dispatch( { type: 'ADD', payload: {type: 'text', state: text, headline} } ); | |
} | |
class App extends Component { | |
render() { | |
return <Render {...this.props} /> | |
} | |
} | |
class Render extends Component { | |
constructor(props) { | |
super(props); | |
const { cards } = this.props; | |
this.state = { cards }; | |
} | |
shouldComponentUpdate(nextProps, nextState) { | |
// for testing purposes... | |
return true; | |
} | |
componentWillReceiveProps(nextProps) { | |
} | |
render() { | |
const { cards } = this.props; | |
return ( | |
<div> | |
{cards.map((c, index) => { | |
const { type, Component, state, headline } = c; | |
if (type === 'card') { | |
return <div key={index}> | |
<h5>Dev Card {headline? headline : null}</h5> | |
<div style={devCardStyle}> | |
<Component {...state} /> | |
</div> | |
</div> | |
} else { | |
return <div key={index}> | |
<div style={devCardStyle}> | |
<div>{ state }</div> | |
</div> | |
</div> | |
} | |
})} | |
</div> | |
); | |
} | |
} | |
store.subscribe(() => { | |
render(<App {...store.getState()} />, window.app); | |
}); | |
devCard(StateBar, {left: 150}, 'test a stateful component!'); | |
devCard(foobar, { name: 'foobar!', model: 30 }, 'some state...'); | |
devMarkDown(` | |
#A Headline | |
##A subtitle. | |
Some text... | |
`); |
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": { | |
"dev": "webpack-dev-server --hot", | |
"start": "webpack --progress --colors --watch", | |
"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-preset-es2015": "^6.6.0", | |
"babel-preset-react": "^6.5.0", | |
"react-hot-loader": "^1.3.0", | |
"webpack": "^1.12.14", | |
"webpack-dev-server": "^1.14.1" | |
}, | |
"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 ASSETS_PATH = path.resolve(__dirname, 'build'); | |
const NAME = 'index.js'; | |
const PORT = 8080; | |
const SERVER_URL = 'http://localhost:' + PORT; | |
module.exports = { | |
debug: true, | |
devtool: 'eval-source-map', | |
entry: [ | |
'./' + NAME | |
], | |
output: { | |
path: ASSETS_PATH, | |
publicPath: 'build', | |
filename: NAME, | |
}, | |
module: { | |
loaders: [ | |
{ test: /\.js$/, loaders: ['react-hot', 'babel'], exclude: /node_modules/ }, | |
{ test: /\.css$/, loader: 'css?minimize' }, | |
{ test: /\.less$/, loader: 'css?sourceMap&localIdentName=[name]__[local]!postcss!less?sourceMap' }, | |
{ test: /\.(woff|woff2|ttf|eot|svg)(\?]?.*)?$/, loader: 'url-loader?limit=8192' }, | |
{ test: /\.(gif|jpg|jpeg|png)(\?]?.*)?$/, loader: 'url-loader?limit=1024' }, | |
{ test: /\.json$/, loader: 'json', exclude: /node_modules/ }, | |
], | |
}, | |
plugins: [ | |
new Webpack.NoErrorsPlugin() | |
], | |
devServer: { | |
port: 8080, | |
contentBase: "./", | |
hot: true, | |
quiet: false, | |
noInfo: false, | |
inline: true, | |
colors: true, | |
historyApiFallback: true | |
}, | |
babel: { | |
presets: ['react', 'es2015'] | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment