react-tooltip 5.22.0-beta.1109.1 → 5.23.0-beta.1109.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.
@@ -6,4 +6,6 @@
6
6
  --rt-color-warning: #f0ad4e;
7
7
  --rt-color-info: #337ab7;
8
8
  --rt-opacity: 0.9;
9
+ --rt-transition-show-delay: 0.15s;
10
+ --rt-transition-closing-delay: 0.15s;
9
11
  }
@@ -327,13 +327,13 @@ const computeTooltipPosition = async ({ elementReference = null, tooltipReferenc
327
327
  });
328
328
  };
329
329
 
330
- var coreStyles = {"tooltip":"core-styles-module_tooltip__3vRRp","fixed":"core-styles-module_fixed__pcSol","arrow":"core-styles-module_arrow__cvMwQ","noArrow":"core-styles-module_noArrow__xock6","clickable":"core-styles-module_clickable__ZuTTB","show":"core-styles-module_show__Nt9eE"};
330
+ var coreStyles = {"tooltip":"core-styles-module_tooltip__3vRRp","fixed":"core-styles-module_fixed__pcSol","arrow":"core-styles-module_arrow__cvMwQ","noArrow":"core-styles-module_noArrow__xock6","clickable":"core-styles-module_clickable__ZuTTB","show":"core-styles-module_show__Nt9eE","closing":"core-styles-module_closing__sGnxF"};
331
331
 
332
332
  var styles = {"tooltip":"styles-module_tooltip__mnnfp","arrow":"styles-module_arrow__K0L3T","dark":"styles-module_dark__xNqje","light":"styles-module_light__Z6W-X","success":"styles-module_success__A2AKt","warning":"styles-module_warning__SCK0X","error":"styles-module_error__JvumD","info":"styles-module_info__BWdHW"};
333
333
 
