{"version":3,"file":"useTimelineExternalClipDrop.mjs","names":[],"sources":["../../../src/hooks/clips/useTimelineExternalClipDrop.ts"],"sourcesContent":["import { timelineCommandFail, timelineCommandOk } from '@techsquidtv/canvas-timeline-core';\nimport type {\n  TimelineCommandFailureReason,\n  TimelineCommandResult,\n  TimelineClipGroupPlacement,\n  TimelineEditCommitResult,\n  TimelineEditRejectionReason,\n  TimelineInteractionGeometry,\n  Track,\n  TimelineReadonly,\n} from '@techsquidtv/canvas-timeline-core';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport { toSeconds } from '@techsquidtv/canvas-timeline-utils';\nimport type { RationalTime } from '@techsquidtv/canvas-timeline-utils';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport type { DragEvent, DragEventHandler } from 'react';\n/** External-drop edit operation selected by app chrome or drop context. */\nexport type TimelineExternalClipDropEditMode = 'insert' | 'overwrite';\n\n/** Metadata applied when an external drop creates a multi-clip group. */\nexport interface TimelineExternalClipDropGroupOptions {\n  /** Optional stable group id. A random id is generated by the engine when omitted. */\n  groupId?: string;\n  /** Optional visible group label for app chrome. */\n  label?: string;\n}\n\n/**\n * Context passed to external clip drop callbacks.\n *\n * @remarks\n *\n * The context combines app-owned drag data with the resolved timeline target.\n * Use it to build clip placements from a media bin, asset browser, file picker,\n * or generated content panel. Times are already converted from pointer position\n * into {@link RationalTime} so placement factories do not need to duplicate\n * timeline geometry math.\n *\n * @template DragData - App-owned payload resolved from the native drag event.\n * surface.\n */\nexport interface TimelineExternalClipDropContext<DragData> {\n  /** App-owned drag payload resolved from the native drag event. */\n  data: DragData;\n  /** Native React drag event for advanced app integrations. */\n  event: DragEvent<HTMLElement>;\n  /** Native browser data transfer payload. */\n  dataTransfer: DataTransfer;\n  /** Track currently under the pointer. */\n  targetTrack: TimelineReadonly<Track>;\n  /** Zero-based index of the target track. */\n  targetTrackIndex: number;\n  /** Timeline time under the pointer. */\n  dropTime: RationalTime;\n  /** Timeline seconds under the pointer. */\n  dropSeconds: number;\n  /** Horizontal pointer position inside the drop surface. */\n  viewportX: number;\n  /** Vertical pointer position inside the drop surface. */\n  viewportY: number;\n  /** Edit operation selected for this drop. */\n  editMode: TimelineExternalClipDropEditMode;\n}\n\n/** Result of an app-owned external drop guard. */\nexport interface TimelineExternalClipDropGuardResult {\n  /** Whether this payload can drop on the resolved target. */\n  canDrop: boolean;\n  /** Machine-readable failure reason when rejected. */\n  reason?: TimelineCommandFailureReason;\n  /** Optional human-readable failure detail. */\n  message?: string;\n}\n\n/**\n * Custom policy for accepting or rejecting an external drop target.\n *\n * @template DragData - App-owned payload resolved from the native drag event.\n */\nexport type TimelineExternalClipDropGuard<DragData> = (\n  context: TimelineExternalClipDropContext<DragData>\n) => boolean | TimelineExternalClipDropGuardResult;\n\n/**\n * Props spread onto the timeline element that receives native external drops.\n *\n * @remarks\n *\n * Spread these onto the same viewport element whose bounds should define\n * pointer-to-time and pointer-to-track hit testing. The hook handles native drag\n * events; applications provide payload parsing and placement creation.\n */\nexport interface TimelineExternalClipDropRootProps {\n  /** Registers a native drag entering the timeline drop surface. */\n  onDragEnter: DragEventHandler<HTMLElement>;\n  /** Updates target track, drop time, validity, and browser drop feedback. */\n  onDragOver: DragEventHandler<HTMLElement>;\n  /** Clears transient hover feedback when the drag leaves the drop surface. */\n  onDragLeave: DragEventHandler<HTMLElement>;\n  /** Commits the resolved insert or overwrite edit for the app-owned payload. */\n  onDrop: DragEventHandler<HTMLElement>;\n}\n\n/**\n * Options accepted by `useTimelineExternalClipDrop`.\n *\n * @remarks\n *\n * `resolveDragData` converts a browser drag event into app data. `createPlacements`\n * turns that data into one or more timeline clip placements. The hook resolves\n * target track, drop time, snapping, edit mode, grouped drops, and command\n * results around those app callbacks.\n *\n * @template DragData - App-owned payload resolved from the native drag event.\n *\n * @see {@link TimelineExternalClipDropContext}\n * @see {@link https://canvastimeline.com/demos/external-clip-drop | External clip drop demo}\n */\nexport interface UseTimelineExternalClipDropOptions<DragData> extends TimelineInteractionGeometry {\n  /** Optional viewport width used for track hit testing. Defaults to the drop surface width. */\n  viewportWidth?: number;\n  /** Edit mode for committed drops. Defaults to overwrite. */\n  editMode?:\n    | TimelineExternalClipDropEditMode\n    | ((\n        context: Omit<TimelineExternalClipDropContext<DragData>, 'editMode'>\n      ) => TimelineExternalClipDropEditMode);\n  /** Resolves app-owned drag data from the native drag event. */\n  resolveDragData: (event: DragEvent<HTMLElement>) => DragData | null;\n  /** Creates one or more clip placements from the resolved drop context. */\n  createPlacements: (\n    context: TimelineExternalClipDropContext<DragData>\n  ) => readonly TimelineClipGroupPlacement[] | null;\n  /** Optional app policy for rejecting target tracks before placement creation. */\n  canDropOnTrack?: TimelineExternalClipDropGuard<DragData>;\n  /** Optional metadata applied when a drop creates a grouped multi-placement edit. */\n  group?:\n    | TimelineExternalClipDropGroupOptions\n    | ((\n        context: TimelineExternalClipDropContext<DragData>\n      ) => TimelineExternalClipDropGroupOptions | null | undefined);\n  /** Whether to resolve magnetic snapping for placed clips. Multi-placement drops share one group delta. Defaults to true. */\n  snap?: boolean;\n}\n\n/**\n * Result returned by `useTimelineExternalClipDrop`.\n *\n * @remarks\n *\n * Use `rootProps` on the drop surface, then render the feedback fields in\n * timeline chrome such as target-row highlighting, invalid-drop messages, or a\n * preview badge. `lastResult` keeps the last command outcome available after\n * hover feedback clears.\n *\n * target track.\n */\nexport interface UseTimelineExternalClipDropResult {\n  /** Props for the element that should accept native external drops. */\n  rootProps: TimelineExternalClipDropRootProps;\n  /** Whether an external drag is currently over the drop surface. */\n  dragging: boolean;\n  /** Track currently under the pointer, including invalid targets. */\n  hoveredTrackId: string | null;\n  /** Valid target track id currently accepting the payload. */\n  targetTrackId: string | null;\n  /** Valid target track currently accepting the payload. */\n  targetTrack: TimelineReadonly<Track> | null;\n  /** Timeline time under the pointer, when a track is resolved. */\n  dropTime: RationalTime | null;\n  /** Timeline seconds under the pointer, when a track is resolved. */\n  dropSeconds: number | null;\n  /** Whether the current external payload can be dropped. */\n  valid: boolean;\n  /** Machine-readable reason for invalid feedback. */\n  reason: TimelineCommandFailureReason | null;\n  /** Last committed or rejected drop result. */\n  lastResult: TimelineCommandResult<TimelineEditCommitResult> | null;\n  /** Clears current hover feedback while preserving the last result. */\n  clearDropFeedback: () => void;\n}\n\ninterface ExternalDropFeedback {\n  dragging: boolean;\n  hoveredTrackId: string | null;\n  targetTrackId: string | null;\n  targetTrack: TimelineReadonly<Track> | null;\n  dropTime: RationalTime | null;\n  dropSeconds: number | null;\n  valid: boolean;\n  reason: TimelineCommandFailureReason | null;\n}\n\ninterface ResolvedExternalDropContext<DragData> {\n  context: TimelineExternalClipDropContext<DragData>;\n  valid: boolean;\n  reason: TimelineCommandFailureReason | null;\n  message?: string;\n}\n\nfunction createEmptyExternalDropFeedback(): ExternalDropFeedback {\n  return {\n    dragging: false,\n    hoveredTrackId: null,\n    targetTrackId: null,\n    targetTrack: null,\n    dropTime: null,\n    dropSeconds: null,\n    valid: false,\n    reason: null,\n  };\n}\n\nfunction toTimelineCommandFailureReason(\n  reason: TimelineEditRejectionReason | null\n): TimelineCommandFailureReason {\n  return reason ?? 'unsupported';\n}\n\nfunction normalizeDropGuardResult(\n  result: boolean | TimelineExternalClipDropGuardResult\n): TimelineExternalClipDropGuardResult {\n  if (typeof result === 'boolean') {\n    return { canDrop: result, reason: result ? undefined : 'unsupported' };\n  }\n  return result;\n}\n\nfunction isLeavingCurrentTarget(event: DragEvent<HTMLElement>) {\n  return (\n    event.relatedTarget === null ||\n    !(event.relatedTarget instanceof Node) ||\n    !event.currentTarget.contains(event.relatedTarget)\n  );\n}\n\n/**\n * Adds native browser drag-and-drop support for app-owned clip data.\n *\n * @remarks\n *\n * The hook owns browser event handling, track/time resolution, and local\n * feedback state. Apps own payload parsing and clip placement factories; the\n * engine owns validation, policy, history, grouped edits, and undo/redo.\n *\n * @param options - Drop geometry, app payload callbacks, edit mode, and optional policy.\n * @returns Root props, feedback state, and the last drop command result.\n * @template DragData - App-owned payload resolved from the native drag event.\n *\n * @example\n * ```tsx\n * import { addRational, fromSeconds } from '@techsquidtv/canvas-timeline-utils';\n * import { useTimelineExternalClipDrop } from '@techsquidtv/canvas-timeline-react';\n *\n * interface MediaAsset {\n *   id: string;\n *   durationSeconds: number;\n * }\n *\n * export function AssetDropSurface() {\n *   const drop = useTimelineExternalClipDrop<MediaAsset>({\n *     resolveDragData: (event) => {\n *       const id = event.dataTransfer.getData('text/plain');\n *       return id ? { id, durationSeconds: 5 } : null;\n *     },\n *     createPlacements: ({ data, dropTime, targetTrack }) => {\n *       const duration = fromSeconds(data.durationSeconds, dropTime.r);\n *\n *       return [\n *         {\n *           trackId: targetTrack.id,\n *           clip: {\n *             id: `clip-${data.id}`,\n *             sourceId: data.id,\n *             timelineStart: dropTime,\n *             timelineEnd: addRational(dropTime, duration),\n *             sourceStart: fromSeconds(0, dropTime.r),\n *             sourceEnd: duration,\n *           },\n *         },\n *       ];\n *     },\n *   });\n *\n *   return <div {...drop.rootProps}>{drop.valid ? 'Drop media' : 'Drag media here'}</div>;\n * }\n * ```\n *\n * @see {@link TimelineExternalClipDropContext}\n * @see {@link useTimelineClipDropFeedback}\n * @see {@link https://canvastimeline.com/docs/tracks-and-clips | Tracks and clips}\n */\nexport function useTimelineExternalClipDrop<DragData>(\n  options: UseTimelineExternalClipDropOptions<DragData>\n): UseTimelineExternalClipDropResult {\n  const engine = useTimelineEngine();\n  const {\n    collapsedTrackHeight,\n    canDropOnTrack,\n    createPlacements,\n    editMode: editModeOption,\n    edgeThreshold,\n    group,\n    resolveDragData,\n    rulerHeight,\n    snap,\n    touchEdgeThreshold,\n    trackHeight,\n    viewportWidth,\n  } = options;\n  const [feedback, setFeedback] = useState<ExternalDropFeedback>(() =>\n    createEmptyExternalDropFeedback()\n  );\n  const [lastResult, setLastResult] =\n    useState<TimelineCommandResult<TimelineEditCommitResult> | null>(null);\n  const snappingPreparedRef = useRef(false);\n\n  const clearDropFeedback = useCallback(() => {\n    setFeedback(createEmptyExternalDropFeedback());\n    snappingPreparedRef.current = false;\n  }, []);\n\n  const prepareDropSnapping = useCallback(() => {\n    if (snap === false || snappingPreparedRef.current) {\n      return;\n    }\n    engine.prepareSnapping({ operation: 'custom' });\n    snappingPreparedRef.current = true;\n  }, [engine, snap]);\n\n  const resolveContext = useCallback(\n    (\n      event: DragEvent<HTMLElement>\n    ): ResolvedExternalDropContext<DragData> | TimelineCommandResult => {\n      const data = resolveDragData(event);\n      if (data === null) {\n        return timelineCommandFail('unsupported');\n      }\n\n      const bounds = event.currentTarget.getBoundingClientRect();\n      const viewportX = event.clientX - bounds.left;\n      const viewportY = event.clientY - bounds.top;\n      const target = engine.geometry.getTrackAtPoint({\n        collapsedTrackHeight,\n        edgeThreshold,\n        rulerHeight,\n        touchEdgeThreshold,\n        trackHeight,\n        viewportWidth: viewportWidth ?? bounds.width,\n        x: viewportX,\n        y: viewportY,\n      });\n\n      if (target === null) {\n        return timelineCommandFail('invalid-track');\n      }\n      if (target.track.locked) {\n        return timelineCommandFail('locked');\n      }\n\n      const dropTime = engine.pixelToTime(viewportX);\n      const baseContext = {\n        data,\n        event,\n        dataTransfer: event.dataTransfer,\n        targetTrack: target.track,\n        targetTrackIndex: target.trackIndex,\n        dropTime,\n        dropSeconds: toSeconds(dropTime),\n        viewportX,\n        viewportY,\n      };\n      const editMode =\n        typeof editModeOption === 'function'\n          ? editModeOption(baseContext)\n          : (editModeOption ?? 'overwrite');\n      const context: TimelineExternalClipDropContext<DragData> = {\n        ...baseContext,\n        editMode,\n      };\n      const guardResult =\n        canDropOnTrack === undefined\n          ? { canDrop: true }\n          : normalizeDropGuardResult(canDropOnTrack(context));\n\n      return {\n        context,\n        valid: guardResult.canDrop,\n        reason: guardResult.canDrop ? null : (guardResult.reason ?? 'unsupported'),\n        ...(guardResult.message !== undefined ? { message: guardResult.message } : {}),\n      };\n    },\n    [\n      engine,\n      collapsedTrackHeight,\n      canDropOnTrack,\n      editModeOption,\n      edgeThreshold,\n      resolveDragData,\n      rulerHeight,\n      touchEdgeThreshold,\n      trackHeight,\n      viewportWidth,\n    ]\n  );\n\n  const publishFeedback = useCallback(\n    (resolved: ResolvedExternalDropContext<DragData> | TimelineCommandResult) => {\n      if ('context' in resolved) {\n        setFeedback({\n          dragging: true,\n          hoveredTrackId: resolved.context.targetTrack.id,\n          targetTrackId: resolved.valid ? resolved.context.targetTrack.id : null,\n          targetTrack: resolved.valid ? resolved.context.targetTrack : null,\n          dropTime: resolved.context.dropTime,\n          dropSeconds: resolved.context.dropSeconds,\n          valid: resolved.valid,\n          reason: resolved.reason,\n        });\n        return;\n      }\n\n      setFeedback({\n        ...createEmptyExternalDropFeedback(),\n        dragging: true,\n        reason: resolved.reason ?? 'unsupported',\n      });\n    },\n    []\n  );\n\n  const commitPlacements = useCallback(\n    (\n      context: TimelineExternalClipDropContext<DragData>,\n      placements: readonly TimelineClipGroupPlacement[]\n    ): TimelineCommandResult<TimelineEditCommitResult> => {\n      if (placements.length === 0) {\n        return timelineCommandFail('unsupported');\n      }\n      const groupOptions = typeof group === 'function' ? group(context) : group;\n      const result = engine.commitEdit(\n        placements.length === 1\n          ? {\n              type: context.editMode,\n              clip: placements[0].clip,\n              targetTrackId: placements[0].targetTrackId,\n              startTime: placements[0].startTime,\n              snap,\n            }\n          : {\n              type: context.editMode === 'insert' ? 'insert-clip-group' : 'overwrite-clip-group',\n              placements,\n              groupId: groupOptions?.groupId,\n              label: groupOptions?.label,\n              snap,\n            }\n      );\n\n      return result.committed\n        ? timelineCommandOk(result)\n        : timelineCommandFail<TimelineEditCommitResult>(\n            toTimelineCommandFailureReason(result.preview.reason),\n            result.preview.message\n          );\n    },\n    [engine, group, snap]\n  );\n\n  const onDragEnter = useCallback<DragEventHandler<HTMLElement>>(\n    (event) => {\n      prepareDropSnapping();\n      publishFeedback(resolveContext(event));\n    },\n    [prepareDropSnapping, publishFeedback, resolveContext]\n  );\n\n  const onDragOver = useCallback<DragEventHandler<HTMLElement>>(\n    (event) => {\n      prepareDropSnapping();\n      const resolved = resolveContext(event);\n      publishFeedback(resolved);\n      event.preventDefault();\n      event.dataTransfer.dropEffect = 'context' in resolved && resolved.valid ? 'copy' : 'none';\n    },\n    [prepareDropSnapping, publishFeedback, resolveContext]\n  );\n\n  const onDragLeave = useCallback<DragEventHandler<HTMLElement>>(\n    (event) => {\n      if (isLeavingCurrentTarget(event)) {\n        clearDropFeedback();\n      }\n    },\n    [clearDropFeedback]\n  );\n\n  const onDrop = useCallback<DragEventHandler<HTMLElement>>(\n    (event) => {\n      event.preventDefault();\n      prepareDropSnapping();\n      const resolved = resolveContext(event);\n      if (!('context' in resolved) || !resolved.valid) {\n        const result = timelineCommandFail<TimelineEditCommitResult>(\n          resolved.reason ?? 'unsupported',\n          resolved.message\n        );\n        setLastResult(result);\n        clearDropFeedback();\n        return;\n      }\n\n      const placements = createPlacements(resolved.context);\n      const result =\n        placements === null\n          ? timelineCommandFail<TimelineEditCommitResult>('unsupported')\n          : commitPlacements(resolved.context, placements);\n      setLastResult(result);\n      clearDropFeedback();\n    },\n    [clearDropFeedback, commitPlacements, createPlacements, prepareDropSnapping, resolveContext]\n  );\n\n  const rootProps = useMemo(\n    () => ({\n      onDragEnter,\n      onDragOver,\n      onDragLeave,\n      onDrop,\n    }),\n    [onDragEnter, onDragLeave, onDragOver, onDrop]\n  );\n\n  return {\n    rootProps,\n    ...feedback,\n    lastResult,\n    clearDropFeedback,\n  };\n}\n"],"mappings":"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"}