Skip to content

Commit c69d127

Browse files
committed
fix: calculate info box width based on char count
1 parent 37c44a1 commit c69d127

File tree

1 file changed

+76
-16
lines changed

1 file changed

+76
-16
lines changed

src/LiveDevelopment/BrowserScripts/RemoteFunctions.js

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -323,20 +323,65 @@ function RemoteFunctions(config) {
323323
delete element._originalDragOpacity;
324324
}
325325

326-
function checkOverlap(elemWidth, id, classes) {
327-
if(elemWidth > 280) {
328-
return false;
329-
}
330-
if(classes.length >= 3 && elemWidth <= 280) {
331-
return true;
326+
/**
327+
* This function is to calculate the width of the info box based on the number of chars in the box
328+
* @param {String} tagName - the element's tag name
329+
* @param {String} id - the element's id
330+
* @param {Array} classes - the array of class names
331+
* @returns {Number} - the total char count
332+
*/
333+
function _calculateInfoBoxCharCount(tagName, id, classes) {
334+
// char count for tag name
335+
let charCount = tagName.length;
336+
337+
// char count for id
338+
if (id) {
339+
charCount += id.length + 1; // +1 for #
332340
}
333-
if((id || classes.length <= 2) && elemWidth <= 250) {
334-
return true;
341+
342+
// char count for classes
343+
if (classes.length > 0) {
344+
for (let i = 0; i < Math.min(classes.length, 3); i++) {
345+
charCount += classes[i].length + 1; // +1 for .
346+
}
347+
348+
if (classes.length > 3) {
349+
// "+ X more" for more than 3 classes
350+
const moreText = `+${classes.length - 3} more`;
351+
charCount += moreText.length;
352+
}
335353
}
336-
if(elemWidth <= 180) {
337-
return true;
354+
return charCount;
355+
}
356+
357+
/**
358+
* This function checks whether there is overlap between the info and the more options box
359+
* @param {Number} elemWidth - the width of the DOM element
360+
* @param {String} tagName - the element's tag name
361+
* @param {String} id - the element's id
362+
* @param {Array} classes - the array of class names
363+
* @returns {Number} - the total char count
364+
*/
365+
function checkOverlap(elemWidth, tagName, id, classes) {
366+
const avgCharWidth = 7;
367+
const basePadding = 16;
368+
369+
// char count for tag name, id, and classes
370+
let charCount = _calculateInfoBoxCharCount(tagName, id, classes);
371+
372+
// calc estimate width based on the char count
373+
const infoBoxWidth = basePadding + (charCount * avgCharWidth);
374+
375+
// more options box is 82px
376+
const moreOptionsBoxWidth = 82;
377+
378+
// check if there's enough space for both boxes
379+
// 20px buffer for spacing between boxes
380+
if (elemWidth > (infoBoxWidth + moreOptionsBoxWidth + 20)) {
381+
return false; // No overlap
338382
}
339-
return false;
383+
384+
return true;
340385
}
341386

342387
/**
@@ -401,8 +446,9 @@ function RemoteFunctions(config) {
401446
// because when we have classes and ids then the info box tends to stretch in width
402447
const id = this.element.id;
403448
const classes = this.element.className ? this.element.className.split(/\s+/).filter(Boolean) : [];
449+
const tagName = this.element.tagName.toLowerCase();
404450

405-
const isOverlap = checkOverlap(elemBounds.width, id, classes);
451+
const isOverlap = checkOverlap(elemBounds.width, tagName, id, classes);
406452

407453
// default position (right aligned with element)
408454
let leftPos = elemBounds.right - boxWidth + scrollLeft;
@@ -591,13 +637,25 @@ function RemoteFunctions(config) {
591637
? elemBounds.top + elemBounds.height + 5
592638
: elemBounds.top - pushBoxUp) + scrollTop;
593639

640+
const avgCharWidth = 7;
641+
const basePadding = 16;
642+
643+
// Get the tag name
644+
const tagName = this.element.tagName.toLowerCase();
645+
646+
// Count characters in tag name, id, and classes
647+
let charCount = _calculateInfoBoxCharCount(tagName, id, classes);
648+
649+
// Calculate estimated width based on character count
650+
// Formula: base padding + (character count * average character width)
651+
const boxWidth = basePadding + (charCount * avgCharWidth);
652+
594653
// we need to check for overlap if this is from a click
595654
if (this.isFromClick) {
596-
const isOverlap = checkOverlap(elemBounds.width, id, classes);
655+
const isOverlap = checkOverlap(elemBounds.width, tagName, id, classes);
597656

598657
if (isOverlap) {
599658
const windowWidth = window.innerWidth;
600-
const boxWidth = 300; // max-width of the box
601659

602660
// Estimate the height of the info box based on its content
603661
// base height for tag name + padding
@@ -616,10 +674,12 @@ function RemoteFunctions(config) {
616674
// align with the bottom of the info box
617675
topPos = (elemBounds.top + elemBounds.height - estimatedHeight) + scrollTop;
618676

619-
// decide whether position at left or right
677+
// decide whether position at left or right based on available space
678+
// check if there's enough space on the left side
620679
if (elemBounds.left > boxWidth + 10) {
621680
leftPos = elemBounds.left - boxWidth - 10 + scrollLeft;
622681
} else if (windowWidth - elemBounds.right > boxWidth + 10) {
682+
// position on the right
623683
leftPos = elemBounds.right + 10 + scrollLeft;
624684
}
625685
}
@@ -638,7 +698,7 @@ function RemoteFunctions(config) {
638698
position: absolute;
639699
left: ${leftPos}px;
640700
top: ${topPos}px;
641-
max-width: 300px;
701+
max-width: ${boxWidth}px;
642702
box-sizing: border-box;
643703
pointer-events: none;
644704
}

0 commit comments

Comments
 (0)