UNPKG

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