|
1 | 1 | /*eslint-disable react/prop-types */
|
2 | 2 | import React, { cloneElement } from 'react';
|
3 |
| - |
| 3 | +import contains from 'dom-helpers/query/contains'; |
4 | 4 | import createChainedFunction from './utils/createChainedFunction';
|
5 | 5 | import createContextWrapper from './utils/createContextWrapper';
|
6 | 6 | import Overlay from './Overlay';
|
@@ -126,6 +126,11 @@ const OverlayTrigger = React.createClass({
|
126 | 126 | }
|
127 | 127 | },
|
128 | 128 |
|
| 129 | + componentWillMount() { |
| 130 | + this.handleMouseOver = this.handleMouseOverOut.bind(null, this.handleDelayedShow); |
| 131 | + this.handleMouseOut = this.handleMouseOverOut.bind(null, this.handleDelayedHide); |
| 132 | + }, |
| 133 | + |
129 | 134 | componentDidMount(){
|
130 | 135 | this._mountNode = document.createElement('div');
|
131 | 136 | React.render(this._overlay, this._mountNode);
|
@@ -195,8 +200,8 @@ const OverlayTrigger = React.createClass({
|
195 | 200 | '[react-bootstrap] Specifying only the `"hover"` trigger limits the visibilty of the overlay to just mouse users. ' +
|
196 | 201 | 'Consider also including the `"focus"` trigger so that touch and keyboard only users can see the overlay as well.');
|
197 | 202 |
|
198 |
| - props.onMouseOver = createChainedFunction(this.handleDelayedShow, this.props.onMouseOver, triggerProps.onMouseOver); |
199 |
| - props.onMouseOut = createChainedFunction(this.handleDelayedHide, this.props.onMouseOut, triggerProps.onMouseOut); |
| 203 | + props.onMouseOver = createChainedFunction(this.handleMouseOver, this.props.onMouseOver, triggerProps.onMouseOver); |
| 204 | + props.onMouseOut = createChainedFunction(this.handleMouseOut, this.props.onMouseOut, triggerProps.onMouseOut); |
200 | 205 | }
|
201 | 206 |
|
202 | 207 | if (isOneOf('focus', this.props.trigger)) {
|
@@ -250,6 +255,19 @@ const OverlayTrigger = React.createClass({
|
250 | 255 | this._hoverDelay = null;
|
251 | 256 | this.hide();
|
252 | 257 | }, delay);
|
| 258 | + }, |
| 259 | + |
| 260 | + // Simple implementation of mouseEnter and mouseLeave. |
| 261 | + // React's built version is broken: https://github.com/facebook/react/issues/4251 |
| 262 | + // for cases when the trigger is disabled and mouseOut/Over can cause flicker moving |
| 263 | + // from one child element to another. |
| 264 | + handleMouseOverOut(handler, e){ |
| 265 | + let target = e.currentTarget; |
| 266 | + let related = e.relatedTarget || e.nativeEvent.toElement; |
| 267 | + |
| 268 | + if (!related || related !== target && !contains(target, related)){ |
| 269 | + handler(e); |
| 270 | + } |
253 | 271 | }
|
254 | 272 |
|
255 | 273 | });
|
|
0 commit comments