1- import React , { useEffect , useRef , useState } from "react"
1+ import React , { useCallback , useEffect , useRef , useState } from "react"
22import { applyToPoint , identity , inverse } from "transformation-matrix"
33import type { Matrix } from "transformation-matrix"
44
@@ -17,13 +17,27 @@ export const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {
1717 const [ dEnd , setDEnd ] = useState ( { x : 0 , y : 0 } )
1818 const mousePosRef = useRef ( { x : 0 , y : 0 } )
1919 const containerRef = useRef < HTMLDivElement | null > ( null )
20+ const isMouseOverRef = useRef ( false )
2021 const container = containerRef . current !
2122 const containerBounds = container ?. getBoundingClientRect ( )
2223
23- const bindKeys = ( ) => {
24- const container = containerRef . current
24+ const handleMouseEnter = useCallback ( ( ) => {
25+ isMouseOverRef . current = true
26+ containerRef . current ?. focus ( )
27+ } , [ ] )
2528
29+ const handleMouseLeave = useCallback ( ( ) => {
30+ isMouseOverRef . current = false
31+ } , [ ] )
32+
33+ useEffect ( ( ) => {
2634 const down = ( e : KeyboardEvent ) => {
35+ const containerHasFocus =
36+ containerRef . current ?. contains ( document . activeElement ) ||
37+ document . activeElement === containerRef . current
38+
39+ if ( ! isMouseOverRef . current && ! containerHasFocus ) return
40+
2741 if ( e . key === "d" ) {
2842 setDStart ( { x : mousePosRef . current . x , y : mousePosRef . current . y } )
2943 setDEnd ( { x : mousePosRef . current . x , y : mousePosRef . current . y } )
@@ -36,41 +50,11 @@ export const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {
3650 }
3751 }
3852
39- const addKeyListener = ( ) => {
40- if ( container ) {
41- window . addEventListener ( "keydown" , down )
42- }
43- }
44-
45- const removeKeyListener = ( ) => {
46- if ( container ) {
47- window . removeEventListener ( "keydown" , down )
48- }
49- }
50-
51- if ( container ) {
52- container . addEventListener ( "focus" , addKeyListener )
53- container . addEventListener ( "blur" , removeKeyListener )
54- container . addEventListener ( "mouseenter" , addKeyListener )
55- container . addEventListener ( "mouseleave" , removeKeyListener )
56-
57- // Ensure the key listener is active immediately so the "d" hotkey
58- // works without requiring a mouse enter/leave cycle
59- addKeyListener ( )
60- }
53+ window . addEventListener ( "keydown" , down )
6154 return ( ) => {
62- // Always remove the key listener on cleanup to avoid leaks
63- removeKeyListener ( )
64- if ( container ) {
65- container . removeEventListener ( "focus" , addKeyListener )
66- container . removeEventListener ( "blur" , removeKeyListener )
67- container . removeEventListener ( "mouseenter" , addKeyListener )
68- container . removeEventListener ( "mouseleave" , removeKeyListener )
69- }
55+ window . removeEventListener ( "keydown" , down )
7056 }
71- }
72-
73- useEffect ( bindKeys , [ containerBounds ?. width , containerBounds ?. height ] )
57+ } , [ ] )
7458
7559 const screenDStart = applyToPoint ( transform , dStart )
7660 const screenDEnd = applyToPoint ( transform , dEnd )
@@ -112,11 +96,8 @@ export const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {
11296 setDimensionToolVisible ( false )
11397 }
11498 } }
115- onMouseEnter = { ( ) => {
116- if ( containerRef . current ) {
117- bindKeys ( )
118- }
119- } }
99+ onMouseEnter = { handleMouseEnter }
100+ onMouseLeave = { handleMouseLeave }
120101 >
121102 { children }
122103 { dimensionToolVisible && (
0 commit comments