react-core-ts 2.1.42 → 2.1.43

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.
@@ -705,6 +705,11 @@ span.dropdown-search-icon {
705
705
  border-color: transparent transparent #000 transparent;
706
706
  }
707
707
 
708
+ .custom_tooltip_style_class.up.tooltiptext::after,
709
+ .custom_tooltip_style_class.down.tooltiptext::after {
710
+ left: var(--tooltip-arrow-left, 50%);
711
+ }
712
+
708
713
  .autocomplete-suggections .qbs-autocomplete-suggections-items {
709
714
  display: flex;
710
715
  /* justify-content: space-between; */
@@ -705,6 +705,11 @@ span.dropdown-search-icon {
705
705
  border-color: transparent transparent #000 transparent;
706
706
  }
707
707
 
708
+ .custom_tooltip_style_class.up.tooltiptext::after,
709
+ .custom_tooltip_style_class.down.tooltiptext::after {
710
+ left: var(--tooltip-arrow-left, 50%);
711
+ }
712
+
708
713
  .autocomplete-suggections .qbs-autocomplete-suggections-items {
709
714
  display: flex;
710
715
  /* justify-content: space-between; */
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  var jsx_runtime_1 = require("react/jsx-runtime");
18
18
  var react_1 = require("react");
19
19
  var react_dom_1 = __importDefault(require("react-dom"));
20
+ var getPosition_1 = require("./getPosition");
20
21
  var ExpandableToolTip = function (_a) {
21
22
  var title = _a.title, children = _a.children, enabled = _a.enabled;
22
23
  var _b = (0, react_1.useState)('bottom-position'), dropdownPosition = _b[0], setDropdownPosition = _b[1];
@@ -27,10 +28,10 @@ var ExpandableToolTip = function (_a) {
27
28
  var _e = (0, react_1.useState)({
28
29
  top: 0,
29
30
  left: 0,
30
- width: 0,
31
+ arrowOffset: 50,
31
32
  }), tooltipStyle = _e[0], setTooltipStyle = _e[1];
32
33
  var hideTimeoutRef = (0, react_1.useRef)(null);
33
- var handleMouseEnter = function (e) {
34
+ var handleMouseEnter = function () {
34
35
  if (hideTimeoutRef.current) {
35
36
  clearTimeout(hideTimeoutRef.current);
36
37
  hideTimeoutRef.current = null;
@@ -39,51 +40,37 @@ var ExpandableToolTip = function (_a) {
39
40
  setVisible(true);
40
41
  }
41
42
  };
42
- (0, react_1.useEffect)(function () {
43
- if (visible &&
44
- isTooltipMounted &&
45
- menuButtonRef.current &&
46
- dropRef.current) {
47
- var inputBoxRect_1 = menuButtonRef.current.getBoundingClientRect();
48
- var tooltipHeight = dropRef.current.offsetHeight;
49
- var tooltipWidth = dropRef.current.offsetWidth;
50
- var boxWidth = inputBoxRect_1.width;
51
- var viewportHeight = window.innerHeight;
52
- var spaceAbove = inputBoxRect_1.top;
53
- var spaceBelow = viewportHeight - inputBoxRect_1.bottom;
54
- var dropPosition_1 = 'bottom-position';
55
- if (spaceBelow >= tooltipHeight + 20) {
56
- dropPosition_1 = 'bottom-position';
57
- }
58
- else if (spaceAbove >= tooltipHeight + 20) {
59
- dropPosition_1 = 'top-position';
43
+ var updatePosition = (0, react_1.useCallback)(function () {
44
+ if (!menuButtonRef.current || !dropRef.current)
45
+ return;
46
+ var coords = (0, getPosition_1.getPortalTooltipCoords)(menuButtonRef.current, dropRef.current);
47
+ setDropdownPosition(coords.placement);
48
+ setTooltipStyle(function (prev) {
49
+ if (prev.top === coords.top &&
50
+ prev.left === coords.left &&
51
+ prev.arrowOffset === coords.arrowOffset) {
52
+ return prev;
60
53
  }
61
- else {
62
- dropPosition_1 =
63
- spaceBelow > spaceAbove ? 'bottom-position' : 'top-position';
64
- }
65
- setDropdownPosition(dropPosition_1);
66
- var top_1 = dropPosition_1 === 'bottom-position'
67
- ? inputBoxRect_1.bottom + 8 + window.scrollY
68
- : inputBoxRect_1.top - tooltipHeight - 8 + window.scrollY;
69
- var left = inputBoxRect_1.left + boxWidth / 2 - 200 / 2 + window.scrollX;
70
- setTooltipStyle({
71
- top: top_1,
72
- left: Math.max(left, 8),
73
- width: 200,
74
- });
75
- // ✨ Recalculate again after a small delay
76
- setTimeout(function () {
77
- if (dropRef.current) {
78
- var correctedHeight = dropRef.current.offsetHeight;
79
- var correctedTop_1 = dropPosition_1 === 'bottom-position'
80
- ? inputBoxRect_1.bottom + 8 + window.scrollY
81
- : inputBoxRect_1.top - correctedHeight - 8 + window.scrollY;
82
- setTooltipStyle(function (prev) { return (__assign(__assign({}, prev), { top: correctedTop_1 })); });
83
- }
84
- }, 0);
85
- }
86
- }, [visible]);
54
+ return {
55
+ top: coords.top,
56
+ left: coords.left,
57
+ arrowOffset: coords.arrowOffset,
58
+ };
59
+ });
60
+ }, []);
61
+ (0, react_1.useLayoutEffect)(function () {
62
+ if (!visible || !isTooltipMounted)
63
+ return;
64
+ updatePosition();
65
+ var frame = window.requestAnimationFrame(updatePosition);
66
+ window.addEventListener('resize', updatePosition);
67
+ window.addEventListener('scroll', updatePosition, true);
68
+ return function () {
69
+ window.cancelAnimationFrame(frame);
70
+ window.removeEventListener('resize', updatePosition);
71
+ window.removeEventListener('scroll', updatePosition, true);
72
+ };
73
+ }, [visible, isTooltipMounted, updatePosition]);
87
74
  (0, react_1.useEffect)(function () {
88
75
  var handleMouseMove = function (event) {
89
76
  if (!menuButtonRef.current || !dropRef.current)
@@ -140,11 +127,11 @@ var ExpandableToolTip = function (_a) {
140
127
  left: tooltipStyle.left,
141
128
  opacity: visible ? 1 : 0,
142
129
  visibility: visible ? 'visible' : 'hidden',
143
- width: tooltipStyle.width,
144
130
  minWidth: '60px',
145
131
  maxWidth: '200px',
146
132
  pointerEvents: 'auto',
147
133
  maxHeight: '210px',
134
+ '--tooltip-arrow-left': "".concat(tooltipStyle.arrowOffset, "px"),
148
135
  } }, { children: (0, jsx_runtime_1.jsx)("div", __assign({ className: "", style: {
149
136
  maxHeight: '200px',
150
137
  overflowY: 'auto',
@@ -1 +1 @@
1
- {"version":3,"file":"NewTooltip.js","sourceRoot":"","sources":["../../src/utilities/NewTooltip.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NewTooltip.js","sourceRoot":"","sources":["../../src/utilities/NewTooltip.tsx"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  var jsx_runtime_1 = require("react/jsx-runtime");
18
18
  var react_1 = require("react");
19
19
  var react_dom_1 = __importDefault(require("react-dom"));
20
+ var getPosition_1 = require("./getPosition");
20
21
  var ExpandableToolTip = function (_a) {
21
22
  var title = _a.title, children = _a.children, enabled = _a.enabled;
22
23
  var _b = (0, react_1.useState)('bottom-position'), dropdownPosition = _b[0], setDropdownPosition = _b[1];
@@ -26,82 +27,45 @@ var ExpandableToolTip = function (_a) {
26
27
  var _d = (0, react_1.useState)({
27
28
  top: 0,
28
29
  left: 0,
29
- width: 0,
30
+ arrowOffset: 50,
30
31
  }), tooltipStyle = _d[0], setTooltipStyle = _d[1];
31
- var adjustDropdownPosition = function () {
32
- var _a;
33
- if (menuButtonRef.current) {
34
- var inputBoxRect = (_a = menuButtonRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
35
- var viewportHeight = window.innerHeight;
36
- var spaceAbove = inputBoxRect.top;
37
- var spaceBelow = viewportHeight - inputBoxRect.bottom;
38
- if (spaceAbove > spaceBelow) {
39
- if (spaceAbove > 90 && spaceBelow < 120) {
40
- return 'top-position';
41
- }
42
- else {
43
- return 'bottom-position';
44
- }
45
- }
46
- else {
47
- var diff = spaceBelow - spaceAbove;
48
- if (spaceAbove > 90 && spaceBelow > 90 && diff < 90) {
49
- return 'top-position';
50
- }
51
- else {
52
- return 'bottom-position';
53
- }
54
- }
55
- }
56
- };
57
- var handleMouseEnter = function (e) {
58
- var _a;
59
- if (menuButtonRef.current) {
60
- var dropPosition = adjustDropdownPosition();
61
- setDropdownPosition(dropPosition);
62
- var rect = e.target.getBoundingClientRect();
63
- var top_1 = rect.bottom + window.scrollY;
64
- var left = rect.left + window.scrollX;
65
- var height = rect.height;
66
- var width = (_a = dropRef === null || dropRef === void 0 ? void 0 : dropRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth;
67
- if (dropPosition === 'bottom-position') {
68
- top_1 = top_1 + height / 2 - 5;
69
- }
70
- else {
71
- top_1 = top_1 - height * 2 + 15;
72
- }
73
- setTooltipStyle({
74
- top: top_1,
75
- left: left,
76
- width: width,
77
- });
78
- setVisible(true);
79
- }
32
+ var handleMouseEnter = function () {
33
+ setVisible(true);
80
34
  };
81
35
  var handleMouseLeave = function () {
82
36
  setVisible(false);
83
37
  };
84
- (0, react_1.useLayoutEffect)(function () {
85
- var updateTooltipPosition = function () {
86
- if (dropRef.current && visible && tooltipStyle) {
87
- var tooltipHeight_1 = dropRef.current.offsetHeight;
88
- var tooltipWidth_1 = dropRef.current.offsetWidth;
89
- var boxWidth_1 = menuButtonRef.current.offsetWidth;
90
- setTooltipStyle(function (prevStyle) { return (__assign(__assign({}, prevStyle), { left: prevStyle.left + boxWidth_1 / 2 - tooltipWidth_1 / 2 < 0
91
- ? 20
92
- : prevStyle.left + boxWidth_1 / 2 - tooltipWidth_1 / 2, width: tooltipWidth_1, top: dropdownPosition === 'bottom-position'
93
- ? prevStyle.top
94
- : prevStyle.top - tooltipHeight_1 })); });
38
+ var updatePosition = (0, react_1.useCallback)(function () {
39
+ if (!menuButtonRef.current || !dropRef.current)
40
+ return;
41
+ var coords = (0, getPosition_1.getPortalTooltipCoords)(menuButtonRef.current, dropRef.current);
42
+ setDropdownPosition(coords.placement);
43
+ setTooltipStyle(function (prev) {
44
+ if (prev.top === coords.top &&
45
+ prev.left === coords.left &&
46
+ prev.arrowOffset === coords.arrowOffset) {
47
+ return prev;
95
48
  }
96
- };
97
- if (visible) {
98
- updateTooltipPosition();
99
- }
100
- window.addEventListener('resize', updateTooltipPosition);
49
+ return {
50
+ top: coords.top,
51
+ left: coords.left,
52
+ arrowOffset: coords.arrowOffset,
53
+ };
54
+ });
55
+ }, []);
56
+ (0, react_1.useLayoutEffect)(function () {
57
+ if (!visible)
58
+ return;
59
+ updatePosition();
60
+ var frame = window.requestAnimationFrame(updatePosition);
61
+ window.addEventListener('resize', updatePosition);
62
+ window.addEventListener('scroll', updatePosition, true);
101
63
  return function () {
102
- window.removeEventListener('resize', updateTooltipPosition);
64
+ window.cancelAnimationFrame(frame);
65
+ window.removeEventListener('resize', updatePosition);
66
+ window.removeEventListener('scroll', updatePosition, true);
103
67
  };
104
- }, [visible, dropdownPosition]);
68
+ }, [visible, updatePosition]);
105
69
  (0, react_1.useEffect)(function () {
106
70
  var handleClickOutside = function (event) {
107
71
  if (dropRef.current && !dropRef.current.contains(event.target)) {
@@ -116,14 +80,16 @@ var ExpandableToolTip = function (_a) {
116
80
  return ((0, jsx_runtime_1.jsxs)("div", __assign({ onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, ref: menuButtonRef, style: { display: 'flex' } }, { children: [children, visible &&
117
81
  enabled &&
118
82
  tooltipStyle &&
119
- react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("span", __assign({ ref: function (node) { return (dropRef.current = node); }, className: "tooltiptext custom_tooltip_style_class ".concat(dropdownPosition == 'bottom-position' ? 'down' : 'up'), style: {
83
+ react_dom_1.default.createPortal((0, jsx_runtime_1.jsx)("span", __assign({ ref: function (node) {
84
+ dropRef.current = node;
85
+ }, className: "tooltiptext custom_tooltip_style_class ".concat(dropdownPosition == 'bottom-position' ? 'down' : 'up'), style: {
120
86
  top: tooltipStyle.top,
121
87
  left: tooltipStyle.left,
122
88
  opacity: 1,
123
- width: tooltipStyle.width,
124
89
  minWidth: '60px',
125
90
  maxWidth: '200px',
126
91
  visibility: 'visible',
92
+ '--tooltip-arrow-left': "".concat(tooltipStyle.arrowOffset, "px"),
127
93
  } }, { children: (0, jsx_runtime_1.jsx)("span", __assign({ className: "tooltip-text-container" }, { children: title })) })), document.body)] })));
128
94
  };
129
95
  exports.default = ExpandableToolTip;
@@ -1 +1 @@
1
- {"version":3,"file":"expandableTootltip.js","sourceRoot":"","sources":["../../src/utilities/expandableTootltip.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"expandableTootltip.js","sourceRoot":"","sources":["../../src/utilities/expandableTootltip.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,12 @@
1
1
  import React from 'react';
2
2
  export declare const applyPositionClass: (textFieldRef: React.RefObject<HTMLDivElement>, isHovered?: boolean) => void;
3
3
  export declare const applyToolTipPositionClass: (textFieldRef: React.RefObject<HTMLDivElement>) => void;
4
+ export type PortalTooltipPlacement = 'top-position' | 'bottom-position';
5
+ export type PortalTooltipCoords = {
6
+ top: number;
7
+ left: number;
8
+ arrowOffset: number;
9
+ placement: PortalTooltipPlacement;
10
+ };
11
+ /** Center a portaled tooltip on its trigger and keep the arrow on the trigger. */
12
+ export declare const getPortalTooltipCoords: (anchorEl: HTMLElement, tooltipEl: HTMLElement) => PortalTooltipCoords;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.applyToolTipPositionClass = exports.applyPositionClass = void 0;
3
+ exports.getPortalTooltipCoords = exports.applyToolTipPositionClass = exports.applyPositionClass = void 0;
4
4
  // const getPosition = (textFieldElement: HTMLElement) => {
5
5
  // const textFieldRect = textFieldElement.getBoundingClientRect()
6
6
  // const spaceBelow = window.innerHeight - textFieldRect.bottom
@@ -52,4 +52,44 @@ var applyToolTipPositionClass = function (textFieldRef) {
52
52
  }
53
53
  };
54
54
  exports.applyToolTipPositionClass = applyToolTipPositionClass;
55
+ var VIEWPORT_PAD = 8;
56
+ var TOOLTIP_GAP = 8;
57
+ var ARROW_HALF = 5;
58
+ /** Center a portaled tooltip on its trigger and keep the arrow on the trigger. */
59
+ var getPortalTooltipCoords = function (anchorEl, tooltipEl) {
60
+ var anchor = anchorEl.getBoundingClientRect();
61
+ var tooltipWidth = Math.max(tooltipEl.offsetWidth, 60);
62
+ var tooltipHeight = tooltipEl.offsetHeight;
63
+ var spaceAbove = anchor.top;
64
+ var spaceBelow = window.innerHeight - anchor.bottom;
65
+ var placement = 'bottom-position';
66
+ if (spaceBelow >= tooltipHeight + 20) {
67
+ placement = 'bottom-position';
68
+ }
69
+ else if (spaceAbove >= tooltipHeight + 20) {
70
+ placement = 'top-position';
71
+ }
72
+ else {
73
+ placement = spaceBelow > spaceAbove ? 'bottom-position' : 'top-position';
74
+ }
75
+ var top = placement === 'bottom-position'
76
+ ? anchor.bottom + TOOLTIP_GAP + window.scrollY
77
+ : anchor.top - tooltipHeight - TOOLTIP_GAP + window.scrollY;
78
+ var triggerCenterX = anchor.left + anchor.width / 2;
79
+ var minLeft = VIEWPORT_PAD;
80
+ var maxLeft = window.innerWidth - tooltipWidth - VIEWPORT_PAD;
81
+ var left = maxLeft < minLeft
82
+ ? minLeft
83
+ : Math.min(Math.max(triggerCenterX - tooltipWidth / 2, minLeft), maxLeft);
84
+ var minArrow = ARROW_HALF + 6;
85
+ var maxArrow = Math.max(minArrow, tooltipWidth - ARROW_HALF - 6);
86
+ var arrowOffset = Math.min(Math.max(triggerCenterX - left, minArrow), maxArrow);
87
+ return {
88
+ top: top,
89
+ left: left + window.scrollX,
90
+ arrowOffset: arrowOffset,
91
+ placement: placement,
92
+ };
93
+ };
94
+ exports.getPortalTooltipCoords = getPortalTooltipCoords;
55
95
  //# sourceMappingURL=getPosition.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getPosition.js","sourceRoot":"","sources":["../../src/utilities/getPosition.ts"],"names":[],"mappings":";;;AAEA,2DAA2D;AAC3D,mEAAmE;AAEnE,iEAAiE;AACjE,+CAA+C;AAC/C,IAAI;AACJ,IAAM,mBAAmB,GAAG,UAAC,OAAoB;IAC/C,IAAI,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IACnC,OAAO,MAAM,EAAE;QACb,IAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC;QAC5D,IAAI,SAAS,KAAK,QAAQ,IAAI,SAAS,KAAK,MAAM,EAAE;YAClD,OAAO,MAAM,CAAC;SACf;QACD,MAAM,GAAG,MAAM,CAAC,aAAa,CAAC;KAC/B;IACD,OAAO,MAAM,CAAC,CAAC,sDAAsD;AACvE,CAAC,CAAC;AAEF,IAAM,WAAW,GAAG,UAClB,gBAA6B,EAC7B,aAAuB;IAEvB,IAAM,aAAa,GAAG,gBAAgB,CAAC,qBAAqB,EAAE,CAAC;IAC/D,IAAM,gBAAgB,GAAG,mBAAmB,CAAC,gBAAgB,CAAgB,CAAC;IAC9E,IAAM,UAAU,GAAG,gBAAgB,CAAC,qBAAqB,EAAE,CAAC;IAE5D,IAAM,UAAU,GAAG,UAAU,CAAC,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC;IAC5D,IAAI,aAAa,EAAE;QACjB,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC;KACrD;SAAM;QACL,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;KAC3C;AACH,CAAC,CAAC;AACK,IAAM,kBAAkB,GAAG,UAChC,YAA6C,EAC7C,SAAmB;IAEnB,IAAI,YAAY,CAAC,OAAO,EAAE;QACxB,IAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,CAAC;QAC9C,IAAI,SAAS,EAAE;YACb,IAAM,aAAa,GAAG,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAC,+BAA+B;YACpF,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACnD,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SAC/C;aAAM;YACL,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;SAC1C;KACF;AACH,CAAC,CAAC;AAdW,QAAA,kBAAkB,sBAc7B;AACK,IAAM,yBAAyB,GAAG,UACvC,YAA6C;IAE7C,IAAI,YAAY,CAAC,OAAO,EAAE;QACxB,IAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,CAAC;QAC9C,IAAM,aAAa,GAAG,WAAW,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,CAAC,+BAA+B;QAE1F,gBAAgB,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;QAC7D,gBAAgB,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;KAC/C;AACH,CAAC,CAAC;AAVW,QAAA,yBAAyB,6BAUpC"}
1
+ {"version":3,"file":"getPosition.js","sourceRoot":"","sources":["../../src/utilities/getPosition.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-core-ts",
3
- "version": "2.1.42",
3
+ "version": "2.1.43",
4
4
  "description": "React Components",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -705,6 +705,11 @@ span.dropdown-search-icon {
705
705
  border-color: transparent transparent #000 transparent;
706
706
  }
707
707
 
708
+ .custom_tooltip_style_class.up.tooltiptext::after,
709
+ .custom_tooltip_style_class.down.tooltiptext::after {
710
+ left: var(--tooltip-arrow-left, 50%);
711
+ }
712
+
708
713
  .autocomplete-suggections .qbs-autocomplete-suggections-items {
709
714
  display: flex;
710
715
  /* justify-content: space-between; */
@@ -1,9 +1,10 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
2
2
  import ReactDOM from 'react-dom';
3
+ import { getPortalTooltipCoords } from './getPosition';
3
4
 
4
5
  const ExpandableToolTip: React.FC<any> = ({ title, children, enabled }) => {
5
6
  const [dropdownPosition, setDropdownPosition] = useState('bottom-position');
6
- const dropRef = useRef(null);
7
+ const dropRef = useRef<HTMLDivElement | null>(null);
7
8
  const menuButtonRef = useRef<HTMLDivElement>(null);
8
9
  const [isTooltipMounted, setIsTooltipMounted] = useState(false);
9
10
 
@@ -11,11 +12,11 @@ const ExpandableToolTip: React.FC<any> = ({ title, children, enabled }) => {
11
12
  const [tooltipStyle, setTooltipStyle] = useState({
12
13
  top: 0,
13
14
  left: 0,
14
- width: 0,
15
+ arrowOffset: 50,
15
16
  });
16
17
  const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
17
18
 
18
- const handleMouseEnter = (e: React.MouseEvent) => {
19
+ const handleMouseEnter = () => {
19
20
  if (hideTimeoutRef.current) {
20
21
  clearTimeout(hideTimeoutRef.current);
21
22
  hideTimeoutRef.current = null;
@@ -25,63 +26,45 @@ const ExpandableToolTip: React.FC<any> = ({ title, children, enabled }) => {
25
26
  }
26
27
  };
27
28
 
28
- useEffect(() => {
29
- if (
30
- visible &&
31
- isTooltipMounted &&
32
- menuButtonRef.current &&
29
+ const updatePosition = useCallback(() => {
30
+ if (!menuButtonRef.current || !dropRef.current) return;
31
+
32
+ const coords = getPortalTooltipCoords(
33
+ menuButtonRef.current,
33
34
  dropRef.current
34
- ) {
35
- const inputBoxRect = menuButtonRef.current.getBoundingClientRect();
36
- const tooltipHeight = dropRef.current.offsetHeight;
37
- const tooltipWidth = dropRef.current.offsetWidth;
38
- const boxWidth = inputBoxRect.width;
39
- const viewportHeight = window.innerHeight;
40
-
41
- const spaceAbove = inputBoxRect.top;
42
- const spaceBelow = viewportHeight - inputBoxRect.bottom;
43
-
44
- let dropPosition: 'top-position' | 'bottom-position' = 'bottom-position';
45
- if (spaceBelow >= tooltipHeight + 20) {
46
- dropPosition = 'bottom-position';
47
- } else if (spaceAbove >= tooltipHeight + 20) {
48
- dropPosition = 'top-position';
49
- } else {
50
- dropPosition =
51
- spaceBelow > spaceAbove ? 'bottom-position' : 'top-position';
35
+ );
36
+ setDropdownPosition(coords.placement);
37
+ setTooltipStyle((prev) => {
38
+ if (
39
+ prev.top === coords.top &&
40
+ prev.left === coords.left &&
41
+ prev.arrowOffset === coords.arrowOffset
42
+ ) {
43
+ return prev;
52
44
  }
53
- setDropdownPosition(dropPosition);
54
-
55
- let top =
56
- dropPosition === 'bottom-position'
57
- ? inputBoxRect.bottom + 8 + window.scrollY
58
- : inputBoxRect.top - tooltipHeight - 8 + window.scrollY;
59
-
60
- const left = inputBoxRect.left + boxWidth / 2 - 200 / 2 + window.scrollX;
61
-
62
- setTooltipStyle({
63
- top,
64
- left: Math.max(left, 8),
65
- width: 200,
66
- });
67
-
68
- // ✨ Recalculate again after a small delay
69
- setTimeout(() => {
70
- if (dropRef.current) {
71
- const correctedHeight = dropRef.current.offsetHeight;
72
- const correctedTop =
73
- dropPosition === 'bottom-position'
74
- ? inputBoxRect.bottom + 8 + window.scrollY
75
- : inputBoxRect.top - correctedHeight - 8 + window.scrollY;
76
-
77
- setTooltipStyle((prev) => ({
78
- ...prev,
79
- top: correctedTop,
80
- }));
81
- }
82
- }, 0);
83
- }
84
- }, [visible]);
45
+ return {
46
+ top: coords.top,
47
+ left: coords.left,
48
+ arrowOffset: coords.arrowOffset,
49
+ };
50
+ });
51
+ }, []);
52
+
53
+ useLayoutEffect(() => {
54
+ if (!visible || !isTooltipMounted) return;
55
+
56
+ updatePosition();
57
+ const frame = window.requestAnimationFrame(updatePosition);
58
+
59
+ window.addEventListener('resize', updatePosition);
60
+ window.addEventListener('scroll', updatePosition, true);
61
+
62
+ return () => {
63
+ window.cancelAnimationFrame(frame);
64
+ window.removeEventListener('resize', updatePosition);
65
+ window.removeEventListener('scroll', updatePosition, true);
66
+ };
67
+ }, [visible, isTooltipMounted, updatePosition]);
85
68
 
86
69
  useEffect(() => {
87
70
  const handleMouseMove = (event: MouseEvent) => {
@@ -152,17 +135,19 @@ const ExpandableToolTip: React.FC<any> = ({ title, children, enabled }) => {
152
135
  className={`tooltiptext custom_tooltip_style_class ${
153
136
  dropdownPosition == 'bottom-position' ? 'down' : 'up'
154
137
  }`}
155
- style={{
156
- top: tooltipStyle.top,
157
- left: tooltipStyle.left,
158
- opacity: visible ? 1 : 0,
159
- visibility: visible ? 'visible' : 'hidden',
160
- width: tooltipStyle.width,
161
- minWidth: '60px',
162
- maxWidth: '200px',
163
- pointerEvents: 'auto',
164
- maxHeight: '210px',
165
- }}
138
+ style={
139
+ {
140
+ top: tooltipStyle.top,
141
+ left: tooltipStyle.left,
142
+ opacity: visible ? 1 : 0,
143
+ visibility: visible ? 'visible' : 'hidden',
144
+ minWidth: '60px',
145
+ maxWidth: '200px',
146
+ pointerEvents: 'auto',
147
+ maxHeight: '210px',
148
+ '--tooltip-arrow-left': `${tooltipStyle.arrowOffset}px`,
149
+ } as React.CSSProperties
150
+ }
166
151
  >
167
152
  <div
168
153
  className=""
@@ -1,99 +1,65 @@
1
- import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
1
+ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
2
2
  import ReactDOM from 'react-dom';
3
+ import { getPortalTooltipCoords } from './getPosition';
3
4
 
4
5
  const ExpandableToolTip: React.FC<any> = ({ title, children, enabled }) => {
5
6
  const [dropdownPosition, setDropdownPosition] = useState('bottom-position');
6
- const dropRef = useRef(null);
7
+ const dropRef = useRef<HTMLSpanElement | null>(null);
7
8
  const menuButtonRef = useRef<HTMLDivElement>(null);
8
9
  const [visible, setVisible] = useState(false);
9
10
  const [tooltipStyle, setTooltipStyle] = useState({
10
11
  top: 0,
11
12
  left: 0,
12
- width: 0,
13
+ arrowOffset: 50,
13
14
  });
14
- const adjustDropdownPosition = (): string => {
15
- if (menuButtonRef.current) {
16
- const inputBoxRect = menuButtonRef.current?.getBoundingClientRect();
17
- const viewportHeight = window.innerHeight;
18
15
 
19
- const spaceAbove = inputBoxRect.top;
20
- const spaceBelow = viewportHeight - inputBoxRect.bottom;
21
- if (spaceAbove > spaceBelow) {
22
- if (spaceAbove > 90 && spaceBelow < 120) {
23
- return 'top-position';
24
- } else {
25
- return 'bottom-position';
26
- }
27
- } else {
28
- const diff: number = spaceBelow - spaceAbove;
29
- if (spaceAbove > 90 && spaceBelow > 90 && diff < 90) {
30
- return 'top-position';
31
- } else {
32
- return 'bottom-position';
33
- }
34
- }
35
- }
36
- };
37
-
38
- const handleMouseEnter = (e: React.MouseEvent) => {
39
- if (menuButtonRef.current) {
40
- const dropPosition = adjustDropdownPosition();
41
- setDropdownPosition(dropPosition);
42
- const rect = (e.target as HTMLElement).getBoundingClientRect();
43
- let top = rect.bottom + window.scrollY;
44
- let left = rect.left + window.scrollX;
45
- const height = rect.height;
46
- const width = dropRef?.current?.offsetWidth;
47
- if (dropPosition === 'bottom-position') {
48
- top = top + height / 2 - 5;
49
- } else {
50
- top = top - height * 2 + 15;
51
- }
52
-
53
- setTooltipStyle({
54
- top: top,
55
- left: left,
56
- width: width,
57
- });
58
- setVisible(true);
59
- }
16
+ const handleMouseEnter = () => {
17
+ setVisible(true);
60
18
  };
61
19
 
62
20
  const handleMouseLeave = () => {
63
21
  setVisible(false);
64
22
  };
65
23
 
66
- useLayoutEffect(() => {
67
- const updateTooltipPosition = () => {
68
- if (dropRef.current && visible && tooltipStyle) {
69
- const tooltipHeight = dropRef.current.offsetHeight;
70
- const tooltipWidth = dropRef.current.offsetWidth;
71
- const boxWidth = menuButtonRef.current.offsetWidth;
72
- setTooltipStyle((prevStyle) => ({
73
- ...prevStyle,
74
- left:
75
- prevStyle.left + boxWidth / 2 - tooltipWidth / 2 < 0
76
- ? 20
77
- : prevStyle.left + boxWidth / 2 - tooltipWidth / 2,
78
- width: tooltipWidth,
79
- top:
80
- dropdownPosition === 'bottom-position'
81
- ? prevStyle.top
82
- : prevStyle.top - tooltipHeight,
83
- }));
24
+ const updatePosition = useCallback(() => {
25
+ if (!menuButtonRef.current || !dropRef.current) return;
26
+
27
+ const coords = getPortalTooltipCoords(
28
+ menuButtonRef.current,
29
+ dropRef.current
30
+ );
31
+ setDropdownPosition(coords.placement);
32
+ setTooltipStyle((prev) => {
33
+ if (
34
+ prev.top === coords.top &&
35
+ prev.left === coords.left &&
36
+ prev.arrowOffset === coords.arrowOffset
37
+ ) {
38
+ return prev;
84
39
  }
85
- };
40
+ return {
41
+ top: coords.top,
42
+ left: coords.left,
43
+ arrowOffset: coords.arrowOffset,
44
+ };
45
+ });
46
+ }, []);
47
+
48
+ useLayoutEffect(() => {
49
+ if (!visible) return;
86
50
 
87
- if (visible) {
88
- updateTooltipPosition();
89
- }
51
+ updatePosition();
52
+ const frame = window.requestAnimationFrame(updatePosition);
90
53
 
91
- window.addEventListener('resize', updateTooltipPosition);
54
+ window.addEventListener('resize', updatePosition);
55
+ window.addEventListener('scroll', updatePosition, true);
92
56
 
93
57
  return () => {
94
- window.removeEventListener('resize', updateTooltipPosition);
58
+ window.cancelAnimationFrame(frame);
59
+ window.removeEventListener('resize', updatePosition);
60
+ window.removeEventListener('scroll', updatePosition, true);
95
61
  };
96
- }, [visible, dropdownPosition]);
62
+ }, [visible, updatePosition]);
97
63
 
98
64
  useEffect(() => {
99
65
  const handleClickOutside = (event: MouseEvent) => {
@@ -122,19 +88,23 @@ const ExpandableToolTip: React.FC<any> = ({ title, children, enabled }) => {
122
88
  tooltipStyle &&
123
89
  ReactDOM.createPortal(
124
90
  <span
125
- ref={(node) => (dropRef.current = node)}
91
+ ref={(node) => {
92
+ dropRef.current = node;
93
+ }}
126
94
  className={`tooltiptext custom_tooltip_style_class ${
127
95
  dropdownPosition == 'bottom-position' ? 'down' : 'up'
128
96
  }`}
129
- style={{
130
- top: tooltipStyle.top,
131
- left: tooltipStyle.left,
132
- opacity: 1,
133
- width: tooltipStyle.width,
134
- minWidth: '60px',
135
- maxWidth: '200px',
136
- visibility: 'visible',
137
- }}
97
+ style={
98
+ {
99
+ top: tooltipStyle.top,
100
+ left: tooltipStyle.left,
101
+ opacity: 1,
102
+ minWidth: '60px',
103
+ maxWidth: '200px',
104
+ visibility: 'visible',
105
+ '--tooltip-arrow-left': `${tooltipStyle.arrowOffset}px`,
106
+ } as React.CSSProperties
107
+ }
138
108
  >
139
109
  <span className="tooltip-text-container">{title}</span>
140
110
  </span>,
@@ -59,3 +59,65 @@ export const applyToolTipPositionClass = (
59
59
  textFieldElement.classList.add(positionClass);
60
60
  }
61
61
  };
62
+
63
+ export type PortalTooltipPlacement = 'top-position' | 'bottom-position';
64
+
65
+ export type PortalTooltipCoords = {
66
+ top: number;
67
+ left: number;
68
+ arrowOffset: number;
69
+ placement: PortalTooltipPlacement;
70
+ };
71
+
72
+ const VIEWPORT_PAD = 8;
73
+ const TOOLTIP_GAP = 8;
74
+ const ARROW_HALF = 5;
75
+
76
+ /** Center a portaled tooltip on its trigger and keep the arrow on the trigger. */
77
+ export const getPortalTooltipCoords = (
78
+ anchorEl: HTMLElement,
79
+ tooltipEl: HTMLElement
80
+ ): PortalTooltipCoords => {
81
+ const anchor = anchorEl.getBoundingClientRect();
82
+ const tooltipWidth = Math.max(tooltipEl.offsetWidth, 60);
83
+ const tooltipHeight = tooltipEl.offsetHeight;
84
+
85
+ const spaceAbove = anchor.top;
86
+ const spaceBelow = window.innerHeight - anchor.bottom;
87
+
88
+ let placement: PortalTooltipPlacement = 'bottom-position';
89
+ if (spaceBelow >= tooltipHeight + 20) {
90
+ placement = 'bottom-position';
91
+ } else if (spaceAbove >= tooltipHeight + 20) {
92
+ placement = 'top-position';
93
+ } else {
94
+ placement = spaceBelow > spaceAbove ? 'bottom-position' : 'top-position';
95
+ }
96
+
97
+ const top =
98
+ placement === 'bottom-position'
99
+ ? anchor.bottom + TOOLTIP_GAP + window.scrollY
100
+ : anchor.top - tooltipHeight - TOOLTIP_GAP + window.scrollY;
101
+
102
+ const triggerCenterX = anchor.left + anchor.width / 2;
103
+ const minLeft = VIEWPORT_PAD;
104
+ const maxLeft = window.innerWidth - tooltipWidth - VIEWPORT_PAD;
105
+ let left =
106
+ maxLeft < minLeft
107
+ ? minLeft
108
+ : Math.min(Math.max(triggerCenterX - tooltipWidth / 2, minLeft), maxLeft);
109
+
110
+ const minArrow = ARROW_HALF + 6;
111
+ const maxArrow = Math.max(minArrow, tooltipWidth - ARROW_HALF - 6);
112
+ const arrowOffset = Math.min(
113
+ Math.max(triggerCenterX - left, minArrow),
114
+ maxArrow
115
+ );
116
+
117
+ return {
118
+ top,
119
+ left: left + window.scrollX,
120
+ arrowOffset,
121
+ placement,
122
+ };
123
+ };