diff --git a/packages/studio/src/components/editor/DomEditOverlay.tsx b/packages/studio/src/components/editor/DomEditOverlay.tsx index ec289fc78..247aaacb1 100644 --- a/packages/studio/src/components/editor/DomEditOverlay.tsx +++ b/packages/studio/src/components/editor/DomEditOverlay.tsx @@ -98,6 +98,7 @@ export const DomEditOverlay = memo(function DomEditOverlay({ const suppressNextOverlayMouseDownRef = useRef(false); const snapGuidesRef = useRef(null); const rafPausedRef = useRef(false); + const rafSelectionOnlyPausedRef = useRef(false); const selectionRef = useRef(selection); selectionRef.current = selection; @@ -142,6 +143,7 @@ export const DomEditOverlay = memo(function DomEditOverlay({ groupSelectionsRef, hoverSelectionRef, rafPausedRef, + rafSelectionOnlyPausedRef, }); const [compRect, setCompRect] = useState({ @@ -199,6 +201,7 @@ export const DomEditOverlay = memo(function DomEditOverlay({ groupGestureRef, blockedMoveRef, rafPausedRef, + rafSelectionOnlyPausedRef, suppressNextBoxClickRef, setOverlayRect, setGroupOverlayItems, diff --git a/packages/studio/src/components/editor/domEditOverlayStartGesture.ts b/packages/studio/src/components/editor/domEditOverlayStartGesture.ts index 8b3dc4775..e6336c2a4 100644 --- a/packages/studio/src/components/editor/domEditOverlayStartGesture.ts +++ b/packages/studio/src/components/editor/domEditOverlayStartGesture.ts @@ -154,7 +154,7 @@ export function startGesture( e.preventDefault(); e.stopPropagation(); e.currentTarget.setPointerCapture(e.pointerId); - opts.rafPausedRef.current = true; + opts.rafSelectionOnlyPausedRef.current = true; opts.gestureRef.current = { kind, mode, diff --git a/packages/studio/src/components/editor/useDomEditOverlayGestures.ts b/packages/studio/src/components/editor/useDomEditOverlayGestures.ts index a43a49653..f2d7ba38e 100644 --- a/packages/studio/src/components/editor/useDomEditOverlayGestures.ts +++ b/packages/studio/src/components/editor/useDomEditOverlayGestures.ts @@ -65,6 +65,7 @@ export type UseDomEditOverlayGesturesOptions = { groupGestureRef: RefObject; blockedMoveRef: RefObject; rafPausedRef: RefObject; + rafSelectionOnlyPausedRef: RefObject; suppressNextBoxClickRef: RefObject; setOverlayRect: (next: OverlayRect | null) => void; setGroupOverlayItems: (next: GroupOverlayItem[]) => void; @@ -391,11 +392,11 @@ export function createDomEditOverlayGestureHandlers(opts: UseDomEditOverlayGestu if (!g || !sel) { opts.gestureRef.current = null; - opts.rafPausedRef.current = false; + opts.rafSelectionOnlyPausedRef.current = false; return; } opts.gestureRef.current = null; - opts.rafPausedRef.current = false; + opts.rafSelectionOnlyPausedRef.current = false; const movedDistance = Math.hypot(e.clientX - g.startX, e.clientY - g.startY); if (g.kind === "drag" && movedDistance < BLOCKED_MOVE_THRESHOLD_PX) { @@ -522,6 +523,7 @@ export function createDomEditOverlayGestureHandlers(opts: UseDomEditOverlayGestu opts.groupGestureRef.current = null; opts.gestureRef.current = null; opts.rafPausedRef.current = false; + opts.rafSelectionOnlyPausedRef.current = false; }; return { startGesture, startGroupDrag, onPointerMove, onPointerUp, clearPointerState }; diff --git a/packages/studio/src/components/editor/useDomEditOverlayRects.ts b/packages/studio/src/components/editor/useDomEditOverlayRects.ts index 1bda0197d..80506fd05 100644 --- a/packages/studio/src/components/editor/useDomEditOverlayRects.ts +++ b/packages/studio/src/components/editor/useDomEditOverlayRects.ts @@ -25,6 +25,8 @@ interface UseDomEditOverlayRectsOptions { groupSelectionsRef: RefObject; hoverSelectionRef: RefObject; rafPausedRef: RefObject; + /** When true, the RAF loop skips only the main selection rect — hover and group rects keep updating. */ + rafSelectionOnlyPausedRef?: RefObject; } interface UseDomEditOverlayRectsResult { @@ -47,6 +49,7 @@ export function useDomEditOverlayRects({ groupSelectionsRef, hoverSelectionRef, rafPausedRef, + rafSelectionOnlyPausedRef, }: UseDomEditOverlayRectsOptions): UseDomEditOverlayRectsResult { const [overlayRect, setOverlayRectState] = useState(null); const [hoverRect, setHoverRectState] = useState(null); @@ -104,6 +107,7 @@ export function useDomEditOverlayRects({ frame = requestAnimationFrame(update); if (rafPausedRef.current) return; + const selectionOnlyPaused = rafSelectionOnlyPausedRef?.current ?? false; const sel = selectionRef.current; const iframe = iframeRef.current; const overlayEl = overlayRef.current; @@ -124,21 +128,23 @@ export function useDomEditOverlayRects({ return; } - if (sel) { - const el = resolveElementForOverlay( - doc, - sel, - activeCompositionPathRef.current, - resolvedElementRef as ResolvedElementRef, - ); - if (el && isElementVisibleForOverlay(el)) { - setOverlayRect(toOverlayRect(overlayEl, iframe, el)); + if (!selectionOnlyPaused) { + if (sel) { + const el = resolveElementForOverlay( + doc, + sel, + activeCompositionPathRef.current, + resolvedElementRef as ResolvedElementRef, + ); + if (el && isElementVisibleForOverlay(el)) { + setOverlayRect(toOverlayRect(overlayEl, iframe, el)); + } else { + setOverlayRect(null); + } } else { + resolvedElementRef.current = null; setOverlayRect(null); } - } else { - resolvedElementRef.current = null; - setOverlayRect(null); } const group = groupSelectionsRef.current;