@unbxd-ui/unbxd-react-components 0.2.145-beta.6 → 0.2.145-beta.8

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.
@@ -11,127 +11,266 @@ var _excluded = ["TooltipActivator", "activatorAction", "direction", "children",
11
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
12
12
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
13
13
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
14
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
15
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
14
16
  function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
15
17
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
16
18
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
17
19
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
18
20
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
19
21
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
20
- function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
21
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
22
22
  /* eslint-disable react/prop-types */
23
23
  var DefaultTooltipActivator = function DefaultTooltipActivator() {
24
24
  return /*#__PURE__*/_react["default"].createElement(_react.Fragment, null, "i");
25
25
  };
26
- var Tooltip = function Tooltip(props, ref) {
26
+
27
+ // Dynamic positioning hook
28
+ var useTooltipPosition = function useTooltipPosition(activatorRef, tooltipRef) {
29
+ var preferredDirection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'top';
30
+ var isOpen = arguments.length > 3 ? arguments[3] : undefined;
31
+ var _useState = (0, _react.useState)({
32
+ direction: preferredDirection,
33
+ tooltipStyle: {},
34
+ arrowStyle: {}
35
+ }),
36
+ _useState2 = _slicedToArray(_useState, 2),
37
+ position = _useState2[0],
38
+ setPosition = _useState2[1];
39
+ var calculatePosition = (0, _react.useCallback)(function () {
40
+ if (!activatorRef.current || !tooltipRef.current || !isOpen) return;
41
+ var activator = activatorRef.current.getBoundingClientRect();
42
+ var tooltip = tooltipRef.current.getBoundingClientRect();
43
+ var viewport = {
44
+ width: window.innerWidth,
45
+ height: window.innerHeight
46
+ };
47
+ var spacing = 12; // Increased from 8 to 12 to prevent overlap
48
+ var arrowSize = 8; // Size of the pointer triangle
49
+
50
+ // Calculate available space in each direction
51
+ var spaces = {
52
+ top: activator.top,
53
+ bottom: viewport.height - activator.bottom,
54
+ left: activator.left,
55
+ right: viewport.width - activator.right
56
+ };
57
+
58
+ // Determine best direction based on available space
59
+ var direction = preferredDirection;
60
+ var requiredSpace = {
61
+ top: tooltip.height + spacing + arrowSize,
62
+ bottom: tooltip.height + spacing + arrowSize,
63
+ left: tooltip.width + spacing + arrowSize,
64
+ right: tooltip.width + spacing + arrowSize
65
+ };
66
+
67
+ // Check if preferred direction has enough space, otherwise find best alternative
68
+ if (spaces[direction] < requiredSpace[direction]) {
69
+ var alternatives = Object.keys(spaces).filter(function (dir) {
70
+ return spaces[dir] >= requiredSpace[dir];
71
+ }).sort(function (a, b) {
72
+ return spaces[b] - spaces[a];
73
+ });
74
+ direction = alternatives[0] || preferredDirection; // Fallback to preferred if no space
75
+ }
76
+
77
+ // Calculate tooltip position relative to the activator
78
+ var tooltipStyle = {
79
+ position: 'absolute'
80
+ };
81
+ var arrowStyle = {
82
+ position: 'absolute'
83
+ };
84
+ switch (direction) {
85
+ case 'top':
86
+ tooltipStyle.bottom = "".concat(activator.height + spacing, "px"); // Changed to use activator height + spacing
87
+ tooltipStyle.left = "50%";
88
+ tooltipStyle.transform = 'translateX(-50%)';
89
+ arrowStyle.top = '100%';
90
+ arrowStyle.left = '50%';
91
+ arrowStyle.transform = 'translateX(-50%)';
92
+ break;
93
+ case 'bottom':
94
+ tooltipStyle.top = "".concat(activator.height + spacing, "px"); // Changed to use activator height + spacing
95
+ tooltipStyle.left = "50%";
96
+ tooltipStyle.transform = 'translateX(-50%)';
97
+ arrowStyle.bottom = '100%';
98
+ arrowStyle.left = '50%';
99
+ arrowStyle.transform = 'translateX(-50%)';
100
+ break;
101
+ case 'left':
102
+ tooltipStyle.right = "".concat(activator.width + spacing, "px"); // Changed to use activator width + spacing
103
+ tooltipStyle.top = "50%";
104
+ tooltipStyle.transform = 'translateY(-50%)';
105
+ arrowStyle.left = '100%';
106
+ arrowStyle.top = '50%';
107
+ arrowStyle.transform = 'translateY(-50%)';
108
+ break;
109
+ case 'right':
110
+ tooltipStyle.left = "".concat(activator.width + spacing, "px"); // Changed to use activator width + spacing
111
+ tooltipStyle.top = "50%";
112
+ tooltipStyle.transform = 'translateY(-50%)';
113
+ arrowStyle.right = '100%';
114
+ arrowStyle.top = '50%';
115
+ arrowStyle.transform = 'translateY(-50%)';
116
+ break;
117
+ }
118
+
119
+ // Handle viewport boundary collisions for horizontal directions
120
+ if (direction === 'top' || direction === 'bottom') {
121
+ var tooltipCenter = activator.left + activator.width / 2;
122
+ var tooltipHalfWidth = tooltip.width / 2;
123
+ if (tooltipCenter - tooltipHalfWidth < 0) {
124
+ // Too far left
125
+ tooltipStyle.left = "".concat(-activator.left, "px");
126
+ tooltipStyle.transform = 'none';
127
+ arrowStyle.left = "".concat(activator.width / 2, "px");
128
+ } else if (tooltipCenter + tooltipHalfWidth > viewport.width) {
129
+ // Too far right
130
+ tooltipStyle.right = "".concat(activator.left + activator.width - viewport.width, "px");
131
+ tooltipStyle.left = 'auto';
132
+ tooltipStyle.transform = 'none';
133
+ arrowStyle.right = "".concat(activator.width / 2, "px");
134
+ arrowStyle.left = 'auto';
135
+ }
136
+ }
137
+ setPosition({
138
+ direction: direction,
139
+ tooltipStyle: tooltipStyle,
140
+ arrowStyle: arrowStyle
141
+ });
142
+ }, [preferredDirection, isOpen]);
143
+ (0, _react.useEffect)(function () {
144
+ if (isOpen && activatorRef.current && tooltipRef.current) {
145
+ // Small delay to ensure tooltip is rendered
146
+ var timer = setTimeout(calculatePosition, 10);
147
+ return function () {
148
+ return clearTimeout(timer);
149
+ };
150
+ }
151
+ }, [calculatePosition, isOpen]);
152
+ (0, _react.useEffect)(function () {
153
+ if (isOpen) {
154
+ var handleResize = function handleResize() {
155
+ return calculatePosition();
156
+ };
157
+ window.addEventListener('resize', handleResize);
158
+ return function () {
159
+ return window.removeEventListener('resize', handleResize);
160
+ };
161
+ }
162
+ }, [calculatePosition, isOpen]);
163
+ return position;
164
+ };
165
+ var Tooltip = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
27
166
  var TooltipActivator = props.TooltipActivator,
28
167
  activatorAction = props.activatorAction,
29
- direction = props.direction,
168
+ _props$direction = props.direction,
169
+ preferredDirection = _props$direction === void 0 ? 'top' : _props$direction,
30
170
  children = props.children,
31
- className = props.className,
171
+ _props$className = props.className,
172
+ className = _props$className === void 0 ? "" : _props$className,
32
173
  restProps = _objectWithoutProperties(props, _excluded);
33
- var _useState = (0, _react.useState)(""),
34
- _useState2 = _slicedToArray(_useState, 2),
35
- actionClassName = _useState2[0],
36
- setActionClassName = _useState2[1];
37
174
  var _useState3 = (0, _react.useState)(false),
38
175
  _useState4 = _slicedToArray(_useState3, 2),
39
176
  isOpen = _useState4[0],
40
177
  setIsOpen = _useState4[1];
41
- var tooltipBodyRef = (0, _react.useRef)(null);
178
+ var _useState5 = (0, _react.useState)(""),
179
+ _useState6 = _slicedToArray(_useState5, 2),
180
+ actionClassName = _useState6[0],
181
+ setActionClassName = _useState6[1];
182
+ var activatorRef = (0, _react.useRef)(null);
42
183
  var tooltipRef = (0, _react.useRef)(null);
43
- var dirClassName = "RCB-tooltip-right";
44
- switch (direction) {
45
- case "bottom":
46
- dirClassName = "RCB-tooltip-bottom";
47
- break;
48
- case "left":
49
- dirClassName = "RCB-tooltip-left";
50
- break;
51
- case "top":
52
- dirClassName = "RCB-tooltip-top";
53
- break;
54
- default:
55
- dirClassName = "RCB-tooltip-right";
56
- break;
57
- }
184
+ var containerRef = (0, _react.useRef)(null);
185
+
186
+ // Use the dynamic positioning hook
187
+ var _useTooltipPosition = useTooltipPosition(activatorRef, tooltipRef, preferredDirection, isOpen),
188
+ direction = _useTooltipPosition.direction,
189
+ tooltipStyle = _useTooltipPosition.tooltipStyle,
190
+ arrowStyle = _useTooltipPosition.arrowStyle;
58
191
  (0, _react.useImperativeHandle)(ref, function () {
59
192
  return {
60
193
  hideToolTip: function hideToolTip() {
61
- setIsOpen(false);
194
+ return setIsOpen(false);
62
195
  }
63
196
  };
64
197
  });
65
- var showToolTipClick = function showToolTipClick(e) {
66
- e.stopPropagation();
67
- setIsOpen(!isOpen);
68
- setActionClassName("RCB-tooltip-click");
69
- };
70
- var showToolTipHover = function showToolTipHover() {
71
- setActionClassName("RCB-tooltip-hover");
72
- setIsOpen(true);
198
+ var showToolTip = function showToolTip(e) {
199
+ if (activatorAction === 'click') {
200
+ e.stopPropagation();
201
+ setIsOpen(!isOpen);
202
+ setActionClassName("RCB-tooltip-click");
203
+ } else {
204
+ setIsOpen(true);
205
+ setActionClassName("RCB-tooltip-hover");
206
+ }
73
207
  };
74
208
  var hideToolTip = function hideToolTip() {
75
209
  setIsOpen(false);
76
210
  };
77
- var changeModalState = function changeModalState(newState) {
78
- setIsOpen(newState);
79
- };
80
- var onBodyClick = function onBodyClick(e) {
81
- var eventTarget = e.target;
82
- var inlineModalNode = tooltipRef.current;
83
- var eventPathNodes = e.composedPath();
84
- var isWithinModal = false;
85
- if (inlineModalNode.contains(eventTarget)) {
86
- isWithinModal = true;
87
- } else {
88
- for (var i = 0; i < eventPathNodes.length; i++) {
89
- var node = eventPathNodes[i];
90
- if (node !== window && inlineModalNode.contains(node)) {
91
- isWithinModal = true;
92
- break;
211
+
212
+ // Handle outside click for click-activated tooltips
213
+ (0, _react.useEffect)(function () {
214
+ if (activatorAction === 'click' && isOpen) {
215
+ var handleOutsideClick = function handleOutsideClick(e) {
216
+ // Check if click is outside the container (includes both activator and tooltip)
217
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
218
+ setIsOpen(false);
93
219
  }
94
- }
95
- }
96
- if (!isWithinModal) {
97
- /* outside click -> close modal */
98
- changeModalState(false);
220
+ };
221
+
222
+ // Add event listener with a small delay to avoid immediate closure
223
+ var timer = setTimeout(function () {
224
+ document.addEventListener('click', handleOutsideClick);
225
+ }, 10);
226
+ return function () {
227
+ clearTimeout(timer);
228
+ document.removeEventListener('click', handleOutsideClick);
229
+ };
99
230
  }
100
- };
101
- (0, _react.useEffect)(function () {
102
- /* add when mounted */
103
- document.addEventListener("click", onBodyClick);
231
+ }, [activatorAction, isOpen]);
104
232
 
105
- /* return function to be called when unmounted */
106
- return function () {
107
- document.removeEventListener("click", onBodyClick);
108
- };
109
- }, []);
110
- var eventProps = activatorAction === "click" ? {
111
- onClick: showToolTipClick
112
- } : {
113
- onMouseEnter: showToolTipHover,
233
+ // For hover tooltips, handle mouse events on the container
234
+ var containerEventProps = activatorAction === 'hover' ? {
235
+ onMouseEnter: showToolTip,
114
236
  onMouseLeave: hideToolTip
115
- };
116
- return /*#__PURE__*/_react["default"].createElement("div", {
237
+ } : {};
238
+
239
+ // For click tooltips, handle events on the activator
240
+ var activatorEventProps = activatorAction === 'click' ? {
241
+ onClick: showToolTip
242
+ } : {};
243
+ return /*#__PURE__*/_react["default"].createElement("div", _extends({
117
244
  className: "RCB-tooltip ".concat(className),
118
- ref: tooltipRef
119
- }, /*#__PURE__*/_react["default"].createElement("div", _extends({
245
+ ref: containerRef
246
+ }, containerEventProps), /*#__PURE__*/_react["default"].createElement("div", _extends({
120
247
  className: "RCB-tooltip-btn"
121
- }, eventProps), /*#__PURE__*/_react["default"].createElement(TooltipActivator, restProps)), isOpen && /*#__PURE__*/_react["default"].createElement("div", {
122
- className: "RCB-tooltip-body ".concat(dirClassName, " ").concat(actionClassName),
123
- ref: tooltipBodyRef
124
- }, children));
125
- };
126
- Tooltip = /*#__PURE__*/(0, _react.forwardRef)(Tooltip);
248
+ }, activatorEventProps, {
249
+ ref: activatorRef
250
+ }), /*#__PURE__*/_react["default"].createElement(TooltipActivator, restProps)), isOpen && /*#__PURE__*/_react["default"].createElement("div", {
251
+ className: "RCB-tooltip-body RCB-tooltip-".concat(direction, " ").concat(actionClassName),
252
+ ref: tooltipRef,
253
+ style: tooltipStyle
254
+ }, children, /*#__PURE__*/_react["default"].createElement("div", {
255
+ className: "RCB-tooltip-arrow RCB-tooltip-arrow-".concat(direction),
256
+ style: arrowStyle
257
+ })));
258
+ });
127
259
  Tooltip.propTypes = {
260
+ /** Custom component to act as the tooltip activator */
128
261
  TooltipActivator: _propTypes["default"].func,
262
+ /** Action that triggers the tooltip - either click or hover */
129
263
  activatorAction: _propTypes["default"].oneOf(["click", "hover"]),
130
- direction: _propTypes["default"].oneOf(["right", "bottom", "left", "top"])
264
+ /** Preferred direction for tooltip placement. Will auto-adjust based on available space */
265
+ direction: _propTypes["default"].oneOf(["right", "bottom", "left", "top"]),
266
+ /** Tooltip content */
267
+ children: _propTypes["default"].node,
268
+ /** Additional CSS classes */
269
+ className: _propTypes["default"].string
131
270
  };
132
271
  Tooltip.defaultProps = {
133
272
  TooltipActivator: DefaultTooltipActivator,
134
273
  activatorAction: "hover",
135
- direction: "right"
274
+ direction: "top"
136
275
  };
137
276
  var _default = exports["default"] = Tooltip;