function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
import PropTypes from 'prop-types';
import elementType from 'prop-types-extra/lib/elementType';
import componentOrElement from 'prop-types-extra/lib/componentOrElement';
import React from 'react';
import ReactDOM from 'react-dom';
import Portal from './Portal';
import RootCloseWrapper from './RootCloseWrapper';
import { Popper, placements } from 'react-popper';
import forwardRef from 'react-context-toolbox/forwardRef';
import WaitForContainer from './WaitForContainer';
/**
* Built on top of `` and ``, the overlay component is
* great for custom tooltip overlays.
*/
var Overlay =
/*#__PURE__*/
function (_React$Component) {
_inheritsLoose(Overlay, _React$Component);
function Overlay(props, context) {
var _this;
_this = _React$Component.call(this, props, context) || this;
_this.handleHidden = function () {
_this.setState({
exited: true
});
if (_this.props.onExited) {
var _this$props;
(_this$props = _this.props).onExited.apply(_this$props, arguments);
}
};
_this.state = {
exited: !props.show
};
_this.onHiddenListener = _this.handleHidden.bind(_assertThisInitialized(_assertThisInitialized(_this)));
_this._lastTarget = null;
return _this;
}
Overlay.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps) {
if (nextProps.show) {
return {
exited: false
};
} else if (!nextProps.transition) {
// Otherwise let handleHidden take care of marking exited.
return {
exited: true
};
}
return null;
};
var _proto = Overlay.prototype;
_proto.componentDidMount = function componentDidMount() {
this.setState({
target: this.getTarget()
});
};
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
if (this.props === prevProps) return;
var target = this.getTarget();
if (target !== this.state.target) {
this.setState({
target: target
});
}
};
_proto.getTarget = function getTarget() {
var target = this.props.target;
target = typeof target === 'function' ? target() : target;
return target && ReactDOM.findDOMNode(target) || null;
};
_proto.render = function render() {
var _this2 = this;
var _this$props2 = this.props,
_0 = _this$props2.target,
container = _this$props2.container,
containerPadding = _this$props2.containerPadding,
placement = _this$props2.placement,
rootClose = _this$props2.rootClose,
children = _this$props2.children,
flip = _this$props2.flip,
_this$props2$popperCo = _this$props2.popperConfig,
popperConfig = _this$props2$popperCo === void 0 ? {} : _this$props2$popperCo,
Transition = _this$props2.transition,
props = _objectWithoutPropertiesLoose(_this$props2, ["target", "container", "containerPadding", "placement", "rootClose", "children", "flip", "popperConfig", "transition"]);
var target = this.state.target; // Don't un-render the overlay while it's transitioning out.
var mountOverlay = props.show || Transition && !this.state.exited;
if (!mountOverlay) {
// Don't bother showing anything if we don't have to.
return null;
}
var child = children;
var _popperConfig$modifie = popperConfig.modifiers,
modifiers = _popperConfig$modifie === void 0 ? {} : _popperConfig$modifie;
var popperProps = _extends({}, popperConfig, {
placement: placement,
referenceElement: target,
enableEvents: props.show,
modifiers: _extends({}, modifiers, {
preventOverflow: _extends({
padding: containerPadding || 5
}, modifiers.preventOverflow),
flip: _extends({
enabled: !!flip
}, modifiers.preventOverflow)
})
});
child = React.createElement(Popper, popperProps, function (_ref) {
var arrowProps = _ref.arrowProps,
style = _ref.style,
ref = _ref.ref,
popper = _objectWithoutPropertiesLoose(_ref, ["arrowProps", "style", "ref"]);
_this2.popper = popper;
var innerChild = _this2.props.children(_extends({}, popper, {
// popper doesn't set the initial placement
placement: popper.placement || placement,
show: props.show,
arrowProps: arrowProps,
props: {
ref: ref,
style: style
}
}));
if (Transition) {
var onExit = props.onExit,
onExiting = props.onExiting,
onEnter = props.onEnter,
onEntering = props.onEntering,
onEntered = props.onEntered;
innerChild = React.createElement(Transition, {
in: props.show,
appear: true,
onExit: onExit,
onExiting: onExiting,
onExited: _this2.onHiddenListener,
onEnter: onEnter,
onEntering: onEntering,
onEntered: onEntered
}, innerChild);
}
return innerChild;
});
if (rootClose) {
child = React.createElement(RootCloseWrapper, {
onRootClose: props.onHide,
event: props.rootCloseEvent,
disabled: props.rootCloseDisabled
}, child);
}
return React.createElement(Portal, {
container: container
}, child);
};
return Overlay;
}(React.Component);
Overlay.propTypes = _extends({}, Portal.propTypes, {
/**
* Set the visibility of the Overlay
*/
show: PropTypes.bool,
/** Specify where the overlay element is positioned in relation to the target element */
placement: PropTypes.oneOf(placements),
/**
* A Node, Component instance, or function that returns either. The `container` will have the Portal children
* appended to it.
*/
container: PropTypes.oneOfType([componentOrElement, PropTypes.func]),
/**
* Enables the Popper.js `flip` modifier, allowing the Overlay to
* automatically adjust it's placement in case of overlap with the viewport or toggle.
* Refer to the [flip docs](https://popper.js.org/popper-documentation.html#modifiers..flip.enabled) for more info
*/
flip: PropTypes.bool,
/**
* A render prop that returns an element to overlay and position. See
* the [react-popper documentation](https://github.com/FezVrasta/react-popper#children) for more info.
*
* @type {Function ({
* show: boolean,
* placement: Placement,
* outOfBoundaries: ?boolean,
* scheduleUpdate: () => void,
* props: {
* ref: (?HTMLElement) => void,
* style: { [string]: string | number },
* aria-labelledby: ?string
* },
* arrowProps: {
* ref: (?HTMLElement) => void,
* style: { [string]: string | number },
* },
* }) => React.Element}
*/
children: PropTypes.func.isRequired,
/**
* A set of popper options and props passed directly to react-popper's Popper component.
*/
popperConfig: PropTypes.object,
/**
* Specify whether the overlay should trigger `onHide` when the user clicks outside the overlay
*/
rootClose: PropTypes.bool,
/**
* Specify event for toggling overlay
*/
rootCloseEvent: RootCloseWrapper.propTypes.event,
/**
* Specify disabled for disable RootCloseWrapper
*/
rootCloseDisabled: RootCloseWrapper.propTypes.disabled,
/**
* A Callback fired by the Overlay when it wishes to be hidden.
*
* __required__ when `rootClose` is `true`.
*
* @type func
*/
onHide: function onHide(props) {
var propType = PropTypes.func;
if (props.rootClose) {
propType = propType.isRequired;
}
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return propType.apply(void 0, [props].concat(args));
},
/**
* A `react-transition-group@2.0.0` `` component
* used to animate the overlay as it changes visibility.
*/
transition: elementType,
/**
* Callback fired before the Overlay transitions in
*/
onEnter: PropTypes.func,
/**
* Callback fired as the Overlay begins to transition in
*/
onEntering: PropTypes.func,
/**
* Callback fired after the Overlay finishes transitioning in
*/
onEntered: PropTypes.func,
/**
* Callback fired right before the Overlay transitions out
*/
onExit: PropTypes.func,
/**
* Callback fired as the Overlay begins to transition out
*/
onExiting: PropTypes.func,
/**
* Callback fired after the Overlay finishes transitioning out
*/
onExited: PropTypes.func
});
export default forwardRef(function (props, ref) {
return (// eslint-disable-next-line react/prop-types
React.createElement(WaitForContainer, {
container: props.container
}, function (container) {
return React.createElement(Overlay, _extends({}, props, {
ref: ref,
container: container
}));
})
);
}, {
displayName: 'withContainer(Overlay)'
});