react-tooltip 5.22.0-beta.1108.0 → 5.22.0-beta.1109.1

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.
@@ -333,9 +333,10 @@ var styles = {"tooltip":"styles-module_tooltip__mnnfp","arrow":"styles-module_ar
333
333
 
334
334
  const Tooltip = ({
335
335
  // props
336
- 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,
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,
337
337
  // props handled by controller
338
338
  content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
339
+ var _a;
339
340
  const tooltipRef = React.useRef(null);
340
341
  const tooltipArrowRef = React.useRef(null);
341
342
  const tooltipShowDelayTimerRef = React.useRef(null);
@@ -345,6 +346,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
345
346
  const [inlineArrowStyles, setInlineArrowStyles] = React.useState({});
346
347
  const [show, setShow] = React.useState(false);
347
348
  const [rendered, setRendered] = React.useState(false);
349
+ const [imperativeOptions, setImperativeOptions] = React.useState(null);
348
350
  const wasShowing = React.useRef(false);
349
351
  const lastFloatPosition = React.useRef(null);
350
352
  /**
@@ -354,48 +356,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
354
356
  const hoveringTooltip = React.useRef(false);
355
357
  const [anchorsBySelect, setAnchorsBySelect] = React.useState([]);
356
358
  const mounted = React.useRef(false);
357
- /**
358
- * @todo Update when deprecated stuff gets removed.
359
- */
360
359
  const shouldOpenOnClick = openOnClick || events.includes('click');
361
- 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);
362
- const actualOpenEvents = openEvents
363
- ? { ...openEvents }
364
- : {
365
- mouseenter: true,
366
- focus: true,
367
- click: false,
368
- dblclick: false,
369
- mousedown: false,
370
- };
371
- if (!openEvents && shouldOpenOnClick) {
372
- Object.assign(actualOpenEvents, {
373
- mouseenter: false,
374
- focus: false,
375
- click: true,
376
- });
377
- }
378
- const actualCloseEvents = closeEvents
379
- ? { ...closeEvents }
380
- : {
381
- mouseleave: true,
382
- blur: true,
383
- click: false,
384
- };
385
- if (!closeEvents && shouldOpenOnClick) {
386
- Object.assign(actualCloseEvents, {
387
- mouseleave: false,
388
- blur: false,
389
- });
390
- }
391
- const actualGlobalCloseEvents = globalCloseEvents
392
- ? { ...globalCloseEvents }
393
- : {
394
- escape: closeOnEsc || false,
395
- scroll: closeOnScroll || false,
396
- resize: closeOnResize || false,
397
- clickOutsideAnchor: hasClickEvent || false,
398
- };
399
360
  /**
400
361
  * useLayoutEffect runs before useEffect,
401
362
  * but should be used carefully because of caveats
@@ -472,16 +433,17 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
472
433
  afterShow === null || afterShow === void 0 ? void 0 : afterShow();
473
434
  }
474
435
  else {
436
+ setImperativeOptions(null);
475
437
  afterHide === null || afterHide === void 0 ? void 0 : afterHide();
476
438
  }
477
439
  }, [show]);
478
- const handleShowTooltipDelayed = () => {
440
+ const handleShowTooltipDelayed = (delay = delayShow) => {
479
441
  if (tooltipShowDelayTimerRef.current) {
480
442
  clearTimeout(tooltipShowDelayTimerRef.current);
481
443
  }
482
444
  tooltipShowDelayTimerRef.current = setTimeout(() => {
483
445
  handleShow(true);
484
- }, delayShow);
446
+ }, delay);
485
447
  };
486
448
  const handleHideTooltipDelayed = (delay = delayHide) => {
487
449
  if (tooltipHideDelayTimerRef.current) {
@@ -537,6 +499,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
537
499
  }
538
500
  };
539
501
  const handleTooltipPosition = ({ x, y }) => {
502
+ var _a;
540
503
  const virtualElement = {
541
504
  getBoundingClientRect() {
542
505
  return {
@@ -552,7 +515,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
552
515
  },
553
516
  };
554
517
  computeTooltipPosition({
555
- place,
518
+ place: (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place) !== null && _a !== void 0 ? _a : place,
556
519
  offset,
557
520
  elementReference: virtualElement,
558
521
  tooltipReference: tooltipRef.current,
@@ -582,8 +545,17 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
582
545
  handleTooltipPosition(mousePosition);
583
546
  lastFloatPosition.current = mousePosition;
584
547
  };
548
+ const handleClickTooltipAnchor = (event) => {
549
+ handleShowTooltip(event);
550
+ if (delayHide) {
551
+ handleHideTooltipDelayed();
552
+ }
553
+ };
585
554
  const handleClickOutsideAnchors = (event) => {
586
555
  var _a;
556
+ if (!show) {
557
+ return;
558
+ }
587
559
  const anchorById = document.querySelector(`[id='${anchorId}']`);
588
560
  const anchors = [anchorById, ...anchorsBySelect];
589
561
  if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(event.target))) {
@@ -602,9 +574,11 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
602
574
  const debouncedHandleShowTooltip = debounce(handleShowTooltip, 50, true);
603
575
  const debouncedHandleHideTooltip = debounce(handleHideTooltip, 50, true);
604
576
  const updateTooltipPosition = React.useCallback(() => {
605
- if (position) {
577
+ var _a, _b;
578
+ const actualPosition = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position) !== null && _a !== void 0 ? _a : position;
579
+ if (actualPosition) {
606
580
  // if `position` is set, override regular and `float` positioning
607
- handleTooltipPosition(position);
581
+ handleTooltipPosition(actualPosition);
608
582
  return;
609
583
  }
610
584
  if (float) {
@@ -625,7 +599,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
625
599
  return;
626
600
  }
627
601
  computeTooltipPosition({
628
- place,
602
+ place: (_b = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place) !== null && _b !== void 0 ? _b : place,
629
603
  offset,
630
604
  elementReference: activeAnchor,
631
605
  tooltipReference: tooltipRef.current,
@@ -652,9 +626,11 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
652
626
  content,
653
627
  externalStyles,
654
628
  place,
629
+ imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
655
630
  offset,
656
631
  positionStrategy,
657
632
  position,
633
+ imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position,
658
634
  float,
659
635
  ]);
660
636
  React.useEffect(() => {
@@ -672,13 +648,13 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
672
648
  };
673
649
  const anchorScrollParent = getScrollParent(activeAnchor);
674
650
  const tooltipScrollParent = getScrollParent(tooltipRef.current);
675
- if (actualGlobalCloseEvents.scroll) {
651
+ if (closeOnScroll) {
676
652
  window.addEventListener('scroll', handleScrollResize);
677
653
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.addEventListener('scroll', handleScrollResize);
678
654
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.addEventListener('scroll', handleScrollResize);
679
655
  }
680
656
  let updateTooltipCleanup = null;
681
- if (actualGlobalCloseEvents.resize) {
657
+ if (closeOnResize) {
682
658
  window.addEventListener('resize', handleScrollResize);
683
659
  }
684
660
  else if (activeAnchor && tooltipRef.current) {
@@ -694,56 +670,22 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
694
670
  }
695
671
  handleShow(false);
696
672
  };
697
- if (actualGlobalCloseEvents.escape) {
673
+ if (closeOnEsc) {
698
674
  window.addEventListener('keydown', handleEsc);
699
675
  }
700
- if (actualGlobalCloseEvents.clickOutsideAnchor) {
676
+ const enabledEvents = [];
677
+ if (shouldOpenOnClick) {
701
678
  window.addEventListener('click', handleClickOutsideAnchors);
679
+ enabledEvents.push({ event: 'click', listener: handleClickTooltipAnchor });
702
680
  }
703
- const enabledEvents = [];
704
- const handleClickOpenTooltipAnchor = (event) => {
705
- if (show) {
706
- return;
707
- }
708
- handleShowTooltip(event);
709
- };
710
- const handleClickCloseTooltipAnchor = () => {
711
- if (!show) {
712
- return;
713
- }
714
- handleHideTooltip();
715
- };
716
- const regularEvents = ['mouseenter', 'mouseleave', 'focus', 'blur'];
717
- const clickEvents = ['click', 'dblclick', 'mousedown', 'mouseup'];
718
- Object.entries(actualOpenEvents).forEach(([event, enabled]) => {
719
- if (!enabled) {
720
- return;
721
- }
722
- if (regularEvents.includes(event)) {
723
- enabledEvents.push({ event, listener: debouncedHandleShowTooltip });
724
- }
725
- else if (clickEvents.includes(event)) {
726
- enabledEvents.push({ event, listener: handleClickOpenTooltipAnchor });
727
- }
728
- else ;
729
- });
730
- Object.entries(actualCloseEvents).forEach(([event, enabled]) => {
731
- if (!enabled) {
732
- return;
733
- }
734
- if (regularEvents.includes(event)) {
735
- enabledEvents.push({ event, listener: debouncedHandleHideTooltip });
736
- }
737
- else if (clickEvents.includes(event)) {
738
- enabledEvents.push({ event, listener: handleClickCloseTooltipAnchor });
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
+ });
739
688
  }
740
- else ;
741
- });
742
- if (float) {
743
- enabledEvents.push({
744
- event: 'mousemove',
745
- listener: handleMouseMove,
746
- });
747
689
  }
748
690
  const handleMouseEnterTooltip = () => {
749
691
  hoveringTooltip.current = true;
@@ -752,9 +694,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
752
694
  hoveringTooltip.current = false;
753
695
  handleHideTooltip();
754
696
  };
755
- if (clickable && !hasClickEvent) {
756
- // used to keep the tooltip open when hovering content.
757
- // not needed if using click events.
697
+ if (clickable && !shouldOpenOnClick) {
758
698
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('mouseenter', handleMouseEnterTooltip);
759
699
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('mouseleave', handleMouseLeaveTooltip);
760
700
  }
@@ -766,24 +706,24 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
766
706
  });
767
707
  return () => {
768
708
  var _a, _b;
769
- if (actualGlobalCloseEvents.scroll) {
709
+ if (closeOnScroll) {
770
710
  window.removeEventListener('scroll', handleScrollResize);
771
711
  anchorScrollParent === null || anchorScrollParent === void 0 ? void 0 : anchorScrollParent.removeEventListener('scroll', handleScrollResize);
772
712
  tooltipScrollParent === null || tooltipScrollParent === void 0 ? void 0 : tooltipScrollParent.removeEventListener('scroll', handleScrollResize);
773
713
  }
774
- if (actualGlobalCloseEvents.resize) {
714
+ if (closeOnResize) {
775
715
  window.removeEventListener('resize', handleScrollResize);
776
716
  }
777
717
  else {
778
718
  updateTooltipCleanup === null || updateTooltipCleanup === void 0 ? void 0 : updateTooltipCleanup();
779
719
  }
780
- if (actualGlobalCloseEvents.clickOutsideAnchor) {
720
+ if (shouldOpenOnClick) {
781
721
  window.removeEventListener('click', handleClickOutsideAnchors);
782
722
  }
783
- if (actualGlobalCloseEvents.escape) {
723
+ if (closeOnEsc) {
784
724
  window.removeEventListener('keydown', handleEsc);
785
725
  }
786
- if (clickable && !hasClickEvent) {
726
+ if (clickable && !shouldOpenOnClick) {
787
727
  (_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('mouseenter', handleMouseEnterTooltip);
788
728
  (_b = tooltipRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('mouseleave', handleMouseLeaveTooltip);
789
729
  }
@@ -804,14 +744,12 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
804
744
  rendered,
805
745
  anchorRefs,
806
746
  anchorsBySelect,
807
- // the effect uses the `actual*Events` objects, but this should work
808
- openEvents,
809
- closeEvents,
810
- globalCloseEvents,
811
- shouldOpenOnClick,
747
+ closeOnEsc,
748
+ events,
812
749
  ]);
813
750
  React.useEffect(() => {
814
- let selector = anchorSelect !== null && anchorSelect !== void 0 ? anchorSelect : '';
751
+ var _a, _b;
752
+ let selector = (_b = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect) !== null && _b !== void 0 ? _b : '';
815
753
  if (!selector && id) {
816
754
  selector = `[data-tooltip-id='${id}']`;
817
755
  }
@@ -900,7 +838,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
900
838
  return () => {
901
839
  documentObserver.disconnect();
902
840
  };
903
- }, [id, anchorSelect, activeAnchor]);
841
+ }, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor]);
904
842
  React.useEffect(() => {
905
843
  updateTooltipPosition();
906
844
  }, [updateTooltipPosition]);
@@ -940,7 +878,8 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
940
878
  };
941
879
  }, []);
942
880
  React.useEffect(() => {
943
- let selector = anchorSelect;
881
+ var _a;
882
+ let selector = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect;
944
883
  if (!selector && id) {
945
884
  selector = `[data-tooltip-id='${id}']`;
946
885
  }
@@ -951,12 +890,47 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
951
890
  const anchors = Array.from(document.querySelectorAll(selector));
952
891
  setAnchorsBySelect(anchors);
953
892
  }
954
- catch (_a) {
893
+ catch (_b) {
955
894
  // warning was already issued in the controller
956
895
  setAnchorsBySelect([]);
957
896
  }
958
- }, [id, anchorSelect]);
959
- const canShow = !hidden && content && show && Object.keys(inlineStyles).length > 0;
897
+ }, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect]);
898
+ const actualContent = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.content) !== null && _a !== void 0 ? _a : content;
899
+ const canShow = Boolean(!hidden && actualContent && show && Object.keys(inlineStyles).length > 0);
900
+ React.useImperativeHandle(forwardRef, () => ({
901
+ open: (options) => {
902
+ if (options === null || options === void 0 ? void 0 : options.anchorSelect) {
903
+ try {
904
+ document.querySelector(options.anchorSelect);
905
+ }
906
+ catch (_a) {
907
+ {
908
+ // eslint-disable-next-line no-console
909
+ console.warn(`[react-tooltip] "${options.anchorSelect}" is not a valid CSS selector`);
910
+ }
911
+ return;
912
+ }
913
+ }
914
+ setImperativeOptions(options !== null && options !== void 0 ? options : null);
915
+ if (options === null || options === void 0 ? void 0 : options.delay) {
916
+ handleShowTooltipDelayed(options.delay);
917
+ }
918
+ else {
919
+ handleShow(true);
920
+ }
921
+ },
922
+ close: (options) => {
923
+ if (options === null || options === void 0 ? void 0 : options.delay) {
924
+ handleHideTooltipDelayed(options.delay);
925
+ }
926
+ else {
927
+ handleShow(false);
928
+ }
929
+ },
930
+ activeAnchor,
931
+ place: actualPlacement,
932
+ isOpen: rendered && canShow,
933
+ }));
960
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}`, {
961
935
  'react-tooltip__show': canShow,
962
936
  [coreStyles['show']]: canShow,
@@ -967,7 +941,7 @@ content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, bo
967
941
  ...inlineStyles,
968
942
  opacity: opacity !== undefined && canShow ? opacity : undefined,
969
943
  }, ref: tooltipRef },
970
- content,
944
+ actualContent,
971
945
  React__default["default"].createElement(WrapperElement, { className: classNames__default["default"]('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, {
972
946
  /**
973
947
  * changed from dash `no-arrow` to camelcase because of:
@@ -987,7 +961,7 @@ const TooltipContent = ({ content }) => {
987
961
  return React__default["default"].createElement("span", { dangerouslySetInnerHTML: { __html: content } });
988
962
  };
989
963
 
990
- 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, }) => {
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) => {
991
965
  const [tooltipContent, setTooltipContent] = React.useState(content);
992
966
  const [tooltipHtml, setTooltipHtml] = React.useState(html);
993
967
  const [tooltipPlace, setTooltipPlace] = React.useState(place);
@@ -1211,6 +1185,7 @@ const TooltipController = ({ id, anchorId, anchorSelect, content, html, render,
1211
1185
  renderedContent = React__default["default"].createElement(TooltipContent, { content: tooltipHtml });
1212
1186
  }
1213
1187
  const props = {
1188
+ forwardRef: ref,
1214
1189
  id,
1215
1190
  anchorId,
1216
1191
  anchorSelect,
@@ -1235,9 +1210,6 @@ const TooltipController = ({ id, anchorId, anchorSelect, content, html, render,
1235
1210
  closeOnEsc,
1236
1211
  closeOnScroll,
1237
1212
  closeOnResize,
1238
- openEvents,
1239
- closeEvents,
1240
- globalCloseEvents,
1241
1213
  style,
1242
1214
  position,
1243
1215
  isOpen,
@@ -1251,7 +1223,7 @@ const TooltipController = ({ id, anchorId, anchorSelect, content, html, render,
1251
1223
  setActiveAnchor: (anchor) => setActiveAnchor(anchor),
1252
1224
  };
1253
1225
  return React__default["default"].createElement(Tooltip, { ...props });
1254
- };
1226
+ });
1255
1227
 
1256
1228
  // those content will be replaced in build time with the `react-tooltip.css` builded content
1257
1229
  const TooltipCoreStyles = `:root {