UNPKG

7.57 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 _reactDom = _interopRequireDefault(require("react-dom"));
21
22var _warning = _interopRequireDefault(require("warning"));
23
24var _Overlay = _interopRequireDefault(require("./Overlay"));
25
26/* eslint-disable max-classes-per-file */
27var RefHolder =
28/*#__PURE__*/
29function (_React$Component) {
30 (0, _inheritsLoose2.default)(RefHolder, _React$Component);
31
32 function RefHolder() {
33 return _React$Component.apply(this, arguments) || this;
34 }
35
36 var _proto = RefHolder.prototype;
37
38 _proto.render = function render() {
39 return this.props.children;
40 };
41
42 return RefHolder;
43}(_react.default.Component);
44
45var normalizeDelay = function normalizeDelay(delay) {
46 return delay && typeof delay === 'object' ? delay : {
47 show: delay,
48 hide: delay
49 };
50};
51
52var defaultProps = {
53 defaultOverlayShown: false,
54 trigger: ['hover', 'focus']
55}; // eslint-disable-next-line react/no-multi-comp
56
57var OverlayTrigger =
58/*#__PURE__*/
59function (_React$Component2) {
60 (0, _inheritsLoose2.default)(OverlayTrigger, _React$Component2);
61
62 function OverlayTrigger(props, context) {
63 var _this;
64
65 _this = _React$Component2.call(this, props, context) || this;
66
67 _this.getTarget = function () {
68 return _reactDom.default.findDOMNode(_this.trigger.current);
69 };
70
71 _this.handleShow = function () {
72 clearTimeout(_this._timeout);
73 _this._hoverState = 'show';
74 var delay = normalizeDelay(_this.props.delay);
75
76 if (!delay.show) {
77 _this.show();
78
79 return;
80 }
81
82 _this._timeout = setTimeout(function () {
83 if (_this._hoverState === 'show') _this.show();
84 }, delay.show);
85 };
86
87 _this.handleHide = function () {
88 clearTimeout(_this._timeout);
89 _this._hoverState = 'hide';
90 var delay = normalizeDelay(_this.props.delay);
91
92 if (!delay.hide) {
93 _this.hide();
94
95 return;
96 }
97
98 _this._timeout = setTimeout(function () {
99 if (_this._hoverState === 'hide') _this.hide();
100 }, delay.hide);
101 };
102
103 _this.handleFocus = function (e) {
104 var _this$getChildProps = _this.getChildProps(),
105 onFocus = _this$getChildProps.onFocus;
106
107 _this.handleShow(e);
108
109 if (onFocus) onFocus(e);
110 };
111
112 _this.handleBlur = function (e) {
113 var _this$getChildProps2 = _this.getChildProps(),
114 onBlur = _this$getChildProps2.onBlur;
115
116 _this.handleHide(e);
117
118 if (onBlur) onBlur(e);
119 };
120
121 _this.handleClick = function (e) {
122 var _this$getChildProps3 = _this.getChildProps(),
123 onClick = _this$getChildProps3.onClick;
124
125 if (_this.state.show) _this.hide();else _this.show();
126 if (onClick) onClick(e);
127 };
128
129 _this.handleMouseOver = function (e) {
130 _this.handleMouseOverOut(_this.handleShow, e, 'fromElement');
131 };
132
133 _this.handleMouseOut = function (e) {
134 return _this.handleMouseOverOut(_this.handleHide, e, 'toElement');
135 };
136
137 _this.trigger = _react.default.createRef();
138 _this.state = {
139 show: !!props.defaultShow
140 }; // We add aria-describedby in the case where the overlay is a role="tooltip"
141 // for other cases describedby isn't appropriate (e.g. a popover with inputs) so we don't add it.
142
143 _this.ariaModifier = {
144 enabled: true,
145 order: 900,
146 fn: function fn(data) {
147 var popper = data.instance.popper;
148
149 var target = _this.getTarget();
150
151 if (!_this.state.show || !target) return data;
152 var role = popper.getAttribute('role') || '';
153
154 if (popper.id && role.toLowerCase() === 'tooltip') {
155 target.setAttribute('aria-describedby', popper.id);
156 }
157
158 return data;
159 }
160 };
161 return _this;
162 }
163
164 var _proto2 = OverlayTrigger.prototype;
165
166 _proto2.componentWillUnmount = function componentWillUnmount() {
167 clearTimeout(this._timeout);
168 };
169
170 _proto2.getChildProps = function getChildProps() {
171 return _react.default.Children.only(this.props.children).props;
172 };
173
174 // Simple implementation of mouseEnter and mouseLeave.
175 // React's built version is broken: https://github.com/facebook/react/issues/4251
176 // for cases when the trigger is disabled and mouseOut/Over can cause flicker
177 // moving from one child element to another.
178 _proto2.handleMouseOverOut = function handleMouseOverOut(handler, e, relatedNative) {
179 var target = e.currentTarget;
180 var related = e.relatedTarget || e.nativeEvent[relatedNative];
181
182 if ((!related || related !== target) && !(0, _contains.default)(target, related)) {
183 handler(e);
184 }
185 };
186
187 _proto2.hide = function hide() {
188 this.setState({
189 show: false
190 });
191 };
192
193 _proto2.show = function show() {
194 this.setState({
195 show: true
196 });
197 };
198
199 _proto2.render = function render() {
200 var _this$props = this.props,
201 trigger = _this$props.trigger,
202 overlay = _this$props.overlay,
203 children = _this$props.children,
204 _this$props$popperCon = _this$props.popperConfig,
205 popperConfig = _this$props$popperCon === void 0 ? {} : _this$props$popperCon,
206 props = (0, _objectWithoutPropertiesLoose2.default)(_this$props, ["trigger", "overlay", "children", "popperConfig"]);
207 delete props.delay;
208 delete props.defaultShow;
209
210 var child = _react.default.Children.only(children);
211
212 var triggerProps = {};
213 var triggers = trigger == null ? [] : [].concat(trigger);
214
215 if (triggers.indexOf('click') !== -1) {
216 triggerProps.onClick = this.handleClick;
217 }
218
219 if (triggers.indexOf('focus') !== -1) {
220 triggerProps.onFocus = this.handleShow;
221 triggerProps.onBlur = this.handleHide;
222 }
223
224 if (triggers.indexOf('hover') !== -1) {
225 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;
226 triggerProps.onMouseOver = this.handleMouseOver;
227 triggerProps.onMouseOut = this.handleMouseOut;
228 }
229
230 return _react.default.createElement(_react.default.Fragment, null, _react.default.createElement(RefHolder, {
231 ref: this.trigger
232 }, (0, _react.cloneElement)(child, triggerProps)), _react.default.createElement(_Overlay.default, (0, _extends2.default)({}, props, {
233 popperConfig: (0, _extends2.default)({}, popperConfig, {
234 modifiers: (0, _extends2.default)({}, popperConfig.modifiers, {
235 ariaModifier: this.ariaModifier
236 })
237 }),
238 show: this.state.show,
239 onHide: this.handleHide,
240 target: this.getTarget
241 }), overlay));
242 };
243
244 return OverlayTrigger;
245}(_react.default.Component);
246
247OverlayTrigger.defaultProps = defaultProps;
248var _default = OverlayTrigger;
249exports.default = _default;
250module.exports = exports["default"];
\No newline at end of file