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