Bootstrap 4-alpha card & react sample

Bootstrap 4-alpha card & react sample

by Masaki Moriwaki

HTML

<link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://fb.me/react-with-addons-0.14.0.js"></script>
<script src="https://fb.me/react-dom-0.14.0.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<br />

<div class="container">
    <div class="row">
        <div id="card-1" class="col-xs-6"></div>
        <div id="card-2" class="col-xs-6"></div>
        <div id="card-3" class="col-xs-6"></div>
    </div>
</div>

CSS

.card img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    opacity: 0;
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
    -webkit-transition: opacity 1s linear;
    -moz-transition: opacity 1s linear;
    -o-transition: opacity 1s linear;
    transition: opacity 1s linear;
}

.card img.selected {
    opacity: 1;
}

.card img.previous {
    position: static;
}

JavaScript 1.7

var Card = React.createClass({
    getInitialState: function () {
        return {
            selected: 0
        };
    },
    animation: function () {
        var selected = (this.state.selected + 1) % this.props.images.length;
        this.setState({
            selected: selected
        });
    },
    handleMouseEnter: function () {
        if (this.state.touch) return;
        this.startAnimation();
    },
    handleMouseLeave: function () {
        if (this.state.touch) return;
        this.stopAnimation();
    },
    handleTouchStart: function (event) {
        event.stopPropagation();
        
        var html = document.documentElement;
        var touch = this.handleOuterTouch.bind(this);
        html.addEventListener('touchstart', touch, false);
        this.setState({touch: touch});
        
        this.startAnimation();
    },
    handleOuterTouch: function () {
        var html = document.documentElement;
        html.removeEventListener('touchstart', this.state.touch, false);
        this.setProps({touch: null});
        
        this.stopAnimation();
    },
    startAnimation: function () {
        if (this.state.timeout) return;
        var timeout = setInterval(this.animation.bind(this), 2000);
        var selected = (this.state.selected + 1) % this.props.images.length;
        this.setState({
            timeout: timeout,
            selected: selected
        });
    },
    stopAnimation: function () {
        clearInterval(this.state.timeout);
        this.setState({
            timeout: null
        });
    },
    render: function () {
        return (
            <div ref="card" className="card" tabIndex="0" onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onTouchStart={this.handleTouchStart} onBlur={this.handleBlur}>
                <img src={this.props.images[this.state.selected]} className="previous" />
                {this.props.images.map(function (image, i) {
                    var className =...