JSFiddle - React, Tailwind, and code Playground
by James MacAulay
HTML
<script src="http://fb.me/react-with-addons-0.9.0.js"></script>
<script src="http://fb.me/JSXTransformer-0.9.0.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore.js"></script>
<script src="http://s3.amazonaws.com/es6-promises/promise-0.1.1.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/bacon.js/0.7.8/bacon.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="https://s3.amazonaws.com/jamesmacaulay.code/react-bacon/0.0.3/react-bacon.js"></script>
<div id="content"></div>
<script src="http://fb.me/react-js-fiddle-integration.js"></script>
CSS
body {
font-family: Helvetica;
padding: 20px;
}
.avatar {
float: right;
}
.avatar img {
width: 50px;
}
JavaScript 1.7
/** @jsx React.DOM */
var BaconMixin = ReactBacon.BaconMixin;
var GitHub = {
get: function(url) {
var response = Promise.resolve($.ajax(url, {dataType: 'jsonp'}));
return response.then(function(data) {
if (data.meta && data.meta.status !== 200) {
throw new Error(data.data.message);
}
return data.data;
});
},
getUser: function(username) {
return GitHub.get("https://api.github.com/users/"+username);
},
getGists: function(username) {
return GitHub.get("https://api.github.com/users/"+username+"/gists");
}
};
var GitHubWidget = React.createClass({
getInitialState: function() {
return {username: ""};
},
handleUsernameChange: function(username) {
this.setState({username: username});
},
render: function() {
return (
<div>
<Avatar username={this.state.username} />
<UsernameInput handleChange={this.handleUsernameChange} />
<GistList username={this.state.username} />
</div>
);
}
});
var Avatar = React.createClass({
mixins: [BaconMixin],
propTypes: {
username: React.PropTypes.string.isRequired
},
getInitialState: function() {
return {user: null};
},
componentWillMount: function() {
var users = this.propsProperty('username').flatMapLatest(
_.compose(Bacon.fromPromise, GitHub.getUser)
).mapError(null);
this.plug(users, 'user');
},
render: function() {
if (this.state.user) {
return (
<div className="avatar">
<a href={this.state.user.html_url}><img src={this.state.user.avatar_url} /></a>
</div>
);
} else {
return <div className="avatar" />;
}
}
})
var UsernameInput = React.createClass({
mixins: [BaconMixin],
propTypes: {
handleChange: React.PropTypes.func.isRequired
},
sendUsername: function(username) {
this.props.handleChange(username);
},
componentWillMount: function() {
this.eventStream('inputChanged').
...