@eric-emg/symphiq-components 1.2.58 → 1.2.59
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/fesm2022/symphiq-components.mjs +79 -42
- package/fesm2022/symphiq-components.mjs.map +1 -1
- package/index.d.ts +2 -2
- package/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -193,35 +193,48 @@ class TooltipService {
|
|
|
193
193
|
// Insight tooltips can be quite tall, so need more space
|
|
194
194
|
const HORIZONTAL_THRESHOLD = 200;
|
|
195
195
|
const VERTICAL_THRESHOLD = type === 'insight' ? 350 : 200;
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
// Calculate effective boundaries
|
|
197
|
+
let leftBound = 0;
|
|
198
|
+
let rightBound = window.innerWidth;
|
|
199
|
+
let topBound = 0;
|
|
200
|
+
let bottomBound = window.innerHeight;
|
|
201
|
+
// If there's a scroll container, adjust boundaries relative to it
|
|
202
|
+
if (this.scrollContainer) {
|
|
203
|
+
const containerRect = this.scrollContainer.getBoundingClientRect();
|
|
204
|
+
leftBound = containerRect.left;
|
|
205
|
+
rightBound = containerRect.right;
|
|
206
|
+
topBound = containerRect.top;
|
|
207
|
+
bottomBound = containerRect.bottom;
|
|
208
|
+
}
|
|
209
|
+
// Calculate space available around target element
|
|
210
|
+
const spaceLeft = targetRect.left - leftBound;
|
|
211
|
+
const spaceRight = rightBound - targetRect.right;
|
|
212
|
+
const spaceTop = targetRect.top - topBound;
|
|
213
|
+
const spaceBelow = bottomBound - targetRect.bottom;
|
|
199
214
|
// Check left edge
|
|
200
|
-
if (position === 'left' &&
|
|
215
|
+
if (position === 'left' && spaceLeft < HORIZONTAL_THRESHOLD) {
|
|
201
216
|
adjustedPosition = 'right';
|
|
202
217
|
}
|
|
203
218
|
// Check right edge
|
|
204
|
-
if (position === 'right' &&
|
|
219
|
+
if (position === 'right' && spaceRight < HORIZONTAL_THRESHOLD) {
|
|
205
220
|
adjustedPosition = 'left';
|
|
206
221
|
}
|
|
207
222
|
// Check top edge
|
|
208
|
-
if (position === 'top' &&
|
|
223
|
+
if (position === 'top' && spaceTop < VERTICAL_THRESHOLD) {
|
|
209
224
|
adjustedPosition = 'bottom';
|
|
210
225
|
}
|
|
211
226
|
// Check bottom edge - prioritize flipping to top if not enough space
|
|
212
|
-
if (position === 'bottom' &&
|
|
227
|
+
if (position === 'bottom' && spaceBelow < VERTICAL_THRESHOLD) {
|
|
213
228
|
adjustedPosition = 'top';
|
|
214
229
|
}
|
|
215
230
|
// Smart auto-detection for 'top' position tooltips near bottom
|
|
216
231
|
if (position === 'top') {
|
|
217
|
-
const spaceBelow = viewportHeight - targetRect.bottom;
|
|
218
|
-
const spaceAbove = targetRect.top;
|
|
219
232
|
// If more space above and not enough space below, keep it on top
|
|
220
233
|
// If more space below, switch to bottom
|
|
221
|
-
if (spaceBelow >
|
|
234
|
+
if (spaceBelow > spaceTop && spaceBelow > VERTICAL_THRESHOLD) {
|
|
222
235
|
adjustedPosition = 'bottom';
|
|
223
236
|
}
|
|
224
|
-
else if (
|
|
237
|
+
else if (spaceTop < VERTICAL_THRESHOLD && spaceBelow > VERTICAL_THRESHOLD) {
|
|
225
238
|
adjustedPosition = 'bottom';
|
|
226
239
|
}
|
|
227
240
|
}
|
|
@@ -11144,17 +11157,25 @@ class TooltipContainerComponent {
|
|
|
11144
11157
|
const mousePos = this.mousePosition();
|
|
11145
11158
|
const tooltipWidth = 384;
|
|
11146
11159
|
const container = this.scrollContainer();
|
|
11147
|
-
|
|
11160
|
+
// Calculate effective viewport boundaries
|
|
11161
|
+
let leftBound = 10;
|
|
11162
|
+
let rightBound = window.innerWidth - 10;
|
|
11163
|
+
// If there's a scroll container, constrain to its boundaries
|
|
11164
|
+
if (container) {
|
|
11165
|
+
const containerRect = container.getBoundingClientRect();
|
|
11166
|
+
leftBound = Math.max(10, containerRect.left + 10);
|
|
11167
|
+
rightBound = Math.min(window.innerWidth - 10, containerRect.right - 10);
|
|
11168
|
+
}
|
|
11148
11169
|
// Handle 'auto' positioning with mouse coordinates
|
|
11149
11170
|
if (position === 'auto' && mousePos) {
|
|
11150
11171
|
const halfWidth = tooltipWidth / 2;
|
|
11151
11172
|
let leftPos = mousePos.x;
|
|
11152
|
-
// Keep tooltip in
|
|
11153
|
-
if (leftPos - halfWidth <
|
|
11154
|
-
leftPos =
|
|
11173
|
+
// Keep tooltip in bounds
|
|
11174
|
+
if (leftPos - halfWidth < leftBound) {
|
|
11175
|
+
leftPos = leftBound + halfWidth;
|
|
11155
11176
|
}
|
|
11156
|
-
else if (leftPos + halfWidth >
|
|
11157
|
-
leftPos =
|
|
11177
|
+
else if (leftPos + halfWidth > rightBound) {
|
|
11178
|
+
leftPos = rightBound - halfWidth;
|
|
11158
11179
|
}
|
|
11159
11180
|
return leftPos;
|
|
11160
11181
|
}
|
|
@@ -11163,16 +11184,16 @@ class TooltipContainerComponent {
|
|
|
11163
11184
|
case 'bottom': {
|
|
11164
11185
|
const centerPosition = rect.left + rect.width / 2;
|
|
11165
11186
|
const halfWidth = tooltipWidth / 2;
|
|
11166
|
-
// Check if centered tooltip would go off
|
|
11167
|
-
const wouldGoOffLeft = centerPosition - halfWidth <
|
|
11168
|
-
const wouldGoOffRight = centerPosition + halfWidth >
|
|
11187
|
+
// Check if centered tooltip would go off bounds
|
|
11188
|
+
const wouldGoOffLeft = centerPosition - halfWidth < leftBound;
|
|
11189
|
+
const wouldGoOffRight = centerPosition + halfWidth > rightBound;
|
|
11169
11190
|
if (wouldGoOffLeft) {
|
|
11170
|
-
// Align to left
|
|
11171
|
-
return
|
|
11191
|
+
// Align to left bound
|
|
11192
|
+
return leftBound;
|
|
11172
11193
|
}
|
|
11173
11194
|
else if (wouldGoOffRight) {
|
|
11174
|
-
// Align to right
|
|
11175
|
-
return
|
|
11195
|
+
// Align to right bound
|
|
11196
|
+
return rightBound - tooltipWidth;
|
|
11176
11197
|
}
|
|
11177
11198
|
else {
|
|
11178
11199
|
// Center normally (transform will be applied)
|
|
@@ -11181,17 +11202,25 @@ class TooltipContainerComponent {
|
|
|
11181
11202
|
}
|
|
11182
11203
|
case 'left': {
|
|
11183
11204
|
const leftPosition = rect.left - tooltipWidth - 8;
|
|
11184
|
-
// If tooltip would go off left
|
|
11185
|
-
if (leftPosition <
|
|
11186
|
-
|
|
11205
|
+
// If tooltip would go off left bound, position it to the right instead
|
|
11206
|
+
if (leftPosition < leftBound) {
|
|
11207
|
+
const rightPosition = rect.right + 8;
|
|
11208
|
+
if (rightPosition + tooltipWidth > rightBound) {
|
|
11209
|
+
return leftBound;
|
|
11210
|
+
}
|
|
11211
|
+
return rightPosition;
|
|
11187
11212
|
}
|
|
11188
11213
|
return leftPosition;
|
|
11189
11214
|
}
|
|
11190
11215
|
case 'right': {
|
|
11191
11216
|
const rightPosition = rect.right + 8;
|
|
11192
|
-
// If tooltip would go off right
|
|
11193
|
-
if (rightPosition + tooltipWidth >
|
|
11194
|
-
|
|
11217
|
+
// If tooltip would go off right bound, position it to the left instead
|
|
11218
|
+
if (rightPosition + tooltipWidth > rightBound) {
|
|
11219
|
+
const leftPosition = rect.left - tooltipWidth - 8;
|
|
11220
|
+
if (leftPosition < leftBound) {
|
|
11221
|
+
return leftBound;
|
|
11222
|
+
}
|
|
11223
|
+
return leftPosition;
|
|
11195
11224
|
}
|
|
11196
11225
|
return rightPosition;
|
|
11197
11226
|
}
|
|
@@ -11207,7 +11236,15 @@ class TooltipContainerComponent {
|
|
|
11207
11236
|
const mousePos = this.mousePosition();
|
|
11208
11237
|
const type = this.tooltipType();
|
|
11209
11238
|
const container = this.scrollContainer();
|
|
11210
|
-
|
|
11239
|
+
// Calculate effective viewport boundaries
|
|
11240
|
+
let topBound = 10;
|
|
11241
|
+
let bottomBound = window.innerHeight - 10;
|
|
11242
|
+
// If there's a scroll container, constrain to its boundaries
|
|
11243
|
+
if (container) {
|
|
11244
|
+
const containerRect = container.getBoundingClientRect();
|
|
11245
|
+
topBound = Math.max(10, containerRect.top + 10);
|
|
11246
|
+
bottomBound = Math.min(window.innerHeight - 10, containerRect.bottom - 10);
|
|
11247
|
+
}
|
|
11211
11248
|
// Estimate tooltip height based on type
|
|
11212
11249
|
let estimatedHeight = 100;
|
|
11213
11250
|
if (type === 'insight') {
|
|
@@ -11220,29 +11257,29 @@ class TooltipContainerComponent {
|
|
|
11220
11257
|
if (position === 'auto' && mousePos) {
|
|
11221
11258
|
const offset = 20; // Offset from mouse cursor
|
|
11222
11259
|
let topPos = mousePos.y + offset;
|
|
11223
|
-
// If tooltip would go off bottom
|
|
11224
|
-
if (topPos + estimatedHeight >
|
|
11260
|
+
// If tooltip would go off bottom, position above cursor
|
|
11261
|
+
if (topPos + estimatedHeight > bottomBound) {
|
|
11225
11262
|
topPos = mousePos.y - estimatedHeight - offset;
|
|
11226
11263
|
}
|
|
11227
11264
|
// Ensure it doesn't go off top
|
|
11228
|
-
if (topPos <
|
|
11229
|
-
topPos =
|
|
11265
|
+
if (topPos < topBound) {
|
|
11266
|
+
topPos = topBound;
|
|
11230
11267
|
}
|
|
11231
11268
|
return topPos;
|
|
11232
11269
|
}
|
|
11233
11270
|
switch (position) {
|
|
11234
11271
|
case 'top': {
|
|
11235
11272
|
const topPosition = rect.top - estimatedHeight - 8;
|
|
11236
|
-
// If tooltip would go off top
|
|
11237
|
-
if (topPosition <
|
|
11273
|
+
// If tooltip would go off top bound, position it below instead
|
|
11274
|
+
if (topPosition < topBound) {
|
|
11238
11275
|
return rect.bottom + 8;
|
|
11239
11276
|
}
|
|
11240
11277
|
return topPosition;
|
|
11241
11278
|
}
|
|
11242
11279
|
case 'bottom': {
|
|
11243
11280
|
const bottomPosition = rect.bottom + 8;
|
|
11244
|
-
// If tooltip would go off bottom
|
|
11245
|
-
if (bottomPosition + estimatedHeight >
|
|
11281
|
+
// If tooltip would go off bottom bound, position it above instead
|
|
11282
|
+
if (bottomPosition + estimatedHeight > bottomBound) {
|
|
11246
11283
|
return rect.top - estimatedHeight - 8;
|
|
11247
11284
|
}
|
|
11248
11285
|
return bottomPosition;
|
|
@@ -11250,9 +11287,9 @@ class TooltipContainerComponent {
|
|
|
11250
11287
|
case 'left':
|
|
11251
11288
|
case 'right': {
|
|
11252
11289
|
const centerPosition = rect.top + rect.height / 2 - estimatedHeight / 2;
|
|
11253
|
-
// Keep within
|
|
11254
|
-
const maxTop =
|
|
11255
|
-
return Math.max(
|
|
11290
|
+
// Keep within bounds
|
|
11291
|
+
const maxTop = bottomBound - estimatedHeight;
|
|
11292
|
+
return Math.max(topBound, Math.min(centerPosition, maxTop));
|
|
11256
11293
|
}
|
|
11257
11294
|
default:
|
|
11258
11295
|
return rect.top - estimatedHeight - 8;
|