react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / addons / transitions / ReactCSSTransitionGroupChild.js
81155 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @typechecks9* @providesModule ReactCSSTransitionGroupChild10*/1112"use strict";1314var React = require('React');1516var CSSCore = require('CSSCore');17var ReactTransitionEvents = require('ReactTransitionEvents');1819var onlyChild = require('onlyChild');2021// We don't remove the element from the DOM until we receive an animationend or22// transitionend event. If the user screws up and forgets to add an animation23// their node will be stuck in the DOM forever, so we detect if an animation24// does not start and if it doesn't, we just call the end listener immediately.25var TICK = 17;26var NO_EVENT_TIMEOUT = 5000;2728var noEventListener = null;293031if (__DEV__) {32noEventListener = function() {33console.warn(34'transition(): tried to perform an animation without ' +35'an animationend or transitionend event after timeout (' +36NO_EVENT_TIMEOUT + 'ms). You should either disable this ' +37'transition in JS or add a CSS animation/transition.'38);39};40}4142var ReactCSSTransitionGroupChild = React.createClass({43displayName: 'ReactCSSTransitionGroupChild',4445transition: function(animationType, finishCallback) {46var node = this.getDOMNode();47var className = this.props.name + '-' + animationType;48var activeClassName = className + '-active';49var noEventTimeout = null;5051var endListener = function(e) {52if (e && e.target !== node) {53return;54}55if (__DEV__) {56clearTimeout(noEventTimeout);57}5859CSSCore.removeClass(node, className);60CSSCore.removeClass(node, activeClassName);6162ReactTransitionEvents.removeEndEventListener(node, endListener);6364// Usually this optional callback is used for informing an owner of65// a leave animation and telling it to remove the child.66finishCallback && finishCallback();67};6869ReactTransitionEvents.addEndEventListener(node, endListener);7071CSSCore.addClass(node, className);7273// Need to do this to actually trigger a transition.74this.queueClass(activeClassName);7576if (__DEV__) {77noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT);78}79},8081queueClass: function(className) {82this.classNameQueue.push(className);8384if (!this.timeout) {85this.timeout = setTimeout(this.flushClassNameQueue, TICK);86}87},8889flushClassNameQueue: function() {90if (this.isMounted()) {91this.classNameQueue.forEach(92CSSCore.addClass.bind(CSSCore, this.getDOMNode())93);94}95this.classNameQueue.length = 0;96this.timeout = null;97},9899componentWillMount: function() {100this.classNameQueue = [];101},102103componentWillUnmount: function() {104if (this.timeout) {105clearTimeout(this.timeout);106}107},108109componentWillEnter: function(done) {110if (this.props.enter) {111this.transition('enter', done);112} else {113done();114}115},116117componentWillLeave: function(done) {118if (this.props.leave) {119this.transition('leave', done);120} else {121done();122}123},124125render: function() {126return onlyChild(this.props.children);127}128});129130module.exports = ReactCSSTransitionGroupChild;131132133