@videojs/react 0.1.0-preview.8 → 10.0.0-alpha.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 (298) hide show
  1. package/README.md +1 -1
  2. package/dist/default/_virtual/_rolldown/runtime.js +18 -0
  3. package/dist/default/index.js +22 -0
  4. package/dist/default/media/audio.js +22 -0
  5. package/dist/default/media/audio.js.map +1 -0
  6. package/dist/default/media/background-video/index.js +28 -0
  7. package/dist/default/media/background-video/index.js.map +1 -0
  8. package/dist/default/media/hls-video/index.js +25 -0
  9. package/dist/default/media/hls-video/index.js.map +1 -0
  10. package/dist/default/media/video.js +22 -0
  11. package/dist/default/media/video.js.map +1 -0
  12. package/dist/default/player/context.js +55 -0
  13. package/dist/default/player/context.js.map +1 -0
  14. package/dist/default/player/create-player.js +38 -0
  15. package/dist/default/player/create-player.js.map +1 -0
  16. package/dist/default/presets/audio/index.js +5 -0
  17. package/dist/default/presets/audio/minimal-skin.css +3 -0
  18. package/dist/default/presets/audio/minimal-skin.js +11 -0
  19. package/dist/default/presets/audio/minimal-skin.js.map +1 -0
  20. package/dist/default/presets/audio/skin.css +3 -0
  21. package/dist/default/presets/audio/skin.js +11 -0
  22. package/dist/default/presets/audio/skin.js.map +1 -0
  23. package/dist/default/presets/background/index.js +4 -0
  24. package/dist/default/presets/background/skin.css +3 -0
  25. package/dist/default/presets/background/skin.js +11 -0
  26. package/dist/default/presets/background/skin.js.map +1 -0
  27. package/dist/default/presets/video/index.js +7 -0
  28. package/dist/default/presets/video/minimal-skin.css +637 -0
  29. package/dist/default/presets/video/minimal-skin.js +234 -0
  30. package/dist/default/presets/video/minimal-skin.js.map +1 -0
  31. package/dist/default/presets/video/minimal-skin.tailwind.js +231 -0
  32. package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -0
  33. package/dist/default/presets/video/skin.css +638 -0
  34. package/dist/default/presets/video/skin.js +223 -0
  35. package/dist/default/presets/video/skin.js.map +1 -0
  36. package/dist/default/presets/video/skin.tailwind.js +222 -0
  37. package/dist/default/presets/video/skin.tailwind.js.map +1 -0
  38. package/dist/default/ui/buffering-indicator/buffering-indicator.js +50 -0
  39. package/dist/default/ui/buffering-indicator/buffering-indicator.js.map +1 -0
  40. package/dist/default/ui/buffering-indicator/index.js +3 -0
  41. package/dist/default/ui/captions-button/captions-button.js +51 -0
  42. package/dist/default/ui/captions-button/captions-button.js.map +1 -0
  43. package/dist/default/ui/captions-button/index.js +3 -0
  44. package/dist/default/ui/controls/controls-group.js +27 -0
  45. package/dist/default/ui/controls/controls-group.js.map +1 -0
  46. package/dist/default/ui/controls/controls-root.js +31 -0
  47. package/dist/default/ui/controls/controls-root.js.map +1 -0
  48. package/dist/default/ui/controls/index.js +3 -0
  49. package/dist/default/ui/controls/index.parts.js +13 -0
  50. package/dist/default/ui/controls/index.parts.js.map +1 -0
  51. package/dist/default/ui/error-dialog/error-dialog.js +54 -0
  52. package/dist/default/ui/error-dialog/error-dialog.js.map +1 -0
  53. package/dist/default/ui/error-dialog/index.js +3 -0
  54. package/dist/default/ui/fullscreen-button/fullscreen-button.js +44 -0
  55. package/dist/default/ui/fullscreen-button/fullscreen-button.js.map +1 -0
  56. package/dist/default/ui/fullscreen-button/index.js +3 -0
  57. package/dist/default/ui/hooks/use-button.js +44 -0
  58. package/dist/default/ui/hooks/use-button.js.map +1 -0
  59. package/dist/default/ui/mute-button/index.js +3 -0
  60. package/dist/default/ui/mute-button/mute-button.js +47 -0
  61. package/dist/default/ui/mute-button/mute-button.js.map +1 -0
  62. package/dist/default/ui/pip-button/index.js +3 -0
  63. package/dist/default/ui/pip-button/pip-button.js +44 -0
  64. package/dist/default/ui/pip-button/pip-button.js.map +1 -0
  65. package/dist/default/ui/play-button/index.js +3 -0
  66. package/dist/default/ui/play-button/play-button.js +60 -0
  67. package/dist/default/ui/play-button/play-button.js.map +1 -0
  68. package/dist/default/ui/poster/index.js +3 -0
  69. package/dist/default/ui/poster/poster.js +43 -0
  70. package/dist/default/ui/poster/poster.js.map +1 -0
  71. package/dist/default/ui/seek-button/index.js +3 -0
  72. package/dist/default/ui/seek-button/seek-button.js +62 -0
  73. package/dist/default/ui/seek-button/seek-button.js.map +1 -0
  74. package/dist/default/ui/time/index.js +3 -0
  75. package/dist/default/ui/time/index.parts.js +15 -0
  76. package/dist/default/ui/time/index.parts.js.map +1 -0
  77. package/dist/default/ui/time/time-group.js +34 -0
  78. package/dist/default/ui/time/time-group.js.map +1 -0
  79. package/dist/default/ui/time/time-separator.js +34 -0
  80. package/dist/default/ui/time/time-separator.js.map +1 -0
  81. package/dist/default/ui/time/time-value.js +54 -0
  82. package/dist/default/ui/time/time-value.js.map +1 -0
  83. package/dist/default/utils/attach-media-element.js +12 -0
  84. package/dist/default/utils/attach-media-element.js.map +1 -0
  85. package/dist/default/utils/media-props.js +11 -0
  86. package/dist/default/utils/media-props.js.map +1 -0
  87. package/dist/default/utils/merge-props.js +85 -0
  88. package/dist/default/utils/merge-props.js.map +1 -0
  89. package/dist/default/utils/use-composed-refs.js +57 -0
  90. package/dist/default/utils/use-composed-refs.js.map +1 -0
  91. package/dist/default/utils/use-render.js +71 -0
  92. package/dist/default/utils/use-render.js.map +1 -0
  93. package/dist/dev/_virtual/_rolldown/runtime.js +18 -0
  94. package/dist/dev/index.d.ts +23 -0
  95. package/dist/dev/index.js +22 -0
  96. package/dist/dev/media/audio.d.ts +12 -0
  97. package/dist/dev/media/audio.d.ts.map +1 -0
  98. package/dist/dev/media/audio.js +22 -0
  99. package/dist/dev/media/audio.js.map +1 -0
  100. package/dist/dev/media/background-video/index.d.ts +12 -0
  101. package/dist/dev/media/background-video/index.d.ts.map +1 -0
  102. package/dist/dev/media/background-video/index.js +28 -0
  103. package/dist/dev/media/background-video/index.js.map +1 -0
  104. package/dist/dev/media/hls-video/index.d.ts +11 -0
  105. package/dist/dev/media/hls-video/index.d.ts.map +1 -0
  106. package/dist/dev/media/hls-video/index.js +25 -0
  107. package/dist/dev/media/hls-video/index.js.map +1 -0
  108. package/dist/dev/media/video.d.ts +12 -0
  109. package/dist/dev/media/video.d.ts.map +1 -0
  110. package/dist/dev/media/video.js +22 -0
  111. package/dist/dev/media/video.js.map +1 -0
  112. package/dist/dev/player/context.d.ts +40 -0
  113. package/dist/dev/player/context.d.ts.map +1 -0
  114. package/dist/dev/player/context.js +55 -0
  115. package/dist/dev/player/context.js.map +1 -0
  116. package/dist/dev/player/create-player.d.ts +47 -0
  117. package/dist/dev/player/create-player.d.ts.map +1 -0
  118. package/dist/dev/player/create-player.js +39 -0
  119. package/dist/dev/player/create-player.js.map +1 -0
  120. package/dist/dev/presets/audio/index.d.ts +4 -0
  121. package/dist/dev/presets/audio/index.js +5 -0
  122. package/dist/dev/presets/audio/minimal-skin.css +3 -0
  123. package/dist/dev/presets/audio/minimal-skin.d.ts +9 -0
  124. package/dist/dev/presets/audio/minimal-skin.d.ts.map +1 -0
  125. package/dist/dev/presets/audio/minimal-skin.js +11 -0
  126. package/dist/dev/presets/audio/minimal-skin.js.map +1 -0
  127. package/dist/dev/presets/audio/skin.css +3 -0
  128. package/dist/dev/presets/audio/skin.d.ts +9 -0
  129. package/dist/dev/presets/audio/skin.d.ts.map +1 -0
  130. package/dist/dev/presets/audio/skin.js +11 -0
  131. package/dist/dev/presets/audio/skin.js.map +1 -0
  132. package/dist/dev/presets/background/index.d.ts +3 -0
  133. package/dist/dev/presets/background/index.js +4 -0
  134. package/dist/dev/presets/background/skin.css +3 -0
  135. package/dist/dev/presets/background/skin.d.ts +9 -0
  136. package/dist/dev/presets/background/skin.d.ts.map +1 -0
  137. package/dist/dev/presets/background/skin.js +11 -0
  138. package/dist/dev/presets/background/skin.js.map +1 -0
  139. package/dist/dev/presets/types.d.ts +10 -0
  140. package/dist/dev/presets/types.d.ts.map +1 -0
  141. package/dist/dev/presets/video/index.d.ts +6 -0
  142. package/dist/dev/presets/video/index.js +7 -0
  143. package/dist/dev/presets/video/minimal-skin.css +637 -0
  144. package/dist/dev/presets/video/minimal-skin.d.ts +9 -0
  145. package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -0
  146. package/dist/dev/presets/video/minimal-skin.js +234 -0
  147. package/dist/dev/presets/video/minimal-skin.js.map +1 -0
  148. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts +8 -0
  149. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -0
  150. package/dist/dev/presets/video/minimal-skin.tailwind.js +231 -0
  151. package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -0
  152. package/dist/dev/presets/video/skin.css +638 -0
  153. package/dist/dev/presets/video/skin.d.ts +9 -0
  154. package/dist/dev/presets/video/skin.d.ts.map +1 -0
  155. package/dist/dev/presets/video/skin.js +223 -0
  156. package/dist/dev/presets/video/skin.js.map +1 -0
  157. package/dist/dev/presets/video/skin.tailwind.d.ts +8 -0
  158. package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -0
  159. package/dist/dev/presets/video/skin.tailwind.js +222 -0
  160. package/dist/dev/presets/video/skin.tailwind.js.map +1 -0
  161. package/dist/dev/ui/buffering-indicator/buffering-indicator.d.ts +32 -0
  162. package/dist/dev/ui/buffering-indicator/buffering-indicator.d.ts.map +1 -0
  163. package/dist/dev/ui/buffering-indicator/buffering-indicator.js +53 -0
  164. package/dist/dev/ui/buffering-indicator/buffering-indicator.js.map +1 -0
  165. package/dist/dev/ui/buffering-indicator/index.d.ts +2 -0
  166. package/dist/dev/ui/buffering-indicator/index.js +3 -0
  167. package/dist/dev/ui/captions-button/captions-button.d.ts +36 -0
  168. package/dist/dev/ui/captions-button/captions-button.d.ts.map +1 -0
  169. package/dist/dev/ui/captions-button/captions-button.js +51 -0
  170. package/dist/dev/ui/captions-button/captions-button.js.map +1 -0
  171. package/dist/dev/ui/captions-button/index.d.ts +2 -0
  172. package/dist/dev/ui/captions-button/index.js +3 -0
  173. package/dist/dev/ui/controls/controls-group.d.ts +17 -0
  174. package/dist/dev/ui/controls/controls-group.d.ts.map +1 -0
  175. package/dist/dev/ui/controls/controls-group.js +27 -0
  176. package/dist/dev/ui/controls/controls-group.js.map +1 -0
  177. package/dist/dev/ui/controls/controls-root.d.ts +18 -0
  178. package/dist/dev/ui/controls/controls-root.d.ts.map +1 -0
  179. package/dist/dev/ui/controls/controls-root.js +34 -0
  180. package/dist/dev/ui/controls/controls-root.js.map +1 -0
  181. package/dist/dev/ui/controls/index.d.ts +2 -0
  182. package/dist/dev/ui/controls/index.js +3 -0
  183. package/dist/dev/ui/controls/index.parts.d.ts +10 -0
  184. package/dist/dev/ui/controls/index.parts.d.ts.map +1 -0
  185. package/dist/dev/ui/controls/index.parts.js +13 -0
  186. package/dist/dev/ui/controls/index.parts.js.map +1 -0
  187. package/dist/dev/ui/error-dialog/error-dialog.d.ts +35 -0
  188. package/dist/dev/ui/error-dialog/error-dialog.d.ts.map +1 -0
  189. package/dist/dev/ui/error-dialog/error-dialog.js +54 -0
  190. package/dist/dev/ui/error-dialog/error-dialog.js.map +1 -0
  191. package/dist/dev/ui/error-dialog/index.d.ts +2 -0
  192. package/dist/dev/ui/error-dialog/index.js +3 -0
  193. package/dist/dev/ui/fullscreen-button/fullscreen-button.d.ts +14 -0
  194. package/dist/dev/ui/fullscreen-button/fullscreen-button.d.ts.map +1 -0
  195. package/dist/dev/ui/fullscreen-button/fullscreen-button.js +47 -0
  196. package/dist/dev/ui/fullscreen-button/fullscreen-button.js.map +1 -0
  197. package/dist/dev/ui/fullscreen-button/index.d.ts +2 -0
  198. package/dist/dev/ui/fullscreen-button/index.js +3 -0
  199. package/dist/dev/ui/hooks/use-button.d.ts +40 -0
  200. package/dist/dev/ui/hooks/use-button.d.ts.map +1 -0
  201. package/dist/dev/ui/hooks/use-button.js +46 -0
  202. package/dist/dev/ui/hooks/use-button.js.map +1 -0
  203. package/dist/dev/ui/mute-button/index.d.ts +2 -0
  204. package/dist/dev/ui/mute-button/index.js +3 -0
  205. package/dist/dev/ui/mute-button/mute-button.d.ts +17 -0
  206. package/dist/dev/ui/mute-button/mute-button.d.ts.map +1 -0
  207. package/dist/dev/ui/mute-button/mute-button.js +50 -0
  208. package/dist/dev/ui/mute-button/mute-button.js.map +1 -0
  209. package/dist/dev/ui/pip-button/index.d.ts +2 -0
  210. package/dist/dev/ui/pip-button/index.js +3 -0
  211. package/dist/dev/ui/pip-button/pip-button.d.ts +14 -0
  212. package/dist/dev/ui/pip-button/pip-button.d.ts.map +1 -0
  213. package/dist/dev/ui/pip-button/pip-button.js +47 -0
  214. package/dist/dev/ui/pip-button/pip-button.js.map +1 -0
  215. package/dist/dev/ui/play-button/index.d.ts +2 -0
  216. package/dist/dev/ui/play-button/index.js +3 -0
  217. package/dist/dev/ui/play-button/play-button.d.ts +30 -0
  218. package/dist/dev/ui/play-button/play-button.d.ts.map +1 -0
  219. package/dist/dev/ui/play-button/play-button.js +63 -0
  220. package/dist/dev/ui/play-button/play-button.js.map +1 -0
  221. package/dist/dev/ui/poster/index.d.ts +2 -0
  222. package/dist/dev/ui/poster/index.js +3 -0
  223. package/dist/dev/ui/poster/poster.d.ts +28 -0
  224. package/dist/dev/ui/poster/poster.d.ts.map +1 -0
  225. package/dist/dev/ui/poster/poster.js +46 -0
  226. package/dist/dev/ui/poster/poster.js.map +1 -0
  227. package/dist/dev/ui/seek-button/index.d.ts +2 -0
  228. package/dist/dev/ui/seek-button/index.js +3 -0
  229. package/dist/dev/ui/seek-button/seek-button.d.ts +31 -0
  230. package/dist/dev/ui/seek-button/seek-button.d.ts.map +1 -0
  231. package/dist/dev/ui/seek-button/seek-button.js +65 -0
  232. package/dist/dev/ui/seek-button/seek-button.js.map +1 -0
  233. package/dist/dev/ui/time/index.d.ts +2 -0
  234. package/dist/dev/ui/time/index.js +3 -0
  235. package/dist/dev/ui/time/index.parts.d.ts +11 -0
  236. package/dist/dev/ui/time/index.parts.d.ts.map +1 -0
  237. package/dist/dev/ui/time/index.parts.js +15 -0
  238. package/dist/dev/ui/time/index.parts.js.map +1 -0
  239. package/dist/dev/ui/time/time-group.d.ts +29 -0
  240. package/dist/dev/ui/time/time-group.d.ts.map +1 -0
  241. package/dist/dev/ui/time/time-group.js +34 -0
  242. package/dist/dev/ui/time/time-group.js.map +1 -0
  243. package/dist/dev/ui/time/time-separator.d.ts +26 -0
  244. package/dist/dev/ui/time/time-separator.d.ts.map +1 -0
  245. package/dist/dev/ui/time/time-separator.js +34 -0
  246. package/dist/dev/ui/time/time-separator.js.map +1 -0
  247. package/dist/dev/ui/time/time-value.d.ts +24 -0
  248. package/dist/dev/ui/time/time-value.d.ts.map +1 -0
  249. package/dist/dev/ui/time/time-value.js +57 -0
  250. package/dist/dev/ui/time/time-value.js.map +1 -0
  251. package/dist/dev/utils/attach-media-element.js +12 -0
  252. package/dist/dev/utils/attach-media-element.js.map +1 -0
  253. package/dist/dev/utils/media-props.js +11 -0
  254. package/dist/dev/utils/media-props.js.map +1 -0
  255. package/dist/dev/utils/merge-props.d.ts +26 -0
  256. package/dist/dev/utils/merge-props.d.ts.map +1 -0
  257. package/dist/dev/utils/merge-props.js +85 -0
  258. package/dist/dev/utils/merge-props.js.map +1 -0
  259. package/dist/dev/utils/types.d.ts +27 -0
  260. package/dist/dev/utils/types.d.ts.map +1 -0
  261. package/dist/dev/utils/use-composed-refs.js +57 -0
  262. package/dist/dev/utils/use-composed-refs.js.map +1 -0
  263. package/dist/dev/utils/use-render.d.ts +45 -0
  264. package/dist/dev/utils/use-render.d.ts.map +1 -0
  265. package/dist/dev/utils/use-render.js +71 -0
  266. package/dist/dev/utils/use-render.js.map +1 -0
  267. package/package.json +58 -53
  268. package/dist/FrostedSkin-t8edr5LV.d.ts +0 -13
  269. package/dist/FrostedSkin-t8edr5LV.d.ts.map +0 -1
  270. package/dist/MinimalSkin-DzHkJgW-.d.ts +0 -13
  271. package/dist/MinimalSkin-DzHkJgW-.d.ts.map +0 -1
  272. package/dist/VolumeSlider-DmlupkvF.js +0 -1042
  273. package/dist/VolumeSlider-DmlupkvF.js.map +0 -1
  274. package/dist/frosted-0lXuIgHt.js +0 -156
  275. package/dist/frosted-0lXuIgHt.js.map +0 -1
  276. package/dist/icons-BqfV81R8.js +0 -316
  277. package/dist/icons-BqfV81R8.js.map +0 -1
  278. package/dist/icons.d.ts +0 -71
  279. package/dist/icons.d.ts.map +0 -1
  280. package/dist/icons.js +0 -3
  281. package/dist/index-CM70WSkA.d.ts +0 -36
  282. package/dist/index-CM70WSkA.d.ts.map +0 -1
  283. package/dist/index.d.ts +0 -312
  284. package/dist/index.d.ts.map +0 -1
  285. package/dist/index.js +0 -89
  286. package/dist/index.js.map +0 -1
  287. package/dist/minimal-B-R9aRNe.js +0 -162
  288. package/dist/minimal-B-R9aRNe.js.map +0 -1
  289. package/dist/skins/frosted.css +0 -4
  290. package/dist/skins/frosted.d.ts +0 -2
  291. package/dist/skins/frosted.js +0 -9
  292. package/dist/skins/minimal.css +0 -4
  293. package/dist/skins/minimal.d.ts +0 -2
  294. package/dist/skins/minimal.js +0 -9
  295. package/dist/store-hGO5HE2A.js +0 -124
  296. package/dist/store-hGO5HE2A.js.map +0 -1
  297. package/dist/store.d.ts +0 -2
  298. package/dist/store.js +0 -6
