Skip to content

Instantly share code, notes, and snippets.

@petebrowne
Created October 3, 2014 21:05
Show Gist options
  • Save petebrowne/9f17072c3472b21435f5 to your computer and use it in GitHub Desktop.
Save petebrowne/9f17072c3472b21435f5 to your computer and use it in GitHub Desktop.
ReactCSSTransitionGroup Events
React = require('react')
ReactTransitionGroup = require('react/lib/ReactTransitionGroup')
CSSTransitionGroupChild = require('./CSSTransitionGroupChild.cjsx')
CSSTransitionGroup = React.createClass
displayName: 'CSSTransitionGroup'
propTypes:
transitionName: React.PropTypes.string.isRequired
transitionEnter: React.PropTypes.bool
transitionLeave: React.PropTypes.bool
onEnterStart: React.PropTypes.func
onEnterEnd: React.PropTypes.func
onLeaveStart: React.PropTypes.func
onLeaveEnd: React.PropTypes.func
getDefaultProps: ->
{
transitionEnter: true
transitionLeave: true
}
_wrapChild: (child) ->
CSSTransitionGroupChild(
{
name: @props.transitionName
enter: @props.transitionEnter
leave: @props.transitionLeave
onEnterStart: @props.onEnterStart
onEnterEnd: @props.onEnterEnd
onLeaveStart: @props.onLeaveStart
onLeaveEnd: @props.onLeaveEnd
},
child
)
render: ->
@transferPropsTo(
ReactTransitionGroup({childFactory: @_wrapChild}, @props.children)
)
module.exports = CSSTransitionGroup
React = require('react')
CSSCore = require('react/lib/CSSCore')
ReactChildren = require('react/lib/ReactChildren')
ReactTransitionEvents = require('react/lib/ReactTransitionEvents')
onlyChild = require('react/lib/onlyChild')
TICK = 17
NO_EVENT_TIMEOUT = 5000
noEventListener = null
if process.env.NODE_ENV isnt 'production'
noEventListener = ->
console.warn(
"transition(): tried to perform an animation without " +
"an animationend or transitionend event after timeout " +
"(#{NO_EVENT_TIMEOUT}ms). You should either disable this " +
"transition in JS or add a CSS animation/transition."
)
return
CSSTransitionGroupChild = React.createClass
displayName: 'CSSTransitionGroupChild'
propTypes:
onEnterStart: React.PropTypes.func
onEnterEnd: React.PropTypes.func
onLeaveStart: React.PropTypes.func
onLeaveEnd: React.PropTypes.func
transition: (animationType, finishCallback) ->
node = @getDOMNode()
className = "#{@props.name}-#{animationType}"
activeClassName = "#{className}-active"
noEventTimeout = null
endListener = ->
clearTimeout(noEventTimeout) if process.env.NODE_ENV isnt 'production'
CSSCore.removeClass(node, className)
CSSCore.removeClass(node, activeClassName)
ReactTransitionEvents.removeEndEventListener(node, endListener)
finishCallback?()
return
ReactTransitionEvents.addEndEventListener(node, endListener)
CSSCore.addClass(node, className)
# Need to do this to actually trigger a transition.
@queueClass(activeClassName)
if process.env.NODE_ENV isnt 'production'
noEventTimeout = setTimeout(noEventListener, NO_EVENT_TIMEOUT)
return
queueClass: (className) ->
@classNameQueue.push(className)
@timeout = setTimeout(@flushClassNameQueue, TICK) unless @timeout
flushClassNameQueue: ->
@classNameQueue.forEach(
CSSCore.addClass.bind(CSSCore, @getDOMNode())
) if @isMounted()
@classNameQueue.length = 0
@timeout = null
componentWillMount: ->
@classNameQueue = []
componentWillUnmount: ->
clearTimeout(@timeout) if @timeout
componentWillEnter: (done) ->
@props.onEnterStart?()
if @props.enter
@transition('enter', done)
else
done()
componentDidEnter: ->
@props.onEnterEnd?()
componentWillLeave: (done) ->
@props.onLeaveStart?()
if @props.leave
@transition('leave', done)
else
done()
componentDidLeave: ->
@props.onLeaveEnd?()
render: ->
onlyChild(@props.children)
module.exports = CSSTransitionGroupChild
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment