{"version":3,"file":"KeyframeInteractionLayer.mjs","names":[],"sources":["../../../src/components/interactions/KeyframeInteractionLayer.tsx"],"sourcesContent":["import { consumeTimelineDoubleTap } from '#react/components/interactions/tapState';\nimport { useKeyframePointer } from '#react/components/interactions/useKeyframePointer';\nimport { useTimelineKeyframeDrag, useTimelineKeyframeGeometry } from '#react/hooks';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport { defaultTimelineInteractionGeometry } from '@techsquidtv/canvas-timeline-core';\nimport type {\n  TimelineEngine,\n  TimelineInteractionGeometry,\n  TimelineKeyframeHitTestResult,\n  TimelineKeyframePropertyId,\n  TimelineKeyframeRect,\n  TimelineKeyframeReference,\n  TimelineKeyframeClipboard,\n  TimelineKeyframeEditCommand,\n} from '@techsquidtv/canvas-timeline-core';\nimport {\n  addRational,\n  fromSeconds,\n  toSeconds,\n  resolveTimecodeFrameRate,\n} from '@techsquidtv/canvas-timeline-utils';\nimport type { TimecodeFrameRate } from '@techsquidtv/canvas-timeline-utils';\nimport React, { useCallback, useMemo, useRef, useState } from 'react';\n/**\n * Details passed to a keyframe double-click or double-tap callback.\n */\nexport interface KeyframeDoubleClickDetails {\n  /** Timeline engine owning the keyframe. */\n  engine: TimelineEngine;\n  /** Original pointer event. */\n  event: PointerEvent;\n}\n\n/**\n * Details passed to a keyframe keyboard delete callback.\n */\nexport interface KeyframeDeleteDetails {\n  /** Timeline engine owning the keyframe. */\n  engine: TimelineEngine;\n  /** Original keyboard event. */\n  event: React.KeyboardEvent<HTMLDivElement>;\n}\n\n/**\n * Props for the delegated keyframe interaction layer.\n */\nexport interface KeyframeInteractionLayerProps\n  extends\n    Omit<React.HTMLAttributes<HTMLDivElement>, keyof TimelineInteractionGeometry>,\n    TimelineInteractionGeometry {\n  /** Keyframe property to render and hit-test. */\n  property: TimelineKeyframePropertyId;\n  /** Only render keyframes owned by selected clips. Defaults to false. */\n  selectedClipOnly?: boolean;\n  /** Extra pixels around the viewport included in visible keyframe queries. */\n  overscanPixels?: number;\n  /** Keyframe affordance square size in CSS pixels. */\n  keyframeSize?: number;\n  /**\n   * Invisible pointer padding in CSS pixels added around each keyframe handle.\n   *\n   * Presses inside the padded area target the keyframe instead of falling\n   * through to lower interaction layers such as the clip layer. Defaults to 8.\n   */\n  hitPadding?: number;\n  /** Vertical padding used when mapping keyframe values into a clip row. */\n  keyframeValuePadding?: number;\n  /** Keyboard nudge amount in seconds for left/right arrow keys. Defaults to one frame at the configured frame rate. */\n  keyboardStepSeconds?: number;\n  /** Frame rate for snapping and keyboard nudges; defaults to the engine configuration. */\n  frameRate?: TimecodeFrameRate;\n  /** Normalized value change for up/down arrow nudges. Defaults to one percent. */\n  keyboardValueStep?: number;\n  /** Optional handler for double-click or double-tap gestures on keyframe handles. */\n  onKeyframeDoubleClick?: (\n    keyframe: TimelineKeyframeRect,\n    details: KeyframeDoubleClickDetails\n  ) => void;\n  /** Optional handler for Delete/Backspace key gestures on keyframe handles. */\n  onKeyframeDelete?: (keyframe: TimelineKeyframeRect, details: KeyframeDeleteDetails) => void;\n  /** Optional accessible label formatter for a canvas-rendered keyframe. */\n  getKeyframeAriaLabel?: (keyframe: TimelineKeyframeHitTestResult) => string;\n}\n\ntype PointerTarget = { type: 'key'; entry: TimelineKeyframeRect } | { type: 'marquee' };\ninterface Marquee {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}\n\n/** Delegated keyframe editing with one focus target and one active affordance. */\nexport const KeyframeInteractionLayer = React.forwardRef<\n  HTMLDivElement,\n  KeyframeInteractionLayerProps\n>(\n  (\n    {\n      property,\n      selectedClipOnly = false,\n      rulerHeight = defaultTimelineInteractionGeometry.rulerHeight,\n      trackHeight,\n      collapsedTrackHeight,\n      edgeThreshold,\n      touchEdgeThreshold,\n      overscanPixels,\n      keyframeSize,\n      keyframeValuePadding,\n      hitPadding = 8,\n      keyboardStepSeconds,\n      keyboardValueStep = 0.01,\n      frameRate,\n      onKeyframeDoubleClick,\n      onKeyframeDelete,\n      getKeyframeAriaLabel,\n      onKeyDown,\n      className = '',\n      style,\n      ...props\n    },\n    forwardedRef\n  ) => {\n    const engine = useTimelineEngine();\n    const root = useRef<HTMLDivElement>(null);\n    const [focused, setFocused] = useState<TimelineKeyframeReference | null>(null);\n    const [marquee, setMarquee] = useState<Marquee | null>(null);\n    const marqueeRef = useRef<{\n      x: number;\n      y: number;\n      selection: TimelineKeyframeReference[];\n      additive: boolean;\n    } | null>(null);\n    const keyPointerRef = useRef<{\n      reference: TimelineKeyframeReference;\n      toggleOnClick: boolean;\n      moved: boolean;\n    } | null>(null);\n    const axisRef = useRef<'time' | 'value' | undefined>(undefined);\n    const originRef = useRef({ x: 0, y: 0 });\n    const clipboard = useRef<TimelineKeyframeClipboard | null>(null);\n    const geometry = useMemo(\n      () => ({\n        property,\n        selectedClipOnly,\n        rulerHeight,\n        trackHeight,\n        collapsedTrackHeight,\n        edgeThreshold,\n        touchEdgeThreshold,\n        overscanPixels,\n        keyframeSize,\n        keyframeValuePadding,\n      }),\n      [\n        property,\n        selectedClipOnly,\n        rulerHeight,\n        trackHeight,\n        collapsedTrackHeight,\n        edgeThreshold,\n        touchEdgeThreshold,\n        overscanPixels,\n        keyframeSize,\n        keyframeValuePadding,\n      ]\n    );\n    const live = useTimelineKeyframeGeometry(geometry);\n    const drag = useTimelineKeyframeDrag({ ...geometry, frameRate });\n    const current =\n      live.keyframeRects.find(\n        (entry) => entry.clip.id === focused?.clipId && entry.keyframe.id === focused.keyframeId\n      ) ??\n      live.keyframeRects.find((entry) => entry.keyframe.selected) ??\n      live.visibleKeyframes[0];\n    const setFocus = (entry: TimelineKeyframeRect) =>\n      setFocused({ clipId: entry.clip.id, keyframeId: entry.keyframe.id });\n    const cancelPointer = useKeyframePointer<PointerTarget>({\n      root,\n      rulerHeight,\n      hitTest: (point, event) => {\n        const hits = live.visibleKeyframes.filter(\n          ({ rect }) =>\n            point.x >= rect.x - hitPadding &&\n            point.x <= rect.x + rect.width + hitPadding &&\n            point.y >= rect.y - hitPadding &&\n            point.y <= rect.y + rect.height + hitPadding\n        );\n        hits.sort(\n          (a, b) =>\n            Math.hypot(\n              point.x - a.rect.x - a.rect.width / 2,\n              point.y - a.rect.y - a.rect.height / 2\n            ) -\n            Math.hypot(\n              point.x - b.rect.x - b.rect.width / 2,\n              point.y - b.rect.y - b.rect.height / 2\n            )\n        );\n        return hits[0]\n          ? { type: 'key', entry: hits[0] }\n          : event.shiftKey && point.y >= rulerHeight\n            ? { type: 'marquee' }\n            : null;\n      },\n      hover: (target) => {\n        if (target?.type === 'key' && !drag.dragging) {\n          setFocus(target.entry);\n        }\n      },\n      start: (target, point, event) => {\n        originRef.current = point;\n        axisRef.current = undefined;\n        if (target.type === 'marquee') {\n          marqueeRef.current = {\n            ...point,\n            selection: engine.keyframes.getSelectedKeyframes(),\n            additive: event.metaKey || event.ctrlKey,\n          };\n          setMarquee({ ...point, width: 0, height: 0 });\n          return true;\n        }\n        const entry = target.entry;\n        setFocus(entry);\n        if (!entry.canEdit) {\n          return false;\n        }\n        const ref = { clipId: entry.clip.id, keyframeId: entry.keyframe.id };\n        const additive = event.shiftKey || event.metaKey || event.ctrlKey;\n        keyPointerRef.current = {\n          reference: ref,\n          toggleOnClick: additive && Boolean(entry.keyframe.selected),\n          moved: false,\n        };\n        if (!entry.keyframe.selected) {\n          engine.keyframes.selectKeyframes([ref], additive ? 'add' : 'replace');\n        }\n        if (onKeyframeDoubleClick && consumeTimelineDoubleTap(event)) {\n          keyPointerRef.current = null;\n          onKeyframeDoubleClick(entry, { engine, event });\n          return false;\n        }\n        const started = drag.startKeyframeDrag({\n          ...ref,\n          clientX: event.clientX,\n          viewportY: point.y,\n          keyframeRect: entry,\n        }).ok;\n        if (!started) {\n          keyPointerRef.current = null;\n        }\n        return started;\n      },\n      move: (point, event) => {\n        const start = marqueeRef.current;\n        if (start) {\n          const box = {\n            x: Math.min(start.x, point.x),\n            y: Math.min(start.y, point.y),\n            width: Math.abs(point.x - start.x),\n            height: Math.abs(point.y - start.y),\n          };\n          setMarquee(box);\n          const selected = live.keyframeRects\n            .filter(\n              (entry) =>\n                entry.canEdit &&\n                entry.rect.x + entry.rect.width >= box.x &&\n                entry.rect.x <= box.x + box.width &&\n                entry.rect.y + entry.rect.height >= box.y &&\n                entry.rect.y <= box.y + box.height\n            )\n            .map((entry) => ({ clipId: entry.clip.id, keyframeId: entry.keyframe.id }));\n          engine.keyframes.selectKeyframes(\n            start.additive ? [...start.selection, ...selected] : selected\n          );\n          return;\n        }\n        const keyPointer = keyPointerRef.current;\n        if (!keyPointer) {\n          return;\n        }\n        if (!keyPointer.moved) {\n          if (Math.hypot(point.x - originRef.current.x, point.y - originRef.current.y) < 3) {\n            return;\n          }\n          keyPointer.moved = true;\n        }\n        if (event.shiftKey && !axisRef.current) {\n          axisRef.current =\n            Math.abs(point.x - originRef.current.x) >= Math.abs(point.y - originRef.current.y)\n              ? 'time'\n              : 'value';\n        }\n        drag.moveKeyframeDrag({\n          clientX: event.clientX,\n          viewportY: point.y,\n          axis: event.shiftKey ? axisRef.current : undefined,\n          fine: event.altKey,\n          snap: !(event.ctrlKey || event.metaKey),\n        });\n      },\n      end: (cancelled) => {\n        if (marqueeRef.current) {\n          if (cancelled) {\n            engine.keyframes.selectKeyframes(marqueeRef.current.selection);\n          }\n          marqueeRef.current = null;\n          setMarquee(null);\n        } else {\n          const keyPointer = keyPointerRef.current;\n          keyPointerRef.current = null;\n          if (cancelled) {\n            drag.cancelKeyframeDrag();\n          } else {\n            const result = drag.endKeyframeDrag();\n            if (result.ok && keyPointer?.toggleOnClick && !keyPointer.moved) {\n              engine.keyframes.selectKeyframes([keyPointer.reference], 'toggle');\n            }\n          }\n        }\n      },\n    });\n    const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n      onKeyDown?.(event);\n      if (event.defaultPrevented) {\n        return;\n      }\n      if (event.key === 'Escape') {\n        event.preventDefault();\n        cancelPointer();\n        return;\n      }\n      if (!current) {\n        return;\n      }\n      const modifier = event.metaKey || event.ctrlKey;\n      const selected = engine.keyframes.getSelectedKeyframes();\n      const references = selected.length\n        ? selected\n        : [{ clipId: current.clip.id, keyframeId: current.keyframe.id }];\n      if (modifier && event.key.toLowerCase() === 'a') {\n        event.preventDefault();\n        engine.keyframes.selectKeyframes(\n          live.keyframeRects\n            .filter((entry) => entry.canEdit)\n            .map((entry) => ({ clipId: entry.clip.id, keyframeId: entry.keyframe.id }))\n        );\n        return;\n      }\n      if (modifier && event.key.toLowerCase() === 'c') {\n        event.preventDefault();\n        clipboard.current = engine.keyframes.copyKeyframes(references);\n        return;\n      }\n      if (modifier && (event.key.toLowerCase() === 'v' || event.key.toLowerCase() === 'd')) {\n        event.preventDefault();\n        const copied =\n          event.key.toLowerCase() === 'd'\n            ? engine.keyframes.copyKeyframes(references)\n            : clipboard.current;\n        if (copied) {\n          engine.commitEdit(\n            engine.keyframes.createPasteCommand(\n              copied,\n              event.key.toLowerCase() === 'd'\n                ? addRational(\n                    current.keyframe.time,\n                    fromSeconds(\n                      keyboardStepSeconds ??\n                        1 / resolveTimecodeFrameRate(frameRate ?? engine.frameRate ?? 30)\n                    )\n                  )\n                : engine.getState().playheadTime\n            )\n          );\n        }\n        return;\n      }\n      if (event.key === 'Delete' || event.key === 'Backspace') {\n        event.preventDefault();\n        if (onKeyframeDelete) {\n          onKeyframeDelete(current, { engine, event });\n        } else {\n          engine.commitEdit({\n            type: 'keyframes',\n            edits: references.map((ref) => ({ type: 'remove', ...ref })),\n          });\n        }\n        return;\n      }\n      if (event.key === '[' || event.key === ']' || event.key === 'Home' || event.key === 'End') {\n        event.preventDefault();\n        const entries = live.keyframeRects;\n        const index = entries.indexOf(current);\n        const next =\n          entries[\n            event.key === 'Home'\n              ? 0\n              : event.key === 'End'\n                ? entries.length - 1\n                : Math.max(0, Math.min(entries.length - 1, index + (event.key === ']' ? 1 : -1)))\n          ];\n        if (next) {\n          setFocus(next);\n          engine.keyframes.selectKeyframes(\n            [{ clipId: next.clip.id, keyframeId: next.keyframe.id }],\n            event.shiftKey ? 'add' : 'replace'\n          );\n          engine.updatePlayhead(next.keyframe.time);\n        }\n        return;\n      }\n      if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.key)) {\n        return;\n      }\n      event.preventDefault();\n      const direction = event.key === 'ArrowRight' || event.key === 'ArrowUp' ? 1 : -1;\n      const multiplier = event.shiftKey ? 10 : event.altKey ? 0.1 : 1;\n      const horizontal = event.key === 'ArrowLeft' || event.key === 'ArrowRight';\n      const step =\n        keyboardStepSeconds ?? 1 / resolveTimecodeFrameRate(frameRate ?? engine.frameRate ?? 30);\n      let valueDelta = keyboardValueStep * direction * multiplier;\n      for (const ref of references) {\n        const key = engine.keyframes\n          .getClipKeyframes(ref.clipId)\n          .find((candidate) => candidate.id === ref.keyframeId);\n        const definition = key ? engine.getKeyframePropertyDefinition(key.property) : null;\n        if (key && definition) {\n          const normalized = definition.normalizeValue(key.value);\n          valueDelta = Math.max(-normalized, Math.min(1 - normalized, valueDelta));\n        }\n      }\n      const command: TimelineKeyframeEditCommand = {\n        type: 'keyframes',\n        edits: references.flatMap((ref) => {\n          const key = engine.keyframes\n            .getClipKeyframes(ref.clipId)\n            .find((candidate) => candidate.id === ref.keyframeId);\n          const definition = key ? engine.getKeyframePropertyDefinition(key.property) : null;\n          if (!key || !definition) {\n            return [];\n          }\n          return [\n            {\n              type: 'update',\n              ...ref,\n              ...(horizontal\n                ? { time: addRational(key.time, fromSeconds(step * direction * multiplier)) }\n                : {\n                    value: definition.denormalizeValue(\n                      Math.max(0, Math.min(1, definition.normalizeValue(key.value) + valueDelta))\n                    ),\n                  }),\n            },\n          ];\n        }),\n      };\n      engine.commitEdit(command);\n    };\n    const label = current\n      ? (getKeyframeAriaLabel?.(current) ??\n        `${property} keyframe at ${toSeconds(current.keyframe.time).toFixed(3)} seconds, ${engine.getKeyframePropertyDefinition(property)?.formatValue?.(current.keyframe.value) ?? current.keyframe.value}`)\n      : `${property} keyframes`;\n    const ref = useCallback(\n      (node: HTMLDivElement | null) => {\n        root.current = node;\n        if (typeof forwardedRef === 'function') {\n          forwardedRef(node);\n        } else if (forwardedRef) {\n          forwardedRef.current = node;\n        }\n      },\n      [forwardedRef]\n    );\n    return (\n      <div\n        {...props}\n        ref={ref}\n        className={`timeline-keyframe-interaction-layer ${className}`}\n        role=\"group\"\n        tabIndex={0}\n        aria-label={label}\n        onKeyDown={handleKeyDown}\n        style={{ top: rulerHeight, ...style }}\n      >\n        <span className=\"timeline-sr-only\" aria-live=\"polite\">\n          {drag.dragging ? '' : label}\n        </span>\n        {current && (\n          <div\n            className=\"timeline-keyframe-handle\"\n            aria-hidden=\"true\"\n            data-clip-id={current.clip.id}\n            data-keyframe-id={current.keyframe.id}\n            data-selected={current.keyframe.selected ? 'true' : undefined}\n            data-active={drag.dragging ? 'true' : undefined}\n            data-editable={current.canEdit ? 'true' : undefined}\n            style={{\n              transform: `translate(${current.rect.x - hitPadding}px, ${current.rect.y - rulerHeight - hitPadding}px)`,\n              width: current.rect.width + hitPadding * 2,\n              height: current.rect.height + hitPadding * 2,\n            }}\n          >\n            <div\n              className=\"timeline-keyframe-handle-shape\"\n              style={{ width: current.rect.width, height: current.rect.height }}\n            />\n          </div>\n        )}\n        {marquee && (\n          <div\n            className=\"timeline-keyframe-marquee\"\n            style={{\n              left: marquee.x,\n              top: marquee.y - rulerHeight,\n              width: marquee.width,\n              height: marquee.height,\n            }}\n          />\n        )}\n      </div>\n    );\n  }\n);\nKeyframeInteractionLayer.displayName = 'Timeline.KeyframeInteractionLayer';\n"],"mappings":"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"}