@videojs/react 10.0.0-beta.28 → 10.0.0-beta.29

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 (259) hide show
  1. package/dist/default/__generated__/skins/default-video/styles/buttons.css +132 -18
  2. package/dist/default/__generated__/skins/default-video/styles/captions.css +22 -0
  3. package/dist/default/__generated__/skins/default-video/styles/container.css +121 -8
  4. package/dist/default/__generated__/skins/default-video/styles/controls.css +436 -21
  5. package/dist/default/__generated__/skins/default-video/styles/dialog.css +169 -0
  6. package/dist/default/__generated__/skins/default-video/styles/indicator.css +459 -0
  7. package/dist/default/__generated__/skins/default-video/styles/menus.css +254 -0
  8. package/dist/default/__generated__/skins/default-video/styles/overlays.css +26 -2
  9. package/dist/default/__generated__/skins/default-video/styles/popups.css +338 -12
  10. package/dist/default/__generated__/skins/default-video/styles/poster.css +4 -4
  11. package/dist/default/__generated__/skins/default-video/styles/sliders.css +355 -31
  12. package/dist/default/__generated__/skins/default-video/styles/styles.css +2455 -216
  13. package/dist/default/__generated__/skins/default-video/styles/theme.css +4 -19
  14. package/dist/default/__generated__/skins/default-video/styles/video.css +29 -0
  15. package/dist/default/__generated__/skins/minimal-video/styles/base.css +25 -0
  16. package/dist/default/__generated__/skins/minimal-video/styles/buttons.css +266 -0
  17. package/dist/default/__generated__/skins/minimal-video/styles/captions.css +22 -0
  18. package/dist/default/__generated__/skins/minimal-video/styles/container.css +158 -0
  19. package/dist/default/__generated__/skins/minimal-video/styles/controls.css +182 -0
  20. package/dist/default/__generated__/skins/minimal-video/styles/dialog.css +77 -0
  21. package/dist/default/__generated__/skins/minimal-video/styles/indicator.css +322 -0
  22. package/dist/default/__generated__/skins/minimal-video/styles/menus.css +254 -0
  23. package/dist/default/__generated__/skins/minimal-video/styles/overlays.css +35 -0
  24. package/dist/default/__generated__/skins/minimal-video/styles/popups.css +371 -0
  25. package/dist/default/__generated__/skins/minimal-video/styles/poster.css +47 -0
  26. package/dist/default/__generated__/skins/minimal-video/styles/sliders.css +436 -0
  27. package/dist/default/__generated__/skins/minimal-video/styles/styles.css +2246 -0
  28. package/dist/default/__generated__/skins/minimal-video/styles/theme.css +7 -0
  29. package/dist/default/__generated__/skins/minimal-video/styles/video.css +29 -0
  30. package/dist/default/i18n/index.js +2 -1
  31. package/dist/default/i18n/text.js +20 -0
  32. package/dist/default/i18n/text.js.map +1 -0
  33. package/dist/default/icons/dist/react/default/airplay-exit.js +3 -3
  34. package/dist/default/icons/dist/react/default/airplay-exit.js.map +1 -1
  35. package/dist/default/icons/dist/react/minimal/airplay-exit.js +3 -3
  36. package/dist/default/icons/dist/react/minimal/airplay-exit.js.map +1 -1
  37. package/dist/default/index.js +2 -1
  38. package/dist/default/media/hls-background-video/media.js +18 -3
  39. package/dist/default/media/hls-background-video/media.js.map +1 -1
  40. package/dist/default/presets/audio/minimal-skin.css +103 -101
  41. package/dist/default/presets/audio/minimal-skin.js +1 -1
  42. package/dist/default/presets/audio/minimal-skin.tailwind.js +1 -1
  43. package/dist/default/presets/audio/skin.css +68 -69
  44. package/dist/default/presets/audio/skin.js +1 -1
  45. package/dist/default/presets/audio/skin.tailwind.js +1 -1
  46. package/dist/default/presets/live-audio/minimal-skin.css +103 -101
  47. package/dist/default/presets/live-audio/skin.css +68 -69
  48. package/dist/default/presets/live-video/minimal-skin.css +140 -120
  49. package/dist/default/presets/live-video/minimal-skin.js +3 -8
  50. package/dist/default/presets/live-video/minimal-skin.js.map +1 -1
  51. package/dist/default/presets/live-video/minimal-skin.tailwind.js +5 -8
  52. package/dist/default/presets/live-video/minimal-skin.tailwind.js.map +1 -1
  53. package/dist/default/presets/live-video/skin.css +89 -76
  54. package/dist/default/presets/live-video/skin.js +3 -8
  55. package/dist/default/presets/live-video/skin.js.map +1 -1
  56. package/dist/default/presets/live-video/skin.tailwind.js +7 -10
  57. package/dist/default/presets/live-video/skin.tailwind.js.map +1 -1
  58. package/dist/default/presets/video/minimal-skin.css +140 -120
  59. package/dist/default/presets/video/minimal-skin.js +3 -8
  60. package/dist/default/presets/video/minimal-skin.js.map +1 -1
  61. package/dist/default/presets/video/minimal-skin.tailwind.js +5 -8
  62. package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
  63. package/dist/default/presets/video/skin.css +89 -76
  64. package/dist/default/presets/video/skin.js +3 -8
  65. package/dist/default/presets/video/skin.js.map +1 -1
  66. package/dist/default/presets/video/skin.tailwind.js +6 -9
  67. package/dist/default/presets/video/skin.tailwind.js.map +1 -1
  68. package/dist/default/skins/dist/default/default/tailwind/components/button.js +3 -1
  69. package/dist/default/skins/dist/default/default/tailwind/components/button.js.map +1 -1
  70. package/dist/default/skins/dist/default/default/tailwind/components/poster.js +8 -1
  71. package/dist/default/skins/dist/default/default/tailwind/components/poster.js.map +1 -1
  72. package/dist/default/skins/dist/default/default/tailwind/components/slider.js +10 -10
  73. package/dist/default/skins/dist/default/default/tailwind/components/slider.js.map +1 -1
  74. package/dist/default/skins/dist/default/default/tailwind/components/thumbnail.js +1 -1
  75. package/dist/default/skins/dist/default/default/tailwind/components/thumbnail.js.map +1 -1
  76. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js +2 -2
  77. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  78. package/dist/default/skins/dist/default/minimal/tailwind/components/poster.js +8 -1
  79. package/dist/default/skins/dist/default/minimal/tailwind/components/poster.js.map +1 -1
  80. package/dist/default/skins/dist/default/minimal/tailwind/components/slider.js +13 -12
  81. package/dist/default/skins/dist/default/minimal/tailwind/components/slider.js.map +1 -1
  82. package/dist/default/skins/dist/default/minimal/tailwind/components/thumbnail.js +1 -1
  83. package/dist/default/skins/dist/default/minimal/tailwind/components/thumbnail.js.map +1 -1
  84. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js +6 -5
  85. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  86. package/dist/default/skins/dist/default/shared/tailwind/icon-state.js +4 -4
  87. package/dist/default/skins/dist/default/shared/tailwind/icon-state.js.map +1 -1
  88. package/dist/default/ui/gesture/gesture.js.map +1 -1
  89. package/dist/default/ui/gesture/use-doubletap-gesture.js.map +1 -1
  90. package/dist/default/ui/gesture/use-tap-gesture.js.map +1 -1
  91. package/dist/default/ui/hotkey/hotkey.js.map +1 -1
  92. package/dist/default/ui/menu/context.js +6 -1
  93. package/dist/default/ui/menu/context.js.map +1 -1
  94. package/dist/default/ui/menu/menu-item-indicator.js +3 -2
  95. package/dist/default/ui/menu/menu-item-indicator.js.map +1 -1
  96. package/dist/default/ui/menu/menu-radio-item.js +19 -15
  97. package/dist/default/ui/menu/menu-radio-item.js.map +1 -1
  98. package/dist/default/ui/menu/menu-root.js +5 -6
  99. package/dist/default/ui/menu/menu-root.js.map +1 -1
  100. package/dist/default/ui/poster/poster.js +64 -17
  101. package/dist/default/ui/poster/poster.js.map +1 -1
  102. package/dist/default/ui/slider/slider-preview.js.map +1 -1
  103. package/dist/default/utils/use-render.js +2 -8
  104. package/dist/default/utils/use-render.js.map +1 -1
  105. package/dist/dev/__generated__/skins/default-video/styles/buttons.css +132 -18
  106. package/dist/dev/__generated__/skins/default-video/styles/captions.css +22 -0
  107. package/dist/dev/__generated__/skins/default-video/styles/container.css +121 -8
  108. package/dist/dev/__generated__/skins/default-video/styles/controls.css +436 -21
  109. package/dist/dev/__generated__/skins/default-video/styles/dialog.css +169 -0
  110. package/dist/dev/__generated__/skins/default-video/styles/indicator.css +459 -0
  111. package/dist/dev/__generated__/skins/default-video/styles/menus.css +254 -0
  112. package/dist/dev/__generated__/skins/default-video/styles/overlays.css +26 -2
  113. package/dist/dev/__generated__/skins/default-video/styles/popups.css +338 -12
  114. package/dist/dev/__generated__/skins/default-video/styles/poster.css +4 -4
  115. package/dist/dev/__generated__/skins/default-video/styles/sliders.css +355 -31
  116. package/dist/dev/__generated__/skins/default-video/styles/styles.css +2455 -216
  117. package/dist/dev/__generated__/skins/default-video/styles/theme.css +4 -19
  118. package/dist/dev/__generated__/skins/default-video/styles/video.css +29 -0
  119. package/dist/dev/__generated__/skins/minimal-video/styles/base.css +25 -0
  120. package/dist/dev/__generated__/skins/minimal-video/styles/buttons.css +266 -0
  121. package/dist/dev/__generated__/skins/minimal-video/styles/captions.css +22 -0
  122. package/dist/dev/__generated__/skins/minimal-video/styles/container.css +158 -0
  123. package/dist/dev/__generated__/skins/minimal-video/styles/controls.css +182 -0
  124. package/dist/dev/__generated__/skins/minimal-video/styles/dialog.css +77 -0
  125. package/dist/dev/__generated__/skins/minimal-video/styles/indicator.css +322 -0
  126. package/dist/dev/__generated__/skins/minimal-video/styles/menus.css +254 -0
  127. package/dist/dev/__generated__/skins/minimal-video/styles/overlays.css +35 -0
  128. package/dist/dev/__generated__/skins/minimal-video/styles/popups.css +371 -0
  129. package/dist/dev/__generated__/skins/minimal-video/styles/poster.css +47 -0
  130. package/dist/dev/__generated__/skins/minimal-video/styles/sliders.css +436 -0
  131. package/dist/dev/__generated__/skins/minimal-video/styles/styles.css +2246 -0
  132. package/dist/dev/__generated__/skins/minimal-video/styles/theme.css +7 -0
  133. package/dist/dev/__generated__/skins/minimal-video/styles/video.css +29 -0
  134. package/dist/dev/i18n/index.d.ts +2 -1
  135. package/dist/dev/i18n/index.js +2 -1
  136. package/dist/dev/i18n/text.d.ts +11 -0
  137. package/dist/dev/i18n/text.d.ts.map +1 -0
  138. package/dist/dev/i18n/text.js +20 -0
  139. package/dist/dev/i18n/text.js.map +1 -0
  140. package/dist/dev/icons/dist/react/default/airplay-exit.js +3 -3
  141. package/dist/dev/icons/dist/react/default/airplay-exit.js.map +1 -1
  142. package/dist/dev/icons/dist/react/minimal/airplay-exit.js +3 -3
  143. package/dist/dev/icons/dist/react/minimal/airplay-exit.js.map +1 -1
  144. package/dist/dev/icons/index.d.ts +6 -1
  145. package/dist/dev/icons/index.d.ts.map +1 -0
  146. package/dist/dev/icons/minimal/index.d.ts +6 -1
  147. package/dist/dev/icons/minimal/index.d.ts.map +1 -0
  148. package/dist/dev/index.d.ts +3 -2
  149. package/dist/dev/index.js +2 -1
  150. package/dist/dev/media/hls-background-video/media.d.ts +8 -0
  151. package/dist/dev/media/hls-background-video/media.d.ts.map +1 -1
  152. package/dist/dev/media/hls-background-video/media.js +18 -3
  153. package/dist/dev/media/hls-background-video/media.js.map +1 -1
  154. package/dist/dev/presets/audio/minimal-skin.css +103 -101
  155. package/dist/dev/presets/audio/minimal-skin.js +1 -1
  156. package/dist/dev/presets/audio/minimal-skin.tailwind.js +1 -1
  157. package/dist/dev/presets/audio/player.d.ts +2 -2
  158. package/dist/dev/presets/audio/skin.css +68 -69
  159. package/dist/dev/presets/audio/skin.js +1 -1
  160. package/dist/dev/presets/audio/skin.tailwind.js +1 -1
  161. package/dist/dev/presets/live-audio/minimal-skin.css +103 -101
  162. package/dist/dev/presets/live-audio/player.d.ts +2 -2
  163. package/dist/dev/presets/live-audio/skin.css +68 -69
  164. package/dist/dev/presets/live-video/minimal-skin.css +140 -120
  165. package/dist/dev/presets/live-video/minimal-skin.d.ts.map +1 -1
  166. package/dist/dev/presets/live-video/minimal-skin.js +3 -8
  167. package/dist/dev/presets/live-video/minimal-skin.js.map +1 -1
  168. package/dist/dev/presets/live-video/minimal-skin.tailwind.d.ts.map +1 -1
  169. package/dist/dev/presets/live-video/minimal-skin.tailwind.js +5 -8
  170. package/dist/dev/presets/live-video/minimal-skin.tailwind.js.map +1 -1
  171. package/dist/dev/presets/live-video/player.d.ts +2 -2
  172. package/dist/dev/presets/live-video/skin.css +89 -76
  173. package/dist/dev/presets/live-video/skin.d.ts.map +1 -1
  174. package/dist/dev/presets/live-video/skin.js +3 -8
  175. package/dist/dev/presets/live-video/skin.js.map +1 -1
  176. package/dist/dev/presets/live-video/skin.tailwind.d.ts.map +1 -1
  177. package/dist/dev/presets/live-video/skin.tailwind.js +7 -10
  178. package/dist/dev/presets/live-video/skin.tailwind.js.map +1 -1
  179. package/dist/dev/presets/types.d.ts +15 -2
  180. package/dist/dev/presets/types.d.ts.map +1 -1
  181. package/dist/dev/presets/video/minimal-skin.css +140 -120
  182. package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
  183. package/dist/dev/presets/video/minimal-skin.js +3 -8
  184. package/dist/dev/presets/video/minimal-skin.js.map +1 -1
  185. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
  186. package/dist/dev/presets/video/minimal-skin.tailwind.js +5 -8
  187. package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
  188. package/dist/dev/presets/video/player.d.ts +2 -2
  189. package/dist/dev/presets/video/skin.css +89 -76
  190. package/dist/dev/presets/video/skin.d.ts.map +1 -1
  191. package/dist/dev/presets/video/skin.js +3 -8
  192. package/dist/dev/presets/video/skin.js.map +1 -1
  193. package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
  194. package/dist/dev/presets/video/skin.tailwind.js +6 -9
  195. package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
  196. package/dist/dev/skins/dist/default/default/tailwind/components/button.js +3 -1
  197. package/dist/dev/skins/dist/default/default/tailwind/components/button.js.map +1 -1
  198. package/dist/dev/skins/dist/default/default/tailwind/components/poster.js +8 -1
  199. package/dist/dev/skins/dist/default/default/tailwind/components/poster.js.map +1 -1
  200. package/dist/dev/skins/dist/default/default/tailwind/components/slider.js +10 -10
  201. package/dist/dev/skins/dist/default/default/tailwind/components/slider.js.map +1 -1
  202. package/dist/dev/skins/dist/default/default/tailwind/components/thumbnail.js +1 -1
  203. package/dist/dev/skins/dist/default/default/tailwind/components/thumbnail.js.map +1 -1
  204. package/dist/dev/skins/dist/default/default/tailwind/video.tailwind.js +2 -2
  205. package/dist/dev/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  206. package/dist/dev/skins/dist/default/minimal/tailwind/components/poster.js +8 -1
  207. package/dist/dev/skins/dist/default/minimal/tailwind/components/poster.js.map +1 -1
  208. package/dist/dev/skins/dist/default/minimal/tailwind/components/slider.js +13 -12
  209. package/dist/dev/skins/dist/default/minimal/tailwind/components/slider.js.map +1 -1
  210. package/dist/dev/skins/dist/default/minimal/tailwind/components/thumbnail.js +1 -1
  211. package/dist/dev/skins/dist/default/minimal/tailwind/components/thumbnail.js.map +1 -1
  212. package/dist/dev/skins/dist/default/minimal/tailwind/video.tailwind.js +6 -5
  213. package/dist/dev/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  214. package/dist/dev/skins/dist/default/shared/tailwind/icon-state.js +4 -4
  215. package/dist/dev/skins/dist/default/shared/tailwind/icon-state.js.map +1 -1
  216. package/dist/dev/ui/gesture/gesture.d.ts +6 -13
  217. package/dist/dev/ui/gesture/gesture.d.ts.map +1 -1
  218. package/dist/dev/ui/gesture/gesture.js.map +1 -1
  219. package/dist/dev/ui/gesture/use-doubletap-gesture.d.ts +2 -5
  220. package/dist/dev/ui/gesture/use-doubletap-gesture.d.ts.map +1 -1
  221. package/dist/dev/ui/gesture/use-doubletap-gesture.js.map +1 -1
  222. package/dist/dev/ui/gesture/use-tap-gesture.d.ts +2 -5
  223. package/dist/dev/ui/gesture/use-tap-gesture.d.ts.map +1 -1
  224. package/dist/dev/ui/gesture/use-tap-gesture.js.map +1 -1
  225. package/dist/dev/ui/hotkey/hotkey.d.ts +6 -12
  226. package/dist/dev/ui/hotkey/hotkey.d.ts.map +1 -1
  227. package/dist/dev/ui/hotkey/hotkey.js.map +1 -1
  228. package/dist/dev/ui/menu/context.js +6 -1
  229. package/dist/dev/ui/menu/context.js.map +1 -1
  230. package/dist/dev/ui/menu/menu-item-indicator.d.ts.map +1 -1
  231. package/dist/dev/ui/menu/menu-item-indicator.js +3 -2
  232. package/dist/dev/ui/menu/menu-item-indicator.js.map +1 -1
  233. package/dist/dev/ui/menu/menu-radio-item.d.ts.map +1 -1
  234. package/dist/dev/ui/menu/menu-radio-item.js +19 -15
  235. package/dist/dev/ui/menu/menu-radio-item.js.map +1 -1
  236. package/dist/dev/ui/menu/menu-root.js +5 -6
  237. package/dist/dev/ui/menu/menu-root.js.map +1 -1
  238. package/dist/dev/ui/poster/poster.d.ts +15 -4
  239. package/dist/dev/ui/poster/poster.d.ts.map +1 -1
  240. package/dist/dev/ui/poster/poster.js +64 -17
  241. package/dist/dev/ui/poster/poster.js.map +1 -1
  242. package/dist/dev/ui/slider/slider-preview.d.ts +5 -9
  243. package/dist/dev/ui/slider/slider-preview.d.ts.map +1 -1
  244. package/dist/dev/ui/slider/slider-preview.js.map +1 -1
  245. package/dist/dev/utils/use-render.d.ts.map +1 -1
  246. package/dist/dev/utils/use-render.js +2 -8
  247. package/dist/dev/utils/use-render.js.map +1 -1
  248. package/docs/README.md +1 -1
  249. package/docs/concepts/skins.md +97 -96
  250. package/docs/how-to/customize-skins.md +421 -411
  251. package/docs/reference/create-player.md +2 -2
  252. package/docs/reference/menu.md +6 -18
  253. package/docs/reference/popover.md +6 -6
  254. package/docs/reference/poster.md +187 -13
  255. package/docs/reference/slider.md +1 -1
  256. package/docs/reference/time-slider.md +1 -1
  257. package/docs/reference/tooltip.md +10 -10
  258. package/docs/reference/volume-slider.md +1 -1
  259. package/package.json +13 -8
