diff --git a/packages/studio/src/hooks/useDomSelection.ts b/packages/studio/src/hooks/useDomSelection.ts index 654d88848..f124d3753 100644 --- a/packages/studio/src/hooks/useDomSelection.ts +++ b/packages/studio/src/hooks/useDomSelection.ts @@ -127,6 +127,9 @@ export function useDomSelection({ const domEditHoverSelectionRef = useRef(domEditHoverSelection); const activeGroupElementRef = useRef(activeGroupElement); const compositionIdentityRef = useRef({ activeCompPath, projectId }); + // Monotonic token so a rapid A->B timeline-clip select can't let A's slower async + // resolution land after B and restore the wrong selection. + const timelineSelectSeqRef = useRef(0); // Keep refs in sync with state domEditSelectionRef.current = domEditSelection; @@ -372,12 +375,15 @@ export function useDomSelection({ const handleTimelineElementSelect = useCallback( async (element: TimelineElement | null) => { if (!STUDIO_INSPECTOR_PANELS_ENABLED) return; + const seq = ++timelineSelectSeqRef.current; if (!element) { applyDomSelection(null, { revealPanel: false }); return; } const selection = await buildDomSelectionForTimelineElement(element); + // A newer selection superseded this one while we were resolving — drop the stale result. + if (seq !== timelineSelectSeqRef.current) return; if (selection) applyDomSelection(selection); }, [applyDomSelection, buildDomSelectionForTimelineElement],