@bazza-ui/react 0.0.0 → 0.1.0-canary.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/ListboxStore-BtcTXpzi.d.cts +351 -0
  2. package/dist/ListboxStore-DPqpLlAL.d.ts +351 -0
  3. package/dist/adapters/index.cjs +2 -0
  4. package/dist/adapters/index.cjs.map +1 -0
  5. package/dist/adapters/index.d.cts +363 -0
  6. package/dist/adapters/index.d.ts +363 -0
  7. package/dist/adapters/index.js +2 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/chunk-4C666HHU.js +2 -0
  10. package/dist/chunk-4C666HHU.js.map +1 -0
  11. package/dist/chunk-AVZ64JQ3.js +2 -0
  12. package/dist/chunk-AVZ64JQ3.js.map +1 -0
  13. package/dist/chunk-BGJJC6GX.cjs +2 -0
  14. package/dist/chunk-BGJJC6GX.cjs.map +1 -0
  15. package/dist/chunk-FWWOE2SW.cjs +2 -0
  16. package/dist/chunk-FWWOE2SW.cjs.map +1 -0
  17. package/dist/chunk-JSPKF52O.cjs +2 -0
  18. package/dist/chunk-JSPKF52O.cjs.map +1 -0
  19. package/dist/chunk-KWGD24VS.js +2 -0
  20. package/dist/chunk-KWGD24VS.js.map +1 -0
  21. package/dist/chunk-M4G6J7DP.cjs +2 -0
  22. package/dist/chunk-M4G6J7DP.cjs.map +1 -0
  23. package/dist/chunk-WKAPAKUL.js +2 -0
  24. package/dist/chunk-WKAPAKUL.js.map +1 -0
  25. package/dist/combobox/index.cjs +2 -0
  26. package/dist/combobox/index.cjs.map +1 -0
  27. package/dist/combobox/index.d.cts +1039 -0
  28. package/dist/combobox/index.d.ts +1039 -0
  29. package/dist/combobox/index.js +2 -0
  30. package/dist/combobox/index.js.map +1 -0
  31. package/dist/command-score-Dgo3ZS3Z.d.ts +36 -0
  32. package/dist/command-score-YjNr3ZWi.d.cts +36 -0
  33. package/dist/context-menu/index.cjs +2 -0
  34. package/dist/context-menu/index.cjs.map +1 -0
  35. package/dist/context-menu/index.d.cts +658 -0
  36. package/dist/context-menu/index.d.ts +658 -0
  37. package/dist/context-menu/index.js +2 -0
  38. package/dist/context-menu/index.js.map +1 -0
  39. package/dist/data-surface-B-eIGTBi.d.cts +678 -0
  40. package/dist/data-surface-D1OilMDu.d.ts +678 -0
  41. package/dist/dropdown-menu/index.cjs +2 -0
  42. package/dist/dropdown-menu/index.cjs.map +1 -0
  43. package/dist/dropdown-menu/index.d.cts +700 -0
  44. package/dist/dropdown-menu/index.d.ts +700 -0
  45. package/dist/dropdown-menu/index.js +2 -0
  46. package/dist/dropdown-menu/index.js.map +1 -0
  47. package/dist/events-BPr8sRGH.d.cts +166 -0
  48. package/dist/events-BPr8sRGH.d.ts +166 -0
  49. package/dist/input-BoIK003I.d.cts +41 -0
  50. package/dist/input-DF7D8YzW.d.ts +41 -0
  51. package/dist/internal/listbox/index.cjs +2 -0
  52. package/dist/internal/listbox/index.cjs.map +1 -0
  53. package/dist/internal/listbox/index.d.cts +269 -0
  54. package/dist/internal/listbox/index.d.ts +269 -0
  55. package/dist/internal/listbox/index.js +2 -0
  56. package/dist/internal/listbox/index.js.map +1 -0
  57. package/dist/internal/popup-menu/index.cjs +2 -0
  58. package/dist/internal/popup-menu/index.cjs.map +1 -0
  59. package/dist/internal/popup-menu/index.d.cts +846 -0
  60. package/dist/internal/popup-menu/index.d.ts +846 -0
  61. package/dist/internal/popup-menu/index.js +2 -0
  62. package/dist/internal/popup-menu/index.js.map +1 -0
  63. package/dist/item-equality-B6TbXlBT.d.cts +7 -0
  64. package/dist/item-equality-B6TbXlBT.d.ts +7 -0
  65. package/dist/loading-DphSt8MY.d.cts +27 -0
  66. package/dist/loading-TsgH6v92.d.ts +27 -0
  67. package/dist/select/index.cjs +2 -0
  68. package/dist/select/index.cjs.map +1 -0
  69. package/dist/select/index.d.cts +927 -0
  70. package/dist/select/index.d.ts +927 -0
  71. package/dist/select/index.js +2 -0
  72. package/dist/select/index.js.map +1 -0
  73. package/dist/separator-B4Ot84B0.d.ts +748 -0
  74. package/dist/separator-BmbUeeaT.d.cts +748 -0
  75. package/dist/types-9vS1uLIK.d.cts +1557 -0
  76. package/dist/types-lQCIvWW8.d.ts +1557 -0
  77. package/dist/use-listbox-item-BIi4eRPI.d.cts +182 -0
  78. package/dist/use-listbox-item-BIi4eRPI.d.ts +182 -0
  79. package/dist/video-player/index.cjs +3 -0
  80. package/dist/video-player/index.cjs.map +1 -0
  81. package/dist/video-player/index.d.cts +1379 -0
  82. package/dist/video-player/index.d.ts +1379 -0
  83. package/dist/video-player/index.js +3 -0
  84. package/dist/video-player/index.js.map +1 -0
  85. package/package.json +56 -12
  86. package/dist/index.d.ts +0 -2
  87. package/dist/index.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/video-player/contexts/video-player-context.ts","../../src/video-player/hooks/use-video-player.ts","../../src/video-player/index.parts.ts","../../src/video-player/components/buffered-indicator/buffered-indicator.tsx","../../src/video-player/components/captions/captions.data-attributes.ts","../../src/video-player/components/captions/captions.tsx","../../src/video-player/components/captions-button/captions-button.tsx","../../src/video-player/components/captions-menu/captions-menu.tsx","../../src/video-player/components/controls/controls.data-attributes.ts","../../src/video-player/components/controls/controls.tsx","../../src/video-player/hooks/use-transition-status.ts","../../src/video-player/components/fullscreen-button/fullscreen-button.tsx","../../src/video-player/components/mute-button/mute-button.tsx","../../src/video-player/components/overlay/overlay.data-attributes.ts","../../src/video-player/components/overlay/overlay.tsx","../../src/video-player/components/picture-in-picture-button/picture-in-picture-button.tsx","../../src/video-player/components/play-button/play-button.tsx","../../src/video-player/components/playback-rate-button/playback-rate-button.tsx","../../src/video-player/components/playback-rate-menu/playback-rate-menu.tsx","../../src/video-player/components/portal/portal.tsx","../../src/video-player/components/poster/poster.tsx","../../src/video-player/components/quality-menu/quality-menu.tsx","../../src/video-player/components/root/root.data-attributes.ts","../../src/video-player/components/root/root.tsx","../../src/video-player/hooks/use-keyboard-shortcuts.ts","../../src/video-player/components/seek-slider/seek-slider.css-vars.ts","../../src/video-player/components/seek-slider/seek-slider.data-attributes.ts","../../src/video-player/components/seek-slider/seek-slider.tsx","../../src/video-player/components/seek-slider/seek-slider-preview-thumb.data-attributes.ts","../../src/video-player/components/thumbnail/thumbnail.data-attributes.ts","../../src/video-player/components/thumbnail/thumbnail.tsx","../../src/video-player/components/time-display/time-display.data-attributes.ts","../../src/video-player/components/time-display/time-display.tsx","../../src/video-player/components/track/track.tsx","../../src/video-player/components/video/video.tsx","../../src/video-player/components/volume-slider/volume-slider.css-vars.ts","../../src/video-player/components/volume-slider/volume-slider.data-attributes.ts","../../src/video-player/components/volume-slider/volume-slider.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport type { VideoPlayerContextValue } from '../types.js'\n\nexport const VideoPlayerContext =\n React.createContext<VideoPlayerContextValue | null>(null)\n\nexport function useVideoPlayerContext(\n component: string,\n): VideoPlayerContextValue {\n const context = React.useContext(VideoPlayerContext)\n if (!context) {\n throw new Error(\n `<VideoPlayer.${component}> must be used within <VideoPlayer.Root>`,\n )\n }\n return context\n}\n","'use client'\n\nimport { useVideoPlayerContext } from '../contexts/video-player-context.js'\nimport type { VideoPlayerContextValue } from '../types.js'\n\n/**\n * Hook to access the VideoPlayer context from custom components.\n *\n * @example\n * ```tsx\n * function CustomControl() {\n * const { playing, toggle, currentTime, duration } = useVideoPlayer()\n *\n * return (\n * <div>\n * {playing ? 'Playing' : 'Paused'} - {currentTime}s / {duration}s\n * <button onClick={toggle}>Toggle</button>\n * </div>\n * )\n * }\n * ```\n */\nexport function useVideoPlayer(): VideoPlayerContextValue {\n return useVideoPlayerContext('useVideoPlayer')\n}\n","// ============================================================================\n// VideoPlayer Composable Parts\n// ============================================================================\n//\n// Import like: import * as VideoPlayer from './video-player/index.parts.js'\n//\n// Usage:\n// <VideoPlayer.Root>\n// <VideoPlayer.Video src=\"...\" />\n// <VideoPlayer.Controls>\n// <VideoPlayer.PlayButton />\n// <VideoPlayer.SeekSlider />\n// <VideoPlayer.TimeDisplay />\n// </VideoPlayer.Controls>\n// </VideoPlayer.Root>\n//\n\nexport { BufferedIndicator } from './components/buffered-indicator/buffered-indicator.js'\nexport { CaptionsDataAttributes } from './components/captions/captions.data-attributes.js'\nexport { Captions } from './components/captions/captions.js'\n// Captions\nexport { CaptionsButton } from './components/captions-button/captions-button.js'\nexport {\n CaptionsMenu,\n CaptionsMenuItem,\n} from './components/captions-menu/captions-menu.js'\nexport { ControlsDataAttributes } from './components/controls/controls.data-attributes.js'\nexport { Controls } from './components/controls/controls.js'\n// Display Controls\nexport { FullscreenButton } from './components/fullscreen-button/fullscreen-button.js'\nexport { MuteButton } from './components/mute-button/mute-button.js'\nexport { OverlayDataAttributes } from './components/overlay/overlay.data-attributes.js'\nexport { Overlay } from './components/overlay/overlay.js'\nexport { PictureInPictureButton } from './components/picture-in-picture-button/picture-in-picture-button.js'\n// Playback Controls\nexport { PlayButton } from './components/play-button/play-button.js'\n// Playback Rate\nexport { PlaybackRateButton } from './components/playback-rate-button/playback-rate-button.js'\nexport {\n PlaybackRateMenu,\n PlaybackRateMenuItem,\n} from './components/playback-rate-menu/playback-rate-menu.js'\n// Layout\nexport { Portal } from './components/portal/portal.js'\nexport { Poster } from './components/poster/poster.js'\n// Quality\nexport {\n QualityMenu,\n QualityMenuItem,\n} from './components/quality-menu/quality-menu.js'\n// Data Attributes & CSS Variables\nexport { RootDataAttributes } from './components/root/root.data-attributes.js'\n// Core\nexport { VideoPlayerRoot as Root } from './components/root/root.js'\nexport { SeekSliderCssVars } from './components/seek-slider/seek-slider.css-vars.js'\nexport { SeekSliderDataAttributes } from './components/seek-slider/seek-slider.data-attributes.js'\nexport {\n SeekSlider,\n SeekSliderBuffered,\n SeekSliderControl,\n SeekSliderHover,\n SeekSliderPreviewThumb,\n SeekSliderPreviewTooltip,\n SeekSliderPreviewTooltipPopup,\n SeekSliderPreviewTooltipPortal,\n SeekSliderPreviewTooltipPositioner,\n SeekSliderProgress,\n SeekSliderThumb,\n SeekSliderTrack,\n} from './components/seek-slider/seek-slider.js'\nexport { SeekSliderPreviewThumbDataAttributes } from './components/seek-slider/seek-slider-preview-thumb.data-attributes.js'\nexport { ThumbnailDataAttributes } from './components/thumbnail/thumbnail.data-attributes.js'\nexport { Thumbnail } from './components/thumbnail/thumbnail.js'\nexport { TimeDisplayDataAttributes } from './components/time-display/time-display.data-attributes.js'\nexport { TimeDisplay } from './components/time-display/time-display.js'\nexport { Track } from './components/track/track.js'\nexport { Video } from './components/video/video.js'\nexport { VolumeSliderCssVars } from './components/volume-slider/volume-slider.css-vars.js'\nexport { VolumeSliderDataAttributes } from './components/volume-slider/volume-slider.data-attributes.js'\n// Audio Controls\nexport {\n VolumeSlider,\n VolumeSliderControl,\n VolumeSliderRange,\n VolumeSliderThumb,\n VolumeSliderTrack,\n} from './components/volume-slider/volume-slider.js'\nexport {\n type TransitionStatus,\n type UseTransitionStatusOptions,\n type UseTransitionStatusReturn,\n useTransitionStatus,\n} from './hooks/use-transition-status.js'\n// Hooks\nexport { useVideoPlayer } from './hooks/use-video-player.js'\n// Types\nexport type {\n PlaybackIntent,\n PlaybackStatus,\n RenderProp,\n TrackInfo,\n VideoPlayerActions,\n VideoPlayerContextValue,\n VideoPlayerRootProps,\n VideoPlayerState,\n VideoQuality,\n VideoTextTrack,\n} from './types.js'\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\n\n// ============================================================================\n// BufferedIndicator Props\n// ============================================================================\n\nexport interface BufferedIndicatorProps\n extends React.ComponentPropsWithRef<'div'> {\n render?: RenderProp<BufferedIndicatorRenderProps, BufferedIndicatorState>\n}\n\nexport interface BufferedIndicatorRenderProps {\n ref: React.Ref<HTMLElement>\n style: React.CSSProperties\n 'aria-hidden': true\n}\n\nexport interface BufferedIndicatorState {\n buffered: TimeRanges | null\n duration: number\n bufferedPercentage: number\n bufferedEnd: number\n}\n\n// ============================================================================\n// BufferedIndicator Component\n// ============================================================================\n\nexport const BufferedIndicator = React.forwardRef<\n HTMLDivElement,\n BufferedIndicatorProps\n>(function BufferedIndicator(props, forwardedRef) {\n const { render, ...divProps } = props\n const context = useVideoPlayerContext('BufferedIndicator')\n\n // Calculate buffered end position (for progress bar display)\n const bufferedEnd = React.useMemo(() => {\n if (!context.buffered || context.buffered.length === 0) return 0\n\n // Find the buffer range that contains current playback position\n for (let i = 0; i < context.buffered.length; i++) {\n if (\n context.buffered.start(i) <= context.currentTime &&\n context.currentTime <= context.buffered.end(i)\n ) {\n return context.buffered.end(i)\n }\n }\n\n // Fallback to end of first range\n return context.buffered.end(0)\n }, [context.buffered, context.currentTime])\n\n const bufferedPercentage =\n context.duration > 0 ? (bufferedEnd / context.duration) * 100 : 0\n\n const state: BufferedIndicatorState = {\n buffered: context.buffered,\n duration: context.duration,\n bufferedPercentage,\n bufferedEnd,\n }\n\n // CSS custom properties for styling\n const style = {\n '--buffered-percentage': `${bufferedPercentage}%`,\n '--buffered-end': bufferedEnd,\n ...divProps.style,\n } as React.CSSProperties\n\n const renderProps: BufferedIndicatorRenderProps = {\n ref: forwardedRef,\n style,\n 'aria-hidden': true,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <div ref={forwardedRef} aria-hidden=\"true\" {...divProps} style={style} />\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace BufferedIndicator {\n export type Props = BufferedIndicatorProps\n export type State = BufferedIndicatorState\n}\n","export enum CaptionsDataAttributes {\n /** Applied when there are active caption cues being displayed. */\n active = 'data-active',\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { CaptionsDataAttributes } from './captions.data-attributes.js'\n\n// ============================================================================\n// Captions Props\n// ============================================================================\n\nexport interface CaptionsProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {\n /**\n * Custom render function for full control over caption rendering.\n * Receives renderProps (ref, aria attributes, data attributes) and state (cues, text).\n */\n render?: RenderProp<CaptionsRenderProps, CaptionsState>\n /**\n * Children to render instead of default cue text.\n * Use the render prop or useVideoPlayer() hook to access cue data.\n */\n children?: React.ReactNode\n}\n\nexport interface CaptionsRenderProps {\n ref: React.Ref<HTMLDivElement>\n /** Announces caption changes to screen readers */\n 'aria-live': 'polite'\n /** Ensures the full caption is read, not just changes */\n 'aria-atomic': true\n /** Role for accessibility */\n role: 'status'\n /** Allow clicks to pass through to video */\n style: React.CSSProperties\n /** Applied when there are active cues */\n [CaptionsDataAttributes.active]?: boolean\n}\n\nexport interface CaptionsState {\n /** Whether there are currently active cues */\n active: boolean\n /** Combined text from all active cues (joined with newlines) */\n cueText: string\n /** Raw VTTCue objects for advanced use cases */\n cues: VTTCue[]\n}\n\n// ============================================================================\n// Captions Component\n// ============================================================================\n\n/**\n * Renders caption text with full styling control and accessibility support.\n * Uses aria-live=\"polite\" to announce caption changes to screen readers.\n *\n * By default, renders the cue text directly. Use the render prop or children\n * for custom rendering.\n *\n * @example\n * // Default rendering with custom styles\n * <VideoPlayer.Captions\n * className=\"absolute bottom-16 bg-black/80 text-white px-4 py-2 rounded\"\n * />\n *\n * @example\n * // Custom rendering with render prop\n * <VideoPlayer.Captions\n * render={(props, state) => (\n * <div {...props} className=\"my-custom-captions\">\n * {state.cues.map((cue, i) => (\n * <p key={i}>{cue.text}</p>\n * ))}\n * </div>\n * )}\n * />\n */\nexport const Captions = React.forwardRef<HTMLDivElement, CaptionsProps>(\n function Captions(props, forwardedRef) {\n const { render, children, ...divProps } = props\n const context = useVideoPlayerContext('Captions')\n\n // Build state from context\n const cues = context.activeCues\n const cueText = cues.map((cue) => cue.text).join('\\n')\n const active = cues.length > 0\n\n const state: CaptionsState = {\n active,\n cueText,\n cues,\n }\n\n const renderProps: CaptionsRenderProps = {\n ref: forwardedRef,\n 'aria-live': 'polite',\n 'aria-atomic': true,\n role: 'status',\n style: { pointerEvents: 'none' },\n [CaptionsDataAttributes.active]: active || undefined,\n }\n\n // Custom render function\n if (render) {\n return render(renderProps, state)\n }\n\n // Custom children (user controls content)\n if (children) {\n return (\n <div {...renderProps} {...divProps}>\n {children}\n </div>\n )\n }\n\n // Default rendering: show cue text\n return (\n <div {...renderProps} {...divProps}>\n {cueText}\n </div>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Captions {\n export type Props = CaptionsProps\n export type State = CaptionsState\n export type RenderProps = CaptionsRenderProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { CaptionsButtonDataAttributes } from './captions-button.data-attributes.js'\n\n// ============================================================================\n// CaptionsButton Props\n// ============================================================================\n\nexport interface CaptionsButtonProps\n extends React.ComponentPropsWithRef<'button'> {\n render?: RenderProp<CaptionsButtonRenderProps, CaptionsButtonState>\n}\n\nexport interface CaptionsButtonRenderProps {\n ref: React.Ref<HTMLButtonElement>\n type: 'button'\n 'aria-label': string\n 'aria-pressed': boolean\n disabled: boolean\n [CaptionsButtonDataAttributes.active]?: boolean\n [CaptionsButtonDataAttributes.available]?: boolean\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nexport interface CaptionsButtonState {\n active: boolean\n available: boolean\n trackCount: number\n}\n\n// ============================================================================\n// CaptionsButton Component\n// ============================================================================\n\nexport const CaptionsButton = React.forwardRef<\n HTMLButtonElement,\n CaptionsButtonProps\n>(function CaptionsButton(props, forwardedRef) {\n const { render, onClick, ...buttonProps } = props\n const context = useVideoPlayerContext('CaptionsButton')\n\n const available = context.registeredTracks.length > 0\n const active = context.activeTextTrack !== null\n\n const state: CaptionsButtonState = {\n active,\n available,\n trackCount: context.registeredTracks.length,\n }\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n if (active) {\n // Turn off captions\n context.setTextTrack(null)\n } else if (context.registeredTracks.length > 0) {\n // Turn on first available track (use the TextTrack reference from TrackInfo)\n const firstTrack = context.registeredTracks[0]\n if (firstTrack?.textTrack) {\n context.setTextTrack(firstTrack.textTrack)\n }\n }\n }\n },\n [onClick, context, active],\n )\n\n const renderProps: CaptionsButtonRenderProps = {\n ref: forwardedRef,\n type: 'button',\n 'aria-label': active ? 'Disable captions' : 'Enable captions',\n 'aria-pressed': active,\n disabled: !available,\n [CaptionsButtonDataAttributes.active]: active || undefined,\n [CaptionsButtonDataAttributes.available]: available || undefined,\n onClick: handleClick,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return <button {...renderProps} {...buttonProps} />\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace CaptionsButton {\n export type Props = CaptionsButtonProps\n export type State = CaptionsButtonState\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp, TrackInfo } from '../../types.js'\nimport {\n CaptionsMenuDataAttributes,\n CaptionsMenuItemDataAttributes,\n} from './captions-menu.data-attributes.js'\n\n// ============================================================================\n// CaptionsMenu Props\n// ============================================================================\n\nexport interface CaptionsMenuProps extends React.ComponentPropsWithRef<'div'> {\n render?: RenderProp<CaptionsMenuRenderProps, CaptionsMenuState>\n}\n\nexport interface CaptionsMenuRenderProps {\n ref: React.Ref<HTMLDivElement>\n role: 'menu'\n 'aria-label': string\n [CaptionsMenuDataAttributes.active]?: boolean\n}\n\nexport interface CaptionsMenuState {\n registeredTracks: TrackInfo[]\n activeTextTrack: TextTrack | null\n}\n\n// ============================================================================\n// CaptionsMenu Component\n// ============================================================================\n\nexport const CaptionsMenu = React.forwardRef<HTMLDivElement, CaptionsMenuProps>(\n function CaptionsMenu(props, forwardedRef) {\n const { render, children, ...divProps } = props\n const context = useVideoPlayerContext('CaptionsMenu')\n\n const state: CaptionsMenuState = {\n registeredTracks: context.registeredTracks,\n activeTextTrack: context.activeTextTrack,\n }\n\n const renderProps: CaptionsMenuRenderProps = {\n ref: forwardedRef,\n role: 'menu',\n 'aria-label': 'Captions',\n [CaptionsMenuDataAttributes.active]:\n context.activeTextTrack !== null || undefined,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n // Default render: list of track options with \"Off\" option\n return (\n <div {...renderProps} {...divProps}>\n {children ?? (\n <>\n <CaptionsMenuItem track={null}>Off</CaptionsMenuItem>\n {context.registeredTracks.map((trackInfo) => (\n <CaptionsMenuItem key={trackInfo.id} track={trackInfo.textTrack}>\n {trackInfo.label}\n </CaptionsMenuItem>\n ))}\n </>\n )}\n </div>\n )\n },\n)\n\n// ============================================================================\n// CaptionsMenuItem\n// ============================================================================\n\nexport interface CaptionsMenuItemProps\n extends React.ComponentPropsWithRef<'button'> {\n track: TextTrack | null\n}\n\nexport const CaptionsMenuItem = React.forwardRef<\n HTMLButtonElement,\n CaptionsMenuItemProps\n>(function CaptionsMenuItem(props, forwardedRef) {\n const { track, onClick, children, ...buttonProps } = props\n const context = useVideoPlayerContext('CaptionsMenuItem')\n\n const isActive = context.activeTextTrack === track\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.setTextTrack(track)\n }\n },\n [onClick, context, track],\n )\n\n return (\n <button\n ref={forwardedRef}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isActive}\n {...{ [CaptionsMenuItemDataAttributes.active]: isActive || undefined }}\n {...buttonProps}\n onClick={handleClick}\n >\n {children}\n </button>\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace CaptionsMenu {\n export type Props = CaptionsMenuProps\n export type State = CaptionsMenuState\n export type ItemProps = CaptionsMenuItemProps\n}\n","export enum ControlsDataAttributes {\n /** Applied when the controls are visible. */\n open = 'data-open',\n /** Applied when the controls are hidden. */\n closed = 'data-closed',\n /** Applied when the player is idle (no user interaction). */\n idle = 'data-idle',\n /** Applied when the video is playing. */\n playing = 'data-playing',\n /** Applied when the video is paused. */\n paused = 'data-paused',\n /** Applied when the video has ended. */\n ended = 'data-ended',\n /** Applied on the first frame when entering. Use for CSS enter animations. */\n startingStyle = 'data-starting-style',\n /** Applied during exit animation. Use for CSS exit animations. */\n endingStyle = 'data-ending-style',\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport { useTransitionStatus } from '../../hooks/use-transition-status.js'\nimport type { RenderProp } from '../../types.js'\nimport { ControlsDataAttributes } from './controls.data-attributes.js'\n\n// ============================================================================\n// Controls Props\n// ============================================================================\n\nexport interface ControlsProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {\n /**\n * Delay before hiding after player becomes idle (ms).\n * Defaults to Root's idleTimeout. Set to 0 to disable auto-hide.\n */\n idleTimeout?: number\n\n /**\n * Keep the element always mounted in the DOM, even when closed.\n * Only needed for JavaScript animation libraries (e.g., Framer Motion).\n * CSS transitions and animations work automatically without this.\n * @default false\n */\n keepMounted?: boolean\n\n render?: RenderProp<ControlsRenderProps, ControlsState>\n children?: React.ReactNode\n}\n\nexport interface ControlsRenderProps {\n ref: React.Ref<HTMLDivElement>\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void\n [ControlsDataAttributes.open]?: boolean\n [ControlsDataAttributes.closed]?: boolean\n [ControlsDataAttributes.idle]?: boolean\n [ControlsDataAttributes.playing]?: boolean\n [ControlsDataAttributes.paused]?: boolean\n [ControlsDataAttributes.ended]?: boolean\n [ControlsDataAttributes.startingStyle]?: boolean\n [ControlsDataAttributes.endingStyle]?: boolean\n}\n\nexport interface ControlsState {\n /** Whether the controls are currently visible */\n open: boolean\n idle: boolean\n playing: boolean\n paused: boolean\n ended: boolean\n}\n\n// ============================================================================\n// Controls Component\n// ============================================================================\n\nexport const Controls = React.forwardRef<HTMLDivElement, ControlsProps>(\n function Controls(props, forwardedRef) {\n const {\n idleTimeout: idleTimeoutProp,\n keepMounted = false,\n render,\n children,\n ...divProps\n } = props\n\n const context = useVideoPlayerContext('Controls')\n\n // Use component's idleTimeout if set, otherwise use context's\n const effectiveIdleTimeout = idleTimeoutProp ?? context.idleTimeout\n\n // Calculate visibility:\n // - Open when idleTimeout is 0 (disabled)\n // - Open when not idle\n const open = effectiveIdleTimeout === 0 || !context.idle\n\n // Handle transition status for animations\n const { mounted, transitionStatus, elementRef } = useTransitionStatus({\n open,\n keepMounted,\n })\n\n // Compose refs\n const composedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n ;(elementRef as React.MutableRefObject<HTMLElement | null>).current =\n node\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef, elementRef],\n )\n\n const { onClick, ...restDivProps } = divProps\n\n // Stop click propagation to prevent Overlay from toggling play/pause\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n event.stopPropagation()\n onClick?.(event)\n },\n [onClick],\n )\n\n const state: ControlsState = {\n open,\n idle: context.idle,\n playing: context.playing,\n paused: context.paused,\n ended: context.ended,\n }\n\n const renderProps: ControlsRenderProps = {\n ref: composedRef,\n onClick: handleClick,\n [ControlsDataAttributes.open]: open || undefined,\n [ControlsDataAttributes.closed]: !open || undefined,\n [ControlsDataAttributes.idle]: context.idle || undefined,\n [ControlsDataAttributes.playing]: context.playing || undefined,\n [ControlsDataAttributes.paused]: context.paused || undefined,\n [ControlsDataAttributes.ended]: context.ended || undefined,\n [ControlsDataAttributes.startingStyle]:\n transitionStatus === 'starting' || undefined,\n [ControlsDataAttributes.endingStyle]:\n transitionStatus === 'ending' || undefined,\n }\n\n if (!mounted) {\n return null\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <div {...renderProps} {...restDivProps}>\n {children}\n </div>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Controls {\n export type Props = ControlsProps\n export type State = ControlsState\n export type RenderProps = ControlsRenderProps\n}\n","'use client'\n\nimport * as React from 'react'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type TransitionStatus = 'starting' | 'ending' | undefined\n\nexport interface UseTransitionStatusOptions {\n /**\n * Whether the element should be visible/open.\n */\n open: boolean\n /**\n * Keep the element always mounted in the DOM, even when closed.\n * Only needed for JavaScript animation libraries (e.g., Framer Motion).\n * CSS transitions and animations work automatically without this.\n * @default false\n */\n keepMounted?: boolean\n}\n\nexport interface UseTransitionStatusReturn {\n /**\n * Whether the element should be rendered in the DOM.\n * Stays true during exit animations.\n */\n mounted: boolean\n /**\n * Current transition status:\n * - 'starting': First frame of enter animation\n * - 'ending': Exit animation in progress\n * - undefined: Idle state\n */\n transitionStatus: TransitionStatus\n /**\n * Ref to attach to the animated element.\n * Used to detect when CSS animations/transitions complete.\n */\n elementRef: React.RefObject<HTMLElement | null>\n}\n\n// ============================================================================\n// Utility: Wait for Animations\n// ============================================================================\n\n/**\n * Returns a promise that resolves when all CSS animations and transitions\n * on the element and its descendants have completed.\n */\nfunction waitForAnimations(element: HTMLElement): Promise<void> {\n // Collect animations from the element and all descendants\n const animations = [\n ...element.getAnimations(),\n ...Array.from(element.querySelectorAll('*')).flatMap((el) =>\n (el as HTMLElement).getAnimations(),\n ),\n ]\n\n if (animations.length === 0) {\n return Promise.resolve()\n }\n return Promise.all(animations.map((a) => a.finished))\n .then(() => {})\n .catch(() => {\n // Animation was cancelled (e.g., element removed or animation interrupted)\n })\n}\n\n// ============================================================================\n// Hook: useTransitionStatus\n// ============================================================================\n\nexport function useTransitionStatus(\n options: UseTransitionStatusOptions,\n): UseTransitionStatusReturn {\n const { open, keepMounted = false } = options\n\n const [mounted, setMounted] = React.useState(open || keepMounted)\n const [transitionStatus, setTransitionStatus] =\n React.useState<TransitionStatus>(open ? 'starting' : undefined)\n\n const elementRef = React.useRef<HTMLElement | null>(null)\n\n // Track if we're currently waiting for animations\n const waitingForAnimationsRef = React.useRef(false)\n\n // Handle open → true (enter)\n React.useEffect(() => {\n if (open) {\n // Cancel any pending exit\n waitingForAnimationsRef.current = false\n\n setMounted(true)\n setTransitionStatus('starting')\n\n // Clear starting style after first paint (double RAF for reliability)\n const raf = requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setTransitionStatus(undefined)\n })\n })\n\n return () => cancelAnimationFrame(raf)\n }\n }, [open])\n\n // Handle open → false (exit)\n React.useEffect(() => {\n if (!open && mounted && !waitingForAnimationsRef.current) {\n setTransitionStatus('ending')\n\n const element = elementRef.current\n\n if (!element) {\n // No element ref, unmount immediately\n setTransitionStatus(undefined)\n if (!keepMounted) {\n setMounted(false)\n }\n return\n }\n\n waitingForAnimationsRef.current = true\n\n // Wait a frame for the browser to process style changes and start animations\n const raf = requestAnimationFrame(() => {\n // Double RAF for reliability (like enter animation)\n requestAnimationFrame(() => {\n waitForAnimations(element).then(() => {\n // Check if we're still supposed to be unmounting\n // (user might have re-opened during animation)\n if (!waitingForAnimationsRef.current) return\n\n waitingForAnimationsRef.current = false\n setTransitionStatus(undefined)\n\n if (!keepMounted) {\n setMounted(false)\n }\n })\n })\n })\n\n return () => {\n cancelAnimationFrame(raf)\n }\n }\n }, [open, mounted, keepMounted])\n\n // Handle keepMounted change\n React.useEffect(() => {\n if (keepMounted && !mounted && !open) {\n setMounted(true)\n }\n }, [keepMounted, mounted, open])\n\n return {\n mounted: mounted || keepMounted,\n transitionStatus,\n elementRef,\n }\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { FullscreenButtonDataAttributes } from './fullscreen-button.data-attributes.js'\n\n// ============================================================================\n// FullscreenButton Props\n// ============================================================================\n\nexport interface FullscreenButtonProps\n extends Omit<React.ComponentPropsWithRef<'button'>, 'children'> {\n render?: RenderProp<FullscreenButtonRenderProps, FullscreenButtonState>\n children?: React.ReactNode\n}\n\nexport interface FullscreenButtonRenderProps {\n ref: React.Ref<HTMLButtonElement>\n type: 'button'\n 'aria-label': string\n 'aria-pressed': boolean\n disabled: boolean\n [FullscreenButtonDataAttributes.fullscreen]?: boolean\n [FullscreenButtonDataAttributes.supported]?: boolean\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nexport interface FullscreenButtonState {\n fullscreen: boolean\n supported: boolean\n}\n\n// ============================================================================\n// FullscreenButton Component\n// ============================================================================\n\nexport const FullscreenButton = React.forwardRef<\n HTMLButtonElement,\n FullscreenButtonProps\n>(function FullscreenButton(props, forwardedRef) {\n const { render, onClick, children, ...buttonProps } = props\n const context = useVideoPlayerContext('FullscreenButton')\n\n // Defer to after hydration to avoid mismatch\n const [supported, setSupported] = React.useState(false)\n React.useEffect(() => {\n setSupported('fullscreenEnabled' in document && document.fullscreenEnabled)\n }, [])\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.toggleFullscreen()\n }\n },\n [onClick, context],\n )\n\n const state: FullscreenButtonState = {\n fullscreen: context.fullscreen,\n supported,\n }\n\n const renderProps: FullscreenButtonRenderProps = {\n ref: forwardedRef,\n type: 'button',\n 'aria-label': context.fullscreen ? 'Exit fullscreen' : 'Enter fullscreen',\n 'aria-pressed': context.fullscreen,\n disabled: !supported,\n [FullscreenButtonDataAttributes.fullscreen]:\n context.fullscreen || undefined,\n [FullscreenButtonDataAttributes.supported]: supported || undefined,\n onClick: handleClick,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <button {...renderProps} {...buttonProps}>\n {children}\n </button>\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace FullscreenButton {\n export type Props = FullscreenButtonProps\n export type State = FullscreenButtonState\n export type RenderProps = FullscreenButtonRenderProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { MuteButtonDataAttributes } from './mute-button.data-attributes.js'\n\n// ============================================================================\n// MuteButton Props\n// ============================================================================\n\nexport interface MuteButtonProps extends React.ComponentPropsWithRef<'button'> {\n render?: RenderProp<MuteButtonRenderProps, MuteButtonState>\n}\n\nexport interface MuteButtonRenderProps {\n ref: React.Ref<HTMLButtonElement>\n type: 'button'\n 'aria-label': string\n 'aria-pressed': boolean\n [MuteButtonDataAttributes.muted]?: boolean\n [MuteButtonDataAttributes.volumeOff]?: boolean\n [MuteButtonDataAttributes.volumeOn]?: boolean\n [MuteButtonDataAttributes.volumeLow]?: boolean\n [MuteButtonDataAttributes.volumeHigh]?: boolean\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nexport interface MuteButtonState {\n muted: boolean\n volume: number\n}\n\n// ============================================================================\n// MuteButton Component\n// ============================================================================\n\nexport const MuteButton = React.forwardRef<HTMLButtonElement, MuteButtonProps>(\n function MuteButton(props, forwardedRef) {\n const { render, onClick, ...buttonProps } = props\n const context = useVideoPlayerContext('MuteButton')\n\n const state: MuteButtonState = {\n muted: context.muted,\n volume: context.volume,\n }\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.toggleMute()\n }\n },\n [onClick, context],\n )\n\n const volume = context.volume\n const muted = context.muted\n const volumeOff = volume === 0 || muted\n const volumeOn = volume > 0 && !muted\n const volumeLow = !muted && volume > 0 && volume < 0.5\n const volumeHigh = !muted && volume >= 0.5\n\n const renderProps: MuteButtonRenderProps = {\n ref: forwardedRef,\n type: 'button',\n 'aria-label': context.muted ? 'Unmute' : 'Mute',\n 'aria-pressed': context.muted,\n [MuteButtonDataAttributes.muted]: muted || undefined,\n [MuteButtonDataAttributes.volumeOff]: volumeOff || undefined,\n [MuteButtonDataAttributes.volumeOn]: volumeOn || undefined,\n [MuteButtonDataAttributes.volumeLow]: volumeLow || undefined,\n [MuteButtonDataAttributes.volumeHigh]: volumeHigh || undefined,\n onClick: handleClick,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return <button {...renderProps} {...buttonProps} />\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace MuteButton {\n export type Props = MuteButtonProps\n export type State = MuteButtonState\n}\n","export enum OverlayDataAttributes {\n /** Applied when the overlay is visible. */\n open = 'data-open',\n /** Applied when the overlay is hidden. */\n closed = 'data-closed',\n /** Applied when the video is playing. */\n playing = 'data-playing',\n /** Applied when the video is paused. */\n paused = 'data-paused',\n /** Applied when the video has ended. */\n ended = 'data-ended',\n /** Applied when the video is buffering/loading. */\n waiting = 'data-waiting',\n /** Applied when the video is seeking to a new position. */\n seeking = 'data-seeking',\n /** Applied when the player is in fullscreen mode. */\n fullscreen = 'data-fullscreen',\n /** Applied when the video is in picture-in-picture mode. */\n pip = 'data-pip',\n /** Applied on the first frame when entering. Use for CSS enter animations. */\n startingStyle = 'data-starting-style',\n /** Applied during exit animation. Use for CSS exit animations. */\n endingStyle = 'data-ending-style',\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport { useTransitionStatus } from '../../hooks/use-transition-status.js'\nimport type { RenderProp } from '../../types.js'\nimport { OverlayDataAttributes } from './overlay.data-attributes.js'\n\n// ============================================================================\n// Overlay Props\n// ============================================================================\n\nexport interface OverlayProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {\n /**\n * Delay before hiding after player becomes idle (ms).\n * Defaults to Root's idleTimeout. Set to 0 to disable auto-hide.\n */\n idleTimeout?: number\n\n /**\n * Keep the element always mounted in the DOM, even when closed.\n * Only needed for JavaScript animation libraries (e.g., Framer Motion).\n * CSS transitions and animations work automatically without this.\n * @default false\n */\n keepMounted?: boolean\n\n render?: RenderProp<OverlayRenderProps, OverlayState>\n children?: React.ReactNode\n}\n\nexport interface OverlayRenderProps {\n ref: React.Ref<HTMLDivElement>\n onClick: (event: React.MouseEvent<HTMLDivElement>) => void\n [OverlayDataAttributes.playing]?: boolean\n [OverlayDataAttributes.paused]?: boolean\n [OverlayDataAttributes.ended]?: boolean\n [OverlayDataAttributes.waiting]?: boolean\n [OverlayDataAttributes.seeking]?: boolean\n [OverlayDataAttributes.fullscreen]?: boolean\n [OverlayDataAttributes.pip]?: boolean\n [OverlayDataAttributes.open]?: boolean\n [OverlayDataAttributes.closed]?: boolean\n [OverlayDataAttributes.startingStyle]?: boolean\n [OverlayDataAttributes.endingStyle]?: boolean\n}\n\nexport interface OverlayState {\n playing: boolean\n paused: boolean\n ended: boolean\n waiting: boolean\n seeking: boolean\n fullscreen: boolean\n pictureInPicture: boolean\n /** Whether the overlay is currently visible (opposite of idle) */\n open: boolean\n}\n\n// ============================================================================\n// Overlay Component\n// ============================================================================\n\nexport const Overlay = React.forwardRef<HTMLDivElement, OverlayProps>(\n function Overlay(props, forwardedRef) {\n const {\n idleTimeout: idleTimeoutProp,\n keepMounted = false,\n render,\n onClick,\n children,\n ...divProps\n } = props\n const context = useVideoPlayerContext('Overlay')\n\n // Use component's idleTimeout if set, otherwise use context's\n const effectiveIdleTimeout = idleTimeoutProp ?? context.idleTimeout\n\n // Determine visibility: open when not idle, or when idleTimeout is 0 (disabled)\n const open = effectiveIdleTimeout === 0 || !context.idle\n\n // Handle transition status for animations\n const { mounted, transitionStatus, elementRef } = useTransitionStatus({\n open,\n keepMounted,\n })\n\n // Compose refs\n const composedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n ;(elementRef as React.MutableRefObject<HTMLElement | null>).current =\n node\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef, elementRef],\n )\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.toggle()\n }\n },\n [onClick, context],\n )\n\n const state: OverlayState = {\n playing: context.playing,\n paused: context.paused,\n ended: context.ended,\n waiting: context.waiting,\n seeking: context.seeking,\n fullscreen: context.fullscreen,\n pictureInPicture: context.pictureInPicture,\n open,\n }\n\n const renderProps: OverlayRenderProps = {\n ref: composedRef,\n onClick: handleClick,\n [OverlayDataAttributes.playing]: context.playing || undefined,\n [OverlayDataAttributes.paused]: context.paused || undefined,\n [OverlayDataAttributes.ended]: context.ended || undefined,\n [OverlayDataAttributes.waiting]: context.waiting || undefined,\n [OverlayDataAttributes.seeking]: context.seeking || undefined,\n [OverlayDataAttributes.fullscreen]: context.fullscreen || undefined,\n [OverlayDataAttributes.pip]: context.pictureInPicture || undefined,\n [OverlayDataAttributes.open]: open || undefined,\n [OverlayDataAttributes.closed]: !open || undefined,\n [OverlayDataAttributes.startingStyle]:\n transitionStatus === 'starting' || undefined,\n [OverlayDataAttributes.endingStyle]:\n transitionStatus === 'ending' || undefined,\n }\n\n if (!mounted) {\n return null\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <div {...renderProps} {...divProps}>\n {children}\n </div>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Overlay {\n export type Props = OverlayProps\n export type State = OverlayState\n export type RenderProps = OverlayRenderProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { PictureInPictureButtonDataAttributes } from './picture-in-picture-button.data-attributes.js'\n\n// ============================================================================\n// PictureInPictureButton Props\n// ============================================================================\n\nexport interface PictureInPictureButtonProps\n extends React.ComponentPropsWithRef<'button'> {\n render?: RenderProp<\n PictureInPictureButtonRenderProps,\n PictureInPictureButtonState\n >\n}\n\nexport interface PictureInPictureButtonRenderProps {\n ref: React.Ref<HTMLButtonElement>\n type: 'button'\n 'aria-label': string\n 'aria-pressed': boolean\n disabled: boolean\n [PictureInPictureButtonDataAttributes.pip]?: boolean\n [PictureInPictureButtonDataAttributes.supported]?: boolean\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nexport interface PictureInPictureButtonState {\n pictureInPicture: boolean\n supported: boolean\n}\n\n// ============================================================================\n// PictureInPictureButton Component\n// ============================================================================\n\nexport const PictureInPictureButton = React.forwardRef<\n HTMLButtonElement,\n PictureInPictureButtonProps\n>(function PictureInPictureButton(props, forwardedRef) {\n const { render, onClick, ...buttonProps } = props\n const context = useVideoPlayerContext('PictureInPictureButton')\n\n // Defer to after hydration to avoid mismatch\n const [supported, setSupported] = React.useState(false)\n React.useEffect(() => {\n setSupported(\n 'pictureInPictureEnabled' in document && document.pictureInPictureEnabled,\n )\n }, [])\n\n const state: PictureInPictureButtonState = {\n pictureInPicture: context.pictureInPicture,\n supported,\n }\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.togglePictureInPicture()\n }\n },\n [onClick, context],\n )\n\n const renderProps: PictureInPictureButtonRenderProps = {\n ref: forwardedRef,\n type: 'button',\n 'aria-label': context.pictureInPicture\n ? 'Exit picture-in-picture'\n : 'Enter picture-in-picture',\n 'aria-pressed': context.pictureInPicture,\n disabled: !supported,\n [PictureInPictureButtonDataAttributes.pip]:\n context.pictureInPicture || undefined,\n [PictureInPictureButtonDataAttributes.supported]: supported || undefined,\n onClick: handleClick,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return <button {...renderProps} {...buttonProps} />\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace PictureInPictureButton {\n export type Props = PictureInPictureButtonProps\n export type State = PictureInPictureButtonState\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { PlayButtonDataAttributes } from './play-button.data-attributes.js'\n\n// ============================================================================\n// PlayButton Props\n// ============================================================================\n\nexport interface PlayButtonProps\n extends Omit<React.ComponentPropsWithRef<'button'>, 'children'> {\n render?: RenderProp<PlayButtonRenderProps, PlayButtonState>\n children?: React.ReactNode\n}\n\nexport interface PlayButtonRenderProps {\n ref: React.Ref<HTMLButtonElement>\n type: 'button'\n 'aria-label': string\n [PlayButtonDataAttributes.playing]?: boolean\n [PlayButtonDataAttributes.paused]?: boolean\n [PlayButtonDataAttributes.ended]?: boolean\n [PlayButtonDataAttributes.waiting]?: boolean\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nexport interface PlayButtonState {\n playing: boolean\n paused: boolean\n ended: boolean\n waiting: boolean\n}\n\n// ============================================================================\n// PlayButton Component\n// ============================================================================\n\nexport const PlayButton = React.forwardRef<HTMLButtonElement, PlayButtonProps>(\n function PlayButton(props, forwardedRef) {\n const { render, onClick, children, ...buttonProps } = props\n const context = useVideoPlayerContext('PlayButton')\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.toggle()\n }\n },\n [onClick, context],\n )\n\n const state: PlayButtonState = {\n playing: context.playing,\n paused: context.paused,\n ended: context.ended,\n waiting: context.waiting,\n }\n\n const renderProps: PlayButtonRenderProps = {\n ref: forwardedRef,\n type: 'button',\n 'aria-label': context.playing ? 'Pause' : 'Play',\n [PlayButtonDataAttributes.playing]: context.playing || undefined,\n [PlayButtonDataAttributes.paused]: context.paused || undefined,\n [PlayButtonDataAttributes.ended]: context.ended || undefined,\n [PlayButtonDataAttributes.waiting]: context.waiting || undefined,\n onClick: handleClick,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <button {...renderProps} {...buttonProps}>\n {children}\n </button>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace PlayButton {\n export type Props = PlayButtonProps\n export type State = PlayButtonState\n export type RenderProps = PlayButtonRenderProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { PlaybackRateButtonDataAttributes } from './playback-rate-button.data-attributes.js'\n\n// ============================================================================\n// PlaybackRateButton Props\n// ============================================================================\n\nexport const DEFAULT_PLAYBACK_RATES = [\n 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2,\n] as const\n\nexport interface PlaybackRateButtonProps\n extends React.ComponentPropsWithRef<'button'> {\n /**\n * Available playback rates to cycle through.\n * @default [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]\n */\n rates?: readonly number[]\n\n render?: RenderProp<PlaybackRateButtonRenderProps, PlaybackRateButtonState>\n}\n\nexport interface PlaybackRateButtonRenderProps {\n ref: React.Ref<HTMLButtonElement>\n type: 'button'\n 'aria-label': string\n [PlaybackRateButtonDataAttributes.rate]: number\n onClick: (event: React.MouseEvent<HTMLButtonElement>) => void\n}\n\nexport interface PlaybackRateButtonState {\n playbackRate: number\n rates: readonly number[]\n}\n\n// ============================================================================\n// PlaybackRateButton Component\n// ============================================================================\n\nexport const PlaybackRateButton = React.forwardRef<\n HTMLButtonElement,\n PlaybackRateButtonProps\n>(function PlaybackRateButton(props, forwardedRef) {\n const {\n rates = DEFAULT_PLAYBACK_RATES,\n render,\n onClick,\n children,\n ...buttonProps\n } = props\n const context = useVideoPlayerContext('PlaybackRateButton')\n\n const state: PlaybackRateButtonState = {\n playbackRate: context.playbackRate,\n rates,\n }\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n // Find next rate in the cycle\n const currentIndex = rates.indexOf(context.playbackRate)\n const nextIndex = (currentIndex + 1) % rates.length\n const nextRate = rates[nextIndex] ?? rates[0] ?? context.playbackRate\n context.setPlaybackRate(nextRate)\n }\n },\n [onClick, context, rates],\n )\n\n const renderProps: PlaybackRateButtonRenderProps = {\n ref: forwardedRef,\n type: 'button',\n 'aria-label': `Playback speed: ${context.playbackRate}x`,\n [PlaybackRateButtonDataAttributes.rate]: context.playbackRate,\n onClick: handleClick,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <button {...renderProps} {...buttonProps}>\n {children ?? `${context.playbackRate}x`}\n </button>\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace PlaybackRateButton {\n export type Props = PlaybackRateButtonProps\n export type State = PlaybackRateButtonState\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport {\n PlaybackRateMenuDataAttributes,\n PlaybackRateMenuItemDataAttributes,\n} from './playback-rate-menu.data-attributes.js'\n\n// ============================================================================\n// PlaybackRateMenu Props\n// ============================================================================\n\nexport const DEFAULT_PLAYBACK_RATES = [\n 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2,\n] as const\n\nexport interface PlaybackRateMenuProps\n extends React.ComponentPropsWithRef<'div'> {\n /**\n * Available playback rates.\n * @default [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]\n */\n rates?: readonly number[]\n\n render?: RenderProp<PlaybackRateMenuRenderProps, PlaybackRateMenuState>\n}\n\nexport interface PlaybackRateMenuRenderProps {\n ref: React.Ref<HTMLDivElement>\n role: 'menu'\n 'aria-label': string\n [PlaybackRateMenuDataAttributes.rate]: number\n}\n\nexport interface PlaybackRateMenuState {\n playbackRate: number\n rates: readonly number[]\n}\n\n// ============================================================================\n// PlaybackRateMenu Component\n// ============================================================================\n\nexport const PlaybackRateMenu = React.forwardRef<\n HTMLDivElement,\n PlaybackRateMenuProps\n>(function PlaybackRateMenu(props, forwardedRef) {\n const {\n rates = DEFAULT_PLAYBACK_RATES,\n render,\n children,\n ...divProps\n } = props\n const context = useVideoPlayerContext('PlaybackRateMenu')\n\n const state: PlaybackRateMenuState = {\n playbackRate: context.playbackRate,\n rates,\n }\n\n const renderProps: PlaybackRateMenuRenderProps = {\n ref: forwardedRef,\n role: 'menu',\n 'aria-label': 'Playback speed',\n [PlaybackRateMenuDataAttributes.rate]: context.playbackRate,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n // Default render: simple list of rate options\n return (\n <div {...renderProps} {...divProps}>\n {children ??\n rates.map((rate) => <PlaybackRateMenuItem key={rate} rate={rate} />)}\n </div>\n )\n})\n\n// ============================================================================\n// PlaybackRateMenuItem\n// ============================================================================\n\nexport interface PlaybackRateMenuItemProps\n extends React.ComponentPropsWithRef<'button'> {\n rate: number\n}\n\nexport const PlaybackRateMenuItem = React.forwardRef<\n HTMLButtonElement,\n PlaybackRateMenuItemProps\n>(function PlaybackRateMenuItem(props, forwardedRef) {\n const { rate, onClick, children, ...buttonProps } = props\n const context = useVideoPlayerContext('PlaybackRateMenuItem')\n\n const isActive = context.playbackRate === rate\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.setPlaybackRate(rate)\n }\n },\n [onClick, context, rate],\n )\n\n return (\n <button\n ref={forwardedRef}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isActive}\n {...{\n [PlaybackRateMenuItemDataAttributes.active]: isActive || undefined,\n }}\n {...buttonProps}\n onClick={handleClick}\n >\n {children ?? `${rate}x`}\n </button>\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace PlaybackRateMenu {\n export type Props = PlaybackRateMenuProps\n export type State = PlaybackRateMenuState\n export type ItemProps = PlaybackRateMenuItemProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\n\n// ============================================================================\n// Portal Props\n// ============================================================================\n\nexport interface PortalProps {\n children: React.ReactNode\n /**\n * Target container for the portal.\n * @default document.body\n */\n container?: Element | null\n}\n\n// ============================================================================\n// Portal Component\n// ============================================================================\n\nexport function Portal(props: PortalProps): React.ReactPortal | null {\n const { children, container } = props\n const [mounted, setMounted] = React.useState(false)\n\n React.useEffect(() => {\n setMounted(true)\n return () => setMounted(false)\n }, [])\n\n if (!mounted) {\n return null\n }\n\n const target =\n container ?? (typeof document !== 'undefined' ? document.body : null)\n\n if (!target) {\n return null\n }\n\n return createPortal(children, target)\n}\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Portal {\n export type Props = PortalProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport { useTransitionStatus } from '../../hooks/use-transition-status.js'\nimport type { RenderProp } from '../../types.js'\nimport { PosterDataAttributes } from './poster.data-attributes.js'\n\n// ============================================================================\n// Poster Props\n// ============================================================================\n\nexport interface PosterProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {\n /**\n * Keep the element always mounted in the DOM, even when loaded.\n * Only needed for JavaScript animation libraries (e.g., Framer Motion).\n * CSS transitions and animations work automatically without this.\n * @default false\n */\n keepMounted?: boolean\n render?: RenderProp<PosterRenderProps, PosterState>\n children?: React.ReactNode\n}\n\nexport interface PosterRenderProps {\n ref: React.Ref<HTMLDivElement>\n 'aria-hidden': true\n [PosterDataAttributes.loading]?: boolean\n [PosterDataAttributes.loaded]?: boolean\n [PosterDataAttributes.startingStyle]?: boolean\n [PosterDataAttributes.endingStyle]?: boolean\n}\n\nexport interface PosterState {\n loading: boolean\n loaded: boolean\n transitionStatus: 'starting' | 'ending' | undefined\n}\n\n// ============================================================================\n// Poster Component\n// ============================================================================\n\nexport const Poster = React.forwardRef<HTMLDivElement, PosterProps>(\n function Poster(props, forwardedRef) {\n const { keepMounted = false, render, children, ...divProps } = props\n const context = useVideoPlayerContext('Poster')\n\n // Show poster while video is loading (before canPlay)\n const loading = !context.canPlay\n const loaded = context.canPlay\n\n // Use transition status for enter/exit animations\n const { mounted, transitionStatus, elementRef } = useTransitionStatus({\n open: loading,\n keepMounted,\n })\n\n // Compose refs\n const composedRef = useComposedRef(forwardedRef, elementRef)\n\n const state: PosterState = {\n loading,\n loaded,\n transitionStatus,\n }\n\n const renderProps: PosterRenderProps = {\n ref: composedRef,\n 'aria-hidden': true,\n [PosterDataAttributes.loading]: loading || undefined,\n [PosterDataAttributes.loaded]: loaded || undefined,\n [PosterDataAttributes.startingStyle]:\n transitionStatus === 'starting' || undefined,\n [PosterDataAttributes.endingStyle]:\n transitionStatus === 'ending' || undefined,\n }\n\n if (!mounted) {\n return null\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <div {...renderProps} {...divProps}>\n {children}\n </div>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Poster {\n export type Props = PosterProps\n export type State = PosterState\n export type RenderProps = PosterRenderProps\n}\n\n// ============================================================================\n// Utility: Compose Refs\n// ============================================================================\n\nfunction useComposedRef<T>(\n ...refs: (React.Ref<T> | React.RefObject<T | null> | undefined)[]\n): React.RefCallback<T> {\n return React.useCallback(\n (node: T) => {\n for (const ref of refs) {\n if (typeof ref === 'function') {\n ref(node)\n } else if (ref != null) {\n ;(ref as React.RefObject<T>).current = node\n }\n }\n },\n // biome-ignore lint/correctness/useExhaustiveDependencies: allowed\n refs,\n )\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp, VideoQuality } from '../../types.js'\nimport {\n QualityMenuDataAttributes,\n QualityMenuItemDataAttributes,\n} from './quality-menu.data-attributes.js'\n\n// ============================================================================\n// QualityMenu Props\n// ============================================================================\n\nexport interface QualityMenuProps extends React.ComponentPropsWithRef<'div'> {\n render?: RenderProp<QualityMenuRenderProps, QualityMenuState>\n}\n\nexport interface QualityMenuRenderProps {\n ref: React.Ref<any>\n role: 'menu'\n 'aria-label': string\n [QualityMenuDataAttributes.quality]?: string\n}\n\nexport interface QualityMenuState {\n qualities: VideoQuality[]\n activeQuality: VideoQuality | null\n}\n\n// ============================================================================\n// QualityMenu Component\n// ============================================================================\n\nexport const QualityMenu = React.forwardRef<HTMLDivElement, QualityMenuProps>(\n function QualityMenu(props, forwardedRef) {\n const { render, children, ...divProps } = props\n const context = useVideoPlayerContext('QualityMenu')\n\n const state: QualityMenuState = {\n qualities: context.qualities,\n activeQuality: context.activeQuality,\n }\n\n const renderProps: QualityMenuRenderProps = {\n ref: forwardedRef,\n role: 'menu',\n 'aria-label': 'Video quality',\n [QualityMenuDataAttributes.quality]:\n context.activeQuality?.label ?? undefined,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n // Default render: list of quality options\n return (\n <div {...renderProps} {...divProps}>\n {children ??\n context.qualities.map((quality) => (\n <QualityMenuItem key={quality.label} quality={quality}>\n {quality.label}\n </QualityMenuItem>\n ))}\n </div>\n )\n },\n)\n\n// ============================================================================\n// QualityMenuItem\n// ============================================================================\n\nexport interface QualityMenuItemProps\n extends React.ComponentPropsWithRef<'button'> {\n quality: VideoQuality\n}\n\nexport const QualityMenuItem = React.forwardRef<\n HTMLButtonElement,\n QualityMenuItemProps\n>(function QualityMenuItem(props, forwardedRef) {\n const { quality, onClick, children, ...buttonProps } = props\n const context = useVideoPlayerContext('QualityMenuItem')\n\n const isActive = context.activeQuality?.label === quality.label\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented) {\n context.setQuality(quality)\n }\n },\n [onClick, context, quality],\n )\n\n return (\n <button\n ref={forwardedRef}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={isActive}\n {...{ [QualityMenuItemDataAttributes.active]: isActive || undefined }}\n {...buttonProps}\n onClick={handleClick}\n >\n {children}\n </button>\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace QualityMenu {\n export type Props = QualityMenuProps\n export type State = QualityMenuState\n export type ItemProps = QualityMenuItemProps\n}\n","export enum RootDataAttributes {\n /** Applied when the video is playing. */\n playing = 'data-playing',\n /** Applied when the video is paused. */\n paused = 'data-paused',\n /** Applied when the video has ended. */\n ended = 'data-ended',\n /** Applied when the video is buffering/loading. */\n waiting = 'data-waiting',\n /** Applied when the video is seeking to a new position. */\n seeking = 'data-seeking',\n /** Applied when the player is in fullscreen mode. */\n fullscreen = 'data-fullscreen',\n /** Applied when the video is in picture-in-picture mode. */\n pip = 'data-pip',\n /** Applied when the audio is muted. */\n muted = 'data-muted',\n /** Applied when the player is idle (no user interaction). */\n idle = 'data-idle',\n}\n","'use client'\n\nimport * as React from 'react'\nimport { VideoPlayerContext } from '../../contexts/video-player-context.js'\nimport { useKeyboardShortcuts } from '../../hooks/use-keyboard-shortcuts.js'\nimport { useVideoPlayer } from '../../hooks/use-video-player.js'\nimport type {\n PlaybackIntent,\n PlaybackStatus,\n TrackInfo,\n VideoPlayerContextValue,\n VideoPlayerRootProps,\n VideoQuality,\n} from '../../types.js'\nimport { RootDataAttributes } from './root.data-attributes.js'\n\n// ============================================================================\n// Hook: useControllableState\n// ============================================================================\n\nfunction useControllableState<T>(\n controlledValue: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void,\n): [T, (value: T | ((prev: T) => T)) => void] {\n const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue)\n const isControlled = controlledValue !== undefined\n const value = isControlled ? controlledValue : uncontrolledValue\n\n const setValue = React.useCallback(\n (nextValue: T | ((prev: T) => T)) => {\n const newValue =\n typeof nextValue === 'function'\n ? (nextValue as (prev: T) => T)(value)\n : nextValue\n\n if (!isControlled) {\n setUncontrolledValue(newValue)\n }\n onChange?.(newValue)\n },\n [isControlled, value, onChange],\n )\n\n return [value, setValue]\n}\n\n// ============================================================================\n// Root Props Interface\n// ============================================================================\n\nexport interface VideoPlayerRootState {\n playbackStatus: PlaybackStatus\n playbackIntent: PlaybackIntent\n playing: boolean\n paused: boolean\n ended: boolean\n waiting: boolean\n seeking: boolean\n canPlay: boolean\n fullscreen: boolean\n pictureInPicture: boolean\n muted: boolean\n volume: number\n currentTime: number\n duration: number\n playbackRate: number\n idle: boolean\n idleTimeout: number\n}\n\n// ============================================================================\n// Provider Component (internal - wraps Root with context)\n// ============================================================================\n\ninterface VideoPlayerProviderProps extends VideoPlayerRootProps {\n rootRef: React.RefObject<HTMLDivElement | null>\n videoRef: React.RefObject<HTMLVideoElement | null>\n}\n\nfunction VideoPlayerProvider({\n // Refs from Root\n rootRef,\n videoRef,\n\n // Actions ref\n actionsRef,\n\n // Uncontrolled defaults\n defaultPlaying = false,\n defaultVolume = 1,\n defaultMuted = false,\n defaultPlaybackRate = 1,\n\n // Controlled values\n playing: controlledPlaying,\n onPlayingChange,\n volume: controlledVolume,\n onVolumeChange,\n muted: controlledMuted,\n onMutedChange,\n playbackRate: controlledPlaybackRate,\n onPlaybackRateChange,\n currentTime: controlledCurrentTime,\n onCurrentTimeChange,\n\n // Idle detection\n idleTimeout = 3000,\n preventIdleWhenPaused = false,\n idle: controlledIdle,\n onIdleChange,\n\n // Events\n onEnded,\n onWaiting,\n onSeeking,\n onSeeked,\n onFullscreenChange,\n onPictureInPictureChange,\n\n // Children\n children,\n}: VideoPlayerProviderProps) {\n // Refs\n const previousVolumeRef = React.useRef(1)\n\n // Controllable state\n // Note: We use playbackStatus internally but still support the controlled `playing` prop\n // for backward compatibility. The `playing` prop maps to playbackIntent.\n const [playbackStatus, setPlaybackStatus] =\n React.useState<PlaybackStatus>('paused')\n const [playbackIntent, setPlaybackIntent] = React.useState<PlaybackIntent>(\n defaultPlaying ? 'play' : 'pause',\n )\n\n // Sync playbackStatus when controlled `playing` prop changes\n React.useEffect(() => {\n if (controlledPlaying !== undefined) {\n setPlaybackIntent(controlledPlaying ? 'play' : 'pause')\n // Only update status if not in a transient state like 'waiting'\n if (playbackStatus !== 'waiting') {\n setPlaybackStatus(controlledPlaying ? 'playing' : 'paused')\n }\n }\n }, [controlledPlaying, playbackStatus])\n const [volume, setVolume] = useControllableState(\n controlledVolume,\n defaultVolume,\n onVolumeChange,\n )\n const [muted, setMuted] = useControllableState(\n controlledMuted,\n defaultMuted,\n onMutedChange,\n )\n const [playbackRate, setPlaybackRateState] = useControllableState(\n controlledPlaybackRate,\n defaultPlaybackRate,\n onPlaybackRateChange,\n )\n const [idle, setIdle] = useControllableState(\n controlledIdle,\n true, // Start idle (controls hidden until interaction)\n onIdleChange,\n )\n\n // Idle timeout ref\n const idleTimeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(\n null,\n )\n\n const clearIdleTimeout = React.useCallback(() => {\n if (idleTimeoutRef.current) {\n clearTimeout(idleTimeoutRef.current)\n idleTimeoutRef.current = null\n }\n }, [])\n\n const startIdleTimeout = React.useCallback(() => {\n if (idleTimeout === 0) return\n\n clearIdleTimeout()\n idleTimeoutRef.current = setTimeout(() => {\n setIdle(true)\n }, idleTimeout)\n }, [idleTimeout, clearIdleTimeout, setIdle])\n\n const resetIdle = React.useCallback(() => {\n setIdle(false)\n startIdleTimeout()\n }, [setIdle, startIdleTimeout])\n\n const handleRootMouseLeave = React.useCallback(() => {\n clearIdleTimeout()\n setIdle(true)\n }, [clearIdleTimeout, setIdle])\n\n // Start idle timeout on mount, cleanup on unmount\n // biome-ignore lint/correctness/useExhaustiveDependencies: allowed\n React.useEffect(() => {\n if (idleTimeout > 0) {\n idleTimeoutRef.current = setTimeout(() => {\n setIdle(true)\n }, idleTimeout)\n }\n return () => {\n if (idleTimeoutRef.current) {\n clearTimeout(idleTimeoutRef.current)\n }\n }\n }, [])\n\n // Compute effective idle state synchronously to prevent flicker\n // When preventIdleWhenPaused is enabled and video is not playing, never be idle\n const effectiveIdle =\n preventIdleWhenPaused && playbackStatus !== 'playing' ? false : idle\n\n // Internal state (not controllable)\n const [currentTime, setCurrentTime] = React.useState(0)\n const [duration, setDuration] = React.useState(0)\n const [buffered, setBuffered] = React.useState<TimeRanges | null>(null)\n const [hoverTime, setHoverTime] = React.useState<number | null>(null)\n const [canPlay, setCanPlay] = React.useState(false)\n const [seeking, setSeeking] = React.useState(false)\n const [fullscreen, setFullscreen] = React.useState(false)\n const [pictureInPicture, setPictureInPicture] = React.useState(false)\n const [registeredTracks, setRegisteredTracks] = React.useState<TrackInfo[]>(\n [],\n )\n const [activeTextTrack, setActiveTextTrack] =\n React.useState<TextTrack | null>(null)\n const [activeCues, setActiveCues] = React.useState<VTTCue[]>([])\n const [qualities, _setQualities] = React.useState<VideoQuality[]>([])\n const [activeQuality, setActiveQuality] = React.useState<VideoQuality | null>(\n null,\n )\n\n // Sync controlled currentTime if provided\n React.useEffect(() => {\n if (controlledCurrentTime !== undefined && videoRef.current) {\n videoRef.current.currentTime = controlledCurrentTime\n }\n }, [controlledCurrentTime, videoRef])\n\n // Fullscreen change listener\n React.useEffect(() => {\n const handleFullscreenChange = () => {\n const isFullscreen = document.fullscreenElement === rootRef.current\n setFullscreen(isFullscreen)\n onFullscreenChange?.(isFullscreen)\n }\n\n document.addEventListener('fullscreenchange', handleFullscreenChange)\n return () =>\n document.removeEventListener('fullscreenchange', handleFullscreenChange)\n }, [onFullscreenChange, rootRef])\n\n // PiP change listener\n React.useEffect(() => {\n const video = videoRef.current\n if (!video) return\n\n const handlePiPEnter = () => {\n setPictureInPicture(true)\n onPictureInPictureChange?.(true)\n }\n const handlePiPLeave = () => {\n setPictureInPicture(false)\n onPictureInPictureChange?.(false)\n }\n\n video.addEventListener('enterpictureinpicture', handlePiPEnter)\n video.addEventListener('leavepictureinpicture', handlePiPLeave)\n return () => {\n video.removeEventListener('enterpictureinpicture', handlePiPEnter)\n video.removeEventListener('leavepictureinpicture', handlePiPLeave)\n }\n }, [onPictureInPictureChange, videoRef])\n\n // Actions\n const play = React.useCallback(async () => {\n if (videoRef.current) {\n setPlaybackIntent('play')\n await videoRef.current.play()\n setPlaybackStatus('playing')\n onPlayingChange?.(true)\n }\n }, [videoRef, onPlayingChange])\n\n const pause = React.useCallback(() => {\n if (videoRef.current) {\n setPlaybackIntent('pause')\n videoRef.current.pause()\n setPlaybackStatus('paused')\n onPlayingChange?.(false)\n }\n }, [videoRef, onPlayingChange])\n\n const toggle = React.useCallback(async () => {\n if (playbackStatus === 'playing') {\n pause()\n } else {\n await play()\n }\n }, [playbackStatus, play, pause])\n\n const seek = React.useCallback(\n (time: number) => {\n if (videoRef.current) {\n videoRef.current.currentTime = time\n setCurrentTime(time)\n onCurrentTimeChange?.(time)\n }\n },\n [onCurrentTimeChange, videoRef],\n )\n\n const handleSetVolume = React.useCallback(\n (vol: number) => {\n const clampedVolume = Math.max(0, Math.min(1, vol))\n if (videoRef.current) {\n videoRef.current.volume = clampedVolume\n }\n setVolume(clampedVolume)\n },\n [setVolume, videoRef],\n )\n\n const toggleMute = React.useCallback(() => {\n // Treat volume === 0 the same as muted for toggle purposes\n const effectivelyMuted = muted || volume === 0\n\n if (!effectivelyMuted) {\n // Muting - save current volume for restoration\n previousVolumeRef.current = volume\n if (videoRef.current) {\n videoRef.current.muted = true\n }\n setMuted(true)\n } else {\n // Unmuting - restore previous volume, or max if previous was 0\n const restoreVolume =\n previousVolumeRef.current > 0 ? previousVolumeRef.current : 1\n if (videoRef.current) {\n videoRef.current.volume = restoreVolume\n videoRef.current.muted = false\n }\n setVolume(restoreVolume)\n setMuted(false)\n }\n }, [muted, volume, setMuted, setVolume, videoRef])\n\n const enterFullscreen = React.useCallback(async () => {\n if (rootRef.current?.requestFullscreen) {\n await rootRef.current.requestFullscreen()\n }\n }, [rootRef])\n\n const exitFullscreen = React.useCallback(async () => {\n if (document.exitFullscreen) {\n await document.exitFullscreen()\n }\n }, [])\n\n const toggleFullscreen = React.useCallback(async () => {\n if (fullscreen) {\n await exitFullscreen()\n } else {\n await enterFullscreen()\n }\n }, [fullscreen, enterFullscreen, exitFullscreen])\n\n const enterPictureInPicture = React.useCallback(async () => {\n if (videoRef.current?.requestPictureInPicture) {\n await videoRef.current.requestPictureInPicture()\n }\n }, [videoRef])\n\n const exitPictureInPicture = React.useCallback(async () => {\n if (document.pictureInPictureElement) {\n await document.exitPictureInPicture()\n }\n }, [])\n\n const togglePictureInPicture = React.useCallback(async () => {\n if (pictureInPicture) {\n await exitPictureInPicture()\n } else {\n await enterPictureInPicture()\n }\n }, [pictureInPicture, enterPictureInPicture, exitPictureInPicture])\n\n const setPlaybackRate = React.useCallback(\n (rate: number) => {\n if (videoRef.current) {\n videoRef.current.playbackRate = rate\n }\n setPlaybackRateState(rate)\n },\n [setPlaybackRateState, videoRef],\n )\n\n const setTextTrack = React.useCallback(\n (track: TextTrack | null) => {\n // Disable all tracks first\n if (videoRef.current) {\n for (let i = 0; i < videoRef.current.textTracks.length; i++) {\n const textTrack = videoRef.current.textTracks[i]\n if (textTrack) {\n textTrack.mode = 'disabled'\n }\n }\n // Enable selected track in 'hidden' mode\n // 'hidden' fires cuechange events but doesn't render native captions\n // allowing our custom Captions component to handle rendering\n if (track) {\n track.mode = 'hidden'\n }\n }\n setActiveTextTrack(track)\n // Clear active cues when switching tracks\n setActiveCues([])\n },\n [videoRef],\n )\n\n const setQuality = React.useCallback((quality: VideoQuality) => {\n // Quality switching requires HLS/DASH library integration\n // This is a placeholder for the action\n setActiveQuality(quality)\n }, [])\n\n // Track registration actions (for VideoPlayer.Track component)\n const registerTrack = React.useCallback((track: TrackInfo) => {\n setRegisteredTracks((prev) => {\n // Avoid duplicates\n if (prev.some((t) => t.id === track.id)) return prev\n return [...prev, track]\n })\n }, [])\n\n const unregisterTrack = React.useCallback((id: string) => {\n setRegisteredTracks((prev) => prev.filter((t) => t.id !== id))\n }, [])\n\n const updateTrackRef = React.useCallback(\n (id: string, textTrack: TextTrack) => {\n setRegisteredTracks((prev) =>\n prev.map((t) => (t.id === id ? { ...t, textTrack } : t)),\n )\n },\n [],\n )\n\n // Cuechange event listener - updates activeCues when cues change\n React.useEffect(() => {\n if (!activeTextTrack) {\n setActiveCues([])\n return\n }\n\n const handleCueChange = () => {\n const cues = activeTextTrack.activeCues\n if (!cues) {\n setActiveCues([])\n return\n }\n // Convert CueList to array of VTTCue\n const cueArray: VTTCue[] = []\n for (let i = 0; i < cues.length; i++) {\n const cue = cues[i]\n if (cue instanceof VTTCue) {\n cueArray.push(cue)\n }\n }\n setActiveCues(cueArray)\n }\n\n // Initial check for any active cues\n handleCueChange()\n\n activeTextTrack.addEventListener('cuechange', handleCueChange)\n return () => {\n activeTextTrack.removeEventListener('cuechange', handleCueChange)\n }\n }, [activeTextTrack])\n\n // Populate actionsRef for external control (Base UI pattern)\n React.useImperativeHandle(\n actionsRef,\n () => ({\n toggle,\n seek,\n setVolume: handleSetVolume,\n toggleFullscreen,\n }),\n [toggle, seek, handleSetVolume, toggleFullscreen],\n )\n\n // Video event handlers (to be called by Video component)\n const handleTimeUpdate = React.useCallback(() => {\n if (videoRef.current) {\n const time = videoRef.current.currentTime\n setCurrentTime(time)\n onCurrentTimeChange?.(time)\n }\n }, [onCurrentTimeChange, videoRef])\n\n const handleDurationChange = React.useCallback(() => {\n if (videoRef.current) {\n setDuration(videoRef.current.duration)\n }\n }, [videoRef])\n\n const handleProgress = React.useCallback(() => {\n if (videoRef.current) {\n setBuffered(videoRef.current.buffered)\n }\n }, [videoRef])\n\n const handlePlay = React.useCallback(() => {\n setPlaybackIntent('play')\n setPlaybackStatus('playing')\n onPlayingChange?.(true)\n }, [onPlayingChange])\n\n const handlePause = React.useCallback(() => {\n // Only set to paused if not ended (ended takes precedence)\n if (playbackStatus !== 'ended') {\n setPlaybackStatus('paused')\n onPlayingChange?.(false)\n }\n }, [playbackStatus, onPlayingChange])\n\n const handleEnded = React.useCallback(() => {\n setPlaybackIntent('pause')\n setPlaybackStatus('ended')\n onPlayingChange?.(false)\n onEnded?.()\n }, [onPlayingChange, onEnded])\n\n const handleWaiting = React.useCallback(() => {\n setPlaybackStatus('waiting')\n onWaiting?.()\n }, [onWaiting])\n\n const handleCanPlay = React.useCallback(() => {\n // Resume based on intent when exiting waiting state\n if (playbackStatus === 'waiting') {\n const resumeStatus = playbackIntent === 'play' ? 'playing' : 'paused'\n setPlaybackStatus(resumeStatus)\n onPlayingChange?.(resumeStatus === 'playing')\n }\n setCanPlay(true)\n }, [playbackStatus, playbackIntent, onPlayingChange])\n\n const handleSeeking = React.useCallback(() => {\n setSeeking(true)\n // Clear ended state when user seeks\n if (playbackStatus === 'ended') {\n setPlaybackStatus('paused')\n }\n onSeeking?.()\n }, [playbackStatus, onSeeking])\n\n const handleSeeked = React.useCallback(() => {\n setSeeking(false)\n // Check if we've seeked to the end (small epsilon for floating point precision)\n if (videoRef.current) {\n const { currentTime, duration } = videoRef.current\n if (duration > 0 && duration - currentTime < 0.01) {\n setPlaybackStatus('ended')\n }\n }\n onSeeked?.()\n }, [onSeeked, videoRef])\n\n const handleVolumeChange = React.useCallback(() => {\n if (videoRef.current) {\n setVolume(videoRef.current.volume)\n setMuted(videoRef.current.muted)\n }\n }, [setVolume, setMuted, videoRef])\n\n const handleLoadedMetadata = React.useCallback(() => {\n if (videoRef.current) {\n setDuration(videoRef.current.duration)\n // Note: Text tracks are now registered via VideoPlayer.Track components\n // instead of being auto-discovered from the video element\n }\n }, [videoRef])\n\n // Context value\n const contextValue = React.useMemo<VideoPlayerContextValue>(\n () => ({\n // Playback - Primary API\n playbackStatus,\n playbackIntent,\n\n // Playback - Derived booleans (backward compatibility)\n playing: playbackStatus === 'playing',\n paused: playbackStatus === 'paused',\n ended: playbackStatus === 'ended',\n waiting: playbackStatus === 'waiting',\n\n // Playback - Orthogonal states\n seeking,\n canPlay,\n currentTime,\n duration,\n buffered,\n hoverTime,\n hoverProgress:\n hoverTime !== null && duration > 0\n ? (hoverTime / duration) * 100\n : null,\n volume,\n muted,\n fullscreen,\n pictureInPicture,\n idle: effectiveIdle,\n idleTimeout,\n preventIdleWhenPaused,\n registeredTracks,\n activeTextTrack,\n activeCues,\n playbackRate,\n qualities,\n activeQuality,\n videoRef,\n rootRef,\n\n // Actions\n play,\n pause,\n toggle,\n seek,\n setVolume: handleSetVolume,\n toggleMute,\n enterFullscreen,\n exitFullscreen,\n toggleFullscreen,\n enterPictureInPicture,\n exitPictureInPicture,\n togglePictureInPicture,\n setPlaybackRate,\n setTextTrack,\n setQuality,\n registerTrack,\n unregisterTrack,\n updateTrackRef,\n resetIdle,\n setHoverTime,\n\n // Internal event handlers\n _handlers: {\n // Video element handlers\n onTimeUpdate: handleTimeUpdate,\n onDurationChange: handleDurationChange,\n onProgress: handleProgress,\n onPlay: handlePlay,\n onPause: handlePause,\n onEnded: handleEnded,\n onWaiting: handleWaiting,\n onCanPlay: handleCanPlay,\n onSeeking: handleSeeking,\n onSeeked: handleSeeked,\n onVolumeChange: handleVolumeChange,\n onLoadedMetadata: handleLoadedMetadata,\n // Root element handlers\n onRootMouseLeave: handleRootMouseLeave,\n },\n }),\n [\n playbackStatus,\n playbackIntent,\n seeking,\n canPlay,\n currentTime,\n duration,\n buffered,\n hoverTime,\n volume,\n muted,\n fullscreen,\n pictureInPicture,\n effectiveIdle,\n idleTimeout,\n preventIdleWhenPaused,\n registeredTracks,\n activeTextTrack,\n activeCues,\n playbackRate,\n qualities,\n activeQuality,\n videoRef,\n rootRef,\n play,\n pause,\n toggle,\n seek,\n handleSetVolume,\n toggleMute,\n enterFullscreen,\n exitFullscreen,\n toggleFullscreen,\n enterPictureInPicture,\n exitPictureInPicture,\n togglePictureInPicture,\n setPlaybackRate,\n setTextTrack,\n setQuality,\n registerTrack,\n unregisterTrack,\n updateTrackRef,\n resetIdle,\n handleTimeUpdate,\n handleDurationChange,\n handleProgress,\n handlePlay,\n handlePause,\n handleEnded,\n handleWaiting,\n handleCanPlay,\n handleSeeking,\n handleSeeked,\n handleVolumeChange,\n handleLoadedMetadata,\n handleRootMouseLeave,\n ],\n )\n\n return (\n <VideoPlayerContext.Provider value={contextValue}>\n {children}\n </VideoPlayerContext.Provider>\n )\n}\n\n// ============================================================================\n// Root Component\n// ============================================================================\n\nexport const VideoPlayerRoot = React.forwardRef<\n HTMLDivElement,\n VideoPlayerRootProps\n>(function VideoPlayerRoot(props, forwardedRef) {\n const {\n // Actions ref\n actionsRef,\n keyboardShortcuts = 'focused',\n\n // Uncontrolled defaults\n defaultPlaying,\n defaultVolume,\n defaultMuted,\n defaultPlaybackRate,\n\n // Controlled values\n playing,\n onPlayingChange,\n volume,\n onVolumeChange,\n muted,\n onMutedChange,\n playbackRate,\n onPlaybackRateChange,\n currentTime,\n onCurrentTimeChange,\n\n // Idle detection\n idleTimeout,\n preventIdleWhenPaused,\n hideCursorWhenIdle = 'fullscreen',\n idle,\n onIdleChange,\n\n // Events\n onEnded,\n onWaiting,\n onSeeking,\n onSeeked,\n onFullscreenChange,\n onPictureInPictureChange,\n\n // Rest goes to the div\n children,\n ...rootDivProps\n } = props\n\n // Refs need to be created here and passed to Provider\n const rootRef = React.useRef<HTMLDivElement>(null)\n const videoRef = React.useRef<HTMLVideoElement>(null)\n\n return (\n <VideoPlayerProvider\n actionsRef={actionsRef}\n defaultPlaying={defaultPlaying}\n defaultVolume={defaultVolume}\n defaultMuted={defaultMuted}\n defaultPlaybackRate={defaultPlaybackRate}\n playing={playing}\n onPlayingChange={onPlayingChange}\n volume={volume}\n onVolumeChange={onVolumeChange}\n muted={muted}\n onMutedChange={onMutedChange}\n playbackRate={playbackRate}\n onPlaybackRateChange={onPlaybackRateChange}\n currentTime={currentTime}\n onCurrentTimeChange={onCurrentTimeChange}\n idleTimeout={idleTimeout}\n preventIdleWhenPaused={preventIdleWhenPaused}\n idle={idle}\n onIdleChange={onIdleChange}\n onEnded={onEnded}\n onWaiting={onWaiting}\n onSeeking={onSeeking}\n onSeeked={onSeeked}\n onFullscreenChange={onFullscreenChange}\n onPictureInPictureChange={onPictureInPictureChange}\n rootRef={rootRef}\n videoRef={videoRef}\n >\n <VideoPlayerRootImpl\n ref={forwardedRef}\n rootRef={rootRef}\n keyboardShortcuts={keyboardShortcuts}\n hideCursorWhenIdle={hideCursorWhenIdle}\n {...rootDivProps}\n >\n {children}\n </VideoPlayerRootImpl>\n </VideoPlayerProvider>\n )\n})\n\n// ============================================================================\n// Root Implementation (inside Provider, can use useVideoPlayer)\n// ============================================================================\n\ninterface VideoPlayerRootImplProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n rootRef: React.RefObject<HTMLDivElement | null>\n keyboardShortcuts: 'focused' | 'global' | 'none'\n hideCursorWhenIdle: 'always' | 'fullscreen' | false\n children: React.ReactNode\n}\n\nconst VideoPlayerRootImpl = React.forwardRef<\n HTMLDivElement,\n VideoPlayerRootImplProps\n>(function VideoPlayerRootImpl(\n {\n rootRef,\n keyboardShortcuts,\n hideCursorWhenIdle,\n children,\n className,\n style,\n ...divProps\n },\n forwardedRef,\n) {\n const context = useVideoPlayer()\n const composedRef = useComposedRef(forwardedRef, rootRef)\n const lastMousePosition = React.useRef<{ x: number; y: number } | null>(null)\n\n // Keyboard shortcuts\n useKeyboardShortcuts(rootRef, keyboardShortcuts)\n\n // Mouse handlers for idle detection\n const handleMouseMove = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n const { clientX, clientY } = event\n const last = lastMousePosition.current\n if (last && last.x === clientX && last.y === clientY) {\n return\n }\n lastMousePosition.current = { x: clientX, y: clientY }\n context.resetIdle()\n },\n [context],\n )\n\n const handleMouseEnter = React.useCallback(\n (event: React.MouseEvent<HTMLDivElement>) => {\n const { clientX, clientY } = event\n const last = lastMousePosition.current\n if (last && last.x === clientX && last.y === clientY) {\n return\n }\n lastMousePosition.current = { x: clientX, y: clientY }\n context.resetIdle()\n },\n [context],\n )\n\n const handleMouseLeave = React.useCallback(() => {\n context._handlers.onRootMouseLeave()\n }, [context._handlers])\n\n const handleClick = React.useCallback(() => {\n context.resetIdle()\n }, [context])\n\n // Data attributes for styling\n const dataAttributes = {\n [RootDataAttributes.playing]: context.playing || undefined,\n [RootDataAttributes.paused]: context.paused || undefined,\n [RootDataAttributes.ended]: context.ended || undefined,\n [RootDataAttributes.waiting]: context.waiting || undefined,\n [RootDataAttributes.seeking]: context.seeking || undefined,\n [RootDataAttributes.fullscreen]: context.fullscreen || undefined,\n [RootDataAttributes.pip]: context.pictureInPicture || undefined,\n [RootDataAttributes.muted]: context.muted || undefined,\n [RootDataAttributes.idle]: context.idle || undefined,\n }\n\n // Determine if cursor should be hidden based on hideCursorWhenIdle prop\n const shouldHideCursor =\n hideCursorWhenIdle !== false &&\n context.idle &&\n (hideCursorWhenIdle === 'always' ||\n (hideCursorWhenIdle === 'fullscreen' && context.fullscreen))\n\n // Generate a stable ID for scoped CSS\n const scopeId = React.useId()\n\n return (\n // biome-ignore lint/a11y/noStaticElementInteractions: allowed\n <div\n ref={composedRef}\n tabIndex={keyboardShortcuts === 'focused' ? 0 : undefined}\n className={className}\n style={style}\n data-video-player-scope={scopeId}\n {...dataAttributes}\n {...divProps}\n onMouseMove={handleMouseMove}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onClick={handleClick}\n >\n {/* Inject scoped style to hide cursor - uses !important to override child styles */}\n {shouldHideCursor && (\n <style>{`[data-video-player-scope=\"${scopeId}\"], [data-video-player-scope=\"${scopeId}\"] * { cursor: none !important; }`}</style>\n )}\n {children}\n </div>\n )\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace VideoPlayerRoot {\n export type Props = VideoPlayerRootProps\n export type State = VideoPlayerRootState\n}\n\n// ============================================================================\n// Utility: Compose Refs\n// ============================================================================\n\nfunction useComposedRef<T>(\n ...refs: (React.Ref<T> | undefined)[]\n): React.RefCallback<T> {\n return React.useCallback(\n (node: T) => {\n for (const ref of refs) {\n if (typeof ref === 'function') {\n ref(node)\n } else if (ref != null) {\n ;(ref as React.RefObject<T>).current = node\n }\n }\n },\n // biome-ignore lint/correctness/useExhaustiveDependencies: allowed\n refs,\n )\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayer } from './use-video-player.js'\n\ntype KeyboardShortcutsScope = 'focused' | 'global' | 'none'\n\nexport function useKeyboardShortcuts(\n rootRef: React.RefObject<HTMLElement | null>,\n scope: KeyboardShortcutsScope,\n) {\n const context = useVideoPlayer()\n\n // Use ref to get fresh values in event handler without re-subscribing\n const contextRef = React.useRef(context)\n contextRef.current = context\n\n React.useEffect(() => {\n if (scope === 'none') return\n\n const handleKeyDown = (e: KeyboardEvent) => {\n // Ignore if user is typing in an input\n const target = e.target as HTMLElement\n if (\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable\n ) {\n return\n }\n\n const ctx = contextRef.current\n\n switch (e.key) {\n case ' ':\n e.preventDefault()\n ctx.toggle()\n break\n case 'f':\n case 'F':\n e.preventDefault()\n ctx.toggleFullscreen()\n break\n case 'ArrowUp':\n e.preventDefault()\n ctx.setVolume(Math.min(ctx.volume + 0.1, 1))\n break\n case 'ArrowDown':\n e.preventDefault()\n ctx.setVolume(Math.max(ctx.volume - 0.1, 0))\n break\n case 'ArrowRight':\n e.preventDefault()\n ctx.seek(Math.min(ctx.currentTime + 5, ctx.duration))\n break\n case 'ArrowLeft':\n e.preventDefault()\n ctx.seek(Math.max(ctx.currentTime - 5, 0))\n break\n default:\n return\n }\n\n ctx.resetIdle()\n }\n\n if (scope === 'global') {\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }\n\n // 'focused' scope - attach to root element\n const root = rootRef.current\n if (!root) return\n\n root.addEventListener('keydown', handleKeyDown)\n return () => root.removeEventListener('keydown', handleKeyDown)\n }, [scope, rootRef])\n}\n","export enum SeekSliderCssVars {\n /** Current playback progress as a percentage (e.g., \"45%\"). */\n progress = '--seek-progress',\n /** Buffered progress as a percentage (e.g., \"80%\"). */\n buffered = '--seek-buffered',\n /** Current playback time in seconds. */\n currentTime = '--seek-current-time',\n /** Total video duration in seconds. */\n duration = '--seek-duration',\n /** Hover position as a percentage (e.g., \"60%\"). Only set when hovering. */\n hoverProgress = '--seek-hover-progress',\n /** Hover time in seconds. Only set when hovering. */\n hoverTime = '--seek-hover-time',\n}\n","export enum SeekSliderDataAttributes {\n /** Applied when the video is actively seeking. */\n seeking = 'data-seeking',\n /** Applied when the pointer is hovering over the slider. */\n hovering = 'data-hovering',\n /** Applied when the pointer is pressed down on the slider. */\n pressing = 'data-pressing',\n /** Applied when the user is actively dragging the slider thumb. */\n dragging = 'data-dragging',\n}\n","'use client'\n\nimport { Slider, type SliderRoot } from '@base-ui/react/slider'\nimport {\n autoUpdate,\n offset,\n type Padding,\n shift,\n useFloating,\n} from '@floating-ui/react'\nimport * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport { useTransitionStatus } from '../../hooks/use-transition-status.js'\nimport type { RenderProp } from '../../types.js'\nimport { SeekSliderCssVars } from './seek-slider.css-vars.js'\nimport { SeekSliderDataAttributes } from './seek-slider.data-attributes.js'\nimport { SeekSliderPreviewThumbDataAttributes } from './seek-slider-preview-thumb.data-attributes.js'\n\n// ============================================================================\n// SeekSlider Context (for sharing refs between SeekSlider children)\n// ============================================================================\n\ninterface SeekSliderContextValue {\n sliderRef: React.RefObject<HTMLDivElement | null>\n previewThumbElement: HTMLElement | null\n setPreviewThumbElement: (element: HTMLElement | null) => void\n hoverProgress: number\n open: boolean\n}\n\nconst SeekSliderContext = React.createContext<SeekSliderContextValue | null>(\n null,\n)\n\nfunction useSeekSliderContext(componentName: string) {\n const context = React.useContext(SeekSliderContext)\n if (!context) {\n throw new Error(`${componentName} must be used within SeekSlider`)\n }\n return context\n}\n\n// ============================================================================\n// SeekSlider Props\n// ============================================================================\n\nexport interface SeekSliderProps\n extends Omit<\n React.ComponentPropsWithRef<typeof Slider.Root>,\n 'value' | 'onValueChange' | 'min' | 'max' | 'children' | 'render'\n > {\n render?: RenderProp<SeekSliderRenderProps, SeekSliderState>\n children?: React.ReactNode\n}\n\nexport interface SeekSliderRenderProps {\n [SeekSliderDataAttributes.seeking]?: boolean\n [SeekSliderDataAttributes.hovering]?: boolean\n [SeekSliderDataAttributes.pressing]?: boolean\n [SeekSliderDataAttributes.dragging]?: boolean\n style: React.CSSProperties\n}\n\nexport interface SeekSliderState {\n currentTime: number\n duration: number\n progress: number\n seeking: boolean\n pressing: boolean\n dragging: boolean\n hoverTime: number | null\n hoverProgress: number | null\n}\n\n// ============================================================================\n// SeekSlider Component\n// ============================================================================\n\nexport const SeekSlider = React.forwardRef<\n React.ComponentRef<typeof Slider.Root>,\n SeekSliderProps\n>(function SeekSlider(props, forwardedRef) {\n const {\n render,\n children,\n onPointerMove,\n onPointerLeave,\n onPointerDown,\n onValueCommitted,\n ...sliderProps\n } = props\n const context = useVideoPlayerContext('SeekSlider')\n const sliderRef = React.useRef<HTMLDivElement | null>(null)\n const [previewThumbElement, setPreviewThumbElement] =\n React.useState<HTMLElement | null>(null)\n const [pressing, setPressing] = React.useState(false)\n const [dragging, setDragging] = React.useState(false)\n const pressingRef = React.useRef(false)\n\n React.useEffect(() => {\n if (!pressing) return\n\n const handleGlobalPointerUp = () => {\n setPressing(false)\n setDragging(false)\n pressingRef.current = false\n }\n\n window.addEventListener('pointerup', handleGlobalPointerUp)\n return () => window.removeEventListener('pointerup', handleGlobalPointerUp)\n }, [pressing])\n\n const progress =\n context.duration > 0 ? (context.currentTime / context.duration) * 100 : 0\n\n const handleValueChange = React.useCallback(\n (value: number | readonly number[]) => {\n const v = typeof value === 'number' ? value : value[0]\n if (v === undefined) return\n context.seek(v)\n context.resetIdle()\n if (pressingRef.current) {\n setDragging(true)\n }\n },\n [context],\n )\n\n const handlePointerMove = React.useCallback(\n (event: React.PointerEvent) => {\n onPointerMove?.(event as any)\n if (!sliderRef.current || context.duration === 0) return\n\n const rect = sliderRef.current.getBoundingClientRect()\n const x = event.clientX - rect.left\n const percentage = Math.max(0, Math.min(1, x / rect.width))\n const time = percentage * context.duration\n\n context.setHoverTime(time)\n },\n [onPointerMove, context],\n )\n\n const handlePointerLeave = React.useCallback(\n (event: React.PointerEvent) => {\n onPointerLeave?.(event as any)\n context.setHoverTime(null)\n },\n [onPointerLeave, context],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent) => {\n onPointerDown?.(event as any)\n setPressing(true)\n pressingRef.current = true\n },\n [onPointerDown],\n )\n\n const handleValueCommitted = React.useCallback(\n (\n value: number | readonly number[],\n eventDetails: SliderRoot.CommitEventDetails,\n ) => {\n const v = typeof value === 'number' ? value : value[0]\n if (v === undefined) return\n onValueCommitted?.(v, eventDetails)\n setPressing(false)\n setDragging(false)\n pressingRef.current = false\n },\n [onValueCommitted],\n )\n\n const bufferedEnd = React.useMemo(() => {\n if (!context.buffered || context.buffered.length === 0) return 0\n for (let i = 0; i < context.buffered.length; i++) {\n if (\n context.buffered.start(i) <= context.currentTime &&\n context.currentTime <= context.buffered.end(i)\n ) {\n return context.buffered.end(i)\n }\n }\n return context.buffered.end(0)\n }, [context.buffered, context.currentTime])\n\n const bufferedPercentage =\n context.duration > 0 ? (bufferedEnd / context.duration) * 100 : 0\n\n // Sync internal ref with forwarded ref\n React.useLayoutEffect(() => {\n if (typeof forwardedRef === 'function') {\n forwardedRef(sliderRef.current)\n } else if (forwardedRef) {\n forwardedRef.current = sliderRef.current\n }\n })\n\n const state: SeekSliderState = {\n currentTime: context.currentTime,\n duration: context.duration,\n progress,\n seeking: context.seeking,\n pressing,\n dragging,\n hoverTime: context.hoverTime,\n hoverProgress: context.hoverProgress,\n }\n\n // Context value for child components (PreviewThumb, Tooltip)\n const open = context.hoverProgress !== null\n const hoverProgress = context.hoverProgress ?? 0\n // biome-ignore lint/correctness/useExhaustiveDependencies: allowed\n const seekSliderContextValue = React.useMemo<SeekSliderContextValue>(\n () => ({\n sliderRef,\n previewThumbElement,\n setPreviewThumbElement,\n hoverProgress,\n open,\n }),\n [\n sliderRef,\n previewThumbElement,\n setPreviewThumbElement,\n hoverProgress,\n open,\n ],\n )\n\n const style = {\n position: 'relative',\n [SeekSliderCssVars.progress]: `${progress}%`,\n [SeekSliderCssVars.buffered]: `${bufferedPercentage}%`,\n [SeekSliderCssVars.currentTime]: context.currentTime,\n [SeekSliderCssVars.duration]: context.duration,\n [SeekSliderCssVars.hoverProgress]:\n context.hoverProgress !== null ? `${context.hoverProgress}%` : undefined,\n [SeekSliderCssVars.hoverTime]: context.hoverTime ?? undefined,\n ...sliderProps.style,\n } as unknown as React.CSSProperties\n\n const renderProps: SeekSliderRenderProps = {\n [SeekSliderDataAttributes.seeking]: context.seeking || undefined,\n [SeekSliderDataAttributes.hovering]:\n context.hoverTime !== null || undefined,\n [SeekSliderDataAttributes.pressing]: pressing || undefined,\n [SeekSliderDataAttributes.dragging]: dragging || undefined,\n style,\n }\n\n // Render prop: use Base UI's render prop to customize the root element\n if (render) {\n return (\n <SeekSliderContext.Provider value={seekSliderContextValue}>\n <Slider.Root\n ref={sliderRef}\n min={0}\n max={context.duration || 100}\n step={0.1}\n value={context.currentTime}\n onValueChange={handleValueChange}\n onValueCommitted={handleValueCommitted}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n onPointerDown={handlePointerDown}\n aria-label=\"Seek\"\n render={(baseProps) =>\n render(\n {\n ...baseProps,\n ...renderProps,\n style: { ...baseProps.style, ...renderProps.style },\n },\n state,\n )\n }\n />\n </SeekSliderContext.Provider>\n )\n }\n\n return (\n <SeekSliderContext.Provider value={seekSliderContextValue}>\n <Slider.Root\n ref={sliderRef}\n min={0}\n max={context.duration || 100}\n step={0.1}\n value={context.currentTime}\n onValueChange={handleValueChange}\n onValueCommitted={handleValueCommitted}\n onPointerMove={handlePointerMove}\n onPointerLeave={handlePointerLeave}\n onPointerDown={handlePointerDown}\n aria-label=\"Seek\"\n {...renderProps}\n {...sliderProps}\n >\n {children ?? (\n <Slider.Control>\n <Slider.Track style={{ position: 'relative' }}>\n <div\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n height: '100%',\n width: `${bufferedPercentage}%`,\n }}\n />\n <Slider.Indicator />\n <Slider.Thumb />\n </Slider.Track>\n </Slider.Control>\n )}\n </Slider.Root>\n </SeekSliderContext.Provider>\n )\n})\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\n// SeekSliderControl - wrapper for Slider.Control\nexport const SeekSliderControl = Slider.Control\n\n// SeekSliderTrack\nexport interface SeekSliderTrackProps\n extends Omit<\n React.ComponentPropsWithRef<typeof Slider.Track>,\n 'render' | 'children'\n > {\n render?: RenderProp<SeekSliderTrackRenderProps, SeekSliderTrackState>\n children?: React.ReactNode\n}\n\nexport interface SeekSliderTrackRenderProps {\n ref: React.Ref<any>\n style: React.CSSProperties\n}\n\nexport type SeekSliderTrackState = {}\n\nexport const SeekSliderTrack = React.forwardRef<\n React.ComponentRef<typeof Slider.Track>,\n SeekSliderTrackProps\n>(function SeekSliderTrack(props, forwardedRef) {\n const { render, children, style, ...trackProps } = props\n\n const state: SeekSliderTrackState = {}\n\n // Always apply position: relative so children with position: absolute work correctly\n const trackStyle: React.CSSProperties = {\n position: 'relative',\n ...style,\n }\n\n const renderProps: SeekSliderTrackRenderProps = {\n ref: forwardedRef,\n style: trackStyle,\n }\n\n if (render) {\n return (\n <Slider.Track\n render={(baseProps) => render({ ...baseProps, ...renderProps }, state)}\n />\n )\n }\n\n return (\n <Slider.Track ref={forwardedRef} style={trackStyle} {...trackProps}>\n {children}\n </Slider.Track>\n )\n})\n\n// SeekSliderProgress\nexport interface SeekSliderProgressProps\n extends Omit<\n React.ComponentPropsWithRef<typeof Slider.Indicator>,\n 'render' | 'children'\n > {\n render?: RenderProp<SeekSliderProgressRenderProps, SeekSliderProgressState>\n children?: React.ReactNode\n}\n\nexport interface SeekSliderProgressRenderProps {\n ref: React.Ref<any>\n style: React.CSSProperties\n}\n\nexport interface SeekSliderProgressState {\n progress: number\n}\n\nexport const SeekSliderProgress = React.forwardRef<\n React.ComponentRef<typeof Slider.Indicator>,\n SeekSliderProgressProps\n>(function SeekSliderProgress(props, forwardedRef) {\n const { render, children, style, ...indicatorProps } = props\n const context = useVideoPlayerContext('SeekSliderProgress')\n\n const progress =\n context.duration > 0 ? (context.currentTime / context.duration) * 100 : 0\n\n const state: SeekSliderProgressState = { progress }\n\n // Base UI handles positioning internally via inline styles\n // We only add height: 100% to ensure it fills the track vertically\n const indicatorStyle: React.CSSProperties = {\n height: '100%',\n ...style,\n }\n\n const renderProps: SeekSliderProgressRenderProps = {\n ref: forwardedRef,\n style: indicatorStyle,\n }\n\n if (render) {\n return (\n <Slider.Indicator\n render={(baseProps) =>\n render(\n {\n ...baseProps,\n ...renderProps,\n style: { ...baseProps.style, ...indicatorStyle },\n },\n state,\n )\n }\n />\n )\n }\n\n return (\n <Slider.Indicator\n ref={forwardedRef}\n style={indicatorStyle}\n {...indicatorProps}\n >\n {children}\n </Slider.Indicator>\n )\n})\n\n// SeekSliderThumb\nexport interface SeekSliderThumbProps\n extends Omit<\n React.ComponentPropsWithRef<typeof Slider.Thumb>,\n 'render' | 'children'\n > {\n render?: RenderProp<SeekSliderThumbRenderProps, SeekSliderThumbState>\n children?: React.ReactNode\n}\n\nexport interface SeekSliderThumbRenderProps {\n ref: React.Ref<any>\n style: React.CSSProperties\n}\n\nexport type SeekSliderThumbState = {}\n\nexport const SeekSliderThumb = React.forwardRef<\n React.ComponentRef<typeof Slider.Thumb>,\n SeekSliderThumbProps\n>(function SeekSliderThumb(props, forwardedRef) {\n const { render, children, style, ...thumbProps } = props\n\n const state: SeekSliderThumbState = {}\n\n // Base UI handles positioning internally (position, insetInlineStart, top, translate)\n // We just pass through user styles\n const renderProps: SeekSliderThumbRenderProps = {\n ref: forwardedRef,\n style: style ?? {},\n }\n\n if (render) {\n return (\n <Slider.Thumb\n render={(baseProps) =>\n render(\n {\n ...baseProps,\n ...renderProps,\n style: { ...baseProps.style, ...style },\n },\n state,\n )\n }\n />\n )\n }\n\n return (\n <Slider.Thumb ref={forwardedRef} style={style} {...thumbProps}>\n {children}\n </Slider.Thumb>\n )\n})\n\n// SeekSliderBuffered\nexport interface SeekSliderBufferedProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {\n render?: RenderProp<SeekSliderBufferedRenderProps, SeekSliderBufferedState>\n children?: React.ReactNode\n}\n\nexport interface SeekSliderBufferedRenderProps {\n ref: React.Ref<HTMLDivElement>\n style: React.CSSProperties\n}\n\nexport interface SeekSliderBufferedState {\n bufferedPercentage: number\n}\n\nexport const SeekSliderBuffered = React.forwardRef<\n HTMLDivElement,\n SeekSliderBufferedProps\n>(function SeekSliderBuffered(props, forwardedRef) {\n const { render, children, ...divProps } = props\n const context = useVideoPlayerContext('SeekSliderBuffered')\n\n const bufferedEnd = React.useMemo(() => {\n if (!context.buffered || context.buffered.length === 0) return 0\n for (let i = 0; i < context.buffered.length; i++) {\n if (\n context.buffered.start(i) <= context.currentTime &&\n context.currentTime <= context.buffered.end(i)\n ) {\n return context.buffered.end(i)\n }\n }\n return context.buffered.end(0)\n }, [context.buffered, context.currentTime])\n\n const bufferedPercentage =\n context.duration > 0 ? (bufferedEnd / context.duration) * 100 : 0\n\n const state: SeekSliderBufferedState = { bufferedPercentage }\n\n const style: React.CSSProperties = {\n position: 'absolute',\n left: 0,\n top: 0,\n height: '100%',\n width: `${bufferedPercentage}%`,\n ...divProps.style,\n }\n\n const renderProps: SeekSliderBufferedRenderProps = {\n ref: forwardedRef,\n style,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <div {...renderProps} {...divProps}>\n {children}\n </div>\n )\n})\n\n// SeekSliderPreviewThumb\nexport interface SeekSliderPreviewThumbProps\n extends Omit<React.ComponentPropsWithRef<'span'>, 'children'> {\n keepMounted?: boolean\n render?: RenderProp<\n SeekSliderPreviewThumbRenderProps,\n SeekSliderPreviewThumbState\n >\n children?: React.ReactNode\n}\n\nexport interface SeekSliderPreviewThumbRenderProps {\n ref: React.Ref<any>\n style: React.CSSProperties\n [SeekSliderPreviewThumbDataAttributes.open]?: boolean\n [SeekSliderPreviewThumbDataAttributes.closed]?: boolean\n [SeekSliderPreviewThumbDataAttributes.startingStyle]?: boolean\n [SeekSliderPreviewThumbDataAttributes.endingStyle]?: boolean\n}\n\nexport interface SeekSliderPreviewThumbState {\n open: boolean\n transitionStatus: 'starting' | 'ending' | undefined\n hoverProgress: number\n}\n\nexport const SeekSliderPreviewThumb = React.forwardRef<\n HTMLSpanElement,\n SeekSliderPreviewThumbProps\n>(function SeekSliderPreviewThumb(props, forwardedRef) {\n const { keepMounted = false, render, children, ...spanProps } = props\n const context = useVideoPlayerContext('SeekSliderPreviewThumb')\n const seekSliderContext = useSeekSliderContext('SeekSliderPreviewThumb')\n\n const open = context.hoverProgress !== null\n\n const lastProgressRef = React.useRef<number>(0)\n if (context.hoverProgress !== null) {\n lastProgressRef.current = context.hoverProgress\n }\n\n const hoverProgress = context.hoverProgress ?? lastProgressRef.current\n\n const { mounted, transitionStatus, elementRef } = useTransitionStatus({\n open,\n keepMounted,\n })\n\n const composedRef = React.useCallback(\n (node: HTMLSpanElement | null) => {\n ;(elementRef as React.MutableRefObject<HTMLElement | null>).current = node\n // Register with SeekSlider context for Tooltip to use as anchor\n seekSliderContext.setPreviewThumbElement(node)\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef, elementRef, seekSliderContext],\n )\n\n const state: SeekSliderPreviewThumbState = {\n open,\n transitionStatus,\n hoverProgress,\n }\n\n const style: React.CSSProperties = {\n position: 'absolute',\n left: `${hoverProgress}%`,\n transform: 'translateX(-50%)',\n pointerEvents: 'none',\n ...spanProps.style,\n }\n\n const renderProps: SeekSliderPreviewThumbRenderProps = {\n ref: composedRef,\n style,\n [SeekSliderPreviewThumbDataAttributes.open]: open || undefined,\n [SeekSliderPreviewThumbDataAttributes.closed]: !open || undefined,\n [SeekSliderPreviewThumbDataAttributes.startingStyle]:\n transitionStatus === 'starting' || undefined,\n [SeekSliderPreviewThumbDataAttributes.endingStyle]:\n transitionStatus === 'ending' || undefined,\n }\n\n if (!mounted) {\n return null\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <span {...renderProps} {...spanProps}>\n {children}\n </span>\n )\n})\n\n// SeekSliderHover\nexport interface SeekSliderHoverProps\n extends Omit<React.ComponentPropsWithRef<'div'>, 'children'> {\n render?: RenderProp<SeekSliderHoverRenderProps, SeekSliderHoverState>\n children?: React.ReactNode\n}\n\nexport interface SeekSliderHoverRenderProps {\n ref: React.Ref<HTMLDivElement>\n style: React.CSSProperties\n 'data-hovering'?: boolean\n}\n\nexport interface SeekSliderHoverState {\n hovering: boolean\n hoverProgress: number | null\n hoverTime: number | null\n}\n\nexport const SeekSliderHover = React.forwardRef<\n HTMLDivElement,\n SeekSliderHoverProps\n>(function SeekSliderHover(props, forwardedRef) {\n const { render, children, style: styleProp, ...divProps } = props\n const context = useVideoPlayerContext('SeekSliderHover')\n\n const hovering = context.hoverProgress !== null\n const hoverProgress = context.hoverProgress ?? 0\n\n const state: SeekSliderHoverState = {\n hovering,\n hoverProgress: context.hoverProgress,\n hoverTime: context.hoverTime,\n }\n\n const style: React.CSSProperties = {\n position: 'absolute',\n left: 0,\n top: 0,\n height: '100%',\n width: `${hoverProgress}%`,\n pointerEvents: 'none',\n ...styleProp,\n }\n\n const renderProps: SeekSliderHoverRenderProps = {\n ref: forwardedRef,\n style,\n 'data-hovering': hovering || undefined,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <div {...renderProps} {...divProps}>\n {children}\n </div>\n )\n})\n\n// ============================================================================\n// SeekSliderPreviewTooltip Components\n// ============================================================================\n\n// Portal - renders content in a portal (defaults to VideoPlayer root for correct stacking context)\nexport interface SeekSliderPreviewTooltipPortalProps {\n children: React.ReactNode\n /** Portal container. Defaults to the VideoPlayer root element. */\n container?: Element | null\n}\n\nexport function SeekSliderPreviewTooltipPortal({\n children,\n container,\n}: SeekSliderPreviewTooltipPortalProps) {\n const videoPlayerContext = useVideoPlayerContext(\n 'SeekSliderPreviewTooltipPortal',\n )\n const [mounted, setMounted] = React.useState(false)\n\n React.useEffect(() => {\n setMounted(true)\n }, [])\n\n if (!mounted) return null\n\n // Default to VideoPlayer root for correct stacking context (z-index works within the player)\n const portalContainer =\n container ?? videoPlayerContext.rootRef.current ?? document.body\n return ReactDOM.createPortal(children, portalContainer)\n}\n\n// Positioner - handles Floating UI positioning\nexport interface SeekSliderPreviewTooltipPositionerProps\n extends React.ComponentPropsWithRef<'div'> {\n /** Offset from the anchor (thumb) in pixels (default: 8) */\n sideOffset?: number\n /** Padding from collision boundary edges (default: 0) */\n collisionPadding?: Padding\n /** Custom collision boundary element(s) */\n collisionBoundary?: Element | Element[]\n /** Keep mounted in DOM even when closed (default: false) */\n keepMounted?: boolean\n children?: React.ReactNode\n}\n\nexport const SeekSliderPreviewTooltipPositioner = React.forwardRef<\n HTMLDivElement,\n SeekSliderPreviewTooltipPositionerProps\n>(function SeekSliderPreviewTooltipPositioner(props, forwardedRef) {\n const {\n sideOffset = 8,\n collisionPadding = 0,\n collisionBoundary,\n keepMounted = false,\n children,\n style: styleProp,\n ...divProps\n } = props\n\n const seekSliderContext = useSeekSliderContext(\n 'SeekSliderPreviewTooltipPositioner',\n )\n const { previewThumbElement, open, hoverProgress } = seekSliderContext\n const [floatingElement, setFloatingElement] =\n React.useState<HTMLDivElement | null>(null)\n\n const { refs, floatingStyles, update } = useFloating({\n placement: 'top',\n middleware: [\n offset(sideOffset),\n shift({\n boundary: collisionBoundary,\n padding: collisionPadding,\n }),\n ],\n })\n\n // Set reference element when it becomes available (following Base UI pattern)\n React.useLayoutEffect(() => {\n if (previewThumbElement) {\n refs.setReference(previewThumbElement)\n }\n }, [previewThumbElement, refs])\n\n // Set up autoUpdate when both elements are available\n React.useEffect(() => {\n if (open && previewThumbElement && floatingElement) {\n return autoUpdate(previewThumbElement, floatingElement, update)\n }\n }, [open, previewThumbElement, floatingElement, update])\n\n // Update position when hover progress changes (PreviewThumb moves via CSS)\n // biome-ignore lint/correctness/useExhaustiveDependencies: see above\n React.useLayoutEffect(() => {\n if (open && previewThumbElement && floatingElement) {\n update()\n }\n }, [hoverProgress, open, previewThumbElement, floatingElement, update])\n\n // Merge refs - track floating element with state for effect dependencies\n const mergedRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n refs.setFloating(node)\n setFloatingElement(node)\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [refs, forwardedRef],\n )\n\n // Don't render until we have the reference element (and open, unless keepMounted)\n const shouldRender = keepMounted\n ? !!previewThumbElement\n : open && !!previewThumbElement\n if (!shouldRender) return null\n\n return (\n <div\n ref={mergedRef}\n style={{ ...floatingStyles, ...styleProp }}\n data-seek-slider-preview-tooltip-positioner\n data-open={open || undefined}\n data-closed={!open || undefined}\n {...divProps}\n >\n {children}\n </div>\n )\n})\n\n// Popup - simple content wrapper\nexport interface SeekSliderPreviewTooltipPopupProps\n extends React.ComponentPropsWithRef<'div'> {\n children?: React.ReactNode\n}\n\nexport const SeekSliderPreviewTooltipPopup = React.forwardRef<\n HTMLDivElement,\n SeekSliderPreviewTooltipPopupProps\n>(function SeekSliderPreviewTooltipPopup(props, forwardedRef) {\n const { children, ...divProps } = props\n\n return (\n <div\n ref={forwardedRef}\n data-seek-slider-preview-tooltip-popup\n {...divProps}\n >\n {children}\n </div>\n )\n})\n\n// Simplified combined component\nexport interface SeekSliderPreviewTooltipProps\n extends Omit<SeekSliderPreviewTooltipPopupProps, 'ref'> {\n /** Offset from the anchor (thumb) in pixels (default: 8) */\n sideOffset?: number\n /** Padding from collision boundary edges (default: 0) */\n collisionPadding?: Padding\n /** Custom collision boundary element(s) */\n collisionBoundary?: Element | Element[]\n /** Keep mounted in DOM even when closed (default: false) */\n keepMounted?: boolean\n /** Portal container element */\n container?: Element | null\n}\n\nexport function SeekSliderPreviewTooltip({\n sideOffset,\n collisionPadding,\n collisionBoundary,\n keepMounted,\n container,\n children,\n ...popupProps\n}: SeekSliderPreviewTooltipProps) {\n return (\n <SeekSliderPreviewTooltipPortal container={container}>\n <SeekSliderPreviewTooltipPositioner\n sideOffset={sideOffset}\n collisionPadding={collisionPadding}\n collisionBoundary={collisionBoundary}\n keepMounted={keepMounted}\n >\n <SeekSliderPreviewTooltipPopup {...popupProps}>\n {children}\n </SeekSliderPreviewTooltipPopup>\n </SeekSliderPreviewTooltipPositioner>\n </SeekSliderPreviewTooltipPortal>\n )\n}\n\n// Attach sub-components for composition pattern\nSeekSliderPreviewTooltip.Portal = SeekSliderPreviewTooltipPortal\nSeekSliderPreviewTooltip.Positioner = SeekSliderPreviewTooltipPositioner\nSeekSliderPreviewTooltip.Popup = SeekSliderPreviewTooltipPopup\n\n// ============================================================================\n// Namespaces\n// ============================================================================\n\nexport namespace SeekSlider {\n export type Props = SeekSliderProps\n export type State = SeekSliderState\n export type RenderProps = SeekSliderRenderProps\n}\n\nexport namespace SeekSliderTrack {\n export type Props = SeekSliderTrackProps\n export type State = SeekSliderTrackState\n export type RenderProps = SeekSliderTrackRenderProps\n}\n\nexport namespace SeekSliderProgress {\n export type Props = SeekSliderProgressProps\n export type State = SeekSliderProgressState\n export type RenderProps = SeekSliderProgressRenderProps\n}\n\nexport namespace SeekSliderThumb {\n export type Props = SeekSliderThumbProps\n export type State = SeekSliderThumbState\n export type RenderProps = SeekSliderThumbRenderProps\n}\n\nexport namespace SeekSliderBuffered {\n export type Props = SeekSliderBufferedProps\n export type State = SeekSliderBufferedState\n export type RenderProps = SeekSliderBufferedRenderProps\n}\n\nexport namespace SeekSliderPreviewThumb {\n export type Props = SeekSliderPreviewThumbProps\n export type State = SeekSliderPreviewThumbState\n export type RenderProps = SeekSliderPreviewThumbRenderProps\n}\n\nexport namespace SeekSliderHover {\n export type Props = SeekSliderHoverProps\n export type State = SeekSliderHoverState\n export type RenderProps = SeekSliderHoverRenderProps\n}\n\nexport namespace SeekSliderPreviewTooltip {\n export type Props = SeekSliderPreviewTooltipProps\n export type PortalProps = SeekSliderPreviewTooltipPortalProps\n export type PositionerProps = SeekSliderPreviewTooltipPositionerProps\n export type PopupProps = SeekSliderPreviewTooltipPopupProps\n}\n","export enum SeekSliderPreviewThumbDataAttributes {\n /** Applied when the preview thumb is visible (hovering over slider). */\n open = 'data-open',\n /** Applied when the preview thumb is hidden (not hovering). */\n closed = 'data-closed',\n /** Applied on the first frame when entering. Use for CSS enter animations. */\n startingStyle = 'data-starting-style',\n /** Applied during exit animation. Use for CSS exit animations. */\n endingStyle = 'data-ending-style',\n}\n","export enum ThumbnailDataAttributes {\n loading = 'data-loading',\n ready = 'data-ready',\n error = 'data-error',\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { ThumbnailDataAttributes } from './thumbnail.data-attributes.js'\n\n// ============================================================================\n// Thumbnail Props\n// ============================================================================\n\nexport interface ThumbnailProps\n extends Omit<React.ComponentPropsWithRef<'canvas'>, 'children'> {\n /**\n * The time in seconds to capture the thumbnail from.\n * If not provided, uses the current hoverTime from context.\n */\n time?: number | null\n /**\n * Crossorigin attribute for the hidden video element.\n * Should match the main video's crossOrigin attribute.\n * @default 'anonymous'\n */\n crossOrigin?: '' | 'anonymous' | 'use-credentials'\n /**\n * Render prop for custom rendering.\n */\n render?: RenderProp<ThumbnailRenderProps, ThumbnailState>\n children?: React.ReactNode\n}\n\nexport interface ThumbnailRenderProps {\n ref: React.Ref<HTMLCanvasElement>\n width: number\n height: number\n [ThumbnailDataAttributes.loading]?: boolean\n [ThumbnailDataAttributes.ready]?: boolean\n [ThumbnailDataAttributes.error]?: boolean\n}\n\nexport interface ThumbnailState {\n loading: boolean\n ready: boolean\n error: boolean\n time: number | null\n /** Natural width of the video */\n videoWidth: number\n /** Natural height of the video */\n videoHeight: number\n}\n\n// ============================================================================\n// Thumbnail Component\n// ============================================================================\n\nexport const Thumbnail = React.forwardRef<HTMLCanvasElement, ThumbnailProps>(\n function Thumbnail(props, forwardedRef) {\n const {\n time: timeProp,\n crossOrigin = 'anonymous',\n render,\n children,\n width: widthProp,\n height: heightProp,\n ...canvasProps\n } = props\n\n const context = useVideoPlayerContext('Thumbnail')\n const canvasRef = React.useRef<HTMLCanvasElement>(null)\n const videoRef = React.useRef<HTMLVideoElement | null>(null)\n const lastDrawnTimeRef = React.useRef<number | null>(null)\n\n const [status, setStatus] = React.useState<\n 'idle' | 'loading' | 'ready' | 'error'\n >('idle')\n const [videoDimensions, setVideoDimensions] = React.useState({\n width: 160,\n height: 90,\n })\n\n // Use prop time or hoverTime from context\n const time = timeProp !== undefined ? timeProp : context.hoverTime\n\n // Get the video source from the main video element\n const videoSrc = React.useMemo(() => {\n const mainVideo = context.videoRef.current\n if (!mainVideo) return null\n return mainVideo.currentSrc || mainVideo.src\n }, [context.videoRef])\n\n // Create and manage the hidden video element\n React.useEffect(() => {\n if (!videoSrc) return\n\n const video = document.createElement('video')\n video.src = videoSrc\n video.crossOrigin = crossOrigin\n video.preload = 'metadata'\n video.muted = true\n video.playsInline = true\n\n const handleLoadedMetadata = () => {\n setVideoDimensions({\n width: video.videoWidth,\n height: video.videoHeight,\n })\n }\n\n const handleError = () => {\n setStatus('error')\n }\n\n video.addEventListener('loadedmetadata', handleLoadedMetadata)\n video.addEventListener('error', handleError)\n\n videoRef.current = video\n\n return () => {\n video.removeEventListener('loadedmetadata', handleLoadedMetadata)\n video.removeEventListener('error', handleError)\n video.src = ''\n videoRef.current = null\n }\n }, [videoSrc, crossOrigin])\n\n // Seek and capture frame when time changes\n React.useEffect(() => {\n const video = videoRef.current\n const canvas = canvasRef.current\n\n if (!video || !canvas || time === null || time === undefined) {\n return\n }\n\n // Skip if we already drew this time (with small tolerance)\n if (\n lastDrawnTimeRef.current !== null &&\n Math.abs(lastDrawnTimeRef.current - time) < 0.1\n ) {\n return\n }\n\n setStatus('loading')\n\n const handleSeeked = () => {\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n\n try {\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n lastDrawnTimeRef.current = time\n setStatus('ready')\n } catch {\n setStatus('error')\n }\n }\n\n video.addEventListener('seeked', handleSeeked, { once: true })\n video.currentTime = time\n\n return () => {\n video.removeEventListener('seeked', handleSeeked)\n }\n }, [time])\n\n // Compose refs\n const composedRef = React.useCallback(\n (node: HTMLCanvasElement | null) => {\n ;(canvasRef as React.RefObject<HTMLCanvasElement | null>).current = node\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n },\n [forwardedRef],\n )\n\n // Calculate dimensions - use props or derive from video aspect ratio\n const aspectRatio = videoDimensions.width / videoDimensions.height\n let width = widthProp ?? 160\n let height = heightProp ?? Math.round((width as number) / aspectRatio)\n\n if (typeof width === 'string') width = 160\n if (typeof height === 'string') height = 90\n\n const state: ThumbnailState = {\n loading: status === 'loading',\n ready: status === 'ready',\n error: status === 'error',\n time,\n videoWidth: videoDimensions.width,\n videoHeight: videoDimensions.height,\n }\n\n const renderProps: ThumbnailRenderProps = {\n ref: composedRef,\n width,\n height,\n [ThumbnailDataAttributes.loading]: status === 'loading' || undefined,\n [ThumbnailDataAttributes.ready]: status === 'ready' || undefined,\n [ThumbnailDataAttributes.error]: status === 'error' || undefined,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <canvas {...renderProps} {...canvasProps}>\n {children}\n </canvas>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Thumbnail {\n export type Props = ThumbnailProps\n export type State = ThumbnailState\n export type RenderProps = ThumbnailRenderProps\n}\n","export enum TimeDisplayDataAttributes {\n /** Applied when the seek slider is being hovered and hover time is available. */\n hovering = 'data-hovering',\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { TimeDisplayDataAttributes } from './time-display.data-attributes.js'\n\n// ============================================================================\n// TimeDisplay Props\n// ============================================================================\n\nexport type TimeDisplayFormat =\n | 'current'\n | 'duration'\n | 'remaining'\n | 'current / duration'\n | 'current / remaining'\n | 'hover'\n\nexport interface TimeDisplayProps extends React.ComponentPropsWithRef<'span'> {\n format?: TimeDisplayFormat\n /**\n * When true, reserves space for the maximum possible width based on\n * the duration format, preventing layout shift during playback/seeking.\n * @default true\n */\n fixedWidth?: boolean\n /**\n * Alignment of the text within the reserved space when fixedWidth is true.\n * @default 'left'\n */\n align?: 'left' | 'center' | 'right'\n render?: RenderProp<TimeDisplayRenderProps, TimeDisplayState>\n}\n\nexport interface TimeDisplayRenderProps {\n ref: React.Ref<HTMLElement>\n style: React.CSSProperties\n [TimeDisplayDataAttributes.hovering]?: boolean\n}\n\nexport interface TimeDisplayState {\n currentTime: number\n duration: number\n remaining: number\n hoverTime: number | null\n hovering: boolean\n formattedCurrent: string\n formattedDuration: string\n formattedRemaining: string\n formattedHover: string | null\n}\n\n// ============================================================================\n// TimeDisplay Component\n// ============================================================================\n\nexport const TimeDisplay = React.forwardRef<HTMLSpanElement, TimeDisplayProps>(\n function TimeDisplay(props, forwardedRef) {\n const {\n format = 'current / duration',\n fixedWidth = true,\n align = 'left',\n render,\n ...spanProps\n } = props\n const context = useVideoPlayerContext('TimeDisplay')\n\n // Preserve last hover time for exit animations\n const lastHoverTimeRef = React.useRef<number>(0)\n if (context.hoverTime !== null) {\n lastHoverTimeRef.current = context.hoverTime\n }\n\n const remaining = context.duration - context.currentTime\n const formattedCurrent = formatTime(context.currentTime)\n const formattedDuration = formatTime(context.duration)\n const formattedRemaining = formatTime(remaining)\n const formattedHover =\n context.hoverTime !== null\n ? formatTime(context.hoverTime)\n : formatTime(lastHoverTimeRef.current)\n\n const state: TimeDisplayState = {\n currentTime: context.currentTime,\n duration: context.duration,\n remaining,\n hoverTime: context.hoverTime,\n hovering: context.hoverTime !== null,\n formattedCurrent,\n formattedDuration,\n formattedRemaining,\n formattedHover,\n }\n\n const getDisplayText = (): string => {\n switch (format) {\n case 'current':\n return formattedCurrent\n case 'duration':\n return formattedDuration\n case 'remaining':\n return `-${formattedRemaining}`\n case 'current / duration':\n return `${formattedCurrent} / ${formattedDuration}`\n case 'current / remaining':\n return `${formattedCurrent} / -${formattedRemaining}`\n case 'hover':\n return formattedHover\n default:\n return `${formattedCurrent} / ${formattedDuration}`\n }\n }\n\n // Generate template string for fixed width based on duration format\n const getTemplateText = (): string => {\n const timeTemplate = getTimeTemplate(context.duration)\n switch (format) {\n case 'current':\n case 'duration':\n case 'hover':\n return timeTemplate\n case 'remaining':\n return `-${timeTemplate}`\n case 'current / duration':\n return `${timeTemplate} / ${timeTemplate}`\n case 'current / remaining':\n return `${timeTemplate} / -${timeTemplate}`\n default:\n return `${timeTemplate} / ${timeTemplate}`\n }\n }\n\n const renderProps: TimeDisplayRenderProps = {\n ref: forwardedRef,\n style: {\n position: fixedWidth ? 'relative' : undefined,\n userSelect: 'none',\n fontVariantNumeric: 'tabular-nums',\n ...spanProps.style,\n },\n [TimeDisplayDataAttributes.hovering]: state.hovering || undefined,\n }\n\n if (render) {\n return render(renderProps, state)\n }\n\n return (\n <span\n ref={forwardedRef}\n {...{\n [TimeDisplayDataAttributes.hovering]: state.hovering || undefined,\n }}\n {...spanProps}\n style={{\n position: fixedWidth ? 'relative' : undefined,\n userSelect: 'none',\n fontVariantNumeric: 'tabular-nums',\n ...spanProps.style,\n }}\n >\n {fixedWidth ? (\n <>\n {/* Invisible template to reserve max width */}\n <span aria-hidden style={{ visibility: 'hidden' }}>\n {getTemplateText()}\n </span>\n {/* Actual content positioned over template */}\n <span style={getAlignmentStyle(align)}>{getDisplayText()}</span>\n </>\n ) : (\n getDisplayText()\n )}\n </span>\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace TimeDisplay {\n export type Props = TimeDisplayProps\n export type State = TimeDisplayState\n export type Format = TimeDisplayFormat\n}\n\n// ============================================================================\n// Utility: Alignment Style\n// ============================================================================\n\nfunction getAlignmentStyle(\n align: 'left' | 'center' | 'right',\n): React.CSSProperties {\n const base: React.CSSProperties = { position: 'absolute' }\n switch (align) {\n case 'left':\n return { ...base, left: 0 }\n case 'right':\n return { ...base, right: 0 }\n case 'center':\n return { ...base, left: '50%', transform: 'translateX(-50%)' }\n }\n}\n\n// ============================================================================\n// Utility: Format Time\n// ============================================================================\n\nfunction formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || Number.isNaN(seconds)) return '0:00'\n\n const hours = Math.floor(seconds / 3600)\n const mins = Math.floor((seconds % 3600) / 60)\n const secs = Math.floor(seconds % 60)\n\n if (hours > 0) {\n return `${hours}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`\n }\n\n return `${mins}:${secs.toString().padStart(2, '0')}`\n}\n\n/**\n * Generate a template string that represents the maximum width\n * for a given duration. Uses 0s which are typically the widest digit.\n */\nfunction getTimeTemplate(duration: number): string {\n if (!Number.isFinite(duration) || Number.isNaN(duration) || duration <= 0) {\n return '0:00'\n }\n\n const hours = Math.floor(duration / 3600)\n const mins = Math.floor((duration % 3600) / 60)\n\n if (hours > 0) {\n // e.g., duration 1:23:45 → template \"0:00:00\"\n // e.g., duration 12:34:56 → template \"00:00:00\"\n const hourDigits = String(hours).length\n return `${'0'.repeat(hourDigits)}:00:00`\n }\n\n // e.g., duration 1:23 → template \"0:00\"\n // e.g., duration 12:34 → template \"00:00\"\n const minDigits = String(mins).length\n return `${'0'.repeat(minDigits)}:00`\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { TrackInfo } from '../../types.js'\n\n// ============================================================================\n// Track Props\n// ============================================================================\n\nexport interface TrackProps\n extends Omit<React.ComponentPropsWithRef<'track'>, 'kind'> {\n /** Track kind (defaults to 'captions') */\n kind?: TextTrackKind\n /** Source URL for the track file (.vtt) */\n src: string\n /** Human-readable label displayed in caption menus */\n label: string\n /** Language code (e.g., 'en', 'es', 'fr') */\n srcLang: string\n /** Set as the default track (auto-enabled) */\n default?: boolean\n}\n\n// ============================================================================\n// Track Component\n// ============================================================================\n\n/**\n * Wraps native <track> element and registers with VideoPlayer context.\n * Must be used as a child of VideoPlayer.Video.\n *\n * @example\n * <VideoPlayer.Video>\n * <VideoPlayer.Track\n * kind=\"captions\"\n * src=\"/captions-en.vtt\"\n * label=\"English\"\n * srcLang=\"en\"\n * />\n * </VideoPlayer.Video>\n */\nexport const Track = React.forwardRef<HTMLTrackElement, TrackProps>(\n function Track(props, forwardedRef) {\n const {\n kind = 'captions',\n src,\n label,\n srcLang,\n default: isDefault,\n ...trackProps\n } = props\n\n const { registerTrack, unregisterTrack, updateTrackRef, setTextTrack } =\n useVideoPlayerContext('Track')\n const trackRef = React.useRef<HTMLTrackElement>(null)\n\n // Generate stable ID for this track registration\n const trackId = React.useId()\n\n // Compose refs\n const composedRef = React.useCallback(\n (node: HTMLTrackElement | null) => {\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n ;(trackRef as React.MutableRefObject<HTMLTrackElement | null>).current =\n node\n },\n [forwardedRef],\n )\n\n // Register track with context on mount\n React.useEffect(() => {\n const trackInfo: TrackInfo = {\n id: trackId,\n kind,\n label,\n srcLang,\n src,\n textTrack: null, // Will be updated once track loads\n }\n\n registerTrack(trackInfo)\n\n return () => {\n unregisterTrack(trackId)\n }\n }, [trackId, kind, label, srcLang, src, registerTrack, unregisterTrack])\n\n // Update textTrack reference once the track element is ready\n React.useEffect(() => {\n const trackElement = trackRef.current\n if (!trackElement) return\n\n // The track property gives us the TextTrack object\n const handleUpdateRef = () => {\n if (trackElement.track) {\n // Disable the track by default to prevent native browser captions\n // It will be enabled via setTextTrack when user activates it\n trackElement.track.mode = 'disabled'\n\n updateTrackRef(trackId, trackElement.track)\n\n // If this is the default track, set it as active\n if (isDefault) {\n setTextTrack(trackElement.track)\n }\n }\n }\n\n // Check if already loaded\n if (trackElement.track) {\n handleUpdateRef()\n }\n\n // Also listen for load event in case it's not ready yet\n trackElement.addEventListener('load', handleUpdateRef)\n return () => {\n trackElement.removeEventListener('load', handleUpdateRef)\n }\n }, [trackId, isDefault, updateTrackRef, setTextTrack])\n\n return (\n <track\n ref={composedRef}\n kind={kind}\n src={src}\n label={label}\n srcLang={srcLang}\n default={isDefault}\n {...trackProps}\n />\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Track {\n export type Props = TrackProps\n}\n","'use client'\n\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport { VideoDataAttributes } from './video.data-attributes.js'\n\n// ============================================================================\n// Video Props\n// ============================================================================\n\nexport interface VideoProps\n extends Omit<\n React.ComponentPropsWithRef<'video'>,\n | 'onTimeUpdate'\n | 'onDurationChange'\n | 'onProgress'\n | 'onPlay'\n | 'onPause'\n | 'onEnded'\n | 'onWaiting'\n | 'onCanPlay'\n | 'onSeeking'\n | 'onSeeked'\n | 'onVolumeChange'\n | 'onLoadedMetadata'\n > {\n /**\n * Toggle play/pause when clicking on the video.\n * @default true\n */\n toggleOnClick?: boolean\n}\n\nexport interface VideoState {\n playing: boolean\n paused: boolean\n ended: boolean\n waiting: boolean\n seeking: boolean\n}\n\n// ============================================================================\n// Video Component\n// ============================================================================\n\nexport const Video = React.forwardRef<HTMLVideoElement, VideoProps>(\n function Video(props, forwardedRef) {\n const { toggleOnClick = true, onClick, ...videoProps } = props\n const context = useVideoPlayerContext('Video')\n\n const hasCheckedMetadata = React.useRef(false)\n\n const composedRef = React.useCallback(\n (node: HTMLVideoElement | null) => {\n // Set refs\n if (typeof forwardedRef === 'function') {\n forwardedRef(node)\n } else if (forwardedRef) {\n forwardedRef.current = node\n }\n ;(\n context.videoRef as React.MutableRefObject<HTMLVideoElement | null>\n ).current = node\n\n // Handle race condition: metadata/canplay may have loaded before handlers attached\n // Only check once to avoid infinite loops\n if (node && !hasCheckedMetadata.current) {\n hasCheckedMetadata.current = true\n\n if (node.readyState >= 1 && node.duration) {\n context._handlers.onLoadedMetadata()\n context._handlers.onDurationChange()\n }\n\n // readyState >= 3 means HAVE_FUTURE_DATA (canplay)\n // readyState >= 4 means HAVE_ENOUGH_DATA (canplaythrough)\n if (node.readyState >= 3) {\n context._handlers.onCanPlay()\n }\n }\n },\n [forwardedRef, context.videoRef, context._handlers],\n )\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLVideoElement>) => {\n onClick?.(event)\n if (!event.defaultPrevented && toggleOnClick) {\n context.toggle()\n }\n },\n [onClick, toggleOnClick, context],\n )\n\n // Data attributes\n const dataAttributes = {\n [VideoDataAttributes.playing]: context.playing || undefined,\n [VideoDataAttributes.paused]: context.paused || undefined,\n [VideoDataAttributes.ended]: context.ended || undefined,\n [VideoDataAttributes.waiting]: context.waiting || undefined,\n [VideoDataAttributes.seeking]: context.seeking || undefined,\n }\n\n return (\n <video\n ref={composedRef}\n preload=\"metadata\"\n {...dataAttributes}\n {...videoProps}\n onClick={handleClick}\n onTimeUpdate={context._handlers.onTimeUpdate}\n onDurationChange={context._handlers.onDurationChange}\n onProgress={context._handlers.onProgress}\n onPlay={context._handlers.onPlay}\n onPause={context._handlers.onPause}\n onEnded={context._handlers.onEnded}\n onWaiting={context._handlers.onWaiting}\n onCanPlay={context._handlers.onCanPlay}\n onSeeking={context._handlers.onSeeking}\n onSeeked={context._handlers.onSeeked}\n onVolumeChange={context._handlers.onVolumeChange}\n onLoadedMetadata={context._handlers.onLoadedMetadata}\n />\n )\n },\n)\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace Video {\n export type Props = VideoProps\n export type State = VideoState\n}\n","export enum VolumeSliderCssVars {\n /** Raw volume value (0-1). */\n volume = '--volume',\n /** Volume as a percentage (e.g., \"75%\"). */\n volumePercentage = '--volume-percentage',\n}\n","export enum VolumeSliderDataAttributes {\n /** Applied when the audio is muted. */\n muted = 'data-muted',\n /** The current volume level (0-1). */\n volume = 'data-volume',\n /** Applied when the slider is being pressed. */\n pressing = 'data-pressing',\n /** Applied when the slider is being dragged after pressing. */\n dragging = 'data-dragging',\n}\n","'use client'\n\nimport { Slider } from '@base-ui/react/slider'\nimport * as React from 'react'\nimport { useVideoPlayerContext } from '../../contexts/video-player-context.js'\nimport type { RenderProp } from '../../types.js'\nimport { VolumeSliderCssVars } from './volume-slider.css-vars.js'\nimport { VolumeSliderDataAttributes } from './volume-slider.data-attributes.js'\n\n// ============================================================================\n// VolumeSlider Props\n// ============================================================================\n\nexport interface VolumeSliderProps\n extends Omit<\n React.ComponentPropsWithRef<typeof Slider.Root>,\n 'value' | 'onValueChange' | 'min' | 'max' | 'step' | 'render'\n > {\n render?: RenderProp<VolumeSliderRenderProps, VolumeSliderState>\n}\n\nexport interface VolumeSliderRenderProps {\n [VolumeSliderDataAttributes.muted]?: boolean\n [VolumeSliderDataAttributes.volume]: number\n [VolumeSliderDataAttributes.pressing]?: boolean\n [VolumeSliderDataAttributes.dragging]?: boolean\n style: React.CSSProperties\n}\n\nexport interface VolumeSliderState {\n volume: number\n muted: boolean\n percentage: number\n pressing: boolean\n dragging: boolean\n}\n\n// ============================================================================\n// VolumeSlider Component\n// ============================================================================\n\nexport const VolumeSlider = React.forwardRef<\n React.ComponentRef<typeof Slider.Root>,\n VolumeSliderProps\n>(function VolumeSlider(props, forwardedRef) {\n const { render, children, onPointerDown, ...sliderProps } = props\n const context = useVideoPlayerContext('VolumeSlider')\n const sliderRef = React.useRef<HTMLDivElement | null>(null)\n const [pressing, setPressing] = React.useState(false)\n const [dragging, setDragging] = React.useState(false)\n const pressingRef = React.useRef(false)\n\n React.useEffect(() => {\n if (!pressing) return\n\n const handleGlobalPointerUp = () => {\n setPressing(false)\n setDragging(false)\n pressingRef.current = false\n }\n\n window.addEventListener('pointerup', handleGlobalPointerUp)\n return () => window.removeEventListener('pointerup', handleGlobalPointerUp)\n }, [pressing])\n\n // Sync internal ref with forwarded ref\n React.useLayoutEffect(() => {\n if (typeof forwardedRef === 'function') {\n forwardedRef(sliderRef.current)\n } else if (forwardedRef) {\n forwardedRef.current = sliderRef.current\n }\n })\n\n const percentage = context.volume * 100\n\n const state: VolumeSliderState = {\n volume: context.volume,\n muted: context.muted,\n percentage,\n pressing,\n dragging,\n }\n\n const handleValueChange = React.useCallback(\n (value: number | readonly number[]) => {\n const v = typeof value === 'number' ? value : value[0]\n if (v === undefined) return\n // If muted and user drags slider, unmute (without restoring previous volume)\n if (context.muted) {\n // Directly set muted to false on the video element and update state\n // by calling toggleMute would restore previous volume, so we need a different approach\n const video = context.videoRef.current\n if (video) {\n video.muted = false\n }\n }\n context.setVolume(v)\n context.resetIdle() // Keep player active while adjusting volume\n if (pressingRef.current) {\n setDragging(true)\n }\n },\n [context],\n )\n\n const handlePointerDown = React.useCallback(\n (event: React.PointerEvent) => {\n onPointerDown?.(event as any)\n setPressing(true)\n pressingRef.current = true\n },\n [onPointerDown],\n )\n\n // Data attributes\n const dataAttributes = {\n [VolumeSliderDataAttributes.muted]: context.muted || undefined,\n [VolumeSliderDataAttributes.volume]: context.volume,\n [VolumeSliderDataAttributes.pressing]: pressing || undefined,\n [VolumeSliderDataAttributes.dragging]: dragging || undefined,\n }\n\n // CSS custom properties for styling\n const style = {\n position: 'relative' as const,\n [VolumeSliderCssVars.volume]: context.volume,\n [VolumeSliderCssVars.volumePercentage]: `${percentage}%`,\n ...sliderProps.style,\n } as unknown as React.CSSProperties\n\n const renderProps: VolumeSliderRenderProps = {\n [VolumeSliderDataAttributes.muted]: context.muted || undefined,\n [VolumeSliderDataAttributes.volume]: context.volume,\n [VolumeSliderDataAttributes.pressing]: pressing || undefined,\n [VolumeSliderDataAttributes.dragging]: dragging || undefined,\n style,\n }\n\n // Render prop takes full control\n if (render) {\n return (\n <Slider.Root\n ref={sliderRef as React.RefObject<HTMLDivElement>}\n min={0}\n max={1}\n step={0.01}\n value={context.muted ? 0 : context.volume}\n onValueChange={handleValueChange}\n onPointerDown={handlePointerDown}\n aria-label=\"Volume\"\n render={(baseProps) => render({ ...baseProps, ...renderProps }, state)}\n />\n )\n }\n\n // Composition pattern: if children provided, use them; otherwise use default structure\n return (\n <Slider.Root\n ref={sliderRef as React.RefObject<HTMLDivElement>}\n min={0}\n max={1}\n step={0.01}\n value={context.muted ? 0 : context.volume}\n onValueChange={handleValueChange}\n onPointerDown={handlePointerDown}\n aria-label=\"Volume\"\n {...dataAttributes}\n {...sliderProps}\n style={style}\n >\n {children ?? (\n <Slider.Control>\n <Slider.Track>\n <Slider.Indicator />\n <Slider.Thumb />\n </Slider.Track>\n </Slider.Control>\n )}\n </Slider.Root>\n )\n})\n\n// ============================================================================\n// Sub-components for custom composition\n// ============================================================================\n\nexport const VolumeSliderControl = Slider.Control\n\n// VolumeSliderTrack - applies position: relative by default\nexport interface VolumeSliderTrackProps\n extends React.ComponentPropsWithRef<typeof Slider.Track> {}\n\nexport const VolumeSliderTrack = React.forwardRef<\n React.ComponentRef<typeof Slider.Track>,\n VolumeSliderTrackProps\n>(function VolumeSliderTrack(props, forwardedRef) {\n const { style, ...trackProps } = props\n\n const trackStyle: React.CSSProperties = {\n position: 'relative',\n ...style,\n }\n\n return <Slider.Track ref={forwardedRef} style={trackStyle} {...trackProps} />\n})\n\n// VolumeSliderRange - Base UI handles positioning internally\nexport interface VolumeSliderRangeProps\n extends React.ComponentPropsWithRef<typeof Slider.Indicator> {}\n\nexport const VolumeSliderRange = React.forwardRef<\n React.ComponentRef<typeof Slider.Indicator>,\n VolumeSliderRangeProps\n>(function VolumeSliderRange(props, forwardedRef) {\n // Base UI handles all positioning internally (width for horizontal, height for vertical)\n return <Slider.Indicator ref={forwardedRef} {...props} />\n})\n\n// VolumeSliderThumb - Base UI handles positioning internally\nexport interface VolumeSliderThumbProps\n extends React.ComponentPropsWithRef<typeof Slider.Thumb> {}\n\nexport const VolumeSliderThumb = React.forwardRef<\n React.ComponentRef<typeof Slider.Thumb>,\n VolumeSliderThumbProps\n>(function VolumeSliderThumb(props, forwardedRef) {\n // Base UI handles positioning internally (position, insetInlineStart, top, translate)\n return <Slider.Thumb ref={forwardedRef} {...props} />\n})\n\n// ============================================================================\n// Namespace\n// ============================================================================\n\nexport namespace VolumeSlider {\n export type Props = VolumeSliderProps\n export type State = VolumeSliderState\n}\n"],"mappings":"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","names":["React","VideoPlayerContext","useVideoPlayerContext","component","context","useVideoPlayer","useVideoPlayerContext","index_parts_exports","__export","BufferedIndicator","Captions","CaptionsButton","CaptionsDataAttributes","CaptionsMenu","CaptionsMenuItem","Controls","ControlsDataAttributes","FullscreenButton","MuteButton","Overlay","OverlayDataAttributes","PictureInPictureButton","PlayButton","PlaybackRateButton","PlaybackRateMenu","PlaybackRateMenuItem","Portal","Poster","QualityMenu","QualityMenuItem","VideoPlayerRoot","RootDataAttributes","SeekSlider","SeekSliderBuffered","SeekSliderControl","SeekSliderCssVars","SeekSliderDataAttributes","SeekSliderHover","SeekSliderPreviewThumb","SeekSliderPreviewThumbDataAttributes","SeekSliderPreviewTooltip","SeekSliderPreviewTooltipPopup","SeekSliderPreviewTooltipPortal","SeekSliderPreviewTooltipPositioner","SeekSliderProgress","SeekSliderThumb","SeekSliderTrack","Thumbnail","ThumbnailDataAttributes","TimeDisplay","TimeDisplayDataAttributes","Track","Video","VolumeSlider","VolumeSliderControl","VolumeSliderCssVars","VolumeSliderDataAttributes","VolumeSliderRange","VolumeSliderThumb","VolumeSliderTrack","useTransitionStatus","useVideoPlayer","React","jsx","BufferedIndicator","props","forwardedRef","render","divProps","context","useVideoPlayerContext","bufferedEnd","i","bufferedPercentage","state","style","renderProps","CaptionsDataAttributes","React","jsx","Captions","props","forwardedRef","render","children","divProps","cues","useVideoPlayerContext","cueText","cue","active","state","renderProps","React","jsx","CaptionsButton","props","forwardedRef","render","onClick","buttonProps","context","useVideoPlayerContext","available","active","state","handleClick","event","firstTrack","renderProps","React","Fragment","jsx","jsxs","CaptionsMenu","props","forwardedRef","render","children","divProps","context","useVideoPlayerContext","state","renderProps","CaptionsMenuItem","trackInfo","track","onClick","buttonProps","isActive","handleClick","event","ControlsDataAttributes","React","React","waitForAnimations","element","animations","el","a","useTransitionStatus","options","open","keepMounted","mounted","setMounted","transitionStatus","setTransitionStatus","elementRef","waitingForAnimationsRef","raf","jsx","Controls","props","forwardedRef","idleTimeoutProp","keepMounted","render","children","divProps","context","useVideoPlayerContext","open","mounted","transitionStatus","elementRef","useTransitionStatus","composedRef","node","onClick","restDivProps","handleClick","event","state","renderProps","React","jsx","FullscreenButton","props","forwardedRef","render","onClick","children","buttonProps","context","useVideoPlayerContext","supported","setSupported","handleClick","event","state","renderProps","React","jsx","MuteButton","props","forwardedRef","render","onClick","buttonProps","context","useVideoPlayerContext","state","handleClick","event","volume","muted","volumeOff","volumeOn","volumeLow","volumeHigh","renderProps","OverlayDataAttributes","React","jsx","Overlay","props","forwardedRef","idleTimeoutProp","keepMounted","render","onClick","children","divProps","context","useVideoPlayerContext","open","mounted","transitionStatus","elementRef","useTransitionStatus","composedRef","node","handleClick","event","state","renderProps","React","jsx","PictureInPictureButton","props","forwardedRef","render","onClick","buttonProps","context","useVideoPlayerContext","supported","setSupported","state","handleClick","event","renderProps","React","jsx","PlayButton","props","forwardedRef","render","onClick","children","buttonProps","context","useVideoPlayerContext","handleClick","event","state","renderProps","React","jsx","DEFAULT_PLAYBACK_RATES","PlaybackRateButton","props","forwardedRef","rates","render","onClick","children","buttonProps","context","useVideoPlayerContext","state","handleClick","event","nextIndex","nextRate","renderProps","React","jsx","DEFAULT_PLAYBACK_RATES","PlaybackRateMenu","props","forwardedRef","rates","render","children","divProps","context","useVideoPlayerContext","state","renderProps","rate","PlaybackRateMenuItem","onClick","buttonProps","isActive","handleClick","event","React","createPortal","Portal","props","children","container","mounted","setMounted","target","React","jsx","Poster","props","forwardedRef","keepMounted","render","children","divProps","context","useVideoPlayerContext","loading","loaded","mounted","transitionStatus","elementRef","useTransitionStatus","composedRef","useComposedRef","state","renderProps","refs","node","ref","React","jsx","QualityMenu","props","forwardedRef","render","children","divProps","context","useVideoPlayerContext","state","renderProps","quality","QualityMenuItem","onClick","buttonProps","isActive","handleClick","event","RootDataAttributes","React","React","useKeyboardShortcuts","rootRef","scope","context","useVideoPlayer","contextRef","handleKeyDown","e","target","ctx","root","jsx","jsxs","useControllableState","controlledValue","defaultValue","onChange","uncontrolledValue","setUncontrolledValue","isControlled","value","setValue","nextValue","newValue","VideoPlayerProvider","rootRef","videoRef","actionsRef","defaultPlaying","defaultVolume","defaultMuted","defaultPlaybackRate","controlledPlaying","onPlayingChange","controlledVolume","onVolumeChange","controlledMuted","onMutedChange","controlledPlaybackRate","onPlaybackRateChange","controlledCurrentTime","onCurrentTimeChange","idleTimeout","preventIdleWhenPaused","controlledIdle","onIdleChange","onEnded","onWaiting","onSeeking","onSeeked","onFullscreenChange","onPictureInPictureChange","children","previousVolumeRef","playbackStatus","setPlaybackStatus","playbackIntent","setPlaybackIntent","volume","setVolume","muted","setMuted","playbackRate","setPlaybackRateState","idle","setIdle","idleTimeoutRef","clearIdleTimeout","startIdleTimeout","resetIdle","handleRootMouseLeave","effectiveIdle","currentTime","setCurrentTime","duration","setDuration","buffered","setBuffered","hoverTime","setHoverTime","canPlay","setCanPlay","seeking","setSeeking","fullscreen","setFullscreen","pictureInPicture","setPictureInPicture","registeredTracks","setRegisteredTracks","activeTextTrack","setActiveTextTrack","activeCues","setActiveCues","qualities","_setQualities","activeQuality","setActiveQuality","handleFullscreenChange","isFullscreen","video","handlePiPEnter","handlePiPLeave","play","pause","toggle","seek","time","handleSetVolume","vol","clampedVolume","toggleMute","restoreVolume","enterFullscreen","exitFullscreen","toggleFullscreen","enterPictureInPicture","exitPictureInPicture","togglePictureInPicture","setPlaybackRate","rate","setTextTrack","track","i","textTrack","setQuality","quality","registerTrack","prev","t","unregisterTrack","id","updateTrackRef","handleCueChange","cues","cueArray","cue","handleTimeUpdate","handleDurationChange","handleProgress","handlePlay","handlePause","handleEnded","handleWaiting","handleCanPlay","resumeStatus","handleSeeking","handleSeeked","handleVolumeChange","handleLoadedMetadata","contextValue","VideoPlayerContext","VideoPlayerRoot","props","forwardedRef","keyboardShortcuts","playing","hideCursorWhenIdle","rootDivProps","VideoPlayerRootImpl","className","style","divProps","context","useVideoPlayer","composedRef","useComposedRef","lastMousePosition","useKeyboardShortcuts","handleMouseMove","event","clientX","clientY","last","handleMouseEnter","handleMouseLeave","handleClick","dataAttributes","shouldHideCursor","scopeId","refs","node","ref","SeekSliderCssVars","SeekSliderDataAttributes","Slider","autoUpdate","offset","shift","useFloating","React","ReactDOM","SeekSliderPreviewThumbDataAttributes","jsx","jsxs","SeekSliderContext","useSeekSliderContext","componentName","context","SeekSlider","props","forwardedRef","render","children","onPointerMove","onPointerLeave","onPointerDown","onValueCommitted","sliderProps","useVideoPlayerContext","sliderRef","previewThumbElement","setPreviewThumbElement","pressing","setPressing","dragging","setDragging","pressingRef","handleGlobalPointerUp","progress","handleValueChange","value","v","handlePointerMove","event","rect","x","time","handlePointerLeave","handlePointerDown","handleValueCommitted","eventDetails","bufferedEnd","i","bufferedPercentage","state","open","hoverProgress","seekSliderContextValue","style","renderProps","Slider","baseProps","SeekSliderControl","SeekSliderTrack","trackProps","trackStyle","SeekSliderProgress","indicatorProps","indicatorStyle","SeekSliderThumb","thumbProps","SeekSliderBuffered","divProps","SeekSliderPreviewThumb","keepMounted","spanProps","seekSliderContext","lastProgressRef","mounted","transitionStatus","elementRef","useTransitionStatus","composedRef","node","SeekSliderHover","styleProp","hovering","SeekSliderPreviewTooltipPortal","container","videoPlayerContext","setMounted","portalContainer","SeekSliderPreviewTooltipPositioner","sideOffset","collisionPadding","collisionBoundary","floatingElement","setFloatingElement","refs","floatingStyles","update","useFloating","offset","shift","autoUpdate","mergedRef","SeekSliderPreviewTooltipPopup","SeekSliderPreviewTooltip","popupProps","ThumbnailDataAttributes","React","jsx","Thumbnail","props","forwardedRef","timeProp","crossOrigin","render","children","widthProp","heightProp","canvasProps","context","useVideoPlayerContext","canvasRef","videoRef","lastDrawnTimeRef","status","setStatus","videoDimensions","setVideoDimensions","time","videoSrc","mainVideo","video","handleLoadedMetadata","handleError","canvas","handleSeeked","ctx","composedRef","node","aspectRatio","width","height","state","renderProps","TimeDisplayDataAttributes","React","Fragment","jsx","jsxs","TimeDisplay","props","forwardedRef","format","fixedWidth","align","render","spanProps","context","useVideoPlayerContext","lastHoverTimeRef","remaining","formattedCurrent","formatTime","formattedDuration","formattedRemaining","formattedHover","state","getDisplayText","getTemplateText","timeTemplate","getTimeTemplate","renderProps","getAlignmentStyle","base","seconds","hours","mins","secs","duration","hourDigits","minDigits","React","jsx","Track","props","forwardedRef","kind","src","label","srcLang","isDefault","trackProps","registerTrack","unregisterTrack","updateTrackRef","setTextTrack","useVideoPlayerContext","trackRef","trackId","composedRef","node","trackElement","handleUpdateRef","React","jsx","Video","props","forwardedRef","toggleOnClick","onClick","videoProps","context","useVideoPlayerContext","hasCheckedMetadata","composedRef","node","handleClick","event","dataAttributes","VolumeSliderCssVars","VolumeSliderDataAttributes","Slider","React","jsx","jsxs","VolumeSlider","props","forwardedRef","render","children","onPointerDown","sliderProps","context","useVideoPlayerContext","sliderRef","pressing","setPressing","dragging","setDragging","pressingRef","handleGlobalPointerUp","percentage","state","handleValueChange","value","v","video","handlePointerDown","event","dataAttributes","style","renderProps","Slider","baseProps","VolumeSliderControl","VolumeSliderTrack","trackProps","trackStyle","VolumeSliderRange","VolumeSliderThumb"]}