Components

Modal

Stability experimental

Depends None

This works like a simplified, React-native version of Bootstrap's modal.

var ButtonWithDialog = React.createClass({ mixins: [LayeredComponentMixin], render: function() { return <button onClick={this.handleClick}> Click Me! </button>; }, renderLayer: function() { if (this.state.clicked) { return <Modal onClose={this.handleClose}> <div className="modal-header"> Header <a href="javascript: void 0;" style={{float: "right", textDecoration: "none"}} onClick={this.handleClose}> × </a> </div> <div className="modal-body">Body!</div> </Modal>; } else { return <div />; } }, // {{{ handleClose: function() { this.setState({ clicked: false }); }, handleClick: function() { this.setState({ clicked: !this.state.clicked }); }, getInitialState: function() { return { clicked: false }; } // }}} }); return <ButtonWithDialog />;

Button Group

Stability unstable

Depends Underscore

A nice looking replacement for a related set of buttons (like radio buttons).

var Options = React.createClass({ render: function() { var labelStyle = { color: this.state.value, padding: '0 10px' }; return <div> <ButtonGroup value={this.state.value} buttons={[ {value: 'red', content: 'red'}, {value: 'green', content: 'green'}, {value: 'blue', content: 'blue'} ]} onChange={this.handleChange} /> <span style={labelStyle}>Your useful text</span> </div>; }, getInitialState: function() { return { value: 'red' }; }, handleChange: function(value) { this.setState({ value }); } }); return <Options />;

Multi Button Group

Stability unstable

Depends Underscore

Like Button Group, but with multi-select (like checkboxes).

var Options = React.createClass({ render: function() { // {{{ // Returns a small, colored div var paint = function (color) { var style = { backgroundColor: color, border: (color === 'white') ? '1px solid' : null, height: 15, width: 15, display: 'inline-block' }; return <div style={style} />; }; var outerStyle = { padding: '0 10px', display: 'inline-block' }; // }}} return <div> Mixing Colors: <div style={outerStyle}> <MultiButtonGroup values={this.state.values} buttons={[ {value: 'red', content: paint('red')}, {value: 'green', content: paint('green')}, {value: 'blue', content: paint('blue')} ]} onChange={this.handleChange} /> </div> {paint(this.mixColors(this.state.values))} </div>; }, getInitialState: function() { return { values: ['red', 'blue'] }; }, // {{{ mixColors: function(colors) { var containsRed = colors.indexOf('red') > -1; var containsBlue = colors.indexOf('blue') > -1; var containsGreen = colors.indexOf('green') > -1; if (containsRed && containsGreen && containsBlue) { return 'white'; } else if (containsRed && containsGreen) { return 'yellow'; } else if (containsRed && containsBlue) { return 'purple'; } else if (containsGreen && containsBlue) { return 'cyan'; } else if (colors.length > 0) { return colors[0]; } return 'black'; }, // }}} handleChange: function(values) { this.setState({ values }); } }); return <Options />;

$_

Stability unstable

Depends Underscore

A pseudo-component useful for internationalization.

var translated = <$_ first="Motoko" last="Kusanagi"> Hello, %(first)s %(last)s! </$_>; var link = <a href="javascript:void 0;" onClick={this._markTooHard}> <$_>Click here</$_> </a>; return <span> <$_ clickHere={link}> We noticed you had a little trouble with this task. %(clickHere)s to hide it until later. </$_> </span>;

Layered Component Mixin

Stability unstable

Depends None

Render another component in a div appended to the page.

var ButtonWithDialog = React.createClass({ mixins: [LayeredComponentMixin], render: function() { return <button onClick={this.handleClick}> Click Me! </button>; }, renderLayer: function() { if (this.state.clicked) { return <Modal onClose={this.handleClose}> <div className="modal-header"> Header <a href="javascript: void 0;" style={{float: "right", textDecoration: "none"}} onClick={this.handleClose}> × </a> </div> <div className="modal-body">Body!</div> </Modal>; } else { return <div />; } }, // {{{ handleClose: function() { this.setState({ clicked: false }); }, handleClick: function() { this.setState({ clicked: !this.state.clicked }); }, getInitialState: function() { return { clicked: false }; } // }}} }); return <ButtonWithDialog />;

Set Interval Mixin

Stability unstable

Depends None

Like setInterval that calls clearInterval for you.

var RefreshingComponent = React.createClass({ mixins: [SetIntervalMixin], componentDidMount: function() { this.setInterval(this.updateState, 1000); }, render: function() { return <div>{this.state.time} seconds</div>; }, // {{{ getInitialState: function() { return { time: 0 }; }, updateState: function() { var time = this.state.time + 1; this.setState({ time }); } // }}} }); return <RefreshingComponent />;

State-from-Store Mixin

Stability unstable

Depends FluxUnderscore

Wires change listeners to get updates from a flux store.

return <div> example needed! </div>;

TimeAgo

Stability unstable

Depends moment

Human friendly display of how long it's been since an event happened.

// {{{ var FormatCommentBody = React.createClass({ render: function() { return <div> {this.props.body} </div>; } }); var UserBadge = React.createClass({ render: function() { return <div>@{this.props.user}</div>; } }); // }}} var Comment = React.createClass({ render: function() { return <div> <FormatCommentBody body={this.props.body} /> <div> <UserBadge user={this.props.user} /> - <TimeAgo time={this.props.date} /> </div> </div>; } }); return <Comment body="such time" user="dinojoel" date={new Date()} />;

Blur Input

Stability unstable

Depends None

An input component that notifies its parent of changes when it loses focus.

// {{{ TODO(joel) - numericalParse var URLInput = React.createClass({ render: function() { // {{{ var imgStyle = { paddingTop: 15, display: 'block', margin: 'auto', maxWidth: '100%' }; // }}} return <div> Image URL: <BlurInput value={this.state.url} onChange={this.handleChange} /> <img style={imgStyle} src={this.state.url} /> </div>; }, handleChange: function(url) { this.setState({ url }); }, getInitialState: function() { return { url: this.props.initialUrl }; } }); return <URLInput initialUrl={"https://www.kastatic.org/images/khan-logo-vertical-transparent.png"} />;

TeX

Stability unstable

Depends KaTeXMathJax

Easily render LaTeX using MathJax or Khan Academy's fast KaTeX library.

// return <TeX>{"\

abla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} = \\frac{4\\pi}{c}\\vec{\\mathbf{j}}"}</TeX> return <TeX>

abla \cdot E = 4 \pi \rho</TeX>;

Tooltip

Stability unstable

Depends Underscore

A better tooltip.

// {{{ var pStyle = { margin: 0, padding: 10, backgroundColor: "white" }; // }}} return <Tooltip className="class-for-tooltip-contents" horizontalPosition="left" horizontalAlign="left" verticalPosition="bottom" arrowSize={10} borderColor="#ccc" show> <div>reticulating splines!</div> <p style={pStyle}> <a href="http://sims.wikia.com/wiki/Reticulating_splines">meaningless phrase</a> </p> </Tooltip>;

Info-Tip

Stability unstable

Depends Underscore

A very simple informational tooltip that displays on hover.

return <div> reticulating splines <InfoTip><p> <a href="http://sims.wikia.com/wiki/Reticulating_splines">meaningless phrase</a> </p></InfoTip> </div>;

Sortable

Stability unstable

Depends Underscore

Sort a list.

var Sorter = React.createClass({ render: function() { return <Sortable components={this.state.components} onReorder={this.handleReorder} className="sidebar-list" verify={() => true} />; }, // {{{ handleReorder: function(components) { this.setState({ components }); }, getInitialState: function() { return { components: this.props.components }; } // }}} }); // {{{ var components = [ <div draggable={true} key="1">1</div>, <div draggable={true} key="2">2</div>, <div draggable={true} key="3">3</div>, <div draggable={true} key="4">4</div> ]; return <Sorter components={components} />; // }}}

Drag Target

Stability unstable

Depends None

Accept dragged content from the browser or the desktop.

var Target = React.createClass({ render: function() { return <DragTarget onDrop={this.handleDrop}> {this.state.message} </DragTarget>; }, handleDrop: function(event) { this.setState({ message: "delicious. thank you!" }); }, getInitialState: function() { return { message: "I haven't received any drags" }; } }); return <Target />;

Window Drag

Stability experimental

Depends Underscore

Detect drags into and out of the page.

var Indicator = React.createClass({ render: function() { return <WindowDrag> {/* modal? */} <div>WINDOW DRAG!</div> </WindowDrag>; } }); return <Indicator />;

Timeout Transition Group

Stability unstable

Depends jQuery

A wrapper which applies CSS classes to children who are entering or leaving. It is very much like the CSSTransitionGroup provided in the React addons. Unfortunately, CSSTransitionGroup uses the transitionEnd event, which is not fired in a variety of conditions (including the transition not being visible or in another tab). This version of CSSTransitionGroup uses a manually set timeout, instead.

// {{{ var itemStyle = { padding: 10, borderColor: "black", borderWidth: 1, borderStyle: "solid", overflow: "hidden", cursor: "pointer" }; // }}} /** * Already in the stylesheet of the page: * * .demo-enter { * opacity: 0.01; * height: 0px; * padding: 0px 10px !important; * transition: opacity 500ms ease-out, * padding 500ms ease-out, * height 500ms ease-out; * } * .demo-enter.demo-enter-active { * opacity: 1; * height: 16px; * padding: 10px !important; * } * .demo-leave { * opacity: 1; * height: 16px; * transition: opacity 500ms ease-out, * padding 500ms ease-out, * height 500ms ease-out; * } * .demo-leave.demo-leave-active { * opacity: 0; * height: 0px; * padding: 0px 10px !important; * } */ var List = React.createClass({ getInitialState: function() { return { items: [0, 1, 2, 3] }; }, removeThenReadd: function(item) { // {{{ var items = this.state.items.slice(0); var found = false; for(var i = 0; i < items.length; i++) { if (items[i] === item) { items.splice(i, 1); found = true; break; } } this.setState({items: items}, function() { if (found) { setTimeout(function() { var items = this.state.items.slice(0); items.push(item); this.setState({items: items}); }.bind(this), 5000); } }.bind(this)); // }}} }, _makeDiv: function(index) { // {{{ return <div onClick={this.removeThenReadd.bind(null, index)} style={itemStyle} key={index}> {"Item " + index} </div>; // }}} }, render: function() { var items = this.state.items.map(this._makeDiv); return <TimeoutTransitionGroup enterTimeout={500} leaveTimeout={500} transitionName="demo"> {items} </TimeoutTransitionGroup>; } }); return <List />;

Backbone Mixin

Stability deprecated

Update this view every time a backbone model updates:

This mixin is deprecated. We do not recommend using it in production.

var SimpleModel = Backbone.Model.extend({ defaults: { comment: "This is a comment!" } }); var Comment = React.createClass({ mixins: [BackboneMixin], getBackboneModels: function() { return [this.props.model]; }, render: function() { return <div>{this.props.model.get("comment")}</div>; } }); var myModel = new SimpleModel(); return <div> <Comment model={myModel} /> <button onClick={function() {myModel.set("comment", "This is an (edited) comment!");}}> Edit </button> </div>;