@clayui/tooltip 3.65.0 → 3.67.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.js +47 -9
- package/package.json +4 -3
- package/src/TooltipProvider.tsx +101 -42
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
|
|
|
@@ -154,12 +171,14 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
154
171
|
_useReducer2 = _slicedToArray(_useReducer, 2),
|
|
155
172
|
_useReducer2$ = _useReducer2[0],
|
|
156
173
|
align = _useReducer2$.align,
|
|
174
|
+
floating = _useReducer2$.floating,
|
|
157
175
|
_useReducer2$$message = _useReducer2$.message,
|
|
158
176
|
message = _useReducer2$$message === void 0 ? '' : _useReducer2$$message,
|
|
159
177
|
setAsHTML = _useReducer2$.setAsHTML,
|
|
160
178
|
show = _useReducer2$.show,
|
|
161
|
-
dispatch = _useReducer2[1];
|
|
179
|
+
dispatch = _useReducer2[1];
|
|
162
180
|
|
|
181
|
+
var mousePosition = (0, _shared.useMousePosition)(20); // Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
|
|
163
182
|
|
|
164
183
|
var timeoutIdRef = (0, _react.useRef)();
|
|
165
184
|
var targetRef = (0, _react.useRef)(null);
|
|
@@ -220,8 +239,8 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
220
239
|
targetRef.current = null;
|
|
221
240
|
}
|
|
222
241
|
}, []);
|
|
223
|
-
var handleShow = (0, _react.useCallback)(function (
|
|
224
|
-
var target =
|
|
242
|
+
var handleShow = (0, _react.useCallback)(function (event) {
|
|
243
|
+
var target = event.target;
|
|
225
244
|
var hasTitle = target && (target.hasAttribute('title') || target.hasAttribute('data-title'));
|
|
226
245
|
var titleNode = hasTitle ? target : closestAncestor(target, '[title], [data-title]');
|
|
227
246
|
|
|
@@ -235,10 +254,12 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
235
254
|
|
|
236
255
|
var _setAsHTML = !!titleNode.getAttribute('data-title-set-as-html');
|
|
237
256
|
|
|
257
|
+
var isFloating = titleNode.getAttribute('data-tooltip-floating');
|
|
238
258
|
clearTimeout(timeoutIdRef.current);
|
|
239
259
|
timeoutIdRef.current = setTimeout(function () {
|
|
240
260
|
dispatch({
|
|
241
261
|
align: newAlign || align,
|
|
262
|
+
floating: Boolean(isFloating),
|
|
242
263
|
message: title,
|
|
243
264
|
setAsHTML: _setAsHTML,
|
|
244
265
|
type: 'show'
|
|
@@ -268,19 +289,36 @@ var TooltipProvider = function TooltipProvider(_ref2) {
|
|
|
268
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];
|
|
310
|
+
|
|
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
|
+
}, [mousePosition, show, floating]);
|
|
282
320
|
(0, _react.useEffect)(function () {
|
|
283
|
-
if (titleNodeRef.current && tooltipRef.current) {
|
|
321
|
+
if (titleNodeRef.current && tooltipRef.current && !floating) {
|
|
284
322
|
var points = ALIGNMENTS_MAP[align || 'top'];
|
|
285
323
|
var alignment = (0, _shared.doAlign)({
|
|
286
324
|
overflow: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clayui/tooltip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.67.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.67.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": "71e84490088d72afb0240a7ef69cde23a6d5dd19"
|
|
42
43
|
}
|
package/src/TooltipProvider.tsx
CHANGED
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
Keys,
|
|
10
10
|
delegate,
|
|
11
11
|
doAlign,
|
|
12
|
+
useMousePosition,
|
|
12
13
|
} from '@clayui/shared';
|
|
14
|
+
import {alignPoint} from 'dom-align';
|
|
13
15
|
import React, {useCallback, useEffect, useReducer, useRef} from 'react';
|
|
14
16
|
import warning from 'warning';
|
|
15
17
|
|
|
@@ -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:
|
|
@@ -191,10 +211,10 @@ const TooltipProvider = ({
|
|
|
191
211
|
delay = 600,
|
|
192
212
|
scope,
|
|
193
213
|
}: IPropsWithChildren | IPropsWithScope) => {
|
|
194
|
-
const [{align, message = '', setAsHTML, show}, dispatch] =
|
|
195
|
-
reducer,
|
|
196
|
-
|
|
197
|
-
);
|
|
214
|
+
const [{align, floating, message = '', setAsHTML, show}, dispatch] =
|
|
215
|
+
useReducer(reducer, initialState);
|
|
216
|
+
|
|
217
|
+
const mousePosition = useMousePosition(20);
|
|
198
218
|
|
|
199
219
|
// Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
|
|
200
220
|
const timeoutIdRef = useRef<any>();
|
|
@@ -267,50 +287,62 @@ const TooltipProvider = ({
|
|
|
267
287
|
}
|
|
268
288
|
}, []);
|
|
269
289
|
|
|
270
|
-
const handleShow = useCallback(
|
|
271
|
-
|
|
272
|
-
target
|
|
273
|
-
(target.hasAttribute('title') || target.hasAttribute('data-title'));
|
|
290
|
+
const handleShow = useCallback(
|
|
291
|
+
(event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
292
|
+
const target = event!.target as HTMLElement;
|
|
274
293
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
294
|
+
const hasTitle =
|
|
295
|
+
target &&
|
|
296
|
+
(target.hasAttribute('title') ||
|
|
297
|
+
target.hasAttribute('data-title'));
|
|
278
298
|
|
|
279
|
-
|
|
280
|
-
|
|
299
|
+
const titleNode = hasTitle
|
|
300
|
+
? target
|
|
301
|
+
: closestAncestor(target, '[title], [data-title]');
|
|
281
302
|
|
|
282
|
-
|
|
303
|
+
if (titleNode) {
|
|
304
|
+
targetRef.current = target;
|
|
283
305
|
|
|
284
|
-
|
|
285
|
-
titleNode.getAttribute('title') ||
|
|
286
|
-
titleNode.getAttribute('data-title') ||
|
|
287
|
-
'';
|
|
306
|
+
target.addEventListener('click', handleHide);
|
|
288
307
|
|
|
289
|
-
|
|
308
|
+
const title =
|
|
309
|
+
titleNode.getAttribute('title') ||
|
|
310
|
+
titleNode.getAttribute('data-title') ||
|
|
311
|
+
'';
|
|
290
312
|
|
|
291
|
-
|
|
292
|
-
const newAlign = titleNode.getAttribute(
|
|
293
|
-
'data-tooltip-align'
|
|
294
|
-
) as typeof align;
|
|
295
|
-
const setAsHTML = !!titleNode.getAttribute(
|
|
296
|
-
'data-title-set-as-html'
|
|
297
|
-
);
|
|
313
|
+
saveTitle(titleNode);
|
|
298
314
|
|
|
299
|
-
|
|
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
|
+
);
|
|
300
323
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
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
|
+
);
|
|
314
346
|
|
|
315
347
|
useEffect(() => {
|
|
316
348
|
const handleEsc = (event: KeyboardEvent) => {
|
|
@@ -345,12 +377,39 @@ const TooltipProvider = ({
|
|
|
345
377
|
disposeHideEvents.forEach(({dispose}) => dispose());
|
|
346
378
|
};
|
|
347
379
|
}
|
|
348
|
-
}, []);
|
|
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];
|
|
389
|
+
|
|
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
|
+
}, [mousePosition, show, floating]);
|
|
349
407
|
|
|
350
408
|
useEffect(() => {
|
|
351
409
|
if (
|
|
352
410
|
titleNodeRef.current &&
|
|
353
|
-
(tooltipRef as React.RefObject<HTMLDivElement>).current
|
|
411
|
+
(tooltipRef as React.RefObject<HTMLDivElement>).current &&
|
|
412
|
+
!floating
|
|
354
413
|
) {
|
|
355
414
|
const points = ALIGNMENTS_MAP[align || 'top'] as [string, string];
|
|
356
415
|
|