react-tooltip 5.22.1-beta.1118.0 → 5.23.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,10 @@
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, openEvents, closeEvents, globalCloseEvents, style: externalStyles, position, afterShow, afterHide,
334
+ 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,
335
335
  // props handled by controller
336
336
  content, contentWrapperRef, isOpen, setIsOpen, activeAnchor, setActiveAnchor, border, opacity, arrowColor, }) => {
337
+ var _a;
337
338
  const tooltipRef = React.useRef(null);
338
339
  const tooltipArrowRef = React.useRef(null);
339
340
  const tooltipShowDelayTimerRef = React.useRef(null);
@@ -343,6 +344,7 @@
343
344
  const [inlineArrowStyles, setInlineArrowStyles] = React.useState({});
344
345
  const [show, setShow] = React.useState(false);
345
346
  const [rendered, setRendered] = React.useState(false);
347
+ const [imperativeOptions, setImperativeOptions] = React.useState(null);
346
348
  const wasShowing = React.useRef(false);
347
349
  const lastFloatPosition = React.useRef(null);
348
350
  /**
@@ -379,6 +381,8 @@
379
381
  mouseleave: true,
380
382
  blur: true,
381
383
  click: false,
384
+ dblclick: false,
385
+ mouseup: false,
382
386
  };
383
387
  if (!closeEvents && shouldOpenOnClick) {
384
388
  Object.assign(actualCloseEvents, {
@@ -394,6 +398,28 @@
394
398
  resize: closeOnResize || false,
395
399
  clickOutsideAnchor: hasClickEvent || false,
396
400
  };
401
+ if (imperativeModeOnly) {
402
+ Object.assign(actualOpenEvents, {
403
+ mouseenter: false,
404
+ focus: false,
405
+ click: false,
406
+ dblclick: false,
407
+ mousedown: false,
408
+ });
409
+ Object.assign(actualCloseEvents, {
410
+ mouseleave: false,
411
+ blur: false,
412
+ click: false,
413
+ dblclick: false,
414
+ mouseup: false,
415
+ });
416
+ Object.assign(actualGlobalCloseEvents, {
417
+ escape: false,
418
+ scroll: false,
419
+ resize: false,
420
+ clickOutsideAnchor: false,
421
+ });
422
+ }
397
423
  /**
398
424
  * useLayoutEffect runs before useEffect,
399
425
  * but should be used carefully because of caveats
@@ -452,17 +478,14 @@
452
478
  if (show) {
453
479
  afterShow === null || afterShow === void 0 ? void 0 : afterShow();
454
480
  }
455
- else {
456
- afterHide === null || afterHide === void 0 ? void 0 : afterHide();
457
- }
458
481
  }, [show]);
459
- const handleShowTooltipDelayed = () => {
482
+ const handleShowTooltipDelayed = (delay = delayShow) => {
460
483
  if (tooltipShowDelayTimerRef.current) {
461
484
  clearTimeout(tooltipShowDelayTimerRef.current);
462
485
  }
463
486
  tooltipShowDelayTimerRef.current = setTimeout(() => {
464
487
  handleShow(true);
465
- }, delayShow);
488
+ }, delay);
466
489
  };
467
490
  const handleHideTooltipDelayed = (delay = delayHide) => {
468
491
  if (tooltipHideDelayTimerRef.current) {
@@ -518,6 +541,7 @@
518
541
  }
519
542
  };
520
543
  const handleTooltipPosition = ({ x, y }) => {
544
+ var _a;
521
545
  const virtualElement = {
522
546
  getBoundingClientRect() {
523
547
  return {
@@ -533,7 +557,7 @@
533
557
  },
534
558
  };
535
559
  computeTooltipPosition({
536
- place,
560
+ place: (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place) !== null && _a !== void 0 ? _a : place,
537
561
  offset,
538
562
  elementReference: virtualElement,
539
563
  tooltipReference: tooltipRef.current,
@@ -565,12 +589,16 @@
565
589
  };
566
590
  const handleClickOutsideAnchors = (event) => {
567
591
  var _a;
568
- const anchorById = document.querySelector(`[id='${anchorId}']`);
569
- const anchors = [anchorById, ...anchorsBySelect];
570
- if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(event.target))) {
592
+ if (!show) {
593
+ return;
594
+ }
595
+ const target = event.target;
596
+ if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(target)) {
571
597
  return;
572
598
  }
573
- if ((_a = tooltipRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.target)) {
599
+ const anchorById = document.querySelector(`[id='${anchorId}']`);
600
+ const anchors = [anchorById, ...anchorsBySelect];
601
+ if (anchors.some((anchor) => anchor === null || anchor === void 0 ? void 0 : anchor.contains(target))) {
574
602
  return;
575
603
  }
576
604
  handleShow(false);
@@ -583,9 +611,11 @@
583
611
  const debouncedHandleShowTooltip = debounce(handleShowTooltip, 50, true);
584
612
  const debouncedHandleHideTooltip = debounce(handleHideTooltip, 50, true);
585
613
  const updateTooltipPosition = React.useCallback(() => {
586
- if (position) {
614
+ var _a, _b;
615
+ const actualPosition = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position) !== null && _a !== void 0 ? _a : position;
616
+ if (actualPosition) {
587
617
  // if `position` is set, override regular and `float` positioning
588
- handleTooltipPosition(position);
618
+ handleTooltipPosition(actualPosition);
589
619
  return;
590
620
  }
591
621
  if (float) {
@@ -606,7 +636,7 @@
606
636
  return;
607
637
  }
608
638
  computeTooltipPosition({
609
- place,
639
+ place: (_b = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place) !== null && _b !== void 0 ? _b : place,
610
640
  offset,
611
641
  elementReference: activeAnchor,
612
642
  tooltipReference: tooltipRef.current,
@@ -633,9 +663,11 @@
633
663
  content,
634
664
  externalStyles,
635
665
  place,
666
+ imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.place,
636
667
  offset,
637
668
  positionStrategy,
638
669
  position,
670
+ imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.position,
639
671
  float,
640
672
  ]);
641
673
  React.useEffect(() => {
@@ -792,7 +824,8 @@
792
824
  shouldOpenOnClick,
793
825
  ]);
794
826
  React.useEffect(() => {
795
- let selector = anchorSelect !== null && anchorSelect !== void 0 ? anchorSelect : '';
827
+ var _a, _b;
828
+ let selector = (_b = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect) !== null && _b !== void 0 ? _b : '';
796
829
  if (!selector && id) {
797
830
  selector = `[data-tooltip-id='${id}']`;
798
831
  }
@@ -881,7 +914,7 @@
881
914
  return () => {
882
915
  documentObserver.disconnect();
883
916
  };
884
- }, [id, anchorSelect, activeAnchor]);
917
+ }, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect, activeAnchor]);
885
918
  React.useEffect(() => {
886
919
  updateTooltipPosition();
887
920
  }, [updateTooltipPosition]);
@@ -921,7 +954,8 @@
921
954
  };
922
955
  }, []);
923
956
  React.useEffect(() => {
924
- let selector = anchorSelect;
957
+ var _a;
958
+ let selector = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect) !== null && _a !== void 0 ? _a : anchorSelect;
925
959
  if (!selector && id) {
926
960
  selector = `[data-tooltip-id='${id}']`;
927
961
  }
@@ -932,13 +966,48 @@
932
966
  const anchors = Array.from(document.querySelectorAll(selector));
933
967
  setAnchorsBySelect(anchors);
934
968
  }
935
- catch (_a) {
969
+ catch (_b) {
936
970
  // warning was already issued in the controller
937
971
  setAnchorsBySelect([]);
938
972
  }
939
- }, [id, anchorSelect]);
973
+ }, [id, anchorSelect, imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.anchorSelect]);
974
+ const actualContent = (_a = imperativeOptions === null || imperativeOptions === void 0 ? void 0 : imperativeOptions.content) !== null && _a !== void 0 ? _a : content;
940
975
  const canShow = show && Object.keys(inlineStyles).length > 0;
941
- return rendered && !hidden && content ? (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) => {
976
+ React.useImperativeHandle(forwardRef, () => ({
977
+ open: (options) => {
978
+ if (options === null || options === void 0 ? void 0 : options.anchorSelect) {
979
+ try {
980
+ document.querySelector(options.anchorSelect);
981
+ }
982
+ catch (_a) {
983
+ {
984
+ // eslint-disable-next-line no-console
985
+ console.warn(`[react-tooltip] "${options.anchorSelect}" is not a valid CSS selector`);
986
+ }
987
+ return;
988
+ }
989
+ }
990
+ setImperativeOptions(options !== null && options !== void 0 ? options : null);
991
+ if (options === null || options === void 0 ? void 0 : options.delay) {
992
+ handleShowTooltipDelayed(options.delay);
993
+ }
994
+ else {
995
+ handleShow(true);
996
+ }
997
+ },
998
+ close: (options) => {
999
+ if (options === null || options === void 0 ? void 0 : options.delay) {
1000
+ handleHideTooltipDelayed(options.delay);
1001
+ }
1002
+ else {
1003
+ handleShow(false);
1004
+ }
1005
+ },
1006
+ activeAnchor,
1007
+ place: actualPlacement,
1008
+ isOpen: Boolean(rendered && !hidden && actualContent && canShow),
1009
+ }));
1010
+ return rendered && !hidden && actualContent ? (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) => {
942
1011
  /**
943
1012
  * @warning if `--rt-transition-closing-delay` is set to 0,
944
1013
  * the tooltip will be stuck (but not visible) on the DOM
@@ -947,12 +1016,14 @@
947
1016
  return;
948
1017
  }
949
1018
  setRendered(false);
1019
+ setImperativeOptions(null);
1020
+ afterHide === null || afterHide === void 0 ? void 0 : afterHide();
950
1021
  }, style: {
951
1022
  ...externalStyles,
952
1023
  ...inlineStyles,
953
1024
  opacity: opacity !== undefined && canShow ? opacity : undefined,
954
1025
  }, ref: tooltipRef },
955
- content,
1026
+ actualContent,
956
1027
  React__default["default"].createElement(WrapperElement, { className: classNames__default["default"]('react-tooltip-arrow', coreStyles['arrow'], styles['arrow'], classNameArrow, noArrow && coreStyles['noArrow']), style: {
957
1028
  ...inlineArrowStyles,
958
1029
  background: arrowColor
@@ -966,7 +1037,12 @@
966
1037
  return React__default["default"].createElement("span", { dangerouslySetInnerHTML: { __html: content } });
967
1038
  };
968
1039
 
969
- 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, }) => {
1040
+ const cssSupports = (property, value) => {
1041
+ const hasCssSupports = 'CSS' in window && 'supports' in window.CSS;
1042
+ return hasCssSupports ? window.CSS.supports(property, value) : true;
1043
+ };
1044
+
1045
+ 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) => {
970
1046
  const [tooltipContent, setTooltipContent] = React.useState(content);
971
1047
  const [tooltipHtml, setTooltipHtml] = React.useState(html);
972
1048
  const [tooltipPlace, setTooltipPlace] = React.useState(place);
@@ -1160,7 +1236,7 @@
1160
1236
  // eslint-disable-next-line no-console
1161
1237
  console.warn('[react-tooltip] Do not set `style.border`. Use `border` prop instead.');
1162
1238
  }
1163
- if (border && !CSS.supports('border', `${border}`)) {
1239
+ if (border && !cssSupports('border', `${border}`)) {
1164
1240
  // eslint-disable-next-line no-console
1165
1241
  console.warn(`[react-tooltip] "${border}" is not a valid \`border\`.`);
1166
1242
  }
@@ -1168,7 +1244,7 @@
1168
1244
  // eslint-disable-next-line no-console
1169
1245
  console.warn('[react-tooltip] Do not set `style.opacity`. Use `opacity` prop instead.');
1170
1246
  }
1171
- if (opacity && !CSS.supports('opacity', `${opacity}`)) {
1247
+ if (opacity && !cssSupports('opacity', `${opacity}`)) {
1172
1248
  // eslint-disable-next-line no-console
1173
1249
  console.warn(`[react-tooltip] "${opacity}" is not a valid \`opacity\`.`);
1174
1250
  }
@@ -1190,6 +1266,7 @@
1190
1266
  renderedContent = React__default["default"].createElement(TooltipContent, { content: tooltipHtml });
1191
1267
  }
1192
1268
  const props = {
1269
+ forwardRef: ref,
1193
1270
  id,
1194
1271
  anchorId,
1195
1272
  anchorSelect,
@@ -1217,6 +1294,7 @@
1217
1294
  openEvents,
1218
1295
  closeEvents,
1219
1296
  globalCloseEvents,
1297
+ imperativeModeOnly,
1220
1298
  style,
1221
1299
  position,
1222
1300
  isOpen,
@@ -1230,7 +1308,7 @@
1230
1308
  setActiveAnchor: (anchor) => setActiveAnchor(anchor),
1231
1309
  };
1232
1310
  return React__default["default"].createElement(Tooltip, { ...props });
1233
- };
1311
+ });
1234
1312
 
1235
1313
  // those content will be replaced in build time with the `react-tooltip.css` builded content
1236
1314
  const TooltipCoreStyles = `:root {