UNPKG

6.76 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
4
5var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
6
7exports.__esModule = true;
8exports.default = void 0;
9
10var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
12var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
13
14var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
15
16var _contains = _interopRequireDefault(require("dom-helpers/contains"));
17
18var _react = _interopRequireWildcard(require("react"));
19
20var _useTimeout = _interopRequireDefault(require("@restart/hooks/useTimeout"));
21
22var _reactDom = _interopRequireDefault(require("react-dom"));
23
24var _warning = _interopRequireDefault(require("warning"));
25
26var _Overlay = _interopRequireDefault(require("./Overlay"));
27
28var RefHolder = /*#__PURE__*/function (_React$Component) {
29 (0, _inheritsLoose2.default)(RefHolder, _React$Component);
30
31 function RefHolder() {
32 return _React$Component.apply(this, arguments) || this;
33 }
34
35 var _proto = RefHolder.prototype;
36
37 _proto.render = function render() {
38 return this.props.children;
39 };
40
41 return RefHolder;
42}(_react.default.Component);
43
44function normalizeDelay(delay) {
45 return delay && typeof delay === 'object' ? delay : {
46 show: delay,
47 hide: delay
48 };
49} // Simple implementation of mouseEnter and mouseLeave.
50// React's built version is broken: https://github.com/facebook/react/issues/4251
51// for cases when the trigger is disabled and mouseOut/Over can cause flicker
52// moving from one child element to another.
53
54
55function handleMouseOverOut(handler, e, relatedNative) {
56 var target = e.currentTarget;
57 var related = e.relatedTarget || e.nativeEvent[relatedNative];
58
59 if ((!related || related !== target) && !(0, _contains.default)(target, related)) {
60 handler(e);
61 }
62}
63
64var defaultProps = {
65 defaultShow: false,
66 trigger: ['hover', 'focus']
67};
68
69function OverlayTrigger(_ref) {
70 var trigger = _ref.trigger,
71 overlay = _ref.overlay,
72 children = _ref.children,
73 _ref$popperConfig = _ref.popperConfig,
74 popperConfig = _ref$popperConfig === void 0 ? {} : _ref$popperConfig,
75 defaultShow = _ref.defaultShow,
76 propsDelay = _ref.delay,
77 props = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["trigger", "overlay", "children", "popperConfig", "defaultShow", "delay"]);
78 var triggerNodeRef = (0, _react.useRef)(null);
79 var timeout = (0, _useTimeout.default)();
80 var hoverStateRef = (0, _react.useRef)();
81
82 var _useState = (0, _react.useState)(!!defaultShow),
83 show = _useState[0],
84 setShow = _useState[1];
85
86 var delay = normalizeDelay(propsDelay);
87
88 var child = _react.default.Children.only(children);
89
90 var _child$props = child.props,
91 onFocus = _child$props.onFocus,
92 onBlur = _child$props.onBlur,
93 onClick = _child$props.onClick;
94 var getTarget = (0, _react.useCallback)(function () {
95 return _reactDom.default.findDOMNode(triggerNodeRef.current);
96 }, []);
97 var handleShow = (0, _react.useCallback)(function () {
98 timeout.clear();
99 hoverStateRef.current = 'show';
100
101 if (!delay.show) {
102 setShow(true);
103 return;
104 }
105
106 timeout.set(function () {
107 if (hoverStateRef.current === 'show') setShow(true);
108 }, delay.show);
109 }, [delay.show, timeout]);
110 var handleHide = (0, _react.useCallback)(function () {
111 timeout.clear();
112 hoverStateRef.current = 'hide';
113
114 if (!delay.hide) {
115 setShow(false);
116 return;
117 }
118
119 timeout.set(function () {
120 if (hoverStateRef.current === 'hide') setShow(false);
121 }, delay.hide);
122 }, [delay.hide, timeout]);
123 var handleFocus = (0, _react.useCallback)(function (e) {
124 handleShow(e);
125 if (onFocus) onFocus(e);
126 }, [handleShow, onFocus]);
127 var handleBlur = (0, _react.useCallback)(function (e) {
128 handleHide(e);
129 if (onBlur) onBlur(e);
130 }, [handleHide, onBlur]);
131 var handleClick = (0, _react.useCallback)(function (e) {
132 setShow(function (prevShow) {
133 return !prevShow;
134 });
135 if (onClick) onClick(e);
136 }, [onClick]);
137 var handleMouseOver = (0, _react.useCallback)(function (e) {
138 handleMouseOverOut(handleShow, e, 'fromElement');
139 }, [handleShow]);
140 var handleMouseOut = (0, _react.useCallback)(function (e) {
141 handleMouseOverOut(handleHide, e, 'toElement');
142 }, [handleHide]); // We add aria-describedby in the case where the overlay is a role="tooltip"
143 // for other cases describedby isn't appropriate (e.g. a popover with inputs) so we don't add it.
144
145 var ariaModifier = {
146 name: 'ariaDescribedBy',
147 enabled: true,
148 phase: 'afterWrite',
149 effect: function effect(_ref2) {
150 var state = _ref2.state;
151 return function () {
152 state.elements.reference.removeAttribute('aria-describedby');
153 };
154 },
155 fn: function fn(_ref3) {
156 var state = _ref3.state;
157 var _state$elements = state.elements,
158 popper = _state$elements.popper,
159 reference = _state$elements.reference;
160 if (!show || !reference) return;
161 var role = popper.getAttribute('role') || '';
162
163 if (popper.id && role.toLowerCase() === 'tooltip') {
164 reference.setAttribute('aria-describedby', popper.id);
165 }
166 }
167 };
168 var triggers = trigger == null ? [] : [].concat(trigger);
169 var triggerProps = {};
170
171 if (triggers.indexOf('click') !== -1) {
172 triggerProps.onClick = handleClick;
173 }
174
175 if (triggers.indexOf('focus') !== -1) {
176 triggerProps.onFocus = handleFocus;
177 triggerProps.onBlur = handleBlur;
178 }
179
180 if (triggers.indexOf('hover') !== -1) {
181 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;
182 triggerProps.onMouseOver = handleMouseOver;
183 triggerProps.onMouseOut = handleMouseOut;
184 }
185
186 return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(RefHolder, {
187 ref: triggerNodeRef
188 }, (0, _react.cloneElement)(child, triggerProps)), _react.default.createElement(_Overlay.default, (0, _extends2.default)({}, props, {
189 popperConfig: (0, _extends2.default)({}, popperConfig, {
190 modifiers: [ariaModifier].concat(popperConfig.modifiers || [])
191 }),
192 show: show,
193 onHide: handleHide,
194 target: getTarget
195 }), overlay));
196}
197
198OverlayTrigger.defaultProps = defaultProps;
199var _default = OverlayTrigger;
200exports.default = _default;
201module.exports = exports["default"];
\No newline at end of file