TweetBox (Mobx + React)
by ramnathv
HTML
<script src="https://npmcdn.com/[email protected]/lib/mobx.umd.js"></script>
<script src="https://npmcdn.com/[email protected]/index.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div class="container" id="main">
<div class="row">
<div class="col-xs-12 col-md-6">
<div id="app"></div>
</div>
</div>
</div>
CSS
#main{margin-top: 20px;}
.list-group-item{
border-radius: 0px !important;
}
.form-control{
border-radius: 0px !important;
}
.constraint .edit,
.constraint .delete{
visibility: hidden;
}
.constraint:hover .edit,
.constraint:hover .delete{
visibility: visible;
}
.constraint{
}
.tweet-editor{
resize: vertical;
}
.tweet-actions{
margin-top: 10px;
}
Babel + JSX
const {observable, computed, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
const {render} = ReactDOM
class Store {
@observable tweetText = ""
@observable photoAdded = false
@computed get remainingChars(){
return 140 - this.tweetText.length - 23*this.photoAdded
}
@computed get disableTweetButton(){
return this.tweetText.length === 0
}
@computed get photoButtonText(){
return this.photoAdded ? 'Photo Added' : 'Add Photo'
}
togglePhotoAdded(){
this.photoAdded = !this.photoAdded
}
}
const TweetAlert = observer(({store}) => {
if (store.remainingChars >= 0) return(null)
return(
<div className="alert alert-warning" role="alert">
Oops! Too Long
</div>
)
})
const TweetEditor = observer(({store}) => {
return(
<textarea
rows="5"
className="form-control tweet-editor"
defaultValue={store.tweetText}
onChange={(e) => store.tweetText = e.target.value}
/>
)
})
const TweetActions = observer(({store}) => {
console.log(store.disableTweetButton)
return(
<div className="tweet-actions">
<span className="pull-left">
{store.remainingChars}
</span>
<span className="pull-right">
<div className="btn-group">
<button
className="btn btn-sm btn-default"
onClick = {store.togglePhotoAdded.bind(store)}
>
{store.photoButtonText}
</button>
<button
className="btn btn-sm btn-primary"
disabled={store.disableTweetButton}
>
Tweet
</button>
</div>
</span>
</div>
)
})
const App = observer(({store}) => {
return(
<div className="well clearfix">
<h3>TweetBox</h3>
<TweetAlert store={store}/>
<TweetEditor store={store}/>
<TweetActions store={store} />
</div>
)
})
const myStore = new Store();
render(
<App store={myStore} />,
...