{"version":3,"file":"ClipInteractionLayer.mjs","names":[],"sources":["../../../src/components/interactions/ClipInteractionLayer.tsx"],"sourcesContent":["import { consumeTimelineDoubleTap } from '#react/components/interactions/tapState';\nimport { useTimelineClipDrag, useTimelineClipTrim, useTimelineClipNavigation } from '#react/hooks';\nimport type { TimelineClipNavigationOptions } from '#react/hooks';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport { useTimelineSelector } from '#react/hooks/core/useTimelineSelector';\nimport { defaultTimelineInteractionGeometry } from '@techsquidtv/canvas-timeline-core';\nimport type {\n  ClipHitRegion,\n  ClipHitTestResult,\n  ClipViewportRect,\n  TimelineEngine,\n  TimelineInteractionGeometry,\n} from '@techsquidtv/canvas-timeline-core';\nimport type { RationalTime } from '@techsquidtv/canvas-timeline-utils';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\ninterface OverlayState {\n  clipId: string;\n  region: ClipHitRegion;\n  rect: ClipViewportRect;\n  canMove: boolean;\n  canTrim: boolean;\n}\n\ninterface ActiveEdit {\n  clipId: string;\n  region: ClipHitRegion;\n  viewportTop: number;\n  dragging: boolean;\n}\n\n/**\n * Details passed to a clip double-click or double-tap callback.\n */\nexport interface ClipDoubleClickDetails {\n  /** Timeline engine owning the hit clip. */\n  engine: TimelineEngine;\n  /** Timeline time under the pointer. */\n  time: RationalTime;\n  /** Pointer X in timeline viewport coordinates. */\n  viewportX: number;\n  /** Pointer Y in timeline viewport coordinates, including the ruler area. */\n  viewportY: number;\n  /** Original pointer event. */\n  event: React.PointerEvent<HTMLDivElement>;\n}\n\n/**\n * Props for the delegated clip interaction layer.\n */\nexport interface ClipInteractionLayerProps\n  extends\n    Omit<React.HTMLAttributes<HTMLDivElement>, keyof TimelineInteractionGeometry>,\n    TimelineInteractionGeometry {\n  /**\n   * Enables one focusable clip navigator for canvas-rendered clips.\n   *\n   * The layer handles keyboard input only while focused and never intercepts\n   * `Tab`. Defaults to `true`.\n   */\n  keyboardNavigation?: boolean;\n  /** Whether next/previous keyboard navigation wraps. Defaults to `false`. */\n  clipNavigationWrap?: boolean;\n  /** Whether keyboard navigation also selects clips in the engine. Defaults to `false`. */\n  selectOnNavigate?: boolean;\n  /** Optional externally controlled active clip id for the delegated overlay. */\n  activeClipId?: string | null;\n  /** Overlay region used for an externally controlled active clip. Defaults to `body`. */\n  activeClipRegion?: ClipHitRegion;\n  /** Whether the externally controlled active clip should render focus-visible styling. */\n  activeClipFocusVisible?: boolean;\n  /** Optional handler for double-click or double-tap gestures on canvas-rendered clips. */\n  onClipDoubleClick?: (hit: ClipHitTestResult, details: ClipDoubleClickDetails) => void;\n  /** Optional accessible label formatter for a canvas-rendered clip. */\n  getClipAriaLabel?: TimelineClipNavigationOptions['getClipAriaLabel'];\n  /** Optional accessible description formatter for a canvas-rendered clip. */\n  getClipAriaDescription?: TimelineClipNavigationOptions['getClipAriaDescription'];\n}\n\nfunction getSelectedClipId(tracks: ReturnType<TimelineEngine['getState']>['tracks']) {\n  for (const track of tracks) {\n    const clip = track.clips.find((candidate) => candidate.selected);\n    if (clip) {\n      return clip.id;\n    }\n  }\n\n  return null;\n}\n\nfunction overlayFromHit(hit: ClipHitTestResult): OverlayState {\n  return {\n    clipId: hit.clip.id,\n    region: hit.region,\n    rect: hit.rect,\n    canMove: hit.canMove,\n    canTrim: hit.canTrim,\n  };\n}\n\n/**\n * Constant-DOM clip interaction surface for canvas-rendered timeline clips.\n */\nexport const ClipInteractionLayer = React.forwardRef<HTMLDivElement, ClipInteractionLayerProps>(\n  (\n    {\n      className = '',\n      style,\n      rulerHeight = defaultTimelineInteractionGeometry.rulerHeight,\n      trackHeight = defaultTimelineInteractionGeometry.trackHeight,\n      collapsedTrackHeight = defaultTimelineInteractionGeometry.collapsedTrackHeight,\n      edgeThreshold = defaultTimelineInteractionGeometry.edgeThreshold,\n      touchEdgeThreshold = defaultTimelineInteractionGeometry.touchEdgeThreshold,\n      keyboardNavigation = true,\n      clipNavigationWrap = false,\n      selectOnNavigate = false,\n      activeClipId: controlledActiveClipId,\n      activeClipRegion = 'body',\n      activeClipFocusVisible,\n      onClipDoubleClick,\n      getClipAriaLabel,\n      getClipAriaDescription,\n      onPointerDown,\n      onPointerMove,\n      onPointerLeave,\n      onPointerUp,\n      onPointerCancel,\n      onLostPointerCapture,\n      ...props\n    },\n    forwardedRef\n  ) => {\n    const engine = useTimelineEngine();\n    const state = useTimelineSelector((state) => ({ tracks: state.tracks }));\n    const internalRef = useRef<HTMLDivElement>(null);\n    const activeEditRef = useRef<ActiveEdit | null>(null);\n    const [hoveredClipId, setHoveredClipId] = useState<string | null>(null);\n    const [hoveredRegion, setHoveredRegion] = useState<ClipHitRegion>('body');\n    const [overlay, setOverlay] = useState<OverlayState | null>(null);\n    const clipNavigation = useTimelineClipNavigation({\n      wrap: clipNavigationWrap,\n      selectOnNavigate,\n      getClipAriaLabel,\n      getClipAriaDescription,\n    });\n    const { cancelClipDrag, endClipDrag, moveClipDrag, startClipDrag } = useTimelineClipDrag({\n      rulerHeight,\n      trackHeight,\n      collapsedTrackHeight,\n      edgeThreshold,\n      touchEdgeThreshold,\n    });\n\n    const { startClipTrim, moveClipTrim, endClipTrim, cancelClipTrim } = useTimelineClipTrim();\n\n    const geometry = useMemo(\n      () => ({\n        rulerHeight,\n        trackHeight,\n        collapsedTrackHeight,\n        edgeThreshold,\n        touchEdgeThreshold,\n      }),\n      [collapsedTrackHeight, edgeThreshold, rulerHeight, touchEdgeThreshold, trackHeight]\n    );\n\n    const selectedClipId = useMemo(() => getSelectedClipId(state.tracks), [state.tracks]);\n    const keyboardActiveClipId = useMemo(\n      () =>\n        keyboardNavigation && clipNavigation.isFocusTargetFocused\n          ? clipNavigation.activeClipId\n          : null,\n      [clipNavigation.activeClipId, clipNavigation.isFocusTargetFocused, keyboardNavigation]\n    );\n    const externalActiveClipId = useMemo(\n      () => (controlledActiveClipId === undefined ? keyboardActiveClipId : controlledActiveClipId),\n      [controlledActiveClipId, keyboardActiveClipId]\n    );\n    const targetClipId = useMemo(\n      () =>\n        activeEditRef.current?.clipId ?? hoveredClipId ?? externalActiveClipId ?? selectedClipId,\n      [externalActiveClipId, hoveredClipId, selectedClipId]\n    );\n    const targetRegion = useMemo(\n      () =>\n        activeEditRef.current?.region ??\n        (hoveredClipId ? hoveredRegion : externalActiveClipId ? activeClipRegion : 'body'),\n      [activeClipRegion, externalActiveClipId, hoveredClipId, hoveredRegion]\n    );\n\n    const ref = useCallback(\n      (node: HTMLDivElement | null) => {\n        internalRef.current = node;\n        if (typeof forwardedRef === 'function') {\n          forwardedRef(node);\n        } else if (forwardedRef) {\n          forwardedRef.current = node;\n        }\n      },\n      [forwardedRef]\n    );\n\n    const getViewportPoint = useCallback(\n      (event: Pick<PointerEvent | React.PointerEvent, 'clientX' | 'clientY'>) => {\n        const rect = internalRef.current?.getBoundingClientRect();\n        if (!rect) {\n          return null;\n        }\n\n        return {\n          x: event.clientX - rect.left,\n          y: event.clientY - rect.top + geometry.rulerHeight,\n        };\n      },\n      [geometry.rulerHeight]\n    );\n\n    const refreshOverlay = useCallback(\n      (clipId: string | null, region: ClipHitRegion = 'body') => {\n        if (!clipId) {\n          setOverlay(null);\n          return;\n        }\n\n        const found = engine.geometry.getClip(clipId);\n        const rect = engine.geometry.getClipRect(clipId, geometry);\n        if (!found || !rect) {\n          setOverlay(null);\n          return;\n        }\n\n        setOverlay({\n          clipId,\n          region,\n          rect,\n          canMove: !found.track.locked && found.clip.movable !== false,\n          canTrim: !found.track.locked && found.clip.resizable !== false,\n        });\n      },\n      [engine, geometry]\n    );\n\n    useEffect(() => {\n      refreshOverlay(targetClipId, targetRegion);\n    }, [refreshOverlay, targetClipId, targetRegion]);\n\n    useEffect(() => {\n      const update = () => {\n        refreshOverlay(activeEditRef.current?.clipId ?? targetClipId, targetRegion);\n      };\n\n      const unsubscribeRender = engine.on('render', update);\n\n      return () => {\n        unsubscribeRender();\n      };\n    }, [engine, refreshOverlay, targetClipId, targetRegion]);\n\n    useEffect(() => {\n      return () => {\n        if (activeEditRef.current?.dragging) {\n          if (activeEditRef.current.region === 'body') {\n            cancelClipDrag();\n          } else {\n            cancelClipTrim();\n          }\n        }\n      };\n    }, [cancelClipDrag, cancelClipTrim]);\n\n    const handleActivePointerMove = useCallback(\n      (event: PointerEvent) => {\n        const activeEdit = activeEditRef.current;\n        if (!activeEdit?.dragging) {\n          return;\n        }\n\n        if (activeEdit.region !== 'body') {\n          moveClipTrim({ clientX: event.clientX });\n        } else {\n          moveClipDrag({\n            clientX: event.clientX,\n            viewportY: event.clientY - activeEdit.viewportTop + geometry.rulerHeight,\n          });\n        }\n      },\n      [geometry.rulerHeight, moveClipDrag, moveClipTrim]\n    );\n\n    const stopActiveEdit = useCallback(\n      (event: PointerEvent) => {\n        const activeEdit = activeEditRef.current;\n        activeEditRef.current = null;\n\n        try {\n          internalRef.current?.releasePointerCapture(event.pointerId);\n        } catch {\n          // Pointer capture may already be released by the browser.\n        }\n\n        if (activeEdit?.dragging) {\n          if (activeEdit.region === 'body') {\n            if (event.type === 'pointercancel') {\n              cancelClipDrag();\n            } else {\n              endClipDrag();\n            }\n          } else {\n            if (event.type === 'pointercancel') {\n              cancelClipTrim();\n            } else {\n              endClipTrim();\n            }\n          }\n        }\n\n        refreshOverlay(hoveredClipId ?? selectedClipId, hoveredRegion);\n      },\n      [\n        cancelClipDrag,\n        endClipDrag,\n        cancelClipTrim,\n        endClipTrim,\n        hoveredClipId,\n        hoveredRegion,\n        refreshOverlay,\n        selectedClipId,\n      ]\n    );\n\n    const handlePointerMove = (event: React.PointerEvent<HTMLDivElement>) => {\n      onPointerMove?.(event);\n      if (event.defaultPrevented) {\n        return;\n      }\n      if (activeEditRef.current) {\n        handleActivePointerMove(event.nativeEvent);\n        return;\n      }\n\n      const point = getViewportPoint(event);\n      const hit = point\n        ? engine.geometry.getClipAtPoint({\n            ...geometry,\n            ...point,\n            pointerType: event.pointerType,\n          })\n        : null;\n\n      setHoveredClipId(hit?.clip.id ?? null);\n      setHoveredRegion(hit?.region ?? 'body');\n      setOverlay(hit ? overlayFromHit(hit) : null);\n    };\n\n    const handlePointerLeave = (event: React.PointerEvent<HTMLDivElement>) => {\n      onPointerLeave?.(event);\n      if (event.defaultPrevented || activeEditRef.current) {\n        return;\n      }\n\n      setHoveredClipId(null);\n      setHoveredRegion('body');\n    };\n\n    const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {\n      onPointerUp?.(event);\n      if (event.defaultPrevented || !activeEditRef.current) {\n        return;\n      }\n\n      stopActiveEdit(event.nativeEvent);\n    };\n\n    const handlePointerCancel = (event: React.PointerEvent<HTMLDivElement>) => {\n      onPointerCancel?.(event);\n      if (event.defaultPrevented || !activeEditRef.current) {\n        return;\n      }\n\n      stopActiveEdit(event.nativeEvent);\n    };\n\n    const handleLostPointerCapture = (event: React.PointerEvent<HTMLDivElement>) => {\n      onLostPointerCapture?.(event);\n      if (event.defaultPrevented || !activeEditRef.current) {\n        return;\n      }\n\n      stopActiveEdit(event.nativeEvent);\n    };\n\n    const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {\n      onPointerDown?.(event);\n      if (event.defaultPrevented || (event.pointerType !== 'touch' && event.button !== 0)) {\n        return;\n      }\n\n      const point = getViewportPoint(event);\n      if (!point) {\n        engine.selectClip(null);\n        return;\n      }\n\n      const hit = engine.geometry.getClipAtPoint({\n        ...geometry,\n        ...point,\n        pointerType: event.pointerType,\n      });\n\n      if (!hit) {\n        engine.selectClip(null);\n        return;\n      }\n\n      event.preventDefault();\n      event.stopPropagation();\n\n      if (event.shiftKey) {\n        engine.toggleClipSelection(hit.clip.id);\n      } else {\n        engine.selectClip(hit.clip.id);\n      }\n      clipNavigation.setActiveClip(hit.clip.id);\n      setHoveredClipId(hit.clip.id);\n      setHoveredRegion(hit.region);\n      setOverlay(overlayFromHit(hit));\n\n      if (onClipDoubleClick && consumeTimelineDoubleTap(event)) {\n        onClipDoubleClick(hit, {\n          engine,\n          time: engine.pixelToTime(point.x),\n          viewportX: point.x,\n          viewportY: point.y,\n          event,\n        });\n        return;\n      }\n\n      const shouldDrag =\n        (hit.region === 'body' && hit.canMove) ||\n        ((hit.region === 'start-edge' || hit.region === 'end-edge') && hit.canTrim);\n\n      if (!shouldDrag) {\n        return;\n      }\n\n      const started =\n        hit.region === 'body'\n          ? startClipDrag({\n              clipId: hit.clip.id,\n              clientX: event.clientX,\n              viewportY: point.y,\n              clipRect: hit.rect,\n            })\n          : startClipTrim({\n              clipId: hit.clip.id,\n              edge: hit.region === 'start-edge' ? 'start' : 'end',\n              clientX: event.clientX,\n            });\n      if (!started.ok) {\n        return;\n      }\n      internalRef.current?.setPointerCapture(event.pointerId);\n\n      activeEditRef.current = {\n        clipId: hit.clip.id,\n        region: hit.region,\n        viewportTop: event.clientY - point.y + geometry.rulerHeight,\n        dragging: true,\n      };\n    };\n\n    const cursorRegion = overlay?.region ?? hoveredRegion;\n    const isEditable = Boolean(overlay && (overlay.canMove || overlay.canTrim));\n    const isKeyboardActiveOverlay =\n      keyboardNavigation &&\n      clipNavigation.isFocusTargetFocused &&\n      overlay?.clipId === clipNavigation.activeClipId;\n    const showFocusVisible = activeClipFocusVisible ?? isKeyboardActiveOverlay;\n    const cursor = activeEditRef.current?.dragging\n      ? 'grabbing'\n      : cursorRegion === 'body'\n        ? overlay?.canMove === false\n          ? 'not-allowed'\n          : 'grab'\n        : overlay?.canTrim === false\n          ? 'not-allowed'\n          : 'ew-resize';\n    const interactionLayerProps = keyboardNavigation\n      ? clipNavigation.getFocusTargetProps<HTMLDivElement>(props)\n      : props;\n\n    return (\n      <div\n        ref={ref}\n        className={`timeline-clip-interaction-layer ${className}`}\n        data-has-target={overlay ? 'true' : undefined}\n        onPointerDown={handlePointerDown}\n        onPointerMove={handlePointerMove}\n        onPointerLeave={handlePointerLeave}\n        onPointerUp={handlePointerUp}\n        onPointerCancel={handlePointerCancel}\n        onLostPointerCapture={handleLostPointerCapture}\n        style={{\n          top: `${geometry.rulerHeight}px`,\n          cursor: overlay ? cursor : undefined,\n          ...style,\n        }}\n        {...interactionLayerProps}\n      >\n        {overlay && (\n          <div\n            className=\"timeline-clip-interaction-overlay\"\n            data-region={overlay.region}\n            data-active={activeEditRef.current?.clipId === overlay.clipId ? 'true' : undefined}\n            data-editable={isEditable ? 'true' : undefined}\n            data-focus-visible={showFocusVisible ? 'true' : undefined}\n            style={{\n              transform: `translate(${overlay.rect.x}px, ${overlay.rect.y - geometry.rulerHeight}px)`,\n              width: `${overlay.rect.width}px`,\n              height: `${overlay.rect.height}px`,\n            }}\n          >\n            {overlay.canTrim && (\n              <>\n                <div\n                  className=\"timeline-clip-interaction-handle timeline-clip-interaction-handle-left\"\n                  data-active={activeEditRef.current?.region === 'start-edge' ? 'true' : undefined}\n                />\n                <div\n                  className=\"timeline-clip-interaction-handle timeline-clip-interaction-handle-right\"\n                  data-active={activeEditRef.current?.region === 'end-edge' ? 'true' : undefined}\n                />\n              </>\n            )}\n            {isEditable && <div className=\"timeline-clip-interaction-feedback\" />}\n          </div>\n        )}\n      </div>\n    );\n  }\n);\n\nClipInteractionLayer.displayName = 'Timeline.ClipInteractionLayer';\n"],"mappings":"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"}