fix timeline zoom + selection box issues

This commit is contained in:
Maze Winther
2026-01-24 06:42:39 +01:00
parent 7de8e4172f
commit 33f453efc7
4 changed files with 10 additions and 11 deletions
-1
View File
@@ -281,7 +281,6 @@ use-timeline-snapping.ts
use-timeline-zoom.ts
export function useTimelineZoom({
containerRef,
isInTimeline = false,
minZoom = TIMELINE_CONSTANTS.ZOOM_MIN,
}: UseTimelineZoomProps): UseTimelineZoomReturn
@@ -71,7 +71,6 @@ export function Timeline() {
const bookmarksScrollRef = useRef<HTMLDivElement>(null);
// state
const [isInTimeline, setIsInTimeline] = useState(false);
const [isResizing, setIsResizing] = useState(false);
const [currentSnapPoint, setCurrentSnapPoint] = useState<SnapPoint | null>(
null,
@@ -98,7 +97,6 @@ export function Timeline() {
const { zoomLevel, setZoomLevel, handleWheel } = useTimelineZoom({
containerRef: timelineRef,
isInTimeline,
minZoom: minZoomLevel,
});
@@ -187,8 +185,6 @@ export function Timeline() {
}
{...dragProps}
aria-label="Timeline"
onMouseEnter={() => setIsInTimeline(true)}
onMouseLeave={() => setIsInTimeline(false)}
>
<TimelineToolbar
zoomLevel={zoomLevel}
@@ -400,6 +396,7 @@ export function Timeline() {
onResizeStateChange={handleResizeStateChange}
onElementMouseDown={handleElementMouseDown}
onElementClick={handleElementClick}
onTrackMouseDown={handleSelectionMouseDown}
/>
</div>
</ContextMenuTrigger>
@@ -30,6 +30,7 @@ interface TimelineTrackContentProps {
element: TimelineElementType;
track: TimelineTrack;
}) => void;
onTrackMouseDown?: (event: React.MouseEvent) => void;
}
export function TimelineTrackContent({
@@ -43,6 +44,7 @@ export function TimelineTrackContent({
onResizeStateChange,
onElementMouseDown,
onElementClick,
onTrackMouseDown,
}: TimelineTrackContentProps) {
const editor = useEditor();
const { isElementSelected, clearElementSelection } = useElementSelection();
@@ -65,6 +67,9 @@ export function TimelineTrackContent({
<button
className={cn("size-full", hasSelectedElements && "bg-panel-accent/35")}
onClick={clearElementSelection}
onMouseDown={(event) => {
onTrackMouseDown?.(event);
}}
type="button"
>
<div className="relative h-full min-w-full">
@@ -9,7 +9,6 @@ import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants";
interface UseTimelineZoomProps {
containerRef: RefObject<HTMLDivElement>;
isInTimeline?: boolean;
minZoom?: number;
}
@@ -21,7 +20,6 @@ interface UseTimelineZoomReturn {
export function useTimelineZoom({
containerRef,
isInTimeline = false,
minZoom = TIMELINE_CONSTANTS.ZOOM_MIN,
}: UseTimelineZoomProps): UseTimelineZoomReturn {
const [zoomLevel, setZoomLevel] = useState(1);
@@ -65,9 +63,9 @@ export function useTimelineZoom({
const isInContainer = containerRef.current?.contains(
event.target as Node,
);
const shouldPrevent =
isInTimeline && isZoomKeyPressed && Boolean(isInContainer);
if (shouldPrevent) {
// only check isInContainer, not isInTimeline state - the state check
// causes race conditions where the closure captures stale state
if (isZoomKeyPressed && isInContainer) {
event.preventDefault();
}
};
@@ -80,7 +78,7 @@ export function useTimelineZoom({
return () => {
document.removeEventListener("wheel", preventZoom, { capture: true });
};
}, [isInTimeline, containerRef]);
}, [containerRef]);
return {
zoomLevel,