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.
@@ -324,9 +324,9 @@ var styles = {"tooltip":"styles-module_tooltip__mnnfp","arrow":"styles-module_ar
324
324
 
325
325
  const Tooltip = ({
326
326
  // props
327
- 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,
327
+ 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,
328
328
  // props handled by controller
329
- content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
329
+ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
330
330
  const tooltipRef = useRef(null);
331
331
  const tooltipArrowRef = useRef(null);
332
332
  const tooltipShowDelayTimerRef = useRef(null);
@@ -345,7 +345,48 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
345
345
  const hoveringTooltip = useRef(false);
346
346
  const [anchorsBySelect, setAnchorsBySelect] = useState([]);
347
347
  const mounted = useRef(false);
348
+ /**
349
+ * @todo Update when deprecated stuff gets removed.
350
+ */
348
351
  const shouldOpenOnClick = openOnClick || events.includes('click');
352
+ 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);
353
+ const actualOpenEvents = openEvents
354
+ ? { ...openEvents }
355
+ : {
356
+ mouseenter: true,
357
+ focus: true,
358
+ click: false,
359
+ dblclick: false,
360
+ mousedown: false,
361
+ };
362
+ if (!openEvents && shouldOpenOnClick) {
363
+ Object.assign(actualOpenEvents, {
364
+ mouseenter: false,
365
+ focus: false,
366
+ click: true,
367
+ });
368
+ }
369
+ const actualCloseEvents = closeEvents
370
+ ? { ...closeEvents }
371
+ : {
372
+ mouseleave: true,
373
+ blur: true,
374
+ click: false,
375
+ };
376
+ if (!closeEvents && shouldOpenOnClick) {
377
+ Object.assign(actualCloseEvents, {
378
+ mouseleave: false,
379
+ blur: false,
380
+ });
381
+ }
382
+ const actualGlobalCloseEvents = globalCloseEvents
383
+ ? { ...globalCloseEvents }
384
+ : {
385
+ escape: closeOnEsc || false,
386
+ scroll: closeOnScroll || false,
387
+ resize: closeOnResize || false,
388
+ clickOutsideAnchor: hasClickEvent || false,
389
+ };
349
390
  /**
350
391
  * useLayoutEffect runs before useEffect,
351
392
  * but should be used carefully because of caveats
@@ -532,12 +573,6 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
532
573
  handleTooltipPosition(mousePosition);
533
574
  lastFloatPosition.current = mousePosition;
534
575
  };
535
- const handleClickTooltipAnchor = (event) => {
536
- handleShowTooltip(event);
537
- if (delayHide) {
538
- handleHideTooltipDelayed();
539
- }
540
- };
541
576
  const handleClickOutsideAnchors = (event) => {
542
577
  var _a;
543
578
  const anchorById = document.querySelector(`[id='${anchorId}']`);
@@ -628,16 +663,16 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
628
663
  };
629
664
  const anchorScrollParent = getScrollParent(activeAnchor);
630
665
  const tooltipScrollParent = getScrollParent(tooltipRef.current);
631
- if (closeOnScroll) {
666
+ if (actualGlobalCloseEvents.scroll) {
632
667
  window.addEventListener('scroll', handleScrollResize);
633
668
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
634
669
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.addEventListener('scroll', handleScrollResize);
635
670
  }
636
671
  let updateTooltipCleanup = null;
637
- if (closeOnResize) {
672
+ if (actualGlobalCloseEvents.resize) {
638
673
  window.addEventListener('resize', handleScrollResize);
639
674
  }
640
- else if (activeAnchor && tooltipRef.current && !holdPositionOnRender) {
675
+ else if (activeAnchor && tooltipRef.current) {
641
676
  updateTooltipCleanup = autoUpdate(activeAnchor, tooltipRef.current, updateTooltipPosition, {
642
677
  ancestorResize: true,
643
678
  elementResize: true,
@@ -650,22 +685,56 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
650
685
  }
651
686
  handleShow(false);
652
687
  };
653
- if (closeOnEsc) {
688
+ if (actualGlobalCloseEvents.escape) {
654
689
  window.addEventListener('keydown', handleEsc);
655
690
  }
656
- const enabledEvents = [];
657
- if (shouldOpenOnClick) {
691
+ if (actualGlobalCloseEvents.clickOutsideAnchor) {
658
692
  window.addEventListener('click', handleClickOutsideAnchors);
659
- enabledEvents.push({ event: 'click', listener: handleClickTooltipAnchor });
660
693
  }
661
- else {
662
- enabledEvents.push({ event: 'mouseenter', listener: debouncedHandleShowTooltip }, { event: 'mouseleave', listener: debouncedHandleHideTooltip }, { event: 'focus', listener: debouncedHandleShowTooltip }, { event: 'blur', listener: debouncedHandleHideTooltip });
663
- if (float) {
664
- enabledEvents.push({
665
- event: 'mousemove',
666
- listener: handleMouseMove,
667
- });
694
+ const enabledEvents = [];
695
+ const handleClickOpenTooltipAnchor = (event) => {
696
+ if (show) {
697
+ return;
668
698
  }
699
+ handleShowTooltip(event);
700
+ };
701
+ const handleClickCloseTooltipAnchor = () => {
702
+ if (!show) {
703
+ return;
704
+ }
705
+ handleHideTooltip();
706
+ };
707
+ const regularEvents = ['mouseenter', 'mouseleave', 'focus', 'blur'];
708
+ const clickEvents = ['click', 'dblclick', 'mousedown', 'mouseup'];
709
+ Object.entries(actualOpenEvents).forEach(([event, enabled]) => {
710
+ if (!enabled) {
711
+ return;
712
+ }
713
+ if (regularEvents.includes(event)) {
714
+ enabledEvents.push({ event, listener: debouncedHandleShowTooltip });
715
+ }
716
+ else if (clickEvents.includes(event)) {
717
+ enabledEvents.push({ event, listener: handleClickOpenTooltipAnchor });
718
+ }
719
+ else ;
720
+ });
721
+ Object.entries(actualCloseEvents).forEach(([event, enabled]) => {
722
+ if (!enabled) {
723
+ return;
724
+ }
725
+ if (regularEvents.includes(event)) {
726
+ enabledEvents.push({ event, listener: debouncedHandleHideTooltip });
727
+ }
728
+ else if (clickEvents.includes(event)) {
729
+ enabledEvents.push({ event, listener: handleClickCloseTooltipAnchor });
730
+ }
731
+ else ;
732
+ });
733
+ if (float) {
734
+ enabledEvents.push({
735
+ event: 'mousemove',
736
+ listener: handleMouseMove,
737
+ });
669
738
  }
670
739
  const handleMouseEnterTooltip = () => {
671
740
  hoveringTooltip.current = true;
@@ -674,7 +743,9 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
674
743
  hoveringTooltip.current = false;
675
744
  handleHideTooltip();
676
745
  };
677
- if (clickable && !shouldOpenOnClick) {
746
+ if (clickable && !hasClickEvent) {
747
+ // used to keep the tooltip open when hovering content.
748
+ // not needed if using click events.
678
749
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseenter', handleMouseEnterTooltip);
679
750
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseleave', handleMouseLeaveTooltip);
680
751
  }
@@ -686,24 +757,24 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
686
757
  });
687
758
  return () => {
688
759
  var _a, _b;
689
- if (closeOnScroll) {
760
+ if (actualGlobalCloseEvents.scroll) {
690
761
  window.removeEventListener('scroll', handleScrollResize);
691
762
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
692
763
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.removeEventListener('scroll', handleScrollResize);
693
764
  }
694
- if (closeOnResize) {
765
+ if (actualGlobalCloseEvents.resize) {
695
766
  window.removeEventListener('resize', handleScrollResize);
696
767
  }
697
768
  else {
698
769
  updateTooltipCleanup === null || updateTooltipCleanup === void 0 ? void 0 : updateTooltipCleanup();
699
770
  }
700
- if (shouldOpenOnClick) {
771
+ if (actualGlobalCloseEvents.clickOutsideAnchor) {
701
772
  window.removeEventListener('click', handleClickOutsideAnchors);
702
773
  }
703
- if (closeOnEsc) {
774
+ if (actualGlobalCloseEvents.escape) {
704
775
  window.removeEventListener('keydown', handleEsc);
705
776
  }
706
- if (clickable && !shouldOpenOnClick) {
777
+ if (clickable && !hasClickEvent) {
707
778
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mouseenter', handleMouseEnterTooltip);
708
779
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseleave', handleMouseLeaveTooltip);
709
780
  }
@@ -724,8 +795,11 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
724
795
  rendered,
725
796
  anchorRefs,
726
797
  anchorsBySelect,
727
- closeOnEsc,
728
- events,
798
+ // the effect uses the `actual*Events` objects, but this should work
799
+ openEvents,
800
+ closeEvents,
801
+ globalCloseEvents,
802
+ shouldOpenOnClick,
729
803
  ]);
730
804
  useEffect(() => {
731
805
  let selector = anchorSelect !== null && anchorSelect !== void 0 ? anchorSelect : '';
@@ -748,12 +822,20 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
748
822
  if (activeAnchor) {
749
823
  const elements = [...mutation.removedNodes].filter((node) => node.nodeType === 1);
750
824
  if (selector) {
751
- removedAnchors.push(
752
- // the element itself is an anchor
753
- ...elements.filter((element) => element.matches(selector)));
754
- removedAnchors.push(
755
- // the element has children which are anchors
756
- ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
825
+ try {
826
+ removedAnchors.push(
827
+ // the element itself is an anchor
828
+ ...elements.filter((element) => element.matches(selector)));
829
+ removedAnchors.push(
830
+ // the element has children which are anchors
831
+ ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
832
+ }
833
+ catch (_a) {
834
+ /**
835
+ * invalid CSS selector.
836
+ * already warned on tooltip controller
837
+ */
838
+ }
757
839
  }
