react-tooltip 5.22.0-beta.1091.1 → 5.22.0-beta.1108.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.
@@ -331,9 +331,9 @@
331
331
 
332
332
  const Tooltip = ({
333
333
  // props
334
- 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,
334
+ 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, style: externalStyles, position, afterShow, afterHide,
335
335
  // props handled by controller
336
- content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
336
+ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
337
337
  const tooltipRef = React.useRef(null);
338
338
  const tooltipArrowRef = React.useRef(null);
339
339
  const tooltipShowDelayTimerRef = React.useRef(null);
@@ -352,7 +352,48 @@
352
352
  const hoveringTooltip = React.useRef(false);
353
353
  const [anchorsBySelect, setAnchorsBySelect] = React.useState([]);
354
354
  const mounted = React.useRef(false);
355
+ /**
356
+ * @todo Update when deprecated stuff gets removed.
357
+ */
355
358
  const shouldOpenOnClick = openOnClick || events.includes('click');
359
+ 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);
360
+ const actualOpenEvents = openEvents
361
+ ? { ...openEvents }
362
+ : {
363
+ mouseenter: true,
364
+ focus: true,
365
+ click: false,
366
+ dblclick: false,
367
+ mousedown: false,
368
+ };
369
+ if (!openEvents && shouldOpenOnClick) {
370
+ Object.assign(actualOpenEvents, {
371
+ mouseenter: false,
372
+ focus: false,
373
+ click: true,
374
+ });
375
+ }
376
+ const actualCloseEvents = closeEvents
377
+ ? { ...closeEvents }
378
+ : {
379
+ mouseleave: true,
380
+ blur: true,
381
+ click: false,
382
+ };
383
+ if (!closeEvents && shouldOpenOnClick) {
384
+ Object.assign(actualCloseEvents, {
385
+ mouseleave: false,
386
+ blur: false,
387
+ });
388
+ }
389
+ const actualGlobalCloseEvents = globalCloseEvents
390
+ ? { ...globalCloseEvents }
391
+ : {
392
+ escape: closeOnEsc || false,
393
+ scroll: closeOnScroll || false,
394
+ resize: closeOnResize || false,
395
+ clickOutsideAnchor: hasClickEvent || false,
396
+ };
356
397
  /**
357
398
  * useLayoutEffect runs before useEffect,
358
399
  * but should be used carefully because of caveats
@@ -539,12 +580,6 @@
539
580
  handleTooltipPosition(mousePosition);
540
581
  lastFloatPosition.current = mousePosition;
541
582
  };
542
- const handleClickTooltipAnchor = (event) => {
543
- handleShowTooltip(event);
544
- if (delayHide) {
545
- handleHideTooltipDelayed();
546
- }
547
- };
548
583
  const handleClickOutsideAnchors = (event) => {
549
584
  var _a;
550
585
  const anchorById = document.querySelector(`[id='${anchorId}']`);
@@ -635,16 +670,16 @@
635
670
  };
636
671
  const anchorScrollParent = getScrollParent(activeAnchor);
637
672
  const tooltipScrollParent = getScrollParent(tooltipRef.current);
638
- if (closeOnScroll) {
673
+ if (actualGlobalCloseEvents.scroll) {
639
674
  window.addEventListener('scroll', handleScrollResize);
640
675
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
641
676
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.addEventListener('scroll', handleScrollResize);
642
677
  }
643
678
  let updateTooltipCleanup = null;
644
- if (closeOnResize) {
679
+ if (actualGlobalCloseEvents.resize) {
645
680
  window.addEventListener('resize', handleScrollResize);
646
681
  }
647
- else if (activeAnchor && tooltipRef.current && !holdPositionOnRender) {
682
+ else if (activeAnchor && tooltipRef.current) {
648
683
  updateTooltipCleanup = dom.autoUpdate(activeAnchor, tooltipRef.current, updateTooltipPosition, {
649
684
  ancestorResize: true,
650
685
  elementResize: true,
@@ -657,22 +692,56 @@
657
692
  }
658
693
  handleShow(false);
659
694
  };
660
- if (closeOnEsc) {
695
+ if (actualGlobalCloseEvents.escape) {
661
696
  window.addEventListener('keydown', handleEsc);
662
697
  }
663
- const enabledEvents = [];
664
- if (shouldOpenOnClick) {
698
+ if (actualGlobalCloseEvents.clickOutsideAnchor) {
665
699
  window.addEventListener('click', handleClickOutsideAnchors);
666
- enabledEvents.push({ event: 'click', listener: handleClickTooltipAnchor });
667
700
  }
668
- else {
669
- enabledEvents.push({ event: 'mouseenter', listener: debouncedHandleShowTooltip }, { event: 'mouseleave', listener: debouncedHandleHideTooltip }, { event: 'focus', listener: debouncedHandleShowTooltip }, { event: 'blur', listener: debouncedHandleHideTooltip });
670
- if (float) {
671
- enabledEvents.push({
672
- event: 'mousemove',
673
- listener: handleMouseMove,
674
- });
701
+ const enabledEvents = [];
702
+ const handleClickOpenTooltipAnchor = (event) => {
703
+ if (show) {
704
+ return;
675
705
  }
706
+ handleShowTooltip(event);
707
+ };
708
+ const handleClickCloseTooltipAnchor = () => {
709
+ if (!show) {
710
+ return;
711
+ }
712
+ handleHideTooltip();
713
+ };
714
+ const regularEvents = ['mouseenter', 'mouseleave', 'focus', 'blur'];
715
+ const clickEvents = ['click', 'dblclick', 'mousedown', 'mouseup'];
716
+ Object.entries(actualOpenEvents).forEach(([event, enabled]) => {
717
+ if (!enabled) {
718
+ return;
719
+ }
720
+ if (regularEvents.includes(event)) {
721
+ enabledEvents.push({ event, listener: debouncedHandleShowTooltip });
722
+ }
723
+ else if (clickEvents.includes(event)) {
724
+ enabledEvents.push({ event, listener: handleClickOpenTooltipAnchor });
725
+ }
726
+ else ;
727
+ });
728
+ Object.entries(actualCloseEvents).forEach(([event, enabled]) => {
729
+ if (!enabled) {
730
+ return;
731
+ }
732
+ if (regularEvents.includes(event)) {
733
+ enabledEvents.push({ event, listener: debouncedHandleHideTooltip });
734
+ }
735
+ else if (clickEvents.includes(event)) {
736
+ enabledEvents.push({ event, listener: handleClickCloseTooltipAnchor });
737
+ }
738
+ else ;
739
+ });
740
+ if (float) {
741
+ enabledEvents.push({
742
+ event: 'mousemove',
743
+ listener: handleMouseMove,
744
+ });
676
745
  }
677
746
  const handleMouseEnterTooltip = () => {
678
747
  hoveringTooltip.current = true;
@@ -681,7 +750,9 @@
681
750
  hoveringTooltip.current = false;
682
751
  handleHideTooltip();
683
752
  };
684
- if (clickable && !shouldOpenOnClick) {
753
+ if (clickable && !hasClickEvent) {
754
+ // used to keep the tooltip open when hovering content.
755
+ // not needed if using click events.
685
756
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseenter', handleMouseEnterTooltip);
686
757
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseleave', handleMouseLeaveTooltip);
687
758
  }
@@ -693,24 +764,24 @@
693
764
  });
694
765
  return () => {
695
766
  var _a, _b;
696
- if (closeOnScroll) {
767
+ if (actualGlobalCloseEvents.scroll) {
697
768
  window.removeEventListener('scroll', handleScrollResize);
698
769
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
699
770
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.removeEventListener('scroll', handleScrollResize);
700
771
  }
701
- if (closeOnResize) {
772
+ if (actualGlobalCloseEvents.resize) {
702
773
  window.removeEventListener('resize', handleScrollResize);
703
774
  }
704
775
  else {
705
776
  updateTooltipCleanup === null || updateTooltipCleanup === void 0 ? void 0 : updateTooltipCleanup();
706
777
  }
707
- if (shouldOpenOnClick) {
778
+ if (actualGlobalCloseEvents.clickOutsideAnchor) {
708
779
  window.removeEventListener('click', handleClickOutsideAnchors);
709
780
  }
710
- if (closeOnEsc) {
781
+ if (actualGlobalCloseEvents.escape) {
711
782
  window.removeEventListener('keydown', handleEsc);
712
783
  }
713
- if (clickable && !shouldOpenOnClick) {
784
+ if (clickable && !hasClickEvent) {
714
785
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mouseenter', handleMouseEnterTooltip);
715
786
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseleave', handleMouseLeaveTooltip);
716
787
  }
@@ -731,8 +802,11 @@
731
802
  rendered,
732
803
  anchorRefs,
733
804
  anchorsBySelect,
734
- closeOnEsc,
735
- events,
805
+ // the effect uses the `actual*Events` objects, but this should work
806
+ openEvents,
807
+ closeEvents,
808
+ globalCloseEvents,
809
+ shouldOpenOnClick,
736
810
  ]);
737
811
  React.useEffect(() => {
738
812
  let selector = anchorSelect !== null && anchorSelect !== void 0 ? anchorSelect : '';
@@ -755,12 +829,20 @@
755
829
  if (activeAnchor) {
756
830
  const elements = [...mutation.removedNodes].filter((node) => node.nodeType === 1);
757
831
  if (selector) {
758
- removedAnchors.push(
759
- // the element itself is an anchor
760
- ...elements.filter((element) => element.matches(selector)));
761
- removedAnchors.push(
762
- // the element has children which are anchors
763
- ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
832
+ try {
833
+ removedAnchors.push(
834
+ // the element itself is an anchor
835
+ ...elements.filter((element) => element.matches(selector)));
836
+ removedAnchors.push(
837
+ // the element has children which are anchors
838
+ ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
839
+ }
840
+ catch (_a) {
841
+ /**
842
+ * invalid CSS selector.
843
+ * already warned on tooltip controller
844
+ */
845
+ }
764
846
  }
