@app-studio/web 0.9.14 → 0.9.15
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.
- package/dist/web.cjs.development.js +331 -282
- package/dist/web.cjs.development.js.map +1 -1
- package/dist/web.cjs.production.min.js +1 -1
- package/dist/web.cjs.production.min.js.map +1 -1
- package/dist/web.esm.js +331 -282
- package/dist/web.esm.js.map +1 -1
- package/dist/web.umd.development.js +331 -282
- package/dist/web.umd.development.js.map +1 -1
- package/dist/web.umd.production.min.js +1 -1
- package/dist/web.umd.production.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -5711,6 +5711,24 @@
|
|
|
5711
5711
|
var {
|
|
5712
5712
|
getColor
|
|
5713
5713
|
} = appStudio.useTheme();
|
|
5714
|
+
// Use useElementPosition for intelligent tooltip positioning
|
|
5715
|
+
var {
|
|
5716
|
+
ref: positionRef,
|
|
5717
|
+
relation
|
|
5718
|
+
} = appStudio.useElementPosition({
|
|
5719
|
+
trackChanges: true,
|
|
5720
|
+
trackOnHover: true,
|
|
5721
|
+
trackOnScroll: true,
|
|
5722
|
+
trackOnResize: true
|
|
5723
|
+
});
|
|
5724
|
+
// Create a separate ref for the SVG element
|
|
5725
|
+
var chartRef = React.useRef(null);
|
|
5726
|
+
// Sync the position ref with the chart ref for positioning calculations
|
|
5727
|
+
React.useEffect(() => {
|
|
5728
|
+
if (chartRef.current && positionRef) {
|
|
5729
|
+
positionRef.current = chartRef.current;
|
|
5730
|
+
}
|
|
5731
|
+
}, [chartRef, positionRef]);
|
|
5714
5732
|
// Calculate chart dimensions
|
|
5715
5733
|
var size = Math.min(width, height);
|
|
5716
5734
|
var radius = size / 2 * 0.8;
|
|
@@ -5779,12 +5797,30 @@
|
|
|
5779
5797
|
return result;
|
|
5780
5798
|
}, [dataPoints, total, radius, centerX, centerY, donutRadius, animationProgress, isDonut]);
|
|
5781
5799
|
return /*#__PURE__*/React__default.createElement("svg", {
|
|
5800
|
+
ref: chartRef,
|
|
5782
5801
|
width: width,
|
|
5783
5802
|
height: height
|
|
5784
5803
|
}, slices.map((slice, index) => {
|
|
5785
5804
|
var handleMouseEnter = e => {
|
|
5786
5805
|
var tooltipContent = slice.label + ": " + slice.value + " (" + slice.percentage + ")";
|
|
5787
|
-
|
|
5806
|
+
// Use intelligent positioning based on useElementPosition relation data
|
|
5807
|
+
var x = e.clientX;
|
|
5808
|
+
var y = e.clientY;
|
|
5809
|
+
if (relation && chartRef.current) {
|
|
5810
|
+
var chartRect = chartRef.current.getBoundingClientRect();
|
|
5811
|
+
// Adjust tooltip position based on available space
|
|
5812
|
+
if (relation.space.horizontal === 'left') {
|
|
5813
|
+
x = e.clientX - 100; // Offset tooltip to the left
|
|
5814
|
+
} else {
|
|
5815
|
+
x = e.clientX + 10; // Offset tooltip to the right
|
|
5816
|
+
}
|
|
5817
|
+
if (relation.space.vertical === 'top') {
|
|
5818
|
+
y = e.clientY - 30; // Offset tooltip above
|
|
5819
|
+
} else {
|
|
5820
|
+
y = e.clientY + 10; // Offset tooltip below
|
|
5821
|
+
}
|
|
5822
|
+
}
|
|
5823
|
+
showTooltip(x, y, tooltipContent);
|
|
5788
5824
|
};
|
|
5789
5825
|
var handleClick = () => {
|
|
5790
5826
|
if (onSliceClick) {
|
|
@@ -13080,6 +13116,16 @@
|
|
|
13080
13116
|
var [mentionStartPos, setMentionStartPos] = React.useState(-1);
|
|
13081
13117
|
var [selectedMentionIndex, setSelectedMentionIndex] = React.useState(-1);
|
|
13082
13118
|
var [filteredMentions, setFilteredMentions] = React.useState([]);
|
|
13119
|
+
// Use useElementPosition for intelligent dropdown positioning
|
|
13120
|
+
var {
|
|
13121
|
+
ref: positionRef,
|
|
13122
|
+
relation
|
|
13123
|
+
} = appStudio.useElementPosition({
|
|
13124
|
+
trackChanges: true,
|
|
13125
|
+
trackOnHover: true,
|
|
13126
|
+
trackOnScroll: true,
|
|
13127
|
+
trackOnResize: true
|
|
13128
|
+
});
|
|
13083
13129
|
// Positioning state for dropdowns
|
|
13084
13130
|
var [mentionPosition, setMentionPosition] = React.useState({
|
|
13085
13131
|
x: 0,
|
|
@@ -13089,7 +13135,6 @@
|
|
|
13089
13135
|
x: 0,
|
|
13090
13136
|
y: 0
|
|
13091
13137
|
});
|
|
13092
|
-
// Note: Using custom positioning logic for better control over dropdown placement
|
|
13093
13138
|
// Update the content of the editable div when the value prop changes
|
|
13094
13139
|
React.useEffect(() => {
|
|
13095
13140
|
var editableDiv = ref;
|
|
@@ -13141,7 +13186,13 @@
|
|
|
13141
13186
|
setMentionStartPos(-1);
|
|
13142
13187
|
setSelectedMentionIndex(-1);
|
|
13143
13188
|
}, [mentionData, mentionTrigger]);
|
|
13144
|
-
//
|
|
13189
|
+
// Sync the position ref with the container ref for positioning calculations
|
|
13190
|
+
React.useEffect(() => {
|
|
13191
|
+
if (containerRef.current && positionRef) {
|
|
13192
|
+
positionRef.current = containerRef.current;
|
|
13193
|
+
}
|
|
13194
|
+
}, [containerRef, positionRef]);
|
|
13195
|
+
// Calculate optimal position for dropdowns using useElementPosition
|
|
13145
13196
|
var calculateDropdownPosition = React.useCallback(function (dropdownHeight) {
|
|
13146
13197
|
if (dropdownHeight === void 0) {
|
|
13147
13198
|
dropdownHeight = 200;
|
|
@@ -13151,22 +13202,26 @@
|
|
|
13151
13202
|
y: 0
|
|
13152
13203
|
};
|
|
13153
13204
|
var containerRect = containerRef.current.getBoundingClientRect();
|
|
13205
|
+
// Use relation data for intelligent positioning if available
|
|
13206
|
+
if (relation) {
|
|
13207
|
+
var _useTopPlacement = relation.space.vertical === 'top';
|
|
13208
|
+
return {
|
|
13209
|
+
x: containerRect.left,
|
|
13210
|
+
y: _useTopPlacement ? containerRect.top - dropdownHeight - 8 : containerRect.bottom + 8
|
|
13211
|
+
};
|
|
13212
|
+
}
|
|
13213
|
+
// Fallback to manual calculation if relation data is not available
|
|
13154
13214
|
var viewportHeight = window.innerHeight;
|
|
13155
|
-
var viewportWidth = window.innerWidth;
|
|
13156
|
-
// Calculate available space
|
|
13157
13215
|
var availableSpace = {
|
|
13158
13216
|
top: containerRect.top,
|
|
13159
|
-
bottom: viewportHeight - containerRect.bottom
|
|
13160
|
-
left: containerRect.left,
|
|
13161
|
-
right: viewportWidth - containerRect.right
|
|
13217
|
+
bottom: viewportHeight - containerRect.bottom
|
|
13162
13218
|
};
|
|
13163
|
-
// Prefer bottom placement, but use top if not enough space
|
|
13164
13219
|
var useTopPlacement = availableSpace.bottom < dropdownHeight + 8 && availableSpace.top > availableSpace.bottom;
|
|
13165
13220
|
return {
|
|
13166
13221
|
x: containerRect.left,
|
|
13167
13222
|
y: useTopPlacement ? containerRect.top - dropdownHeight - 8 : containerRect.bottom + 8
|
|
13168
13223
|
};
|
|
13169
|
-
}, []);
|
|
13224
|
+
}, [relation]);
|
|
13170
13225
|
// Handle focus events
|
|
13171
13226
|
var handleFocus = React.useCallback(() => {
|
|
13172
13227
|
setIsFocused(true);
|
|
@@ -13372,7 +13427,7 @@
|
|
|
13372
13427
|
opacity: 0.7,
|
|
13373
13428
|
padding: '4px'
|
|
13374
13429
|
}
|
|
13375
|
-
}, "Mentions (Trigger: ", mentionTrigger, ")"))))), showSuggestions && suggestions.length > 0 && !showMentions && isFocused && !value && (/*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({
|
|
13430
|
+
}, "Mentions (Trigger: ", mentionTrigger, ")", relation && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "Space: ", relation.space.vertical, "-", relation.space.horizontal))))))), showSuggestions && suggestions.length > 0 && !showMentions && isFocused && !value && (/*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({
|
|
13376
13431
|
position: "fixed",
|
|
13377
13432
|
left: suggestionPosition.x,
|
|
13378
13433
|
top: suggestionPosition.y,
|
|
@@ -13418,7 +13473,7 @@
|
|
|
13418
13473
|
opacity: 0.7,
|
|
13419
13474
|
padding: '4px'
|
|
13420
13475
|
}
|
|
13421
|
-
}, "Suggestions (Focus-triggered)"))))));
|
|
13476
|
+
}, "Suggestions (Focus-triggered)", relation && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "Space: ", relation.space.vertical, "-", relation.space.horizontal))))))));
|
|
13422
13477
|
});
|
|
13423
13478
|
EditableInput.displayName = 'EditableInput';
|
|
13424
13479
|
|
|
@@ -17560,109 +17615,103 @@
|
|
|
17560
17615
|
triggerRef
|
|
17561
17616
|
} = useDropdownMenuContext();
|
|
17562
17617
|
var contentRef = React.useRef(null);
|
|
17618
|
+
// Use useElementPosition for intelligent positioning
|
|
17619
|
+
var {
|
|
17620
|
+
ref: positionRef,
|
|
17621
|
+
relation
|
|
17622
|
+
} = appStudio.useElementPosition({
|
|
17623
|
+
trackChanges: true,
|
|
17624
|
+
trackOnHover: true,
|
|
17625
|
+
trackOnScroll: true,
|
|
17626
|
+
trackOnResize: true
|
|
17627
|
+
});
|
|
17563
17628
|
var [optimalPosition, setOptimalPosition] = React.useState({
|
|
17564
17629
|
x: 0,
|
|
17565
17630
|
y: 0,
|
|
17566
17631
|
placement: side
|
|
17567
17632
|
});
|
|
17568
|
-
//
|
|
17633
|
+
// Sync the position ref with the trigger ref for positioning calculations
|
|
17634
|
+
React.useEffect(() => {
|
|
17635
|
+
if (triggerRef.current && positionRef) {
|
|
17636
|
+
positionRef.current = triggerRef.current;
|
|
17637
|
+
}
|
|
17638
|
+
}, [triggerRef, positionRef, isOpen]);
|
|
17639
|
+
// Calculate optimal position using useElementPosition when the dropdown opens
|
|
17569
17640
|
React.useEffect(() => {
|
|
17570
17641
|
if (isOpen && contentRef.current && triggerRef.current) {
|
|
17571
|
-
var contentRect = contentRef.current.getBoundingClientRect();
|
|
17572
17642
|
var triggerRect = triggerRef.current.getBoundingClientRect();
|
|
17573
|
-
|
|
17574
|
-
|
|
17575
|
-
|
|
17576
|
-
|
|
17577
|
-
|
|
17578
|
-
|
|
17579
|
-
|
|
17580
|
-
|
|
17581
|
-
|
|
17582
|
-
|
|
17583
|
-
|
|
17584
|
-
|
|
17585
|
-
|
|
17586
|
-
// Determine optimal placement based on available space and preferred side
|
|
17587
|
-
var placements = [{
|
|
17588
|
-
placement: 'bottom',
|
|
17589
|
-
space: availableSpace.bottom,
|
|
17590
|
-
fits: availableSpace.bottom >= contentHeight + 8,
|
|
17591
|
-
x: align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - contentWidth : triggerRect.left + triggerRect.width / 2 - contentWidth / 2,
|
|
17592
|
-
y: triggerRect.bottom + 8
|
|
17593
|
-
}, {
|
|
17594
|
-
placement: 'top',
|
|
17595
|
-
space: availableSpace.top,
|
|
17596
|
-
fits: availableSpace.top >= contentHeight + 8,
|
|
17597
|
-
x: align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - contentWidth : triggerRect.left + triggerRect.width / 2 - contentWidth / 2,
|
|
17598
|
-
y: triggerRect.top - contentHeight - 8
|
|
17599
|
-
}, {
|
|
17600
|
-
placement: 'right',
|
|
17601
|
-
space: availableSpace.right,
|
|
17602
|
-
fits: availableSpace.right >= contentWidth + 8,
|
|
17603
|
-
x: triggerRect.right + 8,
|
|
17604
|
-
y: align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - contentHeight : triggerRect.top + triggerRect.height / 2 - contentHeight / 2
|
|
17605
|
-
}, {
|
|
17606
|
-
placement: 'left',
|
|
17607
|
-
space: availableSpace.left,
|
|
17608
|
-
fits: availableSpace.left >= contentWidth + 8,
|
|
17609
|
-
x: triggerRect.left - contentWidth - 8,
|
|
17610
|
-
y: align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - contentHeight : triggerRect.top + triggerRect.height / 2 - contentHeight / 2
|
|
17611
|
-
}];
|
|
17612
|
-
// First try the preferred side if it fits
|
|
17613
|
-
var preferredPlacement = placements.find(p => p.placement === side && p.fits);
|
|
17614
|
-
if (preferredPlacement) {
|
|
17615
|
-
setOptimalPosition({
|
|
17616
|
-
x: preferredPlacement.x,
|
|
17617
|
-
y: preferredPlacement.y,
|
|
17618
|
-
placement: preferredPlacement.placement
|
|
17619
|
-
});
|
|
17620
|
-
return;
|
|
17621
|
-
}
|
|
17622
|
-
// Otherwise, find the best fitting placement
|
|
17623
|
-
var fittingPlacement = placements.find(p => p.fits);
|
|
17624
|
-
if (fittingPlacement) {
|
|
17625
|
-
setOptimalPosition({
|
|
17626
|
-
x: fittingPlacement.x,
|
|
17627
|
-
y: fittingPlacement.y,
|
|
17628
|
-
placement: fittingPlacement.placement
|
|
17629
|
-
});
|
|
17630
|
-
return;
|
|
17631
|
-
}
|
|
17632
|
-
// If nothing fits, choose the placement with the most space
|
|
17633
|
-
var bestPlacement = placements.reduce((best, current) => current.space > best.space ? current : best);
|
|
17634
|
-
// Ensure the content stays within viewport bounds
|
|
17635
|
-
var finalX = bestPlacement.x;
|
|
17636
|
-
var finalY = bestPlacement.y;
|
|
17637
|
-
if (finalX + contentWidth > viewportWidth) {
|
|
17638
|
-
finalX = viewportWidth - contentWidth - 8;
|
|
17639
|
-
}
|
|
17640
|
-
if (finalX < 8) {
|
|
17641
|
-
finalX = 8;
|
|
17642
|
-
}
|
|
17643
|
-
if (finalY + contentHeight > viewportHeight) {
|
|
17644
|
-
finalY = viewportHeight - contentHeight - 8;
|
|
17643
|
+
var placement = side;
|
|
17644
|
+
// Use relation data to determine optimal placement
|
|
17645
|
+
if (relation) {
|
|
17646
|
+
// If preferred side doesn't have enough space, use the side with more space
|
|
17647
|
+
if (side === 'bottom' && relation.space.vertical === 'top') {
|
|
17648
|
+
placement = 'top';
|
|
17649
|
+
} else if (side === 'top' && relation.space.vertical === 'bottom') {
|
|
17650
|
+
placement = 'bottom';
|
|
17651
|
+
} else if (side === 'right' && relation.space.horizontal === 'left') {
|
|
17652
|
+
placement = 'left';
|
|
17653
|
+
} else if (side === 'left' && relation.space.horizontal === 'right') {
|
|
17654
|
+
placement = 'right';
|
|
17655
|
+
}
|
|
17645
17656
|
}
|
|
17646
|
-
|
|
17647
|
-
|
|
17657
|
+
// Calculate position based on optimal placement and alignment
|
|
17658
|
+
var x = 0;
|
|
17659
|
+
var y = 0;
|
|
17660
|
+
switch (placement) {
|
|
17661
|
+
case 'bottom':
|
|
17662
|
+
x = align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - 180 // Estimated content width
|
|
17663
|
+
: triggerRect.left + triggerRect.width / 2 - 90; // Half of estimated width
|
|
17664
|
+
y = triggerRect.bottom + 8;
|
|
17665
|
+
break;
|
|
17666
|
+
case 'top':
|
|
17667
|
+
x = align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - 180 : triggerRect.left + triggerRect.width / 2 - 90;
|
|
17668
|
+
y = triggerRect.top - 8; // Will be adjusted with transform
|
|
17669
|
+
break;
|
|
17670
|
+
case 'right':
|
|
17671
|
+
x = triggerRect.right + 8;
|
|
17672
|
+
y = align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - 100 // Estimated content height
|
|
17673
|
+
: triggerRect.top + triggerRect.height / 2 - 50; // Half of estimated height
|
|
17674
|
+
break;
|
|
17675
|
+
case 'left':
|
|
17676
|
+
x = triggerRect.left - 8; // Will be adjusted with transform
|
|
17677
|
+
y = align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - 100 : triggerRect.top + triggerRect.height / 2 - 50;
|
|
17678
|
+
break;
|
|
17648
17679
|
}
|
|
17649
17680
|
setOptimalPosition({
|
|
17650
|
-
x
|
|
17651
|
-
y
|
|
17652
|
-
placement
|
|
17681
|
+
x,
|
|
17682
|
+
y,
|
|
17683
|
+
placement
|
|
17653
17684
|
});
|
|
17654
17685
|
}
|
|
17655
|
-
}, [isOpen, side, align, triggerRef]);
|
|
17686
|
+
}, [isOpen, side, align, triggerRef, relation]);
|
|
17656
17687
|
if (!isOpen) {
|
|
17657
17688
|
return null;
|
|
17658
17689
|
}
|
|
17659
|
-
// Create intelligent positioning styles
|
|
17660
|
-
var
|
|
17661
|
-
|
|
17662
|
-
|
|
17663
|
-
|
|
17664
|
-
|
|
17690
|
+
// Create intelligent positioning styles with transform for better placement
|
|
17691
|
+
var getPositionStyles = () => {
|
|
17692
|
+
var baseStyles = {
|
|
17693
|
+
position: 'fixed',
|
|
17694
|
+
left: optimalPosition.x,
|
|
17695
|
+
top: optimalPosition.y,
|
|
17696
|
+
zIndex: 1000
|
|
17697
|
+
};
|
|
17698
|
+
// Add transform based on placement for better positioning
|
|
17699
|
+
switch (optimalPosition.placement) {
|
|
17700
|
+
case 'top':
|
|
17701
|
+
return Object.assign({}, baseStyles, {
|
|
17702
|
+
transform: 'translateY(-100%)'
|
|
17703
|
+
});
|
|
17704
|
+
case 'left':
|
|
17705
|
+
return Object.assign({}, baseStyles, {
|
|
17706
|
+
transform: 'translateX(-100%)'
|
|
17707
|
+
});
|
|
17708
|
+
case 'bottom':
|
|
17709
|
+
case 'right':
|
|
17710
|
+
default:
|
|
17711
|
+
return baseStyles;
|
|
17712
|
+
}
|
|
17665
17713
|
};
|
|
17714
|
+
var positionStyles = getPositionStyles();
|
|
17666
17715
|
return /*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({
|
|
17667
17716
|
ref: contentRef,
|
|
17668
17717
|
id: "dropdown-menu",
|
|
@@ -17682,7 +17731,13 @@
|
|
|
17682
17731
|
item: item,
|
|
17683
17732
|
views: views
|
|
17684
17733
|
});
|
|
17685
|
-
})
|
|
17734
|
+
}), (/*#__PURE__*/React__default.createElement("div", {
|
|
17735
|
+
style: {
|
|
17736
|
+
fontSize: '10px',
|
|
17737
|
+
opacity: 0.7,
|
|
17738
|
+
padding: '4px'
|
|
17739
|
+
}
|
|
17740
|
+
}, "Placement: ", optimalPosition.placement, relation && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "Space: ", relation.space.vertical, "-", relation.space.horizontal)))));
|
|
17686
17741
|
};
|
|
17687
17742
|
// DropdownMenu Item component
|
|
17688
17743
|
var DropdownMenuItem = _ref4 => {
|
|
@@ -20866,111 +20921,99 @@
|
|
|
20866
20921
|
contentId,
|
|
20867
20922
|
triggerId
|
|
20868
20923
|
} = useHoverCardContext();
|
|
20869
|
-
|
|
20870
|
-
|
|
20871
|
-
|
|
20872
|
-
|
|
20924
|
+
// Use useElementPosition for intelligent positioning
|
|
20925
|
+
var {
|
|
20926
|
+
ref: positionRef,
|
|
20927
|
+
relation
|
|
20928
|
+
} = appStudio.useElementPosition({
|
|
20929
|
+
trackChanges: true,
|
|
20930
|
+
trackOnHover: true,
|
|
20931
|
+
trackOnScroll: true,
|
|
20932
|
+
trackOnResize: true
|
|
20873
20933
|
});
|
|
20874
|
-
//
|
|
20934
|
+
// Sync the position ref with the trigger ref for positioning calculations
|
|
20875
20935
|
React.useEffect(() => {
|
|
20876
|
-
if (
|
|
20877
|
-
|
|
20878
|
-
|
|
20879
|
-
|
|
20880
|
-
var contentWidth = Math.max(contentRect.width || 200, 200);
|
|
20881
|
-
var contentHeight = Math.max(contentRect.height || 100, 100);
|
|
20882
|
-
// Get viewport dimensions
|
|
20883
|
-
var viewportWidth = window.innerWidth;
|
|
20884
|
-
var viewportHeight = window.innerHeight;
|
|
20885
|
-
// Calculate available space on all sides from the trigger
|
|
20886
|
-
var availableSpace = {
|
|
20887
|
-
top: triggerRect.top,
|
|
20888
|
-
right: viewportWidth - triggerRect.right,
|
|
20889
|
-
bottom: viewportHeight - triggerRect.bottom,
|
|
20890
|
-
left: triggerRect.left
|
|
20891
|
-
};
|
|
20892
|
-
// Determine optimal placement based on available space and preferred side
|
|
20893
|
-
var placements = [{
|
|
20894
|
-
placement: 'bottom',
|
|
20895
|
-
space: availableSpace.bottom,
|
|
20896
|
-
fits: availableSpace.bottom >= contentHeight + sideOffset,
|
|
20897
|
-
x: triggerRect.left + triggerRect.width / 2 - contentWidth / 2,
|
|
20898
|
-
y: triggerRect.bottom + sideOffset
|
|
20899
|
-
}, {
|
|
20900
|
-
placement: 'top',
|
|
20901
|
-
space: availableSpace.top,
|
|
20902
|
-
fits: availableSpace.top >= contentHeight + sideOffset,
|
|
20903
|
-
x: triggerRect.left + triggerRect.width / 2 - contentWidth / 2,
|
|
20904
|
-
y: triggerRect.top - contentHeight - sideOffset
|
|
20905
|
-
}, {
|
|
20906
|
-
placement: 'right',
|
|
20907
|
-
space: availableSpace.right,
|
|
20908
|
-
fits: availableSpace.right >= contentWidth + sideOffset,
|
|
20909
|
-
x: triggerRect.right + sideOffset,
|
|
20910
|
-
y: triggerRect.top + triggerRect.height / 2 - contentHeight / 2
|
|
20911
|
-
}, {
|
|
20912
|
-
placement: 'left',
|
|
20913
|
-
space: availableSpace.left,
|
|
20914
|
-
fits: availableSpace.left >= contentWidth + sideOffset,
|
|
20915
|
-
x: triggerRect.left - contentWidth - sideOffset,
|
|
20916
|
-
y: triggerRect.top + triggerRect.height / 2 - contentHeight / 2
|
|
20917
|
-
}];
|
|
20918
|
-
// First try the preferred side if it fits
|
|
20919
|
-
var preferredPlacement = placements.find(p => p.placement === side && p.fits);
|
|
20920
|
-
if (preferredPlacement) {
|
|
20921
|
-
setOptimalPosition({
|
|
20922
|
-
x: preferredPlacement.x,
|
|
20923
|
-
y: preferredPlacement.y,
|
|
20924
|
-
placement: preferredPlacement.placement
|
|
20925
|
-
});
|
|
20926
|
-
return;
|
|
20927
|
-
}
|
|
20928
|
-
// Otherwise, find the best fitting placement
|
|
20929
|
-
var fittingPlacement = placements.find(p => p.fits);
|
|
20930
|
-
if (fittingPlacement) {
|
|
20931
|
-
setOptimalPosition({
|
|
20932
|
-
x: fittingPlacement.x,
|
|
20933
|
-
y: fittingPlacement.y,
|
|
20934
|
-
placement: fittingPlacement.placement
|
|
20935
|
-
});
|
|
20936
|
-
return;
|
|
20937
|
-
}
|
|
20938
|
-
// If nothing fits, choose the placement with the most space
|
|
20939
|
-
var bestPlacement = placements.reduce((best, current) => current.space > best.space ? current : best);
|
|
20940
|
-
// Ensure the content stays within viewport bounds
|
|
20941
|
-
var finalX = bestPlacement.x;
|
|
20942
|
-
var finalY = bestPlacement.y;
|
|
20943
|
-
if (finalX + contentWidth > viewportWidth) {
|
|
20944
|
-
finalX = viewportWidth - contentWidth - 8;
|
|
20945
|
-
}
|
|
20946
|
-
if (finalX < 8) {
|
|
20947
|
-
finalX = 8;
|
|
20948
|
-
}
|
|
20949
|
-
if (finalY + contentHeight > viewportHeight) {
|
|
20950
|
-
finalY = viewportHeight - contentHeight - 8;
|
|
20951
|
-
}
|
|
20952
|
-
if (finalY < 8) {
|
|
20953
|
-
finalY = 8;
|
|
20936
|
+
if (triggerRef != null && triggerRef.current && (positionRef == null ? void 0 : positionRef.current) !== triggerRef.current) {
|
|
20937
|
+
// Update the position tracking to use the trigger element
|
|
20938
|
+
if (positionRef) {
|
|
20939
|
+
positionRef.current = triggerRef.current;
|
|
20954
20940
|
}
|
|
20955
|
-
setOptimalPosition({
|
|
20956
|
-
x: finalX,
|
|
20957
|
-
y: finalY,
|
|
20958
|
-
placement: bestPlacement.placement
|
|
20959
|
-
});
|
|
20960
20941
|
}
|
|
20961
|
-
}, [
|
|
20942
|
+
}, [triggerRef, positionRef, isOpen]);
|
|
20962
20943
|
var handleMouseEnter = () => cancelCloseTimer(); // Keep card open if mouse enters content
|
|
20963
20944
|
var handleMouseLeave = () => closeCard();
|
|
20964
20945
|
if (!isOpen) {
|
|
20965
20946
|
return null; // Don't render content if not open
|
|
20966
20947
|
}
|
|
20967
|
-
// Create intelligent positioning styles
|
|
20968
|
-
var
|
|
20969
|
-
|
|
20970
|
-
|
|
20971
|
-
|
|
20972
|
-
|
|
20948
|
+
// Create intelligent positioning styles based on useElementPosition relation data
|
|
20949
|
+
var getPositionStyles = () => {
|
|
20950
|
+
if (!relation || !(triggerRef != null && triggerRef.current)) {
|
|
20951
|
+
// Fallback positioning if relation data is not available
|
|
20952
|
+
return {
|
|
20953
|
+
position: 'absolute',
|
|
20954
|
+
top: 0,
|
|
20955
|
+
left: 0,
|
|
20956
|
+
zIndex: 1000
|
|
20957
|
+
};
|
|
20958
|
+
}
|
|
20959
|
+
var triggerRect = triggerRef.current.getBoundingClientRect();
|
|
20960
|
+
var placement = side;
|
|
20961
|
+
// Use relation data to determine optimal placement
|
|
20962
|
+
// If preferred side doesn't have enough space, use the side with more space
|
|
20963
|
+
if (side === 'bottom' && relation.space.vertical === 'top') {
|
|
20964
|
+
placement = 'top';
|
|
20965
|
+
} else if (side === 'top' && relation.space.vertical === 'bottom') {
|
|
20966
|
+
placement = 'bottom';
|
|
20967
|
+
} else if (side === 'right' && relation.space.horizontal === 'left') {
|
|
20968
|
+
placement = 'left';
|
|
20969
|
+
} else if (side === 'left' && relation.space.horizontal === 'right') {
|
|
20970
|
+
placement = 'right';
|
|
20971
|
+
}
|
|
20972
|
+
// Calculate position based on optimal placement
|
|
20973
|
+
var x = 0;
|
|
20974
|
+
var y = 0;
|
|
20975
|
+
switch (placement) {
|
|
20976
|
+
case 'bottom':
|
|
20977
|
+
x = triggerRect.left + triggerRect.width / 2;
|
|
20978
|
+
y = triggerRect.bottom + sideOffset;
|
|
20979
|
+
break;
|
|
20980
|
+
case 'top':
|
|
20981
|
+
x = triggerRect.left + triggerRect.width / 2;
|
|
20982
|
+
y = triggerRect.top - sideOffset;
|
|
20983
|
+
break;
|
|
20984
|
+
case 'right':
|
|
20985
|
+
x = triggerRect.right + sideOffset;
|
|
20986
|
+
y = triggerRect.top + triggerRect.height / 2;
|
|
20987
|
+
break;
|
|
20988
|
+
case 'left':
|
|
20989
|
+
x = triggerRect.left - sideOffset;
|
|
20990
|
+
y = triggerRect.top + triggerRect.height / 2;
|
|
20991
|
+
break;
|
|
20992
|
+
}
|
|
20993
|
+
return {
|
|
20994
|
+
position: 'fixed',
|
|
20995
|
+
left: x,
|
|
20996
|
+
top: y,
|
|
20997
|
+
zIndex: 1000,
|
|
20998
|
+
transform: getTransformOrigin(placement)
|
|
20999
|
+
};
|
|
21000
|
+
};
|
|
21001
|
+
// Helper function to set transform origin for better positioning
|
|
21002
|
+
var getTransformOrigin = placement => {
|
|
21003
|
+
switch (placement) {
|
|
21004
|
+
case 'bottom':
|
|
21005
|
+
return 'translate(-50%, 0)';
|
|
21006
|
+
case 'top':
|
|
21007
|
+
return 'translate(-50%, -100%)';
|
|
21008
|
+
case 'right':
|
|
21009
|
+
return 'translate(0, -50%)';
|
|
21010
|
+
case 'left':
|
|
21011
|
+
return 'translate(-100%, -50%)';
|
|
21012
|
+
default:
|
|
21013
|
+
return 'translate(-50%, 0)';
|
|
21014
|
+
}
|
|
20973
21015
|
};
|
|
21016
|
+
var positionStyles = getPositionStyles();
|
|
20974
21017
|
return /*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({
|
|
20975
21018
|
ref: contentRef,
|
|
20976
21019
|
id: contentId,
|
|
@@ -20987,7 +21030,13 @@
|
|
|
20987
21030
|
maxWidth: maxWidth,
|
|
20988
21031
|
// Combine intelligent position styles with user styles
|
|
20989
21032
|
style: Object.assign({}, positionStyles, userStyle)
|
|
20990
|
-
}, views == null ? void 0 : views.container, props), children
|
|
21033
|
+
}, views == null ? void 0 : views.container, props), children, relation && (/*#__PURE__*/React__default.createElement("div", {
|
|
21034
|
+
style: {
|
|
21035
|
+
fontSize: '10px',
|
|
21036
|
+
opacity: 0.7,
|
|
21037
|
+
marginTop: '4px'
|
|
21038
|
+
}
|
|
21039
|
+
}, "Position: ", relation.position.vertical, "-", relation.position.horizontal, /*#__PURE__*/React__default.createElement("br", null), "More space: ", relation.space.vertical, "-", relation.space.horizontal)));
|
|
20991
21040
|
};
|
|
20992
21041
|
|
|
20993
21042
|
var _excluded$_ = ["children", "views", "openDelay", "closeDelay"];
|
|
@@ -24434,108 +24483,102 @@
|
|
|
24434
24483
|
contentId,
|
|
24435
24484
|
triggerId
|
|
24436
24485
|
} = useTooltipContext();
|
|
24486
|
+
// Use useElementPosition for intelligent positioning
|
|
24487
|
+
var {
|
|
24488
|
+
ref: positionRef,
|
|
24489
|
+
relation
|
|
24490
|
+
} = appStudio.useElementPosition({
|
|
24491
|
+
trackChanges: true,
|
|
24492
|
+
trackOnHover: true,
|
|
24493
|
+
trackOnScroll: true,
|
|
24494
|
+
trackOnResize: true
|
|
24495
|
+
});
|
|
24437
24496
|
var [optimalPosition, setOptimalPosition] = React.useState({
|
|
24438
24497
|
x: 0,
|
|
24439
24498
|
y: 0,
|
|
24440
24499
|
placement: position
|
|
24441
24500
|
});
|
|
24442
|
-
//
|
|
24501
|
+
// Sync the position ref with the trigger ref for positioning calculations
|
|
24502
|
+
React.useEffect(() => {
|
|
24503
|
+
if (triggerRef != null && triggerRef.current && positionRef) {
|
|
24504
|
+
positionRef.current = triggerRef.current;
|
|
24505
|
+
}
|
|
24506
|
+
}, [triggerRef, positionRef, isOpen]);
|
|
24507
|
+
// Calculate optimal position using useElementPosition when the tooltip opens
|
|
24443
24508
|
React.useEffect(() => {
|
|
24444
24509
|
if (isOpen && contentRef != null && contentRef.current && triggerRef != null && triggerRef.current) {
|
|
24445
|
-
var contentRect = contentRef.current.getBoundingClientRect();
|
|
24446
24510
|
var triggerRect = triggerRef.current.getBoundingClientRect();
|
|
24447
|
-
|
|
24448
|
-
|
|
24449
|
-
|
|
24450
|
-
|
|
24451
|
-
|
|
24452
|
-
|
|
24453
|
-
|
|
24454
|
-
|
|
24455
|
-
|
|
24456
|
-
|
|
24457
|
-
|
|
24458
|
-
|
|
24459
|
-
|
|
24460
|
-
// Determine optimal placement based on available space and preferred position
|
|
24461
|
-
var placements = [{
|
|
24462
|
-
placement: 'top',
|
|
24463
|
-
space: availableSpace.top,
|
|
24464
|
-
fits: availableSpace.top >= contentHeight + 16,
|
|
24465
|
-
x: align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - contentWidth : triggerRect.left + triggerRect.width / 2 - contentWidth / 2,
|
|
24466
|
-
y: triggerRect.top - contentHeight - 8
|
|
24467
|
-
}, {
|
|
24468
|
-
placement: 'bottom',
|
|
24469
|
-
space: availableSpace.bottom,
|
|
24470
|
-
fits: availableSpace.bottom >= contentHeight + 16,
|
|
24471
|
-
x: align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - contentWidth : triggerRect.left + triggerRect.width / 2 - contentWidth / 2,
|
|
24472
|
-
y: triggerRect.bottom + 8
|
|
24473
|
-
}, {
|
|
24474
|
-
placement: 'right',
|
|
24475
|
-
space: availableSpace.right,
|
|
24476
|
-
fits: availableSpace.right >= contentWidth + 16,
|
|
24477
|
-
x: triggerRect.right + 8,
|
|
24478
|
-
y: align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - contentHeight : triggerRect.top + triggerRect.height / 2 - contentHeight / 2
|
|
24479
|
-
}, {
|
|
24480
|
-
placement: 'left',
|
|
24481
|
-
space: availableSpace.left,
|
|
24482
|
-
fits: availableSpace.left >= contentWidth + 16,
|
|
24483
|
-
x: triggerRect.left - contentWidth - 8,
|
|
24484
|
-
y: align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - contentHeight : triggerRect.top + triggerRect.height / 2 - contentHeight / 2
|
|
24485
|
-
}];
|
|
24486
|
-
// First try the preferred position if it fits
|
|
24487
|
-
var preferredPlacement = placements.find(p => p.placement === position && p.fits);
|
|
24488
|
-
if (preferredPlacement) {
|
|
24489
|
-
setOptimalPosition({
|
|
24490
|
-
x: preferredPlacement.x,
|
|
24491
|
-
y: preferredPlacement.y,
|
|
24492
|
-
placement: preferredPlacement.placement
|
|
24493
|
-
});
|
|
24494
|
-
return;
|
|
24495
|
-
}
|
|
24496
|
-
// Otherwise, find the best fitting placement
|
|
24497
|
-
var fittingPlacement = placements.find(p => p.fits);
|
|
24498
|
-
if (fittingPlacement) {
|
|
24499
|
-
setOptimalPosition({
|
|
24500
|
-
x: fittingPlacement.x,
|
|
24501
|
-
y: fittingPlacement.y,
|
|
24502
|
-
placement: fittingPlacement.placement
|
|
24503
|
-
});
|
|
24504
|
-
return;
|
|
24505
|
-
}
|
|
24506
|
-
// If nothing fits, choose the placement with the most space
|
|
24507
|
-
var bestPlacement = placements.reduce((best, current) => current.space > best.space ? current : best);
|
|
24508
|
-
// Ensure the content stays within viewport bounds
|
|
24509
|
-
var finalX = bestPlacement.x;
|
|
24510
|
-
var finalY = bestPlacement.y;
|
|
24511
|
-
if (finalX + contentWidth > viewportWidth) {
|
|
24512
|
-
finalX = viewportWidth - contentWidth - 8;
|
|
24513
|
-
}
|
|
24514
|
-
if (finalX < 8) {
|
|
24515
|
-
finalX = 8;
|
|
24516
|
-
}
|
|
24517
|
-
if (finalY + contentHeight > viewportHeight) {
|
|
24518
|
-
finalY = viewportHeight - contentHeight - 8;
|
|
24511
|
+
var placement = position;
|
|
24512
|
+
// Use relation data to determine optimal placement
|
|
24513
|
+
if (relation) {
|
|
24514
|
+
// If preferred position doesn't have enough space, use the position with more space
|
|
24515
|
+
if (position === 'top' && relation.space.vertical === 'bottom') {
|
|
24516
|
+
placement = 'bottom';
|
|
24517
|
+
} else if (position === 'bottom' && relation.space.vertical === 'top') {
|
|
24518
|
+
placement = 'top';
|
|
24519
|
+
} else if (position === 'right' && relation.space.horizontal === 'left') {
|
|
24520
|
+
placement = 'left';
|
|
24521
|
+
} else if (position === 'left' && relation.space.horizontal === 'right') {
|
|
24522
|
+
placement = 'right';
|
|
24523
|
+
}
|
|
24519
24524
|
}
|
|
24520
|
-
|
|
24521
|
-
|
|
24525
|
+
// Calculate position based on optimal placement and alignment
|
|
24526
|
+
var x = 0;
|
|
24527
|
+
var y = 0;
|
|
24528
|
+
switch (placement) {
|
|
24529
|
+
case 'top':
|
|
24530
|
+
x = align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - 120 // Estimated content width
|
|
24531
|
+
: triggerRect.left + triggerRect.width / 2 - 60; // Half of estimated width
|
|
24532
|
+
y = triggerRect.top - 8;
|
|
24533
|
+
break;
|
|
24534
|
+
case 'bottom':
|
|
24535
|
+
x = align === 'start' ? triggerRect.left : align === 'end' ? triggerRect.right - 120 : triggerRect.left + triggerRect.width / 2 - 60;
|
|
24536
|
+
y = triggerRect.bottom + 8;
|
|
24537
|
+
break;
|
|
24538
|
+
case 'right':
|
|
24539
|
+
x = triggerRect.right + 8;
|
|
24540
|
+
y = align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - 32 // Estimated content height
|
|
24541
|
+
: triggerRect.top + triggerRect.height / 2 - 16; // Half of estimated height
|
|
24542
|
+
break;
|
|
24543
|
+
case 'left':
|
|
24544
|
+
x = triggerRect.left - 8;
|
|
24545
|
+
y = align === 'start' ? triggerRect.top : align === 'end' ? triggerRect.bottom - 32 : triggerRect.top + triggerRect.height / 2 - 16;
|
|
24546
|
+
break;
|
|
24522
24547
|
}
|
|
24523
24548
|
setOptimalPosition({
|
|
24524
|
-
x
|
|
24525
|
-
y
|
|
24526
|
-
placement
|
|
24549
|
+
x,
|
|
24550
|
+
y,
|
|
24551
|
+
placement
|
|
24527
24552
|
});
|
|
24528
24553
|
}
|
|
24529
|
-
}, [isOpen, position, align, triggerRef, contentRef]);
|
|
24554
|
+
}, [isOpen, position, align, triggerRef, contentRef, relation]);
|
|
24530
24555
|
// Get arrow styles based on optimal placement
|
|
24531
24556
|
var arrowStyles = showArrow ? getArrowStyles(optimalPosition.placement) : {};
|
|
24532
|
-
// Create intelligent positioning styles
|
|
24533
|
-
var
|
|
24534
|
-
|
|
24535
|
-
|
|
24536
|
-
|
|
24537
|
-
|
|
24557
|
+
// Create intelligent positioning styles with transform for better placement
|
|
24558
|
+
var getPositionStyles = () => {
|
|
24559
|
+
var baseStyles = {
|
|
24560
|
+
position: 'fixed',
|
|
24561
|
+
left: optimalPosition.x,
|
|
24562
|
+
top: optimalPosition.y,
|
|
24563
|
+
zIndex: 1000
|
|
24564
|
+
};
|
|
24565
|
+
// Add transform based on placement for better positioning
|
|
24566
|
+
switch (optimalPosition.placement) {
|
|
24567
|
+
case 'top':
|
|
24568
|
+
return Object.assign({}, baseStyles, {
|
|
24569
|
+
transform: 'translateY(-100%)'
|
|
24570
|
+
});
|
|
24571
|
+
case 'left':
|
|
24572
|
+
return Object.assign({}, baseStyles, {
|
|
24573
|
+
transform: 'translateX(-100%)'
|
|
24574
|
+
});
|
|
24575
|
+
case 'bottom':
|
|
24576
|
+
case 'right':
|
|
24577
|
+
default:
|
|
24578
|
+
return baseStyles;
|
|
24579
|
+
}
|
|
24538
24580
|
};
|
|
24581
|
+
var positionStyles = getPositionStyles();
|
|
24539
24582
|
return /*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({
|
|
24540
24583
|
position: "relative",
|
|
24541
24584
|
display: "inline-block"
|
|
@@ -24547,7 +24590,13 @@
|
|
|
24547
24590
|
borderRadius: 4,
|
|
24548
24591
|
boxShadow: "0px 2px 8px rgba(0, 0, 0, 0.15)",
|
|
24549
24592
|
style: positionStyles
|
|
24550
|
-
}, TooltipSizes[size], TooltipVariants[variant], views == null ? void 0 : views.content), typeof content === 'string' ? (/*#__PURE__*/React__default.createElement(appStudio.Text, Object.assign({}, views == null ? void 0 : views.text), content)) : content, showArrow && /*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({}, arrowStyles, views == null ? void 0 : views.arrow))
|
|
24593
|
+
}, TooltipSizes[size], TooltipVariants[variant], views == null ? void 0 : views.content), typeof content === 'string' ? (/*#__PURE__*/React__default.createElement(appStudio.Text, Object.assign({}, views == null ? void 0 : views.text), content)) : content, showArrow && /*#__PURE__*/React__default.createElement(appStudio.View, Object.assign({}, arrowStyles, views == null ? void 0 : views.arrow)), (/*#__PURE__*/React__default.createElement("div", {
|
|
24594
|
+
style: {
|
|
24595
|
+
fontSize: '8px',
|
|
24596
|
+
opacity: 0.7,
|
|
24597
|
+
marginTop: '2px'
|
|
24598
|
+
}
|
|
24599
|
+
}, "Placement: ", optimalPosition.placement, relation && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "Space: ", relation.space.vertical, "-", relation.space.horizontal)))))));
|
|
24551
24600
|
};
|
|
24552
24601
|
|
|
24553
24602
|
var _excluded$1b = ["content", "children", "position", "align", "size", "variant", "openDelay", "closeDelay", "showArrow", "defaultOpen", "isDisabled", "views"];
|