Skip to content

Commit d272389

Browse files
committed
[added] Overlay and OverlayTrigger accept Transition callbacks
Fixes react-bootstrap#1036
1 parent 99e8cc1 commit d272389

File tree

3 files changed

+92
-14
lines changed

3 files changed

+92
-14
lines changed

src/Overlay.js

+43-2
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,20 @@ class Overlay extends React.Component {
5757
);
5858

5959
if (Transition) {
60+
let { onExit, onExiting, onEnter, onEntering, onEntered } = props;
61+
6062
// This animates the child node by injecting props, so it must precede
6163
// anything that adds a wrapping div.
6264
child = (
6365
<Transition
6466
in={props.show}
6567
transitionAppear
68+
onExit={onExit}
69+
onExiting={onExiting}
6670
onExited={this.onHiddenListener}
71+
onEnter={onEnter}
72+
onEntering={onEntering}
73+
onEntered={onEntered}
6774
>
6875
{child}
6976
</Transition>
@@ -91,8 +98,12 @@ class Overlay extends React.Component {
9198
);
9299
}
93100

94-
handleHidden() {
101+
handleHidden(...args) {
95102
this.setState({exited: true});
103+
104+
if (this.props.onExited) {
105+
this.props.onExited(...args);
106+
}
96107
}
97108
}
98109

@@ -118,7 +129,37 @@ Overlay.propTypes = {
118129
animation: React.PropTypes.oneOfType([
119130
React.PropTypes.bool,
120131
CustomPropTypes.elementType
121-
])
132+
]),
133+
134+
/**
135+
* Callback fired before the Overlay transitions in
136+
*/
137+
onEnter: React.PropTypes.func,
138+
139+
/**
140+
* Callback fired as the Overlay begins to transition in
141+
*/
142+
onEntering: React.PropTypes.func,
143+
144+
/**
145+
* Callback fired after the Overlay finishes transitioning in
146+
*/
147+
onEntered: React.PropTypes.func,
148+
149+
/**
150+
* Callback fired right before the Overlay transitions out
151+
*/
152+
onExit: React.PropTypes.func,
153+
154+
/**
155+
* Callback fired as the Overlay begins to transition out
156+
*/
157+
onExiting: React.PropTypes.func,
158+
159+
/**
160+
* Callback fired after the Overlay finishes transitioning out
161+
*/
162+
onExited: React.PropTypes.func
122163
};
123164

124165
Overlay.defaultProps = {

src/OverlayTrigger.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import createChainedFunction from './utils/createChainedFunction';
55
import createContextWrapper from './utils/createContextWrapper';
66
import Overlay from './Overlay';
77
import warning from 'react/lib/warning';
8-
8+
import pick from 'lodash/object/pick';
99
/**
1010
* Check if value one is inside or equal to the of value
1111
*
@@ -146,24 +146,26 @@ const OverlayTrigger = React.createClass({
146146
},
147147

148148
getOverlay() {
149-
let props = {
150-
show: this.state.isOverlayShown,
151-
onHide: this.hide,
152-
rootClose: this.props.rootClose,
153-
animation: this.props.animation,
149+
let overlayProps = {
150+
...pick(this.props, Object.keys(Overlay.propTypes)),
151+
show: this.state.isOverlayShown,
152+
onHide: this.hide,
154153
target: this.getOverlayTarget,
155-
placement: this.props.placement,
156-
container: this.props.container,
157-
containerPadding: this.props.containerPadding
154+
onExit: this.props.onExit,
155+
onExiting: this.props.onExiting,
156+
onExited: this.props.onExited,
157+
onEnter: this.props.onEnter,
158+
onEntering: this.props.onEntering,
159+
onEntered: this.props.onEntered
158160
};
159161

160162
let overlay = cloneElement(this.props.overlay, {
161-
placement: props.placement,
162-
container: props.container
163+
placement: overlayProps.placement,
164+
container: overlayProps.container
163165
});
164166

165167
return (
166-
<Overlay {...props}>
168+
<Overlay {...overlayProps}>
167169
{ overlay }
168170
</Overlay>
169171
);

test/OverlayTriggerSpec.js

+35
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,41 @@ describe('OverlayTrigger', function() {
3939
instance.state.isOverlayShown.should.be.true;
4040
});
4141

42+
it('Should pass transition callbacks to Transition', function (done) {
43+
let count = 0;
44+
let increment = ()=> count++;
45+
46+
let overlayTrigger;
47+
48+
let instance = ReactTestUtils.renderIntoDocument(
49+
<OverlayTrigger
50+
trigger='click'
51+
overlay={<div>test</div>}
52+
onHide={()=>{}}
53+
onExit={increment}
54+
onExiting={increment}
55+
onExited={()=> {
56+
increment();
57+
expect(count).to.equal(6);
58+
done();
59+
}}
60+
onEnter={increment}
61+
onEntering={increment}
62+
onEntered={()=> {
63+
increment();
64+
ReactTestUtils.Simulate.click(overlayTrigger);
65+
}}
66+
>
67+
<button>button</button>
68+
</OverlayTrigger>
69+
);
70+
71+
overlayTrigger = React.findDOMNode(instance);
72+
73+
ReactTestUtils.Simulate.click(overlayTrigger);
74+
});
75+
76+
4277
it('Should forward requested context', function() {
4378
const contextTypes = {
4479
key: React.PropTypes.string

0 commit comments

Comments
 (0)