@@ -93,10 +93,10 @@ skin.css
93
93
  ```
94
94
  'use client';
95
95
 
96
- import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode, isValidElement } from 'react';
96
+ import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode } from 'react';
97
97
  import { audioText, captionsText, playbackRateText, qualityText, settingsText, speedText } from '@videojs/core/i18n/text/menu';
98
98
  import { AirPlayEnterIcon, AirPlayExitIcon, CaptionsOffIcon, CaptionsOnIcon, CastEnterIcon, CastExitIcon, CheckIcon, ChevronIcon, FullscreenEnterIcon, FullscreenExitIcon, GearIcon, PauseIcon, PipEnterIcon, PipExitIcon, PlayIcon, QualityIcon, RestartIcon, SpeechIcon, SpeedIcon, SpinnerIcon, VolumeHighIcon, VolumeLowIcon, VolumeOffIcon } from '@videojs/react/icons';
99
- import { Poster, useTranslator, Container, usePlayer, AirPlayButton, useAudioTrackOptions, AudioTrackRadioGroup, BufferingIndicator, CaptionsButton, CaptionsRadioGroup, useCaptionsOptions, CastButton, Controls, ErrorDialog, FullscreenButton, Gesture, Hotkey, Menu, MuteButton, PiPButton, PlayButton, usePlaybackRateOptions, PlaybackRateRadioGroup, Popover, useQualityOptions, QualityRadioGroup, SeekIndicator, Slider, StatusAnnouncer, StatusIndicator, Time, TimeSlider, Tooltip, VolumeIndicator, VolumeSlider, type RenderProp } from '@videojs/react';
99
+ import { Poster, useTranslator, Container, usePlayer, AirPlayButton, useAudioTrackOptions, AudioTrackRadioGroup, BufferingIndicator, CaptionsButton, CaptionsRadioGroup, useCaptionsOptions, CastButton, Controls, ErrorDialog, FullscreenButton, Gesture, Hotkey, Menu, MuteButton, PiPButton, PlayButton, usePlaybackRateOptions, PlaybackRateRadioGroup, Popover, useQualityOptions, QualityRadioGroup, SeekIndicator, Slider, StatusAnnouncer, StatusIndicator, Time, TimeSlider, Tooltip, VolumeIndicator, VolumeSlider } from '@videojs/react';
100
100
  import { Video } from '@videojs/react/video';
101
101
  import './player.css';
102
102
  import { Player } from './player';
@@ -379,9 +379,11 @@ const SEEK_TIME = 10;
379
379
 
380
380
  export interface VideoPlayerProps {
381
381
  src: string;
382
+ poster?: string | undefined;
382
383
  style?: CSSProperties;
383
384
  className?: string;
384
- poster?: string | RenderProp<Poster.State> | undefined;
385
+ renderPoster?: Poster.Props['render'];
386
+ placeholder?: string | undefined;
385
387
  }
386
388
 
387
389
  /**
@@ -393,13 +395,13 @@ export interface VideoPlayerProps {
393
395
  * />
394
396
  * ```
