@videojs/react 10.0.0-alpha.4 → 10.0.0-alpha.5

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 (286) hide show
  1. package/dist/default/_virtual/_rolldown/runtime.js +1 -19
  2. package/dist/default/index.js +10 -33
  3. package/dist/default/player/context.js +11 -1
  4. package/dist/default/player/context.js.map +1 -1
  5. package/dist/default/presets/audio/index.js +2 -8
  6. package/dist/default/presets/audio/skin.css +1 -0
  7. package/dist/default/presets/background/index.js +2 -8
  8. package/dist/default/presets/background/skin.css +1 -0
  9. package/dist/default/presets/video/index.js +2 -8
  10. package/dist/default/presets/video/minimal-skin.css +178 -53
  11. package/dist/default/presets/video/minimal-skin.js +63 -90
  12. package/dist/default/presets/video/minimal-skin.js.map +1 -1
  13. package/dist/default/presets/video/minimal-skin.tailwind.js +126 -107
  14. package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
  15. package/dist/default/presets/video/skin.css +179 -54
  16. package/dist/default/presets/video/skin.js +61 -88
  17. package/dist/default/presets/video/skin.js.map +1 -1
  18. package/dist/default/presets/video/skin.tailwind.js +121 -104
  19. package/dist/default/presets/video/skin.tailwind.js.map +1 -1
  20. package/dist/default/skins/dist/default/video/default.tailwind.js +90 -0
  21. package/dist/default/skins/dist/default/video/default.tailwind.js.map +1 -0
  22. package/dist/default/skins/dist/default/video/minimal.tailwind.js +86 -0
  23. package/dist/default/skins/dist/default/video/minimal.tailwind.js.map +1 -0
  24. package/dist/default/ui/captions-button/captions-button.js +1 -16
  25. package/dist/default/ui/captions-button/captions-button.js.map +1 -1
  26. package/dist/default/ui/controls/context.js +16 -0
  27. package/dist/default/ui/controls/context.js.map +1 -0
  28. package/dist/default/ui/controls/controls-group.js +4 -1
  29. package/dist/default/ui/controls/controls-group.js.map +1 -1
  30. package/dist/default/ui/controls/controls-root.js +19 -10
  31. package/dist/default/ui/controls/controls-root.js.map +1 -1
  32. package/dist/default/ui/create-context-part.js +29 -0
  33. package/dist/default/ui/create-context-part.js.map +1 -0
  34. package/dist/default/ui/create-media-button.js +52 -0
  35. package/dist/default/ui/create-media-button.js.map +1 -0
  36. package/dist/default/ui/fullscreen-button/fullscreen-button.js +8 -33
  37. package/dist/default/ui/fullscreen-button/fullscreen-button.js.map +1 -1
  38. package/dist/default/ui/hooks/use-slider.js +75 -0
  39. package/dist/default/ui/hooks/use-slider.js.map +1 -0
  40. package/dist/default/ui/mute-button/mute-button.js +8 -36
  41. package/dist/default/ui/mute-button/mute-button.js.map +1 -1
  42. package/dist/default/ui/pip-button/pip-button.js +8 -33
  43. package/dist/default/ui/pip-button/pip-button.js.map +1 -1
  44. package/dist/default/ui/play-button/play-button.js +7 -33
  45. package/dist/default/ui/play-button/play-button.js.map +1 -1
  46. package/dist/default/ui/playback-rate-button/index.js +3 -0
  47. package/dist/default/ui/playback-rate-button/playback-rate-button.js +34 -0
  48. package/dist/default/ui/playback-rate-button/playback-rate-button.js.map +1 -0
  49. package/dist/default/ui/popover/context.js +16 -0
  50. package/dist/default/ui/popover/context.js.map +1 -0
  51. package/dist/default/ui/popover/index.js +4 -0
  52. package/dist/default/ui/popover/index.parts.js +17 -0
  53. package/dist/default/ui/popover/index.parts.js.map +1 -0
  54. package/dist/default/ui/popover/popover-arrow.js +17 -0
  55. package/dist/default/ui/popover/popover-arrow.js.map +1 -0
  56. package/dist/default/ui/popover/popover-popup.js +94 -0
  57. package/dist/default/ui/popover/popover-popup.js.map +1 -0
  58. package/dist/default/ui/popover/popover-root.js +69 -0
  59. package/dist/default/ui/popover/popover-root.js.map +1 -0
  60. package/dist/default/ui/popover/popover-trigger.js +43 -0
  61. package/dist/default/ui/popover/popover-trigger.js.map +1 -0
  62. package/dist/default/ui/poster/poster.js +2 -1
  63. package/dist/default/ui/poster/poster.js.map +1 -1
  64. package/dist/default/ui/seek-button/seek-button.js +7 -34
  65. package/dist/default/ui/seek-button/seek-button.js.map +1 -1
  66. package/dist/default/ui/slider/context.js +22 -0
  67. package/dist/default/ui/slider/context.js.map +1 -0
  68. package/dist/default/ui/slider/index.js +3 -0
  69. package/dist/default/ui/slider/index.parts.js +21 -0
  70. package/dist/default/ui/slider/index.parts.js.map +1 -0
  71. package/dist/default/ui/slider/slider-buffer.js +16 -0
  72. package/dist/default/ui/slider/slider-buffer.js.map +1 -0
  73. package/dist/default/ui/slider/slider-fill.js +16 -0
  74. package/dist/default/ui/slider/slider-fill.js.map +1 -0
  75. package/dist/default/ui/slider/slider-root.js +71 -0
  76. package/dist/default/ui/slider/slider-root.js.map +1 -0
  77. package/dist/default/ui/slider/slider-thumb.js +32 -0
  78. package/dist/default/ui/slider/slider-thumb.js.map +1 -0
  79. package/dist/default/ui/slider/slider-track.js +16 -0
  80. package/dist/default/ui/slider/slider-track.js.map +1 -0
  81. package/dist/default/ui/slider/slider-value.js +32 -0
  82. package/dist/default/ui/slider/slider-value.js.map +1 -0
  83. package/dist/default/ui/thumbnail/thumbnail.js +87 -0
  84. package/dist/default/ui/thumbnail/thumbnail.js.map +1 -0
  85. package/dist/default/ui/time/time-value.js +2 -1
  86. package/dist/default/ui/time/time-value.js.map +1 -1
  87. package/dist/default/ui/time-slider/index.js +3 -0
  88. package/dist/default/ui/time-slider/index.parts.js +21 -0
  89. package/dist/default/ui/time-slider/index.parts.js.map +1 -0
  90. package/dist/default/ui/time-slider/time-slider-root.js +96 -0
  91. package/dist/default/ui/time-slider/time-slider-root.js.map +1 -0
  92. package/dist/default/ui/volume-slider/index.js +3 -0
  93. package/dist/default/ui/volume-slider/index.parts.js +19 -0
  94. package/dist/default/ui/volume-slider/index.parts.js.map +1 -0
  95. package/dist/default/ui/volume-slider/volume-slider-root.js +86 -0
  96. package/dist/default/ui/volume-slider/volume-slider-root.js.map +1 -0
  97. package/dist/default/utils/use-force-render.js +13 -0
  98. package/dist/default/utils/use-force-render.js.map +1 -0
  99. package/dist/default/utils/use-latest-ref.js +20 -0
  100. package/dist/default/utils/use-latest-ref.js.map +1 -0
  101. package/dist/default/utils/use-safe-id.js +22 -0
  102. package/dist/default/utils/use-safe-id.js.map +1 -0
  103. package/dist/dev/_virtual/_rolldown/runtime.js +1 -19
  104. package/dist/dev/index.d.ts +20 -2
  105. package/dist/dev/index.js +10 -33
  106. package/dist/dev/player/context.d.ts.map +1 -1
  107. package/dist/dev/player/context.js +11 -1
  108. package/dist/dev/player/context.js.map +1 -1
  109. package/dist/dev/presets/audio/index.d.ts +2 -9
  110. package/dist/dev/presets/audio/index.js +2 -8
  111. package/dist/dev/presets/audio/skin.css +1 -0
  112. package/dist/dev/presets/background/index.d.ts +2 -9
  113. package/dist/dev/presets/background/index.js +2 -8
  114. package/dist/dev/presets/background/skin.css +1 -0
  115. package/dist/dev/presets/video/index.d.ts +2 -9
  116. package/dist/dev/presets/video/index.js +2 -8
  117. package/dist/dev/presets/video/minimal-skin.css +178 -53
  118. package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
  119. package/dist/dev/presets/video/minimal-skin.js +61 -88
  120. package/dist/dev/presets/video/minimal-skin.js.map +1 -1
  121. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
  122. package/dist/dev/presets/video/minimal-skin.tailwind.js +124 -105
  123. package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
  124. package/dist/dev/presets/video/skin.css +179 -54
  125. package/dist/dev/presets/video/skin.d.ts.map +1 -1
  126. package/dist/dev/presets/video/skin.js +61 -88
  127. package/dist/dev/presets/video/skin.js.map +1 -1
  128. package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
  129. package/dist/dev/presets/video/skin.tailwind.js +121 -104
  130. package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
  131. package/dist/dev/skins/dist/default/video/default.tailwind.js +90 -0
  132. package/dist/dev/skins/dist/default/video/default.tailwind.js.map +1 -0
  133. package/dist/dev/skins/dist/default/video/minimal.tailwind.js +86 -0
  134. package/dist/dev/skins/dist/default/video/minimal.tailwind.js.map +1 -0
  135. package/dist/dev/ui/captions-button/captions-button.d.ts.map +1 -1
  136. package/dist/dev/ui/captions-button/captions-button.js +1 -16
  137. package/dist/dev/ui/captions-button/captions-button.js.map +1 -1
  138. package/dist/dev/ui/controls/context.js +16 -0
  139. package/dist/dev/ui/controls/context.js.map +1 -0
  140. package/dist/dev/ui/controls/controls-group.d.ts +2 -2
  141. package/dist/dev/ui/controls/controls-group.d.ts.map +1 -1
  142. package/dist/dev/ui/controls/controls-group.js +4 -1
  143. package/dist/dev/ui/controls/controls-group.js.map +1 -1
  144. package/dist/dev/ui/controls/controls-root.d.ts.map +1 -1
  145. package/dist/dev/ui/controls/controls-root.js +19 -10
  146. package/dist/dev/ui/controls/controls-root.js.map +1 -1
  147. package/dist/dev/ui/create-context-part.js +29 -0
  148. package/dist/dev/ui/create-context-part.js.map +1 -0
  149. package/dist/dev/ui/create-media-button.js +55 -0
  150. package/dist/dev/ui/create-media-button.js.map +1 -0
  151. package/dist/dev/ui/fullscreen-button/fullscreen-button.d.ts +2 -1
  152. package/dist/dev/ui/fullscreen-button/fullscreen-button.d.ts.map +1 -1
  153. package/dist/dev/ui/fullscreen-button/fullscreen-button.js +9 -37
  154. package/dist/dev/ui/fullscreen-button/fullscreen-button.js.map +1 -1
  155. package/dist/dev/ui/hooks/use-slider.d.ts +36 -0
  156. package/dist/dev/ui/hooks/use-slider.d.ts.map +1 -0
  157. package/dist/dev/ui/hooks/use-slider.js +75 -0
  158. package/dist/dev/ui/hooks/use-slider.js.map +1 -0
  159. package/dist/dev/ui/mute-button/mute-button.d.ts +2 -4
  160. package/dist/dev/ui/mute-button/mute-button.d.ts.map +1 -1
  161. package/dist/dev/ui/mute-button/mute-button.js +9 -40
  162. package/dist/dev/ui/mute-button/mute-button.js.map +1 -1
  163. package/dist/dev/ui/pip-button/pip-button.d.ts +2 -1
  164. package/dist/dev/ui/pip-button/pip-button.d.ts.map +1 -1
  165. package/dist/dev/ui/pip-button/pip-button.js +9 -37
  166. package/dist/dev/ui/pip-button/pip-button.js.map +1 -1
  167. package/dist/dev/ui/play-button/play-button.d.ts +1 -1
  168. package/dist/dev/ui/play-button/play-button.d.ts.map +1 -1
  169. package/dist/dev/ui/play-button/play-button.js +8 -37
  170. package/dist/dev/ui/play-button/play-button.js.map +1 -1
  171. package/dist/dev/ui/playback-rate-button/index.d.ts +2 -0
  172. package/dist/dev/ui/playback-rate-button/index.js +3 -0
  173. package/dist/dev/ui/playback-rate-button/playback-rate-button.d.ts +30 -0
  174. package/dist/dev/ui/playback-rate-button/playback-rate-button.d.ts.map +1 -0
  175. package/dist/dev/ui/playback-rate-button/playback-rate-button.js +34 -0
  176. package/dist/dev/ui/playback-rate-button/playback-rate-button.js.map +1 -0
  177. package/dist/dev/ui/popover/context.d.ts +17 -0
  178. package/dist/dev/ui/popover/context.d.ts.map +1 -0
  179. package/dist/dev/ui/popover/context.js +16 -0
  180. package/dist/dev/ui/popover/context.js.map +1 -0
  181. package/dist/dev/ui/popover/index.d.ts +3 -0
  182. package/dist/dev/ui/popover/index.js +4 -0
  183. package/dist/dev/ui/popover/index.parts.d.ts +12 -0
  184. package/dist/dev/ui/popover/index.parts.d.ts.map +1 -0
  185. package/dist/dev/ui/popover/index.parts.js +17 -0
  186. package/dist/dev/ui/popover/index.parts.js.map +1 -0
  187. package/dist/dev/ui/popover/popover-arrow.d.ts +15 -0
  188. package/dist/dev/ui/popover/popover-arrow.d.ts.map +1 -0
  189. package/dist/dev/ui/popover/popover-arrow.js +17 -0
  190. package/dist/dev/ui/popover/popover-arrow.js.map +1 -0
  191. package/dist/dev/ui/popover/popover-popup.d.ts +15 -0
  192. package/dist/dev/ui/popover/popover-popup.d.ts.map +1 -0
  193. package/dist/dev/ui/popover/popover-popup.js +94 -0
  194. package/dist/dev/ui/popover/popover-popup.js.map +1 -0
  195. package/dist/dev/ui/popover/popover-root.d.ts +29 -0
  196. package/dist/dev/ui/popover/popover-root.d.ts.map +1 -0
  197. package/dist/dev/ui/popover/popover-root.js +69 -0
  198. package/dist/dev/ui/popover/popover-root.js.map +1 -0
  199. package/dist/dev/ui/popover/popover-trigger.d.ts +15 -0
  200. package/dist/dev/ui/popover/popover-trigger.d.ts.map +1 -0
  201. package/dist/dev/ui/popover/popover-trigger.js +43 -0
  202. package/dist/dev/ui/popover/popover-trigger.js.map +1 -0
  203. package/dist/dev/ui/poster/poster.d.ts.map +1 -1
  204. package/dist/dev/ui/poster/poster.js +2 -1
  205. package/dist/dev/ui/poster/poster.js.map +1 -1
  206. package/dist/dev/ui/seek-button/seek-button.d.ts +1 -1
  207. package/dist/dev/ui/seek-button/seek-button.d.ts.map +1 -1
  208. package/dist/dev/ui/seek-button/seek-button.js +8 -38
  209. package/dist/dev/ui/seek-button/seek-button.js.map +1 -1
  210. package/dist/dev/ui/slider/context.js +22 -0
  211. package/dist/dev/ui/slider/context.js.map +1 -0
  212. package/dist/dev/ui/slider/index.d.ts +2 -0
  213. package/dist/dev/ui/slider/index.js +3 -0
  214. package/dist/dev/ui/slider/index.parts.d.ts +14 -0
  215. package/dist/dev/ui/slider/index.parts.d.ts.map +1 -0
  216. package/dist/dev/ui/slider/index.parts.js +21 -0
  217. package/dist/dev/ui/slider/index.parts.js.map +1 -0
  218. package/dist/dev/ui/slider/slider-buffer.d.ts +14 -0
  219. package/dist/dev/ui/slider/slider-buffer.d.ts.map +1 -0
  220. package/dist/dev/ui/slider/slider-buffer.js +16 -0
  221. package/dist/dev/ui/slider/slider-buffer.js.map +1 -0
  222. package/dist/dev/ui/slider/slider-fill.d.ts +14 -0
  223. package/dist/dev/ui/slider/slider-fill.d.ts.map +1 -0
  224. package/dist/dev/ui/slider/slider-fill.js +16 -0
  225. package/dist/dev/ui/slider/slider-fill.js.map +1 -0
  226. package/dist/dev/ui/slider/slider-root.d.ts +19 -0
  227. package/dist/dev/ui/slider/slider-root.d.ts.map +1 -0
  228. package/dist/dev/ui/slider/slider-root.js +71 -0
  229. package/dist/dev/ui/slider/slider-root.js.map +1 -0
  230. package/dist/dev/ui/slider/slider-thumb.d.ts +14 -0
  231. package/dist/dev/ui/slider/slider-thumb.d.ts.map +1 -0
  232. package/dist/dev/ui/slider/slider-thumb.js +32 -0
  233. package/dist/dev/ui/slider/slider-thumb.js.map +1 -0
  234. package/dist/dev/ui/slider/slider-track.d.ts +14 -0
  235. package/dist/dev/ui/slider/slider-track.d.ts.map +1 -0
  236. package/dist/dev/ui/slider/slider-track.js +16 -0
  237. package/dist/dev/ui/slider/slider-track.js.map +1 -0
  238. package/dist/dev/ui/slider/slider-value.d.ts +19 -0
  239. package/dist/dev/ui/slider/slider-value.d.ts.map +1 -0
  240. package/dist/dev/ui/slider/slider-value.js +32 -0
  241. package/dist/dev/ui/slider/slider-value.js.map +1 -0
  242. package/dist/dev/ui/thumbnail/thumbnail.d.ts +17 -0
  243. package/dist/dev/ui/thumbnail/thumbnail.d.ts.map +1 -0
  244. package/dist/dev/ui/thumbnail/thumbnail.js +87 -0
  245. package/dist/dev/ui/thumbnail/thumbnail.js.map +1 -0
  246. package/dist/dev/ui/time/time-value.d.ts.map +1 -1
  247. package/dist/dev/ui/time/time-value.js +2 -1
  248. package/dist/dev/ui/time/time-value.js.map +1 -1
  249. package/dist/dev/ui/time-slider/index.d.ts +2 -0
  250. package/dist/dev/ui/time-slider/index.js +3 -0
  251. package/dist/dev/ui/time-slider/index.parts.d.ts +15 -0
  252. package/dist/dev/ui/time-slider/index.parts.d.ts.map +1 -0
  253. package/dist/dev/ui/time-slider/index.parts.js +21 -0
  254. package/dist/dev/ui/time-slider/index.parts.js.map +1 -0
  255. package/dist/dev/ui/time-slider/time-slider-root.d.ts +17 -0
  256. package/dist/dev/ui/time-slider/time-slider-root.d.ts.map +1 -0
  257. package/dist/dev/ui/time-slider/time-slider-root.js +99 -0
  258. package/dist/dev/ui/time-slider/time-slider-root.js.map +1 -0
  259. package/dist/dev/ui/volume-slider/index.d.ts +2 -0
  260. package/dist/dev/ui/volume-slider/index.js +3 -0
  261. package/dist/dev/ui/volume-slider/index.parts.d.ts +14 -0
  262. package/dist/dev/ui/volume-slider/index.parts.d.ts.map +1 -0
  263. package/dist/dev/ui/volume-slider/index.parts.js +19 -0
  264. package/dist/dev/ui/volume-slider/index.parts.js.map +1 -0
  265. package/dist/dev/ui/volume-slider/volume-slider-root.d.ts +17 -0
  266. package/dist/dev/ui/volume-slider/volume-slider-root.d.ts.map +1 -0
  267. package/dist/dev/ui/volume-slider/volume-slider-root.js +89 -0
  268. package/dist/dev/ui/volume-slider/volume-slider-root.js.map +1 -0
  269. package/dist/dev/utils/use-force-render.js +13 -0
  270. package/dist/dev/utils/use-force-render.js.map +1 -0
  271. package/dist/dev/utils/use-latest-ref.js +20 -0
  272. package/dist/dev/utils/use-latest-ref.js.map +1 -0
  273. package/dist/dev/utils/use-safe-id.js +22 -0
  274. package/dist/dev/utils/use-safe-id.js.map +1 -0
  275. package/package.json +6 -5
  276. package/dist/default/index.js.map +0 -1
  277. package/dist/default/presets/audio/index.js.map +0 -1
  278. package/dist/default/presets/background/index.js.map +0 -1
  279. package/dist/default/presets/video/index.js.map +0 -1
  280. package/dist/dev/index.js.map +0 -1
  281. package/dist/dev/presets/audio/index.d.ts.map +0 -1
  282. package/dist/dev/presets/audio/index.js.map +0 -1
  283. package/dist/dev/presets/background/index.d.ts.map +0 -1
  284. package/dist/dev/presets/background/index.js.map +0 -1
  285. package/dist/dev/presets/video/index.d.ts.map +0 -1
  286. package/dist/dev/presets/video/index.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail.js","names":[],"sources":["../../../../src/ui/thumbnail/thumbnail.tsx"],"sourcesContent":["'use client';\n\nimport {\n mapCuesToThumbnails,\n ThumbnailCore,\n ThumbnailDataAttrs,\n type ThumbnailFetchPriority,\n type ThumbnailImage,\n} from '@videojs/core';\nimport { createThumbnail, selectTextTrack } from '@videojs/core/dom';\nimport type { CSSProperties } from 'react';\nimport { forwardRef, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useOptionalPlayer } from '../../player/context';\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\n\nexport interface ThumbnailProps extends UIComponentProps<'div', ThumbnailCore.State>, ThumbnailCore.Props {\n /** Pre-parsed thumbnail images — bypasses the automatic `<track>` detection. */\n thumbnails?: ThumbnailImage[] | undefined;\n}\n\nexport const Thumbnail = forwardRef<HTMLDivElement, ThumbnailProps>(function Thumbnail(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n time = 0,\n thumbnails: externalThumbnails,\n crossOrigin,\n loading,\n fetchPriority,\n ...elementProps\n } = componentProps;\n\n const [core] = useState(() => new ThumbnailCore());\n const divRef = useRef<HTMLDivElement>(null);\n const imgRef = useRef<HTMLImageElement>(null);\n const textTrack = useOptionalPlayer(selectTextTrack);\n\n // Force re-render when the handle's state changes (img load/error, resize).\n const [, setRenderToken] = useState(0);\n\n const [handle] = useState(() =>\n createThumbnail({\n getContainer: () => divRef.current,\n getImg: () => imgRef.current,\n onStateChange: () => setRenderToken((n) => n + 1),\n })\n );\n\n useEffect(() => {\n handle.connect();\n return () => handle.destroy();\n }, [handle]);\n\n // Resolve thumbnails: external prop takes priority over auto <track> path.\n const thumbnails = useMemo(() => {\n if (externalThumbnails && externalThumbnails.length > 0) return externalThumbnails;\n if (!textTrack?.thumbnailCues.length) return [];\n return mapCuesToThumbnails(textTrack.thumbnailCues, textTrack.thumbnailTrackSrc ?? undefined);\n }, [externalThumbnails, textTrack]);\n\n const thumbnail = useMemo(() => core.findActiveThumbnail(thumbnails, time), [core, thumbnails, time]);\n\n // Track src changes via the handle.\n handle.updateSrc(thumbnail?.url);\n\n const state = core.getState(handle.loading, handle.error, thumbnail);\n\n // Compute styles declaratively from resize result.\n let containerStyle: CSSProperties = { overflow: 'hidden' };\n let imgStyle: CSSProperties | undefined;\n\n if (thumbnail && handle.naturalWidth && handle.naturalHeight) {\n const constraints = handle.readConstraints();\n const result = core.resize(thumbnail, handle.naturalWidth, handle.naturalHeight, constraints);\n\n if (result) {\n containerStyle = {\n overflow: 'hidden',\n width: result.containerWidth,\n height: result.containerHeight,\n };\n imgStyle = {\n width: result.imageWidth,\n height: result.imageHeight,\n maxWidth: 'none',\n transform:\n result.offsetX || result.offsetY ? `translate(-${result.offsetX}px, -${result.offsetY}px)` : undefined,\n };\n }\n }\n\n return renderElement(\n 'div',\n { render, className, style },\n {\n state,\n stateAttrMap: ThumbnailDataAttrs,\n ref: [forwardedRef, divRef],\n props: [\n core.getAttrs(state),\n { style: containerStyle },\n elementProps,\n {\n children: (\n <img\n ref={imgRef}\n alt=\"\"\n aria-hidden=\"true\"\n decoding=\"async\"\n src={thumbnail?.url}\n crossOrigin={crossOrigin === '' || crossOrigin === null ? undefined : crossOrigin}\n loading={loading}\n style={imgStyle}\n // React's types omit `| undefined` from fetchPriority — cast to satisfy exactOptionalPropertyTypes.\n fetchPriority={fetchPriority as ThumbnailFetchPriority}\n />\n ),\n },\n ],\n }\n );\n});\n\nexport namespace Thumbnail {\n export type Props = ThumbnailProps;\n export type State = ThumbnailCore.State;\n}\n"],"mappings":";;;;;;;;;;AAsBA,MAAa,YAAY,WAA2C,SAAS,UAAU,gBAAgB,cAAc;CACnH,MAAM,EACJ,QACA,WACA,OACA,OAAO,GACP,YAAY,oBACZ,aACA,SACA,eACA,GAAG,iBACD;CAEJ,MAAM,CAAC,QAAQ,eAAe,IAAI,eAAe,CAAC;CAClD,MAAM,SAAS,OAAuB,KAAK;CAC3C,MAAM,SAAS,OAAyB,KAAK;CAC7C,MAAM,YAAY,kBAAkB,gBAAgB;CAGpD,MAAM,GAAG,kBAAkB,SAAS,EAAE;CAEtC,MAAM,CAAC,UAAU,eACf,gBAAgB;EACd,oBAAoB,OAAO;EAC3B,cAAc,OAAO;EACrB,qBAAqB,gBAAgB,MAAM,IAAI,EAAE;EAClD,CAAC,CACH;AAED,iBAAgB;AACd,SAAO,SAAS;AAChB,eAAa,OAAO,SAAS;IAC5B,CAAC,OAAO,CAAC;CAGZ,MAAM,aAAa,cAAc;AAC/B,MAAI,sBAAsB,mBAAmB,SAAS,EAAG,QAAO;AAChE,MAAI,CAAC,WAAW,cAAc,OAAQ,QAAO,EAAE;AAC/C,SAAO,oBAAoB,UAAU,eAAe,UAAU,qBAAqB,OAAU;IAC5F,CAAC,oBAAoB,UAAU,CAAC;CAEnC,MAAM,YAAY,cAAc,KAAK,oBAAoB,YAAY,KAAK,EAAE;EAAC;EAAM;EAAY;EAAK,CAAC;AAGrG,QAAO,UAAU,WAAW,IAAI;CAEhC,MAAM,QAAQ,KAAK,SAAS,OAAO,SAAS,OAAO,OAAO,UAAU;CAGpE,IAAI,iBAAgC,EAAE,UAAU,UAAU;CAC1D,IAAI;AAEJ,KAAI,aAAa,OAAO,gBAAgB,OAAO,eAAe;EAC5D,MAAM,cAAc,OAAO,iBAAiB;EAC5C,MAAM,SAAS,KAAK,OAAO,WAAW,OAAO,cAAc,OAAO,eAAe,YAAY;AAE7F,MAAI,QAAQ;AACV,oBAAiB;IACf,UAAU;IACV,OAAO,OAAO;IACd,QAAQ,OAAO;IAChB;AACD,cAAW;IACT,OAAO,OAAO;IACd,QAAQ,OAAO;IACf,UAAU;IACV,WACE,OAAO,WAAW,OAAO,UAAU,cAAc,OAAO,QAAQ,OAAO,OAAO,QAAQ,OAAO;IAChG;;;AAIL,QAAO,cACL,OACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA,cAAc;EACd,KAAK,CAAC,cAAc,OAAO;EAC3B,OAAO;GACL,KAAK,SAAS,MAAM;GACpB,EAAE,OAAO,gBAAgB;GACzB;GACA,EACE,UACE,oBAAC;IACC,KAAK;IACL,KAAI;IACJ,eAAY;IACZ,UAAS;IACT,KAAK,WAAW;IAChB,aAAa,gBAAgB,MAAM,gBAAgB,OAAO,SAAY;IAC7D;IACT,OAAO;IAEQ;KACf,EAEL;GACF;EACF,CACF;EACD"}
@@ -28,7 +28,8 @@ const Value = forwardRef(function Value(componentProps, forwardedRef) {
28
28
  label
29
29
  });
30
30
  if (!time) return null;
31
- const state = core.getState(time);
31
+ core.setMedia(time);
32
+ const state = core.getState();
32
33
  const content = state.negative ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
33
34
  "aria-hidden": "true",
34
35
  children: negativeSign ?? TimeCore.defaultProps.negativeSign
@@ -1 +1 @@
1
- {"version":3,"file":"time-value.js","names":[],"sources":["../../../../src/ui/time/time-value.tsx"],"sourcesContent":["'use client';\n\nimport { TimeCore, TimeDataAttrs } from '@videojs/core';\nimport { logMissingFeature, selectTime } from '@videojs/core/dom';\nimport type { ForwardedRef } from 'react';\nimport { forwardRef, useState } from 'react';\n\nimport { usePlayer } from '../../player/context';\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\n\nexport interface ValueProps extends Omit<UIComponentProps<'time', TimeCore.State>, 'children'>, TimeCore.Props {}\n\n/**\n * Displays a formatted time value (current, duration, or remaining).\n *\n * @example\n * ```tsx\n * <Time.Value />\n * <Time.Value type=\"duration\" />\n * <Time.Value type=\"remaining\" negativeSign=\"−\" />\n * ```\n */\nexport const Value = forwardRef(function Value(\n componentProps: ValueProps,\n forwardedRef: ForwardedRef<HTMLTimeElement>\n) {\n const { render, className, style, type, negativeSign, label, ...elementProps } = componentProps;\n\n const time = usePlayer(selectTime);\n\n const [core] = useState(() => new TimeCore());\n core.setProps({ type, negativeSign, label });\n\n if (!time) {\n if (__DEV__) logMissingFeature('Time.Value', 'time');\n return null;\n }\n\n const state = core.getState(time);\n\n const content = state.negative ? (\n <>\n <span aria-hidden=\"true\">{negativeSign ?? TimeCore.defaultProps.negativeSign}</span>\n {state.text}\n </>\n ) : (\n state.text\n );\n\n return renderElement(\n 'time',\n { render, className, style },\n {\n state,\n stateAttrMap: TimeDataAttrs,\n ref: [forwardedRef],\n props: [\n {\n dateTime: state.datetime,\n children: content,\n ...core.getAttrs(state),\n },\n elementProps,\n ],\n }\n );\n});\n\nexport namespace Value {\n export type Props = ValueProps;\n export type State = TimeCore.State;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,QAAQ,WAAW,SAAS,MACvC,gBACA,cACA;CACA,MAAM,EAAE,QAAQ,WAAW,OAAO,MAAM,cAAc,OAAO,GAAG,iBAAiB;CAEjF,MAAM,OAAO,UAAU,WAAW;CAElC,MAAM,CAAC,QAAQ,eAAe,IAAI,UAAU,CAAC;AAC7C,MAAK,SAAS;EAAE;EAAM;EAAc;EAAO,CAAC;AAE5C,KAAI,CAAC,KAEH,QAAO;CAGT,MAAM,QAAQ,KAAK,SAAS,KAAK;CAEjC,MAAM,UAAU,MAAM,WACpB,4CACE,oBAAC;EAAK,eAAY;YAAQ,gBAAgB,SAAS,aAAa;GAAoB,EACnF,MAAM,QACN,GAEH,MAAM;AAGR,QAAO,cACL,QACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA,cAAc;EACd,KAAK,CAAC,aAAa;EACnB,OAAO,CACL;GACE,UAAU,MAAM;GAChB,UAAU;GACV,GAAG,KAAK,SAAS,MAAM;GACxB,EACD,aACD;EACF,CACF;EACD"}
1
+ {"version":3,"file":"time-value.js","names":[],"sources":["../../../../src/ui/time/time-value.tsx"],"sourcesContent":["'use client';\n\nimport { TimeCore, TimeDataAttrs } from '@videojs/core';\nimport { logMissingFeature, selectTime } from '@videojs/core/dom';\nimport type { ForwardedRef } from 'react';\nimport { forwardRef, useState } from 'react';\n\nimport { usePlayer } from '../../player/context';\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\n\nexport interface ValueProps extends Omit<UIComponentProps<'time', TimeCore.State>, 'children'>, TimeCore.Props {}\n\n/**\n * Displays a formatted time value (current, duration, or remaining).\n *\n * @example\n * ```tsx\n * <Time.Value />\n * <Time.Value type=\"duration\" />\n * <Time.Value type=\"remaining\" negativeSign=\"−\" />\n * ```\n */\nexport const Value = forwardRef(function Value(\n componentProps: ValueProps,\n forwardedRef: ForwardedRef<HTMLTimeElement>\n) {\n const { render, className, style, type, negativeSign, label, ...elementProps } = componentProps;\n\n const time = usePlayer(selectTime);\n\n const [core] = useState(() => new TimeCore());\n core.setProps({ type, negativeSign, label });\n\n if (!time) {\n if (__DEV__) logMissingFeature('Time.Value', 'time');\n return null;\n }\n\n core.setMedia(time);\n const state = core.getState();\n\n const content = state.negative ? (\n <>\n <span aria-hidden=\"true\">{negativeSign ?? TimeCore.defaultProps.negativeSign}</span>\n {state.text}\n </>\n ) : (\n state.text\n );\n\n return renderElement(\n 'time',\n { render, className, style },\n {\n state,\n stateAttrMap: TimeDataAttrs,\n ref: [forwardedRef],\n props: [\n {\n dateTime: state.datetime,\n children: content,\n ...core.getAttrs(state),\n },\n elementProps,\n ],\n }\n );\n});\n\nexport namespace Value {\n export type Props = ValueProps;\n export type State = TimeCore.State;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,QAAQ,WAAW,SAAS,MACvC,gBACA,cACA;CACA,MAAM,EAAE,QAAQ,WAAW,OAAO,MAAM,cAAc,OAAO,GAAG,iBAAiB;CAEjF,MAAM,OAAO,UAAU,WAAW;CAElC,MAAM,CAAC,QAAQ,eAAe,IAAI,UAAU,CAAC;AAC7C,MAAK,SAAS;EAAE;EAAM;EAAc;EAAO,CAAC;AAE5C,KAAI,CAAC,KAEH,QAAO;AAGT,MAAK,SAAS,KAAK;CACnB,MAAM,QAAQ,KAAK,UAAU;CAE7B,MAAM,UAAU,MAAM,WACpB,4CACE,oBAAC;EAAK,eAAY;YAAQ,gBAAgB,SAAS,aAAa;GAAoB,EACnF,MAAM,QACN,GAEH,MAAM;AAGR,QAAO,cACL,QACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA,cAAc;EACd,KAAK,CAAC,aAAa;EACnB,OAAO,CACL;GACE,UAAU,MAAM;GAChB,UAAU;GACV,GAAG,KAAK,SAAS,MAAM;GACxB,EACD,aACD;EACF,CACF;EACD"}
@@ -0,0 +1,3 @@
1
+ import { index_parts_exports } from "./index.parts.js";
2
+
3
+ export { index_parts_exports as TimeSlider };
@@ -0,0 +1,21 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { SliderBuffer } from "../slider/slider-buffer.js";
3
+ import { SliderFill } from "../slider/slider-fill.js";
4
+ import { SliderThumb } from "../slider/slider-thumb.js";
5
+ import { SliderTrack } from "../slider/slider-track.js";
6
+ import { SliderValue } from "../slider/slider-value.js";
7
+ import { TimeSliderRoot } from "./time-slider-root.js";
8
+
9
+ //#region src/ui/time-slider/index.parts.ts
10
+ var index_parts_exports = /* @__PURE__ */ __exportAll({
11
+ Buffer: () => SliderBuffer,
12
+ Fill: () => SliderFill,
13
+ Root: () => TimeSliderRoot,
14
+ Thumb: () => SliderThumb,
15
+ Track: () => SliderTrack,
16
+ Value: () => SliderValue
17
+ });
18
+
19
+ //#endregion
20
+ export { index_parts_exports };
21
+ //# sourceMappingURL=index.parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.parts.js","names":[],"sources":["../../../../src/ui/time-slider/index.parts.ts"],"sourcesContent":["export {\n Buffer,\n type BufferProps,\n Fill,\n type FillProps,\n Thumb,\n type ThumbProps,\n Track,\n type TrackProps,\n Value,\n type ValueProps,\n} from '../slider/index.parts';\nexport { TimeSliderRoot as Root, type TimeSliderRootProps as RootProps } from './time-slider-root';\n"],"mappings":""}
@@ -0,0 +1,96 @@
1
+ 'use client';
2
+
3
+ import { usePlayer } from "../../player/context.js";
4
+ import { renderElement } from "../../utils/use-render.js";
5
+ import { useLatestRef } from "../../utils/use-latest-ref.js";
6
+ import { useSlider } from "../hooks/use-slider.js";
7
+ import { SliderProvider } from "../slider/context.js";
8
+ import { getTimeSliderCSSVars, selectBuffer, selectTime } from "@videojs/core/dom";
9
+ import { forwardRef, useState } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ import { TimeSliderCore, TimeSliderDataAttrs } from "@videojs/core";
12
+ import { formatTime } from "@videojs/utils/time";
13
+
14
+ //#region src/ui/time-slider/time-slider-root.tsx
15
+ const noopSeek = () => Promise.resolve(0);
16
+ const TimeSliderRoot = forwardRef(function TimeSliderRoot(componentProps, forwardedRef) {
17
+ const { render, className, style, label, commitThrottle = TimeSliderCore.defaultProps.commitThrottle, step = TimeSliderCore.defaultProps.step, largeStep = TimeSliderCore.defaultProps.largeStep, orientation, disabled, thumbAlignment, onDragStart, onDragEnd, ...elementProps } = componentProps;
18
+ const time = usePlayer(selectTime);
19
+ const buffer = usePlayer(selectBuffer);
20
+ const [core] = useState(() => new TimeSliderCore());
21
+ core.setProps({
22
+ label,
23
+ step,
24
+ largeStep,
25
+ orientation,
26
+ disabled,
27
+ thumbAlignment
28
+ });
29
+ const mediaRef = useLatestRef(time && buffer ? {
30
+ ...time,
31
+ ...buffer
32
+ } : null);
33
+ const duration = time?.duration ?? 0;
34
+ const { state, cssVars, rootRef, thumbRef, rootProps, thumbProps } = useSlider({
35
+ computeState: (input) => {
36
+ core.setInput(input);
37
+ if (!time || !buffer) core.setMedia({
38
+ currentTime: 0,
39
+ duration: 0,
40
+ seeking: false,
41
+ seek: noopSeek,
42
+ buffered: [],
43
+ seekable: []
44
+ });
45
+ else core.setMedia({
46
+ ...time,
47
+ ...buffer
48
+ });
49
+ return core.getState();
50
+ },
51
+ getPercent: () => duration > 0 ? (time?.currentTime ?? 0) / duration * 100 : 0,
52
+ getStepPercent: () => core.getStepPercent(),
53
+ getLargeStepPercent: () => core.getLargeStepPercent(),
54
+ orientation,
55
+ disabled,
56
+ commitThrottle,
57
+ adjustPercent: (rawPercent, thumbSize, trackSize) => core.adjustPercentForAlignment(rawPercent, thumbSize, trackSize),
58
+ getCSSVars: getTimeSliderCSSVars,
59
+ onValueCommit: (percent) => {
60
+ const media = mediaRef.current;
61
+ if (media) media.seek(core.valueFromPercent(percent));
62
+ },
63
+ onDragStart,
64
+ onDragEnd
65
+ });
66
+ if (!time) return null;
67
+ return /* @__PURE__ */ jsx(SliderProvider, {
68
+ value: {
69
+ state,
70
+ pointerValue: core.valueFromPercent(state.pointerPercent),
71
+ thumbRef,
72
+ thumbProps,
73
+ stateAttrMap: TimeSliderDataAttrs,
74
+ getAttrs: (sliderState) => core.getAttrs(sliderState),
75
+ formatValue: (value) => formatTime(value, duration)
76
+ },
77
+ children: renderElement("div", {
78
+ render,
79
+ className,
80
+ style
81
+ }, {
82
+ state,
83
+ stateAttrMap: TimeSliderDataAttrs,
84
+ ref: [forwardedRef, rootRef],
85
+ props: [
86
+ { style: cssVars },
87
+ rootProps,
88
+ elementProps
89
+ ]
90
+ })
91
+ });
92
+ });
93
+
94
+ //#endregion
95
+ export { TimeSliderRoot };
96
+ //# sourceMappingURL=time-slider-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-slider-root.js","names":[],"sources":["../../../../src/ui/time-slider/time-slider-root.tsx"],"sourcesContent":["'use client';\n\nimport { TimeSliderCore, TimeSliderDataAttrs } from '@videojs/core';\nimport { getTimeSliderCSSVars, logMissingFeature, selectBuffer, selectTime } from '@videojs/core/dom';\nimport { formatTime } from '@videojs/utils/time';\nimport { forwardRef, useState } from 'react';\n\nimport { usePlayer } from '../../player/context';\nimport type { UIComponentProps } from '../../utils/types';\nimport { useLatestRef } from '../../utils/use-latest-ref';\nimport { renderElement } from '../../utils/use-render';\nimport { useSlider } from '../hooks/use-slider';\nimport { SliderProvider } from '../slider/context';\n\nconst noopSeek = (): Promise<number> => Promise.resolve(0);\n\nexport interface TimeSliderRootProps extends UIComponentProps<'div', TimeSliderCore.State>, TimeSliderCore.Props {\n onDragStart?: (() => void) | undefined;\n onDragEnd?: (() => void) | undefined;\n}\n\nexport const TimeSliderRoot = forwardRef<HTMLDivElement, TimeSliderRootProps>(\n function TimeSliderRoot(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n label,\n commitThrottle = TimeSliderCore.defaultProps.commitThrottle,\n step = TimeSliderCore.defaultProps.step,\n largeStep = TimeSliderCore.defaultProps.largeStep,\n orientation,\n disabled,\n thumbAlignment,\n onDragStart,\n onDragEnd,\n ...elementProps\n } = componentProps;\n\n const time = usePlayer(selectTime);\n const buffer = usePlayer(selectBuffer);\n\n const [core] = useState(() => new TimeSliderCore());\n core.setProps({ label, step, largeStep, orientation, disabled, thumbAlignment });\n\n // Keep a ref to the latest media state for callbacks that fire outside the render cycle.\n const mediaRef = useLatestRef(time && buffer ? { ...time, ...buffer } : null);\n\n const duration = time?.duration ?? 0;\n\n const { state, cssVars, rootRef, thumbRef, rootProps, thumbProps } = useSlider<TimeSliderCore.State>({\n computeState: (input) => {\n core.setInput(input);\n if (!time || !buffer) {\n core.setMedia({\n currentTime: 0,\n duration: 0,\n seeking: false,\n seek: noopSeek,\n buffered: [],\n seekable: [],\n });\n } else {\n core.setMedia({ ...time, ...buffer });\n }\n\n return core.getState();\n },\n getPercent: () => (duration > 0 ? ((time?.currentTime ?? 0) / duration) * 100 : 0),\n getStepPercent: () => core.getStepPercent(),\n getLargeStepPercent: () => core.getLargeStepPercent(),\n orientation,\n disabled,\n commitThrottle,\n adjustPercent: (rawPercent, thumbSize, trackSize) =>\n core.adjustPercentForAlignment(rawPercent, thumbSize, trackSize),\n getCSSVars: getTimeSliderCSSVars,\n onValueCommit: (percent) => {\n const media = mediaRef.current;\n if (media) media.seek(core.valueFromPercent(percent));\n },\n onDragStart,\n onDragEnd,\n });\n\n if (!time) {\n if (__DEV__) logMissingFeature('TimeSlider', 'time');\n return null;\n }\n\n return (\n <SliderProvider\n value={{\n state,\n pointerValue: core.valueFromPercent(state.pointerPercent),\n thumbRef,\n thumbProps,\n stateAttrMap: TimeSliderDataAttrs,\n getAttrs: (sliderState) => core.getAttrs(sliderState as TimeSliderCore.State),\n formatValue: (value) => formatTime(value, duration),\n }}\n >\n {renderElement(\n 'div',\n { render, className, style },\n {\n state,\n stateAttrMap: TimeSliderDataAttrs,\n ref: [forwardedRef, rootRef],\n props: [{ style: cssVars }, rootProps, elementProps],\n }\n )}\n </SliderProvider>\n );\n }\n);\n\nexport namespace TimeSliderRoot {\n export type Props = TimeSliderRootProps;\n export type State = TimeSliderCore.State;\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAM,iBAAkC,QAAQ,QAAQ,EAAE;AAO1D,MAAa,iBAAiB,WAC5B,SAAS,eAAe,gBAAgB,cAAc;CACpD,MAAM,EACJ,QACA,WACA,OACA,OACA,iBAAiB,eAAe,aAAa,gBAC7C,OAAO,eAAe,aAAa,MACnC,YAAY,eAAe,aAAa,WACxC,aACA,UACA,gBACA,aACA,WACA,GAAG,iBACD;CAEJ,MAAM,OAAO,UAAU,WAAW;CAClC,MAAM,SAAS,UAAU,aAAa;CAEtC,MAAM,CAAC,QAAQ,eAAe,IAAI,gBAAgB,CAAC;AACnD,MAAK,SAAS;EAAE;EAAO;EAAM;EAAW;EAAa;EAAU;EAAgB,CAAC;CAGhF,MAAM,WAAW,aAAa,QAAQ,SAAS;EAAE,GAAG;EAAM,GAAG;EAAQ,GAAG,KAAK;CAE7E,MAAM,WAAW,MAAM,YAAY;CAEnC,MAAM,EAAE,OAAO,SAAS,SAAS,UAAU,WAAW,eAAe,UAAgC;EACnG,eAAe,UAAU;AACvB,QAAK,SAAS,MAAM;AACpB,OAAI,CAAC,QAAQ,CAAC,OACZ,MAAK,SAAS;IACZ,aAAa;IACb,UAAU;IACV,SAAS;IACT,MAAM;IACN,UAAU,EAAE;IACZ,UAAU,EAAE;IACb,CAAC;OAEF,MAAK,SAAS;IAAE,GAAG;IAAM,GAAG;IAAQ,CAAC;AAGvC,UAAO,KAAK,UAAU;;EAExB,kBAAmB,WAAW,KAAM,MAAM,eAAe,KAAK,WAAY,MAAM;EAChF,sBAAsB,KAAK,gBAAgB;EAC3C,2BAA2B,KAAK,qBAAqB;EACrD;EACA;EACA;EACA,gBAAgB,YAAY,WAAW,cACrC,KAAK,0BAA0B,YAAY,WAAW,UAAU;EAClE,YAAY;EACZ,gBAAgB,YAAY;GAC1B,MAAM,QAAQ,SAAS;AACvB,OAAI,MAAO,OAAM,KAAK,KAAK,iBAAiB,QAAQ,CAAC;;EAEvD;EACA;EACD,CAAC;AAEF,KAAI,CAAC,KAEH,QAAO;AAGT,QACE,oBAAC;EACC,OAAO;GACL;GACA,cAAc,KAAK,iBAAiB,MAAM,eAAe;GACzD;GACA;GACA,cAAc;GACd,WAAW,gBAAgB,KAAK,SAAS,YAAoC;GAC7E,cAAc,UAAU,WAAW,OAAO,SAAS;GACpD;YAEA,cACC,OACA;GAAE;GAAQ;GAAW;GAAO,EAC5B;GACE;GACA,cAAc;GACd,KAAK,CAAC,cAAc,QAAQ;GAC5B,OAAO;IAAC,EAAE,OAAO,SAAS;IAAE;IAAW;IAAa;GACrD,CACF;GACc;EAGtB"}
@@ -0,0 +1,3 @@
1
+ import { index_parts_exports } from "./index.parts.js";
2
+
3
+ export { index_parts_exports as VolumeSlider };
@@ -0,0 +1,19 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { SliderFill } from "../slider/slider-fill.js";
3
+ import { SliderThumb } from "../slider/slider-thumb.js";
4
+ import { SliderTrack } from "../slider/slider-track.js";
5
+ import { SliderValue } from "../slider/slider-value.js";
6
+ import { VolumeSliderRoot } from "./volume-slider-root.js";
7
+
8
+ //#region src/ui/volume-slider/index.parts.ts
9
+ var index_parts_exports = /* @__PURE__ */ __exportAll({
10
+ Fill: () => SliderFill,
11
+ Root: () => VolumeSliderRoot,
12
+ Thumb: () => SliderThumb,
13
+ Track: () => SliderTrack,
14
+ Value: () => SliderValue
15
+ });
16
+
17
+ //#endregion
18
+ export { index_parts_exports };
19
+ //# sourceMappingURL=index.parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.parts.js","names":[],"sources":["../../../../src/ui/volume-slider/index.parts.ts"],"sourcesContent":["export {\n Fill,\n type FillProps,\n Thumb,\n type ThumbProps,\n Track,\n type TrackProps,\n Value,\n type ValueProps,\n} from '../slider/index.parts';\nexport { VolumeSliderRoot as Root, type VolumeSliderRootProps as RootProps } from './volume-slider-root';\n"],"mappings":""}
@@ -0,0 +1,86 @@
1
+ 'use client';
2
+
3
+ import { usePlayer } from "../../player/context.js";
4
+ import { renderElement } from "../../utils/use-render.js";
5
+ import { useLatestRef } from "../../utils/use-latest-ref.js";
6
+ import { useSlider } from "../hooks/use-slider.js";
7
+ import { SliderProvider } from "../slider/context.js";
8
+ import { getSliderCSSVars, selectVolume } from "@videojs/core/dom";
9
+ import { forwardRef, useState } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ import { SliderDataAttrs, VolumeSliderCore } from "@videojs/core";
12
+
13
+ //#region src/ui/volume-slider/volume-slider-root.tsx
14
+ const noopVolume = {
15
+ volume: 0,
16
+ muted: false,
17
+ volumeAvailability: "unsupported",
18
+ changeVolume: () => 0,
19
+ toggleMute: () => false
20
+ };
21
+ const VolumeSliderRoot = forwardRef(function VolumeSliderRoot(componentProps, forwardedRef) {
22
+ const { render, className, style, label, orientation, step = VolumeSliderCore.defaultProps.step, largeStep = VolumeSliderCore.defaultProps.largeStep, disabled, thumbAlignment, onDragStart, onDragEnd, ...elementProps } = componentProps;
23
+ const volume = usePlayer(selectVolume);
24
+ const [core] = useState(() => new VolumeSliderCore());
25
+ core.setProps({
26
+ label,
27
+ orientation,
28
+ step,
29
+ largeStep,
30
+ disabled,
31
+ thumbAlignment
32
+ });
33
+ const volumeRef = useLatestRef(volume);
34
+ const { state, cssVars, rootRef, thumbRef, rootProps, thumbProps } = useSlider({
35
+ computeState: (input) => {
36
+ core.setInput(input);
37
+ core.setMedia(volume ?? noopVolume);
38
+ return core.getState();
39
+ },
40
+ getPercent: () => volume ? volume.volume * 100 : 0,
41
+ getStepPercent: () => core.getStepPercent(),
42
+ getLargeStepPercent: () => core.getLargeStepPercent(),
43
+ orientation,
44
+ disabled,
45
+ adjustPercent: (rawPercent, thumbSize, trackSize) => core.adjustPercentForAlignment(rawPercent, thumbSize, trackSize),
46
+ getCSSVars: getSliderCSSVars,
47
+ onValueChange: (percent) => {
48
+ volumeRef.current?.changeVolume(percent / 100);
49
+ },
50
+ onValueCommit: (percent) => {
51
+ volumeRef.current?.changeVolume(percent / 100);
52
+ },
53
+ onDragStart,
54
+ onDragEnd
55
+ });
56
+ if (!volume) return null;
57
+ return /* @__PURE__ */ jsx(SliderProvider, {
58
+ value: {
59
+ state,
60
+ pointerValue: core.valueFromPercent(state.pointerPercent),
61
+ thumbRef,
62
+ thumbProps,
63
+ stateAttrMap: SliderDataAttrs,
64
+ getAttrs: (sliderState) => core.getAttrs(sliderState),
65
+ formatValue: (value) => `${Math.round(value)}%`
66
+ },
67
+ children: renderElement("div", {
68
+ render,
69
+ className,
70
+ style
71
+ }, {
72
+ state,
73
+ stateAttrMap: SliderDataAttrs,
74
+ ref: [forwardedRef, rootRef],
75
+ props: [
76
+ { style: cssVars },
77
+ rootProps,
78
+ elementProps
79
+ ]
80
+ })
81
+ });
82
+ });
83
+
84
+ //#endregion
85
+ export { VolumeSliderRoot };
86
+ //# sourceMappingURL=volume-slider-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volume-slider-root.js","names":[],"sources":["../../../../src/ui/volume-slider/volume-slider-root.tsx"],"sourcesContent":["'use client';\n\nimport { SliderDataAttrs, VolumeSliderCore } from '@videojs/core';\nimport { getSliderCSSVars, logMissingFeature, selectVolume } from '@videojs/core/dom';\nimport { forwardRef, useState } from 'react';\n\nimport { usePlayer } from '../../player/context';\nimport type { UIComponentProps } from '../../utils/types';\nimport { useLatestRef } from '../../utils/use-latest-ref';\nimport { renderElement } from '../../utils/use-render';\nimport { useSlider } from '../hooks/use-slider';\nimport { SliderProvider } from '../slider/context';\n\nconst noopVolume = {\n volume: 0,\n muted: false,\n volumeAvailability: 'unsupported' as const,\n changeVolume: () => 0,\n toggleMute: () => false,\n};\n\nexport interface VolumeSliderRootProps extends UIComponentProps<'div', VolumeSliderCore.State>, VolumeSliderCore.Props {\n onDragStart?: (() => void) | undefined;\n onDragEnd?: (() => void) | undefined;\n}\n\nexport const VolumeSliderRoot = forwardRef<HTMLDivElement, VolumeSliderRootProps>(\n function VolumeSliderRoot(componentProps, forwardedRef) {\n const {\n render,\n className,\n style,\n label,\n orientation,\n step = VolumeSliderCore.defaultProps.step,\n largeStep = VolumeSliderCore.defaultProps.largeStep,\n disabled,\n thumbAlignment,\n onDragStart,\n onDragEnd,\n ...elementProps\n } = componentProps;\n\n const volume = usePlayer(selectVolume);\n\n const [core] = useState(() => new VolumeSliderCore());\n core.setProps({ label, orientation, step, largeStep, disabled, thumbAlignment });\n\n // Keep a ref to the latest volume state for callbacks.\n const volumeRef = useLatestRef(volume);\n\n const { state, cssVars, rootRef, thumbRef, rootProps, thumbProps } = useSlider<VolumeSliderCore.State>({\n computeState: (input) => {\n core.setInput(input);\n core.setMedia(volume ?? noopVolume);\n return core.getState();\n },\n getPercent: () => (volume ? volume.volume * 100 : 0),\n getStepPercent: () => core.getStepPercent(),\n getLargeStepPercent: () => core.getLargeStepPercent(),\n orientation,\n disabled,\n adjustPercent: (rawPercent, thumbSize, trackSize) =>\n core.adjustPercentForAlignment(rawPercent, thumbSize, trackSize),\n getCSSVars: getSliderCSSVars,\n onValueChange: (percent) => {\n volumeRef.current?.changeVolume(percent / 100);\n },\n onValueCommit: (percent) => {\n volumeRef.current?.changeVolume(percent / 100);\n },\n onDragStart,\n onDragEnd,\n });\n\n if (!volume) {\n if (__DEV__) logMissingFeature('VolumeSlider', 'volume');\n return null;\n }\n\n return (\n <SliderProvider\n value={{\n state,\n pointerValue: core.valueFromPercent(state.pointerPercent),\n thumbRef,\n thumbProps,\n stateAttrMap: SliderDataAttrs,\n getAttrs: (sliderState) => core.getAttrs(sliderState as VolumeSliderCore.State),\n formatValue: (value) => `${Math.round(value)}%`,\n }}\n >\n {renderElement(\n 'div',\n { render, className, style },\n {\n state,\n stateAttrMap: SliderDataAttrs,\n ref: [forwardedRef, rootRef],\n props: [{ style: cssVars }, rootProps, elementProps],\n }\n )}\n </SliderProvider>\n );\n }\n);\n\nexport namespace VolumeSliderRoot {\n export type Props = VolumeSliderRootProps;\n export type State = VolumeSliderCore.State;\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAM,aAAa;CACjB,QAAQ;CACR,OAAO;CACP,oBAAoB;CACpB,oBAAoB;CACpB,kBAAkB;CACnB;AAOD,MAAa,mBAAmB,WAC9B,SAAS,iBAAiB,gBAAgB,cAAc;CACtD,MAAM,EACJ,QACA,WACA,OACA,OACA,aACA,OAAO,iBAAiB,aAAa,MACrC,YAAY,iBAAiB,aAAa,WAC1C,UACA,gBACA,aACA,WACA,GAAG,iBACD;CAEJ,MAAM,SAAS,UAAU,aAAa;CAEtC,MAAM,CAAC,QAAQ,eAAe,IAAI,kBAAkB,CAAC;AACrD,MAAK,SAAS;EAAE;EAAO;EAAa;EAAM;EAAW;EAAU;EAAgB,CAAC;CAGhF,MAAM,YAAY,aAAa,OAAO;CAEtC,MAAM,EAAE,OAAO,SAAS,SAAS,UAAU,WAAW,eAAe,UAAkC;EACrG,eAAe,UAAU;AACvB,QAAK,SAAS,MAAM;AACpB,QAAK,SAAS,UAAU,WAAW;AACnC,UAAO,KAAK,UAAU;;EAExB,kBAAmB,SAAS,OAAO,SAAS,MAAM;EAClD,sBAAsB,KAAK,gBAAgB;EAC3C,2BAA2B,KAAK,qBAAqB;EACrD;EACA;EACA,gBAAgB,YAAY,WAAW,cACrC,KAAK,0BAA0B,YAAY,WAAW,UAAU;EAClE,YAAY;EACZ,gBAAgB,YAAY;AAC1B,aAAU,SAAS,aAAa,UAAU,IAAI;;EAEhD,gBAAgB,YAAY;AAC1B,aAAU,SAAS,aAAa,UAAU,IAAI;;EAEhD;EACA;EACD,CAAC;AAEF,KAAI,CAAC,OAEH,QAAO;AAGT,QACE,oBAAC;EACC,OAAO;GACL;GACA,cAAc,KAAK,iBAAiB,MAAM,eAAe;GACzD;GACA;GACA,cAAc;GACd,WAAW,gBAAgB,KAAK,SAAS,YAAsC;GAC/E,cAAc,UAAU,GAAG,KAAK,MAAM,MAAM,CAAC;GAC9C;YAEA,cACC,OACA;GAAE;GAAQ;GAAW;GAAO,EAC5B;GACE;GACA,cAAc;GACd,KAAK,CAAC,cAAc,QAAQ;GAC5B,OAAO;IAAC,EAAE,OAAO,SAAS;IAAE;IAAW;IAAa;GACrD,CACF;GACc;EAGtB"}
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+
3
+ import { useReducer } from "react";
4
+
5
+ //#region src/utils/use-force-render.ts
6
+ function useForceRender() {
7
+ const [, forceRender] = useReducer((c) => c + 1, 0);
8
+ return forceRender;
9
+ }
10
+
11
+ //#endregion
12
+ export { useForceRender };
13
+ //# sourceMappingURL=use-force-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-force-render.js","names":[],"sources":["../../../src/utils/use-force-render.ts"],"sourcesContent":["'use client';\n\nimport { useReducer } from 'react';\n\nexport function useForceRender() {\n const [, forceRender] = useReducer((c: number) => c + 1, 0);\n return forceRender;\n}\n\nexport namespace useForceRender {\n export type Result = () => void;\n}\n"],"mappings":";;;;;AAIA,SAAgB,iBAAiB;CAC/B,MAAM,GAAG,eAAe,YAAY,MAAc,IAAI,GAAG,EAAE;AAC3D,QAAO"}
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+
3
+ import { useRef } from "react";
4
+
5
+ //#region src/utils/use-latest-ref.ts
6
+ /**
7
+ * Keep a ref that always points to the latest value.
8
+ *
9
+ * Useful for capturing callbacks or derived values inside closures
10
+ * that are created once (e.g. factory callbacks) without stale reads.
11
+ */
12
+ function useLatestRef(value) {
13
+ const ref = useRef(value);
14
+ ref.current = value;
15
+ return ref;
16
+ }
17
+
18
+ //#endregion
19
+ export { useLatestRef };
20
+ //# sourceMappingURL=use-latest-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-latest-ref.js","names":[],"sources":["../../../src/utils/use-latest-ref.ts"],"sourcesContent":["'use client';\n\nimport { useRef } from 'react';\n\n/**\n * Keep a ref that always points to the latest value.\n *\n * Useful for capturing callbacks or derived values inside closures\n * that are created once (e.g. factory callbacks) without stale reads.\n */\nexport function useLatestRef<Value>(value: Value): Readonly<{ current: Value }> {\n const ref = useRef(value);\n ref.current = value;\n return ref;\n}\n\nexport namespace useLatestRef {\n export type Result<Value> = Readonly<{ current: Value }>;\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgB,aAAoB,OAA4C;CAC9E,MAAM,MAAM,OAAO,MAAM;AACzB,KAAI,UAAU;AACd,QAAO"}
@@ -0,0 +1,22 @@
1
+ 'use client';
2
+
3
+ import { useId } from "react";
4
+
5
+ //#region src/utils/use-safe-id.ts
6
+ const UNSAFE_CHARS = /[^a-zA-Z0-9_-]/g;
7
+ /**
8
+ * Generate a CSS-safe identifier from React's `useId()`.
9
+ *
10
+ * `useId()` returns values like `:r0:` which contain colons — invalid
11
+ * in CSS `<dashed-ident>` tokens (used by `anchor-name` / `position-anchor`).
12
+ * This hook strips non-alphanumeric/underscore/hyphen characters and
13
+ * optionally prepends a prefix.
14
+ */
15
+ function useSafeId(prefix) {
16
+ const raw = useId().replace(UNSAFE_CHARS, "");
17
+ return prefix ? `${prefix}${raw}` : raw;
18
+ }
19
+
20
+ //#endregion
21
+ export { useSafeId };
22
+ //# sourceMappingURL=use-safe-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-safe-id.js","names":[],"sources":["../../../src/utils/use-safe-id.ts"],"sourcesContent":["'use client';\n\nimport { useId } from 'react';\n\nconst UNSAFE_CHARS = /[^a-zA-Z0-9_-]/g;\n\n/**\n * Generate a CSS-safe identifier from React's `useId()`.\n *\n * `useId()` returns values like `:r0:` which contain colons — invalid\n * in CSS `<dashed-ident>` tokens (used by `anchor-name` / `position-anchor`).\n * This hook strips non-alphanumeric/underscore/hyphen characters and\n * optionally prepends a prefix.\n */\nexport function useSafeId(prefix?: string): string {\n const raw = useId().replace(UNSAFE_CHARS, '');\n return prefix ? `${prefix}${raw}` : raw;\n}\n"],"mappings":";;;;;AAIA,MAAM,eAAe;;;;;;;;;AAUrB,SAAgB,UAAU,QAAyB;CACjD,MAAM,MAAM,OAAO,CAAC,QAAQ,cAAc,GAAG;AAC7C,QAAO,SAAS,GAAG,SAAS,QAAQ"}
@@ -1,8 +1,5 @@
1
1
  //#region \0rolldown/runtime.js
2
2
  var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
3
  var __exportAll = (all, no_symbols) => {
7
4
  let target = {};
8
5
  for (var name in all) {
@@ -16,21 +13,6 @@ var __exportAll = (all, no_symbols) => {
16
13
  }
17
14
  return target;
18
15
  };
19
- var __copyProps = (to, from, except, desc) => {
20
- if (from && typeof from === "object" || typeof from === "function") {
21
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
22
- key = keys[i];
23
- if (!__hasOwnProp.call(to, key) && key !== except) {
24
- __defProp(to, key, {
25
- get: ((k) => from[k]).bind(null, key),
26
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
27
- });
28
- }
29
- }
30
- }
31
- return to;
32
- };
33
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
34
16
 
35
17
  //#endregion
36
- export { __exportAll, __reExport };
18
+ export { __exportAll };
@@ -8,16 +8,34 @@ import { index_parts_d_exports } from "./ui/controls/index.parts.js";
8
8
  import "./ui/controls/index.js";
9
9
  import { FullscreenButton, FullscreenButtonProps } from "./ui/fullscreen-button/fullscreen-button.js";
10
10
  import { useButton } from "./ui/hooks/use-button.js";
11
+ import { useSlider } from "./ui/hooks/use-slider.js";
11
12
  import { MuteButton, MuteButtonProps } from "./ui/mute-button/mute-button.js";
12
13
  import { PiPButton, PiPButtonProps } from "./ui/pip-button/pip-button.js";
13
14
  import { PlayButton, PlayButtonProps } from "./ui/play-button/play-button.js";
15
+ import { PlaybackRateButton, PlaybackRateButtonProps } from "./ui/playback-rate-button/playback-rate-button.js";
16
+ import { PopoverContextValue, usePopoverContext } from "./ui/popover/context.js";
17
+ import { index_parts_d_exports as index_parts_d_exports$1 } from "./ui/popover/index.parts.js";
18
+ import "./ui/popover/index.js";
14
19
  import { Poster, PosterProps } from "./ui/poster/poster.js";
15
20
  import { SeekButton, SeekButtonProps } from "./ui/seek-button/seek-button.js";
16
- import { index_parts_d_exports as index_parts_d_exports$1 } from "./ui/time/index.parts.js";
21
+ import { SliderBufferProps } from "./ui/slider/slider-buffer.js";
22
+ import { SliderFillProps } from "./ui/slider/slider-fill.js";
23
+ import { SliderRootProps } from "./ui/slider/slider-root.js";
24
+ import { SliderThumbProps } from "./ui/slider/slider-thumb.js";
25
+ import { SliderTrackProps } from "./ui/slider/slider-track.js";
26
+ import { SliderValueProps } from "./ui/slider/slider-value.js";
27
+ import { index_parts_d_exports as index_parts_d_exports$2 } from "./ui/slider/index.parts.js";
28
+ import "./ui/slider/index.js";
29
+ import { Thumbnail, ThumbnailProps } from "./ui/thumbnail/thumbnail.js";
30
+ import { index_parts_d_exports as index_parts_d_exports$3 } from "./ui/time/index.parts.js";
17
31
  import "./ui/time/index.js";
32
+ import { index_parts_d_exports as index_parts_d_exports$4 } from "./ui/time-slider/index.parts.js";
33
+ import "./ui/time-slider/index.js";
34
+ import { index_parts_d_exports as index_parts_d_exports$5 } from "./ui/volume-slider/index.parts.js";
35
+ import "./ui/volume-slider/index.js";
18
36
  import { mergeProps } from "./utils/merge-props.js";
19
37
  import { renderElement } from "./utils/use-render.js";
20
38
  import { Comparator, Selector, createSelector, shallowEqual } from "@videojs/store";
21
39
  import { useSelector, useStore } from "@videojs/store/react";
22
40
  export * from "@videojs/core/dom";
23
- export { BufferingIndicator, type BufferingIndicatorProps, type Comparator, Container, type ContainerProps, index_parts_d_exports as Controls, type ControlsGroupProps, type ControlsRootProps, type CreatePlayerConfig, type CreatePlayerResult, FullscreenButton, type FullscreenButtonProps, type HTMLProps, MuteButton, type MuteButtonProps, PiPButton, type PiPButtonProps, PlayButton, type PlayButtonProps, type PlayerContextValue, Poster, type PosterProps, type ProviderProps, type RenderFunction, type RenderProp, SeekButton, type SeekButtonProps, type Selector, index_parts_d_exports$1 as Time, type UIComponentProps, createPlayer, createSelector, mergeProps, renderElement, shallowEqual, useButton, useMedia, useMediaRegistration, usePlayer, usePlayerContext, useSelector, useStore };
41
+ export { BufferingIndicator, type BufferingIndicatorProps, type Comparator, Container, type ContainerProps, index_parts_d_exports as Controls, type ControlsGroupProps, type ControlsRootProps, type CreatePlayerConfig, type CreatePlayerResult, FullscreenButton, type FullscreenButtonProps, type HTMLProps, MuteButton, type MuteButtonProps, PiPButton, type PiPButtonProps, PlayButton, type PlayButtonProps, PlaybackRateButton, type PlaybackRateButtonProps, type PlayerContextValue, index_parts_d_exports$1 as Popover, type PopoverContextValue, Poster, type PosterProps, type ProviderProps, type RenderFunction, type RenderProp, SeekButton, type SeekButtonProps, type Selector, index_parts_d_exports$2 as Slider, type SliderBufferProps, type SliderFillProps, type SliderRootProps, type SliderThumbProps, type SliderTrackProps, type SliderValueProps, Thumbnail, type ThumbnailProps, index_parts_d_exports$3 as Time, index_parts_d_exports$4 as TimeSlider, type UIComponentProps, index_parts_d_exports$5 as VolumeSlider, createPlayer, createSelector, mergeProps, renderElement, shallowEqual, useButton, useMedia, useMediaRegistration, usePlayer, usePlayerContext, usePopoverContext, useSelector, useSlider, useStore };
package/dist/dev/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  'use client';
2
2
 
3
- import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
4
3
  import { Container, useMedia, useMediaRegistration, usePlayer, usePlayerContext } from "./player/context.js";
5
4
  import { createPlayer } from "./player/create-player.js";
6
5
  import { mergeProps } from "./utils/merge-props.js";
@@ -9,45 +8,23 @@ import { BufferingIndicator } from "./ui/buffering-indicator/buffering-indicator
9
8
  import { index_parts_exports } from "./ui/controls/index.parts.js";
10
9
  import { useButton } from "./ui/hooks/use-button.js";
11
10
  import { FullscreenButton } from "./ui/fullscreen-button/fullscreen-button.js";
11
+ import { useSlider } from "./ui/hooks/use-slider.js";
12
12
  import { MuteButton } from "./ui/mute-button/mute-button.js";
13
13
  import { PiPButton } from "./ui/pip-button/pip-button.js";
14
14
  import { PlayButton } from "./ui/play-button/play-button.js";
15
+ import { PlaybackRateButton } from "./ui/playback-rate-button/playback-rate-button.js";
16
+ import { usePopoverContext } from "./ui/popover/context.js";
17
+ import { index_parts_exports as index_parts_exports$1 } from "./ui/popover/index.parts.js";
15
18
  import { Poster } from "./ui/poster/poster.js";
16
19
  import { SeekButton } from "./ui/seek-button/seek-button.js";
17
- import { index_parts_exports as index_parts_exports$1 } from "./ui/time/index.parts.js";
20
+ import { index_parts_exports as index_parts_exports$2 } from "./ui/slider/index.parts.js";
21
+ import { Thumbnail } from "./ui/thumbnail/thumbnail.js";
22
+ import { index_parts_exports as index_parts_exports$3 } from "./ui/time/index.parts.js";
23
+ import { index_parts_exports as index_parts_exports$4 } from "./ui/time-slider/index.parts.js";
24
+ import { index_parts_exports as index_parts_exports$5 } from "./ui/volume-slider/index.parts.js";
18
25
  import { createSelector, shallowEqual } from "@videojs/store";
19
26
  import { useSelector, useStore } from "@videojs/store/react";
20
27
 
21
28
  export * from "@videojs/core/dom"
22
29
 
23
- //#region src/index.ts
24
- var src_exports = /* @__PURE__ */ __exportAll({
25
- BufferingIndicator: () => BufferingIndicator,
26
- Container: () => Container,
27
- Controls: () => index_parts_exports,
28
- FullscreenButton: () => FullscreenButton,
29
- MuteButton: () => MuteButton,
30
- PiPButton: () => PiPButton,
31
- PlayButton: () => PlayButton,
32
- Poster: () => Poster,
33
- SeekButton: () => SeekButton,
34
- Time: () => index_parts_exports$1,
35
- createPlayer: () => createPlayer,
36
- createSelector: () => createSelector,
37
- mergeProps: () => mergeProps,
38
- renderElement: () => renderElement,
39
- shallowEqual: () => shallowEqual,
40
- useButton: () => useButton,
41
- useMedia: () => useMedia,
42
- useMediaRegistration: () => useMediaRegistration,
43
- usePlayer: () => usePlayer,
44
- usePlayerContext: () => usePlayerContext,
45
- useSelector: () => useSelector,
46
- useStore: () => useStore
47
- });
48
- import * as import__videojs_core_dom from "@videojs/core/dom";
49
- __reExport(src_exports, import__videojs_core_dom);
50
-
51
- //#endregion
52
- export { BufferingIndicator, Container, index_parts_exports as Controls, FullscreenButton, MuteButton, PiPButton, PlayButton, Poster, SeekButton, index_parts_exports$1 as Time, createPlayer, createSelector, mergeProps, renderElement, shallowEqual, src_exports, useButton, useMedia, useMediaRegistration, usePlayer, usePlayerContext, useSelector, useStore };
53
- //# sourceMappingURL=index.js.map
30
+ export { BufferingIndicator, Container, index_parts_exports as Controls, FullscreenButton, MuteButton, PiPButton, PlayButton, PlaybackRateButton, index_parts_exports$1 as Popover, Poster, SeekButton, index_parts_exports$2 as Slider, Thumbnail, index_parts_exports$3 as Time, index_parts_exports$4 as TimeSlider, index_parts_exports$5 as VolumeSlider, createPlayer, createSelector, mergeProps, renderElement, shallowEqual, useButton, useMedia, useMediaRegistration, usePlayer, usePlayerContext, usePopoverContext, useSelector, useSlider, useStore };
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","names":[],"sources":["../../../src/player/context.tsx"],"mappings":";;;;;;UAUiB,kBAAA;EACf,KAAA,EAAO,YAAA;EACP,KAAA,EAAO,KAAA;EACP,QAAA,EAAU,QAAA,CAAS,cAAA,CAAe,KAAA;AAAA;;iBAgBpB,gBAAA,CAAA,GAAoB,kBAAA;;;;;;iBAWpB,SAAA,CAAA,GAAa,YAAA;;;;;;;iBAOb,SAAA,GAAA,CAAa,QAAA,GAAW,KAAA,EAAO,YAAA,KAAiB,CAAA,GAAI,CAAA;;iBAOpD,QAAA,CAAA,GAAY,KAAA;;iBAMZ,oBAAA,CAAA,GAAwB,QAAA,CAAS,cAAA,CAAe,KAAA;AAAA,UAK/C,cAAA,SAAuB,cAAA,CAAe,cAAA;EACrD,QAAA,GAAW,SAAA;AAAA;AAAA,cAGA,SAAA,EAAS,KAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,KAAA,CAAA,aAAA,CAAA,cAAA;AAAA,kBAiBL,SAAA;EAAA,KACH,KAAA,GAAQ,cAAA;AAAA"}
1
+ {"version":3,"file":"context.d.ts","names":[],"sources":["../../../src/player/context.tsx"],"mappings":";;;;;;UAUiB,kBAAA;EACf,KAAA,EAAO,YAAA;EACP,KAAA,EAAO,KAAA;EACP,QAAA,EAAU,QAAA,CAAS,cAAA,CAAe,KAAA;AAAA;;iBAqBpB,gBAAA,CAAA,GAAoB,kBAAA;;;;;;iBAWpB,SAAA,CAAA,GAAa,YAAA;;;;;;;iBAOb,SAAA,GAAA,CAAa,QAAA,GAAW,KAAA,EAAO,YAAA,KAAiB,CAAA,GAAI,CAAA;;iBAwBpD,QAAA,CAAA,GAAY,KAAA;;iBAMZ,oBAAA,CAAA,GAAwB,QAAA,CAAS,cAAA,CAAe,KAAA;AAAA,UAK/C,cAAA,SAAuB,cAAA,CAAe,cAAA;EACrD,QAAA,GAAW,SAAA;AAAA;AAAA,cAGA,SAAA,EAAS,KAAA,CAAA,yBAAA,CAAA,cAAA,GAAA,KAAA,CAAA,aAAA,CAAA,cAAA;AAAA,kBAiBL,SAAA;EAAA,KACH,KAAA,GAAQ,cAAA;AAAA"}
@@ -7,6 +7,11 @@ import { jsx } from "react/jsx-runtime";
7
7
 
8
8
  //#region src/player/context.tsx
9
9
  const PlayerContext = createContext(null);
10
+ const EMPTY_UNSUBSCRIBE = () => {};
11
+ const EMPTY_STORE = {
12
+ state: {},
13
+ subscribe: () => EMPTY_UNSUBSCRIBE
14
+ };
10
15
  function PlayerContextProvider({ value, children }) {
11
16
  return /* @__PURE__ */ jsx(PlayerContext.Provider, {
12
17
  value,
@@ -23,6 +28,11 @@ function usePlayer(selector) {
23
28
  const { store } = usePlayerContext();
24
29
  return useStore(store, selector);
25
30
  }
31
+ function useOptionalPlayer(selector) {
32
+ const ctx = useContext(PlayerContext);
33
+ const value = useStore(ctx?.store ?? EMPTY_STORE, ctx ? selector : void 0);
34
+ return ctx ? value : void 0;
35
+ }
26
36
  /** Access the media element from within a Player Provider. */
27
37
  function useMedia() {
28
38
  const { media } = usePlayerContext();
@@ -51,5 +61,5 @@ const Container = forwardRef(function Container({ children, ...props }, ref) {
51
61
  });
52
62
 
53
63
  //#endregion
54
- export { Container, PlayerContextProvider, useMedia, useMediaRegistration, usePlayer, usePlayerContext };
64
+ export { Container, PlayerContextProvider, useMedia, useMediaRegistration, useOptionalPlayer, usePlayer, usePlayerContext };
55
65
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../src/player/context.tsx"],"sourcesContent":["'use client';\n\nimport type { Media } from '@videojs/core/dom';\nimport type { UnknownState, UnknownStore } from '@videojs/store';\nimport { useStore } from '@videojs/store/react';\nimport type { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react';\nimport { createContext, forwardRef, useContext, useEffect, useRef } from 'react';\n\nimport { useComposedRefs } from '../utils/use-composed-refs';\n\nexport interface PlayerContextValue {\n store: UnknownStore;\n media: Media | null;\n setMedia: Dispatch<SetStateAction<Media | null>>;\n}\n\nconst PlayerContext = createContext<PlayerContextValue | null>(null);\n\nexport function PlayerContextProvider({\n value,\n children,\n}: {\n value: PlayerContextValue;\n children: ReactNode;\n}): ReactNode {\n return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;\n}\n\n/** Access the full player context value. Throws if used outside a Player Provider. */\nexport function usePlayerContext(): PlayerContextValue {\n const ctx = useContext(PlayerContext);\n if (!ctx) throw new Error('usePlayerContext must be used within a Player Provider');\n return ctx;\n}\n\n/**\n * Access the player store from within a Player Provider.\n *\n * @label Without Selector\n */\nexport function usePlayer(): UnknownStore;\n/**\n * Select a value from the player store. Re-renders when the selected value changes.\n *\n * @label With Selector\n * @param selector - Derives a value from the player store state.\n */\nexport function usePlayer<R>(selector: (state: UnknownState) => R): R;\nexport function usePlayer<R>(selector?: (state: UnknownState) => R) {\n const { store } = usePlayerContext();\n return useStore(store, selector as any);\n}\n\n/** Access the media element from within a Player Provider. */\nexport function useMedia(): Media | null {\n const { media } = usePlayerContext();\n return media;\n}\n\n/** Access the media registration setter for connecting a media element to the player. */\nexport function useMediaRegistration(): Dispatch<SetStateAction<Media | null>> | undefined {\n const ctx = useContext(PlayerContext);\n return ctx?.setMedia;\n}\n\nexport interface ContainerProps extends HTMLAttributes<HTMLDivElement> {\n children?: ReactNode;\n}\n\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container({ children, ...props }, ref) {\n const { store, media } = usePlayerContext();\n const internalRef = useRef<HTMLDivElement>(null);\n const composedRef = useComposedRefs(ref, internalRef);\n\n useEffect(() => {\n if (!media) return;\n return store.attach({ media, container: internalRef.current });\n }, [media, store]);\n\n return (\n <div ref={composedRef} {...props}>\n {children}\n </div>\n );\n});\n\nexport namespace Container {\n export type Props = ContainerProps;\n}\n"],"mappings":";;;;;;;;AAgBA,MAAM,gBAAgB,cAAyC,KAAK;AAEpE,SAAgB,sBAAsB,EACpC,OACA,YAIY;AACZ,QAAO,oBAAC,cAAc;EAAgB;EAAQ;GAAkC;;;AAIlF,SAAgB,mBAAuC;CACrD,MAAM,MAAM,WAAW,cAAc;AACrC,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,yDAAyD;AACnF,QAAO;;AAgBT,SAAgB,UAAa,UAAuC;CAClE,MAAM,EAAE,UAAU,kBAAkB;AACpC,QAAO,SAAS,OAAO,SAAgB;;;AAIzC,SAAgB,WAAyB;CACvC,MAAM,EAAE,UAAU,kBAAkB;AACpC,QAAO;;;AAIT,SAAgB,uBAA2E;AAEzF,QADY,WAAW,cAAc,EACzB;;AAOd,MAAa,YAAY,WAA2C,SAAS,UAAU,EAAE,UAAU,GAAG,SAAS,KAAK;CAClH,MAAM,EAAE,OAAO,UAAU,kBAAkB;CAC3C,MAAM,cAAc,OAAuB,KAAK;CAChD,MAAM,cAAc,gBAAgB,KAAK,YAAY;AAErD,iBAAgB;AACd,MAAI,CAAC,MAAO;AACZ,SAAO,MAAM,OAAO;GAAE;GAAO,WAAW,YAAY;GAAS,CAAC;IAC7D,CAAC,OAAO,MAAM,CAAC;AAElB,QACE,oBAAC;EAAI,KAAK;EAAa,GAAI;EACxB;GACG;EAER"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../src/player/context.tsx"],"sourcesContent":["'use client';\n\nimport type { Media } from '@videojs/core/dom';\nimport type { UnknownState, UnknownStore } from '@videojs/store';\nimport { useStore } from '@videojs/store/react';\nimport type { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react';\nimport { createContext, forwardRef, useContext, useEffect, useRef } from 'react';\n\nimport { useComposedRefs } from '../utils/use-composed-refs';\n\nexport interface PlayerContextValue {\n store: UnknownStore;\n media: Media | null;\n setMedia: Dispatch<SetStateAction<Media | null>>;\n}\n\nconst PlayerContext = createContext<PlayerContextValue | null>(null);\nconst EMPTY_UNSUBSCRIBE = () => {};\nconst EMPTY_STORE = {\n state: {} as UnknownState,\n subscribe: () => EMPTY_UNSUBSCRIBE,\n} as Pick<UnknownStore, 'state' | 'subscribe'>;\n\nexport function PlayerContextProvider({\n value,\n children,\n}: {\n value: PlayerContextValue;\n children: ReactNode;\n}): ReactNode {\n return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;\n}\n\n/** Access the full player context value. Throws if used outside a Player Provider. */\nexport function usePlayerContext(): PlayerContextValue {\n const ctx = useContext(PlayerContext);\n if (!ctx) throw new Error('usePlayerContext must be used within a Player Provider');\n return ctx;\n}\n\n/**\n * Access the player store from within a Player Provider.\n *\n * @label Without Selector\n */\nexport function usePlayer(): UnknownStore;\n/**\n * Select a value from the player store. Re-renders when the selected value changes.\n *\n * @label With Selector\n * @param selector - Derives a value from the player store state.\n */\nexport function usePlayer<R>(selector: (state: UnknownState) => R): R;\nexport function usePlayer<R>(selector?: (state: UnknownState) => R) {\n const { store } = usePlayerContext();\n return useStore(store, selector as any);\n}\n\n/**\n * Access player state when available, but return `undefined` outside Provider.\n *\n * This is useful for components that can operate without player context\n * (e.g. they accept fully explicit props as a fallback).\n */\n/** @label Without Selector */\nexport function useOptionalPlayer(): UnknownStore | undefined;\n/** @label With Selector */\nexport function useOptionalPlayer<R>(selector: (state: UnknownState) => R): R | undefined;\nexport function useOptionalPlayer<R>(selector?: (state: UnknownState) => R) {\n const ctx = useContext(PlayerContext);\n const store = (ctx?.store ?? (EMPTY_STORE as unknown as UnknownStore)) as UnknownStore;\n const value = useStore(store, (ctx ? selector : undefined) as any);\n return ctx ? value : undefined;\n}\n\n/** Access the media element from within a Player Provider. */\nexport function useMedia(): Media | null {\n const { media } = usePlayerContext();\n return media;\n}\n\n/** Access the media registration setter for connecting a media element to the player. */\nexport function useMediaRegistration(): Dispatch<SetStateAction<Media | null>> | undefined {\n const ctx = useContext(PlayerContext);\n return ctx?.setMedia;\n}\n\nexport interface ContainerProps extends HTMLAttributes<HTMLDivElement> {\n children?: ReactNode;\n}\n\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container({ children, ...props }, ref) {\n const { store, media } = usePlayerContext();\n const internalRef = useRef<HTMLDivElement>(null);\n const composedRef = useComposedRefs(ref, internalRef);\n\n useEffect(() => {\n if (!media) return;\n return store.attach({ media, container: internalRef.current });\n }, [media, store]);\n\n return (\n <div ref={composedRef} {...props}>\n {children}\n </div>\n );\n});\n\nexport namespace Container {\n export type Props = ContainerProps;\n}\n"],"mappings":";;;;;;;;AAgBA,MAAM,gBAAgB,cAAyC,KAAK;AACpE,MAAM,0BAA0B;AAChC,MAAM,cAAc;CAClB,OAAO,EAAE;CACT,iBAAiB;CAClB;AAED,SAAgB,sBAAsB,EACpC,OACA,YAIY;AACZ,QAAO,oBAAC,cAAc;EAAgB;EAAQ;GAAkC;;;AAIlF,SAAgB,mBAAuC;CACrD,MAAM,MAAM,WAAW,cAAc;AACrC,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,yDAAyD;AACnF,QAAO;;AAgBT,SAAgB,UAAa,UAAuC;CAClE,MAAM,EAAE,UAAU,kBAAkB;AACpC,QAAO,SAAS,OAAO,SAAgB;;AAazC,SAAgB,kBAAqB,UAAuC;CAC1E,MAAM,MAAM,WAAW,cAAc;CAErC,MAAM,QAAQ,SADC,KAAK,SAAU,aACC,MAAM,WAAW,OAAkB;AAClE,QAAO,MAAM,QAAQ;;;AAIvB,SAAgB,WAAyB;CACvC,MAAM,EAAE,UAAU,kBAAkB;AACpC,QAAO;;;AAIT,SAAgB,uBAA2E;AAEzF,QADY,WAAW,cAAc,EACzB;;AAOd,MAAa,YAAY,WAA2C,SAAS,UAAU,EAAE,UAAU,GAAG,SAAS,KAAK;CAClH,MAAM,EAAE,OAAO,UAAU,kBAAkB;CAC3C,MAAM,cAAc,OAAuB,KAAK;CAChD,MAAM,cAAc,gBAAgB,KAAK,YAAY;AAErD,iBAAgB;AACd,MAAI,CAAC,MAAO;AACZ,SAAO,MAAM,OAAO;GAAE;GAAO,WAAW,YAAY;GAAS,CAAC;IAC7D,CAAC,OAAO,MAAM,CAAC;AAElB,QACE,oBAAC;EAAI,KAAK;EAAa,GAAI;EACxB;GACG;EAER"}
@@ -1,12 +1,5 @@
1
- import { ProviderProps } from "../../player/create-player.js";
2
- import "../../index.js";
3
1
  import { Audio, AudioProps } from "../../media/audio.js";
4
2
  import { MinimalAudioSkin, MinimalAudioSkinProps } from "./minimal-skin.js";
5
3
  import { AudioSkin, AudioSkinProps } from "./skin.js";
6
- import * as react from "react";
7
-
8
- //#region src/presets/audio/index.d.ts
9
- declare const AudioProvider: react.FC<ProviderProps>;
10
- //#endregion
11
- export { Audio, type AudioProps, AudioProvider, AudioSkin, AudioSkinProps, MinimalAudioSkin, MinimalAudioSkinProps };
12
- //# sourceMappingURL=index.d.ts.map
4
+ import { audioFeatures } from "@videojs/core/dom";
5
+ export { Audio, type AudioProps, AudioSkin, AudioSkinProps, MinimalAudioSkin, MinimalAudioSkinProps, audioFeatures };
@@ -1,12 +1,6 @@
1
- import { createPlayer } from "../../player/create-player.js";
2
- import { src_exports } from "../../index.js";
3
1
  import { Audio } from "../../media/audio.js";
4
2
  import { MinimalAudioSkin } from "./minimal-skin.js";
5
3
  import { AudioSkin } from "./skin.js";
4
+ import { audioFeatures } from "@videojs/core/dom";
6
5
 
7
- //#region src/presets/audio/index.ts
8
- const { Provider: AudioProvider } = createPlayer({ features: src_exports.features.audio });
9
-
10
- //#endregion
11
- export { Audio, AudioProvider, AudioSkin, MinimalAudioSkin };
12
- //# sourceMappingURL=index.js.map
6
+ export { Audio, AudioSkin, MinimalAudioSkin, audioFeatures };
@@ -1,3 +1,4 @@
1
1
  .media-skin {
2
2
  color: var(--media-color, red);
3
3
  }
4
+