diff --git a/components/ripple/Ripple.js b/components/ripple/Ripple.js index 6f3de37e..382b53cc 100644 --- a/components/ripple/Ripple.js +++ b/components/ripple/Ripple.js @@ -2,6 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import ClassNames from 'classnames'; import style from './style'; +import events from '../utils/events'; import prefixer from '../utils/prefixer'; const defaults = { @@ -23,6 +24,7 @@ const Ripple = (options = {}) => { static propTypes = { children: React.PropTypes.any, disabled: React.PropTypes.bool, + onRippleEnded: React.PropTypes.func, ripple: React.PropTypes.bool, rippleCentered: React.PropTypes.bool, rippleClassName: React.PropTypes.string, @@ -45,6 +47,20 @@ const Ripple = (options = {}) => { width: null }; + componentDidMount () { + if (this.props.onRippleEnded) { + events.addEventListenerOnTransitionEnded(this.refs.ripple, (evt) => { + if (evt.propertyName === 'transform') this.props.onRippleEnded(evt); + }); + } + } + + componentWillUnmount () { + if (this.props.onRippleEnded) { + events.removeEventListenerOnTransitionEnded(this.refs.ripple); + } + } + handleEnd = () => { document.removeEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd); this.setState({active: false}); diff --git a/components/ripple/readme.md b/components/ripple/readme.md index 05c2861f..c9bac5f5 100644 --- a/components/ripple/readme.md +++ b/components/ripple/readme.md @@ -20,8 +20,9 @@ const RippleTest = () => Test; In any component you decorate with the Ripple you'd get some additional props: -| Name | Type | Default | Description| +| Name | Type | Default | Description| |:-----|:-----|:-----|:-----| -| `centered` | `Boolean` | `false` | True in case you want a centered ripple.| -| `className` | `String` | `''` | String to customize appearance (color and opacity for example).| -| `spread` | `Number` | `2` | Factor to indicate how much should the ripple spread under the component.| +| `centered` | `Boolean` | `false` | True in case you want a centered ripple.| +| `className` | `String` | `''` | String to customize appearance (color and opacity for example).| +| `onRippleEnded` | `Function` | | Function that will be called when the ripple animation ends. | +| `spread` | `Number` | `2` | Factor to indicate how much should the ripple spread under the component.| diff --git a/components/utils/events.js b/components/utils/events.js index 47d80551..52d4b8d4 100644 --- a/components/utils/events.js +++ b/components/utils/events.js @@ -37,5 +37,34 @@ export default { node = node.parentNode; } return false; + }, + + addEventListenerOnTransitionEnded (element, fn) { + const eventName = transitionEventNamesFor(element); + if (!eventName) return false; + element.addEventListener(eventName, fn); + return true; + }, + + removeEventListenerOnTransitionEnded (element) { + const eventName = transitionEventNamesFor(element); + if (!eventName) return false; + element.removeEventListener(eventName); + return true; } }; + +const TRANSITIONS = { + 'transition': 'transitionend', + 'OTransition': 'oTransitionEnd', + 'MozTransition': 'transitionend', + 'WebkitTransition': 'webkitTransitionEnd' +}; + +function transitionEventNamesFor (element) { + for (const transition in TRANSITIONS) { + if (element.style[transition] !== undefined) { + return TRANSITIONS[transition]; + } + } +} diff --git a/spec/components/button.js b/spec/components/button.js index 4cf434d9..97a69c07 100644 --- a/spec/components/button.js +++ b/spec/components/button.js @@ -10,7 +10,7 @@ const ButtonTest = () => ( -