395
397
  */
396
- export function VideoPlayer({ src, className, poster, placeholder, style, ...rest }: VideoPlayerProps): ReactNode {
398
+ export function VideoPlayer({ src, poster, className, renderPoster, placeholder, style, ...rest }: VideoPlayerProps): ReactNode {
397
399
  const containerStyle = placeholder
398
400
  ? ({ '--media-poster-placeholder': `url(${placeholder})`, ...style } as CSSProperties)
399
401
  : style;
400
402
 
401
403
  return (
402
- <Player>
404
+ <Player poster={poster}>
403
405
  <Container
404
406
  className={`media-default-skin media-default-skin--video ${className ?? ''}`}
405
407
  style={containerStyle}
@@ -407,9 +409,7 @@ export function VideoPlayer({ src, className, poster, placeholder, style, ...res
407
409
  >
408
410
  <Video src={src} playsInline />
409
411
 
410
- {poster && (
411
- <Poster src={isString(poster) ? poster : undefined} render={isRenderProp(poster) ? poster : undefined} />
412
- )}
412
+ <Poster render={renderPoster} />
413
413
 
414
414
  <BufferingIndicator
415
415
  render={(props) => (
@@ -633,18 +633,6 @@ function VolumePopover(): ReactNode {
633
633
  </Popover.Root>
634
634
  );
635
635
  }
636
-
637
- // ================================================================
638
- // Utilities
639
- // ================================================================
640
-
641
- function isString(value: unknown): value is string {
642
- return typeof value === 'string';
643
- }
644
-
645
- function isRenderProp(value: unknown): value is RenderProp<unknown> {
646
- return typeof value === 'function' || isValidElement(value);
647
- }
648
636
  ```
649
637
  ```
650
638
  import { createPlayer } from '@videojs/react';
@@ -1212,7 +1200,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
1212
1200
  position: relative;
1213
1201
  display: block;
1214
1202
  max-width: var(--thumbnail-max-width);
1215
- max-height: var(--max-height);
1203
+ max-height: var(--thumbnail-max-height);
1216
1204
  overflow: clip;
1217
1205
  border-radius: inherit;
1218
1206
 
@@ -1267,8 +1255,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
1267
1255
  --track-size: calc(var(--spacing) * 1);
1268
1256
  --track-highlighted-size: calc(var(--spacing) * 1.75);
1269
1257
  --track-border-radius: 99px;
1270
- --thumb-size: calc(var(--spacing) * 2.5);
1271
- --thumb-active-size: calc(var(--spacing) * 3);
1258
+ --thumb-size: calc(var(--spacing) * 3);
1272
1259
  --chapter-gap: calc(var(--spacing) * 1);
1273
1260
  --chapter-inset-start: calc(var(--chapter-gap) / 2);
1274
1261
  --chapter-inset-end: calc(var(--chapter-gap) / 2);
@@ -1321,13 +1308,22 @@ export const { Player } = createPlayer({ features: videoFeatures });
1321
1308
  inset-block: 0;
1322
1309
  left: 0;
1323
1310
  width: 100%;
1324
- transition-property: clip-path;
1325
1311
  }
1326
1312
  &[data-orientation="vertical"] {
1327
1313
  inset-inline: 0;
1328
1314
  bottom: 0;
1329
1315
  height: 100%;
1330
- transition-property: clip-path;
1316
+ }
1317
+
1318
+ @media (prefers-reduced-motion: no-preference) {
1319
+ transition: clip-path 200ms ease-out;
1320
+ }
1321
+ }
1322
+ &[data-dragging],
1323
+ &[data-seeking] {
1324
+ .media-slider__fill,
1325
+ .media-slider__buffer {
1326
+ transition-duration: 0ms;
1331
1327
  }
1332
1328
  }
1333
1329
 
@@ -1354,6 +1350,14 @@ export const { Player } = createPlayer({ features: videoFeatures });
1354
1350
  clip-path: inset(calc(100% - var(--media-slider-fill)) 0 0 0 round var(--track-border-radius));
1355
1351
  }
1356
1352
  }
1353
+ &[data-dragging] {
1354
+ .media-slider__fill[data-orientation="horizontal"] {
1355
+ clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
1356
+ }
1357
+ .media-slider__fill[data-orientation="vertical"] {
1358
+ clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
1359
+ }
1360
+ }
1357
1361
 
1358
1362
  /* Chapters */
1359
1363
  .media-slider__chapters {
@@ -1435,45 +1439,6 @@ export const { Player } = createPlayer({ features: videoFeatures });
1435
1439
  }
1436
1440
  }
1437
1441
 
1438
- /* Dragging — thumb and fill follow the pointer position */
1439
- &[data-dragging] {
1440
- .media-slider__thumb[data-orientation="horizontal"] {
1441
- left: var(--media-slider-pointer);
1442
- }
1443
- .media-slider__thumb[data-orientation="vertical"] {
1444
- top: calc(100% - var(--media-slider-pointer));
1445
- }
1446
- .media-slider__fill[data-orientation="horizontal"] {
1447
- clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
1448
- }
1449
- .media-slider__fill[data-orientation="vertical"] {
1450
- clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
1451
- }
1452
- }
1453
-
1454
- @media (prefers-reduced-motion: no-preference) {
1455
- .media-slider__thumb {
1456
- transition-property: opacity, height, width, outline-offset, left, top;
1457
- }
1458
- .media-slider__fill {
1459
- transition-timing-function: linear;
1460
- transition-duration: 200ms;
1461
- }
1462
- .media-slider__buffer {
1463
- transition-timing-function: ease-out;
1464
- transition-duration: 250ms;
1465
- }
1466
- }
1467
-
1468
- &[data-dragging],
1469
- &[data-seeking] {
1470
- .media-slider__thumb,
1471
- .media-slider__fill,
1472
- .media-slider__buffer {
1473
- transition-duration: 0ms;
1474
- }
1475
- }
1476
-
1477
1442
  /* Thumb */
1478
1443
  .media-slider__thumb {
1479
1444
  position: absolute;
@@ -1490,10 +1455,8 @@ export const { Player } = createPlayer({ features: videoFeatures });
1490
1455
  0 1px 3px 0 oklch(0 0 0 / 0.35),
1491
1456
  0 1px 2px -1px oklch(0 0 0 / 0.35);
1492
1457
  opacity: 0;
1458
+ scale: 0.8;
1493
1459
  translate: -50% -50%;
1494
- transition-timing-function: ease-out;
1495
- transition-duration: 150ms;
1496
- transition-property: opacity, height, width, outline-offset;
1497
1460
 
1498
1461
  &[data-orientation="horizontal"] {
1499
1462
  top: 50%;
@@ -1510,22 +1473,12 @@ export const { Player } = createPlayer({ features: videoFeatures });
1510
1473
  opacity: 1;
1511
1474
  }
1512
1475
 
1513
- @media (hover: hover) and (pointer: fine) {
1514
- &:hover {
1515
- outline-color: oklch(from currentColor l c h / 0.15);
1516
- outline-offset: 0;
1517
- }
1518
- }
1519
-
1520
1476
  &::after {
1521
1477
  position: absolute;
1522
1478
  inset: -4px;
1523
1479
  content: "";
1524
1480
  border-radius: inherit;
1525
1481
  box-shadow: 0 0 0 2px currentColor;
1526
- transition-timing-function: ease-out;
1527
- transition-duration: 150ms;
1528
- transition-property: opacity, scale;
1529
1482
  }
1530
1483
 
1531
1484
  &:not(:focus-visible)::after {
@@ -1534,37 +1487,70 @@ export const { Player } = createPlayer({ features: videoFeatures });
1534
1487
  }
1535
1488
 
1536
1489
  &.media-slider__thumb--persistent {
1537
- width: var(--thumb-active-size);
1538
- height: var(--thumb-active-size);
1539
1490
  opacity: 1;
1491
+ scale: 1;
1492
+ }
1493
+
1494
+ @media (hover: hover) and (pointer: fine) {
1495
+ &:hover {
1496
+ outline-color: oklch(from currentColor l c h / 0.15);
1497
+ outline-offset: 0;
1498
+ }
1540
1499
  }
1541
- }
1542
1500
 
1543
- &:active .media-slider__thumb,
1544
- &:focus-within .media-slider__thumb {
1545
- width: var(--thumb-active-size);
1546
- height: var(--thumb-active-size);
1501
+ @media (prefers-reduced-motion: no-preference) {
1502
+ transition-timing-function: ease-out;
1503
+ transition-duration: 150ms;
1504
+ transition-property: opacity, outline-offset, left, top, scale;
1505
+
1506
+ &::after {
1507
+ transition-timing-function: ease-out;
1508
+ transition-duration: 150ms;
1509
+ transition-property: opacity, scale;
1510
+ }
1511
+ }
1547
1512
  }
1548
1513
 
1549
1514
  @media (hover: hover) and (pointer: fine) {
1550
1515
  &:hover .media-slider__thumb {
1551
1516
  opacity: 1;
1517
+ scale: 1;
1518
+ }
1519
+ }
1520
+
1521
+ &[data-dragging] .media-slider__thumb {
1522
+ opacity: 1;
1523
+ scale: 0.9;
1524
+
1525
+ @media (prefers-reduced-motion: no-preference) {
1526
+ transition-property: opacity, outline-offset, scale;
1527
+ }
1528
+
1529
+ &[data-orientation="horizontal"] {
1530
+ left: var(--media-slider-pointer);
1531
+ }
1532
+ &[data-orientation="vertical"] {
1533
+ top: calc(100% - var(--media-slider-pointer));
1552
1534
  }
1553
1535
  }
1554
1536
 
1555
1537
  /* Preview */
1556
1538
  .media-slider__preview {
1557
- --max-width: min(calc(var(--spacing) * 48), 100cqi);
1558
- --max-height: calc(var(--spacing) * 32);
1539
+ --max-size-factor: 36;
1540
+ --max-size: min(calc(var(--spacing) * var(--max-size-factor)), 100cqi);
1559
1541
 
1560
- min-width: var(--max-width);
1542
+ min-width: var(--max-size);
1561
1543
  height: calc(var(--spacing) * 1);
1562
1544
 
1545
+ @container media-root (width > 42rem) {
1546
+ --max-size-factor: 48;
1547
+ }
1548
+
1563
1549
  .media-slider__thumbnail,
1564
1550
  .media-slider__value {
1565
1551
  position: absolute;
1566
1552
  left: 50%;
1567
- max-width: var(--max-width);
1553
+ max-width: var(--max-size);
1568
1554
  opacity: 0;
1569
1555
  filter: blur(8px);
1570
1556
  transform-origin: bottom;
@@ -1575,7 +1561,8 @@ export const { Player } = createPlayer({ features: videoFeatures });
1575
1561
  }
1576
1562
 
1577
1563
  .media-slider__thumbnail {
1578
- --thumbnail-max-width: var(--max-width);
1564
+ --thumbnail-max-width: var(--max-size);
1565
+ --thumbnail-max-height: var(--max-size);
1579
1566
  bottom: calc(100% + (var(--spacing) * 9));
1580
1567
  }
1581
1568
 
@@ -1589,7 +1576,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
1589
1576
 
1590
1577
  .media-slider__chapter-title {
1591
1578
  min-width: 0;
1592
- max-width: var(--max-width);
1579
+ max-width: var(--max-size);
1593
1580
  padding-inline: calc(var(--spacing) * 6);
1594
1581
  overflow: hidden;
1595
1582
  text-overflow: ellipsis;
@@ -2336,8 +2323,8 @@ export const { Player } = createPlayer({ features: videoFeatures });
2336
2323
  still in the DOM — just `display: none` — so its animations would keep
2337
2324
  running. Set the variables to `none` to short-circuit the keyframes. */
2338
2325
  .media-button--airplay:not([data-airplay-state="connected"]) {
2339
- --media-icon--airplay__fill-animation: none;
2340
- --media-icon--airplay__triangle-animation: none;
2326
+ --media-icon-airplay-fill-animation: none;
2327
+ --media-icon-airplay-triangle-animation: none;
2341
2328
  }
2342
2329
 
2343
2330
  @media (prefers-reduced-motion: reduce) {
@@ -2504,6 +2491,12 @@ export const { Player } = createPlayer({ features: videoFeatures });
2504
2491
  .media-controls--primary,
2505
2492
  .media-controls--secondary {
2506
2493
  position: absolute;
2494
+ }
2495
+ /* Primary must be higher for the preview/thumbnail */
2496
+ .media-controls--primary {
2497
+ z-index: 20;
2498
+ }
2499
+ .media-controls--secondary {
2507
2500
  z-index: 10;
2508
2501
  }
2509
2502
 
@@ -2520,6 +2513,11 @@ export const { Player } = createPlayer({ features: videoFeatures });
2520
2513
  transform-origin: top;
2521
2514
  }
2522
2515
 
2516
+ .media-time-controls {
2517
+ flex: 1;
2518
+ padding-inline: calc(var(--spacing) * 2);
2519
+ }
2520
+
2523
2521
  @container media-root (width < 32rem) {
2524
2522
  .media-controls--primary,
2525
2523
  .media-controls--secondary {
@@ -2570,6 +2568,10 @@ export const { Player } = createPlayer({ features: videoFeatures });
2570
2568
  }
2571
2569
  }
2572
2570
  }
2571
+
2572
+ .media-button--captions {
2573
+ display: none;
2574
+ }
2573
2575
  }
2574
2576
 
2575
2577
  @container media-root (width >= 32rem) {
@@ -2606,11 +2608,10 @@ export const { Player } = createPlayer({ features: videoFeatures });
2606
2608
  translate: 0 4px;
2607
2609
  }
2608
2610
  }
