@clayui/tooltip 3.58.0 → 3.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/TooltipProvider.d.ts +1 -1
- package/lib/TooltipProvider.js +78 -38
- package/package.json +4 -3
- package/src/TooltipProvider.tsx +168 -87
package/lib/TooltipProvider.d.ts
CHANGED
|
@@ -39,5 +39,5 @@ interface IPropsWithScope extends IPropsBase {
|
|
|
39
39
|
*/
|
|
40
40
|
scope: string;
|
|
41
41
|
}
|
|
42
|
-
declare const TooltipProvider:
|
|
42
|
+
declare const TooltipProvider: ({ autoAlign, children, containerProps, contentRenderer, delay, scope, }: IPropsWithChildren | IPropsWithScope) => JSX.Element;
|
|
43
43
|
export default TooltipProvider;
|
package/lib/TooltipProvider.js
CHANGED
|
@@ -9,6 +9,8 @@ exports.default = void 0;
|
|
|
9
9
|
|
|
10
10
|
var _shared = require("@clayui/shared");
|
|
11
11
|
|
|
12
|
+
var _domAlign = require("dom-align");
|
|
13
|
+
|
|
12
14
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
15
|
|
|
14
16
|
var _warning = _interopRequireDefault(require("warning"));
|
|
@@ -66,6 +68,20 @@ var ALIGNMENTS_INVERSE_MAP = {
|
|
|
66
68
|
tlbl: 'bottom-left',
|
|
67
69
|
trbr: 'bottom-right'
|
|
68
70
|
};
|
|
71
|
+
var BOTTOM_OFFSET = [0, 7];
|
|
72
|
+
var LEFT_OFFSET = [-7, 0];
|
|
73
|
+
var RIGHT_OFFSET = [7, 0];
|
|
74
|
+
var TOP_OFFSET = [0, -7];
|
|
75
|
+
var OFFSET_MAP = {
|
|
76
|
+
bctc: TOP_OFFSET,
|
|
77
|
+
bltl: TOP_OFFSET,
|
|
78
|
+
brtr: TOP_OFFSET,
|
|
79
|
+
clcr: RIGHT_OFFSET,
|
|
80
|
+
crcl: LEFT_OFFSET,
|
|
81
|
+
tcbc: BOTTOM_OFFSET,
|
|
82
|
+
tlbl: BOTTOM_OFFSET,
|
|
83
|
+
trbr: BOTTOM_OFFSET
|
|
84
|
+
};
|
|
69
85
|
|
|
70
86
|
var ALIGNMENTS_FORCE_MAP = _objectSpread(_objectSpread({}, ALIGNMENTS_INVERSE_MAP), {}, {
|
|
71
87
|
bctc: 'top-left',
|
|
@@ -97,6 +113,7 @@ var reducer = function reducer(state, _ref) {
|
|
|
97
113
|
case 'hide':
|
|
98
114
|
return _objectSpread(_objectSpread({}, state), {}, {
|
|
99
115
|
align: initialState.align,
|
|
116
|
+
floating: undefined,
|
|
100
117
|
show: false
|
|
101
118
|
});
|
|
102
119
|
|
|
@@ -150,25 +167,23 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
150
167
|
delay = _ref2$delay === void 0 ? 600 : _ref2$delay,
|
|
151
168
|
scope = _ref2.scope;
|
|
152
169
|
|
|
153
|
-
var
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
align =
|
|
157
|
-
|
|
158
|
-
message =
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
var
|
|
165
|
-
|
|
166
|
-
var
|
|
167
|
-
|
|
168
|
-
var titleNodeRef = _react.
|
|
169
|
-
|
|
170
|
-
var tooltipRef = _react.default.useRef(null);
|
|
171
|
-
|
|
170
|
+
var _useReducer = (0, _react.useReducer)(reducer, initialState),
|
|
171
|
+
_useReducer2 = _slicedToArray(_useReducer, 2),
|
|
172
|
+
_useReducer2$ = _useReducer2[0],
|
|
173
|
+
align = _useReducer2$.align,
|
|
174
|
+
floating = _useReducer2$.floating,
|
|
175
|
+
_useReducer2$$message = _useReducer2$.message,
|
|
176
|
+
message = _useReducer2$$message === void 0 ? '' : _useReducer2$$message,
|
|
177
|
+
setAsHTML = _useReducer2$.setAsHTML,
|
|
178
|
+
show = _useReducer2$.show,
|
|
179
|
+
dispatch = _useReducer2[1];
|
|
180
|
+
|
|
181
|
+
var mousePosition = (0, _shared.useMousePosition)(20); // Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
|
|
182
|
+
|
|
183
|
+
var timeoutIdRef = (0, _react.useRef)();
|
|
184
|
+
var targetRef = (0, _react.useRef)(null);
|
|
185
|
+
var titleNodeRef = (0, _react.useRef)(null);
|
|
186
|
+
var tooltipRef = (0, _react.useRef)(null);
|
|
172
187
|
var saveTitle = (0, _react.useCallback)(function (element) {
|
|
173
188
|
titleNodeRef.current = element;
|
|
174
189
|
var title = element.getAttribute('title');
|
|
@@ -206,7 +221,13 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
206
221
|
titleNodeRef.current = null;
|
|
207
222
|
}
|
|
208
223
|
}, []);
|
|
209
|
-
var handleHide = (0, _react.useCallback)(function () {
|
|
224
|
+
var handleHide = (0, _react.useCallback)(function (event) {
|
|
225
|
+
var _tooltipRef$current, _targetRef$current;
|
|
226
|
+
|
|
227
|
+
if (event && ((_tooltipRef$current = tooltipRef.current) !== null && _tooltipRef$current !== void 0 && _tooltipRef$current.contains(event.relatedTarget) || (_targetRef$current = targetRef.current) !== null && _targetRef$current !== void 0 && _targetRef$current.contains(event.relatedTarget))) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
|
|
210
231
|
dispatch({
|
|
211
232
|
type: 'hide'
|
|
212
233
|
});
|
|
@@ -218,13 +239,13 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
218
239
|
targetRef.current = null;
|
|
219
240
|
}
|
|
220
241
|
}, []);
|
|
221
|
-
var handleShow = (0, _react.useCallback)(function (
|
|
222
|
-
var target =
|
|
223
|
-
targetRef.current = target;
|
|
242
|
+
var handleShow = (0, _react.useCallback)(function (event) {
|
|
243
|
+
var target = event.target;
|
|
224
244
|
var hasTitle = target && (target.hasAttribute('title') || target.hasAttribute('data-title'));
|
|
225
245
|
var titleNode = hasTitle ? target : closestAncestor(target, '[title], [data-title]');
|
|
226
246
|
|
|
227
247
|
if (titleNode) {
|
|
248
|
+
targetRef.current = target;
|
|
228
249
|
target.addEventListener('click', handleHide);
|
|
229
250
|
var title = titleNode.getAttribute('title') || titleNode.getAttribute('data-title') || '';
|
|
230
251
|
saveTitle(titleNode);
|
|
@@ -233,10 +254,12 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
233
254
|
|
|
234
255
|
var _setAsHTML = !!titleNode.getAttribute('data-title-set-as-html');
|
|
235
256
|
|
|
257
|
+
var isFloating = titleNode.getAttribute('data-tooltip-floating');
|
|
236
258
|
clearTimeout(timeoutIdRef.current);
|
|
237
259
|
timeoutIdRef.current = setTimeout(function () {
|
|
238
260
|
dispatch({
|
|
239
261
|
align: newAlign || align,
|
|
262
|
+
floating: Boolean(isFloating),
|
|
240
263
|
message: title,
|
|
241
264
|
setAsHTML: _setAsHTML,
|
|
242
265
|
type: 'show'
|
|
@@ -244,8 +267,7 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
244
267
|
}, customDelay ? Number(customDelay) : delay);
|
|
245
268
|
}
|
|
246
269
|
}, []);
|
|
247
|
-
|
|
248
|
-
_react.default.useEffect(function () {
|
|
270
|
+
(0, _react.useEffect)(function () {
|
|
249
271
|
var handleEsc = function handleEsc(event) {
|
|
250
272
|
if (show && event.key === _shared.Keys.Esc) {
|
|
251
273
|
event.stopImmediatePropagation();
|
|
@@ -258,30 +280,45 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
258
280
|
return document.removeEventListener('keyup', handleEsc, true);
|
|
259
281
|
};
|
|
260
282
|
}, [show]);
|
|
261
|
-
|
|
262
|
-
_react.default.useEffect(function () {
|
|
283
|
+
(0, _react.useEffect)(function () {
|
|
263
284
|
if (scope) {
|
|
264
285
|
var disposeShowEvents = TRIGGER_SHOW_EVENTS.map(function (eventName) {
|
|
265
286
|
return (0, _shared.delegate)(document.body, eventName, scope, handleShow);
|
|
266
287
|
});
|
|
267
288
|
var disposeHideEvents = TRIGGER_HIDE_EVENTS.map(function (eventName) {
|
|
268
|
-
return (0, _shared.delegate)(document.body, eventName, scope, handleHide);
|
|
289
|
+
return (0, _shared.delegate)(document.body, eventName, "".concat(scope, ", .tooltip"), handleHide);
|
|
269
290
|
});
|
|
270
291
|
return function () {
|
|
271
|
-
disposeShowEvents.forEach(function (
|
|
272
|
-
var dispose =
|
|
292
|
+
disposeShowEvents.forEach(function (_ref3) {
|
|
293
|
+
var dispose = _ref3.dispose;
|
|
273
294
|
return dispose();
|
|
274
295
|
});
|
|
275
|
-
disposeHideEvents.forEach(function (
|
|
276
|
-
var dispose =
|
|
296
|
+
disposeHideEvents.forEach(function (_ref4) {
|
|
297
|
+
var dispose = _ref4.dispose;
|
|
277
298
|
return dispose();
|
|
278
299
|
});
|
|
279
300
|
};
|
|
280
301
|
}
|
|
281
|
-
}, []);
|
|
302
|
+
}, [handleShow]);
|
|
303
|
+
(0, _react.useEffect)(function () {
|
|
304
|
+
if (tooltipRef.current && show && floating) {
|
|
305
|
+
var points = ALIGNMENTS_MAP[align || 'top'];
|
|
306
|
+
|
|
307
|
+
var _mousePosition = _slicedToArray(mousePosition, 2),
|
|
308
|
+
clientX = _mousePosition[0],
|
|
309
|
+
clientY = _mousePosition[1];
|
|
282
310
|
|
|
283
|
-
|
|
284
|
-
|
|
311
|
+
(0, _domAlign.alignPoint)(tooltipRef.current, {
|
|
312
|
+
clientX: clientX,
|
|
313
|
+
clientY: clientY
|
|
314
|
+
}, {
|
|
315
|
+
offset: OFFSET_MAP[points.join('')],
|
|
316
|
+
points: points
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}, [show, floating]);
|
|
320
|
+
(0, _react.useEffect)(function () {
|
|
321
|
+
if (titleNodeRef.current && tooltipRef.current && !floating) {
|
|
285
322
|
var points = ALIGNMENTS_MAP[align || 'top'];
|
|
286
323
|
var alignment = (0, _shared.doAlign)({
|
|
287
324
|
overflow: {
|
|
@@ -308,7 +345,6 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
308
345
|
}
|
|
309
346
|
}
|
|
310
347
|
}, [align, show]);
|
|
311
|
-
|
|
312
348
|
"production" !== "production" ? (0, _warning.default)(typeof children === 'undefined' && typeof scope !== 'undefined' || typeof scope === 'undefined' && typeof children !== 'undefined', '<TooltipProvider />: You must use at least one of the following props: `children` or `scope`.') : void 0;
|
|
313
349
|
"production" !== "production" ? (0, _warning.default)(typeof children !== 'undefined' || typeof scope !== 'undefined', '<TooltipProvider />: If you want to use `scope`, use <TooltipProvider /> as a singleton and do not pass `children`.') : void 0;
|
|
314
350
|
"production" !== "production" ? (0, _warning.default)((children === null || children === void 0 ? void 0 : children.type) !== _react.default.Fragment, '<TooltipProvider />: React Fragment is not allowed as a child to TooltipProvider. Child must be a single HTML element that accepts `onMouseOver` and `onMouseOut`.') : void 0;
|
|
@@ -316,7 +352,8 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
316
352
|
targetNode: targetRef.current,
|
|
317
353
|
title: message
|
|
318
354
|
});
|
|
319
|
-
|
|
355
|
+
|
|
356
|
+
var tooltip = show && /*#__PURE__*/_react.default.createElement(_shared.ClayPortal, containerProps, /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
|
|
320
357
|
alignPosition: align,
|
|
321
358
|
ref: tooltipRef,
|
|
322
359
|
show: true
|
|
@@ -324,7 +361,10 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
324
361
|
dangerouslySetInnerHTML: {
|
|
325
362
|
__html: titleContent
|
|
326
363
|
}
|
|
327
|
-
}) : titleContent))
|
|
364
|
+
}) : titleContent));
|
|
365
|
+
|
|
366
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, scope ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, tooltip, children) : children && /*#__PURE__*/_react.default.cloneElement(children, _objectSpread(_objectSpread({}, children.props), {}, {
|
|
367
|
+
children: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children.props.children, tooltip),
|
|
328
368
|
onMouseOut: handleHide,
|
|
329
369
|
onMouseOver: handleShow
|
|
330
370
|
})));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clayui/tooltip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.69.0",
|
|
4
4
|
"description": "ClayTooltip component",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"repository": "https://github.com/liferay/clay",
|
|
@@ -26,8 +26,9 @@
|
|
|
26
26
|
"react"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@clayui/shared": "^3.
|
|
29
|
+
"@clayui/shared": "^3.69.0",
|
|
30
30
|
"classnames": "^2.2.6",
|
|
31
|
+
"dom-align": "^1.12.2",
|
|
31
32
|
"warning": "^4.0.3"
|
|
32
33
|
},
|
|
33
34
|
"peerDependencies": {
|
|
@@ -38,5 +39,5 @@
|
|
|
38
39
|
"browserslist": [
|
|
39
40
|
"extends browserslist-config-clay"
|
|
40
41
|
],
|
|
41
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "510da79d152edf887a1eed74d2d38787343ce6e4"
|
|
42
43
|
}
|
package/src/TooltipProvider.tsx
CHANGED
|
@@ -9,8 +9,10 @@ import {
|
|
|
9
9
|
Keys,
|
|
10
10
|
delegate,
|
|
11
11
|
doAlign,
|
|
12
|
+
useMousePosition,
|
|
12
13
|
} from '@clayui/shared';
|
|
13
|
-
import
|
|
14
|
+
import {alignPoint} from 'dom-align';
|
|
15
|
+
import React, {useCallback, useEffect, useReducer, useRef} from 'react';
|
|
14
16
|
import warning from 'warning';
|
|
15
17
|
|
|
16
18
|
import ClayTooltip from './Tooltip';
|
|
@@ -48,6 +50,22 @@ const ALIGNMENTS_INVERSE_MAP = {
|
|
|
48
50
|
trbr: 'bottom-right',
|
|
49
51
|
} as const;
|
|
50
52
|
|
|
53
|
+
const BOTTOM_OFFSET = [0, 7] as const;
|
|
54
|
+
const LEFT_OFFSET = [-7, 0] as const;
|
|
55
|
+
const RIGHT_OFFSET = [7, 0] as const;
|
|
56
|
+
const TOP_OFFSET = [0, -7] as const;
|
|
57
|
+
|
|
58
|
+
const OFFSET_MAP = {
|
|
59
|
+
bctc: TOP_OFFSET,
|
|
60
|
+
bltl: TOP_OFFSET,
|
|
61
|
+
brtr: TOP_OFFSET,
|
|
62
|
+
clcr: RIGHT_OFFSET,
|
|
63
|
+
crcl: LEFT_OFFSET,
|
|
64
|
+
tcbc: BOTTOM_OFFSET,
|
|
65
|
+
tlbl: BOTTOM_OFFSET,
|
|
66
|
+
trbr: BOTTOM_OFFSET,
|
|
67
|
+
};
|
|
68
|
+
|
|
51
69
|
const ALIGNMENTS_FORCE_MAP = {
|
|
52
70
|
...ALIGNMENTS_INVERSE_MAP,
|
|
53
71
|
bctc: 'top-left',
|
|
@@ -56,6 +74,7 @@ const ALIGNMENTS_FORCE_MAP = {
|
|
|
56
74
|
|
|
57
75
|
interface IState {
|
|
58
76
|
align?: typeof ALIGNMENTS[number];
|
|
77
|
+
floating?: boolean;
|
|
59
78
|
message?: string;
|
|
60
79
|
show?: boolean;
|
|
61
80
|
setAsHTML?: boolean;
|
|
@@ -97,6 +116,7 @@ const reducer = (state: IState, {type, ...payload}: IAction): IState => {
|
|
|
97
116
|
return {
|
|
98
117
|
...state,
|
|
99
118
|
align: initialState.align,
|
|
119
|
+
floating: undefined,
|
|
100
120
|
show: false,
|
|
101
121
|
};
|
|
102
122
|
default:
|
|
@@ -183,26 +203,24 @@ interface IPropsWithScope extends IPropsBase {
|
|
|
183
203
|
scope: string;
|
|
184
204
|
}
|
|
185
205
|
|
|
186
|
-
const TooltipProvider
|
|
187
|
-
IPropsWithChildren | IPropsWithScope
|
|
188
|
-
> = ({
|
|
206
|
+
const TooltipProvider = ({
|
|
189
207
|
autoAlign = true,
|
|
190
208
|
children,
|
|
191
209
|
containerProps = {},
|
|
192
210
|
contentRenderer = (props) => props.title,
|
|
193
211
|
delay = 600,
|
|
194
212
|
scope,
|
|
195
|
-
}) => {
|
|
196
|
-
const [{align, message = '', setAsHTML, show}, dispatch] =
|
|
197
|
-
reducer,
|
|
198
|
-
|
|
199
|
-
);
|
|
213
|
+
}: IPropsWithChildren | IPropsWithScope) => {
|
|
214
|
+
const [{align, floating, message = '', setAsHTML, show}, dispatch] =
|
|
215
|
+
useReducer(reducer, initialState);
|
|
216
|
+
|
|
217
|
+
const mousePosition = useMousePosition(20);
|
|
200
218
|
|
|
201
219
|
// Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
|
|
202
|
-
const timeoutIdRef =
|
|
203
|
-
const targetRef =
|
|
204
|
-
const titleNodeRef =
|
|
205
|
-
const tooltipRef =
|
|
220
|
+
const timeoutIdRef = useRef<any>();
|
|
221
|
+
const targetRef = useRef<HTMLElement | null>(null);
|
|
222
|
+
const titleNodeRef = useRef<HTMLElement | null>(null);
|
|
223
|
+
const tooltipRef = useRef<HTMLElement | null>(null);
|
|
206
224
|
|
|
207
225
|
const saveTitle = useCallback((element: HTMLElement) => {
|
|
208
226
|
titleNodeRef.current = element;
|
|
@@ -247,7 +265,15 @@ const TooltipProvider: React.FunctionComponent<
|
|
|
247
265
|
}
|
|
248
266
|
}, []);
|
|
249
267
|
|
|
250
|
-
const handleHide = useCallback(() => {
|
|
268
|
+
const handleHide = useCallback((event?: any) => {
|
|
269
|
+
if (
|
|
270
|
+
event &&
|
|
271
|
+
(tooltipRef.current?.contains(event.relatedTarget) ||
|
|
272
|
+
targetRef.current?.contains(event.relatedTarget))
|
|
273
|
+
) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
251
277
|
dispatch({type: 'hide'});
|
|
252
278
|
|
|
253
279
|
clearTimeout(timeoutIdRef.current);
|
|
@@ -261,52 +287,64 @@ const TooltipProvider: React.FunctionComponent<
|
|
|
261
287
|
}
|
|
262
288
|
}, []);
|
|
263
289
|
|
|
264
|
-
const handleShow = useCallback(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
290
|
+
const handleShow = useCallback(
|
|
291
|
+
(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
292
|
+
const target = event!.target as HTMLElement;
|
|
293
|
+
|
|
294
|
+
const hasTitle =
|
|
295
|
+
target &&
|
|
296
|
+
(target.hasAttribute('title') ||
|
|
297
|
+
target.hasAttribute('data-title'));
|
|
298
|
+
|
|
299
|
+
const titleNode = hasTitle
|
|
300
|
+
? target
|
|
301
|
+
: closestAncestor(target, '[title], [data-title]');
|
|
302
|
+
|
|
303
|
+
if (titleNode) {
|
|
304
|
+
targetRef.current = target;
|
|
305
|
+
|
|
306
|
+
target.addEventListener('click', handleHide);
|
|
307
|
+
|
|
308
|
+
const title =
|
|
309
|
+
titleNode.getAttribute('title') ||
|
|
310
|
+
titleNode.getAttribute('data-title') ||
|
|
311
|
+
'';
|
|
312
|
+
|
|
313
|
+
saveTitle(titleNode);
|
|
314
|
+
|
|
315
|
+
const customDelay =
|
|
316
|
+
titleNode.getAttribute('data-tooltip-delay');
|
|
317
|
+
const newAlign = titleNode.getAttribute(
|
|
318
|
+
'data-tooltip-align'
|
|
319
|
+
) as typeof align;
|
|
320
|
+
const setAsHTML = !!titleNode.getAttribute(
|
|
321
|
+
'data-title-set-as-html'
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
const isFloating = titleNode.getAttribute(
|
|
325
|
+
'data-tooltip-floating'
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
clearTimeout(timeoutIdRef.current);
|
|
329
|
+
|
|
330
|
+
timeoutIdRef.current = setTimeout(
|
|
331
|
+
() => {
|
|
332
|
+
dispatch({
|
|
333
|
+
align: newAlign || align,
|
|
334
|
+
floating: Boolean(isFloating),
|
|
335
|
+
message: title,
|
|
336
|
+
setAsHTML,
|
|
337
|
+
type: 'show',
|
|
338
|
+
});
|
|
339
|
+
},
|
|
340
|
+
customDelay ? Number(customDelay) : delay
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
[]
|
|
345
|
+
);
|
|
308
346
|
|
|
309
|
-
|
|
347
|
+
useEffect(() => {
|
|
310
348
|
const handleEsc = (event: KeyboardEvent) => {
|
|
311
349
|
if (show && event.key === Keys.Esc) {
|
|
312
350
|
event.stopImmediatePropagation();
|
|
@@ -320,13 +358,18 @@ const TooltipProvider: React.FunctionComponent<
|
|
|
320
358
|
return () => document.removeEventListener('keyup', handleEsc, true);
|
|
321
359
|
}, [show]);
|
|
322
360
|
|
|
323
|
-
|
|
361
|
+
useEffect(() => {
|
|
324
362
|
if (scope) {
|
|
325
363
|
const disposeShowEvents = TRIGGER_SHOW_EVENTS.map((eventName) => {
|
|
326
364
|
return delegate(document.body, eventName, scope, handleShow);
|
|
327
365
|
});
|
|
328
366
|
const disposeHideEvents = TRIGGER_HIDE_EVENTS.map((eventName) => {
|
|
329
|
-
return delegate(
|
|
367
|
+
return delegate(
|
|
368
|
+
document.body,
|
|
369
|
+
eventName,
|
|
370
|
+
`${scope}, .tooltip`,
|
|
371
|
+
handleHide
|
|
372
|
+
);
|
|
330
373
|
});
|
|
331
374
|
|
|
332
375
|
return () => {
|
|
@@ -334,12 +377,39 @@ const TooltipProvider: React.FunctionComponent<
|
|
|
334
377
|
disposeHideEvents.forEach(({dispose}) => dispose());
|
|
335
378
|
};
|
|
336
379
|
}
|
|
337
|
-
}, []);
|
|
380
|
+
}, [handleShow]);
|
|
381
|
+
|
|
382
|
+
useEffect(() => {
|
|
383
|
+
if (
|
|
384
|
+
(tooltipRef as React.RefObject<HTMLDivElement>).current &&
|
|
385
|
+
show &&
|
|
386
|
+
floating
|
|
387
|
+
) {
|
|
388
|
+
const points = ALIGNMENTS_MAP[align || 'top'] as [string, string];
|
|
338
389
|
|
|
339
|
-
|
|
390
|
+
const [clientX, clientY] = mousePosition;
|
|
391
|
+
|
|
392
|
+
alignPoint(
|
|
393
|
+
(tooltipRef as React.RefObject<HTMLDivElement>).current!,
|
|
394
|
+
{
|
|
395
|
+
clientX,
|
|
396
|
+
clientY,
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
offset: OFFSET_MAP[
|
|
400
|
+
points.join('') as keyof typeof OFFSET_MAP
|
|
401
|
+
] as [number, number],
|
|
402
|
+
points,
|
|
403
|
+
}
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
}, [show, floating]);
|
|
407
|
+
|
|
408
|
+
useEffect(() => {
|
|
340
409
|
if (
|
|
341
410
|
titleNodeRef.current &&
|
|
342
|
-
(tooltipRef as React.RefObject<HTMLDivElement>).current
|
|
411
|
+
(tooltipRef as React.RefObject<HTMLDivElement>).current &&
|
|
412
|
+
!floating
|
|
343
413
|
) {
|
|
344
414
|
const points = ALIGNMENTS_MAP[align || 'top'] as [string, string];
|
|
345
415
|
|
|
@@ -395,32 +465,43 @@ const TooltipProvider: React.FunctionComponent<
|
|
|
395
465
|
title: message,
|
|
396
466
|
});
|
|
397
467
|
|
|
468
|
+
const tooltip = show && (
|
|
469
|
+
<ClayPortal {...containerProps}>
|
|
470
|
+
<ClayTooltip alignPosition={align} ref={tooltipRef} show>
|
|
471
|
+
{setAsHTML && typeof titleContent === 'string' ? (
|
|
472
|
+
<span
|
|
473
|
+
dangerouslySetInnerHTML={{
|
|
474
|
+
__html: titleContent,
|
|
475
|
+
}}
|
|
476
|
+
/>
|
|
477
|
+
) : (
|
|
478
|
+
titleContent
|
|
479
|
+
)}
|
|
480
|
+
</ClayTooltip>
|
|
481
|
+
</ClayPortal>
|
|
482
|
+
);
|
|
483
|
+
|
|
398
484
|
return (
|
|
399
485
|
<>
|
|
400
|
-
{
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
486
|
+
{scope ? (
|
|
487
|
+
<>
|
|
488
|
+
{tooltip}
|
|
489
|
+
{children}
|
|
490
|
+
</>
|
|
491
|
+
) : (
|
|
492
|
+
children &&
|
|
493
|
+
React.cloneElement(children, {
|
|
494
|
+
...children.props,
|
|
495
|
+
children: (
|
|
496
|
+
<>
|
|
497
|
+
{children.props.children}
|
|
498
|
+
{tooltip}
|
|
499
|
+
</>
|
|
500
|
+
),
|
|
501
|
+
onMouseOut: handleHide,
|
|
502
|
+
onMouseOver: handleShow,
|
|
503
|
+
})
|
|
414
504
|
)}
|
|
415
|
-
|
|
416
|
-
{scope
|
|
417
|
-
? children
|
|
418
|
-
: children &&
|
|
419
|
-
React.cloneElement(children, {
|
|
420
|
-
...children.props,
|
|
421
|
-
onMouseOut: handleHide,
|
|
422
|
-
onMouseOver: handleShow,
|
|
423
|
-
})}
|
|
424
505
|
</>
|
|
425
506
|
);
|
|
426
507
|
};
|