react-bootstrap
Version:
Bootstrap 4 components built with React
249 lines (187 loc) • 7.53 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
var _contains = _interopRequireDefault(require("dom-helpers/query/contains"));
var _react = _interopRequireWildcard(require("react"));
var _reactDom = _interopRequireDefault(require("react-dom"));
var _warning = _interopRequireDefault(require("warning"));
var _Overlay = _interopRequireDefault(require("./Overlay"));
var RefHolder =
/*#__PURE__*/
function (_React$Component) {
(0, _inheritsLoose2.default)(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.default.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) {
(0, _inheritsLoose2.default)(OverlayTrigger, _React$Component2);
function OverlayTrigger(props, context) {
var _this;
_this = _React$Component2.call(this, props, context) || this;
_this.getTarget = function () {
return _reactDom.default.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.default.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.default.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) && !(0, _contains.default)(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 = (0, _objectWithoutPropertiesLoose2.default)(_this$props, ["trigger", "overlay", "children", "popperConfig"]);
delete props.delay;
delete props.defaultShow;
var child = _react.default.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" ? (0, _warning.default)(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.default.createElement(_react.default.Fragment, null, _react.default.createElement(RefHolder, {
ref: this.trigger
}, (0, _react.cloneElement)(child, triggerProps)), _react.default.createElement(_Overlay.default, (0, _extends2.default)({}, props, {
popperConfig: (0, _extends2.default)({}, popperConfig, {
modifiers: (0, _extends2.default)({}, popperConfig.modifiers, {
ariaModifier: this.ariaModifier
})
}),
show: this.state.show,
onHide: this.handleHide,
target: this.getTarget
}), overlay));
};
return OverlayTrigger;
}(_react.default.Component);
OverlayTrigger.defaultProps = defaultProps;
var _default = OverlayTrigger;
exports.default = _default;
module.exports = exports["default"];