2609
- }
2610
2611
 
2611
- .media-time-controls {
2612
- flex: 1;
2613
- padding-inline: calc(var(--spacing) * 3);
2612
+ .media-time-controls {
2613
+ padding-inline: calc(var(--spacing) * 3);
2614
+ }
2614
2615
  }
2615
2616
 
2616
2617
  @media (pointer: fine) {
@@ -2659,7 +2660,7 @@ skin.css
2659
2660
  import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode } from 'react';
2660
2661
  import { playbackRateText } from '@videojs/core/i18n/text/menu';
2661
2662
  import { CheckIcon, PauseIcon, PlayIcon, RestartIcon, SeekIcon, SpinnerIcon, VolumeHighIcon, VolumeLowIcon, VolumeOffIcon } from '@videojs/react/icons';
2662
- import { useTranslator, Container, usePlayer, BufferingIndicator, ErrorDialog, Hotkey, Menu, MuteButton, PlayButton, usePlaybackRateOptions, PlaybackRateButton, PlaybackRateRadioGroup as PlaybackRateRadioGroupComponent, Popover, SeekButton, StatusAnnouncer, Time, TimeSlider, Tooltip, VolumeSlider, type Poster, type RenderProp } from '@videojs/react';
2663
+ import { useTranslator, Container, usePlayer, BufferingIndicator, ErrorDialog, Hotkey, Menu, MuteButton, PlayButton, usePlaybackRateOptions, PlaybackRateButton, PlaybackRateRadioGroup as PlaybackRateRadioGroupComponent, Popover, SeekButton, StatusAnnouncer, Time, TimeSlider, Tooltip, VolumeSlider, type Poster } from '@videojs/react';
2663
2664
  import { Audio } from '@videojs/react/audio';
2664
2665
  import './player.css';
2665
2666
  import { Player } from './player';
@@ -3340,8 +3341,7 @@ export const { Player } = createPlayer({ features: audioFeatures });
3340
3341
  --track-size: calc(var(--spacing) * 1);
3341
3342
  --track-highlighted-size: calc(var(--spacing) * 1.75);
3342
3343
  --track-border-radius: 99px;
3343
- --thumb-size: calc(var(--spacing) * 2.5);
3344
- --thumb-active-size: calc(var(--spacing) * 3);
3344
+ --thumb-size: calc(var(--spacing) * 3);
3345
3345
  --chapter-gap: calc(var(--spacing) * 1);
3346
3346
  --chapter-inset-start: calc(var(--chapter-gap) / 2);
3347
3347
  --chapter-inset-end: calc(var(--chapter-gap) / 2);
@@ -3394,13 +3394,22 @@ export const { Player } = createPlayer({ features: audioFeatures });
3394
3394
  inset-block: 0;
3395
3395
  left: 0;
3396
3396
  width: 100%;
3397
- transition-property: clip-path;
3398
3397
  }
3399
3398
  &[data-orientation="vertical"] {
3400
3399
  inset-inline: 0;
3401
3400
  bottom: 0;
3402
3401
  height: 100%;
3403
- transition-property: clip-path;
3402
+ }
3403
+
3404
+ @media (prefers-reduced-motion: no-preference) {
3405
+ transition: clip-path 200ms ease-out;
3406
+ }
3407
+ }
3408
+ &[data-dragging],
3409
+ &[data-seeking] {
3410
+ .media-slider__fill,
3411
+ .media-slider__buffer {
3412
+ transition-duration: 0ms;
3404
3413
  }
3405
3414
  }
3406
3415
 
@@ -3427,6 +3436,14 @@ export const { Player } = createPlayer({ features: audioFeatures });
3427
3436
  clip-path: inset(calc(100% - var(--media-slider-fill)) 0 0 0 round var(--track-border-radius));
3428
3437
  }
3429
3438
  }
3439
+ &[data-dragging] {
3440
+ .media-slider__fill[data-orientation="horizontal"] {
3441
+ clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
3442
+ }
3443
+ .media-slider__fill[data-orientation="vertical"] {
3444
+ clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
3445
+ }
3446
+ }
3430
3447
 
3431
3448
  /* Chapters */
3432
3449
  .media-slider__chapters {
@@ -3508,45 +3525,6 @@ export const { Player } = createPlayer({ features: audioFeatures });
3508
3525
  }
3509
3526
  }
3510
3527
 
3511
- /* Dragging — thumb and fill follow the pointer position */
3512
- &[data-dragging] {
3513
- .media-slider__thumb[data-orientation="horizontal"] {
3514
- left: var(--media-slider-pointer);
3515
- }
3516
- .media-slider__thumb[data-orientation="vertical"] {
3517
- top: calc(100% - var(--media-slider-pointer));
3518
- }
3519
- .media-slider__fill[data-orientation="horizontal"] {
3520
- clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
3521
- }
3522
- .media-slider__fill[data-orientation="vertical"] {
3523
- clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
3524
- }
3525
- }
3526
-
3527
- @media (prefers-reduced-motion: no-preference) {
3528
- .media-slider__thumb {
3529
- transition-property: opacity, height, width, outline-offset, left, top;
3530
- }
3531
- .media-slider__fill {
3532
- transition-timing-function: linear;
3533
- transition-duration: 200ms;
3534
- }
3535
- .media-slider__buffer {
3536
- transition-timing-function: ease-out;
3537
- transition-duration: 250ms;
3538
- }
3539
- }
3540
-
3541
- &[data-dragging],
3542
- &[data-seeking] {
3543
- .media-slider__thumb,
3544
- .media-slider__fill,
3545
- .media-slider__buffer {
3546
- transition-duration: 0ms;
3547
- }
3548
- }
3549
-
3550
3528
  /* Thumb */
