Skip to content

Commit 7d4d33e

Browse files
committed
Fix OverlayTrigger unable to use (newer) contexts
1 parent 3e5771d commit 7d4d33e

File tree

2 files changed

+46
-40
lines changed

2 files changed

+46
-40
lines changed

src/OverlayTrigger.js

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import contains from 'dom-helpers/query/contains';
22
import React, { cloneElement } from 'react';
33
import PropTypes from 'prop-types';
4-
import ReactDOM from 'react-dom';
54
import warning from 'warning';
65

76
import Overlay from './Overlay';
@@ -112,26 +111,12 @@ class OverlayTrigger extends React.Component {
112111
this.handleMouseOut = e =>
113112
this.handleMouseOverOut(this.handleDelayedHide, e, 'toElement');
114113

115-
this._mountNode = null;
116-
117114
this.state = {
118115
show: props.defaultOverlayShown
119116
};
120117
}
121118

122-
componentDidMount() {
123-
this._mountNode = document.createElement('div');
124-
this.renderOverlay();
125-
}
126-
127-
componentDidUpdate() {
128-
this.renderOverlay();
129-
}
130-
131119
componentWillUnmount() {
132-
ReactDOM.unmountComponentAtNode(this._mountNode);
133-
this._mountNode = null;
134-
135120
clearTimeout(this._hoverShowDelay);
136121
clearTimeout(this._hoverHideDelay);
137122
}
@@ -215,31 +200,10 @@ class OverlayTrigger extends React.Component {
215200
this.setState({ show: false });
216201
}
217202

218-
makeOverlay(overlay, props) {
219-
return (
220-
<Overlay
221-
{...props}
222-
show={this.state.show}
223-
onHide={this.handleHide}
224-
target={this}
225-
>
226-
{overlay}
227-
</Overlay>
228-
);
229-
}
230-
231203
show() {
232204
this.setState({ show: true });
233205
}
234206

235-
renderOverlay() {
236-
ReactDOM.unstable_renderSubtreeIntoContainer(
237-
this,
238-
this._overlay,
239-
this._mountNode
240-
);
241-
}
242-
243207
render() {
244208
const {
245209
trigger,
@@ -312,9 +276,19 @@ class OverlayTrigger extends React.Component {
312276
);
313277
}
314278

315-
this._overlay = this.makeOverlay(overlay, props);
316-
317-
return cloneElement(child, triggerProps);
279+
return (
280+
<>
281+
{cloneElement(child, triggerProps)}
282+
<Overlay
283+
{...props}
284+
show={this.state.show}
285+
onHide={this.handleHide}
286+
target={this}
287+
>
288+
{overlay}
289+
</Overlay>
290+
</>
291+
);
318292
}
319293
}
320294

test/OverlayTriggerSpec.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ describe('<OverlayTrigger>', () => {
149149
ReactTestUtils.Simulate.click(overlayTrigger);
150150
});
151151

152-
it('Should forward requested context', () => {
152+
it('Should forward requested legacy context', () => {
153153
const contextTypes = {
154154
key: PropTypes.string
155155
};
@@ -187,6 +187,38 @@ describe('<OverlayTrigger>', () => {
187187
contextSpy.calledWith('value').should.be.true;
188188
});
189189

190+
it('Should mount overlay in current tree to allow access to context', () => {
191+
const Context = React.createContext();
192+
const contextSpy = sinon.spy();
193+
194+
class ContextReader extends React.Component {
195+
static contextType = Context;
196+
197+
render() {
198+
contextSpy(this.context.key);
199+
return <div />;
200+
}
201+
}
202+
203+
class ContextHolder extends React.Component {
204+
render() {
205+
return (
206+
<Context.Provider value={{ key: 'value' }}>
207+
<OverlayTrigger trigger="click" overlay={<ContextReader />}>
208+
<button>button</button>
209+
</OverlayTrigger>
210+
</Context.Provider>
211+
);
212+
}
213+
}
214+
215+
const instance = ReactTestUtils.renderIntoDocument(<ContextHolder />);
216+
const overlayTrigger = ReactDOM.findDOMNode(instance);
217+
ReactTestUtils.Simulate.click(overlayTrigger);
218+
219+
contextSpy.calledWith('value').should.be.true;
220+
});
221+
190222
describe('overlay types', () => {
191223
[
192224
{

0 commit comments

Comments
 (0)