334
334
  const Tooltip = ({
335
335
  // props
336
- forwardRef, id, className, classNameArrow, variant = 'dark', anchorId, anchorSelect, place = 'top', offset = 10, events = ['hover'], openOnClick = false, positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, closeOnEsc = false, closeOnScroll = false, closeOnResize = false, style: externalStyles, position, afterShow, afterHide,
336
+ forwardRef, id, className, classNameArrow, variant = 'dark', anchorId, anchorSelect, place = 'top', offset = 10, events = ['hover'], openOnClick = false, positionStrategy = 'absolute', middlewares, wrapper: WrapperElement, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, closeOnEsc = false, closeOnScroll = false, closeOnResize = false, openEvents, closeEvents, globalCloseEvents, imperativeModeOnly, style: externalStyles, position, afterShow, afterHide,
337
337
  // props handled by controller
338
338
  content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
339
339
  var _a;
@@ -356,7 +356,72 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
356
356
  const hoveringTooltip = React.useRef(false);
357
357
  const [anchorsBySelect, setAnchorsBySelect] = React.useState([]);
358
358
  const mounted = React.useRef(false);
359
+ /**
360
+ * @todo Update when deprecated stuff gets removed.
361
+ */
359
362
  const shouldOpenOnClick = openOnClick || events.includes('click');
363
+ const hasClickEvent = shouldOpenOnClick || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.click) || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.dblclick) || (openEvents === null || openEvents === void 0 ? void 0 : openEvents.mousedown);
364
+ const actualOpenEvents = openEvents
365
+ ? { ...openEvents }
366
+ : {
367
+ mouseenter: true,
368
+ focus: true,
369
+ click: false,
370
+ dblclick: false,
371
+ mousedown: false,
372
+ };
373
+ if (!openEvents && shouldOpenOnClick) {
374
+ Object.assign(actualOpenEvents, {
375
+ mouseenter: false,
376
+ focus: false,
377
+ click: true,
378
+ });
379
+ }
380
+ const actualCloseEvents = closeEvents
381
+ ? { ...closeEvents }
382
+ : {
383
+ mouseleave: true,
384
+ blur: true,
385
+ click: false,
386
+ dblclick: false,
387
+ mouseup: false,
388
+ };
389
+ if (!closeEvents && shouldOpenOnClick) {
390
+ Object.assign(actualCloseEvents, {
391
+ mouseleave: false,
392
+ blur: false,
393
+ });
394
+ }
395
+ const actualGlobalCloseEvents = globalCloseEvents
396
+ ? { ...globalCloseEvents }
397
+ : {
398
+ escape: closeOnEsc || false,
399
+ scroll: closeOnScroll || false,
400
+ resize: closeOnResize || false,
401
+ clickOutsideAnchor: hasClickEvent || false,
402
+ };
403
+ if (imperativeModeOnly) {
404
+ Object.assign(actualOpenEvents, {
405
+ mouseenter: false,
406
+ focus: false,
407
+ click: false,
408
+ dblclick: false,
409
+ mousedown: false,
410
+ });
411
+ Object.assign(actualCloseEvents, {
412
+ mouseleave: false,
413
+ blur: false,
414
+ click: false,
415
+ dblclick: false,
416
+ mouseup: false,
417
+ });
418
+ Object.assign(actualGlobalCloseEvents, {
419
+ escape: false,
420
+ scroll: false,
421
+ resize: false,
422
+ clickOutsideAnchor: false,
423
+ });
424
+ }
360
425
  /**
361
426
  * useLayoutEffect runs before useEffect,
362
427
  * but should be used carefully because of caveats
@@ -368,23 +433,6 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
368
433
  mounted.current = false;
369
434
  };
370
435
  }, []);
371
- React.useEffect(() => {
372
- if (!show) {
373
- /**
374
- * this fixes weird behavior when switching between two anchor elements very quickly
375
- * remove the timeout and switch quickly between two adjancent anchor elements to see it
376
- *
377
- * in practice, this means the tooltip is not immediately removed from the DOM on hide
378
- */
379
- const timeout = setTimeout(() => {
380
- setRendered(false);
381
- }, 150);
382
- return () => {
383
- clearTimeout(timeout);
384
- };
385
- }
386
- return () => null;
387
- }, [show]);
388
436
  const handleShow = (value) => {
389
437
  if (!mounted.current) {
390
438
  return;
@@ -432,10 +480,6 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
432
480
  if (show) {
433
481
  afterShow === null || afterShow === void 0 ? void 0 : afterShow();
434
482
  }
435
- else {
436
- setImperativeOptions(null);
437
- afterHide === null || afterHide === void 0 ? void 0 : afterHide();
438
- }
439
483
  }, [show]);
440
484
  const handleShowTooltipDelayed = (delay = delayShow) => {
441
485
  if (tooltipShowDelayTimerRef.current) {
@@ -545,23 +589,18 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
545
589
  handleTooltipPosition(mousePosition);
546
590
  lastFloatPosition.current = mousePosition;
547
591
  };
548
- const handleClickTooltipAnchor = (event) => {
549
- handleShowTooltip(event);
550
- if (delayHide) {
551
- handleHideTooltipDelayed();
552
- }
553
- };
554
592
  const handleClickOutsideAnchors = (event) => {
555
593
  var _a;
556
594
  if (!show) {
557
595
  return;
558
596
  }
559
- const anchorById = document.querySelector(`[id='${anchorId}']`);
560
- const anchors = [anchorById, ...anchorsBySelect];
561
- if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(event.target))) {
597
+ const target = event.target;
598
+ if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
562
599
  return;
563
600
  }
564
- if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target)) {
601
+ const anchorById = document.querySelector(`[id='${anchorId}']`);
602
+ const anchors = [anchorById, ...anchorsBySelect];
603
+ if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
565
604
  return;
566
605
  }
567
606
  handleShow(false);
@@ -648,13 +687,13 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
648
687
  };
649
688
  const anchorScrollParent = getScrollParent(activeAnchor);
650
689
  const tooltipScrollParent = getScrollParent(tooltipRef.current);
