@clayui/tooltip 3.142.0 → 3.143.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/cjs/Tooltip.js +36 -0
- package/lib/cjs/TooltipProvider.js +218 -0
- package/lib/{index.js → cjs/index.js} +2 -2
- package/lib/cjs/useAlign.js +101 -0
- package/lib/{useClosestTitle.js → cjs/useClosestTitle.js} +26 -27
- package/lib/cjs/useTooltipState.js +38 -0
- package/lib/esm/Tooltip.js +31 -0
- package/lib/esm/TooltipProvider.js +208 -0
- package/lib/esm/index.js +8 -0
- package/lib/esm/useAlign.js +95 -0
- package/lib/esm/useClosestTitle.js +134 -0
- package/lib/esm/useTooltipState.js +32 -0
- package/package.json +11 -8
- package/lib/Tooltip.js +0 -39
- package/lib/TooltipProvider.js +0 -233
- package/lib/useAlign.js +0 -110
- package/lib/useTooltipState.js +0 -44
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ClayPortal, Keys, delegate, useInteractionFocus } from '@clayui/shared';
|
|
7
|
+
import React, { useCallback, useEffect, useReducer, useRef } from 'react';
|
|
8
|
+
import warning from 'warning';
|
|
9
|
+
import { Tooltip } from "./Tooltip.js";
|
|
10
|
+
import { useAlign } from "./useAlign.js";
|
|
11
|
+
import { useClosestTitle } from "./useClosestTitle.js";
|
|
12
|
+
import { useTooltipState } from "./useTooltipState.js";
|
|
13
|
+
const initialState = {
|
|
14
|
+
align: 'top',
|
|
15
|
+
floating: false,
|
|
16
|
+
setAsHTML: false,
|
|
17
|
+
title: ''
|
|
18
|
+
};
|
|
19
|
+
const TRIGGER_HIDE_EVENTS = ['dragstart', 'mouseout', 'mouseup', 'pointerup', 'touchend'];
|
|
20
|
+
const TRIGGER_SHOW_EVENTS = ['mouseover', 'mouseup', 'pointerdown', 'touchstart'];
|
|
21
|
+
const reducer = (state, _ref) => {
|
|
22
|
+
let {
|
|
23
|
+
type,
|
|
24
|
+
...payload
|
|
25
|
+
} = _ref;
|
|
26
|
+
switch (type) {
|
|
27
|
+
case 'update':
|
|
28
|
+
return {
|
|
29
|
+
...state,
|
|
30
|
+
...payload
|
|
31
|
+
};
|
|
32
|
+
case 'reset':
|
|
33
|
+
return {
|
|
34
|
+
...state,
|
|
35
|
+
align: initialState.align,
|
|
36
|
+
floating: false
|
|
37
|
+
};
|
|
38
|
+
default:
|
|
39
|
+
throw new TypeError();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
export const ClayTooltipProvider = _ref2 => {
|
|
43
|
+
let {
|
|
44
|
+
autoAlign = true,
|
|
45
|
+
children,
|
|
46
|
+
containerProps = {},
|
|
47
|
+
contentRenderer = props => props.title,
|
|
48
|
+
delay = 600,
|
|
49
|
+
scope
|
|
50
|
+
} = _ref2;
|
|
51
|
+
const [{
|
|
52
|
+
align,
|
|
53
|
+
floating,
|
|
54
|
+
setAsHTML,
|
|
55
|
+
title = ''
|
|
56
|
+
}, dispatch] = useReducer(reducer, initialState);
|
|
57
|
+
const tooltipRef = useRef(null);
|
|
58
|
+
const {
|
|
59
|
+
getInteraction,
|
|
60
|
+
isFocusVisible
|
|
61
|
+
} = useInteractionFocus();
|
|
62
|
+
const isHovered = useRef(false);
|
|
63
|
+
const isFocused = useRef(false);
|
|
64
|
+
const {
|
|
65
|
+
close,
|
|
66
|
+
isOpen,
|
|
67
|
+
open
|
|
68
|
+
} = useTooltipState({
|
|
69
|
+
delay
|
|
70
|
+
});
|
|
71
|
+
const {
|
|
72
|
+
forceHide,
|
|
73
|
+
getProps,
|
|
74
|
+
onHide,
|
|
75
|
+
target,
|
|
76
|
+
titleNode
|
|
77
|
+
} = useClosestTitle({
|
|
78
|
+
forceHide: useCallback(() => {
|
|
79
|
+
dispatch({
|
|
80
|
+
type: 'reset'
|
|
81
|
+
});
|
|
82
|
+
close();
|
|
83
|
+
}, []),
|
|
84
|
+
onClick: useCallback(() => {
|
|
85
|
+
isFocused.current = false;
|
|
86
|
+
isHovered.current = false;
|
|
87
|
+
}, []),
|
|
88
|
+
onHide: useCallback(() => {
|
|
89
|
+
if (!isHovered.current && !isFocused.current) {
|
|
90
|
+
dispatch({
|
|
91
|
+
type: 'reset'
|
|
92
|
+
});
|
|
93
|
+
close();
|
|
94
|
+
}
|
|
95
|
+
}, []),
|
|
96
|
+
tooltipRef
|
|
97
|
+
});
|
|
98
|
+
useAlign({
|
|
99
|
+
align,
|
|
100
|
+
autoAlign,
|
|
101
|
+
floating,
|
|
102
|
+
isOpen,
|
|
103
|
+
onAlign: useCallback(align => dispatch({
|
|
104
|
+
align,
|
|
105
|
+
type: 'update'
|
|
106
|
+
}), []),
|
|
107
|
+
sourceElement: tooltipRef,
|
|
108
|
+
targetElement: titleNode,
|
|
109
|
+
title
|
|
110
|
+
});
|
|
111
|
+
const onShow = useCallback(event => {
|
|
112
|
+
if (isHovered.current || isFocused.current) {
|
|
113
|
+
const props = getProps(event, isHovered.current);
|
|
114
|
+
if (props) {
|
|
115
|
+
dispatch({
|
|
116
|
+
align: props.align ?? align,
|
|
117
|
+
floating: props.floating,
|
|
118
|
+
setAsHTML: props.setAsHTML,
|
|
119
|
+
title: props.title,
|
|
120
|
+
type: 'update'
|
|
121
|
+
});
|
|
122
|
+
open(isFocused.current, props.delay ? Number(props.delay) : undefined);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}, [align]);
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
const handleEsc = event => {
|
|
128
|
+
if (isOpen && event.key === Keys.Esc) {
|
|
129
|
+
event.stopImmediatePropagation();
|
|
130
|
+
forceHide();
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
document.addEventListener('keyup', handleEsc, true);
|
|
134
|
+
return () => document.removeEventListener('keyup', handleEsc, true);
|
|
135
|
+
}, [isOpen]);
|
|
136
|
+
const onHoverStart = event => {
|
|
137
|
+
if (getInteraction() === 'pointer') {
|
|
138
|
+
isHovered.current = true;
|
|
139
|
+
} else {
|
|
140
|
+
isHovered.current = false;
|
|
141
|
+
}
|
|
142
|
+
onShow(event);
|
|
143
|
+
};
|
|
144
|
+
const onHoverEnd = event => {
|
|
145
|
+
isFocused.current = false;
|
|
146
|
+
isHovered.current = false;
|
|
147
|
+
onHide(event);
|
|
148
|
+
};
|
|
149
|
+
const onFocus = event => {
|
|
150
|
+
if (isFocusVisible()) {
|
|
151
|
+
isFocused.current = true;
|
|
152
|
+
onShow(event);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const onBlur = event => {
|
|
156
|
+
isFocused.current = false;
|
|
157
|
+
isHovered.current = false;
|
|
158
|
+
onHide(event);
|
|
159
|
+
};
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (scope) {
|
|
162
|
+
const disposeShowEvents = TRIGGER_SHOW_EVENTS.map(eventName => delegate(document.body, eventName, scope, onHoverStart));
|
|
163
|
+
const disposeHideEvents = TRIGGER_HIDE_EVENTS.map(eventName => delegate(document.body, eventName, `${scope}, .tooltip`, onHoverEnd));
|
|
164
|
+
const disposeShowFocus = delegate(document.body, 'focus', `${scope}, .tooltip`, onFocus, true);
|
|
165
|
+
const disposeCloseBlur = delegate(document.body, 'blur', `${scope}, .tooltip`, onBlur, true);
|
|
166
|
+
return () => {
|
|
167
|
+
disposeShowEvents.forEach(_ref3 => {
|
|
168
|
+
let {
|
|
169
|
+
dispose
|
|
170
|
+
} = _ref3;
|
|
171
|
+
return dispose();
|
|
172
|
+
});
|
|
173
|
+
disposeHideEvents.forEach(_ref4 => {
|
|
174
|
+
let {
|
|
175
|
+
dispose
|
|
176
|
+
} = _ref4;
|
|
177
|
+
return dispose();
|
|
178
|
+
});
|
|
179
|
+
disposeShowFocus.dispose();
|
|
180
|
+
disposeCloseBlur.dispose();
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}, [onShow]);
|
|
184
|
+
"production" !== "production" ? warning(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;
|
|
185
|
+
"production" !== "production" ? warning(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;
|
|
186
|
+
"production" !== "production" ? warning(children?.type !== React.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;
|
|
187
|
+
const titleContent = contentRenderer({
|
|
188
|
+
targetNode: target.current,
|
|
189
|
+
title
|
|
190
|
+
});
|
|
191
|
+
const tooltip = isOpen && /*#__PURE__*/React.createElement(ClayPortal, containerProps, /*#__PURE__*/React.createElement(Tooltip, {
|
|
192
|
+
alignPosition: align,
|
|
193
|
+
ref: tooltipRef,
|
|
194
|
+
show: true
|
|
195
|
+
}, setAsHTML && typeof titleContent === 'string' ? /*#__PURE__*/React.createElement("span", {
|
|
196
|
+
dangerouslySetInnerHTML: {
|
|
197
|
+
__html: titleContent
|
|
198
|
+
}
|
|
199
|
+
}) : titleContent));
|
|
200
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, scope ? /*#__PURE__*/React.createElement(React.Fragment, null, tooltip, children) : children && /*#__PURE__*/React.cloneElement(children, {
|
|
201
|
+
...children.props,
|
|
202
|
+
children: /*#__PURE__*/React.createElement(React.Fragment, null, children.props.children, tooltip),
|
|
203
|
+
onBlur,
|
|
204
|
+
onFocus,
|
|
205
|
+
onMouseOut: onHoverEnd,
|
|
206
|
+
onMouseOver: onHoverStart
|
|
207
|
+
}));
|
|
208
|
+
};
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*/
|
|
5
|
+
import { Tooltip } from "./Tooltip.js";
|
|
6
|
+
import { ClayTooltipProvider } from "./TooltipProvider.js";
|
|
7
|
+
export { Tooltip, ClayTooltipProvider };
|
|
8
|
+
export default Tooltip;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { doAlign, useMousePosition } from '@clayui/shared';
|
|
7
|
+
import { alignPoint } from 'dom-align';
|
|
8
|
+
import { useEffect } from 'react';
|
|
9
|
+
const ALIGNMENTS = ['top', 'top-right', 'right', 'bottom-right', 'bottom', 'bottom-left', 'left', 'top-left'];
|
|
10
|
+
const ALIGNMENTS_MAP = {
|
|
11
|
+
bottom: ['tc', 'bc'],
|
|
12
|
+
'bottom-left': ['tl', 'bl'],
|
|
13
|
+
'bottom-right': ['tr', 'br'],
|
|
14
|
+
left: ['cr', 'cl'],
|
|
15
|
+
right: ['cl', 'cr'],
|
|
16
|
+
top: ['bc', 'tc'],
|
|
17
|
+
'top-left': ['bl', 'tl'],
|
|
18
|
+
'top-right': ['br', 'tr']
|
|
19
|
+
};
|
|
20
|
+
const ALIGNMENTS_INVERSE_MAP = {
|
|
21
|
+
bctc: 'top',
|
|
22
|
+
bltl: 'top-left',
|
|
23
|
+
brtr: 'top-right',
|
|
24
|
+
clcr: 'right',
|
|
25
|
+
crcl: 'left',
|
|
26
|
+
tcbc: 'bottom',
|
|
27
|
+
tlbl: 'bottom-left',
|
|
28
|
+
trbr: 'bottom-right'
|
|
29
|
+
};
|
|
30
|
+
const BOTTOM_OFFSET = [0, 7];
|
|
31
|
+
const LEFT_OFFSET = [-7, 0];
|
|
32
|
+
const RIGHT_OFFSET = [7, 0];
|
|
33
|
+
const TOP_OFFSET = [0, -7];
|
|
34
|
+
const OFFSET_MAP = {
|
|
35
|
+
bctc: TOP_OFFSET,
|
|
36
|
+
bltl: TOP_OFFSET,
|
|
37
|
+
brtr: TOP_OFFSET,
|
|
38
|
+
clcr: RIGHT_OFFSET,
|
|
39
|
+
crcl: LEFT_OFFSET,
|
|
40
|
+
tcbc: BOTTOM_OFFSET,
|
|
41
|
+
tlbl: BOTTOM_OFFSET,
|
|
42
|
+
trbr: BOTTOM_OFFSET
|
|
43
|
+
};
|
|
44
|
+
const ALIGNMENTS_FORCE_MAP = {
|
|
45
|
+
...ALIGNMENTS_INVERSE_MAP,
|
|
46
|
+
bctc: 'top-left',
|
|
47
|
+
tcbc: 'bottom-left'
|
|
48
|
+
};
|
|
49
|
+
export function useAlign(_ref) {
|
|
50
|
+
let {
|
|
51
|
+
align,
|
|
52
|
+
autoAlign,
|
|
53
|
+
floating,
|
|
54
|
+
isOpen,
|
|
55
|
+
onAlign,
|
|
56
|
+
sourceElement,
|
|
57
|
+
targetElement,
|
|
58
|
+
title
|
|
59
|
+
} = _ref;
|
|
60
|
+
const mousePosition = useMousePosition(20);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (sourceElement.current && isOpen && floating) {
|
|
63
|
+
const points = ALIGNMENTS_MAP[align || 'top'];
|
|
64
|
+
const [clientX, clientY] = mousePosition;
|
|
65
|
+
alignPoint(sourceElement.current, {
|
|
66
|
+
clientX,
|
|
67
|
+
clientY
|
|
68
|
+
}, {
|
|
69
|
+
offset: OFFSET_MAP[points.join('')],
|
|
70
|
+
points
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}, [isOpen, floating]);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (targetElement.current && sourceElement.current && isOpen && !floating) {
|
|
76
|
+
const points = ALIGNMENTS_MAP[align || 'top'];
|
|
77
|
+
const alignment = doAlign({
|
|
78
|
+
overflow: {
|
|
79
|
+
adjustX: autoAlign,
|
|
80
|
+
adjustY: autoAlign
|
|
81
|
+
},
|
|
82
|
+
points,
|
|
83
|
+
sourceElement: sourceElement.current,
|
|
84
|
+
targetElement: targetElement.current
|
|
85
|
+
});
|
|
86
|
+
const alignmentString = alignment.points.join('');
|
|
87
|
+
const pointsString = points.join('');
|
|
88
|
+
if (alignment.overflow.adjustX) {
|
|
89
|
+
onAlign(ALIGNMENTS_FORCE_MAP[alignmentString]);
|
|
90
|
+
} else if (pointsString !== alignmentString) {
|
|
91
|
+
onAlign(ALIGNMENTS_INVERSE_MAP[alignmentString]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}, [align, title, isOpen]);
|
|
95
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback, useRef } from 'react';
|
|
7
|
+
function matches(element, selectorString) {
|
|
8
|
+
if (element.matches) {
|
|
9
|
+
return element.matches(selectorString);
|
|
10
|
+
} else if (element.msMatchesSelector) {
|
|
11
|
+
return element.msMatchesSelector(selectorString);
|
|
12
|
+
} else if (element.webkitMatchesSelector) {
|
|
13
|
+
return element.webkitMatchesSelector(selectorString);
|
|
14
|
+
} else {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function closestAncestor(node, s) {
|
|
19
|
+
const element = node;
|
|
20
|
+
let ancestor = node;
|
|
21
|
+
if (!document.documentElement.contains(element)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
do {
|
|
25
|
+
if (matches(ancestor, s)) {
|
|
26
|
+
return ancestor;
|
|
27
|
+
}
|
|
28
|
+
ancestor = ancestor.parentElement;
|
|
29
|
+
} while (ancestor !== null);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
export function useClosestTitle(props) {
|
|
33
|
+
const targetRef = useRef(null);
|
|
34
|
+
const titleNodeRef = useRef(null);
|
|
35
|
+
const saveTitle = useCallback(element => {
|
|
36
|
+
const title = element.getAttribute('title');
|
|
37
|
+
if (title) {
|
|
38
|
+
element.setAttribute('data-restore-title', title);
|
|
39
|
+
element.removeAttribute('title');
|
|
40
|
+
} else if (element.tagName === 'svg') {
|
|
41
|
+
const titleTag = element.querySelector('title');
|
|
42
|
+
if (titleTag) {
|
|
43
|
+
element.setAttribute('data-restore-title', titleTag.innerHTML);
|
|
44
|
+
titleTag.remove();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const hasParentTitle = element.closest('[title]');
|
|
48
|
+
if (hasParentTitle) {
|
|
49
|
+
saveTitle(hasParentTitle);
|
|
50
|
+
}
|
|
51
|
+
}, []);
|
|
52
|
+
const restoreTitle = useCallback(element => {
|
|
53
|
+
const title = element.getAttribute('data-restore-title');
|
|
54
|
+
if (title) {
|
|
55
|
+
if (element.tagName === 'svg') {
|
|
56
|
+
const titleTag = document.createElement('title');
|
|
57
|
+
titleTag.innerHTML = title;
|
|
58
|
+
element.appendChild(titleTag);
|
|
59
|
+
} else {
|
|
60
|
+
element.setAttribute('title', title);
|
|
61
|
+
}
|
|
62
|
+
element.removeAttribute('data-restore-title');
|
|
63
|
+
}
|
|
64
|
+
const hasParentTitle = element.closest('[data-restore-title]');
|
|
65
|
+
if (hasParentTitle) {
|
|
66
|
+
restoreTitle(hasParentTitle);
|
|
67
|
+
}
|
|
68
|
+
}, []);
|
|
69
|
+
const onClick = useCallback(event => {
|
|
70
|
+
props.onClick();
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
72
|
+
onHide(event);
|
|
73
|
+
}, []);
|
|
74
|
+
const onHide = useCallback(event => {
|
|
75
|
+
if (event && !event.relatedTarget?.getAttribute('title') && (props.tooltipRef.current?.contains(event.relatedTarget) || targetRef.current?.contains(event.relatedTarget))) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
props.onHide();
|
|
79
|
+
if (titleNodeRef.current) {
|
|
80
|
+
restoreTitle(titleNodeRef.current);
|
|
81
|
+
titleNodeRef.current = null;
|
|
82
|
+
}
|
|
83
|
+
if (targetRef.current) {
|
|
84
|
+
targetRef.current.removeEventListener('click', onClick);
|
|
85
|
+
targetRef.current = null;
|
|
86
|
+
}
|
|
87
|
+
}, []);
|
|
88
|
+
const forceHide = useCallback(() => {
|
|
89
|
+
props.forceHide();
|
|
90
|
+
if (titleNodeRef.current) {
|
|
91
|
+
restoreTitle(titleNodeRef.current);
|
|
92
|
+
titleNodeRef.current = null;
|
|
93
|
+
}
|
|
94
|
+
if (targetRef.current) {
|
|
95
|
+
targetRef.current.removeEventListener('click', onClick);
|
|
96
|
+
targetRef.current = null;
|
|
97
|
+
}
|
|
98
|
+
}, []);
|
|
99
|
+
const getProps = useCallback((event, hideBrowserTitle) => {
|
|
100
|
+
if (targetRef.current) {
|
|
101
|
+
props.onClick();
|
|
102
|
+
if (onHide(event) === null) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const target = event.target;
|
|
107
|
+
const hasTitle = target && (target.hasAttribute('[title]') || target.hasAttribute('[data-title]'));
|
|
108
|
+
const node = hasTitle ? target : closestAncestor(target, '[title], [data-title]');
|
|
109
|
+
const hasNonEmptyTitle = node?.getAttribute('title') !== '';
|
|
110
|
+
if (node && hasNonEmptyTitle) {
|
|
111
|
+
targetRef.current = target;
|
|
112
|
+
target.addEventListener('click', onClick);
|
|
113
|
+
const title = node.getAttribute('title') || node.getAttribute('data-title') || '';
|
|
114
|
+
titleNodeRef.current = node;
|
|
115
|
+
if (hideBrowserTitle) {
|
|
116
|
+
saveTitle(node);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
align: node.getAttribute('data-tooltip-align'),
|
|
120
|
+
delay: node.getAttribute('data-tooltip-delay'),
|
|
121
|
+
floating: Boolean(node.getAttribute('data-tooltip-floating')),
|
|
122
|
+
setAsHTML: !!node.getAttribute('data-title-set-as-html'),
|
|
123
|
+
title
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}, []);
|
|
127
|
+
return {
|
|
128
|
+
forceHide,
|
|
129
|
+
getProps,
|
|
130
|
+
onHide,
|
|
131
|
+
target: targetRef,
|
|
132
|
+
titleNode: titleNodeRef
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
|
|
3
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useCallback, useRef, useState } from 'react';
|
|
7
|
+
export function useTooltipState(_ref) {
|
|
8
|
+
let {
|
|
9
|
+
delay = 600
|
|
10
|
+
} = _ref;
|
|
11
|
+
const [isOpen, setOpen] = useState(false);
|
|
12
|
+
const timeoutIdRef = useRef();
|
|
13
|
+
const open = useCallback((immediate, customDelay) => {
|
|
14
|
+
if (!immediate) {
|
|
15
|
+
clearTimeout(timeoutIdRef.current);
|
|
16
|
+
timeoutIdRef.current = setTimeout(() => {
|
|
17
|
+
setOpen(true);
|
|
18
|
+
}, customDelay !== undefined ? customDelay : delay);
|
|
19
|
+
} else {
|
|
20
|
+
setOpen(true);
|
|
21
|
+
}
|
|
22
|
+
}, []);
|
|
23
|
+
const close = useCallback(() => {
|
|
24
|
+
clearTimeout(timeoutIdRef.current);
|
|
25
|
+
setOpen(false);
|
|
26
|
+
}, []);
|
|
27
|
+
return {
|
|
28
|
+
close,
|
|
29
|
+
isOpen,
|
|
30
|
+
open
|
|
31
|
+
};
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clayui/tooltip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.143.0",
|
|
4
4
|
"description": "ClayTooltip component",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"repository": "https://github.com/liferay/clay",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
"main": "lib/cjs/index.js",
|
|
8
|
+
"module": "lib/esm/index.js",
|
|
9
|
+
"exports": {
|
|
10
|
+
"import": "./lib/esm/index.js",
|
|
11
|
+
"require": "./lib/cjs/index.js"
|
|
10
12
|
},
|
|
11
|
-
"main": "lib/index.js",
|
|
12
13
|
"types": "lib/index.d.ts",
|
|
13
14
|
"ts:main": "src/index.tsx",
|
|
14
15
|
"files": [
|
|
15
16
|
"lib"
|
|
16
17
|
],
|
|
17
18
|
"scripts": {
|
|
18
|
-
"build": "
|
|
19
|
+
"build": "yarn build:cjs && yarn build:esm",
|
|
20
|
+
"build:cjs": "cross-env NODE_ENV=production babel src --root-mode upward --out-dir lib/cjs --extensions .ts,.tsx",
|
|
21
|
+
"build:esm": "cross-env NODE_ENV=production babel src --root-mode upward --out-dir lib/esm --extensions .ts,.tsx --env-name esm",
|
|
19
22
|
"buildTypes": "cross-env NODE_ENV=production tsc --project ./tsconfig.declarations.json",
|
|
20
23
|
"format": "prettier --write \"**/*.{js,ts,tsx,md,mdx,json,scss}\"",
|
|
21
24
|
"test": "jest --config ../../jest.config.js"
|
|
@@ -25,7 +28,7 @@
|
|
|
25
28
|
"react"
|
|
26
29
|
],
|
|
27
30
|
"dependencies": {
|
|
28
|
-
"@clayui/shared": "^3.
|
|
31
|
+
"@clayui/shared": "^3.143.0",
|
|
29
32
|
"classnames": "^2.2.6",
|
|
30
33
|
"dom-align": "^1.12.2",
|
|
31
34
|
"warning": "^4.0.3"
|
|
@@ -38,5 +41,5 @@
|
|
|
38
41
|
"browserslist": [
|
|
39
42
|
"extends browserslist-config-clay"
|
|
40
43
|
],
|
|
41
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "aacf20646cc7fb25c4d60e865ec77d2d503d23e9"
|
|
42
45
|
}
|
package/lib/Tooltip.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.Tooltip = exports.ALIGN_POSITIONS = void 0;
|
|
7
|
-
var _classnames = _interopRequireDefault(require("classnames"));
|
|
8
|
-
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
var _excluded = ["alignPosition", "children", "className", "show"];
|
|
10
|
-
/**
|
|
11
|
-
* SPDX-FileCopyrightText: © 2019 Liferay, Inc. <https://liferay.com>
|
|
12
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
13
|
-
*/
|
|
14
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
-
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) { ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } } return n; }, _extends.apply(null, arguments); }
|
|
16
|
-
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var s = Object.getOwnPropertySymbols(e); for (r = 0; r < s.length; r++) { o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } } return i; }
|
|
17
|
-
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) { if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } } return t; }
|
|
18
|
-
var ALIGN_POSITIONS = exports.ALIGN_POSITIONS = ['top', 'top-left', 'top-right', 'bottom', 'bottom-left', 'bottom-right', 'left', 'right'];
|
|
19
|
-
var Tooltip = exports.Tooltip = /*#__PURE__*/_react.default.forwardRef(function (_ref, ref) {
|
|
20
|
-
var _ref$alignPosition = _ref.alignPosition,
|
|
21
|
-
alignPosition = _ref$alignPosition === void 0 ? 'bottom' : _ref$alignPosition,
|
|
22
|
-
children = _ref.children,
|
|
23
|
-
className = _ref.className,
|
|
24
|
-
show = _ref.show,
|
|
25
|
-
otherProps = _objectWithoutProperties(_ref, _excluded);
|
|
26
|
-
return /*#__PURE__*/_react.default.createElement("div", _extends({
|
|
27
|
-
className: (0, _classnames.default)(className, 'tooltip', "clay-tooltip-".concat(alignPosition), {
|
|
28
|
-
show: show
|
|
29
|
-
}),
|
|
30
|
-
role: "tooltip"
|
|
31
|
-
}, otherProps, {
|
|
32
|
-
ref: ref
|
|
33
|
-
}), /*#__PURE__*/_react.default.createElement("div", {
|
|
34
|
-
className: "arrow"
|
|
35
|
-
}), /*#__PURE__*/_react.default.createElement("div", {
|
|
36
|
-
className: "tooltip-inner"
|
|
37
|
-
}, children));
|
|
38
|
-
});
|
|
39
|
-
Tooltip.displayName = 'ClayTooltip';
|