{"version":3,"file":"useTimelineZoomControl.mjs","names":[],"sources":["../../../src/hooks/viewport/useTimelineZoomControl.ts"],"sourcesContent":["import { useTimelineViewportBounds } from '#react/hooks/viewport/useTimelineViewportBounds';\nimport type { TimelineControlCommitDetails } from '#react/hooks/core/timelineControlEvents';\nimport { createTimelineScalarControlProps } from '#react/hooks/core/timelineScalarControlProps';\nimport { useTimelineEngine } from '#react/hooks/core/useTimelineEngine';\nimport { useTimelineZoomScale } from '#react/hooks/viewport/useTimelineZoomScale';\nimport { clamp, round } from '@techsquidtv/canvas-timeline-utils';\nimport { useCallback, useMemo } from 'react';\n/**\n * Options for adapting timeline zoom to a scalar control.\n */\nexport interface TimelineZoomControlOptions {\n  /** Minimum zoom scale in pixels per second. Defaults to 10. */\n  min?: number;\n  /** Maximum zoom scale in pixels per second. Defaults to 1000. */\n  max?: number;\n  /** Slider step in pixels per second. Defaults to 10. */\n  step?: number;\n  /** Accessible label for the zoom control. */\n  label?: string;\n  /**\n   * Called after the hook applies a committed control value to the engine.\n   *\n   * When the underlying scalar control provides commit details, Canvas Timeline\n   * forwards them unchanged as the second argument and does not read their\n   * fields.\n   */\n  onValueCommitted?: (value: number[], eventDetails?: TimelineControlCommitDetails) => void;\n}\n\nfunction formatZoomValue(value: number) {\n  const rounded = round(value, 2);\n  return `${rounded} pixels per second`;\n}\n\n/**\n * Adapts timeline zoom scale to a Base UI-compatible scalar slider.\n *\n * Use this hook when a product toolbar needs a focused, semantic zoom control\n * rather than broad viewport commands from `useTimelineViewport`. The returned\n * root props mutate `TimelineEngine.zoomScale`; thumb props provide the default\n * label and formatted `aria-valuetext`.\n *\n * @param options - Optional zoom bounds, step size, label, and commit callback.\n * @returns Current zoom scale, formatted value text, imperative setters, and props for `Slider.Root` plus `Slider.Thumb`.\n *\n * @example\n * ```tsx\n * const zoom = useTimelineZoomControl({ min: 25, max: 400, step: 25 });\n *\n * return (\n *   <Slider.Root {...zoom.rootProps}>\n *     <Slider.Control>\n *       <Slider.Track>\n *         <Slider.Indicator />\n *         <Slider.Thumb {...zoom.thumbProps} />\n *       </Slider.Track>\n *     </Slider.Control>\n *   </Slider.Root>\n * );\n * ```\n */\nexport function useTimelineZoomControl(options: TimelineZoomControlOptions = {}) {\n  const { label: optionLabel, max: optionMax, min: optionMin, onValueCommitted, step } = options;\n  const engine = useTimelineEngine();\n  const bounds = useTimelineViewportBounds();\n  const zoomScale = useTimelineZoomScale();\n  const control = useMemo(() => {\n    const engineMin = bounds.minZoomScale;\n    const engineMax = bounds.maxZoomScale;\n    const min = Math.max(optionMin ?? 10, engineMin);\n    const requestedMax = optionMax ?? (Number.isFinite(engineMax) ? engineMax : 1000);\n    const max = Math.max(min, Math.min(requestedMax, engineMax));\n\n    return {\n      label: optionLabel ?? 'Timeline zoom',\n      max,\n      min,\n      step: step ?? 10,\n      value: zoomScale,\n      valueText: formatZoomValue(zoomScale),\n    };\n  }, [\n    bounds.maxZoomScale,\n    bounds.minZoomScale,\n    optionLabel,\n    optionMax,\n    optionMin,\n    step,\n    zoomScale,\n  ]);\n\n  const setValue = useCallback(\n    (nextValue: number) => {\n      engine.setZoomScale(clamp(nextValue, control.min, control.max));\n    },\n    [control.max, control.min, engine]\n  );\n\n  const commit = useCallback(\n    (nextValue = control.value) => {\n      setValue(nextValue);\n      engine.settle();\n    },\n    [control.value, engine, setValue]\n  );\n\n  return useMemo(() => {\n    const scalarProps = createTimelineScalarControlProps({\n      control,\n      setValue,\n      commit,\n      getAriaValueText: formatZoomValue,\n      onEmptyCommit: () => engine.settle(),\n      onValueCommitted,\n    });\n\n    return {\n      /** Accessible label used by the default thumb props. */\n      label: control.label,\n      /** Maximum zoom scale in pixels per second. */\n      max: control.max,\n      /** Minimum zoom scale in pixels per second. */\n      min: control.min,\n      /** Slider step in pixels per second. */\n      step: control.step,\n      /** Current zoom scale in pixels per second. */\n      value: control.value,\n      /** Formatted zoom value for assistive technology. */\n      valueText: control.valueText,\n      /** Sets zoom scale without an additional explicit commit callback. */\n      setValue,\n      /** Sets zoom scale and settles the engine interaction. */\n      commit,\n      /** Formats a zoom-scale value for `aria-valuetext`. */\n      getAriaValueText: scalarProps.getAriaValueText,\n      /** Props for a Base UI `Slider.Root`. */\n      rootProps: scalarProps.rootProps,\n      /** Props for a Base UI `Slider.Thumb`. */\n      thumbProps: scalarProps.thumbProps,\n    };\n  }, [commit, control, engine, onValueCommitted, setValue]);\n}\n"],"mappings":";;;;;;;AA6BA,SAAS,gBAAgB,OAAe;CAEtC,OAAO,GADS,MAAM,OAAO,CACb,EAAE;AACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,uBAAuB,UAAsC,CAAC,GAAG;CAC/E,MAAM,EAAE,OAAO,aAAa,KAAK,WAAW,KAAK,WAAW,kBAAkB,SAAS;CACvF,MAAM,SAAS,kBAAkB;CACjC,MAAM,SAAS,0BAA0B;CACzC,MAAM,YAAY,qBAAqB;CACvC,MAAM,UAAU,cAAc;EAC5B,MAAM,YAAY,OAAO;EACzB,MAAM,YAAY,OAAO;EACzB,MAAM,MAAM,KAAK,IAAI,aAAa,IAAI,SAAS;EAI/C,OAAO;GACL,OAAO,eAAe;GACtB,KAJU,KAAK,IAAI,KAAK,KAAK,IADV,cAAc,OAAO,SAAS,SAAS,IAAI,YAAY,MAC3B,SAAS,CAItD;GACF;GACA,MAAM,QAAQ;GACd,OAAO;GACP,WAAW,gBAAgB,SAAS;EACtC;CACF,GAAG;EACD,OAAO;EACP,OAAO;EACP;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,WAAW,aACd,cAAsB;EACrB,OAAO,aAAa,MAAM,WAAW,QAAQ,KAAK,QAAQ,GAAG,CAAC;CAChE,GACA;EAAC,QAAQ;EAAK,QAAQ;EAAK;CAAM,CACnC;CAEA,MAAM,SAAS,aACZ,YAAY,QAAQ,UAAU;EAC7B,SAAS,SAAS;EAClB,OAAO,OAAO;CAChB,GACA;EAAC,QAAQ;EAAO;EAAQ;CAAQ,CAClC;CAEA,OAAO,cAAc;EACnB,MAAM,cAAc,iCAAiC;GACnD;GACA;GACA;GACA,kBAAkB;GAClB,qBAAqB,OAAO,OAAO;GACnC;EACF,CAAC;EAED,OAAO;;GAEL,OAAO,QAAQ;;GAEf,KAAK,QAAQ;;GAEb,KAAK,QAAQ;;GAEb,MAAM,QAAQ;;GAEd,OAAO,QAAQ;;GAEf,WAAW,QAAQ;;GAEnB;;GAEA;;GAEA,kBAAkB,YAAY;;GAE9B,WAAW,YAAY;;GAEvB,YAAY,YAAY;EAC1B;CACF,GAAG;EAAC;EAAQ;EAAS;EAAQ;EAAkB;CAAQ,CAAC;AAC1D"}