232 lines
6.7 KiB
JavaScript
232 lines
6.7 KiB
JavaScript
|
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;
|