{"version":3,"file":"TimecodeField.mjs","names":[],"sources":["../../src/timecodeField/TimecodeField.tsx"],"sourcesContent":["import {\n  formatTimecode,\n  fromSeconds,\n  parseTimecode,\n  toSeconds,\n  type RationalTime,\n  type TimecodeFormatOptions,\n  type TimecodeParseOptions,\n} from '@techsquidtv/canvas-timeline-utils';\nimport React, {\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useId,\n  useLayoutEffect,\n  useMemo,\n  useRef,\n  useState,\n} from 'react';\nimport { TimecodeInput, type TimecodeInputProps } from '#react/timecodeInput';\n\n/**\n * Reason a `TimecodeField` committed the current draft text.\n */\nexport type TimecodeFieldCommitReason = 'enter' | 'blur';\n\n/**\n * Details passed when a `TimecodeField` commits a valid value.\n */\nexport interface TimecodeFieldCommitDetails {\n  /** Parsed seconds from the committed draft text. */\n  seconds: number;\n  /** Parsed time converted to `RationalTime` at the field's configured timebase. */\n  time: RationalTime;\n  /** User-entered text that produced the committed value. */\n  text: string;\n  /** Interaction that committed the value. */\n  reason: TimecodeFieldCommitReason;\n}\n\n/**\n * Props for the compact inline timecode editing root.\n */\nexport interface TimecodeFieldRootProps extends Omit<\n  React.HTMLAttributes<HTMLSpanElement>,\n  'children' | 'onChange'\n> {\n  /** Current field value as seconds or `RationalTime`. */\n  value: number | RationalTime;\n  /** Duration used to size fixed-width display slots. Defaults to the current value. */\n  duration?: number | RationalTime;\n  /** Human-readable name used for default trigger and input labels. */\n  ariaLabel: string;\n  /** Called when the user commits valid timecode text. */\n  onCommit: (seconds: number, details: TimecodeFieldCommitDetails) => void | Promise<void>;\n  /** Optional label used in trigger accessibility text instead of the formatted value. */\n  valueLabel?: string;\n  /** Formatting options used for the trigger text and draft value when editing starts. */\n  formatOptions?: TimecodeFormatOptions;\n  /** Parsing options used for draft validation and commit. */\n  parseOptions?: TimecodeParseOptions;\n  /** Tick rate used for `details.time`. Defaults to the value rate, or `60000` for seconds. */\n  timebase?: number;\n  /** Disables trigger activation and cancels active editing when true. */\n  disabled?: boolean;\n  /** Controlled editing state. */\n  editing?: boolean;\n  /** Initial editing state when uncontrolled. */\n  defaultEditing?: boolean;\n  /** Called when the field requests an editing state change. */\n  onEditingChange?: (editing: boolean) => void;\n  /** Field parts. Defaults to the compact trigger plus the temporary editing input. */\n  children?: React.ReactNode;\n}\n\n/**\n * Props for the compact displayed timecode value.\n */\nexport interface TimecodeFieldTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n  /** Custom display content. Defaults to the formatted timecode value. */\n  children?: React.ReactNode;\n}\n\n/**\n * Props for the temporary typed timecode editor.\n */\nexport interface TimecodeFieldInputProps extends Omit<\n  TimecodeInputProps,\n  'className' | 'defaultValue' | 'invalid' | 'onValueChange' | 'value'\n> {\n  /** Adds design-system classes to the active input. */\n  className?: string;\n  /** Called with draft text as the user types, after internal state updates. */\n  onValueChange?: TimecodeInputProps['onValueChange'];\n}\n\ninterface TimecodeFieldContextValue {\n  accessibleValue: string;\n  ariaLabel: string;\n  describedBy: string;\n  disabled: boolean;\n  displaySegments: TimecodeFieldDisplaySegment[];\n  draftValue: string;\n  editing: boolean;\n  errorId: string;\n  formattedValue: string;\n  hintId: string;\n  inputRef: React.RefObject<HTMLInputElement | null>;\n  invalid: boolean;\n  triggerRef: React.RefObject<HTMLButtonElement | null>;\n  cancelEditing: (options: { restoreFocus: boolean }) => void;\n  commitDraft: (options: {\n    cancelOnInvalid: boolean;\n    reason: TimecodeFieldCommitReason;\n    restoreFocus: boolean;\n  }) => void;\n  setDraftValue: (value: string) => void;\n  setInvalid: (invalid: boolean) => void;\n  startEditing: () => void;\n}\n\nconst TimecodeFieldContext = createContext<TimecodeFieldContextValue | null>(null);\n\ntype TimecodeFieldDisplaySegment =\n  | {\n      part: 'hours' | 'minutes' | 'seconds' | 'centiseconds' | 'frames';\n      text: string;\n      widthCh: number;\n    }\n  | {\n      part: 'separator';\n      text: string;\n    };\n\ntype TimecodeFieldSegmentStyle = React.CSSProperties & {\n  '--timecode-field-segment-width'?: string;\n};\n\nfunction useTimecodeFieldContext() {\n  const context = useContext(TimecodeFieldContext);\n  if (!context) {\n    throw new Error('TimecodeField parts must be used within TimecodeField.Root');\n  }\n\n  return context;\n}\n\nfunction isRationalTime(value: number | RationalTime): value is RationalTime {\n  return typeof value === 'object' && value !== null && 'v' in value && 'r' in value;\n}\n\nfunction getValueSeconds(value: number | RationalTime) {\n  return isRationalTime(value) ? toSeconds(value) : value;\n}\n\nfunction getSafeSlotSeconds(seconds: number) {\n  return Math.max(0, Number.isFinite(seconds) ? seconds : 0);\n}\n\nfunction getDigitCount(value: number) {\n  return Math.max(1, Math.floor(Math.max(0, value)).toString().length);\n}\n\nfunction getTimecodeFieldDisplaySegments(\n  formattedValue: string,\n  durationSeconds: number\n): TimecodeFieldDisplaySegment[] {\n  const safeDurationSeconds = getSafeSlotSeconds(durationSeconds);\n  const frameMatch = /^(\\d+):(\\d{2}):(\\d{2})([:;])(\\d+)$/.exec(formattedValue);\n\n  if (frameMatch) {\n    const [, hours, minutes, seconds, separator, frames] = frameMatch;\n    const durationHoursWidth = getDigitCount(Math.floor(safeDurationSeconds / 3600));\n\n    return [\n      { part: 'hours', text: hours, widthCh: Math.max(hours.length, durationHoursWidth) },\n      { part: 'separator', text: ':' },\n      { part: 'minutes', text: minutes, widthCh: Math.max(minutes.length, 2) },\n      { part: 'separator', text: ':' },\n      { part: 'seconds', text: seconds, widthCh: 2 },\n      { part: 'separator', text: separator },\n      { part: 'frames', text: frames, widthCh: frames.length },\n    ];\n  }\n\n  const decimalMatch = /^(.+)\\.(\\d{2})$/.exec(formattedValue);\n  if (!decimalMatch) {\n    return [{ part: 'seconds', text: formattedValue, widthCh: Math.max(2, formattedValue.length) }];\n  }\n\n  const [, clockText, centiseconds] = decimalMatch;\n  const clockParts = clockText.split(':');\n\n  if (clockParts.length === 3) {\n    const [hours, minutes, seconds] = clockParts;\n    const durationHoursWidth = getDigitCount(Math.floor(safeDurationSeconds / 3600));\n\n    return [\n      { part: 'hours', text: hours, widthCh: Math.max(hours.length, durationHoursWidth) },\n      { part: 'separator', text: ':' },\n      { part: 'minutes', text: minutes, widthCh: Math.max(minutes.length, 2) },\n      { part: 'separator', text: ':' },\n      { part: 'seconds', text: seconds, widthCh: 2 },\n      { part: 'separator', text: '.' },\n      { part: 'centiseconds', text: centiseconds, widthCh: 2 },\n    ];\n  }\n\n  if (clockParts.length === 2) {\n    const [minutes, seconds] = clockParts;\n    const durationMinutesWidth = getDigitCount(Math.floor(safeDurationSeconds / 60));\n\n    return [\n      { part: 'minutes', text: minutes, widthCh: Math.max(minutes.length, durationMinutesWidth) },\n      { part: 'separator', text: ':' },\n      { part: 'seconds', text: seconds, widthCh: 2 },\n      { part: 'separator', text: '.' },\n      { part: 'centiseconds', text: centiseconds, widthCh: 2 },\n    ];\n  }\n\n  const [seconds] = clockParts;\n  const durationSecondsWidth = getDigitCount(Math.floor(safeDurationSeconds));\n\n  return [\n    { part: 'seconds', text: seconds, widthCh: Math.max(seconds.length, durationSecondsWidth, 2) },\n    { part: 'separator', text: '.' },\n    { part: 'centiseconds', text: centiseconds, widthCh: 2 },\n  ];\n}\n\nfunction mergeClassNames(...classNames: Array<string | undefined>) {\n  return classNames.filter(Boolean).join(' ');\n}\n\nfunction setRef<T>(ref: React.ForwardedRef<T> | undefined, value: T | null) {\n  if (!ref) {\n    return;\n  }\n\n  if (typeof ref === 'function') {\n    ref(value);\n    return;\n  }\n\n  ref.current = value;\n}\n\nfunction useComposedRef<T>(\n  internalRef: React.RefObject<T | null>,\n  externalRef: React.ForwardedRef<T>\n) {\n  return useCallback(\n    (value: T | null) => {\n      internalRef.current = value;\n      setRef(externalRef, value);\n    },\n    [externalRef, internalRef]\n  );\n}\n\nfunction getEffectiveParseOptions(\n  formatOptions: TimecodeFormatOptions | undefined,\n  parseOptions: TimecodeParseOptions | undefined\n): TimecodeParseOptions {\n  return {\n    frameRate: formatOptions?.frameRate,\n    dropFrame: formatOptions?.format === 'drop-frame' ? true : formatOptions?.dropFrame,\n    ...parseOptions,\n  };\n}\n\nfunction TimecodeFieldFormattedValue({ segments }: { segments: TimecodeFieldDisplaySegment[] }) {\n  const segmentCounts = new Map<string, number>();\n\n  return (\n    <>\n      {segments.map((segment) => {\n        const segmentIdentity =\n          segment.part === 'separator'\n            ? `${segment.part}-${segment.text}`\n            : `${segment.part}-${segment.text}-${segment.widthCh}`;\n        const segmentCount = segmentCounts.get(segmentIdentity) ?? 0;\n        segmentCounts.set(segmentIdentity, segmentCount + 1);\n        const segmentKey = `${segmentIdentity}-${segmentCount}`;\n\n        if (segment.part === 'separator') {\n          return (\n            <span\n              key={segmentKey}\n              className=\"timecode-field-separator\"\n              data-timecode-part={segment.part}\n            >\n              {segment.text}\n            </span>\n          );\n        }\n\n        return (\n          <span\n            key={segmentKey}\n            className=\"timecode-field-segment\"\n            data-timecode-part={segment.part}\n            style={\n              {\n                '--timecode-field-segment-width': `${segment.widthCh}ch`,\n              } as TimecodeFieldSegmentStyle\n            }\n          >\n            {segment.text}\n          </span>\n        );\n      })}\n    </>\n  );\n}\n\n/**\n * Compact displayed value for `TimecodeField`.\n *\n * Renders while the field is not editing so dense timeline chrome can read like\n * text instead of a form. Clicking it starts editing unless the field or trigger\n * is disabled.\n *\n * @param props - Native button props and optional custom trigger content.\n * @returns A button that opens the temporary inline timecode input.\n */\nexport const TimecodeFieldTrigger = React.forwardRef<HTMLButtonElement, TimecodeFieldTriggerProps>(\n  (\n    {\n      'aria-label': ariaLabel,\n      children,\n      className = '',\n      disabled,\n      onClick,\n      type = 'button',\n      ...props\n    },\n    ref\n  ) => {\n    const context = useTimecodeFieldContext();\n    const triggerRef = useComposedRef(context.triggerRef, ref);\n    const triggerDisabled = disabled ?? context.disabled;\n\n    if (context.editing) {\n      return null;\n    }\n\n    return (\n      <button\n        ref={triggerRef}\n        {...props}\n        aria-label={\n          ariaLabel ??\n          (triggerDisabled\n            ? `${context.ariaLabel}: ${context.accessibleValue}`\n            : `Edit ${context.ariaLabel}: ${context.accessibleValue}`)\n        }\n        className={mergeClassNames('timecode-field-trigger', className)}\n        data-slot=\"timecode-field-trigger\"\n        disabled={triggerDisabled}\n        onClick={(event) => {\n          onClick?.(event);\n\n          if (!event.defaultPrevented && !triggerDisabled) {\n            context.startEditing();\n          }\n        }}\n        type={type}\n      >\n        {children ?? <TimecodeFieldFormattedValue segments={context.displaySegments} />}\n      </button>\n    );\n  }\n);\n\nTimecodeFieldTrigger.displayName = 'TimecodeField.Trigger';\n\n/**\n * Temporary typed editor for `TimecodeField`.\n *\n * Renders only while the field is editing. Enter commits valid text, Escape\n * cancels, and blur commits valid text or cancels invalid text.\n *\n * @param props - `TimecodeInput` props for the editable control.\n * @returns A `TimecodeInput` plus screen-reader hint and error text.\n */\nexport const TimecodeFieldInput = React.forwardRef<HTMLInputElement, TimecodeFieldInputProps>(\n  (\n    {\n      'aria-describedby': ariaDescribedBy,\n      'aria-errormessage': ariaErrorMessage,\n      'aria-label': ariaLabel,\n      className = '',\n      onBlur,\n      onKeyDown,\n      onValueChange,\n      ...props\n    },\n    ref\n  ) => {\n    const context = useTimecodeFieldContext();\n    const inputRef = useComposedRef(context.inputRef, ref);\n    const describedBy = [context.describedBy, ariaDescribedBy].filter(Boolean).join(' ');\n\n    if (!context.editing) {\n      return null;\n    }\n\n    return (\n      <>\n        <TimecodeInput\n          ref={inputRef}\n          {...props}\n          aria-describedby={describedBy || undefined}\n          aria-errormessage={ariaErrorMessage ?? (context.invalid ? context.errorId : undefined)}\n          aria-label={ariaLabel ?? `Edit ${context.ariaLabel}`}\n          className={mergeClassNames('timecode-field-input', className)}\n          invalid={context.invalid}\n          onBlur={(event) => {\n            onBlur?.(event);\n\n            if (!event.defaultPrevented) {\n              context.commitDraft({\n                cancelOnInvalid: true,\n                reason: 'blur',\n                restoreFocus: false,\n              });\n            }\n          }}\n          onKeyDown={(event) => {\n            onKeyDown?.(event);\n\n            if (event.defaultPrevented) {\n              return;\n            }\n\n            if (event.key === 'Enter') {\n              event.preventDefault();\n              context.commitDraft({\n                cancelOnInvalid: false,\n                reason: 'enter',\n                restoreFocus: true,\n              });\n              return;\n            }\n\n            if (event.key === 'Escape') {\n              event.preventDefault();\n              context.cancelEditing({ restoreFocus: true });\n            }\n          }}\n          onValueChange={(value, details) => {\n            context.setDraftValue(value);\n            context.setInvalid(false);\n            onValueChange?.(value, details);\n          }}\n          value={context.draftValue}\n        />\n        <span id={context.hintId} className=\"timecode-field-sr-only\">\n          Enter seconds, minutes and seconds, hours minutes and seconds, or frame timecode when\n          configured. Press Enter to apply or Escape to cancel.\n        </span>\n        {context.invalid && (\n          <span id={context.errorId} className=\"timecode-field-sr-only\" role=\"alert\">\n            Invalid timecode.\n          </span>\n        )}\n      </>\n    );\n  }\n);\n\nTimecodeFieldInput.displayName = 'TimecodeField.Input';\n\n/**\n * Root state manager for compact label-to-input timecode editing.\n *\n * Use `TimecodeField.Root` around `TimecodeField.Trigger` and\n * `TimecodeField.Input` when playhead clocks, clip boundaries, trim controls, or\n * other dense editor chrome should show a stable timecode value until the user\n * chooses to type a precise correction. The root owns draft state, validation,\n * keyboard handling, blur behavior, focus restoration, and width reservation\n * while leaving timeline mutation to your `onCommit` handler.\n *\n * @param props - Inline editing state, value, parser/formatter options, and span props.\n * @returns A span containing the active `TimecodeField` part.\n */\nexport const TimecodeFieldRoot = React.forwardRef<HTMLSpanElement, TimecodeFieldRootProps>(\n  (\n    {\n      ariaLabel,\n      children,\n      className = '',\n      defaultEditing = false,\n      disabled = false,\n      duration,\n      editing: controlledEditing,\n      formatOptions,\n      onCommit,\n      onEditingChange,\n      parseOptions,\n      style,\n      timebase,\n      value,\n      valueLabel,\n      ...props\n    },\n    ref\n  ) => {\n    const triggerRef = useRef<HTMLButtonElement>(null);\n    const inputRef = useRef<HTMLInputElement>(null);\n    const restoreFocusAfterEditRef = useRef(false);\n    const descriptionId = useId();\n    const valueSeconds = useMemo(() => getValueSeconds(value), [value]);\n    const durationSeconds = useMemo(\n      () => (duration === undefined ? valueSeconds : getValueSeconds(duration)),\n      [duration, valueSeconds]\n    );\n    const formattedValue = useMemo(\n      () => formatTimecode(valueSeconds, formatOptions),\n      [formatOptions, valueSeconds]\n    );\n    const displaySegments = useMemo(\n      () => getTimecodeFieldDisplaySegments(formattedValue, durationSeconds),\n      [durationSeconds, formattedValue]\n    );\n    const commitTimebase = useMemo(\n      () => timebase ?? (isRationalTime(value) ? value.r : 60000),\n      [timebase, value]\n    );\n    const [uncontrolledEditing, setUncontrolledEditing] = useState(defaultEditing);\n    const editing = useMemo(\n      () => controlledEditing ?? uncontrolledEditing,\n      [controlledEditing, uncontrolledEditing]\n    );\n    const [draftValue, setDraftValue] = useState(() =>\n      formatTimecode(getValueSeconds(value), formatOptions)\n    );\n    const [invalid, setInvalid] = useState(false);\n    const [reservedWidth, setReservedWidth] = useState<string | undefined>();\n    const wasEditingRef = useRef(editing);\n    const effectiveParseOptions = useMemo(\n      () => getEffectiveParseOptions(formatOptions, parseOptions),\n      [formatOptions, parseOptions]\n    );\n\n    const setEditing = useCallback(\n      (nextEditing: boolean) => {\n        if (controlledEditing === undefined) {\n          setUncontrolledEditing(nextEditing);\n        }\n\n        onEditingChange?.(nextEditing);\n      },\n      [controlledEditing, onEditingChange]\n    );\n\n    useLayoutEffect(() => {\n      if (editing) {\n        inputRef.current?.focus();\n        inputRef.current?.select();\n        return;\n      }\n\n      if (restoreFocusAfterEditRef.current) {\n        restoreFocusAfterEditRef.current = false;\n        triggerRef.current?.focus();\n      }\n    }, [editing]);\n\n    useEffect(() => {\n      if (editing && !wasEditingRef.current) {\n        setDraftValue(formattedValue);\n        setInvalid(false);\n      }\n\n      wasEditingRef.current = editing;\n    }, [editing, formattedValue]);\n\n    useEffect(() => {\n      if (disabled && editing) {\n        restoreFocusAfterEditRef.current = false;\n        const timeoutId = window.setTimeout(() => {\n          setInvalid(false);\n          setEditing(false);\n        }, 0);\n\n        return () => window.clearTimeout(timeoutId);\n      }\n\n      return undefined;\n    }, [disabled, editing, setEditing]);\n\n    const startEditing = useCallback(() => {\n      if (disabled) {\n        return;\n      }\n\n      const triggerWidth = triggerRef.current?.getBoundingClientRect().width ?? 0;\n      setReservedWidth(triggerWidth > 0 ? `${triggerWidth.toFixed(3)}px` : undefined);\n      setDraftValue(formattedValue);\n      setInvalid(false);\n      setEditing(true);\n    }, [disabled, formattedValue, setEditing]);\n\n    const cancelEditing = useCallback(\n      ({ restoreFocus }: { restoreFocus: boolean }) => {\n        restoreFocusAfterEditRef.current = restoreFocus;\n        setInvalid(false);\n        setEditing(false);\n      },\n      [setEditing]\n    );\n\n    const commitDraft = useCallback(\n      ({\n        cancelOnInvalid,\n        reason,\n        restoreFocus,\n      }: {\n        cancelOnInvalid: boolean;\n        reason: TimecodeFieldCommitReason;\n        restoreFocus: boolean;\n      }) => {\n        const parsedSeconds = parseTimecode(draftValue, effectiveParseOptions);\n\n        if (parsedSeconds === null) {\n          if (cancelOnInvalid) {\n            cancelEditing({ restoreFocus });\n            return;\n          }\n\n          setInvalid(true);\n          return;\n        }\n\n        const time = fromSeconds(parsedSeconds, commitTimebase);\n        restoreFocusAfterEditRef.current = restoreFocus;\n        setInvalid(false);\n        setEditing(false);\n        void onCommit(parsedSeconds, {\n          reason,\n          seconds: parsedSeconds,\n          text: draftValue,\n          time,\n        });\n      },\n      [cancelEditing, commitTimebase, draftValue, effectiveParseOptions, onCommit, setEditing]\n    );\n\n    const hintId = useMemo(() => `${descriptionId}-hint`, [descriptionId]);\n    const errorId = useMemo(() => `${descriptionId}-error`, [descriptionId]);\n    const describedBy = useMemo(\n      () => (invalid ? `${hintId} ${errorId}` : hintId),\n      [errorId, hintId, invalid]\n    );\n    const accessibleValue = useMemo(\n      () => valueLabel ?? formattedValue,\n      [formattedValue, valueLabel]\n    );\n    const rootStyle = useMemo(\n      () =>\n        editing && (reservedWidth !== undefined || style?.width !== undefined)\n          ? { ...style, width: reservedWidth ?? style?.width }\n          : style,\n      [editing, reservedWidth, style]\n    );\n    const context = useMemo<TimecodeFieldContextValue>(\n      () => ({\n        accessibleValue,\n        ariaLabel,\n        cancelEditing,\n        commitDraft,\n        describedBy,\n        disabled,\n        displaySegments,\n        draftValue,\n        editing,\n        errorId,\n        formattedValue,\n        hintId,\n        inputRef,\n        invalid,\n        setDraftValue,\n        setInvalid,\n        startEditing,\n        triggerRef,\n      }),\n      [\n        accessibleValue,\n        ariaLabel,\n        cancelEditing,\n        commitDraft,\n        describedBy,\n        disabled,\n        displaySegments,\n        draftValue,\n        editing,\n        errorId,\n        formattedValue,\n        hintId,\n        invalid,\n        startEditing,\n      ]\n    );\n\n    return (\n      <TimecodeFieldContext.Provider value={context}>\n        <span\n          ref={ref}\n          {...props}\n          className={mergeClassNames('timecode-field', className)}\n          data-slot=\"timecode-field\"\n          style={rootStyle}\n        >\n          {children ?? (\n            <>\n              <TimecodeFieldTrigger />\n              <TimecodeFieldInput />\n            </>\n          )}\n        </span>\n      </TimecodeFieldContext.Provider>\n    );\n  }\n);\n\nTimecodeFieldRoot.displayName = 'TimecodeField.Root';\n\n/**\n * Compact timecode field parts.\n *\n * `TimecodeField.Root` owns editing state. `TimecodeField.Trigger` renders the\n * compact displayed value, and `TimecodeField.Input` renders the temporary\n * `TimecodeInput` used for typed edits.\n */\n// oxlint-disable-next-line react-refresh/only-export-components\nexport const TimecodeField = {\n  /** Root state manager that swaps between compact display and typed editing. */\n  Root: TimecodeFieldRoot,\n  /** Button that displays the formatted timecode and starts editing on activation. */\n  Trigger: TimecodeFieldTrigger,\n  /** Temporary `TimecodeInput` rendered while the field is actively editing. */\n  Input: TimecodeFieldInput,\n};\n"],"mappings":"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"}