import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; /* eslint-disable max-classes-per-file */ import contains from 'dom-helpers/contains'; import React, { cloneElement } from 'react'; import ReactDOM from 'react-dom'; import warning from 'warning'; import Overlay from './Overlay'; var RefHolder = /*#__PURE__*/ function (_React$Component) { _inheritsLoose(RefHolder, _React$Component); function RefHolder() { return _React$Component.apply(this, arguments) || this; } var _proto = RefHolder.prototype; _proto.render = function render() { return this.props.children; }; return RefHolder; }(React.Component); var normalizeDelay = function normalizeDelay(delay) { return delay && typeof delay === 'object' ? delay : { show: delay, hide: delay }; }; var defaultProps = { defaultOverlayShown: false, trigger: ['hover', 'focus'] }; // eslint-disable-next-line react/no-multi-comp var OverlayTrigger = /*#__PURE__*/ function (_React$Component2) { _inheritsLoose(OverlayTrigger, _React$Component2); function OverlayTrigger(props, context) { var _this; _this = _React$Component2.call(this, props, context) || this; _this.getTarget = function () { return ReactDOM.findDOMNode(_this.trigger.current); }; _this.handleShow = function () { clearTimeout(_this._timeout); _this._hoverState = 'show'; var delay = normalizeDelay(_this.props.delay); if (!delay.show) { _this.show(); return; } _this._timeout = setTimeout(function () { if (_this._hoverState === 'show') _this.show(); }, delay.show); }; _this.handleHide = function () { clearTimeout(_this._timeout); _this._hoverState = 'hide'; var delay = normalizeDelay(_this.props.delay); if (!delay.hide) { _this.hide(); return; } _this._timeout = setTimeout(function () { if (_this._hoverState === 'hide') _this.hide(); }, delay.hide); }; _this.handleFocus = function (e) { var _this$getChildProps = _this.getChildProps(), onFocus = _this$getChildProps.onFocus; _this.handleShow(e); if (onFocus) onFocus(e); }; _this.handleBlur = function (e) { var _this$getChildProps2 = _this.getChildProps(), onBlur = _this$getChildProps2.onBlur; _this.handleHide(e); if (onBlur) onBlur(e); }; _this.handleClick = function (e) { var _this$getChildProps3 = _this.getChildProps(), onClick = _this$getChildProps3.onClick; if (_this.state.show) _this.hide();else _this.show(); if (onClick) onClick(e); }; _this.handleMouseOver = function (e) { _this.handleMouseOverOut(_this.handleShow, e, 'fromElement'); }; _this.handleMouseOut = function (e) { return _this.handleMouseOverOut(_this.handleHide, e, 'toElement'); }; _this.trigger = React.createRef(); _this.state = { show: !!props.defaultShow }; // We add aria-describedby in the case where the overlay is a role="tooltip" // for other cases describedby isn't appropriate (e.g. a popover with inputs) so we don't add it. _this.ariaModifier = { enabled: true, order: 900, fn: function fn(data) { var popper = data.instance.popper; var target = _this.getTarget(); if (!_this.state.show || !target) return data; var role = popper.getAttribute('role') || ''; if (popper.id && role.toLowerCase() === 'tooltip') { target.setAttribute('aria-describedby', popper.id); } return data; } }; return _this; } var _proto2 = OverlayTrigger.prototype; _proto2.componentWillUnmount = function componentWillUnmount() { clearTimeout(this._timeout); }; _proto2.getChildProps = function getChildProps() { return React.Children.only(this.props.children).props; }; // Simple implementation of mouseEnter and mouseLeave. // React's built version is broken: https://github.com/facebook/react/issues/4251 // for cases when the trigger is disabled and mouseOut/Over can cause flicker // moving from one child element to another. _proto2.handleMouseOverOut = function handleMouseOverOut(handler, e, relatedNative) { var target = e.currentTarget; var related = e.relatedTarget || e.nativeEvent[relatedNative]; if ((!related || related !== target) && !contains(target, related)) { handler(e); } }; _proto2.hide = function hide() { this.setState({ show: false }); }; _proto2.show = function show() { this.setState({ show: true }); }; _proto2.render = function render() { var _this$props = this.props, trigger = _this$props.trigger, overlay = _this$props.overlay, children = _this$props.children, _this$props$popperCon = _this$props.popperConfig, popperConfig = _this$props$popperCon === void 0 ? {} : _this$props$popperCon, props = _objectWithoutPropertiesLoose(_this$props, ["trigger", "overlay", "children", "popperConfig"]); delete props.delay; delete props.defaultShow; var child = React.Children.only(children); var triggerProps = {}; var triggers = trigger == null ? [] : [].concat(trigger); if (triggers.indexOf('click') !== -1) { triggerProps.onClick = this.handleClick; } if (triggers.indexOf('focus') !== -1) { triggerProps.onFocus = this.handleShow; triggerProps.onBlur = this.handleHide; } if (triggers.indexOf('hover') !== -1) { process.env.NODE_ENV !== "production" ? warning(triggers.length >= 1, '[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; triggerProps.onMouseOver = this.handleMouseOver; triggerProps.onMouseOut = this.handleMouseOut; } return React.createElement(React.Fragment, null, React.createElement(RefHolder, { ref: this.trigger }, cloneElement(child, triggerProps)), React.createElement(Overlay, _extends({}, props, { popperConfig: _extends({}, popperConfig, { modifiers: _extends({}, popperConfig.modifiers, { ariaModifier: this.ariaModifier }) }), show: this.state.show, onHide: this.handleHide, target: this.getTarget }), overlay)); }; return OverlayTrigger; }(React.Component); OverlayTrigger.defaultProps = defaultProps; export default OverlayTrigger;