@@ -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