{"version":3,"file":"useTimelineTrack.mjs","names":[],"sources":["../../../src/hooks/tracks/useTimelineTrack.ts"],"sourcesContent":["import type {\n  TimelineCommandResult,\n  TimelineReadonly,\n  TimelineTrackGeometryOptions,\n  TimelineTrackRect,\n  Track,\n} from '@techsquidtv/canvas-timeline-core';\nimport { useTimelineTrackGeometry } from '#react/hooks/tracks/useTimelineTrackGeometry';\nimport { useTimelineSelector } from '#react/hooks/core/useTimelineSelector';\nimport { useTimelineTrackCommands } from '#react/hooks/tracks/useTimelineTrackCommands';\nimport { useCallback, useMemo } from 'react';\n/**\n * Result returned by `useTimelineTrack`.\n *\n * @remarks\n *\n * The result is scoped to one track row and includes both state flags and\n * row-level commands. It also includes `rect`, which is aligned with canvas\n * track geometry for DOM overlays, resize handles, and track header layouts.\n *\n *\n * @see {@link useTimelineTrackHeader}\n * @see {@link useTimelineTracks}\n */\nexport interface UseTimelineTrackResult {\n  /** Requested track id. */\n  trackId: string;\n  /** Current track, or null when the id is missing. */\n  track: TimelineReadonly<Track> | null;\n  /** Zero-based track index, or -1 when the track is missing. */\n  trackIndex: number;\n  /** Viewport row rectangle matching canvas track geometry. */\n  rect: Readonly<TimelineTrackRect> | null;\n  /** Whether the requested track exists. */\n  exists: boolean;\n  /** App-defined track kind, or null when the track is missing. */\n  kind: string | null;\n  /** User-facing track name, when set. */\n  name: string | undefined;\n  /** Optional track group id. */\n  groupId: string | undefined;\n  /** Expanded row height in pixels, matching canvas geometry. */\n  height: number;\n  /** Whether the track itself is selected. */\n  selected: boolean;\n  /** Whether the track participates in active layer and media lookup. */\n  visible: boolean;\n  /** Whether the track is muted. */\n  muted: boolean;\n  /** Whether the track is locked for editing. */\n  locked: boolean;\n  /** Whether the track is targeted for edit operations. */\n  targeted: boolean;\n  /** Whether the track row is collapsed. */\n  collapsed: boolean;\n  /** Selects this track. */\n  selectTrack: () => TimelineCommandResult;\n  /** Renames this track, or clears its app-defined name. */\n  renameTrack: (name: string | undefined) => TimelineCommandResult;\n  /** Moves this track to a final zero-based row index. */\n  moveTrack: (toIndex: number) => TimelineCommandResult;\n  /** Sets this row's collapsed state. */\n  setCollapsed: (collapsed: boolean) => TimelineCommandResult;\n  /** Toggles this row's collapsed state. */\n  toggleCollapse: () => TimelineCommandResult;\n  /** Toggles this track's output visibility. */\n  toggleVisibility: () => TimelineCommandResult;\n  /** Sets this track's output visibility. */\n  setVisible: (visible: boolean) => TimelineCommandResult;\n  /** Toggles this track's muted state. */\n  toggleMute: () => TimelineCommandResult;\n  /** Sets this track's muted state. */\n  setMuted: (muted: boolean) => TimelineCommandResult;\n  /** Toggles this track's locked state. */\n  toggleLock: () => TimelineCommandResult;\n  /** Sets this track's locked state. */\n  setLocked: (locked: boolean) => TimelineCommandResult;\n  /** Sets this track's expanded display height in pixels. */\n  setTrackHeight: (height: number) => TimelineCommandResult;\n  /** Toggles this track's edit-targeted state. */\n  toggleTrackTarget: () => TimelineCommandResult;\n  /** Sets this track's edit-targeted state. */\n  setTrackTarget: (targeted: boolean) => TimelineCommandResult;\n  /** Assigns this track to a group, or clears its group. */\n  setTrackGroup: (groupId: string | undefined) => TimelineCommandResult;\n}\n\n/**\n * Accesses one timeline track with canvas-aligned row geometry and commands.\n *\n * @remarks\n *\n * Use this hook when a component owns controls for one specific row: mute,\n * visibility, lock, targeted state, grouping, or row height. It returns safe\n * no-op failure commands when the track id is missing, so header components can\n * remain mounted while project data changes.\n *\n * @param trackId - Track id to read and update.\n * @param options - Optional track geometry overrides matching the renderer.\n * @returns Track row state, canvas-aligned geometry, and row-scoped commands.\n *\n * @example\n * ```tsx\n * import { useTimelineTrack } from '@techsquidtv/canvas-timeline-react';\n *\n * export function TrackMuteButton({ trackId }: { trackId: string }) {\n *   const track = useTimelineTrack(trackId);\n *\n *   return (\n *     <button type=\"button\" aria-pressed={track.muted} onClick={() => track.toggleMute()}>\n *       {track.muted ? 'Unmute' : 'Mute'} {track.name ?? track.trackId}\n *     </button>\n *   );\n * }\n * ```\n *\n * @see {@link useTimelineTracks}\n * @see {@link useTimelineTrackHeader}\n * @see {@link https://canvastimeline.com/docs/tracks-and-clips | Tracks and clips}\n */\nexport function useTimelineTrack(\n  trackId: string,\n  options: TimelineTrackGeometryOptions = {}\n): UseTimelineTrackResult {\n  const rect = useTimelineTrackGeometry(trackId, options);\n  const track = useTimelineSelector((state) => {\n    const indexed = rect === null ? undefined : state.tracks[rect.trackIndex];\n    return indexed?.id === trackId\n      ? indexed\n      : (state.tracks.find((candidate) => candidate.id === trackId) ?? null);\n  }, Object.is);\n  const tracksState = useTimelineTrackCommands();\n  const trackSnapshot = useMemo(\n    () => ({ track, trackIndex: rect?.trackIndex ?? -1, rect }),\n    [track, rect]\n  );\n\n  const selectTrack = useCallback(() => tracksState.selectTrack(trackId), [trackId, tracksState]);\n\n  const renameTrack = useCallback(\n    (name: string | undefined) => tracksState.renameTrack(trackId, name),\n    [trackId, tracksState]\n  );\n  const moveTrack = useCallback(\n    (toIndex: number) => tracksState.moveTrack(trackId, toIndex),\n    [trackId, tracksState]\n  );\n  const setCollapsed = useCallback(\n    (collapsed: boolean) => tracksState.setCollapsed(trackId, collapsed),\n    [trackId, tracksState]\n  );\n  const toggleCollapse = useCallback(\n    () => tracksState.toggleCollapse(trackId),\n    [trackId, tracksState]\n  );\n\n  const toggleVisibility = useCallback(\n    () => tracksState.toggleVisibility(trackId),\n    [trackId, tracksState]\n  );\n\n  const setVisible = useCallback(\n    (visible: boolean) => tracksState.setVisible(trackId, visible),\n    [trackId, tracksState]\n  );\n\n  const toggleMute = useCallback(() => tracksState.toggleMute(trackId), [trackId, tracksState]);\n\n  const setMuted = useCallback(\n    (muted: boolean) => tracksState.setMuted(trackId, muted),\n    [trackId, tracksState]\n  );\n\n  const toggleLock = useCallback(() => tracksState.toggleLock(trackId), [trackId, tracksState]);\n\n  const setLocked = useCallback(\n    (locked: boolean) => tracksState.setLocked(trackId, locked),\n    [trackId, tracksState]\n  );\n\n  const setTrackHeight = useCallback(\n    (height: number) => tracksState.setTrackHeight(trackId, height),\n    [trackId, tracksState]\n  );\n\n  const toggleTrackTarget = useCallback(\n    () => tracksState.toggleTrackTarget(trackId),\n    [trackId, tracksState]\n  );\n\n  const setTrackTarget = useCallback(\n    (targeted: boolean) => tracksState.setTrackTarget(trackId, targeted),\n    [trackId, tracksState]\n  );\n\n  const setTrackGroup = useCallback(\n    (groupId: string | undefined) => tracksState.setTrackGroup(trackId, groupId),\n    [trackId, tracksState]\n  );\n\n  return useMemo(() => {\n    const { rect, track, trackIndex } = trackSnapshot;\n\n    return {\n      trackId,\n      track,\n      trackIndex,\n      rect,\n      exists: track !== null,\n      kind: track?.kind ?? null,\n      name: track?.name,\n      groupId: track?.groupId,\n      height: rect?.height ?? 0,\n      selected: track?.selected ?? false,\n      visible: track?.visible ?? false,\n      muted: track?.muted ?? false,\n      locked: track?.locked ?? false,\n      targeted: track?.targeted === true,\n      collapsed: track?.collapsed === true,\n      renameTrack,\n      moveTrack,\n      setCollapsed,\n      toggleCollapse,\n      selectTrack,\n      toggleVisibility,\n      setVisible,\n      toggleMute,\n      setMuted,\n      toggleLock,\n      setLocked,\n      setTrackHeight,\n      toggleTrackTarget,\n      setTrackTarget,\n      setTrackGroup,\n    };\n  }, [\n    renameTrack,\n    moveTrack,\n    setCollapsed,\n    toggleCollapse,\n    selectTrack,\n    setLocked,\n    setMuted,\n    setTrackGroup,\n    setTrackHeight,\n    setTrackTarget,\n    setVisible,\n    toggleLock,\n    toggleMute,\n    toggleTrackTarget,\n    toggleVisibility,\n    trackSnapshot,\n    trackId,\n  ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwHA,SAAgB,iBACd,SACA,UAAwC,CAAC,GACjB;CACxB,MAAM,OAAO,yBAAyB,SAAS,OAAO;CACtD,MAAM,QAAQ,qBAAqB,UAAU;EAC3C,MAAM,UAAU,SAAS,OAAO,KAAA,IAAY,MAAM,OAAO,KAAK;EAC9D,OAAO,SAAS,OAAO,UACnB,UACC,MAAM,OAAO,MAAM,cAAc,UAAU,OAAO,OAAO,KAAK;CACrE,GAAG,OAAO,EAAE;CACZ,MAAM,cAAc,yBAAyB;CAC7C,MAAM,gBAAgB,eACb;EAAE;EAAO,YAAY,MAAM,cAAc;EAAI;CAAK,IACzD,CAAC,OAAO,IAAI,CACd;CAEA,MAAM,cAAc,kBAAkB,YAAY,YAAY,OAAO,GAAG,CAAC,SAAS,WAAW,CAAC;CAE9F,MAAM,cAAc,aACjB,SAA6B,YAAY,YAAY,SAAS,IAAI,GACnE,CAAC,SAAS,WAAW,CACvB;CACA,MAAM,YAAY,aACf,YAAoB,YAAY,UAAU,SAAS,OAAO,GAC3D,CAAC,SAAS,WAAW,CACvB;CACA,MAAM,eAAe,aAClB,cAAuB,YAAY,aAAa,SAAS,SAAS,GACnE,CAAC,SAAS,WAAW,CACvB;CACA,MAAM,iBAAiB,kBACf,YAAY,eAAe,OAAO,GACxC,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,mBAAmB,kBACjB,YAAY,iBAAiB,OAAO,GAC1C,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,aAAa,aAChB,YAAqB,YAAY,WAAW,SAAS,OAAO,GAC7D,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,aAAa,kBAAkB,YAAY,WAAW,OAAO,GAAG,CAAC,SAAS,WAAW,CAAC;CAE5F,MAAM,WAAW,aACd,UAAmB,YAAY,SAAS,SAAS,KAAK,GACvD,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,aAAa,kBAAkB,YAAY,WAAW,OAAO,GAAG,CAAC,SAAS,WAAW,CAAC;CAE5F,MAAM,YAAY,aACf,WAAoB,YAAY,UAAU,SAAS,MAAM,GAC1D,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,iBAAiB,aACpB,WAAmB,YAAY,eAAe,SAAS,MAAM,GAC9D,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,oBAAoB,kBAClB,YAAY,kBAAkB,OAAO,GAC3C,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,iBAAiB,aACpB,aAAsB,YAAY,eAAe,SAAS,QAAQ,GACnE,CAAC,SAAS,WAAW,CACvB;CAEA,MAAM,gBAAgB,aACnB,YAAgC,YAAY,cAAc,SAAS,OAAO,GAC3E,CAAC,SAAS,WAAW,CACvB;CAEA,OAAO,cAAc;EACnB,MAAM,EAAE,MAAM,OAAO,eAAe;EAEpC,OAAO;GACL;GACA;GACA;GACA;GACA,QAAQ,UAAU;GAClB,MAAM,OAAO,QAAQ;GACrB,MAAM,OAAO;GACb,SAAS,OAAO;GAChB,QAAQ,MAAM,UAAU;GACxB,UAAU,OAAO,YAAY;GAC7B,SAAS,OAAO,WAAW;GAC3B,OAAO,OAAO,SAAS;GACvB,QAAQ,OAAO,UAAU;GACzB,UAAU,OAAO,aAAa;GAC9B,WAAW,OAAO,cAAc;GAChC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;AACH"}