@@ -15,6 +15,8 @@ document.addEventListener('alpine:init', () => {
1515 floatingButton : null ,
1616 mouseMoveHandler : null ,
1717 clickHandler : null ,
18+ hoverTimeout : null ,
19+ hoverDelay : 50 , // ms delay for accurate position calculation
1820 lastBadgeUpdate : 0 ,
1921 badgeUpdateDelay : 150 , // ms delay to prevent flickering
2022 panelData : {
@@ -94,7 +96,7 @@ document.addEventListener('alpine:init', () => {
9496 font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
9597 font-size: 11px;
9698 line-height: 1.6;
97- pointer-events: auto ;
99+ pointer-events: none ;
98100 z-index: 10000000;
99101 display: none;
100102 box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.05);
@@ -265,6 +267,13 @@ document.addEventListener('alpine:init', () => {
265267 */
266268 deactivatePicker ( ) {
267269 this . isPickerActive = false ;
270+
271+ // Clear any pending hover timeout
272+ if ( this . hoverTimeout ) {
273+ clearTimeout ( this . hoverTimeout ) ;
274+ this . hoverTimeout = null ;
275+ }
276+
268277 document . removeEventListener ( 'mousemove' , this . mouseMoveHandler ) ;
269278 document . removeEventListener ( 'click' , this . clickHandler , false ) ;
270279 document . body . style . cursor = '' ;
@@ -279,29 +288,37 @@ document.addEventListener('alpine:init', () => {
279288 handleMouseMove ( e ) {
280289 if ( ! this . isPickerActive ) return ;
281290
282- // Don't update if mouse is over the info badge or floating button
283- if ( ( this . infoBadge && this . infoBadge . contains ( e . target ) ) ||
284- ( this . floatingButton && this . floatingButton . contains ( e . target ) ) ) {
291+ // Don't update if mouse is over the floating button
292+ if ( this . floatingButton && this . floatingButton . contains ( e . target ) ) {
285293 return ;
286294 }
287295
288296 const element = this . findInspectableElement ( e . target ) ;
289297
298+ // Clear any existing hover timeout
299+ if ( this . hoverTimeout ) {
300+ clearTimeout ( this . hoverTimeout ) ;
301+ this . hoverTimeout = null ;
302+ }
303+
290304 if ( element && element !== this . hoveredElement ) {
291- // Throttle badge updates to prevent flickering
292- const now = Date . now ( ) ;
293- if ( now - this . lastBadgeUpdate < this . badgeUpdateDelay ) {
294- // Only update highlight, keep badge
305+ // Debounce hover updates for accurate positioning
306+ this . hoverTimeout = setTimeout ( ( ) => {
307+ // Throttle badge updates to prevent flickering
308+ const now = Date . now ( ) ;
309+ if ( now - this . lastBadgeUpdate < this . badgeUpdateDelay ) {
310+ // Only update highlight, keep badge
311+ this . hoveredElement = element ;
312+ this . showHighlight ( element ) ;
313+ return ;
314+ }
315+
295316 this . hoveredElement = element ;
317+ this . lastBadgeUpdate = now ;
296318 this . showHighlight ( element ) ;
297- return ;
298- }
299-
300- this . hoveredElement = element ;
301- this . lastBadgeUpdate = now ;
302- this . showHighlight ( element ) ;
303- this . updatePanelData ( element ) ;
304- this . showInfoBadge ( element ) ;
319+ this . updatePanelData ( element ) ;
320+ this . showInfoBadge ( element ) ;
321+ } , this . hoverDelay ) ;
305322 } else if ( ! element && this . hoveredElement ) {
306323 // Only hide highlight when leaving element, keep badge visible
307324 if ( this . highlightBox ) {
@@ -599,6 +616,7 @@ document.addEventListener('alpine:init', () => {
599616 width: 100%;
600617 box-sizing: border-box;
601618 font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
619+ pointer-events: auto;
602620 ` ;
603621 textSpan . textContent = text ;
604622 textSpan . title = 'Click to copy' ;
0 commit comments