From 56ca09692a308b22455420d11376ff8d41244c47 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 26 Apr 2026 17:31:28 +0200 Subject: refactor: thinner hooks --- apps/web/src/timeline/drag-source.ts | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 apps/web/src/timeline/drag-source.ts (limited to 'apps/web/src/timeline/drag-source.ts') diff --git a/apps/web/src/timeline/drag-source.ts b/apps/web/src/timeline/drag-source.ts new file mode 100644 index 00000000..503c547b --- /dev/null +++ b/apps/web/src/timeline/drag-source.ts @@ -0,0 +1,40 @@ +import type { TimelineDragData } from "@/timeline/drag"; + +const TIMELINE_DRAG_MIME = "application/x-timeline-drag"; + +/** + * Owns the state of an in-progress timeline drag session. + * + * Exists because browsers restrict `DataTransfer.getData()` to the `drop` + * event for security — during `dragover`/`dragenter` only `types` is + * readable. The drop target needs the payload (element type, target + * element types, source duration) while the pointer is hovering, so we + * keep a live copy here and hand it out via {@link getActive}. + */ +export class TimelineDragSource { + private active: TimelineDragData | null = null; + + begin({ + dataTransfer, + dragData, + }: { + dataTransfer: DataTransfer; + dragData: TimelineDragData; + }): void { + dataTransfer.setData(TIMELINE_DRAG_MIME, JSON.stringify(dragData)); + dataTransfer.effectAllowed = "copy"; + this.active = dragData; + } + + end(): void { + this.active = null; + } + + getActive(): TimelineDragData | null { + return this.active; + } + + isActive(): boolean { + return this.active !== null; + } +} -- cgit v1.3.1