651
- if (closeOnScroll) {
690
+ if (actualGlobalCloseEvents.scroll) {
652
691
  window.addEventListener('scroll', handleScrollResize);
653
692
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
654
693
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.addEventListener('scroll', handleScrollResize);
655
694
  }
656
695
  let updateTooltipCleanup = null;
657
- if (closeOnResize) {
696
+ if (actualGlobalCloseEvents.resize) {
658
697
  window.addEventListener('resize', handleScrollResize);
659
698
  }
660
699
  else if (activeAnchor && tooltipRef.current) {
@@ -670,22 +709,56 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
670
709
  }
671
710
  handleShow(false);
672
711
  };
673
- if (closeOnEsc) {
712
+ if (actualGlobalCloseEvents.escape) {
674
713
  window.addEventListener('keydown', handleEsc);
675
714
  }
676
- const enabledEvents = [];
677
- if (shouldOpenOnClick) {
715
+ if (actualGlobalCloseEvents.clickOutsideAnchor) {
678
716
  window.addEventListener('click', handleClickOutsideAnchors);
679
- enabledEvents.push({ event: 'click', listener: handleClickTooltipAnchor });
680
717
  }
681
- else {
682
- enabledEvents.push({ event: 'mouseenter', listener: debouncedHandleShowTooltip }, { event: 'mouseleave', listener: debouncedHandleHideTooltip }, { event: 'focus', listener: debouncedHandleShowTooltip }, { event: 'blur', listener: debouncedHandleHideTooltip });
683
- if (float) {
684
- enabledEvents.push({
685
- event: 'mousemove',
686
- listener: handleMouseMove,
687
- });
718
+ const enabledEvents = [];
719
+ const handleClickOpenTooltipAnchor = (event) => {
720
+ if (show) {
721
+ return;
722
+ }
723
+ handleShowTooltip(event);
724
+ };
725
+ const handleClickCloseTooltipAnchor = () => {
726
+ if (!show) {
727
+ return;
728
+ }
729
+ handleHideTooltip();
730
+ };
731
+ const regularEvents = ['mouseenter', 'mouseleave', 'focus', 'blur'];
732
+ const clickEvents = ['click', 'dblclick', 'mousedown', 'mouseup'];
733
+ Object.entries(actualOpenEvents).forEach(([event, enabled]) => {
734
+ if (!enabled) {
735
+ return;
736
+ }
737
+ if (regularEvents.includes(event)) {
738
+ enabledEvents.push({ event, listener: debouncedHandleShowTooltip });
739
+ }
740
+ else if (clickEvents.includes(event)) {
741
+ enabledEvents.push({ event, listener: handleClickOpenTooltipAnchor });
742
+ }
743
+ else ;
744
+ });
745
+ Object.entries(actualCloseEvents).forEach(([event, enabled]) => {
746
+ if (!enabled) {
747
+ return;
748
+ }
749
+ if (regularEvents.includes(event)) {
750
+ enabledEvents.push({ event, listener: debouncedHandleHideTooltip });
688
751
  }
752
+ else if (clickEvents.includes(event)) {
753
+ enabledEvents.push({ event, listener: handleClickCloseTooltipAnchor });
754
+ }
755
+ else ;
756
+ });
757
+ if (float) {
758
+ enabledEvents.push({
759
+ event: 'mousemove',
760
+ listener: handleMouseMove,
761
+ });
689
762
  }
690
763
  const handleMouseEnterTooltip = () => {
691
764
  hoveringTooltip.current = true;
@@ -694,7 +767,9 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
694
767
  hoveringTooltip.current = false;
695
768
  handleHideTooltip();
696
769
  };
697
- if (clickable && !shouldOpenOnClick) {
770
+ if (clickable && !hasClickEvent) {
771
+ // used to keep the tooltip open when hovering content.
772
+ // not needed if using click events.
698
773
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseenter', handleMouseEnterTooltip);
699
774
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseleave', handleMouseLeaveTooltip);
700
775
  }
@@ -706,24 +781,24 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
706
781
  });
707
782
  return () => {
708
783
  var _a, _b;
709
- if (closeOnScroll) {
784
+ if (actualGlobalCloseEvents.scroll) {
710
785
  window.removeEventListener('scroll', handleScrollResize);
711
786
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
712
787
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.removeEventListener('scroll', handleScrollResize);
713
788
  }
714
- if (closeOnResize) {
789
+ if (actualGlobalCloseEvents.resize) {
715
790
  window.removeEventListener('resize', handleScrollResize);
716
791
  }
717
792
  else {
718
793
  updateTooltipCleanup === null || updateTooltipCleanup === void 0 ? void 0 : updateTooltipCleanup();
719
794
  }
720
- if (shouldOpenOnClick) {
795
+ if (actualGlobalCloseEvents.clickOutsideAnchor) {
721
796
  window.removeEventListener('click', handleClickOutsideAnchors);
722
797
  }
723
- if (closeOnEsc) {
798
+ if (actualGlobalCloseEvents.escape) {
724
799
  window.removeEventListener('keydown', handleEsc);
725
800
  }
726
- if (clickable && !shouldOpenOnClick) {
801
+ if (clickable && !hasClickEvent) {
727
802
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mouseenter', handleMouseEnterTooltip);
728
803
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseleave', handleMouseLeaveTooltip);
729
804
  }
@@ -744,8 +819,11 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
744
819
  rendered,
745
820
  anchorRefs,
746
821
  anchorsBySelect,
747
- closeOnEsc,
748
- events,
822
+ // the effect uses the `actual*Events` objects, but this should work
823
+ openEvents,
824
+ closeEvents,
825
+ globalCloseEvents,
826
+ shouldOpenOnClick,
749
827
  ]);
750
828
  React.useEffect(() => {
751
829
  var _a, _b;
@@ -822,7 +900,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
822
900
  });
823
901
  if (newAnchors.length || removedAnchors.length) {
824
902
  setAnchorsBySelect((anchors) => [
825
- ...anchors.filter((anchor) => removedAnchors.includes(anchor)),
903
+ ...anchors.filter((anchor) => !removedAnchors.includes(anchor)),
826
904
  ...newAnchors,
827
905
  ]);
828
906
  }
@@ -931,24 +1009,24 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
931
1009
  place: actualPlacement,
932
1010
  isOpen: rendered && canShow,
933
1011
  }));
934
- return rendered ? (React__default["default"].createElement(WrapperElement, { id: id, role: "tooltip", className: classNames__default["default"]('react-tooltip', coreStyles['tooltip'], styles['tooltip'], styles[variant], className, `react-tooltip__place-${actualPlacement}`, {
935
- 'react-tooltip__show': canShow,
936
- [coreStyles['show']]: canShow,
937
- [coreStyles['fixed']]: positionStrategy === 'fixed',
938
- [coreStyles['clickable']]: clickable,
939
- }), style: {
1012
+ return rendered ? (React__default["default"].createElement(WrapperElement, { id: id, role: "tooltip", className: classNames__default["default"]('react-tooltip', coreStyles['tooltip'], styles['tooltip'], styles[variant], className, `react-tooltip__place-${actualPlacement}`, coreStyles[canShow ? 'show' : 'closing'], canShow ? 'react-tooltip__show' : 'react-tooltip__closing', positionStrategy === 'fixed' && coreStyles['fixed'], clickable && coreStyles['clickable']), onTransitionEnd: (event) => {
1013
+ /**
1014
+ * @warning if `--rt-transition-closing-delay` is set to 0,
1015
+ * the tooltip will be stuck (but not visible) on the DOM
1016
+ */
1017
+ if (show || event.propertyName !== 'opacity') {
1018
+ return;
1019
+ }
1020
+ setRendered(false);
1021
+ setImperativeOptions(null);
1022
+ afterHide === null || afterHide === void 0 ? void 0 : afterHide();
1023
+ }, style: {
940
1024
  ...externalStyles,
941
1025
  ...inlineStyles,
942
1026
  opacity: opacity !== undefined && canShow ? opacity : undefined,
943
1027
  }, ref: tooltipRef },
944
1028
  actualContent,
945
- React__default["default"].createElement(WrapperElement, { className: classNames__default["default"]('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, {
946
- /**
947
- * changed from dash `no-arrow` to camelcase because of:
948
- * https://github.com/indooorsman/esbuild-css-modules-plugin/issues/42
949
- */
950
- [coreStyles['noArrow']]: noArrow,
951
- }), style: {
1029
+ React__default["default"].createElement(WrapperElement, { className: classNames__default["default"]('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, noArrow && coreStyles['noArrow']), style: {
952
1030
  ...inlineArrowStyles,
953
1031
  background: arrowColor
954
1032
  ? `linear-gradient(to right bottom, transparent 50%, ${arrowColor} 50%)`
@@ -961,7 +1039,7 @@ const TooltipContent = ({ content }) => {
961
1039
  return React__default["default"].createElement("span", { dangerouslySetInnerHTML: { __html: content } });
962
1040
  };
963
1041
 
964
- const TooltipController = React__default["default"].forwardRef(({ id, anchorId, anchorSelect, content, html, render, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], openOnClick = false, positionStrategy = 'absolute', middlewares, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, closeOnEsc = false, closeOnScroll = false, closeOnResize = false, style, position, isOpen, disableStyleInjection = false, border, opacity, arrowColor, setIsOpen, afterShow, afterHide, }, ref) => {
1042
+ const TooltipController = React__default["default"].forwardRef(({ id, anchorId, anchorSelect, content, html, render, className, classNameArrow, variant = 'dark', place = 'top', offset = 10, wrapper = 'div', children = null, events = ['hover'], openOnClick = false, positionStrategy = 'absolute', middlewares, delayShow = 0, delayHide = 0, float = false, hidden = false, noArrow = false, clickable = false, closeOnEsc = false, closeOnScroll = false, closeOnResize = false, openEvents, closeEvents, globalCloseEvents, imperativeModeOnly = false, style, position, isOpen, disableStyleInjection = false, border, opacity, arrowColor, setIsOpen, afterShow, afterHide, }, ref) => {
965
1043
  const [tooltipContent, setTooltipContent] = React.useState(content);
966
1044
  const [tooltipHtml, setTooltipHtml] = React.useState(html);
967
1045
  const [tooltipPlace, setTooltipPlace] = React.useState(place);
@@ -1210,6 +1288,10 @@ const TooltipController = React__default["default"].forwardRef(({ id, anchorId,
1210
1288
  closeOnEsc,
1211
1289
  closeOnScroll,
1212
1290
  closeOnResize,
1291
+ openEvents,
1292
+ closeEvents,
1293
+ globalCloseEvents,
1294
+ imperativeModeOnly,
1213
1295
  style,
1214
1296
  position,
1215
1297
  isOpen,
@@ -1234,17 +1316,17 @@ const TooltipCoreStyles = `:root {
1234
1316
  --rt-color-warning: #f0ad4e;
1235
1317
  --rt-color-info: #337ab7;
1236
1318
  --rt-opacity: 0.9;
1319
+ --rt-transition-show-delay: 0.15s;
1320
+ --rt-transition-closing-delay: 0.15s;
1237
1321
  }
1238
1322
 
1239
1323
  .core-styles-module_tooltip__3vRRp {
1240
- visibility: hidden;
1241
1324
  position: absolute;
1242
1325
  top: 0;
1243
1326
  left: 0;
1244
1327
  pointer-events: none;
1245
1328
  opacity: 0;
1246
- transition: opacity 0.3s ease-out;
1247
- will-change: opacity, visibility;
1329
+ will-change: opacity;
1248
1330
  }
1249
1331
 
1250
1332
  .core-styles-module_fixed__pcSol {
@@ -1265,8 +1347,13 @@ const TooltipCoreStyles = `:root {
1265
1347
  }
1266
1348
 
1267
1349
  .core-styles-module_show__Nt9eE {
1268
- visibility: visible;
1269
1350
  opacity: var(--rt-opacity);
1351
+ transition: opacity var(--rt-transition-show-delay) ease-out;
1352
+ }
1353
+
1354
+ .core-styles-module_closing__sGnxF {
1355
+ opacity: 0;
1356
+ transition: opacity var(--rt-transition-closing-delay) ease-in;
1270
1357
  }
1271
1358
 
1272
1359
  `;