{"version":3,"file":"useTimelineClipNavigation.mjs","names":[],"sources":["../../../src/hooks/clips/useTimelineClipNavigation.ts"],"sourcesContent":["import { useTimelineSelection } from '#react/hooks/selection/useTimelineSelection';\nimport { getClipAccessibleDescription, getClipAccessibleName } from '#react/accessibility';\nimport type { TimelineClipEntry } from '#react/hooks/clips/timelineClipModel';\nimport { useTimelineClips } from '#react/hooks/clips/useTimelineClips';\nimport { timelineCommandFail } from '@techsquidtv/canvas-timeline-core';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport { useTimelineSelector } from '#react/hooks/core/useTimelineSelector';\nimport { useTimelineEditCommands } from '#react/hooks/editing/useTimelineEditCommands';\nimport { useTimelineSnapping } from '#react/hooks/editing/useTimelineSnapping';\nimport type { TimelineReadonly, Clip, Track } from '@techsquidtv/canvas-timeline-core';\nimport { addRational, fromSeconds } from '@techsquidtv/canvas-timeline-utils';\nimport React, { useCallback, useMemo, useState } from 'react';\n/**\n * Metadata for one canvas-rendered clip exposed through clip navigation.\n *\n * @remarks\n *\n * Canvas Timeline keeps clip visuals on canvas for performance. This model\n * gives a single DOM focus target enough metadata to announce and manipulate\n * whichever canvas clip is currently active.\n *\n *\n * @see {@link useTimelineClipNavigation}\n */\nexport interface TimelineNavigableClip {\n  /** Raw timeline clip represented by this navigation item. */\n  clip: TimelineReadonly<Clip>;\n  /** Track containing the clip. */\n  track: TimelineReadonly<Track<string>>;\n  /** Zero-based track index in timeline order. */\n  trackIndex: number;\n  /** Zero-based clip index inside the track. */\n  clipIndex: number;\n  /** Zero-based flattened clip index across all tracks. */\n  index: number;\n  /** Whether the active clip may be moved by command helpers. */\n  canMove: boolean;\n  /** Whether the active clip may be trimmed by command helpers. */\n  canTrim: boolean;\n  /** Concise accessible name derived from clip and track labels. */\n  name: string;\n  /** Longer accessible description with timing and edit-state details. */\n  description: string;\n}\n\n/**\n * Options for constant-DOM canvas clip navigation.\n *\n * @remarks\n *\n * Use these options when a canvas timeline needs keyboard navigation without\n * rendering one DOM button per clip. `selectOnNavigate` is useful for inspector\n * workflows; leave it disabled when navigation should move a virtual cursor\n * without mutating timeline selection.\n *\n * and description formatters.\n */\nexport interface TimelineClipNavigationOptions {\n  /** Initial active clip id. Defaults to selected clip, then the first clip. */\n  initialClipId?: string | null;\n  /** Whether next/previous navigation wraps around the clip list. Defaults to true. */\n  wrap?: boolean;\n  /** Whether navigation also selects the active clip in the engine. Defaults to false. */\n  selectOnNavigate?: boolean;\n  /** Optional accessible label formatter for a canvas-rendered clip. */\n  getClipAriaLabel?: (\n    clip: TimelineReadonly<Clip>,\n    track: TimelineReadonly<Track<string>>\n  ) => string;\n  /** Optional accessible description formatter for a canvas-rendered clip. */\n  getClipAriaDescription?: (\n    clip: TimelineReadonly<Clip>,\n    track: TimelineReadonly<Track<string>>\n  ) => string;\n}\n\nfunction buildNavigableClips(\n  clipEntries: readonly TimelineReadonly<TimelineClipEntry<string>>[],\n  getClipAriaLabel?: (\n    clip: TimelineReadonly<Clip>,\n    track: TimelineReadonly<Track<string>>\n  ) => string,\n  getClipAriaDescription?: (\n    clip: TimelineReadonly<Clip>,\n    track: TimelineReadonly<Track<string>>\n  ) => string\n): TimelineNavigableClip[] {\n  return clipEntries.map(({ clip, clipIndex, track, trackIndex }, index) => ({\n    clip,\n    track,\n    trackIndex,\n    clipIndex,\n    index,\n    canMove: !track.locked && clip.movable !== false,\n    canTrim: !track.locked && clip.resizable !== false,\n    name: getClipAriaLabel?.(clip, track) ?? getClipAccessibleName(clip, track),\n    description: getClipAriaDescription?.(clip, track) ?? getClipAccessibleDescription(clip, track),\n  }));\n}\n\nfunction getActiveClipStatus(activeClip: TimelineNavigableClip | null, clipCount: number) {\n  if (!activeClip) {\n    return clipCount === 0 ? 'No clips in timeline' : 'No active clip';\n  }\n\n  return `Clip ${activeClip.index + 1} of ${clipCount}, ${activeClip.name}, ${\n    activeClip.description\n  }`;\n}\n\n/**\n * Provides constant-DOM keyboard navigation and commands for canvas clips.\n *\n * The hook flattens canvas-rendered clips into a navigable model without\n * mounting one DOM element per clip. Consumers can use the returned\n * `focusTargetProps` on a single focused element, or wire the navigation and\n * edit commands into their own shortcut system and selected-clip inspector.\n *\n * @param options - Initial active clip and navigation behavior options.\n * @returns Active clip metadata, flattened clip list, navigation commands, edit commands, and optional focus-target props.\n * clips.\n *\n * @example\n * ```tsx\n * import { useTimelineClipNavigation } from '@techsquidtv/canvas-timeline-react';\n *\n * export function CanvasClipNavigator() {\n *   const clipNavigation = useTimelineClipNavigation({ selectOnNavigate: true });\n *\n *   return (\n *     <div {...clipNavigation.focusTargetProps}>\n *       <p>{clipNavigation.activeClipStatus}</p>\n *       <button type=\"button\" onClick={() => clipNavigation.navigatePrevious()}>\n *         Previous clip\n *       </button>\n *       <button type=\"button\" onClick={() => clipNavigation.navigateNext()}>\n *         Next clip\n *       </button>\n *     </div>\n *   );\n * }\n * ```\n *\n * @see {@link TimelineNavigableClip}\n * @see {@link https://canvastimeline.com/docs/react-hooks | React editor hooks}\n */\nexport function useTimelineClipNavigation(options: TimelineClipNavigationOptions = {}) {\n  const {\n    getClipAriaDescription,\n    getClipAriaLabel,\n    initialClipId,\n    selectOnNavigate = false,\n    wrap = true,\n  } = options;\n  const engine = useTimelineEngine();\n  const state = useTimelineSelector((state) => ({ tracks: state.tracks }));\n  const { clips: clipEntries } = useTimelineClips();\n  const { selectedClipId } = useTimelineSelection();\n  const { moveClip, trimClip } = useTimelineEditCommands();\n  const { prepareSnapping, settle } = useTimelineSnapping();\n  const clips = useMemo(\n    () => buildNavigableClips(clipEntries, getClipAriaLabel, getClipAriaDescription),\n    [clipEntries, getClipAriaDescription, getClipAriaLabel]\n  );\n\n  const [requestedActiveClipId, setRequestedActiveClipId] = useState<string | null>(\n    initialClipId ?? selectedClipId ?? clips[0]?.clip.id ?? null\n  );\n  const [isFocusTargetFocused, setIsFocusTargetFocused] = useState(false);\n\n  const activeClipId = useMemo(\n    () =>\n      requestedActiveClipId &&\n      clips.some((candidate) => candidate.clip.id === requestedActiveClipId)\n        ? requestedActiveClipId\n        : (selectedClipId ?? clips[0]?.clip.id ?? null),\n    [clips, requestedActiveClipId, selectedClipId]\n  );\n\n  const activeClip = useMemo(\n    () => clips.find((candidate) => candidate.clip.id === activeClipId) ?? null,\n    [activeClipId, clips]\n  );\n\n  const setActiveClip = useCallback(\n    (clipId: string | null) => {\n      setRequestedActiveClipId(clipId);\n      if (selectOnNavigate) {\n        engine.selectClip(clipId);\n      }\n    },\n    [engine, selectOnNavigate]\n  );\n\n  const navigateBy = useCallback(\n    (delta: number) => {\n      if (clips.length === 0) {\n        setActiveClip(null);\n        return null;\n      }\n\n      const currentIndex = Math.max(\n        0,\n        activeClip ? clips.findIndex((candidate) => candidate.clip.id === activeClip.clip.id) : 0\n      );\n      let nextIndex = currentIndex + delta;\n\n      if (wrap) {\n        nextIndex = (nextIndex + clips.length) % clips.length;\n      } else {\n        nextIndex = Math.max(0, Math.min(clips.length - 1, nextIndex));\n      }\n\n      const next = clips[nextIndex] ?? null;\n      setActiveClip(next?.clip.id ?? null);\n      return next;\n    },\n    [activeClip, clips, setActiveClip, wrap]\n  );\n\n  const navigateToTrack = useCallback(\n    (delta: number) => {\n      if (!activeClip) {\n        return navigateBy(delta > 0 ? 1 : -1);\n      }\n\n      const nextTrackIndex = activeClip.trackIndex + delta;\n      const nextTrack = state.tracks[nextTrackIndex];\n      if (!nextTrack || nextTrack.clips.length === 0) {\n        return activeClip;\n      }\n\n      const nextClip = nextTrack.clips[Math.min(activeClip.clipIndex, nextTrack.clips.length - 1)];\n      setActiveClip(nextClip.id);\n      return clips.find((candidate) => candidate.clip.id === nextClip.id) ?? null;\n    },\n    [activeClip, clips, navigateBy, setActiveClip, state.tracks]\n  );\n\n  const navigateToFirst = useCallback(() => {\n    const next = clips[0] ?? null;\n    setActiveClip(next?.clip.id ?? null);\n    return next;\n  }, [clips, setActiveClip]);\n\n  const navigateToLast = useCallback(() => {\n    const next = clips[clips.length - 1] ?? null;\n    setActiveClip(next?.clip.id ?? null);\n    return next;\n  }, [clips, setActiveClip]);\n\n  const selectActiveClip = useCallback(() => {\n    engine.selectClip(activeClip?.clip.id ?? null);\n  }, [activeClip, engine]);\n\n  const moveActiveClipBy = useCallback(\n    (deltaSeconds: number) => {\n      if (!activeClip?.canMove) {\n        return timelineCommandFail('locked');\n      }\n      const found = engine.geometry.getClip(activeClip.clip.id);\n      if (!found) {\n        return timelineCommandFail('not-found');\n      }\n      prepareSnapping(found.clip.id);\n      const result = moveClip({\n        clipId: found.clip.id,\n        startTime: addRational(\n          found.clip.timelineStart,\n          fromSeconds(deltaSeconds, found.clip.timelineStart.r)\n        ),\n      });\n      if (result.ok) {\n        settle();\n      }\n      return result;\n    },\n    [activeClip, engine, moveClip, prepareSnapping, settle]\n  );\n\n  const moveActiveClipToTrack = useCallback(\n    (deltaTrackIndex: number) => {\n      if (!activeClip?.canMove) {\n        return timelineCommandFail('locked');\n      }\n      const found = engine.geometry.getClip(activeClip.clip.id);\n      if (!found) {\n        return timelineCommandFail('not-found');\n      }\n\n      const nextTrack = state.tracks[found.trackIndex + deltaTrackIndex];\n      if (!nextTrack) {\n        return timelineCommandFail('invalid-track');\n      }\n\n      prepareSnapping(found.clip.id);\n      const result = moveClip({\n        clipId: found.clip.id,\n        startTime: found.clip.timelineStart,\n        targetTrackId: nextTrack.id,\n      });\n      if (result.ok) {\n        settle();\n      }\n      return result;\n    },\n    [activeClip, engine, moveClip, prepareSnapping, settle, state.tracks]\n  );\n\n  const trimActiveClipBy = useCallback(\n    (edge: 'start' | 'end', deltaSeconds: number) => {\n      if (!activeClip?.canTrim) {\n        return timelineCommandFail('locked');\n      }\n      const found = engine.geometry.getClip(activeClip.clip.id);\n      if (!found) {\n        return timelineCommandFail('not-found');\n      }\n      const currentTime = edge === 'start' ? found.clip.timelineStart : found.clip.timelineEnd;\n      prepareSnapping(found.clip.id);\n      const result = trimClip({\n        clipId: found.clip.id,\n        edge,\n        newTime: addRational(currentTime, fromSeconds(deltaSeconds, currentTime.r)),\n      });\n      if (result.ok) {\n        settle();\n      }\n      return result;\n    },\n    [activeClip, engine, prepareSnapping, settle, trimClip]\n  );\n\n  const activeClipStatusText = useMemo(\n    () => getActiveClipStatus(activeClip, clips.length),\n    [activeClip, clips.length]\n  );\n\n  const getFocusTargetProps = useCallback(\n    <T extends HTMLElement>(props: React.HTMLAttributes<T> = {}): React.HTMLAttributes<T> => ({\n      ...props,\n      role: props.role ?? 'group',\n      'aria-roledescription': props['aria-roledescription'] ?? 'timeline clip navigator',\n      tabIndex: props.tabIndex ?? 0,\n      'aria-label': props['aria-label'] ?? activeClipStatusText,\n      'aria-description': props['aria-description'] ?? activeClip?.description,\n      onFocus: (event) => {\n        props.onFocus?.(event);\n        setIsFocusTargetFocused(true);\n      },\n      onBlur: (event) => {\n        props.onBlur?.(event);\n        setIsFocusTargetFocused(false);\n      },\n      onKeyDown: (event) => {\n        props.onKeyDown?.(event);\n        if (event.defaultPrevented) {\n          return;\n        }\n\n        setIsFocusTargetFocused(true);\n\n        switch (event.key) {\n          case 'ArrowRight':\n            event.preventDefault();\n            navigateBy(1);\n            break;\n          case 'ArrowLeft':\n            event.preventDefault();\n            navigateBy(-1);\n            break;\n          case 'ArrowDown':\n            event.preventDefault();\n            navigateToTrack(1);\n            break;\n          case 'ArrowUp':\n            event.preventDefault();\n            navigateToTrack(-1);\n            break;\n          case 'Home':\n            event.preventDefault();\n            navigateToFirst();\n            break;\n          case 'End':\n            event.preventDefault();\n            navigateToLast();\n            break;\n          case 'Enter':\n          case ' ':\n            event.preventDefault();\n            selectActiveClip();\n            break;\n          default:\n            break;\n        }\n      },\n    }),\n    [\n      activeClip,\n      activeClipStatusText,\n      navigateBy,\n      navigateToFirst,\n      navigateToLast,\n      navigateToTrack,\n      selectActiveClip,\n    ]\n  );\n\n  const focusTargetProps = useMemo(() => getFocusTargetProps(), [getFocusTargetProps]);\n\n  return useMemo(\n    () => ({\n      /** Metadata for the active navigable clip, or `null` when no clips exist. */\n      activeClip,\n      /** Clip id for the active navigable clip. */\n      activeClipId,\n      /** Flattened list of canvas clips with accessibility metadata. */\n      clips,\n      /** Number of navigable clips. */\n      clipCount: clips.length,\n      /** Sets the active clip id and optionally selects it in the engine. */\n      setActiveClip,\n      /** Moves active navigation by a flattened clip delta. */\n      navigateBy,\n      /** Moves active navigation vertically between tracks. */\n      navigateToTrack,\n      /** Moves active navigation to the first clip in timeline order. */\n      navigateToFirst,\n      /** Moves active navigation to the last clip in timeline order. */\n      navigateToLast,\n      /** Selects the active clip in the timeline engine. */\n      selectActiveClip,\n      /** Moves the active clip by a relative number of seconds and returns the command result. */\n      moveActiveClipBy,\n      /** Moves the active clip vertically by a relative track delta and returns the command result. */\n      moveActiveClipToTrack,\n      /** Trims one edge of the active clip by a relative number of seconds and returns the command result. */\n      trimActiveClipBy,\n      /** Builds props for a single focusable clip-navigation target. */\n      getFocusTargetProps,\n      /** Whether the returned focus target currently contains focus. */\n      isFocusTargetFocused,\n      /** Active clip summary suitable for an accessible label or live status. */\n      activeClipStatusText,\n      /** Default props for a single focusable clip-navigation target. */\n      focusTargetProps,\n    }),\n    [\n      activeClip,\n      activeClipId,\n      activeClipStatusText,\n      clips,\n      focusTargetProps,\n      getFocusTargetProps,\n      isFocusTargetFocused,\n      moveActiveClipBy,\n      moveActiveClipToTrack,\n      navigateBy,\n      navigateToFirst,\n      navigateToLast,\n      navigateToTrack,\n      selectActiveClip,\n      setActiveClip,\n      trimActiveClipBy,\n    ]\n  );\n}\n"],"mappings":"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"}