3551
3529
  .media-slider__thumb {
3552
3530
  position: absolute;
@@ -3563,10 +3541,8 @@ export const { Player } = createPlayer({ features: audioFeatures });
3563
3541
  0 1px 3px 0 oklch(0 0 0 / 0.35),
3564
3542
  0 1px 2px -1px oklch(0 0 0 / 0.35);
3565
3543
  opacity: 0;
3544
+ scale: 0.8;
3566
3545
  translate: -50% -50%;
3567
- transition-timing-function: ease-out;
3568
- transition-duration: 150ms;
3569
- transition-property: opacity, height, width, outline-offset;
3570
3546
 
3571
3547
  &[data-orientation="horizontal"] {
3572
3548
  top: 50%;
@@ -3583,22 +3559,12 @@ export const { Player } = createPlayer({ features: audioFeatures });
3583
3559
  opacity: 1;
3584
3560
  }
3585
3561
 
3586
- @media (hover: hover) and (pointer: fine) {
3587
- &:hover {
3588
- outline-color: oklch(from currentColor l c h / 0.15);
3589
- outline-offset: 0;
3590
- }
3591
- }
3592
-
3593
3562
  &::after {
3594
3563
  position: absolute;
3595
3564
  inset: -4px;
3596
3565
  content: "";
3597
3566
  border-radius: inherit;
3598
3567
  box-shadow: 0 0 0 2px currentColor;
3599
- transition-timing-function: ease-out;
3600
- transition-duration: 150ms;
3601
- transition-property: opacity, scale;
3602
3568
  }
3603
3569
 
3604
3570
  &:not(:focus-visible)::after {
@@ -3607,37 +3573,70 @@ export const { Player } = createPlayer({ features: audioFeatures });
3607
3573
  }
3608
3574
 
3609
3575
  &.media-slider__thumb--persistent {
3610
- width: var(--thumb-active-size);
3611
- height: var(--thumb-active-size);
3612
3576
  opacity: 1;
3577
+ scale: 1;
3578
+ }
3579
+
3580
+ @media (hover: hover) and (pointer: fine) {
3581
+ &:hover {
3582
+ outline-color: oklch(from currentColor l c h / 0.15);
3583
+ outline-offset: 0;
3584
+ }
3613
3585
  }
3614
- }
3615
3586
 
3616
- &:active .media-slider__thumb,
3617
- &:focus-within .media-slider__thumb {
3618
- width: var(--thumb-active-size);
3619
- height: var(--thumb-active-size);
3587
+ @media (prefers-reduced-motion: no-preference) {
3588
+ transition-timing-function: ease-out;
3589
+ transition-duration: 150ms;
3590
+ transition-property: opacity, outline-offset, left, top, scale;
3591
+
3592
+ &::after {
3593
+ transition-timing-function: ease-out;
3594
+ transition-duration: 150ms;
3595
+ transition-property: opacity, scale;
3596
+ }
3597
+ }
3620
3598
  }
3621
3599
 
3622
3600
  @media (hover: hover) and (pointer: fine) {
3623
3601
  &:hover .media-slider__thumb {
3624
3602
  opacity: 1;
3603
+ scale: 1;
3604
+ }
3605
+ }
3606
+
3607
+ &[data-dragging] .media-slider__thumb {
3608
+ opacity: 1;
3609
+ scale: 0.9;
3610
+
3611
+ @media (prefers-reduced-motion: no-preference) {
3612
+ transition-property: opacity, outline-offset, scale;
3613
+ }
3614
+
3615
+ &[data-orientation="horizontal"] {
3616
+ left: var(--media-slider-pointer);
3617
+ }
3618
+ &[data-orientation="vertical"] {
3619
+ top: calc(100% - var(--media-slider-pointer));
3625
3620
  }
3626
3621
  }
3627
3622
 
3628
3623
  /* Preview */
