@clayui/tooltip 3.58.0 → 3.65.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.
@@ -39,5 +39,5 @@ interface IPropsWithScope extends IPropsBase {
39
39
  */
40
40
  scope: string;
41
41
  }
42
- declare const TooltipProvider: React.FunctionComponent<IPropsWithChildren | IPropsWithScope>;
42
+ declare const TooltipProvider: ({ autoAlign, children, containerProps, contentRenderer, delay, scope, }: IPropsWithChildren | IPropsWithScope) => JSX.Element;
43
43
  export default TooltipProvider;
@@ -150,25 +150,21 @@ var TooltipProvider = function TooltipProvider(_ref2) {
150
150
  delay = _ref2$delay === void 0 ? 600 : _ref2$delay,
151
151
  scope = _ref2.scope;
152
152
 
153
- var _React$useReducer = _react.default.useReducer(reducer, initialState),
154
- _React$useReducer2 = _slicedToArray(_React$useReducer, 2),
155
- _React$useReducer2$ = _React$useReducer2[0],
156
- align = _React$useReducer2$.align,
157
- _React$useReducer2$$m = _React$useReducer2$.message,
158
- message = _React$useReducer2$$m === void 0 ? '' : _React$useReducer2$$m,
159
- setAsHTML = _React$useReducer2$.setAsHTML,
160
- show = _React$useReducer2$.show,
161
- dispatch = _React$useReducer2[1]; // Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
162
-
163
-
164
- var timeoutIdRef = _react.default.useRef();
165
-
166
- var targetRef = _react.default.useRef(null);
167
-
168
- var titleNodeRef = _react.default.useRef(null);
169
-
170
- var tooltipRef = _react.default.useRef(null);
171
-
153
+ var _useReducer = (0, _react.useReducer)(reducer, initialState),
154
+ _useReducer2 = _slicedToArray(_useReducer, 2),
155
+ _useReducer2$ = _useReducer2[0],
156
+ align = _useReducer2$.align,
157
+ _useReducer2$$message = _useReducer2$.message,
158
+ message = _useReducer2$$message === void 0 ? '' : _useReducer2$$message,
159
+ setAsHTML = _useReducer2$.setAsHTML,
160
+ show = _useReducer2$.show,
161
+ dispatch = _useReducer2[1]; // Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
162
+
163
+
164
+ var timeoutIdRef = (0, _react.useRef)();
165
+ var targetRef = (0, _react.useRef)(null);
166
+ var titleNodeRef = (0, _react.useRef)(null);
167
+ var tooltipRef = (0, _react.useRef)(null);
172
168
  var saveTitle = (0, _react.useCallback)(function (element) {
173
169
  titleNodeRef.current = element;
174
170
  var title = element.getAttribute('title');
@@ -206,7 +202,13 @@ var TooltipProvider = function TooltipProvider(_ref2) {
206
202
  titleNodeRef.current = null;
207
203
  }
208
204
  }, []);
209
- var handleHide = (0, _react.useCallback)(function () {
205
+ var handleHide = (0, _react.useCallback)(function (event) {
206
+ var _tooltipRef$current, _targetRef$current;
207
+
208
+ 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))) {
209
+ return;
210
+ }
211
+
210
212
  dispatch({
211
213
  type: 'hide'
212
214
  });
@@ -220,11 +222,11 @@ var TooltipProvider = function TooltipProvider(_ref2) {
220
222
  }, []);
221
223
  var handleShow = (0, _react.useCallback)(function (_ref3) {
222
224
  var target = _ref3.target;
223
- targetRef.current = target;
224
225
  var hasTitle = target && (target.hasAttribute('title') || target.hasAttribute('data-title'));
225
226
  var titleNode = hasTitle ? target : closestAncestor(target, '[title], [data-title]');
226
227
 
227
228
  if (titleNode) {
229
+ targetRef.current = target;
228
230
  target.addEventListener('click', handleHide);
229
231
  var title = titleNode.getAttribute('title') || titleNode.getAttribute('data-title') || '';
230
232
  saveTitle(titleNode);
@@ -244,8 +246,7 @@ var TooltipProvider = function TooltipProvider(_ref2) {
244
246
  }, customDelay ? Number(customDelay) : delay);
245
247
  }
246
248
  }, []);