758
840
  elements.some((node) => {
759
841
  var _a;
@@ -784,14 +866,14 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
784
866
  // the element has children which are anchors
785
867
  ...elements.flatMap((element) => [...element.querySelectorAll(selector)]));
786
868
  }
787
- catch (_a) {
869
+ catch (_b) {
788
870
  /**
789
871
  * invalid CSS selector.
790
872
  * already warned on tooltip controller
791
873
  */
792
874
  }
793
875
  });
794
- if (newAnchors.length) {
876
+ if (newAnchors.length || removedAnchors.length) {
795
877
  setAnchorsBySelect((anchors) => [
796
878
  ...anchors.filter((anchor) => removedAnchors.includes(anchor)),
797
879
  ...newAnchors,
@@ -866,7 +948,7 @@ content, contentWrapperRef, isOpen, holdPositionOnRender, setIsOpen, activeAncho
866
948
  }
867
949
  }, [id, anchorSelect]);
868
950
  const canShow = !hidden && content && show && Object.keys(inlineStyles).length > 0;
869
- return rendered || (wasShowing.current && holdPositionOnRender) ? (React.createElement(WrapperElement, { id: id, role: "tooltip", className: classNames('react-tooltip', coreStyles['tooltip'], styles['tooltip'], styles[variant], className, `react-tooltip__place-${actualPlacement}`, {
951
+ return rendered ? (React.createElement(WrapperElement, { id: id, role: "tooltip", className: classNames('react-tooltip', coreStyles['tooltip'], styles['tooltip'], styles[variant], className, `react-tooltip__place-${actualPlacement}`, {
870
952
  'react-tooltip__show': canShow,
871
953
  [coreStyles['show']]: canShow,
872
954
  [coreStyles['fixed']]: positionStrategy === 'fixed',
@@ -896,7 +978,7 @@ const TooltipContent = ({ content }) => {
896
978
  return React.createElement("span", { dangerouslySetInnerHTML: { __html: content } });
897
979
  };
898
980
 
899
- 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, }) => {
981
+ 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, }) => {
900
982
  const [tooltipContent, setTooltipContent] = useState(content);
901
983
  const [tooltipHtml, setTooltipHtml] = useState(html);
902
984
  const [tooltipPlace, setTooltipPlace] = useState(place);
@@ -1144,10 +1226,12 @@ const TooltipController = ({ id, anchorId, anchorSelect, content, html, render,
1144
1226
  closeOnEsc,
1145
1227
  closeOnScroll,
1146
1228
  closeOnResize,
1229
+ openEvents,
1230
+ closeEvents,
1231
+ globalCloseEvents,
1147
1232
  style,
1148
1233
  position,
1149
1234
  isOpen,
1150
- holdPositionOnRender,
1151
1235
  border,
1152
1236
  opacity,
1153
1237
  arrowColor,