UNPKG

10.1 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime-corejs2/helpers/interopRequireWildcard");
4
5var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
6
7exports.__esModule = true;
8exports.default = void 0;
9
10var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/objectWithoutPropertiesLoose"));
11
12var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inheritsLoose"));
13
14var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/assertThisInitialized"));
15
16var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/extends"));
17
18var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
19
20var _contains = _interopRequireDefault(require("dom-helpers/query/contains"));
21
22var _react = _interopRequireWildcard(require("react"));
23
24var _propTypes = _interopRequireDefault(require("prop-types"));
25
26var _reactDom = _interopRequireDefault(require("react-dom"));
27
28var _warning = _interopRequireDefault(require("warning"));
29
30var _Overlay = _interopRequireDefault(require("./Overlay"));
31
32var _createChainedFunction = _interopRequireDefault(require("./utils/createChainedFunction"));
33
34/**
35 * Check if value one is inside or equal to the of value
36 *
37 * @param {string} one
38 * @param {string|array} of
39 * @returns {boolean}
40 */
41function isOneOf(one, of) {
42 if ((0, _isArray.default)(of)) {
43 return of.indexOf(one) >= 0;
44 }
45
46 return one === of;
47}
48
49var triggerType = _propTypes.default.oneOf(['click', 'hover', 'focus']);
50
51var propTypes = (0, _extends2.default)({}, _Overlay.default.propTypes, {
52 /**
53 * Specify which action or actions trigger Overlay visibility
54 */
55 trigger: _propTypes.default.oneOfType([triggerType, _propTypes.default.arrayOf(triggerType)]),
56
57 /**
58 * A millisecond delay amount to show and hide the Overlay once triggered
59 */
60 delay: _propTypes.default.number,
61
62 /**
63 * A millisecond delay amount before showing the Overlay once triggered.
64 */
65 delayShow: _propTypes.default.number,
66
67 /**
68 * A millisecond delay amount before hiding the Overlay once triggered.
69 */
70 delayHide: _propTypes.default.number,
71 // FIXME: This should be `defaultShow`.
72
73 /**
74 * The initial visibility state of the Overlay. For more nuanced visibility
75 * control, consider using the Overlay component directly.
76 */
77 defaultOverlayShown: _propTypes.default.bool,
78
79 /**
80 * An element or text to overlay next to the target.
81 */
82 overlay: _propTypes.default.node.isRequired,
83
84 /**
85 * @private
86 */
87 onBlur: _propTypes.default.func,
88
89 /**
90 * @private
91 */
92 onClick: _propTypes.default.func,
93
94 /**
95 * @private
96 */
97 onFocus: _propTypes.default.func,
98
99 /**
100 * @private
101 */
102 onMouseOut: _propTypes.default.func,
103
104 /**
105 * @private
106 */
107 onMouseOver: _propTypes.default.func,
108 // Overridden props from `<Overlay>`.
109
110 /**
111 * @private
112 */
113 target: _propTypes.default.oneOf([null]),
114
115 /**
116 * @private
117 */
118 onHide: _propTypes.default.oneOf([null]),
119
120 /**
121 * @private
122 */
123 show: _propTypes.default.oneOf([null])
124});
125var defaultProps = {
126 defaultOverlayShown: false,
127 trigger: ['hover', 'focus']
128};
129
130var OverlayTrigger =
131/*#__PURE__*/
132function (_React$Component) {
133 (0, _inheritsLoose2.default)(OverlayTrigger, _React$Component);
134
135 function OverlayTrigger(props, context) {
136 var _this;
137
138 _this = _React$Component.call(this, props, context) || this;
139 _this.handleToggle = _this.handleToggle.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
140 _this.handleDelayedShow = _this.handleDelayedShow.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
141 _this.handleDelayedHide = _this.handleDelayedHide.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
142 _this.handleHide = _this.handleHide.bind((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)));
143
144 _this.handleMouseOver = function (e) {
145 return _this.handleMouseOverOut(_this.handleDelayedShow, e, 'fromElement');
146 };
147
148 _this.handleMouseOut = function (e) {
149 return _this.handleMouseOverOut(_this.handleDelayedHide, e, 'toElement');
150 };
151
152 _this._mountNode = null;
153 _this.state = {
154 show: props.defaultOverlayShown
155 };
156 return _this;
157 }
158
159 var _proto = OverlayTrigger.prototype;
160
161 _proto.componentDidMount = function componentDidMount() {
162 this._mountNode = document.createElement('div');
163 this.renderOverlay();
164 };
165
166 _proto.componentDidUpdate = function componentDidUpdate() {
167 this.renderOverlay();
168 };
169
170 _proto.componentWillUnmount = function componentWillUnmount() {
171 _reactDom.default.unmountComponentAtNode(this._mountNode);
172
173 this._mountNode = null;
174 clearTimeout(this._hoverShowDelay);
175 clearTimeout(this._hoverHideDelay);
176 };
177
178 _proto.handleDelayedHide = function handleDelayedHide() {
179 var _this2 = this;
180
181 if (this._hoverShowDelay != null) {
182 clearTimeout(this._hoverShowDelay);
183 this._hoverShowDelay = null;
184 return;
185 }
186
187 if (!this.state.show || this._hoverHideDelay != null) {
188 return;
189 }
190
191 var delay = this.props.delayHide != null ? this.props.delayHide : this.props.delay;
192
193 if (!delay) {
194 this.hide();
195 return;
196 }
197
198 this._hoverHideDelay = setTimeout(function () {
199 _this2._hoverHideDelay = null;
200
201 _this2.hide();
202 }, delay);
203 };
204
205 _proto.handleDelayedShow = function handleDelayedShow() {
206 var _this3 = this;
207
208 if (this._hoverHideDelay != null) {
209 clearTimeout(this._hoverHideDelay);
210 this._hoverHideDelay = null;
211 return;
212 }
213
214 if (this.state.show || this._hoverShowDelay != null) {
215 return;
216 }
217
218 var delay = this.props.delayShow != null ? this.props.delayShow : this.props.delay;
219
220 if (!delay) {
221 this.show();
222 return;
223 }
224
225 this._hoverShowDelay = setTimeout(function () {
226 _this3._hoverShowDelay = null;
227
228 _this3.show();
229 }, delay);
230 };
231
232 _proto.handleHide = function handleHide() {
233 this.hide();
234 }; // Simple implementation of mouseEnter and mouseLeave.
235 // React's built version is broken: https://github.com/facebook/react/issues/4251
236 // for cases when the trigger is disabled and mouseOut/Over can cause flicker
237 // moving from one child element to another.
238
239
240 _proto.handleMouseOverOut = function handleMouseOverOut(handler, e, relatedNative) {
241 var target = e.currentTarget;
242 var related = e.relatedTarget || e.nativeEvent[relatedNative];
243
244 if ((!related || related !== target) && !(0, _contains.default)(target, related)) {
245 handler(e);
246 }
247 };
248
249 _proto.handleToggle = function handleToggle() {
250 if (this.state.show) {
251 this.hide();
252 } else {
253 this.show();
254 }
255 };
256
257 _proto.hide = function hide() {
258 this.setState({
259 show: false
260 });
261 };
262
263 _proto.makeOverlay = function makeOverlay(overlay, props) {
264 return _react.default.createElement(_Overlay.default, (0, _extends2.default)({}, props, {
265 show: this.state.show,
266 onHide: this.handleHide,
267 target: this
268 }), overlay);
269 };
270
271 _proto.show = function show() {
272 this.setState({
273 show: true
274 });
275 };
276
277 _proto.renderOverlay = function renderOverlay() {
278 _reactDom.default.unstable_renderSubtreeIntoContainer(this, this._overlay, this._mountNode);
279 };
280
281 _proto.render = function render() {
282 var _this$props = this.props,
283 trigger = _this$props.trigger,
284 overlay = _this$props.overlay,
285 children = _this$props.children,
286 onBlur = _this$props.onBlur,
287 onClick = _this$props.onClick,
288 onFocus = _this$props.onFocus,
289 onMouseOut = _this$props.onMouseOut,
290 onMouseOver = _this$props.onMouseOver,
291 props = (0, _objectWithoutPropertiesLoose2.default)(_this$props, ["trigger", "overlay", "children", "onBlur", "onClick", "onFocus", "onMouseOut", "onMouseOver"]);
292 delete props.delay;
293 delete props.delayShow;
294 delete props.delayHide;
295 delete props.defaultOverlayShown;
296
297 var child = _react.default.Children.only(children);
298
299 var childProps = child.props;
300 var triggerProps = {};
301
302 if (this.state.show) {
303 triggerProps['aria-describedby'] = overlay.props.id;
304 } // FIXME: The logic here for passing through handlers on this component is
305 // inconsistent. We shouldn't be passing any of these props through.
306
307
308 triggerProps.onClick = (0, _createChainedFunction.default)(childProps.onClick, onClick);
309
310 if (isOneOf('click', trigger)) {
311 triggerProps.onClick = (0, _createChainedFunction.default)(triggerProps.onClick, this.handleToggle);
312 }
313
314 if (isOneOf('hover', trigger)) {
315 process.env.NODE_ENV !== "production" ? (0, _warning.default)(!(trigger === 'hover'), '[react-bootstrap] Specifying only the `"hover"` trigger limits the ' + 'visibility of the overlay to just mouse users. Consider also ' + 'including the `"focus"` trigger so that touch and keyboard only ' + 'users can see the overlay as well.') : void 0;
316 triggerProps.onMouseOver = (0, _createChainedFunction.default)(childProps.onMouseOver, onMouseOver, this.handleMouseOver);
317 triggerProps.onMouseOut = (0, _createChainedFunction.default)(childProps.onMouseOut, onMouseOut, this.handleMouseOut);
318 }
319
320 if (isOneOf('focus', trigger)) {
321 triggerProps.onFocus = (0, _createChainedFunction.default)(childProps.onFocus, onFocus, this.handleDelayedShow);
322 triggerProps.onBlur = (0, _createChainedFunction.default)(childProps.onBlur, onBlur, this.handleDelayedHide);
323 }
324
325 this._overlay = this.makeOverlay(overlay, props);
326 return (0, _react.cloneElement)(child, triggerProps);
327 };
328
329 return OverlayTrigger;
330}(_react.default.Component);
331
332OverlayTrigger.propTypes = propTypes;
333OverlayTrigger.defaultProps = defaultProps;
334var _default = OverlayTrigger;
335exports.default = _default;
336module.exports = exports["default"];
\No newline at end of file