diff --git a/src/Overlay.js b/src/Overlay.js
index 6d82a7f401..6debd6f9e7 100644
--- a/src/Overlay.js
+++ b/src/Overlay.js
@@ -57,13 +57,20 @@ class Overlay extends React.Component {
);
if (Transition) {
+ let { onExit, onExiting, onEnter, onEntering, onEntered } = props;
+
// This animates the child node by injecting props, so it must precede
// anything that adds a wrapping div.
child = (
{child}
@@ -91,8 +98,12 @@ class Overlay extends React.Component {
);
}
- handleHidden() {
+ handleHidden(...args) {
this.setState({exited: true});
+
+ if (this.props.onExited) {
+ this.props.onExited(...args);
+ }
}
}
@@ -118,7 +129,37 @@ Overlay.propTypes = {
animation: React.PropTypes.oneOfType([
React.PropTypes.bool,
CustomPropTypes.elementType
- ])
+ ]),
+
+ /**
+ * Callback fired before the Overlay transitions in
+ */
+ onEnter: React.PropTypes.func,
+
+ /**
+ * Callback fired as the Overlay begins to transition in
+ */
+ onEntering: React.PropTypes.func,
+
+ /**
+ * Callback fired after the Overlay finishes transitioning in
+ */
+ onEntered: React.PropTypes.func,
+
+ /**
+ * Callback fired right before the Overlay transitions out
+ */
+ onExit: React.PropTypes.func,
+
+ /**
+ * Callback fired as the Overlay begins to transition out
+ */
+ onExiting: React.PropTypes.func,
+
+ /**
+ * Callback fired after the Overlay finishes transitioning out
+ */
+ onExited: React.PropTypes.func
};
Overlay.defaultProps = {
diff --git a/src/OverlayTrigger.js b/src/OverlayTrigger.js
index 783e3b4ee8..1c980b1a68 100644
--- a/src/OverlayTrigger.js
+++ b/src/OverlayTrigger.js
@@ -5,7 +5,7 @@ import createChainedFunction from './utils/createChainedFunction';
import createContextWrapper from './utils/createContextWrapper';
import Overlay from './Overlay';
import warning from 'react/lib/warning';
-
+import pick from 'lodash/object/pick';
/**
* Check if value one is inside or equal to the of value
*
@@ -146,24 +146,26 @@ const OverlayTrigger = React.createClass({
},
getOverlay() {
- let props = {
- show: this.state.isOverlayShown,
- onHide: this.hide,
- rootClose: this.props.rootClose,
- animation: this.props.animation,
+ let overlayProps = {
+ ...pick(this.props, Object.keys(Overlay.propTypes)),
+ show: this.state.isOverlayShown,
+ onHide: this.hide,
target: this.getOverlayTarget,
- placement: this.props.placement,
- container: this.props.container,
- containerPadding: this.props.containerPadding
+ onExit: this.props.onExit,
+ onExiting: this.props.onExiting,
+ onExited: this.props.onExited,
+ onEnter: this.props.onEnter,
+ onEntering: this.props.onEntering,
+ onEntered: this.props.onEntered
};
let overlay = cloneElement(this.props.overlay, {
- placement: props.placement,
- container: props.container
+ placement: overlayProps.placement,
+ container: overlayProps.container
});
return (
-
+
{ overlay }
);
diff --git a/test/OverlayTriggerSpec.js b/test/OverlayTriggerSpec.js
index 768ad20c7c..637f59d2ba 100644
--- a/test/OverlayTriggerSpec.js
+++ b/test/OverlayTriggerSpec.js
@@ -39,6 +39,41 @@ describe('OverlayTrigger', function() {
instance.state.isOverlayShown.should.be.true;
});
+ it('Should pass transition callbacks to Transition', function (done) {
+ let count = 0;
+ let increment = ()=> count++;
+
+ let overlayTrigger;
+
+ let instance = ReactTestUtils.renderIntoDocument(
+ test}
+ onHide={()=>{}}
+ onExit={increment}
+ onExiting={increment}
+ onExited={()=> {
+ increment();
+ expect(count).to.equal(6);
+ done();
+ }}
+ onEnter={increment}
+ onEntering={increment}
+ onEntered={()=> {
+ increment();
+ ReactTestUtils.Simulate.click(overlayTrigger);
+ }}
+ >
+
+
+ );
+
+ overlayTrigger = React.findDOMNode(instance);
+
+ ReactTestUtils.Simulate.click(overlayTrigger);
+ });
+
+
it('Should forward requested context', function() {
const contextTypes = {
key: React.PropTypes.string