@@ -1,1042 +0,0 @@
1
- import { a as useMediaStore, i as useMediaSelector } from "./store-hGO5HE2A.js";
2
- import { currentTimeDisplayStateDefinition, durationDisplayStateDefinition, fullscreenButtonStateDefinition, muteButtonStateDefinition, playButtonStateDefinition, previewTimeDisplayStateDefinition, timeSliderStateDefinition, volumeSliderStateDefinition } from "@videojs/core/store";
3
- import { formatDisplayTime, shallowEqual } from "@videojs/utils";
4
- import * as React$1 from "react";
5
- import { Children, cloneElement, createContext, forwardRef, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
6
- import { Fragment, jsx } from "react/jsx-runtime";
7
- import { contains, getBoundingClientRectWithoutTransform, getInBoundsAdjustments, safePolygon } from "@videojs/utils/dom";
8
- import { TimeSlider, VolumeSlider } from "@videojs/core";
9
-
10
- //#region src/utils/component-factory.tsx
11
- const Context$1 = createContext(null);
12
- /**
13
- * Generic factory function to create connected components following the hooks pattern
14
- * inspired by Adobe React Spectrum and Base UI architectures.
15
- *
16
- * @param useStateHook - Hook that provides component state
17
- * @param usePropsHook - Hook that enhances props with state-derived values
18
- * @param defaultRender - Default render function for the component
19
- * @param displayName - Display name for React DevTools
20
- * @returns Connected component with customizable render prop
21
- */
22
- function toConnectedComponent(useStateHook, usePropsHook, defaultRender, displayName) {
23
- const ConnectedComponent = forwardRef(({ render = defaultRender,...props }, ref) => {
24
- const propsWithRef = ref ? {
25
- ...props,
26
- ref
27
- } : props;
28
- const connectedState = useStateHook(propsWithRef);
29
- const connectedProps = usePropsHook(propsWithRef, connectedState);
30
- return /* @__PURE__ */ jsx(Context$1.Provider, {
31
- value: connectedState,
32
- children: render(connectedProps, connectedState)
33
- });
34
- });
35
- ConnectedComponent.displayName = displayName;
36
- return ConnectedComponent;
37
- }
38
- /**
39
- * Factory function to create context-based components that don't use toConnectedComponent
40
- * These components rely on context provided by a parent component.
41
- *
42
- * @param usePropsHook - Hook that enhances props with context-derived values
43
- * @param defaultRender - Default render function for the component
44
- * @param displayName - Display name for React DevTools
45
- * @returns Context-based component with customizable render prop
46
- */
47
- function toContextComponent(usePropsHook, defaultRender, displayName) {
48
- const ContextComponent = forwardRef(({ render = defaultRender,...props }, ref) => {
49
- const context = useContext(Context$1);
50
- return render(usePropsHook(ref ? {
51
- ...props,
52
- ref
53
- } : props, context), context);
54
- });
55
- ContextComponent.displayName = displayName;
56
- return ContextComponent;
57
- }
58
- /**
59
- * Hook that manages a CoreClass instance and triggers re-renders when state changes.
60
- * Uses useSyncExternalStore for optimal performance with external state subscriptions.
61
- */
62
- function useCore(CoreClass, state) {
63
- const coreRef = useRef(null);
64
- const snapshotRef = useRef(null);
65
- if (!coreRef.current) {
66
- coreRef.current = new CoreClass();
67
- snapshotRef.current = coreRef.current.getState();
68
- }
69
- useEffect(() => {
70
- coreRef.current?.setState(state);
71
- }, [...Object.values(state)]);
72
- useSyncExternalStore(useCallback((onStoreChange) => {
73
- if (!coreRef.current) return () => {};
74
- return coreRef.current.subscribe((newState) => {
75
- snapshotRef.current = newState;
76
- onStoreChange();
77
- });
78
- }, []), useCallback(() => {
79
- return snapshotRef.current;
80
- }, []), () => null);
81
- return coreRef.current;
82
- }
83
-
84
- //#endregion
85
- //#region src/components/CurrentTimeDisplay.tsx
86
- function useCurrentTimeDisplayState(_props) {
87
- /** @TODO Fix type issues with hooks (CJP) */
88
- const mediaState = useMediaSelector(currentTimeDisplayStateDefinition.stateTransform, shallowEqual);
89
- return {
90
- currentTime: mediaState.currentTime ?? 0,
91
- duration: mediaState.duration ?? 0
92
- };
93
- }
94
- function useCurrentTimeDisplayProps(props, _state) {
95
- return { ...props };
96
- }
97
- function renderCurrentTimeDisplay(props, state) {
98
- const { showRemaining,...restProps } = props;
99
- /** @TODO Should this live here or elsewhere? (CJP) */
100
- const timeLabel = showRemaining && state.duration != null && state.currentTime != null ? formatDisplayTime(-(state.duration - state.currentTime)) : formatDisplayTime(state.currentTime);
101
- return /* @__PURE__ */ jsx("span", {
102
- ...restProps,
103
- children: timeLabel
104
- });
105
- }
106
- const CurrentTimeDisplay = toConnectedComponent(useCurrentTimeDisplayState, useCurrentTimeDisplayProps, renderCurrentTimeDisplay, "CurrentTimeDisplay");
107
-
108
- //#endregion
109
- //#region src/components/DurationDisplay.tsx
110
- function useDurationDisplayState(_props) {
111
- return { duration: useMediaSelector(durationDisplayStateDefinition.stateTransform, shallowEqual).duration ?? 0 };
112
- }
113
- function useDurationDisplayProps(props) {
114
- return { ...props };
115
- }
116
- function renderDurationDisplay(props, state) {
117
- return /* @__PURE__ */ jsx("span", {
118
- ...props,
119
- children: formatDisplayTime(state.duration)
120
- });
121
- }
122
- const DurationDisplay = toConnectedComponent(useDurationDisplayState, useDurationDisplayProps, renderDurationDisplay, "DurationDisplay");
123
-
124
- //#endregion
125
- //#region src/components/FullscreenButton.tsx
126
- function useFullscreenButtonState(_props) {
127
- const mediaStore = useMediaStore();
128
- const mediaState = useMediaSelector(fullscreenButtonStateDefinition.stateTransform, shallowEqual);
129
- const methods = useMemo(() => fullscreenButtonStateDefinition.createRequestMethods(mediaStore.dispatch), [mediaStore]);
130
- return {
131
- fullscreen: mediaState.fullscreen,
132
- requestEnterFullscreen: methods.requestEnterFullscreen,
133
- requestExitFullscreen: methods.requestExitFullscreen
134
- };
135
- }
136
- function getFullscreenButtonProps(props, state) {
137
- const baseProps = {
138
- role: "button",
139
- "aria-label": state.fullscreen ? "exit fullscreen" : "enter fullscreen",
140
- "data-tooltip": state.fullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
141
- ...props
142
- };
143
- if (state.fullscreen) baseProps["data-fullscreen"] = "";
144
- return baseProps;
145
- }
146
- function renderFullscreenButton(props, state) {
147
- return /* @__PURE__ */ jsx("button", {
148
- type: "button",
149
- ...props,
150
- onClick: () => {
151
- if (props.disabled) return;
152
- if (state.fullscreen) state.requestExitFullscreen();
153
- else state.requestEnterFullscreen();
154
- },
155
- children: props.children
156
- });
157
- }
158
- const FullscreenButton = toConnectedComponent(useFullscreenButtonState, getFullscreenButtonProps, renderFullscreenButton, "FullscreenButton");
159
-
160
- //#endregion
161
- //#region src/utils/use-composed-refs.ts
162
- /**
163
- * Set a given ref to a given value
164
- * This utility takes care of different types of refs: callback refs and RefObject(s)
165
- */
166
- function setRef(ref, value) {
167
- if (typeof ref === "function") return ref(value);
168
- else if (ref !== null && ref !== void 0) ref.current = value;
169
- }
170
- /**
171
- * A utility to compose multiple refs together
172
- * Accepts callback refs and RefObject(s)
173
- */
174
- function composeRefs(...refs) {
175
- return (node) => {
176
- let hasCleanup = false;
177
- const cleanups = refs.map((ref) => {
178
- const cleanup = setRef(ref, node);
179
- if (!hasCleanup && typeof cleanup == "function") hasCleanup = true;
180
- return cleanup;
181
- });
182
- if (hasCleanup) return () => {
183
- for (let i = 0; i < cleanups.length; i++) {
184
- const cleanup = cleanups[i];
185
- if (typeof cleanup == "function") cleanup();
186
- else setRef(refs[i], null);
187
- }
188
- };
189
- };
190
- }
191
- /**
192
- * A custom hook that composes multiple refs
193
- * Accepts callback refs and RefObject(s)
194
- */
195
- function useComposedRefs(...refs) {
196
- return React$1.useCallback(composeRefs(...refs), refs);
197
- }
198
-
199
- //#endregion
200
- //#region src/components/MediaContainer.tsx
201
- /**
202
- * Hook to associate a React element as the fullscreen container for the media store.
203
- * This is equivalent to Media Chrome's useMediaFullscreenRef but for VJS-10.
204
- *
205
- * The ref callback will register the element as the container state owner
206
- * in the media store, enabling fullscreen functionality.
207
- *
208
- * @example
209
- * import { useMediaContainerRef } from '@videojs/react';
210
- *
211
- * const PlayerContainer = ({ children }) => {
212
- * const containerRef = useMediaContainerRef();
213
- * return <div ref={containerRef}>{children}</div>;
214
- * };
215
- */
216
- function useMediaContainerRef() {
217
- const mediaStore = useMediaStore();
218
- return useCallback((containerElement) => {
219
- if (!mediaStore) return;
220
- mediaStore.dispatch({
221
- type: "containerstateownerchangerequest",
222
- detail: containerElement
223
- });
224
- }, [mediaStore]);
225
- }
226
- /**
227
- * MediaContainer component that automatically registers itself as the fullscreen container.
228
- * This provides a simple wrapper component for fullscreen functionality.
229
- *
230
- * @example
231
- * import { MediaContainer } from '@videojs/react';
232
- *
233
- * const MyPlayer = () => (
234
- * <MediaContainer>
235
- * <video src="video.mp4" />
236
- * <div>Controls here</div>
237
- * </MediaContainer>
238
- * );
239
- */
240
- const MediaContainer = forwardRef(({ children,...props }, ref) => {
241
- const composedRef = useComposedRefs(ref, useMediaContainerRef());
242
- const mediaStore = useMediaStore();
243
- const mediaState = useMediaSelector(playButtonStateDefinition.stateTransform, shallowEqual);
244
- const methods = useMemo(() => playButtonStateDefinition.createRequestMethods(mediaStore.dispatch), [mediaStore]);
245
- return /* @__PURE__ */ jsx("div", {
246
- ref: composedRef,
247
- onClick: useCallback((event) => {
248
- if (!["video", "audio"].includes(event.target.localName || "")) return;
249
- if (mediaState.paused) methods.requestPlay();
250
- else methods.requestPause();
251
- }, [mediaState.paused, methods]),
252
- "data-media-container": true,
253
- ...props,
254
- children
255
- });
256
- });
257
-
258
- //#endregion
259
- //#region src/components/MuteButton.tsx
260
- function useMuteButtonState(_props) {
261
- const mediaStore = useMediaStore();
262
- const mediaState = useMediaSelector(muteButtonStateDefinition.stateTransform, shallowEqual);
263
- const methods = useMemo(() => muteButtonStateDefinition.createRequestMethods(mediaStore.dispatch), [mediaStore]);
264
- return {
265
- volumeLevel: mediaState.volumeLevel,
266
- muted: mediaState.muted,
267
- requestMute: methods.requestMute,
268
- requestUnmute: methods.requestUnmute
269
- };
270
- }
271
- function getMuteButtonProps(props, state) {
272
- const baseProps = {
273
- "data-volume-level": state.volumeLevel,
274
- role: "button",
275
- "aria-label": state.muted ? "unmute" : "mute",
276
- "data-tooltip": state.muted ? "Unmute" : "Mute",
277
- ...props
278
- };
279
- if (state.muted) baseProps["data-muted"] = "";
280
- return baseProps;
281
- }
282
- function renderMuteButton(props, state) {
283
- return /* @__PURE__ */ jsx("button", {
284
- type: "button",
285
- ...props,
286
- onClick: () => {
287
- if (props.disabled) return;
288
- if (state.volumeLevel === "off") state.requestUnmute();
289
- else state.requestMute();
290
- },
291
- children: props.children
292
- });
293
- }
294
- const MuteButton = toConnectedComponent(useMuteButtonState, getMuteButtonProps, renderMuteButton, "MuteButton");
295
- var MuteButton_default = MuteButton;
296
-
297
- //#endregion
298
- //#region src/components/PlayButton.tsx
299
- function usePlayButtonState(_props) {
300
- const mediaStore = useMediaStore();
301
- const mediaState = useMediaSelector(playButtonStateDefinition.stateTransform, shallowEqual);
302
- const methods = useMemo(() => playButtonStateDefinition.createRequestMethods(mediaStore.dispatch), [mediaStore]);
303
- return {
304
- paused: mediaState.paused,
305
- requestPlay: methods.requestPlay,
306
- requestPause: methods.requestPause
307
- };
308
- }
309
- function getPlayButtonProps(props, state) {
310
- const baseProps = {
311
- role: "button",
312
- "aria-label": state.paused ? "play" : "pause",
313
- "data-tooltip": state.paused ? "Play" : "Pause",
314
- ...props
315
- };
316
- if (state.paused) baseProps["data-paused"] = "";
317
- return baseProps;
318
- }
319
- function renderPlayButton(props, state) {
320
- return /* @__PURE__ */ jsx("button", {
321
- type: "button",
322
- ...props,
323
- onClick: () => {
324
- if (props.disabled) return;
325
- if (state.paused) state.requestPlay();
326
- else state.requestPause();
327
- },
328
- children: props.children
329
- });
330
- }
331
- const PlayButton = toConnectedComponent(usePlayButtonState, getPlayButtonProps, renderPlayButton, "PlayButton");
332
- var PlayButton_default = PlayButton;
333
-
334
- //#endregion
335
- //#region src/components/Popover.tsx
336
- const PopoverContext = createContext(null);
337
- function usePopoverContext() {
338
- const context = useContext(PopoverContext);
339
- if (!context) throw new Error("Popover components must be used within PopoverRoot");
340
- return context;
341
- }
342
- function PopoverRoot({ openOnHover = false, delay = 0, closeDelay = 0, children }) {
343
- const [open, setOpen] = useState(false);
344
- const [placement, setPlacement] = useState("top");
345
- const [sideOffset, setSideOffset] = useState(5);
346
- const [transitionStatus, setTransitionStatus] = useState("initial");
347
- const popupRef = useRef(null);
348
- const triggerRef = useRef(null);
349
- const hoverTimeoutRef = useRef(null);
350
- const pointerMoveHandlerRef = useRef(null);
351
- const clearHoverTimeout = useCallback(() => {
352
- if (hoverTimeoutRef.current) {
353
- clearTimeout(hoverTimeoutRef.current);
354
- hoverTimeoutRef.current = null;
355
- }
356
- }, []);
357
- const setOpenState = useCallback((newOpen) => {
358
- if (open === newOpen) return;
359
- setOpen(newOpen);
360
- if (newOpen) {
361
- setTransitionStatus("initial");
362
- if (popupRef.current) popupRef.current.showPopover();
363
- requestAnimationFrame(() => {
364
- setTransitionStatus("open");
365
- });
366
- } else setTransitionStatus("close");
367
- }, [open]);
368
- useEffect(() => {
369
- if (!popupRef.current || open) return;
370
- const transitions = popupRef.current.getAnimations().filter((anim) => anim instanceof CSSTransition);
371
- if (transitions.length > 0) Promise.all(transitions.map((t) => t.finished)).then(() => popupRef.current?.hidePopover()).catch(() => popupRef.current?.hidePopover());
372
- else popupRef.current.hidePopover();
373
- }, [open, transitionStatus]);
374
- const updatePositioning = useCallback((newPlacement, newSideOffset) => {
375
- setPlacement(newPlacement);
376
- setSideOffset(newSideOffset);
377
- }, []);
378
- useEffect(() => {
379
- const trigger = triggerRef.current;
380
- const popup = popupRef.current;
381
- if (!trigger || !popup) return;
382
- const abortController = new AbortController();
383
- const { signal } = abortController;
384
- const addPointerMoveListener = () => {
385
- if (!globalThis.matchMedia?.("(hover: hover)")?.matches) return;
386
- if (!pointerMoveHandlerRef.current) pointerMoveHandlerRef.current = safePolygon({ blockPointerEvents: true })({
387
- placement,
388
- elements: {
389
- domReference: trigger,
390
- floating: popup
391
- },
392
- x: 0,
393
- y: 0,
394
- onClose: () => {
395
- if (pointerMoveHandlerRef.current) document.documentElement.removeEventListener("pointermove", pointerMoveHandlerRef.current);
396
- clearHoverTimeout();
397
- hoverTimeoutRef.current = setTimeout(() => {
398
- setOpenState(false);
399
- }, closeDelay);
400
- }
401
- });
402
- document.documentElement.addEventListener("pointermove", pointerMoveHandlerRef.current, { signal });
403
- };
404
- const handlePointerEnter = (event) => {
405
- if (!openOnHover) return;
406
- clearHoverTimeout();
407
- if (event.currentTarget === popup) addPointerMoveListener();
408
- if (open) return;
409
- hoverTimeoutRef.current = setTimeout(() => {
410
- setOpenState(true);
411
- }, delay);
412
- };
413
- const handlePointerLeave = () => {
414
- if (!openOnHover) return;
415
- addPointerMoveListener();
416
- };
417
- if (globalThis.matchMedia?.("(hover: hover)")?.matches) {
418
- trigger.addEventListener("pointerenter", handlePointerEnter, { signal });
419
- trigger.addEventListener("pointerleave", handlePointerLeave, { signal });
420
- popup.addEventListener("pointerenter", handlePointerEnter, { signal });
421
- }
422
- const handleFocusIn = () => {
423
- setOpenState(true);
424
- };
425
- const handleFocusOut = (event) => {
426
- const relatedTarget = event.relatedTarget;
427
- if (relatedTarget && popup && contains(popup, relatedTarget)) return;
428
- setOpenState(false);
429
- };
430
- trigger.addEventListener("focusin", handleFocusIn, { signal });
431
- trigger.addEventListener("focusout", handleFocusOut, { signal });
432
- popup.addEventListener("focusout", handleFocusOut, { signal });
433
- return () => {
434
- abortController.abort();
435
- clearHoverTimeout();
436
- if (pointerMoveHandlerRef.current) document.documentElement.removeEventListener("pointermove", pointerMoveHandlerRef.current);
437
- pointerMoveHandlerRef.current = null;
438
- };
439
- }, [
440
- openOnHover,
441
- delay,
442
- closeDelay,
443
- open,
444
- placement,
445
- setOpenState,
446
- clearHoverTimeout
447
- ]);
448
- useEffect(() => {
449
- if (!popupRef.current || !triggerRef.current) return;
450
- const popup = popupRef.current;
451
- const popupId = popup.id;
452
- if (popupId) popup.style.setProperty("position-anchor", `--${popupId}`);
453
- const [side, alignment] = placement.split("-");
454
- popup.style.setProperty("top", `calc(anchor(${side}) - ${sideOffset}px)`);
455
- popup.style.setProperty("translate", `0 -100%`);
456
- popup.style.setProperty("justify-self", alignment === "start" ? "anchor-start" : alignment === "end" ? "anchor-end" : "anchor-center");
457
- }, [placement, sideOffset]);
458
- const value = useMemo(() => ({
459
- open,
460
- setOpen: setOpenState,
461
- popupRef,
462
- triggerRef,
463
- updatePositioning,
464
- transitionStatus,
465
- placement,
466
- sideOffset
467
- }), [
468
- open,
469
- setOpenState,
470
- updatePositioning,
471
- transitionStatus,
472
- placement,
473
- sideOffset
474
- ]);
475
- return /* @__PURE__ */ jsx(PopoverContext.Provider, {
476
- value,
477
- children
478
- });
479
- }
480
- function PopoverTrigger({ children }) {
481
- const { triggerRef, open } = usePopoverContext();
482
- return cloneElement(Children.only(children), {
483
- ref: triggerRef,
484
- "data-popup-open": open ? "" : void 0
485
- });
486
- }
487
- function PopoverPositioner({ side = "top", sideOffset = 5, children }) {
488
- const { updatePositioning } = usePopoverContext();
489
- useEffect(() => {
490
- updatePositioning(side, sideOffset);
491
- }, [
492
- side,
493
- sideOffset,
494
- updatePositioning
495
- ]);
496
- return /* @__PURE__ */ jsx(Fragment, { children });
497
- }
498
- function PopoverPopup({ id, className, children }) {
499
- const { popupRef, triggerRef, transitionStatus, placement } = usePopoverContext();
500
- const triggerElement = triggerRef.current;
501
- const uniqueId = useId();
502
- const popupId = id ?? uniqueId;
503
- useEffect(() => {
504
- if (!popupRef.current || !triggerRef.current) return;
505
- const popup = popupRef.current;
506
- const trigger = triggerRef.current;
507
- popup.setAttribute("popover", "manual");
508
- trigger.setAttribute("commandfor", popupId);
509
- trigger.style.setProperty("anchor-name", `--${popupId}`);
510
- }, [
511
- popupId,
512
- popupRef,
513
- triggerRef
514
- ]);
515
- return /* @__PURE__ */ jsx("div", {
516
- ref: popupRef,
517
- id: popupId,
518
- className,
519
- ...useMemo(() => {
520
- if (!triggerElement?.attributes) return {};
521
- return Object.fromEntries(Array.from(triggerElement.attributes).filter((attr) => attr.name.startsWith("data-")).map((attr) => [attr.name, attr.value]));
522
- }, [triggerElement]),
523
- "data-side": placement,
524
- "data-starting-style": transitionStatus === "initial" ? "" : void 0,
525
- "data-open": transitionStatus === "initial" || transitionStatus === "open" ? "" : void 0,
526
- "data-ending-style": transitionStatus === "close" || transitionStatus === "unmounted" ? "" : void 0,
527
- "data-closed": transitionStatus === "close" || transitionStatus === "unmounted" ? "" : void 0,
528
- children
529
- });
530
- }
531
- const Popover = {
532
- Root: PopoverRoot,
533
- Trigger: PopoverTrigger,
534
- Positioner: PopoverPositioner,
535
- Popup: PopoverPopup
536
- };
537
- var Popover_default = Popover;
538
-
539
- //#endregion
540
- //#region src/components/PreviewTimeDisplay.tsx
541
- function usePreviewTimeDisplayState(_props) {
542
- return { previewTime: useMediaSelector(previewTimeDisplayStateDefinition.stateTransform, shallowEqual).previewTime ?? 0 };
543
- }
544
- function getPreviewTimeDisplayProps(props, _state) {
545
- return { ...props };
546
- }
547
- function renderPreviewTimeDisplay(props, state) {
548
- const { showRemaining,...restProps } = props;
549
- /** @TODO Should this live here or elsewhere? (CJP) */
550
- const timeLabel = formatDisplayTime(state.previewTime);
551
- return /* @__PURE__ */ jsx("span", {
552
- ...restProps,
553
- children: timeLabel
554
- });
555
- }
556
- const PreviewTimeDisplay = toConnectedComponent(usePreviewTimeDisplayState, getPreviewTimeDisplayProps, renderPreviewTimeDisplay, "PreviewTimeDisplay");
557
- var PreviewTimeDisplay_default = PreviewTimeDisplay;
558
-
559
- //#endregion
560
- //#region src/components/TimeSlider.tsx
561
- function useTimeSliderRootState(props) {
562
- const { orientation = "horizontal" } = props;
563
- const mediaStore = useMediaStore();
564
- const mediaState = useMediaSelector(timeSliderStateDefinition.stateTransform, shallowEqual);
565
- const mediaMethods = useMemo(() => timeSliderStateDefinition.createRequestMethods(mediaStore.dispatch), [mediaStore]);
566
- const core = useCore(TimeSlider, {
567
- ...mediaState,
568
- ...mediaMethods
569
- });
570
- return {
571
- ...mediaState,
572
- ...mediaMethods,
573
- orientation,
574
- core
575
- };
576
- }
577
- function useTimeSliderRootProps(props, state) {
578
- const { _fillWidth, _pointerWidth, _currentTimeText, _durationText } = state.core.getState();
579
- const { children, className, id, style, orientation = "horizontal", ref } = props;
580
- return {
581
- ref: useComposedRefs(ref, useCallback((el) => {
582
- if (!el) return;
583
- state.core?.attach(el);
584
- }, [state.core])),
585
- id,
586
- role: "slider",
587
- tabIndex: 0,
588
- "aria-label": "Seek",
589
- "aria-valuemin": 0,
590
- "aria-valuemax": Math.round(state.duration),
591
- "aria-valuenow": Math.round(state.currentTime),
592
- "aria-valuetext": `${_currentTimeText} of ${_durationText}`,
593
- "aria-orientation": orientation,
594
- "data-orientation": orientation,
595
- "data-current-time": state.currentTime,
596
- "data-duration": state.duration,
597
- className,
598
- style: {
599
- ...style,
600
- "--slider-fill": `${_fillWidth.toFixed(3)}%`,
601
- "--slider-pointer": `${(_pointerWidth * 100).toFixed(3)}%`
602
- },
603
- children
604
- };
605
- }
606
- function renderTimeSliderRoot(props) {
607
- return /* @__PURE__ */ jsx("div", { ...props });
608
- }
609
- const TimeSliderRoot = toConnectedComponent(useTimeSliderRootState, useTimeSliderRootProps, renderTimeSliderRoot, "TimeSlider.Root");
610
- function useTimeSliderTrackProps(props, context) {
611
- return {
612
- ref: useCallback((el) => {
613
- context.core?.setState({ _trackElement: el });
614
- }, [context.core]),
615
- "data-orientation": context.orientation,
616
- ...props,
617
- style: {
618
- ...props.style,
619
- [context.orientation === "horizontal" ? "width" : "height"]: "100%"
620
- }
621
- };
622
- }
623
- function renderTimeSliderTrack(props) {
624
- return /* @__PURE__ */ jsx("div", { ...props });
625
- }
626
- const TimeSliderTrack = toContextComponent(useTimeSliderTrackProps, renderTimeSliderTrack, "TimeSlider.Track");
627
- function getTimeSliderThumbProps(props, context) {
628
- return {
629
- "data-orientation": context.orientation,
630
- ...props,
631
- style: {
632
- ...props.style,
633
- [context.orientation === "horizontal" ? "insetInlineStart" : "insetBlockEnd"]: "var(--slider-fill)",
634
- [context.orientation === "horizontal" ? "top" : "left"]: "50%",
635
- translate: context.orientation === "horizontal" ? "-50% -50%" : "-50% 50%",
636
- position: "absolute"
637
- }
638
- };
639
- }
640
- function renderTimeSliderThumb(props) {
641
- return /* @__PURE__ */ jsx("div", { ...props });
642
- }
643
- const TimeSliderThumb = toContextComponent(getTimeSliderThumbProps, renderTimeSliderThumb, "TimeSlider.Thumb");
644
- function getTimeSliderPointerProps(props, context) {
645
- return {
646
- "data-orientation": context.orientation,
647
- ...props,
648
- style: {
649
- ...props.style,
650
- [context.orientation === "horizontal" ? "width" : "height"]: "var(--slider-pointer, 0%)",
651
- [context.orientation === "horizontal" ? "height" : "width"]: "100%",
652
- position: "absolute"
653
- }
654
- };
655
- }
656
- function renderTimeSliderPointer(props) {
657
- return /* @__PURE__ */ jsx("div", { ...props });
658
- }
659
- const TimeSliderPointer = toContextComponent(getTimeSliderPointerProps, renderTimeSliderPointer, "TimeSlider.Pointer");
660
- function getTimeSliderProgressProps(props, context) {
661
- return {
662
- "data-orientation": context.orientation,
663
- ...props,
664
- style: {
665
- ...props.style,
666
- [context.orientation === "horizontal" ? "width" : "height"]: "var(--slider-fill, 0%)",
667
- [context.orientation === "horizontal" ? "height" : "width"]: "100%",
668
- [context.orientation === "horizontal" ? "top" : "bottom"]: "0",
669
- position: "absolute"
670
- }
671
- };
672
- }
673
- function renderTimeSliderProgress(props) {
674
- return /* @__PURE__ */ jsx("div", { ...props });
675
- }
676
- const TimeSliderProgress = toContextComponent(getTimeSliderProgressProps, renderTimeSliderProgress, "TimeSlider.Progress");
677
- const TimeSlider$1 = Object.assign({}, {
678
- Root: TimeSliderRoot,
679
- Track: TimeSliderTrack,
680
- Thumb: TimeSliderThumb,
681
- Pointer: TimeSliderPointer,
682
- Progress: TimeSliderProgress
683
- });
684
-
685
- //#endregion
686
- //#region src/components/Tooltip.tsx
687
- const TooltipContext = createContext(null);
688
- function useTooltipContext() {
689
- const context = useContext(TooltipContext);
690
- if (!context) throw new Error("Tooltip components must be used within TooltipRoot");
691
- return context;
692
- }
693
- function TooltipRoot({ delay = 0, closeDelay = 0, trackCursorAxis, children }) {
694
- const [open, setOpen] = useState(false);
695
- const [placement, setPlacement] = useState("top");
696
- const [sideOffset, setSideOffset] = useState(0);
697
- const [collisionPadding, setCollisionPadding] = useState(0);
698
- const [transitionStatus, setTransitionStatus] = useState("initial");
699
- const popupRef = useRef(null);
700
- const triggerRef = useRef(null);
701
- const hoverTimeoutRef = useRef(null);
702
- const pointerPositionRef = useRef({
703
- x: 0,
704
- y: 0
705
- });
706
- const updatePositioning = useCallback(({ side, sideOffset: sideOffset$1, collisionPadding: collisionPadding$1 }) => {
707
- setPlacement(side);
708
- setSideOffset(sideOffset$1);
709
- setCollisionPadding(collisionPadding$1);
710
- }, []);
711
- const clearHoverTimeout = useCallback(() => {
712
- if (hoverTimeoutRef.current) {
713
- clearTimeout(hoverTimeoutRef.current);
714
- hoverTimeoutRef.current = null;
715
- }
716
- }, []);
717
- const checkCollision = useCallback(() => {
718
- if (!popupRef.current || !triggerRef.current || !open) return;
719
- const mediaContainer = popupRef.current.closest("[data-media-container]");
720
- if (!mediaContainer) return;
721
- const { x } = getInBoundsAdjustments(getBoundingClientRectWithoutTransform(popupRef.current), getBoundingClientRectWithoutTransform(mediaContainer), collisionPadding);
722
- if (x !== 0) if (trackCursorAxis) {
723
- const currentLeft = Number.parseFloat(popupRef.current.style.left || "0");
724
- popupRef.current.style.setProperty("left", `${currentLeft + x}px`);
725
- } else popupRef.current.style.setProperty("translate", `${x}px -100%`);
726
- else if (trackCursorAxis) popupRef.current.style.setProperty("translate", "-50% -100%");
727
- else popupRef.current.style.setProperty("translate", "0 -100%");
728
- }, [
729
- open,
730
- collisionPadding,
731
- trackCursorAxis
732
- ]);
733
- const updatePosition = useCallback(() => {
734
- if (open && trackCursorAxis && popupRef.current) {
735
- popupRef.current.style.setProperty("left", `${pointerPositionRef.current.x}px`);
736
- checkCollision();
737
- }
738
- }, [
739
- open,
740
- trackCursorAxis,
741
- checkCollision
742
- ]);
743
- const setOpenState = useCallback((newOpen) => {
744
- if (open === newOpen) return;
745
- setOpen(newOpen);
746
- if (newOpen) {
747
- setTransitionStatus("initial");
748
- if (popupRef.current) popupRef.current.showPopover();
749
- requestAnimationFrame(() => {
750
- setTransitionStatus("open");
751
- checkCollision();
752
- });
753
- } else setTransitionStatus("close");
754
- }, [open, checkCollision]);
755
- useEffect(() => {
756
- if (!popupRef.current || open) return;
757
- const transitions = popupRef.current.getAnimations().filter((anim) => anim instanceof CSSTransition);
758
- if (transitions.length > 0) Promise.all(transitions.map((t) => t.finished)).then(() => popupRef.current?.hidePopover()).catch(() => popupRef.current?.hidePopover());
759
- else popupRef.current.hidePopover();
760
- }, [open, transitionStatus]);
761
- useEffect(() => {
762
- const trigger = triggerRef.current;
763
- const popup = popupRef.current;
764
- if (!trigger || !popup) return;
765
- const abortController = new AbortController();
766
- const { signal } = abortController;
767
- const handlePointerEnter = () => {
768
- clearHoverTimeout();
769
- hoverTimeoutRef.current = setTimeout(() => {
770
- setOpenState(true);
771
- }, delay);
772
- };
773
- const handlePointerLeave = () => {
774
- clearHoverTimeout();
775
- hoverTimeoutRef.current = setTimeout(() => {
776
- setOpenState(false);
777
- }, closeDelay);
778
- };
779
- const handlePointerMove = (event) => {
780
- if (trackCursorAxis) {
781
- pointerPositionRef.current = {
782
- x: event.clientX,
783
- y: event.clientY
784
- };
785
- if (open) updatePosition();
786
- }
787
- };
788
- const handleFocusIn = () => {
789
- setOpenState(true);
790
- };
791
- const handleFocusOut = (event) => {
792
- const relatedTarget = event.relatedTarget;
793
- if (relatedTarget && popup && contains(popup, relatedTarget)) return;
794
- setOpenState(false);
795
- };
796
- if (globalThis.matchMedia?.("(hover: hover)")?.matches) {
797
- trigger.addEventListener("pointerenter", handlePointerEnter, { signal });
798
- trigger.addEventListener("pointerleave", handlePointerLeave, { signal });
799
- if (trackCursorAxis) trigger.addEventListener("pointermove", handlePointerMove, { signal });
800
- }
801
- trigger.addEventListener("focusin", handleFocusIn, { signal });
802
- trigger.addEventListener("focusout", handleFocusOut, { signal });
803
- return () => {
804
- abortController.abort();
805
- clearHoverTimeout();
806
- };
807
- }, [
808
- delay,
809
- closeDelay,
810
- trackCursorAxis,
811
- open,
812
- setOpenState,
813
- clearHoverTimeout,
814
- updatePosition
815
- ]);
816
- useEffect(() => {
817
- if (!popupRef.current || !triggerRef.current) return;
818
- const popup = popupRef.current;
819
- const popupId = popup.id;
820
- if (popupId) popup.style.setProperty("position-anchor", `--${popupId}`);
821
- const [side, alignment] = placement.split("-");
822
- popup.style.setProperty("top", `calc(anchor(${side}) - ${sideOffset}px)`);
823
- if (trackCursorAxis) popup.style.setProperty("translate", `-50% -100%`);
824
- else {
825
- popup.style.setProperty("translate", `0 -100%`);
826
- popup.style.setProperty("justify-self", alignment === "start" ? "anchor-start" : alignment === "end" ? "anchor-end" : "anchor-center");
827
- }
828
- }, [
829
- placement,
830
- sideOffset,
831
- trackCursorAxis
832
- ]);
833
- useEffect(() => {
834
- if (!popupRef.current) return;
835
- const resizeObserver = new ResizeObserver(checkCollision);
836
- resizeObserver.observe(popupRef.current);
837
- return () => {
838
- resizeObserver.disconnect();
839
- };
840
- }, [checkCollision]);
841
- const value = useMemo(() => ({
842
- popupRef,
843
- triggerRef,
844
- open,
845
- transitionStatus,
846
- updatePositioning,
847
- trackCursorAxis,
848
- placement,
849
- sideOffset,
850
- collisionPadding
851
- }), [
852
- open,
853
- transitionStatus,
854
- updatePositioning,
855
- trackCursorAxis,
856
- placement,
857
- sideOffset,
858
- collisionPadding
859
- ]);
860
- return /* @__PURE__ */ jsx(TooltipContext.Provider, {
861
- value,
862
- children
863
- });
864
- }
865
- function TooltipTrigger({ children }) {
866
- const { triggerRef, open } = useTooltipContext();
867
- return cloneElement(Children.only(children), {
868
- ref: triggerRef,
869
- "data-popup-open": open ? "" : void 0
870
- });
871
- }
872
- function TooltipPositioner({ side = "top", sideOffset = 0, collisionPadding = 0, children }) {
873
- const { updatePositioning } = useTooltipContext();
874
- useEffect(() => {
875
- updatePositioning({
876
- side,
877
- sideOffset,
878
- collisionPadding
879
- });
880
- }, [
881
- side,
882
- sideOffset,
883
- collisionPadding,
884
- updatePositioning
885
- ]);
886
- return /* @__PURE__ */ jsx(Fragment, { children });
887
- }
888
- function TooltipPopup({ id, className = "", children }) {
889
- const { popupRef, triggerRef, transitionStatus, placement } = useTooltipContext();
890
- const triggerElement = triggerRef.current;
891
- const uniqueId = useId();
892
- const popupId = id ?? uniqueId;
893
- useEffect(() => {
894
- if (!popupRef.current || !triggerRef.current) return;
895
- const popup = popupRef.current;
896
- const trigger = triggerRef.current;
897
- popup.setAttribute("popover", "manual");
898
- trigger.setAttribute("commandfor", popupId);
899
- trigger.style.setProperty("anchor-name", `--${popupId}`);
900
- }, [
901
- popupId,
902
- popupRef,
903
- triggerRef
904
- ]);
905
- return /* @__PURE__ */ jsx("div", {
906
- ref: popupRef,
907
- id: popupId,
908
- className,
909
- role: "tooltip",
910
- ...useMemo(() => {
911
- if (!triggerElement?.attributes) return {};
912
- return Object.fromEntries(Array.from(triggerElement.attributes).filter((attr) => attr.name.startsWith("data-")).map((attr) => [attr.name, attr.value]));
913
- }, [triggerElement]),
914
- "data-side": placement,
915
- "data-starting-style": transitionStatus === "initial" ? "" : void 0,
916
- "data-open": transitionStatus === "initial" || transitionStatus === "open" ? "" : void 0,
917
- "data-ending-style": transitionStatus === "close" || transitionStatus === "unmounted" ? "" : void 0,
918
- "data-closed": transitionStatus === "close" || transitionStatus === "unmounted" ? "" : void 0,
919
- children
920
- });
921
- }
922
- const Tooltip = {
923
- Root: TooltipRoot,
924
- Trigger: TooltipTrigger,
925
- Positioner: TooltipPositioner,
926
- Popup: TooltipPopup
927
- };
928
- var Tooltip_default = Tooltip;
929
-
930
- //#endregion
931
- //#region src/components/VolumeSlider.tsx
932
- function useVolumeSliderRootState(props) {
933
- const { orientation = "horizontal" } = props;
934
- const mediaStore = useMediaStore();
935
- const mediaState = useMediaSelector(volumeSliderStateDefinition.stateTransform, shallowEqual);
936
- const mediaMethods = useMemo(() => volumeSliderStateDefinition.createRequestMethods(mediaStore.dispatch), [mediaStore]);
937
- const core = useCore(VolumeSlider, {
938
- ...mediaState,
939
- ...mediaMethods
940
- });
941
- return {
942
- ...mediaState,
943
- ...mediaMethods,
944
- orientation,
945
- core
946
- };
947
- }
948
- function useVolumeSliderRootProps(props, state) {
949
- const { _fillWidth, _pointerWidth, _volumeText } = state.core.getState();
950
- const { children, className, id, style, orientation = "horizontal" } = props;
951
- return {
952
- ref: useCallback((el) => {
953
- if (!el) return;
954
- state.core?.attach(el);
955
- }, []),
956
- id,
957
- role: "slider",
958
- tabIndex: 0,
959
- "aria-label": "Volume",
960
- "aria-valuemin": 0,
961
- "aria-valuemax": 100,
962
- "aria-valuenow": Math.round(state.volume * 100),
963
- "aria-valuetext": _volumeText,
964
- "aria-orientation": orientation,
965
- "data-orientation": orientation,
966
- "data-muted": state.muted,
967
- "data-volume-level": state.volumeLevel,
968
- className,
969
- style: {
970
- ...style,
971
- "--slider-fill": `${_fillWidth.toFixed(3)}%`,
972
- "--slider-pointer": `${_pointerWidth.toFixed(3)}%`
973
- },
974
- children
975
- };
976
- }
977
- function renderVolumeSliderRoot(props) {
978
- return /* @__PURE__ */ jsx("div", { ...props });
979
- }
980
- const VolumeSliderRoot = toConnectedComponent(useVolumeSliderRootState, useVolumeSliderRootProps, renderVolumeSliderRoot, "VolumeSlider.Root");
981
- function useVolumeSliderTrackProps(props, context) {
982
- return {
983
- ref: useCallback((el) => {
984
- context.core?.setState({ _trackElement: el });
985
- }, []),
986
- "data-orientation": context.orientation,
987
- ...props,
988
- style: {
989
- ...props.style,
990
- [context.orientation === "horizontal" ? "width" : "height"]: "100%"
991
- }
992
- };
993
- }
994
- function renderVolumeSliderTrack(props) {
995
- return /* @__PURE__ */ jsx("div", { ...props });
996
- }
997
- const VolumeSliderTrack = toContextComponent(useVolumeSliderTrackProps, renderVolumeSliderTrack, "VolumeSlider.Track");
998
- function getVolumeSliderThumbProps(props, context) {
999
- return {
1000
- "data-orientation": context.orientation,
1001
- ...props,
1002
- style: {
1003
- ...props.style,
1004
- [context.orientation === "horizontal" ? "insetInlineStart" : "insetBlockEnd"]: "var(--slider-fill)",
1005
- [context.orientation === "horizontal" ? "top" : "left"]: "50%",
1006
- translate: context.orientation === "horizontal" ? "-50% -50%" : "-50% 50%",
1007
- position: "absolute"
1008
- }
1009
- };
1010
- }
1011
- function renderVolumeSliderThumb(props) {
1012
- return /* @__PURE__ */ jsx("div", { ...props });
1013
- }
1014
- const VolumeSliderThumb = toContextComponent(getVolumeSliderThumbProps, renderVolumeSliderThumb, "VolumeSlider.Thumb");
1015
- function getVolumeSliderProgressProps(props, context) {
1016
- return {
1017
- "data-orientation": context.orientation,
1018
- ...props,
1019
- style: {
1020
- ...props.style,
1021
- [context.orientation === "horizontal" ? "width" : "height"]: "var(--slider-fill, 0%)",
1022
- [context.orientation === "horizontal" ? "height" : "width"]: "100%",
1023
- [context.orientation === "horizontal" ? "top" : "bottom"]: "0",
1024
- position: "absolute"
1025
- }
1026
- };
1027
- }
1028
- function renderVolumeSliderProgress(props) {
1029
- return /* @__PURE__ */ jsx("div", { ...props });
1030
- }
1031
- const VolumeSliderProgress = toContextComponent(getVolumeSliderProgressProps, renderVolumeSliderProgress, "VolumeSlider.Progress");
1032
- const VolumeSlider$1 = Object.assign({}, {
1033
- Root: VolumeSliderRoot,
1034
- Track: VolumeSliderTrack,
1035
- Thumb: VolumeSliderThumb,
1036
- Progress: VolumeSliderProgress
1037
- });
1038
- var VolumeSlider_default = VolumeSlider$1;
1039
-
1040
- //#endregion
1041
- export { DurationDisplay as _, TimeSlider$1 as a, Popover as c, PlayButton_default as d, MuteButton as f, FullscreenButton as g, useMediaContainerRef as h, Tooltip_default as i, Popover_default as l, MediaContainer as m, VolumeSlider_default as n, PreviewTimeDisplay as o, MuteButton_default as p, Tooltip as r, PreviewTimeDisplay_default as s, VolumeSlider$1 as t, PlayButton as u, CurrentTimeDisplay as v };
1042
- //# sourceMappingURL=VolumeSlider-DmlupkvF.js.map