3629
3624
  .media-slider__preview {
3630
- --max-width: min(calc(var(--spacing) * 48), 100cqi);
3631
- --max-height: calc(var(--spacing) * 32);
3625
+ --max-size-factor: 36;
3626
+ --max-size: min(calc(var(--spacing) * var(--max-size-factor)), 100cqi);
3632
3627
 
3633
- min-width: var(--max-width);
3628
+ min-width: var(--max-size);
3634
3629
  height: calc(var(--spacing) * 1);
3635
3630
 
3631
+ @container media-root (width > 42rem) {
3632
+ --max-size-factor: 48;
3633
+ }
3634
+
3636
3635
  .media-slider__thumbnail,
3637
3636
  .media-slider__value {
3638
3637
  position: absolute;
3639
3638
  left: 50%;
3640
- max-width: var(--max-width);
3639
+ max-width: var(--max-size);
3641
3640
  opacity: 0;
3642
3641
  filter: blur(8px);
3643
3642
  transform-origin: bottom;
@@ -3648,7 +3647,8 @@ export const { Player } = createPlayer({ features: audioFeatures });
3648
3647
  }
3649
3648
 
3650
3649
  .media-slider__thumbnail {
3651
- --thumbnail-max-width: var(--max-width);
3650
+ --thumbnail-max-width: var(--max-size);
3651
+ --thumbnail-max-height: var(--max-size);
3652
3652
  bottom: calc(100% + (var(--spacing) * 9));
3653
3653
  }
3654
3654
 
@@ -3662,7 +3662,7 @@ export const { Player } = createPlayer({ features: audioFeatures });
3662
3662
 
3663
3663
  .media-slider__chapter-title {
3664
3664
  min-width: 0;
3665
- max-width: var(--max-width);
3665
+ max-width: var(--max-size);
3666
3666
  padding-inline: calc(var(--spacing) * 6);
3667
3667
  overflow: hidden;
3668
3668
  text-overflow: ellipsis;
@@ -4243,10 +4243,10 @@ skin.css
4243
4243
  ```
4244
4244
  'use client';
4245
4245
 
4246
- import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode, isValidElement } from 'react';
4246
+ import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode } from 'react';
4247
4247
  import { audioText, captionsText, playbackRateText, qualityText, settingsText, speedText } from '@videojs/core/i18n/text/menu';
4248
4248
  import { AirPlayEnterIcon, AirPlayExitIcon, CaptionsOffIcon, CaptionsOnIcon, CastEnterIcon, CastExitIcon, CheckIcon, ChevronIcon, FullscreenEnterIcon, FullscreenExitIcon, GearIcon, PauseIcon, PipEnterIcon, PipExitIcon, PlayIcon, QualityIcon, RestartIcon, SpeechIcon, SpeedIcon, SpinnerIcon, VolumeHighIcon, VolumeLowIcon, VolumeOffIcon } from '@videojs/react/icons/minimal';
4249
- import { Poster, useTranslator, Container, usePlayer, AirPlayButton, useAudioTrackOptions, AudioTrackRadioGroup, BufferingIndicator, CaptionsButton, CaptionsRadioGroup, useCaptionsOptions, CastButton, Controls, ErrorDialog, FullscreenButton, Gesture, Hotkey, Menu, MuteButton, PiPButton, PlayButton, usePlaybackRateOptions, PlaybackRateRadioGroup, Popover, useQualityOptions, QualityRadioGroup, SeekIndicator, Slider, StatusAnnouncer, StatusIndicator, Time, TimeSlider, Tooltip, VolumeIndicator, VolumeSlider, type RenderProp } from '@videojs/react';
4249
+ import { Poster, useTranslator, Container, usePlayer, AirPlayButton, useAudioTrackOptions, AudioTrackRadioGroup, BufferingIndicator, CaptionsButton, CaptionsRadioGroup, useCaptionsOptions, CastButton, Controls, ErrorDialog, FullscreenButton, Gesture, Hotkey, Menu, MuteButton, PiPButton, PlayButton, usePlaybackRateOptions, PlaybackRateRadioGroup, Popover, useQualityOptions, QualityRadioGroup, SeekIndicator, Slider, StatusAnnouncer, StatusIndicator, Time, TimeSlider, Tooltip, VolumeIndicator, VolumeSlider } from '@videojs/react';
4250
4250
  import { Video } from '@videojs/react/video';
4251
4251
  import './player.css';
4252
4252
  import { Player } from './player';
@@ -4453,9 +4453,11 @@ const SEEK_TIME = 10;
4453
4453
 
4454
4454
  export interface VideoPlayerProps {
4455
4455
  src: string;
4456
+ poster?: string | undefined;
4456
4457
  style?: CSSProperties;
4457
4458
  className?: string;
4458
- poster?: string | RenderProp<Poster.State> | undefined;
4459
+ renderPoster?: Poster.Props['render'];
4460
+ placeholder?: string | undefined;
4459
4461
  }
4460
4462
 
4461
4463
  /**
@@ -4467,13 +4469,13 @@ export interface VideoPlayerProps {
4467
4469
  * />
4468
4470
  * ```
4469
4471
  */
4470
- export function VideoPlayer({ src, className, poster, placeholder, style, ...rest }: VideoPlayerProps): ReactNode {
4472
+ export function VideoPlayer({ src, poster, className, renderPoster, placeholder, style, ...rest }: VideoPlayerProps): ReactNode {
4471
4473
  const containerStyle = placeholder
4472
4474
  ? ({ '--media-poster-placeholder': `url(${placeholder})`, ...style } as CSSProperties)
4473
4475
  : style;
4474
4476
 
4475
4477
  return (
4476
- <Player>
4478
+ <Player poster={poster}>
4477
4479
  <Container
4478
4480
  className={`media-minimal-skin media-minimal-skin--video ${className ?? ''}`}
4479
4481
  style={containerStyle}
@@ -4481,9 +4483,7 @@ export function VideoPlayer({ src, className, poster, placeholder, style, ...res
4481
4483
  >
4482
4484
  <Video src={src} playsInline />
4483
4485
 
4484
- {poster && (
4485
- <Poster src={isString(poster) ? poster : undefined} render={isRenderProp(poster) ? poster : undefined} />
4486
- )}
4486
+ <Poster render={renderPoster} />
4487
4487
 
4488
4488
  <BufferingIndicator
4489
4489
  render={(props) => (
@@ -4761,18 +4761,6 @@ function VolumePopover(): ReactNode {
4761
4761
  </Popover.Root>
4762
4762
  );
4763
4763
  }
4764
-
4765
- // ================================================================
4766
- // Utilities
4767
- // ================================================================
4768
-
4769
- function isString(value: unknown): value is string {
4770
- return typeof value === 'string';
4771
- }
4772
-
4773
- function isRenderProp(value: unknown): value is RenderProp<unknown> {
4774
- return typeof value === 'function' || isValidElement(value);
4775
- }
4776
4764
  ```
4777
4765
  ```
4778
4766
  import { createPlayer } from '@videojs/react';
@@ -5365,7 +5353,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
5365
5353
  position: relative;
5366
5354
  display: block;
5367
5355
  max-width: var(--thumbnail-max-width);
5368
- max-height: var(--max-height);
5356
+ max-height: var(--thumbnail-max-height);
5369
5357
  overflow: clip;
5370
5358
  border-radius: inherit;
5371
5359
  }
@@ -5409,9 +5397,13 @@ export const { Player } = createPlayer({ features: videoFeatures });
5409
5397
  }
5410
5398
 
5411
5399
  .media-minimal-skin .media-slider {
5400
+ --track-size: calc(var(--spacing) * 1);
5401
+ --track-highlighted-size: calc(var(--spacing) * 1.75);
5402
+ --track-border-radius: 99px;
5412
5403
  --thumb-size: calc(var(--spacing) * 3);
5413
- --thumb-active-size: calc(var(--spacing) * 3);
5414
- --track-border-radius: calc(Infinity * 1px);
5404
+ --chapter-gap: calc(var(--spacing) * 1);
5405
+ --chapter-inset-start: calc(var(--chapter-gap) / 2);
5406
+ --chapter-inset-end: calc(var(--chapter-gap) / 2);
5415
5407
 
5416
5408
  position: relative;
5417
5409
  display: flex;
@@ -5443,71 +5435,17 @@ export const { Player } = createPlayer({ features: videoFeatures });
5443
5435
 
5444
5436
  &[data-orientation="horizontal"] {
5445
5437
  width: 100%;
5446
- height: calc(var(--spacing) * 0.75);
5438
+ height: var(--track-size);
5447
5439
  }
5448
5440
  &[data-orientation="vertical"] {
5449
- width: calc(var(--spacing) * 0.75);
5441
+ width: var(--track-size);
5450
5442
  height: 100%;
5451
5443
  }
5452
5444
  }
5453
5445
 
5454
- /* Thumb */
5455
- .media-slider__thumb {
5456
- position: absolute;
5457
- z-index: 10;
5458
- width: var(--thumb-size);
5459
- height: var(--thumb-size);
5460
- user-select: none;
5461
- outline: 2px solid transparent;
5462
- outline-offset: -2px;
5463
- background-color: currentColor;
5464
- border-radius: calc(Infinity * 1px);
5465
- box-shadow:
5466
- 0 0 0 1px var(--shadow-current-color, oklch(0 0 0 / 0.15)),
5467
- 0 1px 3px 0 oklch(0 0 0 / 0.15),
5468
- 0 1px 2px -1px oklch(0 0 0 / 0.15);
5469
- opacity: 0;
5470
- transform-origin: center;
5471
- scale: 0.7;
5472
- translate: -50% -50%;
5473
- transition-timing-function: ease-out;
5474
- transition-duration: 150ms;
5475
-
5476
- &[data-orientation="horizontal"] {
5477
- top: 50%;
5478
- left: var(--media-slider-fill);
5479
- }
5480
- &[data-orientation="vertical"] {
5481
- top: calc(100% - var(--media-slider-fill));
5482
- left: 50%;
5483
- }
5484
-
5485
- &:focus-visible {
5486
- outline-color: var(--focus-ring-color);
5487
- outline-offset: 2px;
5488
- }
5489
- }
5490
-
5491
- &:focus-within .media-slider__thumb,
5492
- .media-slider__thumb--persistent {
5493
- width: var(--thumb-active-size);
5494
- height: var(--thumb-active-size);
5495
- opacity: 1;
5496
- scale: 1;
5497
- }
5498
-
5499
- @media (hover: hover) and (pointer: fine) {
5500
- &:hover .media-slider__thumb {
5501
- width: var(--thumb-active-size);
5502
- height: var(--thumb-active-size);
5503
- opacity: 1;
5504
- scale: 1;
5505
- }
5506
- }
5507
-
5508
- /* Shared track fills */
5509
- .media-slider__buffer,
5510
- .media-slider__fill {
5446
+ /* Shared track fills */
5447
+ .media-slider__buffer,
5448
+ .media-slider__fill {
5511
5449
  position: absolute;
5512
5450
  pointer-events: none;
5513
5451
  border-radius: inherit;
@@ -5516,13 +5454,22 @@ export const { Player } = createPlayer({ features: videoFeatures });
5516
5454
  inset-block: 0;
5517
5455
  left: 0;
5518
5456
  width: 100%;
5519
- transition-property: clip-path;
5520
5457
  }
5521
5458
  &[data-orientation="vertical"] {
5522
5459
  inset-inline: 0;
5523
5460
  bottom: 0;
5524
5461
  height: 100%;
5525
- transition-property: clip-path;
5462
+ }
5463
+
5464
+ @media (prefers-reduced-motion: no-preference) {
5465
+ transition: clip-path 200ms ease-out;
5466
+ }
5467
+ }
5468
+ &[data-dragging],
5469
+ &[data-seeking] {
5470
+ .media-slider__fill,
5471
+ .media-slider__buffer {
5472
+ transition-duration: 0ms;
5526
5473
  }
5527
5474
  }
5528
5475
 
@@ -5549,6 +5496,14 @@ export const { Player } = createPlayer({ features: videoFeatures });
5549
5496
  clip-path: inset(calc(100% - var(--media-slider-fill)) 0 0 0 round var(--track-border-radius));
5550
5497
  }
5551
5498
  }
5499
+ &[data-dragging] {
5500
+ .media-slider__fill[data-orientation="horizontal"] {
5501
+ clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
5502
+ }
5503
+ .media-slider__fill[data-orientation="vertical"] {
5504
+ clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
5505
+ }
5506
+ }
5552
5507
 
5553
5508
  /* Chapters */
5554
5509
  .media-slider__chapters {
@@ -5572,9 +5527,6 @@ export const { Player } = createPlayer({ features: videoFeatures });
5572
5527
  }
5573
5528
 
5574
5529
  .media-slider__chapter {
5575
- --chapter-gap: calc(var(--spacing) * 1);
5576
- --chapter-inset-start: calc(var(--chapter-gap) / 2);
5577
- --chapter-inset-end: calc(var(--chapter-gap) / 2);
5578
5530
  position: absolute;
5579
5531
  inset: 0;
5580
5532
  display: flex;
@@ -5591,8 +5543,6 @@ export const { Player } = createPlayer({ features: videoFeatures });
5591
5543
  }
5592
5544
 
5593
5545
  .media-slider__chapter-track {
5594
- --chapter-track-size: calc(var(--spacing) * 0.75);
5595
- --chapter-track-highlighted-size: calc(var(--spacing) * 1.25);
5596
5546
  border-radius: var(--track-border-radius);
5597
5547
 
5598
5548
  @media (prefers-reduced-motion: no-preference) {
@@ -5605,7 +5555,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
5605
5555
  clip-path: inset(0 calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start));
5606
5556
 
5607
5557
  .media-slider__chapter-track {
5608
- height: var(--chapter-track-size);
5558
+ height: var(--track-size);
5609
5559
  clip-path: inset(
5610
5560
  0 calc(100% - var(--media-slider-chapter-end) + var(--chapter-inset-end)) 0
5611
5561
  calc(var(--media-slider-chapter-start) + var(--chapter-inset-start)) round var(--track-border-radius)
@@ -5613,7 +5563,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
5613
5563
  }
5614
5564
 
5615
5565
  &[data-highlighted] .media-slider__chapter-track {
5616
- height: var(--chapter-track-highlighted-size);
5566
+ height: var(--track-highlighted-size);
5617
5567
  }
5618
5568
  }
5619
5569
 
@@ -5621,7 +5571,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
5621
5571
  clip-path: inset(calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start) 0);
5622
5572
 
5623
5573
  .media-slider__chapter-track {
5624
- width: var(--chapter-track-size);
5574
+ width: var(--track-size);
5625
5575
  clip-path: inset(
5626
5576
  calc(100% - var(--media-slider-chapter-end) + var(--chapter-inset-end)) 0
5627
5577
  calc(var(--media-slider-chapter-start) + var(--chapter-inset-start)) 0 round var(--track-border-radius)
@@ -5629,63 +5579,102 @@ export const { Player } = createPlayer({ features: videoFeatures });
5629
5579
  }
5630
5580
 
5631
5581
  &[data-highlighted] .media-slider__chapter-track {
5632
- width: var(--chapter-track-highlighted-size);
5582
+ width: var(--track-highlighted-size);
5633
5583
  }
5634
5584
  }
5635
5585
  }
5636
5586
 
5637
- /* Dragging — thumb and fill follow the pointer position */
5638
- &[data-dragging] {
5639
- .media-slider__thumb[data-orientation="horizontal"] {
5640
- left: var(--media-slider-pointer);
5641
- }
5642
- .media-slider__thumb[data-orientation="vertical"] {
5643
- top: calc(100% - var(--media-slider-pointer));
5644
- }
5645
- .media-slider__fill[data-orientation="horizontal"] {
5646
- clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
5587
+ /* Thumb */
5588
+ .media-slider__thumb {
5589
+ position: absolute;
5590
+ z-index: 10;
5591
+ width: var(--thumb-size);
5592
+ height: var(--thumb-size);
5593
+ user-select: none;
5594
+ outline: 2px solid transparent;
5595
+ outline-offset: -2px;
5596
+ background-color: currentColor;
5597
+ border-radius: calc(Infinity * 1px);
5598
+ box-shadow:
5599
+ 0 0 0 1px var(--shadow-current-color, oklch(0 0 0 / 0.15)),
5600
+ 0 1px 3px 0 oklch(0 0 0 / 0.15),
5601
+ 0 1px 2px -1px oklch(0 0 0 / 0.15);
5602
+ opacity: 0;
5603
+ transform-origin: center;
5604
+ scale: 0.7;
5605
+ translate: -50% -50%;
5606
+
5607
+ &[data-orientation="horizontal"] {
5608
+ top: 50%;
5609
+ left: var(--media-slider-fill);
5647
5610
  }
5648
- .media-slider__fill[data-orientation="vertical"] {
5649
- clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
5611
+ &[data-orientation="vertical"] {
5612
+ top: calc(100% - var(--media-slider-fill));
5613
+ left: 50%;
5650
5614
  }
5651
- }
5652
5615
 
5653
- @media (prefers-reduced-motion: no-preference) {
5654
- .media-slider__thumb {
5655
- transition-property: opacity, scale, height, width, outline-offset, left, top;
5616
+ &:focus-visible {
5617
+ outline-color: var(--focus-ring-color);
5618
+ outline-offset: 2px;
5656
5619
  }
5657
- .media-slider__fill {
5658
- transition-timing-function: linear;
5659
- transition-duration: 200ms;
5620
+
5621
+ &:focus-visible,
5622
+ &.media-slider__thumb--persistent {
5623
+ opacity: 1;
5624
+ scale: 1;
5660
5625
  }
5661
- .media-slider__buffer {
5626
+
5627
+ @media (prefers-reduced-motion: no-preference) {
5662
5628
  transition-timing-function: ease-out;
5663
- transition-duration: 250ms;
5629
+ transition-duration: 150ms;
5630
+ transition-property: opacity, outline-offset, left, top, scale;
5664
5631
  }
5665
5632
  }
5666
5633
 
5667
- &[data-dragging],
5668
- &[data-seeking] {
5669
- .media-slider__thumb,
5670
- .media-slider__fill,
5671
- .media-slider__buffer {
5672
- transition-duration: 0ms;
5634
+ @media (hover: hover) and (pointer: fine) {
5635
+ &:hover .media-slider__thumb {
5636
+ opacity: 1;
5637
+ scale: 1;
5638
+ }
5639
+ }
5640
+
5641
+ &[data-dragging] .media-slider__thumb {
5642
+ opacity: 1;
5643
+ scale: 0.9;
5644
+
5645
+ @media (prefers-reduced-motion: no-preference) {
5646
+ transition-property: opacity, outline-offset, scale;
5647
+ }
5648
+
5649
+ &[data-orientation="horizontal"] {
5650
+ left: var(--media-slider-pointer);
5651
+ }
5652
+ &[data-orientation="vertical"] {
5653
+ top: calc(100% - var(--media-slider-pointer));
5673
5654
  }
5674
5655
  }
5675
5656
 
5676
5657
  /* Preview */
5677
5658
  .media-slider__preview {
5678
- --max-width: min(calc(var(--spacing) * 48), 100cqi);
5679
- --max-height: calc(var(--spacing) * 32);
5659
+ --max-size-factor: 28;
5660
+ --max-size: min(calc(var(--spacing) * var(--max-size-factor)), 100cqi);
5680
5661
 
5681
5662
  min-width: 100%;
5682
5663
  height: calc(var(--spacing) * 1);
5683
5664
 
5665
+ @container media-root (width > 32rem) {
5666
+ --max-size-factor: 36;
5667
+ }
5668
+
5669
+ @container media-root (width > 42rem) {
5670
+ --max-size-factor: 48;
5671
+ }
5672
+
5684
5673
  .media-slider__thumbnail,
5685
5674
  .media-slider__value {
5686
5675
  position: absolute;
5687
5676
  left: var(--preview-left, var(--media-slider-pointer));
5688
- max-width: var(--max-width);
5677
+ max-width: var(--max-size);
5689
5678
  opacity: 0;
5690
5679
  filter: blur(8px);
5691
5680
  transform-origin: bottom;
@@ -5697,8 +5686,9 @@ export const { Player } = createPlayer({ features: videoFeatures });
5697
5686
  }
5698
5687
 
5699
5688
  .media-slider__thumbnail {
5700
- --thumbnail-max-width: var(--max-width);
5701
- bottom: calc(100% + (var(--spacing) * 12));
5689
+ --thumbnail-max-width: var(--max-size);
5690
+ --thumbnail-max-height: var(--max-size);
5691
+ bottom: calc(100% + (var(--spacing) * 11));
5702
5692
  }
5703
5693
 
5704
5694
  .media-slider__value {
@@ -6498,8 +6488,8 @@ export const { Player } = createPlayer({ features: videoFeatures });
6498
6488
  still in the DOM — just `display: none` — so its animations would keep
6499
6489
  running. Set the variables to `none` to short-circuit the keyframes. */
6500
6490
  .media-button--airplay:not([data-airplay-state="connected"]) {
6501
- --media-icon--airplay__fill-animation: none;
6502
- --media-icon--airplay__triangle-animation: none;
6491
+ --media-icon-airplay-fill-animation: none;
6492
+ --media-icon-airplay-triangle-animation: none;
6503
6493
  }
6504
6494
 
6505
6495
  @media (prefers-reduced-motion: reduce) {
@@ -6661,6 +6651,7 @@ export const { Player } = createPlayer({ features: videoFeatures });
6661
6651
  --base-boundary-offset: 1;
6662
6652
  --inset-factor: 1;
6663
6653
  --inset: calc(var(--spacing) * var(--inset-factor));
6654
+ --volume-mask: linear-gradient(to right, transparent 10%, #000 25%, #000 100%);
6664
6655
 
6665
6656
  position: absolute;
6666
6657
  inset-inline: var(--inset);
@@ -6716,6 +6707,37 @@ export const { Player } = createPlayer({ features: videoFeatures });
6716
6707
  justify-content: end;
6717
6708
  }
6718
6709
 
6710
+ :is(.media-time-controls, .media-button-group:last-child) {
6711
+ mask-image: var(--volume-mask-image, none);
6712
+ mask-repeat: no-repeat;
6713
+ mask-position: var(--volume-mask-position, 100% 0);
6714
+ mask-size: var(--volume-mask-size, 200% 100%);
6715
+ transition: mask-position 50ms ease-out;
6716
+ }
6717
+
6718
+ @container media-root (width <= 42rem) {
6719
+ .media-popover--volume {
6720
+ --media-popover-side-offset: calc(var(--spacing) * 3);
6721
+ }
6722
+ }
6723
+
6724
+ &:has(.media-button--mute[aria-expanded="true"]) {
6725
+ @container media-root (width <= 42rem) {
6726
+ .media-button-group:last-child {
6727
+ --volume-mask-image: var(--volume-mask);
6728
+ --volume-mask-position: 0 0;
6729
+ --volume-mask-size: 400% 100%;
6730
+ }
6731
+ }
6732
+
6733
+ @container media-root (width > 42rem) {
6734
+ .media-time-controls {
6735
+ --volume-mask-image: var(--volume-mask);
6736
+ --volume-mask-position: 0 0;
6737
+ }
6738
+ }
6739
+ }
6740
+
6719
6741
  @container media-root (width > 42rem) {
6720
6742
  --inset-factor: 2;
6721
6743
  --base-side-offset: 2;
@@ -6733,20 +6755,6 @@ export const { Player } = createPlayer({ features: videoFeatures });
6733
6755
  .media-button-group:last-child {
6734
6756
  flex: 0 0 auto;
6735
6757
  }
6736
-
6737
- .media-time-controls {
6738
- mask-position: 100% 0;
6739
- mask-size: 200% 100%;
6740
- transition: mask-position 50ms ease-out;
6741
- }
6742
-
6743
- &:has(.media-button--mute[aria-expanded="true"]) .media-time-controls {
6744
- mask-image: linear-gradient(to right, transparent 10%, #000 25%, #000 100%);
6745
- }
6746
-
6747
- &:has(.media-button--mute[aria-expanded="true"]) .media-time-controls {
6748
- mask-position: 0 0;
6749
- }
6750
6758
  }
6751
6759
  }
6752
6760
 
@@ -6771,9 +6779,9 @@ export const { Player } = createPlayer({ features: videoFeatures });
6771
6779
  .media-minimal-skin--video .media-slider .media-slider__preview {
6772
6780
  --preview-end-inset: calc(100cqi - 100%);
6773
6781
  --preview-left: clamp(
6774
- calc(var(--max-width) / 2),
6782
+ calc(var(--max-size) / 2),
6775
6783
  var(--media-slider-pointer),
6776
- calc(100% - var(--max-width) / 2 + var(--preview-end-inset))
6784
+ calc(100% - var(--max-size) / 2 + var(--preview-end-inset))
6777
6785
  );
6778
6786
 
6779
6787
  @container media-root (width > 42rem) {
@@ -6797,7 +6805,7 @@ skin.css
6797
6805
  import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode } from 'react';
6798
6806
  import { playbackRateText } from '@videojs/core/i18n/text/menu';
6799
6807
  import { CheckIcon, PauseIcon, PlayIcon, RestartIcon, SeekIcon, SpinnerIcon, VolumeHighIcon, VolumeLowIcon, VolumeOffIcon } from '@videojs/react/icons/minimal';
6800
- import { useTranslator, Container, usePlayer, BufferingIndicator, ErrorDialog, Hotkey, Menu, MuteButton, PlayButton, usePlaybackRateOptions, PlaybackRateButton, PlaybackRateRadioGroup as PlaybackRateRadioGroupComponent, Popover, SeekButton, StatusAnnouncer, Time, TimeSlider, Tooltip, VolumeSlider, type Poster, type RenderProp } from '@videojs/react';
6808
+ import { useTranslator, Container, usePlayer, BufferingIndicator, ErrorDialog, Hotkey, Menu, MuteButton, PlayButton, usePlaybackRateOptions, PlaybackRateButton, PlaybackRateRadioGroup as PlaybackRateRadioGroupComponent, Popover, SeekButton, StatusAnnouncer, Time, TimeSlider, Tooltip, VolumeSlider, type Poster } from '@videojs/react';
6801
6809
  import { Audio } from '@videojs/react/audio';
6802
6810
  import './player.css';
6803
6811
  import { Player } from './player';
@@ -7488,9 +7496,13 @@ export const { Player } = createPlayer({ features: audioFeatures });
7488
7496
  }
7489
7497
 
7490
7498
  .media-minimal-skin .media-slider {
7499
+ --track-size: calc(var(--spacing) * 1);
7500
+ --track-highlighted-size: calc(var(--spacing) * 1.75);
7501
+ --track-border-radius: 99px;
7491
7502
  --thumb-size: calc(var(--spacing) * 3);
7492
- --thumb-active-size: calc(var(--spacing) * 3);
7493
- --track-border-radius: calc(Infinity * 1px);
7503
+ --chapter-gap: calc(var(--spacing) * 1);
7504
+ --chapter-inset-start: calc(var(--chapter-gap) / 2);
7505
+ --chapter-inset-end: calc(var(--chapter-gap) / 2);
7494
7506
 
7495
7507
  position: relative;
7496
7508
  display: flex;
@@ -7522,68 +7534,14 @@ export const { Player } = createPlayer({ features: audioFeatures });
7522
7534
 
7523
7535
  &[data-orientation="horizontal"] {
7524
7536
  width: 100%;
7525
- height: calc(var(--spacing) * 0.75);
7537
+ height: var(--track-size);
7526
7538
  }
7527
7539
  &[data-orientation="vertical"] {
7528
- width: calc(var(--spacing) * 0.75);
7540
+ width: var(--track-size);
7529
7541
  height: 100%;
7530
7542
  }
7531
7543
  }
7532
7544
 
7533
- /* Thumb */
7534
- .media-slider__thumb {
7535
- position: absolute;
7536
- z-index: 10;
7537
- width: var(--thumb-size);
7538
- height: var(--thumb-size);
7539
- user-select: none;
7540
- outline: 2px solid transparent;
7541
- outline-offset: -2px;
7542
- background-color: currentColor;
7543
- border-radius: calc(Infinity * 1px);
7544
- box-shadow:
7545
- 0 0 0 1px var(--shadow-current-color, oklch(0 0 0 / 0.15)),
7546
- 0 1px 3px 0 oklch(0 0 0 / 0.15),
7547
- 0 1px 2px -1px oklch(0 0 0 / 0.15);
7548
- opacity: 0;
7549
- transform-origin: center;
7550
- scale: 0.7;
7551
- translate: -50% -50%;
7552
- transition-timing-function: ease-out;
7553
- transition-duration: 150ms;
7554
-
7555
- &[data-orientation="horizontal"] {
7556
- top: 50%;
7557
- left: var(--media-slider-fill);
7558
- }
7559
- &[data-orientation="vertical"] {
7560
- top: calc(100% - var(--media-slider-fill));
7561
- left: 50%;
7562
- }
7563
-
7564
- &:focus-visible {
7565
- outline-color: var(--focus-ring-color);
7566
- outline-offset: 2px;
7567
- }
7568
- }
7569
-
7570
- &:focus-within .media-slider__thumb,
7571
- .media-slider__thumb--persistent {
7572
- width: var(--thumb-active-size);
7573
- height: var(--thumb-active-size);
7574
- opacity: 1;
7575
- scale: 1;
7576
- }
7577
-
7578
- @media (hover: hover) and (pointer: fine) {
7579
- &:hover .media-slider__thumb {
7580
- width: var(--thumb-active-size);
7581
- height: var(--thumb-active-size);
7582
- opacity: 1;
7583
- scale: 1;
7584
- }
7585
- }
7586
-
7587
7545
  /* Shared track fills */
7588
7546
  .media-slider__buffer,
7589
7547
  .media-slider__fill {
@@ -7595,13 +7553,22 @@ export const { Player } = createPlayer({ features: audioFeatures });
7595
7553
  inset-block: 0;
7596
7554
  left: 0;
7597
7555
  width: 100%;
7598
- transition-property: clip-path;
7599
7556
  }
7600
7557
  &[data-orientation="vertical"] {
7601
7558
  inset-inline: 0;
7602
7559
  bottom: 0;
7603
7560
  height: 100%;
7604
- transition-property: clip-path;
7561
+ }
7562
+
7563
+ @media (prefers-reduced-motion: no-preference) {
7564
+ transition: clip-path 200ms ease-out;
7565
+ }
7566
+ }
7567
+ &[data-dragging],
7568
+ &[data-seeking] {
7569
+ .media-slider__fill,
7570
+ .media-slider__buffer {
7571
+ transition-duration: 0ms;
7605
7572
  }
7606
7573
  }
7607
7574
 
@@ -7628,6 +7595,14 @@ export const { Player } = createPlayer({ features: audioFeatures });
7628
7595
  clip-path: inset(calc(100% - var(--media-slider-fill)) 0 0 0 round var(--track-border-radius));
7629
7596
  }
7630
7597
  }
7598
+ &[data-dragging] {
7599
+ .media-slider__fill[data-orientation="horizontal"] {
7600
+ clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
7601
+ }
7602
+ .media-slider__fill[data-orientation="vertical"] {
7603
+ clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
7604
+ }
7605
+ }
7631
7606
 
7632
7607
  /* Chapters */
7633
7608
  .media-slider__chapters {
@@ -7651,9 +7626,6 @@ export const { Player } = createPlayer({ features: audioFeatures });
7651
7626
  }
7652
7627
 
7653
7628
  .media-slider__chapter {
7654
- --chapter-gap: calc(var(--spacing) * 1);
7655
- --chapter-inset-start: calc(var(--chapter-gap) / 2);
7656
- --chapter-inset-end: calc(var(--chapter-gap) / 2);
7657
7629
  position: absolute;
7658
7630
  inset: 0;
7659
7631
  display: flex;
@@ -7670,8 +7642,6 @@ export const { Player } = createPlayer({ features: audioFeatures });
7670
7642
  }
7671
7643
 
7672
7644
  .media-slider__chapter-track {
7673
- --chapter-track-size: calc(var(--spacing) * 0.75);
7674
- --chapter-track-highlighted-size: calc(var(--spacing) * 1.25);
7675
7645
  border-radius: var(--track-border-radius);
7676
7646
 
7677
7647
  @media (prefers-reduced-motion: no-preference) {
@@ -7684,7 +7654,7 @@ export const { Player } = createPlayer({ features: audioFeatures });
7684
7654
  clip-path: inset(0 calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start));
7685
7655
 
7686
7656
  .media-slider__chapter-track {
7687
- height: var(--chapter-track-size);
7657
+ height: var(--track-size);
7688
7658
  clip-path: inset(
7689
7659
  0 calc(100% - var(--media-slider-chapter-end) + var(--chapter-inset-end)) 0
7690
7660
  calc(var(--media-slider-chapter-start) + var(--chapter-inset-start)) round var(--track-border-radius)
@@ -7692,7 +7662,7 @@ export const { Player } = createPlayer({ features: audioFeatures });
7692
7662
  }
7693
7663
 
7694
7664
  &[data-highlighted] .media-slider__chapter-track {
7695
- height: var(--chapter-track-highlighted-size);
7665
+ height: var(--track-highlighted-size);
7696
7666
  }
7697
7667
  }
7698
7668
 
@@ -7700,7 +7670,7 @@ export const { Player } = createPlayer({ features: audioFeatures });
7700
7670
  clip-path: inset(calc(100% - var(--media-slider-chapter-end)) 0 var(--media-slider-chapter-start) 0);
7701
7671
 
7702
7672
  .media-slider__chapter-track {
7703
- width: var(--chapter-track-size);
7673
+ width: var(--track-size);
7704
7674
  clip-path: inset(
7705
7675
  calc(100% - var(--media-slider-chapter-end) + var(--chapter-inset-end)) 0
7706
7676
  calc(var(--media-slider-chapter-start) + var(--chapter-inset-start)) 0 round var(--track-border-radius)
@@ -7708,63 +7678,102 @@ export const { Player } = createPlayer({ features: audioFeatures });
7708
7678
  }
7709
7679
 
7710
7680
  &[data-highlighted] .media-slider__chapter-track {
7711
- width: var(--chapter-track-highlighted-size);
7681
+ width: var(--track-highlighted-size);
7712
7682
  }
7713
7683
  }
7714
7684
  }
7715
7685
 
7716
- /* Dragging — thumb and fill follow the pointer position */
7717
- &[data-dragging] {
7718
- .media-slider__thumb[data-orientation="horizontal"] {
7719
- left: var(--media-slider-pointer);
7720
- }
7721
- .media-slider__thumb[data-orientation="vertical"] {
7722
- top: calc(100% - var(--media-slider-pointer));
7723
- }
7724
- .media-slider__fill[data-orientation="horizontal"] {
7725
- clip-path: inset(0 calc(100% - var(--media-slider-pointer)) 0 0 round var(--track-border-radius));
7686
+ /* Thumb */
7687
+ .media-slider__thumb {
7688
+ position: absolute;
7689
+ z-index: 10;
7690
+ width: var(--thumb-size);
7691
+ height: var(--thumb-size);
7692
+ user-select: none;
7693
+ outline: 2px solid transparent;
7694
+ outline-offset: -2px;
7695
+ background-color: currentColor;
7696
+ border-radius: calc(Infinity * 1px);
7697
+ box-shadow:
7698
+ 0 0 0 1px var(--shadow-current-color, oklch(0 0 0 / 0.15)),
7699
+ 0 1px 3px 0 oklch(0 0 0 / 0.15),
7700
+ 0 1px 2px -1px oklch(0 0 0 / 0.15);
7701
+ opacity: 0;
7702
+ transform-origin: center;
7703
+ scale: 0.7;
7704
+ translate: -50% -50%;
7705
+
7706
+ &[data-orientation="horizontal"] {
7707
+ top: 50%;
7708
+ left: var(--media-slider-fill);
7726
7709
  }
7727
- .media-slider__fill[data-orientation="vertical"] {
7728
- clip-path: inset(calc(100% - var(--media-slider-pointer)) 0 0 0 round var(--track-border-radius));
7710
+ &[data-orientation="vertical"] {
7711
+ top: calc(100% - var(--media-slider-fill));
7712
+ left: 50%;
7729
7713
  }
7730
- }
7731
7714
 
7732
- @media (prefers-reduced-motion: no-preference) {
7733
- .media-slider__thumb {
7734
- transition-property: opacity, scale, height, width, outline-offset, left, top;
7715
+ &:focus-visible {
7716
+ outline-color: var(--focus-ring-color);
7717
+ outline-offset: 2px;
7735
7718
  }
7736
- .media-slider__fill {
7737
- transition-timing-function: linear;
7738
- transition-duration: 200ms;
7719
+
7720
+ &:focus-visible,
7721
+ &.media-slider__thumb--persistent {
7722
+ opacity: 1;
7723
+ scale: 1;
7739
7724
  }
7740
- .media-slider__buffer {
7725
+
7726
+ @media (prefers-reduced-motion: no-preference) {
7741
7727
  transition-timing-function: ease-out;
7742
- transition-duration: 250ms;
7728
+ transition-duration: 150ms;
7729
+ transition-property: opacity, outline-offset, left, top, scale;
7743
7730
  }
7744
7731
  }
7745
7732
 
7746
- &[data-dragging],
7747
- &[data-seeking] {
7748
- .media-slider__thumb,
7749
- .media-slider__fill,
7750
- .media-slider__buffer {
7751
- transition-duration: 0ms;
7733
+ @media (hover: hover) and (pointer: fine) {
7734
+ &:hover .media-slider__thumb {
7735
+ opacity: 1;
7736
+ scale: 1;
7737
+ }
7738
+ }
7739
+
7740
+ &[data-dragging] .media-slider__thumb {
7741
+ opacity: 1;
7742
+ scale: 0.9;
7743
+
7744
+ @media (prefers-reduced-motion: no-preference) {
7745
+ transition-property: opacity, outline-offset, scale;
7746
+ }
7747
+
7748
+ &[data-orientation="horizontal"] {
7749
+ left: var(--media-slider-pointer);
7750
+ }
7751
+ &[data-orientation="vertical"] {
7752
+ top: calc(100% - var(--media-slider-pointer));
7752
7753
  }
7753
7754
  }
7754
7755
 
7755
7756
  /* Preview */
7756
7757
  .media-slider__preview {
7757
- --max-width: min(calc(var(--spacing) * 48), 100cqi);
7758
- --max-height: calc(var(--spacing) * 32);
7758
+ --max-size-factor: 28;
7759
+ --max-size: min(calc(var(--spacing) * var(--max-size-factor)), 100cqi);
7759
7760
 
7760
7761
  min-width: 100%;
7761
7762
  height: calc(var(--spacing) * 1);
7762
7763
 
7764
+ @container media-root (width > 32rem) {
7765
+ --max-size-factor: 36;
7766
+ }
7767
+
7768
+ @container media-root (width > 42rem) {
7769
+ --max-size-factor: 48;
7770
+ }
7771
+
7763
7772
  .media-slider__thumbnail,
7764
7773
  .media-slider__value {
7765
7774
  position: absolute;
7766
7775
  left: var(--preview-left, var(--media-slider-pointer));
7767
- max-width: var(--max-width);
7776
+ max-width: var(--max-size);
7768
7777
  opacity: 0;
7769
7778
  filter: blur(8px);
7770
7779
  transform-origin: bottom;
@@ -7776,8 +7785,9 @@ export const { Player } = createPlayer({ features: audioFeatures });
7776
7785
  }
7777
7786
 
7778
7787
  .media-slider__thumbnail {
7779
- --thumbnail-max-width: var(--max-width);
7780
- bottom: calc(100% + (var(--spacing) * 12));
7788
+ --thumbnail-max-width: var(--max-size);
7789
+ --thumbnail-max-height: var(--max-size);
7790
+ bottom: calc(100% + (var(--spacing) * 11));
7781
7791
  }
7782
7792
 
7783
7793
  .media-slider__value {