Reacting to touch and animation

Josephine Hall / @jojoconstance

Reppin' Icelab and the ACT

React...

User interfaces, components and state

var Button = React.createClass({
  render: function() {
    if (this.state.disabled){
      //don't display the button
    } else {
      return (
        <div onClick={this._getLocation} className="find-button">
          <span className="find-button__text">Nearby</span>
          <i className="find-button__icon"/>
        </div>
      );
    }
  },
  _getLocation: function() {
    AppDispatcher.trigger("geolocator:request");
    this.setState({
      disabled: true
    });
  }
});

React.renderComponent(
  <Button />
  document.body
);

Can't touch this

(DOM)

JSX block:

<div>
     <TouchPreview previewClassName="link--preview">
         <a href="/foo">
            Hello
        </a>
     </TouchPreview>
 </div>

CSS:

a {
    color: blue;
}

.link--preview a {
    color: red;
    text-decoration: underline;
}
TouchPreview = React.createClass({
//sets the default preview class name if not passed in by this.props
  getDefaultProps: function() {
    return {
      previewClassName: "preview"
    };
  },
  getInitialState: function() {
    return {
      preview: false
    };
  },
  render: function() {
//extend the built in React events to include our behaviour
    var props = _.extend({
      onTouchStart: this._startPreview,
      onMouseOver:  this._startPreview,
      onTouchEnd:   this._endPreview,
      onTouchMove:  this._endPreview,
      onMouseOut:   this._endPreview
    }, this.props);
//set the class property to be our preview class
    props.className = (this.state.preview) ?
    									this.props.previewClassName : "";
//clear out the props so that the class can be different next time
    delete props.previewClassName;
//return a span with all these properties
// set on it, preserving the child elements
    return React.DOM.span(props, this.props.children);
  },
  _startPreview: function(e) {
    this.setState({
      preview: true
    });
  },
  _endPreview: function(e) {
    this.setState({
      preview: false
    });
  }
});

Animating a list that might get re-rendered, say what??

Using it...

_renderResultType: function(type) {
var results = this._renderResults(this.props.latLng, type);
return (
  <AnimationItem key={type+"group"} prefix="result-group">
    <div className="results-list-body__group">
      {results}
    </div>
  </AnimationItem>
  );
}
var AnimationItem = React.createClass({
  componentWillEnter: function(done) {
    this.el = this.getDOMNode();
    this.$el = $(this.el);
    // Before state applied immediately
    this.$el.addClass(this.props.prefix+"-enter-before");
    // Ensure parent class changes propagate in time
    requestAnimationFrame(function() {
      this.$el
        .removeClass(this.props.prefix+"-enter-before")
        .addClass(this.props.prefix+"-enter");

      requestAnimationFrame(function() {
        getComputedStyle(this.el);
        this.$el.addClass(this.props.prefix+"-enter-active");
        Arrival.complete(this.$el, done);
      }.bind(this));
    }.bind(this));
  },
  componentDidEnter: function() {
    this.$el
      .removeClass(this.props.prefix+"-enter")
      .removeClass(this.props.prefix+"-enter-active");
  },
  componentWillLeave: function(done) {
    this.el = this.getDOMNode();
    this.$el = $(this.el);
    // Before state applied immediately
    this.$el.addClass(this.props.prefix+"-leave-before");
    requestAnimationFrame(function() {
      this.$el
        .removeClass(this.props.prefix+"-leave-before")
        .addClass(this.props.prefix+"-leave");
      requestAnimationFrame(function() {
        this.$el.addClass(this.props.prefix+"-leave-active");
        Arrival.complete(this.$el, done);
      }.bind(this));
    }.bind(this));
  },
  componentDidLeave: function() {
    this.$el
      .removeClass(this.props.prefix+"-leave")
      .removeClass(this.props.prefix+"-leave-active");
  },
  render: function() {
    return (
      React.DOM.div(
        {className: "animation-item", key: this.props.key},
        this.props.children
      )
    )
  }
});

TouchPreview component

Animation Item codepen

All due credit for these goes go my esteemed colleague Max (@makenosound), he knows a thing or two