765
847
  elements.some((node) => {
766
848
  var _a;
@@ -791,14 +873,14 @@
791
873
  // the element has children which are anchors
792
874
  ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
793
875
  }
794
- catch (_a) {
876
+ catch (_b) {
795
877
  /**
796
878
  * invalid CSS selector.
797
879
  * already warned on tooltip controller
798
880
  */
799
881
  }
800
882
  });
801
- if (newAnchors.length) {
883
+ if (newAnchors.length || removedAnchors.length) {
802
884
  setAnchorsBySelect((anchors) => [
803
885
  ...anchors.filter((anchor) => removedAnchors.includes(anchor)),
804
886
  ...newAnchors,
@@ -873,7 +955,7 @@
873
955
  }
874
956
  }, [id, anchorSelect]);
875
957
  const canShow = !hidden && content && show && Object.keys(inlineStyles).length > 0;
876
- return rendered || (wasShowing.current && holdPositionOnRender) ? (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}`, {
958
+ 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}`, {
877
959
  'react-tooltip__show': canShow,
878
960
  [coreStyles['show']]: canShow,
879
961
  [coreStyles['fixed']]: positionStrategy === 'fixed',
@@ -903,7 +985,7 @@
903
985
  return React__default["default"].createElement("span", { dangerouslySetInnerHTML: { __html: content } });
904
986
  };
905
987
 
906
- const TooltipController = ({ 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, holdPositionOnRender, border, opacity, arrowColor, setIsOpen, afterShow, afterHide, }) => {
988
+ const TooltipController = ({ 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, style, position, isOpen, disableStyleInjection = false, border, opacity, arrowColor, setIsOpen, afterShow, afterHide, }) => {
907
989
  const [tooltipContent, setTooltipContent] = React.useState(content);
908
990
  const [tooltipHtml, setTooltipHtml] = React.useState(html);
909
991
  const [tooltipPlace, setTooltipPlace] = React.useState(place);
@@ -1151,10 +1233,12 @@
1151
1233
  closeOnEsc,
1152
1234
  closeOnScroll,
1153
1235
  closeOnResize,
1236
+ openEvents,
1237
+ closeEvents,
1238
+ globalCloseEvents,
1154
1239
  style,
1155
1240
  position,
1156
1241
  isOpen,
1157
- holdPositionOnRender,
1158
1242
  border,
1159
1243
  opacity,
1160
1244
  arrowColor,