247
-
248
- _react.default.useEffect(function () {
249
+ (0, _react.useEffect)(function () {
249
250
  var handleEsc = function handleEsc(event) {
250
251
  if (show && event.key === _shared.Keys.Esc) {
251
252
  event.stopImmediatePropagation();
@@ -258,14 +259,13 @@ var TooltipProvider = function TooltipProvider(_ref2) {
258
259
  return document.removeEventListener('keyup', handleEsc, true);
259
260
  };
260
261
  }, [show]);
261
-
262
- _react.default.useEffect(function () {
262
+ (0, _react.useEffect)(function () {
263
263
  if (scope) {
264
264
  var disposeShowEvents = TRIGGER_SHOW_EVENTS.map(function (eventName) {
265
265
  return (0, _shared.delegate)(document.body, eventName, scope, handleShow);
266
266
  });
267
267
  var disposeHideEvents = TRIGGER_HIDE_EVENTS.map(function (eventName) {
268
- return (0, _shared.delegate)(document.body, eventName, scope, handleHide);
268
+ return (0, _shared.delegate)(document.body, eventName, "".concat(scope, ", .tooltip"), handleHide);
269
269
  });
270
270
  return function () {
271
271
  disposeShowEvents.forEach(function (_ref4) {
@@ -279,8 +279,7 @@ var TooltipProvider = function TooltipProvider(_ref2) {
279
279
  };
280
280
  }
281
281
  }, []);
282
-
283
- _react.default.useEffect(function () {
282
+ (0, _react.useEffect)(function () {
284
283
  if (titleNodeRef.current && tooltipRef.current) {
285
284
  var points = ALIGNMENTS_MAP[align || 'top'];
286
285
  var alignment = (0, _shared.doAlign)({
@@ -308,7 +307,6 @@ var TooltipProvider = function TooltipProvider(_ref2) {
308
307
  }
309
308
  }
310
309
  }, [align, show]);
311
-
312
310
  "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
311
  "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
312
  "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 +314,8 @@ var TooltipProvider = function TooltipProvider(_ref2) {
316
314
  targetNode: targetRef.current,
317
315
  title: message
318
316
  });
319
- return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, show && /*#__PURE__*/_react.default.createElement(_shared.ClayPortal, containerProps, /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
317
+
318
+ var tooltip = show && /*#__PURE__*/_react.default.createElement(_shared.ClayPortal, containerProps, /*#__PURE__*/_react.default.createElement(_Tooltip.default, {
320
319
  alignPosition: align,
321
320
  ref: tooltipRef,
322
321
  show: true
@@ -324,7 +323,10 @@ var TooltipProvider = function TooltipProvider(_ref2) {
324
323
  dangerouslySetInnerHTML: {
325
324
  __html: titleContent
326
325
  }
327
- }) : titleContent)), scope ? children : children && /*#__PURE__*/_react.default.cloneElement(children, _objectSpread(_objectSpread({}, children.props), {}, {
326
+ }) : titleContent));
327
+
328
+ 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), {}, {
329
+ children: /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children.props.children, tooltip),
328
330
  onMouseOut: handleHide,
329
331
  onMouseOver: handleShow
330
332
  })));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clayui/tooltip",
3
- "version": "3.58.0",
3
+ "version": "3.65.0",
4
4
  "description": "ClayTooltip component",
5
5
  "license": "BSD-3-Clause",
6
6
  "repository": "https://github.com/liferay/clay",
@@ -26,7 +26,7 @@
26
26
  "react"
27
27
  ],
28
28
  "dependencies": {
29
- "@clayui/shared": "^3.58.0",
29
+ "@clayui/shared": "^3.65.0",
30
30
  "classnames": "^2.2.6",
31
31
  "warning": "^4.0.3"
32
32
  },
@@ -38,5 +38,5 @@
38
38
  "browserslist": [
39
39
  "extends browserslist-config-clay"
40
40
  ],
41
- "gitHead": "db7f178a1a0dff04d700f8dca2b04f6a5321353b"
41
+ "gitHead": "603f05c8d617d98e29f0456b5d6618f9a95ce740"
42
42
  }
@@ -10,7 +10,7 @@ import {
10
10
  delegate,
11
11
  doAlign,
12
12
  } from '@clayui/shared';
13
- import React, {useCallback} from 'react';
13
+ import React, {useCallback, useEffect, useReducer, useRef} from 'react';
14
14
  import warning from 'warning';
15
15
 
16
16
  import ClayTooltip from './Tooltip';
@@ -183,26 +183,24 @@ interface IPropsWithScope extends IPropsBase {
183
183
  scope: string;
184
184
  }
185
185
 
186
- const TooltipProvider: React.FunctionComponent<
187
- IPropsWithChildren | IPropsWithScope
188
- > = ({
186
+ const TooltipProvider = ({
189
187
  autoAlign = true,
190
188
  children,
191
189
  containerProps = {},
192
190
  contentRenderer = (props) => props.title,
193
191
  delay = 600,
194
192
  scope,
195
- }) => {
196
- const [{align, message = '', setAsHTML, show}, dispatch] = React.useReducer(
193
+ }: IPropsWithChildren | IPropsWithScope) => {
194
+ const [{align, message = '', setAsHTML, show}, dispatch] = useReducer(
197
195
  reducer,
198
196
  initialState
199
197
  );
200
198
 
201
199
  // Using `any` type since TS incorrectly infers setTimeout to be from NodeJS
202
- const timeoutIdRef = React.useRef<any>();
203
- const targetRef = React.useRef<HTMLElement | null>(null);
204
- const titleNodeRef = React.useRef<HTMLElement | null>(null);
205
- const tooltipRef = React.useRef<HTMLElement | null>(null);
200
+ const timeoutIdRef = useRef<any>();
201
+ const targetRef = useRef<HTMLElement | null>(null);
202
+ const titleNodeRef = useRef<HTMLElement | null>(null);
203
+ const tooltipRef = useRef<HTMLElement | null>(null);
206
204
 
207
205
  const saveTitle = useCallback((element: HTMLElement) => {
208
206
  titleNodeRef.current = element;
@@ -247,7 +245,15 @@ const TooltipProvider: React.FunctionComponent<
247
245
  }
248
246
  }, []);
249
247
 
250
- const handleHide = useCallback(() => {
248
+ const handleHide = useCallback((event?: any) => {
249
+ if (
250
+ event &&
251
+ (tooltipRef.current?.contains(event.relatedTarget) ||
252
+ targetRef.current?.contains(event.relatedTarget))
253
+ ) {
254
+ return;
255
+ }
256
+
251
257
  dispatch({type: 'hide'});
252
258
 
253
259
  clearTimeout(timeoutIdRef.current);
@@ -262,8 +268,6 @@ const TooltipProvider: React.FunctionComponent<
262
268
  }, []);
263
269
 
264
270
  const handleShow = useCallback(({target}: {target: HTMLElement}) => {
265
- targetRef.current = target;
266
-
267
271
  const hasTitle =
268
272
  target &&
269
273
  (target.hasAttribute('title') || target.hasAttribute('data-title'));
@@ -273,6 +277,8 @@ const TooltipProvider: React.FunctionComponent<
273
277
  : closestAncestor(target, '[title], [data-title]');
274
278
 
275
279
  if (titleNode) {
280
+ targetRef.current = target;
281
+
276
282
  target.addEventListener('click', handleHide);
277
283
 
278
284
  const title =
@@ -306,7 +312,7 @@ const TooltipProvider: React.FunctionComponent<
306
312
  }
307
313
  }, []);
308
314
 
309
- React.useEffect(() => {
315
+ useEffect(() => {
310
316
  const handleEsc = (event: KeyboardEvent) => {
311
317
  if (show && event.key === Keys.Esc) {
312
318
  event.stopImmediatePropagation();
@@ -320,13 +326,18 @@ const TooltipProvider: React.FunctionComponent<
320
326
  return () => document.removeEventListener('keyup', handleEsc, true);
321
327
  }, [show]);
322
328
 
323
- React.useEffect(() => {
329
+ useEffect(() => {
324
330
  if (scope) {
325
331
  const disposeShowEvents = TRIGGER_SHOW_EVENTS.map((eventName) => {
326
332
  return delegate(document.body, eventName, scope, handleShow);
327
333
  });
328
334
  const disposeHideEvents = TRIGGER_HIDE_EVENTS.map((eventName) => {
329
- return delegate(document.body, eventName, scope, handleHide);
335
+ return delegate(
336
+ document.body,
337
+ eventName,
338
+ `${scope}, .tooltip`,
339
+ handleHide
340
+ );
330
341
  });
331
342
 
332
343
  return () => {
@@ -336,7 +347,7 @@ const TooltipProvider: React.FunctionComponent<
336
347
  }
337
348
  }, []);
338
349
 
339
- React.useEffect(() => {
350
+ useEffect(() => {
340
351
  if (
341
352
  titleNodeRef.current &&
342
353
  (tooltipRef as React.RefObject<HTMLDivElement>).current
@@ -395,32 +406,43 @@ const TooltipProvider: React.FunctionComponent<
395
406
  title: message,
396
407
  });
397
408
 
409
+ const tooltip = show && (
410
+ <ClayPortal {...containerProps}>
411
+ <ClayTooltip alignPosition={align} ref={tooltipRef} show>
412
+ {setAsHTML && typeof titleContent === 'string' ? (
413
+ <span
414
+ dangerouslySetInnerHTML={{
415
+ __html: titleContent,
416
+ }}
417
+ />
418
+ ) : (
419
+ titleContent
420
+ )}
421
+ </ClayTooltip>
422
+ </ClayPortal>
423
+ );
424
+
398
425
  return (
399
426
  <>
400
- {show && (
401
- <ClayPortal {...containerProps}>
402
- <ClayTooltip alignPosition={align} ref={tooltipRef} show>
403
- {setAsHTML && typeof titleContent === 'string' ? (
404
- <span
405
- dangerouslySetInnerHTML={{
406
- __html: titleContent,
407
- }}
408
- />
409
- ) : (
410
- titleContent
411
- )}
412
- </ClayTooltip>
413
- </ClayPortal>
427
+ {scope ? (
428
+ <>
429
+ {tooltip}
430
+ {children}
431
+ </>
432
+ ) : (
433
+ children &&
434
+ React.cloneElement(children, {
435
+ ...children.props,
436
+ children: (
437
+ <>
438
+ {children.props.children}
439
+ {tooltip}
440
+ </>
441
+ ),
442
+ onMouseOut: handleHide,
443
+ onMouseOver: handleShow,
444
+ })
414
445
  )}
415
-
416
- {scope
417
- ? children
418
- : children &&
419
- React.cloneElement(children, {
420
- ...children.props,
421
- onMouseOut: handleHide,
422
- onMouseOver: handleShow,
423
- })}
424
446
  </>
425
447
  );
426
448
  };