@videojs/react 10.0.0-beta.24 → 10.0.0-beta.25

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 (713) hide show
  1. package/dist/default/icons/dist/react/default/airplay-enter.js +16 -0
  2. package/dist/default/icons/dist/react/default/airplay-enter.js.map +1 -0
  3. package/dist/default/icons/dist/react/default/airplay-exit.js +28 -0
  4. package/dist/default/icons/dist/react/default/airplay-exit.js.map +1 -0
  5. package/dist/default/icons/dist/react/default/captions-off.js +5 -0
  6. package/dist/default/icons/dist/react/default/captions-off.js.map +1 -1
  7. package/dist/default/icons/dist/react/default/gear.js +16 -0
  8. package/dist/default/icons/dist/react/default/gear.js.map +1 -0
  9. package/dist/default/icons/dist/react/default/quality.js +16 -0
  10. package/dist/default/icons/dist/react/default/quality.js.map +1 -0
  11. package/dist/default/icons/dist/react/default/speech.js +19 -0
  12. package/dist/default/icons/dist/react/default/speech.js.map +1 -0
  13. package/dist/default/icons/dist/react/default/speed.js +52 -0
  14. package/dist/default/icons/dist/react/default/speed.js.map +1 -0
  15. package/dist/default/icons/dist/react/default/switches.js +19 -0
  16. package/dist/default/icons/dist/react/default/switches.js.map +1 -0
  17. package/dist/default/icons/dist/react/minimal/airplay-enter.js +16 -0
  18. package/dist/default/icons/dist/react/minimal/airplay-enter.js.map +1 -0
  19. package/dist/default/icons/dist/react/minimal/airplay-exit.js +28 -0
  20. package/dist/default/icons/dist/react/minimal/airplay-exit.js.map +1 -0
  21. package/dist/default/icons/dist/react/minimal/captions-off.js +5 -0
  22. package/dist/default/icons/dist/react/minimal/captions-off.js.map +1 -1
  23. package/dist/default/icons/dist/react/minimal/gear.js +16 -0
  24. package/dist/default/icons/dist/react/minimal/gear.js.map +1 -0
  25. package/dist/default/icons/dist/react/minimal/quality.js +16 -0
  26. package/dist/default/icons/dist/react/minimal/quality.js.map +1 -0
  27. package/dist/default/icons/dist/react/minimal/speech.js +54 -0
  28. package/dist/default/icons/dist/react/minimal/speech.js.map +1 -0
  29. package/dist/default/icons/dist/react/minimal/speed.js +52 -0
  30. package/dist/default/icons/dist/react/minimal/speed.js.map +1 -0
  31. package/dist/default/icons/dist/react/minimal/switches.js +19 -0
  32. package/dist/default/icons/dist/react/minimal/switches.js.map +1 -0
  33. package/dist/default/icons/index.js +8 -1
  34. package/dist/default/icons/minimal/index.js +8 -1
  35. package/dist/default/index.js +21 -17
  36. package/dist/default/media/dash-video/index.js +5 -1
  37. package/dist/default/media/dash-video/index.js.map +1 -1
  38. package/dist/default/media/{hls-video → hlsjs-video}/index.js +9 -5
  39. package/dist/default/media/hlsjs-video/index.js.map +1 -0
  40. package/dist/default/media/mux-audio/index.js +9 -3
  41. package/dist/default/media/mux-audio/index.js.map +1 -1
  42. package/dist/default/media/mux-video/index.js +9 -3
  43. package/dist/default/media/mux-video/index.js.map +1 -1
  44. package/dist/default/media/native-hls-video/index.js +5 -1
  45. package/dist/default/media/native-hls-video/index.js.map +1 -1
  46. package/dist/default/media/simple-hls-audio-only/index.js +22 -0
  47. package/dist/default/media/simple-hls-audio-only/index.js.map +1 -0
  48. package/dist/default/media/simple-hls-video/index.js +1 -1
  49. package/dist/default/media/vimeo-video/index.js +37 -0
  50. package/dist/default/media/vimeo-video/index.js.map +1 -0
  51. package/dist/default/player/context.js.map +1 -1
  52. package/dist/default/player/create-player.js +13 -4
  53. package/dist/default/player/create-player.js.map +1 -1
  54. package/dist/default/presets/audio/minimal-skin.css +414 -69
  55. package/dist/default/presets/audio/minimal-skin.js +69 -39
  56. package/dist/default/presets/audio/minimal-skin.js.map +1 -1
  57. package/dist/default/presets/audio/minimal-skin.tailwind.js +71 -42
  58. package/dist/default/presets/audio/minimal-skin.tailwind.js.map +1 -1
  59. package/dist/default/presets/audio/skin.css +419 -121
  60. package/dist/default/presets/audio/skin.js +70 -40
  61. package/dist/default/presets/audio/skin.js.map +1 -1
  62. package/dist/default/presets/audio/skin.tailwind.js +72 -42
  63. package/dist/default/presets/audio/skin.tailwind.js.map +1 -1
  64. package/dist/default/presets/live-audio/index.js +2 -2
  65. package/dist/default/presets/live-audio/minimal-skin.css +414 -69
  66. package/dist/default/presets/live-audio/minimal-skin.js +26 -12
  67. package/dist/default/presets/live-audio/minimal-skin.js.map +1 -1
  68. package/dist/default/presets/live-audio/minimal-skin.tailwind.js +27 -14
  69. package/dist/default/presets/live-audio/minimal-skin.tailwind.js.map +1 -1
  70. package/dist/default/presets/live-audio/skin.css +419 -121
  71. package/dist/default/presets/live-audio/skin.js +32 -14
  72. package/dist/default/presets/live-audio/skin.js.map +1 -1
  73. package/dist/default/presets/live-audio/skin.tailwind.js +27 -13
  74. package/dist/default/presets/live-audio/skin.tailwind.js.map +1 -1
  75. package/dist/default/presets/live-video/minimal-skin.css +566 -210
  76. package/dist/default/presets/live-video/minimal-skin.js +93 -12
  77. package/dist/default/presets/live-video/minimal-skin.js.map +1 -1
  78. package/dist/default/presets/live-video/minimal-skin.tailwind.js +94 -13
  79. package/dist/default/presets/live-video/minimal-skin.tailwind.js.map +1 -1
  80. package/dist/default/presets/live-video/skin.css +581 -264
  81. package/dist/default/presets/live-video/skin.js +95 -16
  82. package/dist/default/presets/live-video/skin.js.map +1 -1
  83. package/dist/default/presets/live-video/skin.tailwind.js +95 -17
  84. package/dist/default/presets/live-video/skin.tailwind.js.map +1 -1
  85. package/dist/default/presets/video/minimal-skin.css +566 -210
  86. package/dist/default/presets/video/minimal-skin.js +281 -53
  87. package/dist/default/presets/video/minimal-skin.js.map +1 -1
  88. package/dist/default/presets/video/minimal-skin.tailwind.js +284 -57
  89. package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
  90. package/dist/default/presets/video/skin.css +581 -264
  91. package/dist/default/presets/video/skin.js +282 -57
  92. package/dist/default/presets/video/skin.js.map +1 -1
  93. package/dist/default/presets/video/skin.tailwind.js +285 -61
  94. package/dist/default/presets/video/skin.tailwind.js.map +1 -1
  95. package/dist/default/skins/dist/default/default/tailwind/audio.tailwind.js +8 -3
  96. package/dist/default/skins/dist/default/default/tailwind/audio.tailwind.js.map +1 -1
  97. package/dist/default/skins/dist/default/default/tailwind/components/badge.js +6 -0
  98. package/dist/default/skins/dist/default/default/tailwind/components/badge.js.map +1 -0
  99. package/dist/default/skins/dist/default/default/tailwind/components/buffering.js +1 -4
  100. package/dist/default/skins/dist/default/default/tailwind/components/buffering.js.map +1 -1
  101. package/dist/default/skins/dist/default/default/tailwind/components/icon.js +1 -1
  102. package/dist/default/skins/dist/default/default/tailwind/components/icon.js.map +1 -1
  103. package/dist/default/skins/dist/default/default/tailwind/components/input-feedback.js +9 -9
  104. package/dist/default/skins/dist/default/default/tailwind/components/input-feedback.js.map +1 -1
  105. package/dist/default/skins/dist/default/default/tailwind/components/menu.js +26 -4
  106. package/dist/default/skins/dist/default/default/tailwind/components/menu.js.map +1 -1
  107. package/dist/default/skins/dist/default/default/tailwind/components/overlay.js +1 -1
  108. package/dist/default/skins/dist/default/default/tailwind/components/overlay.js.map +1 -1
  109. package/dist/default/skins/dist/default/default/tailwind/components/popup.js +4 -3
  110. package/dist/default/skins/dist/default/default/tailwind/components/popup.js.map +1 -1
  111. package/dist/default/skins/dist/default/default/tailwind/components/poster.js +7 -1
  112. package/dist/default/skins/dist/default/default/tailwind/components/poster.js.map +1 -1
  113. package/dist/default/skins/dist/default/default/tailwind/components/root.js +1 -1
  114. package/dist/default/skins/dist/default/default/tailwind/components/root.js.map +1 -1
  115. package/dist/default/skins/dist/default/default/tailwind/components/seek.js +1 -1
  116. package/dist/default/skins/dist/default/default/tailwind/components/seek.js.map +1 -1
  117. package/dist/default/skins/dist/default/default/tailwind/components/slider.js +5 -3
  118. package/dist/default/skins/dist/default/default/tailwind/components/slider.js.map +1 -1
  119. package/dist/default/skins/dist/default/default/tailwind/components/thumbnail.js +12 -0
  120. package/dist/default/skins/dist/default/default/tailwind/components/thumbnail.js.map +1 -0
  121. package/dist/default/skins/dist/default/default/tailwind/components/time.js +1 -1
  122. package/dist/default/skins/dist/default/default/tailwind/components/time.js.map +1 -1
  123. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js +26 -13
  124. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  125. package/dist/default/skins/dist/default/minimal/tailwind/audio.tailwind.js +13 -3
  126. package/dist/default/skins/dist/default/minimal/tailwind/audio.tailwind.js.map +1 -1
  127. package/dist/default/skins/dist/default/minimal/tailwind/components/badge.js +6 -0
  128. package/dist/default/skins/dist/default/minimal/tailwind/components/badge.js.map +1 -0
  129. package/dist/default/skins/dist/default/minimal/tailwind/components/buffering.js +1 -1
  130. package/dist/default/skins/dist/default/minimal/tailwind/components/buffering.js.map +1 -1
  131. package/dist/default/skins/dist/default/minimal/tailwind/components/icon.js +1 -1
  132. package/dist/default/skins/dist/default/minimal/tailwind/components/icon.js.map +1 -1
  133. package/dist/default/skins/dist/default/minimal/tailwind/components/input-feedback.js +9 -9
  134. package/dist/default/skins/dist/default/minimal/tailwind/components/input-feedback.js.map +1 -1
  135. package/dist/default/skins/dist/default/minimal/tailwind/components/menu.js +25 -4
  136. package/dist/default/skins/dist/default/minimal/tailwind/components/menu.js.map +1 -1
  137. package/dist/default/skins/dist/default/minimal/tailwind/components/overlay.js +1 -1
  138. package/dist/default/skins/dist/default/minimal/tailwind/components/overlay.js.map +1 -1
  139. package/dist/default/skins/dist/default/minimal/tailwind/components/popup.js +3 -2
  140. package/dist/default/skins/dist/default/minimal/tailwind/components/popup.js.map +1 -1
  141. package/dist/default/skins/dist/default/minimal/tailwind/components/poster.js +7 -1
  142. package/dist/default/skins/dist/default/minimal/tailwind/components/poster.js.map +1 -1
  143. package/dist/default/skins/dist/default/minimal/tailwind/components/root.js +1 -1
  144. package/dist/default/skins/dist/default/minimal/tailwind/components/root.js.map +1 -1
  145. package/dist/default/skins/dist/default/minimal/tailwind/components/seek.js +1 -1
  146. package/dist/default/skins/dist/default/minimal/tailwind/components/seek.js.map +1 -1
  147. package/dist/default/skins/dist/default/minimal/tailwind/components/slider.js +5 -3
  148. package/dist/default/skins/dist/default/minimal/tailwind/components/slider.js.map +1 -1
  149. package/dist/default/skins/dist/default/minimal/tailwind/components/thumbnail.js +13 -0
  150. package/dist/default/skins/dist/default/minimal/tailwind/components/thumbnail.js.map +1 -0
  151. package/dist/default/skins/dist/default/minimal/tailwind/components/time.js +1 -1
  152. package/dist/default/skins/dist/default/minimal/tailwind/components/time.js.map +1 -1
  153. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js +27 -11
  154. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  155. package/dist/default/skins/dist/default/shared/tailwind/icon-state.js +17 -2
  156. package/dist/default/skins/dist/default/shared/tailwind/icon-state.js.map +1 -1
  157. package/dist/default/tailwind.css +0 -24
  158. package/dist/default/ui/airplay-button/airplay-button.js +17 -0
  159. package/dist/default/ui/airplay-button/airplay-button.js.map +1 -0
  160. package/dist/default/ui/airplay-button/index.js +2 -0
  161. package/dist/default/ui/alert-dialog/alert-dialog-close.js +1 -1
  162. package/dist/default/ui/alert-dialog/alert-dialog-popup.js +1 -1
  163. package/dist/default/ui/audio-track/index.js +2 -0
  164. package/dist/default/ui/audio-track/use-audio-track-options.js +31 -0
  165. package/dist/default/ui/audio-track/use-audio-track-options.js.map +1 -0
  166. package/dist/default/ui/captions-radio-group/index.js +2 -0
  167. package/dist/default/ui/captions-radio-group/use-captions-options.js +37 -0
  168. package/dist/default/ui/captions-radio-group/use-captions-options.js.map +1 -0
  169. package/dist/default/ui/create-media-button.js +23 -10
  170. package/dist/default/ui/create-media-button.js.map +1 -1
  171. package/dist/default/ui/error-dialog/error-dialog-description.js +1 -1
  172. package/dist/default/ui/hooks/use-button.js.map +1 -1
  173. package/dist/default/ui/hotkey/use-hotkey-shortcut.js +28 -0
  174. package/dist/default/ui/hotkey/use-hotkey-shortcut.js.map +1 -0
  175. package/dist/default/ui/hotkey/use-hotkey.js +1 -2
  176. package/dist/default/ui/hotkey/use-hotkey.js.map +1 -1
  177. package/dist/default/ui/input-indicators/use-input-indicator-root.js +2 -2
  178. package/dist/default/ui/input-indicators/use-input-indicator-root.js.map +1 -1
  179. package/dist/default/ui/input-indicators/use-rendered-indicator-state.js +7 -4
  180. package/dist/default/ui/input-indicators/use-rendered-indicator-state.js.map +1 -1
  181. package/dist/default/ui/live-button/live-button.js +1 -1
  182. package/dist/default/ui/live-button/live-button.js.map +1 -1
  183. package/dist/default/ui/menu/context.js +16 -1
  184. package/dist/default/ui/menu/context.js.map +1 -1
  185. package/dist/default/ui/menu/index.parts.js +4 -2
  186. package/dist/default/ui/menu/index.parts.js.map +1 -1
  187. package/dist/default/ui/menu/menu-back.js +0 -1
  188. package/dist/default/ui/menu/menu-back.js.map +1 -1
  189. package/dist/default/ui/menu/menu-checkbox-item.js +1 -2
  190. package/dist/default/ui/menu/menu-checkbox-item.js.map +1 -1
  191. package/dist/default/ui/menu/menu-content.js +23 -5
  192. package/dist/default/ui/menu/menu-content.js.map +1 -1
  193. package/dist/default/ui/menu/menu-group-label.js +29 -0
  194. package/dist/default/ui/menu/menu-group-label.js.map +1 -0
  195. package/dist/default/ui/menu/menu-group.js +7 -9
  196. package/dist/default/ui/menu/menu-group.js.map +1 -1
  197. package/dist/default/ui/menu/menu-item-indicator.js +1 -2
  198. package/dist/default/ui/menu/menu-item-indicator.js.map +1 -1
  199. package/dist/default/ui/menu/menu-item-setting-provider.js +72 -0
  200. package/dist/default/ui/menu/menu-item-setting-provider.js.map +1 -0
  201. package/dist/default/ui/menu/menu-item-value.js +28 -0
  202. package/dist/default/ui/menu/menu-item-value.js.map +1 -0
  203. package/dist/default/ui/menu/menu-item.js +44 -23
  204. package/dist/default/ui/menu/menu-item.js.map +1 -1
  205. package/dist/default/ui/menu/menu-radio-group.js +6 -9
  206. package/dist/default/ui/menu/menu-radio-group.js.map +1 -1
  207. package/dist/default/ui/menu/menu-radio-item.js +1 -2
  208. package/dist/default/ui/menu/menu-radio-item.js.map +1 -1
  209. package/dist/default/ui/menu/menu-root.js +1 -1
  210. package/dist/default/ui/menu/menu-separator.js +1 -2
  211. package/dist/default/ui/menu/menu-separator.js.map +1 -1
  212. package/dist/default/ui/menu/menu-trigger.js +85 -29
  213. package/dist/default/ui/menu/menu-trigger.js.map +1 -1
  214. package/dist/default/ui/menu/use-menu-group.js +31 -0
  215. package/dist/default/ui/menu/use-menu-group.js.map +1 -0
  216. package/dist/default/ui/playback-rate/index.js +2 -0
  217. package/dist/default/ui/playback-rate/use-playback-rate-options.js +34 -0
  218. package/dist/default/ui/playback-rate/use-playback-rate-options.js.map +1 -0
  219. package/dist/default/ui/playback-rate-button/playback-rate-button.js +2 -1
  220. package/dist/default/ui/playback-rate-button/playback-rate-button.js.map +1 -1
  221. package/dist/default/ui/poster/poster.js +17 -3
  222. package/dist/default/ui/poster/poster.js.map +1 -1
  223. package/dist/default/ui/quality/index.js +2 -0
  224. package/dist/default/ui/quality/use-quality-options.js +37 -0
  225. package/dist/default/ui/quality/use-quality-options.js.map +1 -0
  226. package/dist/default/ui/seek-button/seek-button.js +3 -1
  227. package/dist/default/ui/seek-button/seek-button.js.map +1 -1
  228. package/dist/default/ui/time/time-value.js +32 -5
  229. package/dist/default/ui/time/time-value.js.map +1 -1
  230. package/dist/default/ui/time-slider/time-slider-root.js +18 -6
  231. package/dist/default/ui/time-slider/time-slider-root.js.map +1 -1
  232. package/dist/default/ui/tooltip/context.js.map +1 -1
  233. package/dist/default/ui/tooltip/index.parts.js +4 -0
  234. package/dist/default/ui/tooltip/index.parts.js.map +1 -1
  235. package/dist/default/ui/tooltip/tooltip-arrow.js +1 -1
  236. package/dist/default/ui/tooltip/tooltip-label.js +24 -0
  237. package/dist/default/ui/tooltip/tooltip-label.js.map +1 -0
  238. package/dist/default/ui/tooltip/tooltip-popup.js +7 -3
  239. package/dist/default/ui/tooltip/tooltip-popup.js.map +1 -1
  240. package/dist/default/ui/tooltip/tooltip-root.js +1 -1
  241. package/dist/default/ui/tooltip/tooltip-root.js.map +1 -1
  242. package/dist/default/ui/tooltip/tooltip-shortcut.js +25 -0
  243. package/dist/default/ui/tooltip/tooltip-shortcut.js.map +1 -0
  244. package/dist/default/ui/volume-indicator/volume-indicator-root.js +1 -1
  245. package/dist/default/ui/volume-indicator/volume-indicator-root.js.map +1 -1
  246. package/dist/default/utils/use-attach-iframe.js +14 -0
  247. package/dist/default/utils/use-attach-iframe.js.map +1 -0
  248. package/dist/default/utils/use-media-instance.js +11 -3
  249. package/dist/default/utils/use-media-instance.js.map +1 -1
  250. package/dist/default/utils/use-render.js +1 -1
  251. package/dist/default/utils/use-render.js.map +1 -1
  252. package/dist/dev/icons/dist/react/default/airplay-enter.js +16 -0
  253. package/dist/dev/icons/dist/react/default/airplay-enter.js.map +1 -0
  254. package/dist/dev/icons/dist/react/default/airplay-exit.js +28 -0
  255. package/dist/dev/icons/dist/react/default/airplay-exit.js.map +1 -0
  256. package/dist/dev/icons/dist/react/default/captions-off.js +5 -0
  257. package/dist/dev/icons/dist/react/default/captions-off.js.map +1 -1
  258. package/dist/dev/icons/dist/react/default/gear.js +16 -0
  259. package/dist/dev/icons/dist/react/default/gear.js.map +1 -0
  260. package/dist/dev/icons/dist/react/default/index.d.ts +8 -1
  261. package/dist/dev/icons/dist/react/default/index.d.ts.map +1 -1
  262. package/dist/dev/icons/dist/react/default/quality.js +16 -0
  263. package/dist/dev/icons/dist/react/default/quality.js.map +1 -0
  264. package/dist/dev/icons/dist/react/default/speech.js +19 -0
  265. package/dist/dev/icons/dist/react/default/speech.js.map +1 -0
  266. package/dist/dev/icons/dist/react/default/speed.js +52 -0
  267. package/dist/dev/icons/dist/react/default/speed.js.map +1 -0
  268. package/dist/dev/icons/dist/react/default/switches.js +19 -0
  269. package/dist/dev/icons/dist/react/default/switches.js.map +1 -0
  270. package/dist/dev/icons/dist/react/minimal/airplay-enter.js +16 -0
  271. package/dist/dev/icons/dist/react/minimal/airplay-enter.js.map +1 -0
  272. package/dist/dev/icons/dist/react/minimal/airplay-exit.js +28 -0
  273. package/dist/dev/icons/dist/react/minimal/airplay-exit.js.map +1 -0
  274. package/dist/dev/icons/dist/react/minimal/captions-off.js +5 -0
  275. package/dist/dev/icons/dist/react/minimal/captions-off.js.map +1 -1
  276. package/dist/dev/icons/dist/react/minimal/gear.js +16 -0
  277. package/dist/dev/icons/dist/react/minimal/gear.js.map +1 -0
  278. package/dist/dev/icons/dist/react/minimal/index.d.ts +8 -1
  279. package/dist/dev/icons/dist/react/minimal/index.d.ts.map +1 -1
  280. package/dist/dev/icons/dist/react/minimal/quality.js +16 -0
  281. package/dist/dev/icons/dist/react/minimal/quality.js.map +1 -0
  282. package/dist/dev/icons/dist/react/minimal/speech.js +54 -0
  283. package/dist/dev/icons/dist/react/minimal/speech.js.map +1 -0
  284. package/dist/dev/icons/dist/react/minimal/speed.js +52 -0
  285. package/dist/dev/icons/dist/react/minimal/speed.js.map +1 -0
  286. package/dist/dev/icons/dist/react/minimal/switches.js +19 -0
  287. package/dist/dev/icons/dist/react/minimal/switches.js.map +1 -0
  288. package/dist/dev/icons/index.d.ts +2 -2
  289. package/dist/dev/icons/index.js +8 -1
  290. package/dist/dev/icons/minimal/index.d.ts +2 -2
  291. package/dist/dev/icons/minimal/index.js +8 -1
  292. package/dist/dev/index.d.ts +19 -15
  293. package/dist/dev/index.js +21 -17
  294. package/dist/dev/media/dash-video/index.d.ts.map +1 -1
  295. package/dist/dev/media/dash-video/index.js +5 -1
  296. package/dist/dev/media/dash-video/index.js.map +1 -1
  297. package/dist/dev/media/hlsjs-video/index.d.ts +15 -0
  298. package/dist/dev/media/hlsjs-video/index.d.ts.map +1 -0
  299. package/dist/dev/media/{hls-video → hlsjs-video}/index.js +9 -5
  300. package/dist/dev/media/hlsjs-video/index.js.map +1 -0
  301. package/dist/dev/media/mux-audio/index.d.ts +2 -2
  302. package/dist/dev/media/mux-audio/index.d.ts.map +1 -1
  303. package/dist/dev/media/mux-audio/index.js +9 -3
  304. package/dist/dev/media/mux-audio/index.js.map +1 -1
  305. package/dist/dev/media/mux-video/index.d.ts +2 -2
  306. package/dist/dev/media/mux-video/index.d.ts.map +1 -1
  307. package/dist/dev/media/mux-video/index.js +9 -3
  308. package/dist/dev/media/mux-video/index.js.map +1 -1
  309. package/dist/dev/media/native-hls-video/index.d.ts.map +1 -1
  310. package/dist/dev/media/native-hls-video/index.js +5 -1
  311. package/dist/dev/media/native-hls-video/index.js.map +1 -1
  312. package/dist/dev/media/simple-hls-audio-only/index.d.ts +15 -0
  313. package/dist/dev/media/simple-hls-audio-only/index.d.ts.map +1 -0
  314. package/dist/dev/media/simple-hls-audio-only/index.js +22 -0
  315. package/dist/dev/media/simple-hls-audio-only/index.js.map +1 -0
  316. package/dist/dev/media/simple-hls-video/index.js +1 -1
  317. package/dist/dev/media/vimeo-video/index.d.ts +15 -0
  318. package/dist/dev/media/vimeo-video/index.d.ts.map +1 -0
  319. package/dist/dev/media/vimeo-video/index.js +37 -0
  320. package/dist/dev/media/vimeo-video/index.js.map +1 -0
  321. package/dist/dev/player/context.d.ts +8 -0
  322. package/dist/dev/player/context.d.ts.map +1 -1
  323. package/dist/dev/player/context.js.map +1 -1
  324. package/dist/dev/player/create-player.js +13 -4
  325. package/dist/dev/player/create-player.js.map +1 -1
  326. package/dist/dev/presets/audio/minimal-skin.css +414 -69
  327. package/dist/dev/presets/audio/minimal-skin.d.ts.map +1 -1
  328. package/dist/dev/presets/audio/minimal-skin.js +69 -39
  329. package/dist/dev/presets/audio/minimal-skin.js.map +1 -1
  330. package/dist/dev/presets/audio/minimal-skin.tailwind.d.ts.map +1 -1
  331. package/dist/dev/presets/audio/minimal-skin.tailwind.js +71 -42
  332. package/dist/dev/presets/audio/minimal-skin.tailwind.js.map +1 -1
  333. package/dist/dev/presets/audio/skin.css +419 -121
  334. package/dist/dev/presets/audio/skin.d.ts.map +1 -1
  335. package/dist/dev/presets/audio/skin.js +70 -40
  336. package/dist/dev/presets/audio/skin.js.map +1 -1
  337. package/dist/dev/presets/audio/skin.tailwind.d.ts.map +1 -1
  338. package/dist/dev/presets/audio/skin.tailwind.js +72 -42
  339. package/dist/dev/presets/audio/skin.tailwind.js.map +1 -1
  340. package/dist/dev/presets/live-audio/index.d.ts +2 -2
  341. package/dist/dev/presets/live-audio/index.js +2 -2
  342. package/dist/dev/presets/live-audio/minimal-skin.css +414 -69
  343. package/dist/dev/presets/live-audio/minimal-skin.d.ts.map +1 -1
  344. package/dist/dev/presets/live-audio/minimal-skin.js +26 -12
  345. package/dist/dev/presets/live-audio/minimal-skin.js.map +1 -1
  346. package/dist/dev/presets/live-audio/minimal-skin.tailwind.d.ts.map +1 -1
  347. package/dist/dev/presets/live-audio/minimal-skin.tailwind.js +27 -14
  348. package/dist/dev/presets/live-audio/minimal-skin.tailwind.js.map +1 -1
  349. package/dist/dev/presets/live-audio/skin.css +419 -121
  350. package/dist/dev/presets/live-audio/skin.d.ts +3 -1
  351. package/dist/dev/presets/live-audio/skin.d.ts.map +1 -1
  352. package/dist/dev/presets/live-audio/skin.js +32 -14
  353. package/dist/dev/presets/live-audio/skin.js.map +1 -1
  354. package/dist/dev/presets/live-audio/skin.tailwind.d.ts.map +1 -1
  355. package/dist/dev/presets/live-audio/skin.tailwind.js +27 -13
  356. package/dist/dev/presets/live-audio/skin.tailwind.js.map +1 -1
  357. package/dist/dev/presets/live-video/minimal-skin.css +566 -210
  358. package/dist/dev/presets/live-video/minimal-skin.d.ts +0 -7
  359. package/dist/dev/presets/live-video/minimal-skin.d.ts.map +1 -1
  360. package/dist/dev/presets/live-video/minimal-skin.js +93 -12
  361. package/dist/dev/presets/live-video/minimal-skin.js.map +1 -1
  362. package/dist/dev/presets/live-video/minimal-skin.tailwind.d.ts.map +1 -1
  363. package/dist/dev/presets/live-video/minimal-skin.tailwind.js +94 -13
  364. package/dist/dev/presets/live-video/minimal-skin.tailwind.js.map +1 -1
  365. package/dist/dev/presets/live-video/skin.css +581 -264
  366. package/dist/dev/presets/live-video/skin.d.ts +0 -6
  367. package/dist/dev/presets/live-video/skin.d.ts.map +1 -1
  368. package/dist/dev/presets/live-video/skin.js +95 -16
  369. package/dist/dev/presets/live-video/skin.js.map +1 -1
  370. package/dist/dev/presets/live-video/skin.tailwind.d.ts.map +1 -1
  371. package/dist/dev/presets/live-video/skin.tailwind.js +95 -17
  372. package/dist/dev/presets/live-video/skin.tailwind.js.map +1 -1
  373. package/dist/dev/presets/types.d.ts +2 -1
  374. package/dist/dev/presets/types.d.ts.map +1 -1
  375. package/dist/dev/presets/video/minimal-skin.css +566 -210
  376. package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
  377. package/dist/dev/presets/video/minimal-skin.js +281 -53
  378. package/dist/dev/presets/video/minimal-skin.js.map +1 -1
  379. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
  380. package/dist/dev/presets/video/minimal-skin.tailwind.js +284 -57
  381. package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
  382. package/dist/dev/presets/video/skin.css +581 -264
  383. package/dist/dev/presets/video/skin.d.ts.map +1 -1
  384. package/dist/dev/presets/video/skin.js +282 -57
  385. package/dist/dev/presets/video/skin.js.map +1 -1
  386. package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
  387. package/dist/dev/presets/video/skin.tailwind.js +285 -61
  388. package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
  389. package/dist/dev/skins/dist/default/default/tailwind/audio.tailwind.js +8 -3
  390. package/dist/dev/skins/dist/default/default/tailwind/audio.tailwind.js.map +1 -1
  391. package/dist/dev/skins/dist/default/default/tailwind/components/badge.js +6 -0
  392. package/dist/dev/skins/dist/default/default/tailwind/components/badge.js.map +1 -0
  393. package/dist/dev/skins/dist/default/default/tailwind/components/buffering.js +1 -4
  394. package/dist/dev/skins/dist/default/default/tailwind/components/buffering.js.map +1 -1
  395. package/dist/dev/skins/dist/default/default/tailwind/components/icon.js +1 -1
  396. package/dist/dev/skins/dist/default/default/tailwind/components/icon.js.map +1 -1
  397. package/dist/dev/skins/dist/default/default/tailwind/components/input-feedback.js +9 -9
  398. package/dist/dev/skins/dist/default/default/tailwind/components/input-feedback.js.map +1 -1
  399. package/dist/dev/skins/dist/default/default/tailwind/components/menu.js +26 -4
  400. package/dist/dev/skins/dist/default/default/tailwind/components/menu.js.map +1 -1
  401. package/dist/dev/skins/dist/default/default/tailwind/components/overlay.js +1 -1
  402. package/dist/dev/skins/dist/default/default/tailwind/components/overlay.js.map +1 -1
  403. package/dist/dev/skins/dist/default/default/tailwind/components/popup.js +4 -3
  404. package/dist/dev/skins/dist/default/default/tailwind/components/popup.js.map +1 -1
  405. package/dist/dev/skins/dist/default/default/tailwind/components/poster.js +7 -1
  406. package/dist/dev/skins/dist/default/default/tailwind/components/poster.js.map +1 -1
  407. package/dist/dev/skins/dist/default/default/tailwind/components/root.js +1 -1
  408. package/dist/dev/skins/dist/default/default/tailwind/components/root.js.map +1 -1
  409. package/dist/dev/skins/dist/default/default/tailwind/components/seek.js +1 -1
  410. package/dist/dev/skins/dist/default/default/tailwind/components/seek.js.map +1 -1
  411. package/dist/dev/skins/dist/default/default/tailwind/components/slider.js +5 -3
  412. package/dist/dev/skins/dist/default/default/tailwind/components/slider.js.map +1 -1
  413. package/dist/dev/skins/dist/default/default/tailwind/components/thumbnail.js +12 -0
  414. package/dist/dev/skins/dist/default/default/tailwind/components/thumbnail.js.map +1 -0
  415. package/dist/dev/skins/dist/default/default/tailwind/components/time.js +1 -1
  416. package/dist/dev/skins/dist/default/default/tailwind/components/time.js.map +1 -1
  417. package/dist/dev/skins/dist/default/default/tailwind/video.tailwind.js +26 -13
  418. package/dist/dev/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  419. package/dist/dev/skins/dist/default/minimal/tailwind/audio.tailwind.js +13 -3
  420. package/dist/dev/skins/dist/default/minimal/tailwind/audio.tailwind.js.map +1 -1
  421. package/dist/dev/skins/dist/default/minimal/tailwind/components/badge.js +6 -0
  422. package/dist/dev/skins/dist/default/minimal/tailwind/components/badge.js.map +1 -0
  423. package/dist/dev/skins/dist/default/minimal/tailwind/components/buffering.js +1 -1
  424. package/dist/dev/skins/dist/default/minimal/tailwind/components/buffering.js.map +1 -1
  425. package/dist/dev/skins/dist/default/minimal/tailwind/components/icon.js +1 -1
  426. package/dist/dev/skins/dist/default/minimal/tailwind/components/icon.js.map +1 -1
  427. package/dist/dev/skins/dist/default/minimal/tailwind/components/input-feedback.js +9 -9
  428. package/dist/dev/skins/dist/default/minimal/tailwind/components/input-feedback.js.map +1 -1
  429. package/dist/dev/skins/dist/default/minimal/tailwind/components/menu.js +25 -4
  430. package/dist/dev/skins/dist/default/minimal/tailwind/components/menu.js.map +1 -1
  431. package/dist/dev/skins/dist/default/minimal/tailwind/components/overlay.js +1 -1
  432. package/dist/dev/skins/dist/default/minimal/tailwind/components/overlay.js.map +1 -1
  433. package/dist/dev/skins/dist/default/minimal/tailwind/components/popup.js +3 -2
  434. package/dist/dev/skins/dist/default/minimal/tailwind/components/popup.js.map +1 -1
  435. package/dist/dev/skins/dist/default/minimal/tailwind/components/poster.js +7 -1
  436. package/dist/dev/skins/dist/default/minimal/tailwind/components/poster.js.map +1 -1
  437. package/dist/dev/skins/dist/default/minimal/tailwind/components/root.js +1 -1
  438. package/dist/dev/skins/dist/default/minimal/tailwind/components/root.js.map +1 -1
  439. package/dist/dev/skins/dist/default/minimal/tailwind/components/seek.js +1 -1
  440. package/dist/dev/skins/dist/default/minimal/tailwind/components/seek.js.map +1 -1
  441. package/dist/dev/skins/dist/default/minimal/tailwind/components/slider.js +5 -3
  442. package/dist/dev/skins/dist/default/minimal/tailwind/components/slider.js.map +1 -1
  443. package/dist/dev/skins/dist/default/minimal/tailwind/components/thumbnail.js +13 -0
  444. package/dist/dev/skins/dist/default/minimal/tailwind/components/thumbnail.js.map +1 -0
  445. package/dist/dev/skins/dist/default/minimal/tailwind/components/time.js +1 -1
  446. package/dist/dev/skins/dist/default/minimal/tailwind/components/time.js.map +1 -1
  447. package/dist/dev/skins/dist/default/minimal/tailwind/video.tailwind.js +27 -11
  448. package/dist/dev/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  449. package/dist/dev/skins/dist/default/shared/tailwind/icon-state.js +17 -2
  450. package/dist/dev/skins/dist/default/shared/tailwind/icon-state.js.map +1 -1
  451. package/dist/dev/tailwind.css +0 -24
  452. package/dist/dev/ui/airplay-button/airplay-button.d.ts +15 -0
  453. package/dist/dev/ui/airplay-button/airplay-button.d.ts.map +1 -0
  454. package/dist/dev/ui/airplay-button/airplay-button.js +17 -0
  455. package/dist/dev/ui/airplay-button/airplay-button.js.map +1 -0
  456. package/dist/dev/ui/airplay-button/index.d.ts +2 -0
  457. package/dist/dev/ui/airplay-button/index.js +2 -0
  458. package/dist/dev/ui/alert-dialog/alert-dialog-close.js +1 -1
  459. package/dist/dev/ui/alert-dialog/alert-dialog-popup.js +1 -1
  460. package/dist/dev/ui/audio-track/index.d.ts +2 -0
  461. package/dist/dev/ui/audio-track/index.js +2 -0
  462. package/dist/dev/ui/audio-track/use-audio-track-options.d.ts +25 -0
  463. package/dist/dev/ui/audio-track/use-audio-track-options.d.ts.map +1 -0
  464. package/dist/dev/ui/audio-track/use-audio-track-options.js +34 -0
  465. package/dist/dev/ui/audio-track/use-audio-track-options.js.map +1 -0
  466. package/dist/dev/ui/captions-radio-group/index.d.ts +2 -0
  467. package/dist/dev/ui/captions-radio-group/index.js +2 -0
  468. package/dist/dev/ui/captions-radio-group/use-captions-options.d.ts +26 -0
  469. package/dist/dev/ui/captions-radio-group/use-captions-options.d.ts.map +1 -0
  470. package/dist/dev/ui/captions-radio-group/use-captions-options.js +40 -0
  471. package/dist/dev/ui/captions-radio-group/use-captions-options.js.map +1 -0
  472. package/dist/dev/ui/create-media-button.js +23 -10
  473. package/dist/dev/ui/create-media-button.js.map +1 -1
  474. package/dist/dev/ui/error-dialog/error-dialog-description.js +1 -1
  475. package/dist/dev/ui/hooks/use-button.d.ts +2 -1
  476. package/dist/dev/ui/hooks/use-button.d.ts.map +1 -1
  477. package/dist/dev/ui/hooks/use-button.js.map +1 -1
  478. package/dist/dev/ui/hotkey/use-hotkey-shortcut.d.ts +7 -0
  479. package/dist/dev/ui/hotkey/use-hotkey-shortcut.d.ts.map +1 -0
  480. package/dist/dev/ui/hotkey/use-hotkey-shortcut.js +28 -0
  481. package/dist/dev/ui/hotkey/use-hotkey-shortcut.js.map +1 -0
  482. package/dist/dev/ui/hotkey/use-hotkey.js +1 -2
  483. package/dist/dev/ui/hotkey/use-hotkey.js.map +1 -1
  484. package/dist/dev/ui/input-indicators/use-input-indicator-root.js +2 -2
  485. package/dist/dev/ui/input-indicators/use-input-indicator-root.js.map +1 -1
  486. package/dist/dev/ui/input-indicators/use-rendered-indicator-state.js +7 -4
  487. package/dist/dev/ui/input-indicators/use-rendered-indicator-state.js.map +1 -1
  488. package/dist/dev/ui/live-button/live-button.js +1 -1
  489. package/dist/dev/ui/live-button/live-button.js.map +1 -1
  490. package/dist/dev/ui/menu/context.d.ts.map +1 -1
  491. package/dist/dev/ui/menu/context.js +16 -1
  492. package/dist/dev/ui/menu/context.js.map +1 -1
  493. package/dist/dev/ui/menu/index.parts.d.ts +3 -2
  494. package/dist/dev/ui/menu/index.parts.js +4 -2
  495. package/dist/dev/ui/menu/index.parts.js.map +1 -1
  496. package/dist/dev/ui/menu/menu-back.d.ts.map +1 -1
  497. package/dist/dev/ui/menu/menu-back.js +0 -1
  498. package/dist/dev/ui/menu/menu-back.js.map +1 -1
  499. package/dist/dev/ui/menu/menu-checkbox-item.d.ts.map +1 -1
  500. package/dist/dev/ui/menu/menu-checkbox-item.js +1 -2
  501. package/dist/dev/ui/menu/menu-checkbox-item.js.map +1 -1
  502. package/dist/dev/ui/menu/menu-content.d.ts.map +1 -1
  503. package/dist/dev/ui/menu/menu-content.js +23 -5
  504. package/dist/dev/ui/menu/menu-content.js.map +1 -1
  505. package/dist/dev/ui/menu/menu-group-label.d.ts +15 -0
  506. package/dist/dev/ui/menu/menu-group-label.d.ts.map +1 -0
  507. package/dist/dev/ui/menu/menu-group-label.js +29 -0
  508. package/dist/dev/ui/menu/menu-group-label.js.map +1 -0
  509. package/dist/dev/ui/menu/menu-group.d.ts +1 -4
  510. package/dist/dev/ui/menu/menu-group.d.ts.map +1 -1
  511. package/dist/dev/ui/menu/menu-group.js +7 -9
  512. package/dist/dev/ui/menu/menu-group.js.map +1 -1
  513. package/dist/dev/ui/menu/menu-item-indicator.d.ts.map +1 -1
  514. package/dist/dev/ui/menu/menu-item-indicator.js +1 -2
  515. package/dist/dev/ui/menu/menu-item-indicator.js.map +1 -1
  516. package/dist/dev/ui/menu/menu-item-setting-provider.js +72 -0
  517. package/dist/dev/ui/menu/menu-item-setting-provider.js.map +1 -0
  518. package/dist/dev/ui/menu/menu-item-type.d.ts +5 -0
  519. package/dist/dev/ui/menu/menu-item-type.d.ts.map +1 -0
  520. package/dist/dev/ui/menu/menu-item-value.d.ts +14 -0
  521. package/dist/dev/ui/menu/menu-item-value.d.ts.map +1 -0
  522. package/dist/dev/ui/menu/menu-item-value.js +28 -0
  523. package/dist/dev/ui/menu/menu-item-value.js.map +1 -0
  524. package/dist/dev/ui/menu/menu-item.d.ts +3 -0
  525. package/dist/dev/ui/menu/menu-item.d.ts.map +1 -1
  526. package/dist/dev/ui/menu/menu-item.js +44 -23
  527. package/dist/dev/ui/menu/menu-item.js.map +1 -1
  528. package/dist/dev/ui/menu/menu-radio-group.d.ts +0 -2
  529. package/dist/dev/ui/menu/menu-radio-group.d.ts.map +1 -1
  530. package/dist/dev/ui/menu/menu-radio-group.js +6 -9
  531. package/dist/dev/ui/menu/menu-radio-group.js.map +1 -1
  532. package/dist/dev/ui/menu/menu-radio-item.d.ts.map +1 -1
  533. package/dist/dev/ui/menu/menu-radio-item.js +1 -2
  534. package/dist/dev/ui/menu/menu-radio-item.js.map +1 -1
  535. package/dist/dev/ui/menu/menu-root.js +1 -1
  536. package/dist/dev/ui/menu/menu-separator.d.ts.map +1 -1
  537. package/dist/dev/ui/menu/menu-separator.js +1 -2
  538. package/dist/dev/ui/menu/menu-separator.js.map +1 -1
  539. package/dist/dev/ui/menu/menu-trigger.d.ts +5 -2
  540. package/dist/dev/ui/menu/menu-trigger.d.ts.map +1 -1
  541. package/dist/dev/ui/menu/menu-trigger.js +85 -29
  542. package/dist/dev/ui/menu/menu-trigger.js.map +1 -1
  543. package/dist/dev/ui/menu/use-menu-group.js +31 -0
  544. package/dist/dev/ui/menu/use-menu-group.js.map +1 -0
  545. package/dist/dev/ui/playback-rate/index.d.ts +2 -0
  546. package/dist/dev/ui/playback-rate/index.js +2 -0
  547. package/dist/dev/ui/playback-rate/use-playback-rate-options.d.ts +28 -0
  548. package/dist/dev/ui/playback-rate/use-playback-rate-options.d.ts.map +1 -0
  549. package/dist/dev/ui/playback-rate/use-playback-rate-options.js +37 -0
  550. package/dist/dev/ui/playback-rate/use-playback-rate-options.js.map +1 -0
  551. package/dist/dev/ui/playback-rate-button/playback-rate-button.d.ts.map +1 -1
  552. package/dist/dev/ui/playback-rate-button/playback-rate-button.js +2 -1
  553. package/dist/dev/ui/playback-rate-button/playback-rate-button.js.map +1 -1
  554. package/dist/dev/ui/poster/poster.d.ts.map +1 -1
  555. package/dist/dev/ui/poster/poster.js +17 -3
  556. package/dist/dev/ui/poster/poster.js.map +1 -1
  557. package/dist/dev/ui/quality/index.d.ts +2 -0
  558. package/dist/dev/ui/quality/index.js +2 -0
  559. package/dist/dev/ui/quality/use-quality-options.d.ts +27 -0
  560. package/dist/dev/ui/quality/use-quality-options.d.ts.map +1 -0
  561. package/dist/dev/ui/quality/use-quality-options.js +40 -0
  562. package/dist/dev/ui/quality/use-quality-options.js.map +1 -0
  563. package/dist/dev/ui/seek-button/seek-button.d.ts.map +1 -1
  564. package/dist/dev/ui/seek-button/seek-button.js +3 -1
  565. package/dist/dev/ui/seek-button/seek-button.js.map +1 -1
  566. package/dist/dev/ui/time/time-value.d.ts.map +1 -1
  567. package/dist/dev/ui/time/time-value.js +32 -5
  568. package/dist/dev/ui/time/time-value.js.map +1 -1
  569. package/dist/dev/ui/time-slider/time-slider-root.d.ts.map +1 -1
  570. package/dist/dev/ui/time-slider/time-slider-root.js +18 -6
  571. package/dist/dev/ui/time-slider/time-slider-root.js.map +1 -1
  572. package/dist/dev/ui/tooltip/context.d.ts +7 -3
  573. package/dist/dev/ui/tooltip/context.d.ts.map +1 -1
  574. package/dist/dev/ui/tooltip/context.js.map +1 -1
  575. package/dist/dev/ui/tooltip/index.d.ts +2 -2
  576. package/dist/dev/ui/tooltip/index.parts.d.ts +3 -1
  577. package/dist/dev/ui/tooltip/index.parts.js +4 -0
  578. package/dist/dev/ui/tooltip/index.parts.js.map +1 -1
  579. package/dist/dev/ui/tooltip/tooltip-arrow.js +1 -1
  580. package/dist/dev/ui/tooltip/tooltip-label.d.ts +15 -0
  581. package/dist/dev/ui/tooltip/tooltip-label.d.ts.map +1 -0
  582. package/dist/dev/ui/tooltip/tooltip-label.js +24 -0
  583. package/dist/dev/ui/tooltip/tooltip-label.js.map +1 -0
  584. package/dist/dev/ui/tooltip/tooltip-popup.d.ts.map +1 -1
  585. package/dist/dev/ui/tooltip/tooltip-popup.js +7 -3
  586. package/dist/dev/ui/tooltip/tooltip-popup.js.map +1 -1
  587. package/dist/dev/ui/tooltip/tooltip-root.js +1 -1
  588. package/dist/dev/ui/tooltip/tooltip-root.js.map +1 -1
  589. package/dist/dev/ui/tooltip/tooltip-shortcut.d.ts +15 -0
  590. package/dist/dev/ui/tooltip/tooltip-shortcut.d.ts.map +1 -0
  591. package/dist/dev/ui/tooltip/tooltip-shortcut.js +25 -0
  592. package/dist/dev/ui/tooltip/tooltip-shortcut.js.map +1 -0
  593. package/dist/dev/ui/volume-indicator/volume-indicator-root.d.ts.map +1 -1
  594. package/dist/dev/ui/volume-indicator/volume-indicator-root.js +1 -1
  595. package/dist/dev/ui/volume-indicator/volume-indicator-root.js.map +1 -1
  596. package/dist/dev/utils/use-attach-iframe.js +14 -0
  597. package/dist/dev/utils/use-attach-iframe.js.map +1 -0
  598. package/dist/dev/utils/use-media-instance.d.ts +7 -2
  599. package/dist/dev/utils/use-media-instance.d.ts.map +1 -1
  600. package/dist/dev/utils/use-media-instance.js +11 -3
  601. package/dist/dev/utils/use-media-instance.js.map +1 -1
  602. package/dist/dev/utils/use-render.d.ts.map +1 -1
  603. package/dist/dev/utils/use-render.js +1 -1
  604. package/dist/dev/utils/use-render.js.map +1 -1
  605. package/docs/README.md +1 -1
  606. package/docs/concepts/browser-support.md +1 -1
  607. package/docs/concepts/cast.md +162 -0
  608. package/docs/concepts/features.md +1 -1
  609. package/docs/concepts/overview.md +4 -4
  610. package/docs/concepts/presets.md +32 -6
  611. package/docs/concepts/skins.md +903 -318
  612. package/docs/concepts/why-videojs.md +1 -1
  613. package/docs/how-to/build-with-ai.md +7 -7
  614. package/docs/how-to/build-your-own-component.md +3 -3
  615. package/docs/how-to/customize-skins.md +2721 -847
  616. package/docs/how-to/installation.md +10 -10
  617. package/docs/llms.txt +23 -1
  618. package/docs/reference/airplay-button.md +264 -0
  619. package/docs/reference/audio-track-radio-group.md +59 -0
  620. package/docs/reference/background-video.md +76 -0
  621. package/docs/reference/captions-button.md +16 -0
  622. package/docs/reference/cast-button.md +236 -0
  623. package/docs/reference/dash-video.md +138 -0
  624. package/docs/reference/feature-audio-track.md +60 -0
  625. package/docs/reference/feature-fullscreen.md +20 -3
  626. package/docs/reference/feature-orientation-lock.md +35 -0
  627. package/docs/reference/feature-quality.md +70 -0
  628. package/docs/reference/feature-remote-playback.md +3 -1
  629. package/docs/reference/feature-text-tracks.md +10 -0
  630. package/docs/reference/hlsjs-video.md +274 -0
  631. package/docs/reference/menu.md +1194 -0
  632. package/docs/reference/mux-audio.md +218 -0
  633. package/docs/reference/mux-video.md +275 -0
  634. package/docs/reference/native-hls-video.md +212 -0
  635. package/docs/reference/play-button.md +1 -1
  636. package/docs/reference/playback-rate-button.md +16 -0
  637. package/docs/reference/player-container.md +9 -3
  638. package/docs/reference/player-provider.md +3 -1
  639. package/docs/reference/quality-radio-group.md +59 -0
  640. package/docs/reference/simple-hls-audio-only.md +93 -0
  641. package/docs/reference/simple-hls-video.md +150 -0
  642. package/docs/reference/time-slider.md +12 -0
  643. package/docs/reference/time.md +24 -0
  644. package/docs/reference/tooltip.md +89 -5
  645. package/docs/reference/use-media-attach.md +2 -2
  646. package/docs/reference/use-media.md +103 -2
  647. package/docs/reference/use-player-context.md +1 -1
  648. package/docs/reference/use-player.md +16 -1
  649. package/docs/reference/use-selector.md +1 -1
  650. package/docs/reference/use-snapshot.md +3 -3
  651. package/docs/reference/volume-slider.md +1 -1
  652. package/package.json +7 -7
  653. package/dist/default/media/hls-video/index.js.map +0 -1
  654. package/dist/default/skins/dist/default/default/tailwind/components/preview.js +0 -12
  655. package/dist/default/skins/dist/default/default/tailwind/components/preview.js.map +0 -1
  656. package/dist/default/skins/dist/default/minimal/tailwind/components/preview.js +0 -13
  657. package/dist/default/skins/dist/default/minimal/tailwind/components/preview.js.map +0 -1
  658. package/dist/default/ui/hotkey/use-aria-key-shortcuts.js +0 -16
  659. package/dist/default/ui/hotkey/use-aria-key-shortcuts.js.map +0 -1
  660. package/dist/default/ui/menu/menu-label.js +0 -23
  661. package/dist/default/ui/menu/menu-label.js.map +0 -1
  662. package/dist/default/ui/playback-rate-menu/context.js +0 -20
  663. package/dist/default/ui/playback-rate-menu/context.js.map +0 -1
  664. package/dist/default/ui/playback-rate-menu/index.js +0 -3
  665. package/dist/default/ui/playback-rate-menu/index.parts.js +0 -17
  666. package/dist/default/ui/playback-rate-menu/index.parts.js.map +0 -1
  667. package/dist/default/ui/playback-rate-menu/playback-rate-menu-content.js +0 -28
  668. package/dist/default/ui/playback-rate-menu/playback-rate-menu-content.js.map +0 -1
  669. package/dist/default/ui/playback-rate-menu/playback-rate-menu-root.js +0 -36
  670. package/dist/default/ui/playback-rate-menu/playback-rate-menu-root.js.map +0 -1
  671. package/dist/default/ui/playback-rate-menu/playback-rate-menu-trigger.js +0 -51
  672. package/dist/default/ui/playback-rate-menu/playback-rate-menu-trigger.js.map +0 -1
  673. package/dist/default/ui/playback-rate-menu/use-playback-rate-menu.js +0 -27
  674. package/dist/default/ui/playback-rate-menu/use-playback-rate-menu.js.map +0 -1
  675. package/dist/dev/media/hls-video/index.d.ts +0 -15
  676. package/dist/dev/media/hls-video/index.d.ts.map +0 -1
  677. package/dist/dev/media/hls-video/index.js.map +0 -1
  678. package/dist/dev/skins/dist/default/default/tailwind/components/preview.js +0 -12
  679. package/dist/dev/skins/dist/default/default/tailwind/components/preview.js.map +0 -1
  680. package/dist/dev/skins/dist/default/minimal/tailwind/components/preview.js +0 -13
  681. package/dist/dev/skins/dist/default/minimal/tailwind/components/preview.js.map +0 -1
  682. package/dist/dev/ui/hotkey/use-aria-key-shortcuts.d.ts +0 -5
  683. package/dist/dev/ui/hotkey/use-aria-key-shortcuts.d.ts.map +0 -1
  684. package/dist/dev/ui/hotkey/use-aria-key-shortcuts.js +0 -16
  685. package/dist/dev/ui/hotkey/use-aria-key-shortcuts.js.map +0 -1
  686. package/dist/dev/ui/menu/menu-label.d.ts +0 -15
  687. package/dist/dev/ui/menu/menu-label.d.ts.map +0 -1
  688. package/dist/dev/ui/menu/menu-label.js +0 -23
  689. package/dist/dev/ui/menu/menu-label.js.map +0 -1
  690. package/dist/dev/ui/playback-rate-menu/context.js +0 -20
  691. package/dist/dev/ui/playback-rate-menu/context.js.map +0 -1
  692. package/dist/dev/ui/playback-rate-menu/index.d.ts +0 -3
  693. package/dist/dev/ui/playback-rate-menu/index.js +0 -3
  694. package/dist/dev/ui/playback-rate-menu/index.parts.d.ts +0 -12
  695. package/dist/dev/ui/playback-rate-menu/index.parts.d.ts.map +0 -1
  696. package/dist/dev/ui/playback-rate-menu/index.parts.js +0 -17
  697. package/dist/dev/ui/playback-rate-menu/index.parts.js.map +0 -1
  698. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-content.d.ts +0 -14
  699. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-content.d.ts.map +0 -1
  700. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-content.js +0 -28
  701. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-content.js.map +0 -1
  702. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-root.d.ts +0 -23
  703. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-root.d.ts.map +0 -1
  704. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-root.js +0 -39
  705. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-root.js.map +0 -1
  706. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-trigger.d.ts +0 -14
  707. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-trigger.d.ts.map +0 -1
  708. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-trigger.js +0 -51
  709. package/dist/dev/ui/playback-rate-menu/playback-rate-menu-trigger.js.map +0 -1
  710. package/dist/dev/ui/playback-rate-menu/use-playback-rate-menu.d.ts +0 -26
  711. package/dist/dev/ui/playback-rate-menu/use-playback-rate-menu.d.ts.map +0 -1
  712. package/dist/dev/ui/playback-rate-menu/use-playback-rate-menu.js +0 -27
  713. package/dist/dev/ui/playback-rate-menu/use-playback-rate-menu.js.map +0 -1
@@ -19,7 +19,7 @@ tsx
19
19
 
20
20
  ## Packaged vs. ejected
21
21
 
22
- When you choose a skin you have two options for how you use it: **packaged** or **ejected** . It’s usually easiest to start with a packaged skin and later eject its internal components into your project when you need more customization.
22
+ When you choose a skin you have two options for how you use it: **packaged** or **ejected**. It’s usually easiest to start with a packaged skin and later eject its internal components into your project when you need more customization.
23
23
 
24
24
  Packaged
25
25
 
@@ -63,8 +63,8 @@ skin.css
63
63
  'use client';
64
64
 
65
65
  import { type CSSProperties, type ComponentProps, forwardRef, type ReactNode, isValidElement } from 'react';
66
- import { CaptionsOffIcon, CaptionsOnIcon, CastEnterIcon, CastExitIcon, CheckIcon, ChevronIcon, FullscreenEnterIcon, FullscreenExitIcon, PauseIcon, PipEnterIcon, PipExitIcon, PlayIcon, RestartIcon, SeekIcon, SpinnerIcon, VolumeHighIcon, VolumeLowIcon, VolumeOffIcon } from '@videojs/react/icons';
67
- import { createPlayer, Poster, Container, usePlayer, BufferingIndicator, CaptionsButton, CastButton, Controls, ErrorDialog, FullscreenButton, Gesture, Hotkey, Menu, MuteButton, PiPButton, PlayButton, PlaybackRateMenu, usePlaybackRateMenu, Popover, SeekButton, SeekIndicator, Slider, StatusAnnouncer, StatusIndicator, Time, TimeSlider, Tooltip, VolumeIndicator, VolumeSlider, type RenderProp } from '@videojs/react';
66
+ import { AirPlayEnterIcon, AirPlayExitIcon, CaptionsOffIcon, CaptionsOnIcon, CastEnterIcon, CastExitIcon, CheckIcon, ChevronIcon, FullscreenEnterIcon, FullscreenExitIcon, GearIcon, PauseIcon, PipEnterIcon, PipExitIcon, PlayIcon, QualityIcon, RestartIcon, SeekIcon, SpeechIcon, SpeedIcon, SpinnerIcon, VolumeHighIcon, VolumeLowIcon, VolumeOffIcon } from '@videojs/react/icons';
67
+ import { createPlayer, Poster, Container, usePlayer, AirPlayButton, useAudioTrackOptions, BufferingIndicator, useCaptionsOptions, CastButton, Controls, ErrorDialog, FullscreenButton, Gesture, Hotkey, Menu, MuteButton, PiPButton, PlayButton, usePlaybackRateOptions, Popover, useQualityOptions, SeekButton, SeekIndicator, Slider, StatusAnnouncer, StatusIndicator, Time, TimeSlider, Tooltip, VolumeIndicator, VolumeSlider, type RenderProp } from '@videojs/react';
68
68
  import { Video, videoFeatures } from '@videojs/react/video';
69
69
  import './player.css';
70
70
 
@@ -72,20 +72,237 @@ const TOP_STATUS_ACTIONS = ['toggleSubtitles', 'toggleFullscreen', 'togglePictur
72
72
 
73
73
  const CENTER_STATUS_ACTIONS = ['togglePaused'] as const;
74
74
 
75
- function PlaybackRateMenuItems(): ReactNode {
76
- const { options, setValue, value } = usePlaybackRateMenu();
75
+ function MenuChevron({ flipped = false }: { flipped?: boolean }): ReactNode {
76
+ return <ChevronIcon className={`media-icon media-menu__chevron ${flipped ? 'media-icon--flipped' : undefined}`} />;
77
+ }
78
+
79
+ function SettingsMenu(): ReactNode {
80
+ const playbackRate = usePlaybackRateOptions();
81
+ const quality = useQualityOptions();
82
+ const audioTrack = useAudioTrackOptions();
83
+ const captions = useCaptionsOptions();
84
+ const hasPlaybackRate = playbackRate?.state.availability === 'available';
85
+ const hasQuality = quality?.state.availability === 'available';
86
+ const hasAudioTrack = audioTrack?.state.availability === 'available';
87
+ const hasCaptions = captions?.state.availability === 'available';
88
+
89
+ if (!hasPlaybackRate && !hasQuality && !hasAudioTrack && !hasCaptions) return null;
77
90
 
78
91
  return (
79
- <Menu.RadioGroup className="media-menu__group" value={value} onValueChange={setValue} label="Playback rate">
80
- {options.map((option) => (
81
- <Menu.RadioItem key={option.value} className="media-menu__item" value={option.value} disabled={option.disabled}>
82
- <span>{option.label}</span>
83
- <Menu.ItemIndicator checked={option.value === value} forceMount className="media-menu__indicator">
84
- <CheckIcon className="media-icon" />
85
- </Menu.ItemIndicator>
86
- </Menu.RadioItem>
87
- ))}
88
- </Menu.RadioGroup>
92
+ <Menu.Root side="top" align="center">
93
+ <Menu.Trigger aria-label="Settings" className="media-button--settings" render={<Button />}>
94
+ <GearIcon className="media-icon media-icon--settings" />
95
+ </Menu.Trigger>
96
+ <Menu.Content className="media-surface media-popover media-menu media-menu--settings">
97
+ <Menu.View className="media-menu__panel">
98
+ <div className="media-menu__group">
99
+ {hasQuality ? (
100
+ <Menu.Root>
101
+ <Menu.Trigger
102
+ type="quality"
103
+ className="media-menu__item media-menu__item--submenu"
104
+ render={(props) => (
105
+ <div {...props}>
106
+ <QualityIcon className="media-icon" />
107
+ <span>Quality</span>
108
+ <span className="media-menu__hint">
109
+ <Menu.ItemValue className="media-menu__hint-label" />
110
+ <MenuChevron />
111
+ </span>
112
+ </div>
113
+ )}
114
+ />
115
+ <Menu.Content className="media-menu__panel">
116
+ <Menu.Back className="media-menu__back">
117
+ <MenuChevron flipped />
118
+ Quality
119
+ </Menu.Back>
120
+ <Menu.Separator className="media-menu__separator" />
121
+ <Menu.RadioGroup
122
+ className="media-menu__group"
123
+ value={quality.value}
124
+ onValueChange={quality.setValue}
125
+ aria-label="Quality"
126
+ >
127
+ {quality.options.map((option) => (
128
+ <Menu.RadioItem
129
+ key={option.value}
130
+ className="media-menu__item"
131
+ value={option.value}
132
+ disabled={option.disabled}
133
+ >
134
+ <span>
135
+ {option.label}
136
+ {option.tier ? <sup className="media-menu__tier">{option.tier}</sup> : null}
137
+ </span>
138
+ {option.badge ? <span className="media-badge">{option.badge}</span> : null}
139
+ <Menu.ItemIndicator
140
+ checked={option.value === quality.value}
141
+ forceMount
142
+ className="media-menu__indicator"
143
+ >
144
+ <CheckIcon className="media-icon" />
145
+ </Menu.ItemIndicator>
146
+ </Menu.RadioItem>
147
+ ))}
148
+ </Menu.RadioGroup>
149
+ </Menu.Content>
150
+ </Menu.Root>
151
+ ) : null}
152
+
153
+ {hasAudioTrack ? (
154
+ <Menu.Root>
155
+ <Menu.Trigger
156
+ type="audio-track"
157
+ className="media-menu__item media-menu__item--submenu"
158
+ render={(props) => (
159
+ <div {...props}>
160
+ <SpeechIcon className="media-icon" />
161
+ <span>Audio</span>
162
+ <span className="media-menu__hint">
163
+ <Menu.ItemValue className="media-menu__hint-label" />
164
+ <MenuChevron />
165
+ </span>
166
+ </div>
167
+ )}
168
+ />
169
+ <Menu.Content className="media-menu__panel">
170
+ <Menu.Back className="media-menu__back">
171
+ <MenuChevron flipped />
172
+ Audio
173
+ </Menu.Back>
174
+ <Menu.Separator className="media-menu__separator" />
175
+ <Menu.RadioGroup
176
+ className="media-menu__group"
177
+ value={audioTrack.value}
178
+ onValueChange={audioTrack.setValue}
179
+ aria-label="Audio tracks"
180
+ >
181
+ {audioTrack.options.map((option) => (
182
+ <Menu.RadioItem
183
+ key={option.value}
184
+ className="media-menu__item"
185
+ value={option.value}
186
+ disabled={option.disabled}
187
+ >
188
+ <span>{option.label}</span>
189
+ <Menu.ItemIndicator
190
+ checked={option.value === audioTrack.value}
191
+ forceMount
192
+ className="media-menu__indicator"
193
+ >
194
+ <CheckIcon className="media-icon" />
195
+ </Menu.ItemIndicator>
196
+ </Menu.RadioItem>
197
+ ))}
198
+ </Menu.RadioGroup>
199
+ </Menu.Content>
200
+ </Menu.Root>
201
+ ) : null}
202
+
203
+ {hasPlaybackRate ? (
204
+ <Menu.Root>
205
+ <Menu.Trigger
206
+ type="playback-rate"
207
+ className="media-menu__item media-menu__item--submenu"
208
+ render={(props) => (
209
+ <div {...props}>
210
+ <SpeedIcon className="media-icon" />
211
+ <span>Speed</span>
212
+ <span className="media-menu__hint">
213
+ <Menu.ItemValue className="media-menu__hint-label" />
214
+ <MenuChevron />
215
+ </span>
216
+ </div>
217
+ )}
218
+ />
219
+ <Menu.Content className="media-menu__panel">
220
+ <Menu.Back className="media-menu__back">
221
+ <MenuChevron flipped />
222
+ Speed
223
+ </Menu.Back>
224
+ <Menu.Separator className="media-menu__separator" />
225
+ <Menu.RadioGroup
226
+ className="media-menu__group"
227
+ value={playbackRate.value}
228
+ onValueChange={playbackRate.setValue}
229
+ aria-label="Playback rate"
230
+ >
231
+ {playbackRate.options.map((option) => (
232
+ <Menu.RadioItem
233
+ key={option.value}
234
+ className="media-menu__item"
235
+ value={option.value}
236
+ disabled={option.disabled}
237
+ >
238
+ <span>{option.label}</span>
239
+ <Menu.ItemIndicator
240
+ checked={option.value === playbackRate.value}
241
+ forceMount
242
+ className="media-menu__indicator"
243
+ >
244
+ <CheckIcon className="media-icon" />
245
+ </Menu.ItemIndicator>
246
+ </Menu.RadioItem>
247
+ ))}
248
+ </Menu.RadioGroup>
249
+ </Menu.Content>
250
+ </Menu.Root>
251
+ ) : null}
252
+
253
+ {hasCaptions ? (
254
+ <Menu.Root>
255
+ <Menu.Trigger
256
+ type="captions"
257
+ className="media-menu__item media-menu__item--submenu"
258
+ render={(props) => (
259
+ <div {...props}>
260
+ <CaptionsOffIcon className="media-icon" />
261
+ <span>Captions</span>
262
+ <span className="media-menu__hint">
263
+ <Menu.ItemValue className="media-menu__hint-label" />
264
+ <MenuChevron />
265
+ </span>
266
+ </div>
267
+ )}
268
+ />
269
+ <Menu.Content className="media-menu__panel">
270
+ <Menu.Back className="media-menu__back">
271
+ <MenuChevron flipped />
272
+ Captions
273
+ </Menu.Back>
274
+ <Menu.Separator className="media-menu__separator" />
275
+ <Menu.RadioGroup
276
+ className="media-menu__group"
277
+ value={captions.value}
278
+ onValueChange={captions.setValue}
279
+ aria-label="Captions"
280
+ >
281
+ {captions.options.map((option) => (
282
+ <Menu.RadioItem
283
+ key={option.value}
284
+ className="media-menu__item"
285
+ value={option.value}
286
+ disabled={option.disabled}
287
+ >
288
+ <span>{option.label}</span>
289
+ <Menu.ItemIndicator
290
+ checked={option.value === captions.value}
291
+ forceMount
292
+ className="media-menu__indicator"
293
+ >
294
+ <CheckIcon className="media-icon" />
295
+ </Menu.ItemIndicator>
296
+ </Menu.RadioItem>
297
+ ))}
298
+ </Menu.RadioGroup>
299
+ </Menu.Content>
300
+ </Menu.Root>
301
+ ) : null}
302
+ </div>
303
+ </Menu.View>
304
+ </Menu.Content>
305
+ </Menu.Root>
89
306
  );
90
307
  }
91
308
 
@@ -113,10 +330,18 @@ export interface VideoPlayerProps {
113
330
  * />
114
331
  * ```
115
332
  */
116
- export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProps): ReactNode {
333
+ export function VideoPlayer({ src, className, poster, placeholder, style, ...rest }: VideoPlayerProps): ReactNode {
334
+ const containerStyle = placeholder
335
+ ? ({ '--media-poster-placeholder': `url(${placeholder})`, ...style } as CSSProperties)
336
+ : style;
337
+
117
338
  return (
118
339
  <Player.Provider>
119
- <Container className={`media-default-skin media-default-skin--video ${className ?? ''}`} {...rest}>
340
+ <Container
341
+ className={`media-default-skin media-default-skin--video ${className ?? ''}`}
342
+ style={containerStyle}
343
+ {...rest}
344
+ >
120
345
  <Video src={src} playsInline />
121
346
 
122
347
  {poster && (
@@ -126,9 +351,7 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
126
351
  <BufferingIndicator
127
352
  render={(props) => (
128
353
  <div {...props} className="media-buffering-indicator">
129
- <div className="media-surface">
130
- <SpinnerIcon className="media-icon" />
131
- </div>
354
+ <SpinnerIcon className="media-icon" />
132
355
  </div>
133
356
  )}
134
357
  />
@@ -160,7 +383,10 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
160
383
  </PlayButton>
161
384
  }
162
385
  />
163
- <Tooltip.Popup className="media-surface media-tooltip" />
386
+ <Tooltip.Popup className="media-surface media-tooltip">
387
+ <Tooltip.Label />
388
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
389
+ </Tooltip.Popup>
164
390
  </Tooltip.Root>
165
391
 
166
392
  <Tooltip.Root side="top">
@@ -174,7 +400,10 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
174
400
  </SeekButton>
175
401
  }
176
402
  />
177
- <Tooltip.Popup className="media-surface media-tooltip" />
403
+ <Tooltip.Popup className="media-surface media-tooltip">
404
+ <Tooltip.Label />
405
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
406
+ </Tooltip.Popup>
178
407
  </Tooltip.Root>
179
408
 
180
409
  <Tooltip.Root side="top">
@@ -188,7 +417,10 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
188
417
  </SeekButton>
189
418
  }
190
419
  />
191
- <Tooltip.Popup className="media-surface media-tooltip" />
420
+ <Tooltip.Popup className="media-surface media-tooltip">
421
+ <Tooltip.Label />
422
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
423
+ </Tooltip.Popup>
192
424
  </Tooltip.Root>
193
425
  </div>
194
426
 
@@ -201,47 +433,51 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
201
433
  </TimeSlider.Track>
202
434
  <TimeSlider.Thumb className="media-slider__thumb" />
203
435
 
204
- <div className="media-surface media-preview media-slider__preview">
205
- <Slider.Thumbnail className="media-preview__thumbnail" />
206
- <TimeSlider.Value type="pointer" className="media-time media-preview__time" />
207
- <SpinnerIcon className="media-preview__spinner media-icon" />
436
+ <div className="media-surface media-thumbnail media-slider__thumbnail">
437
+ <Slider.Thumbnail className="media-thumbnail__image" />
438
+ <TimeSlider.Value type="pointer" className="media-time media-thumbnail__time" />
439
+ <SpinnerIcon className="media-thumbnail__spinner media-icon" />
208
440
  </div>
441
+ <TimeSlider.Preview className="media-slider__preview">
442
+ <TimeSlider.Value type="pointer" className="media-time media-slider__value" />
443
+ </TimeSlider.Preview>
209
444
  </TimeSlider.Root>
210
- <Time.Value type="duration" className="media-time" />
445
+ <Time.Value toggle type="remaining" className="media-time" />
211
446
  </div>
212
447
 
213
448
  <div className="media-button-group">
214
- <PlaybackRateMenu.Root side="top" align="center">
215
- <PlaybackRateMenu.Trigger className="media-button--playback-rate" render={<Button />} />
216
- <PlaybackRateMenu.Content className="media-surface media-popover media-menu media-menu--playback-rate">
217
- <PlaybackRateMenuItems />
218
- </PlaybackRateMenu.Content>
219
- </PlaybackRateMenu.Root>
220
-
221
449
  <VolumePopover />
222
450
 
451
+ <SettingsMenu />
452
+
223
453
  <Tooltip.Root side="top">
224
454
  <Tooltip.Trigger
225
455
  render={
226
- <CaptionsButton className="media-button--captions" render={<Button />}>
227
- <CaptionsOffIcon className="media-icon media-icon--captions-off" />
228
- <CaptionsOnIcon className="media-icon media-icon--captions-on" />
229
- </CaptionsButton>
456
+ <CastButton className="media-button--cast" render={<Button />}>
457
+ <CastEnterIcon className="media-icon media-icon--cast-enter" />
458
+ <CastExitIcon className="media-icon media-icon--cast-exit" />
459
+ </CastButton>
230
460
  }
231
461
  />
232
- <Tooltip.Popup className="media-surface media-tooltip" />
462
+ <Tooltip.Popup className="media-surface media-tooltip">
463
+ <Tooltip.Label />
464
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
465
+ </Tooltip.Popup>
233
466
  </Tooltip.Root>
234
467
 
235
468
  <Tooltip.Root side="top">
236
469
  <Tooltip.Trigger
237
470
  render={
238
- <CastButton className="media-button--cast" render={<Button />}>
239
- <CastEnterIcon className="media-icon media-icon--cast-enter" />
240
- <CastExitIcon className="media-icon media-icon--cast-exit" />
241
- </CastButton>
471
+ <AirPlayButton className="media-button--airplay" render={<Button />}>
472
+ <AirPlayEnterIcon className="media-icon media-icon--airplay-enter" />
473
+ <AirPlayExitIcon className="media-icon media-icon--airplay-exit" />
474
+ </AirPlayButton>
242
475
  }
243
476
  />
244
- <Tooltip.Popup className="media-surface media-tooltip" />
477
+ <Tooltip.Popup className="media-surface media-tooltip">
478
+ <Tooltip.Label />
479
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
480
+ </Tooltip.Popup>
245
481
  </Tooltip.Root>
246
482
 
247
483
  <Tooltip.Root side="top">
@@ -253,7 +489,10 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
253
489
  </PiPButton>
254
490
  }
255
491
  />
256
- <Tooltip.Popup className="media-surface media-tooltip" />
492
+ <Tooltip.Popup className="media-surface media-tooltip">
493
+ <Tooltip.Label />
494
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
495
+ </Tooltip.Popup>
257
496
  </Tooltip.Root>
258
497
 
259
498
  <Tooltip.Root side="top">
@@ -265,7 +504,10 @@ export function VideoPlayer({ src, className, poster, ...rest }: VideoPlayerProp
265
504
  </FullscreenButton>
266
505
  }
267
506
  />
268
- <Tooltip.Popup className="media-surface media-tooltip" />
507
+ <Tooltip.Popup className="media-surface media-tooltip">
508
+ <Tooltip.Label />
509
+ <Tooltip.Shortcut className="media-tooltip__kbd" />
510
+ </Tooltip.Popup>
269
511
  </Tooltip.Root>
270
512
  </div>
271
513
  </Tooltip.Provider>
@@ -434,6 +676,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
434
676
  --media-current-shadow-color: oklch(from currentColor 0 0 0 / clamp(0, calc((l - 0.5) * 0.5), 0.15));
435
677
  --media-current-shadow-color-subtle: oklch(from var(--media-current-shadow-color) l c h / calc(alpha * 0.4));
436
678
  --media-icon-size: 18px;
679
+ --media-color-scrollbar-thumb: oklch(from currentColor l c h / 0.3);
437
680
  position: relative;
438
681
  display: block;
439
682
  width: 100%;
@@ -452,6 +695,8 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
452
695
  letter-spacing: normal;
453
696
  outline: 2px solid transparent;
454
697
  outline-offset: -4px;
698
+ scrollbar-color: var(--media-color-scrollbar-thumb) transparent;
699
+ scrollbar-width: thin;
455
700
  border-radius: var(--media-border-radius, 2rem);
456
701
  isolation: isolate;
457
702
  transition-timing-function: ease-out;
@@ -462,6 +707,16 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
462
707
  outline-color: currentColor;
463
708
  outline-offset: 2px;
464
709
  }
710
+
711
+ &::-webkit-scrollbar-thumb {
712
+ background: var(--media-color-scrollbar-thumb);
713
+ border-radius: 9999px;
714
+ }
715
+
716
+ @media (prefers-reduced-transparency: reduce) or (prefers-contrast: more) {
717
+ --media-color-scrollbar-thumb: oklch(from currentColor l c h / 0.8);
718
+ scrollbar-width: auto;
719
+ }
465
720
  }
466
721
 
467
722
  /* ==========================================================================
@@ -520,7 +775,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
520
775
  position: absolute;
521
776
  inset: 0;
522
777
  pointer-events: none;
523
- background-image: linear-gradient(to top, oklch(0 0 0 / 0.5), oklch(0 0 0 / 0.3), oklch(0 0 0 / 0));
778
+ background-image: linear-gradient(to top, oklch(0 0 0 / 0.5), oklch(0 0 0 / 0.3) 25%, oklch(0 0 0 / 0));
524
779
  border-radius: inherit;
525
780
  opacity: 0;
526
781
  backdrop-filter: blur(0) saturate(1);
@@ -539,6 +794,12 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
539
794
  opacity: 1;
540
795
  }
541
796
 
797
+ .media-default-skin .media-buffering-indicator[data-visible] ~ .media-overlay {
798
+ background: oklch(0 0 0 / 0.35);
799
+ opacity: 1;
800
+ backdrop-filter: blur(8px);
801
+ }
802
+
542
803
  .media-default-skin .media-error[data-open] ~ .media-overlay {
543
804
  backdrop-filter: blur(16px) saturate(1.5);
544
805
  }
@@ -550,9 +811,9 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
550
811
  .media-default-skin .media-buffering-indicator {
551
812
  position: absolute;
552
813
  inset: 0;
814
+ z-index: 10;
553
815
  display: none;
554
- align-items: center;
555
- justify-content: center;
816
+ place-content: center;
556
817
  color: oklch(1 0 0);
557
818
  pointer-events: none;
558
819
 
@@ -561,12 +822,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
561
822
  }
562
823
 
563
824
  &[data-visible] {
564
- display: flex;
565
- }
566
-
567
- .media-surface {
568
- padding: 0.25rem;
569
- border-radius: 100%;
825
+ display: grid;
570
826
  }
571
827
  }
572
828
 
@@ -636,6 +892,21 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
636
892
  font-variant-numeric: tabular-nums;
637
893
  }
638
894
 
895
+ .media-default-skin .media-time[role="button"] {
896
+ cursor: pointer;
897
+ outline: 2px solid transparent;
898
+ outline-offset: -2px;
899
+ border-radius: 0.25rem;
900
+ transition-timing-function: ease-out;
901
+ transition-duration: 100ms;
902
+ transition-property: outline-color, outline-offset;
903
+
904
+ &:focus-visible {
905
+ outline-color: currentColor;
906
+ outline-offset: 2px;
907
+ }
908
+ }
909
+
639
910
  /* ==========================================================================
640
911
  Buttons
641
912
  ========================================================================== */
@@ -716,6 +987,10 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
716
987
  scale: 0.9;
717
988
  }
718
989
 
990
+ & .media-icon__container {
991
+ display: grid;
992
+ }
993
+
719
994
  & .media-icon {
720
995
  grid-area: 1 / 1;
721
996
  transition-behavior: allow-discrete;
@@ -733,8 +1008,9 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
733
1008
  right: -1px;
734
1009
  bottom: -3px;
735
1010
  font-size: 10px;
736
- font-weight: 480;
1011
+ font-weight: 500;
737
1012
  font-variant-numeric: tabular-nums;
1013
+ letter-spacing: -0.05em;
738
1014
  }
739
1015
 
740
1016
  &:has(.media-icon--flipped) .media-icon__label {
@@ -758,6 +1034,27 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
758
1034
  }
759
1035
  }
760
1036
 
1037
+ /* Settings button */
1038
+ .media-default-skin .media-button--settings {
1039
+ display: none;
1040
+
1041
+ & .media-icon--settings {
1042
+ transition: transform 150ms ease-in-out;
1043
+
1044
+ @media (prefers-reduced-motion: reduce) {
1045
+ transition-duration: 0ms;
1046
+ }
1047
+ }
1048
+
1049
+ &[aria-expanded="true"] .media-icon--settings {
1050
+ transform: rotate(90deg);
1051
+ }
1052
+ }
1053
+
1054
+ .media-default-skin .media-button-group:has([data-availability="available"]) .media-button--settings {
1055
+ display: grid;
1056
+ }
1057
+
761
1058
  /* Live button — wide pill button with a status dot (gray → red at the live
762
1059
  edge) rendered via ::before, and "LIVE" text rendered as the button's own
763
1060
  text content. */
@@ -804,6 +1101,21 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
804
1101
  }
805
1102
  }
806
1103
 
1104
+ /* ==========================================================================
1105
+ Badge
1106
+ ========================================================================== */
1107
+
1108
+ .media-default-skin .media-badge {
1109
+ padding: 0.125rem 0.375rem;
1110
+ font-size: 0.6875rem;
1111
+ font-weight: 500;
1112
+ line-height: 1;
1113
+ color: oklch(from currentColor l c h / 0.85);
1114
+ white-space: nowrap;
1115
+ background-color: oklch(from currentColor l c h / 0.1);
1116
+ border-radius: calc(infinity * 1px);
1117
+ }
1118
+
807
1119
  /* ==========================================================================
808
1120
  Icons
809
1121
  ========================================================================== */
@@ -811,6 +1123,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
811
1123
  .media-default-skin .media-icon__container {
812
1124
  position: relative;
813
1125
  }
1126
+
814
1127
  .media-default-skin .media-icon {
815
1128
  flex-shrink: 0;
816
1129
  width: var(--media-icon-size);
@@ -820,102 +1133,6 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
820
1133
  scale: -1 1;
821
1134
  }
822
1135
 
823
- /* ==========================================================================
824
- Menus
825
- Note: Menus use `.media-popover` styles for positioning and transitions.
826
- ========================================================================== */
827
-
828
- .media-default-skin .media-popover.media-menu {
829
- box-sizing: border-box;
830
- min-width: min(6rem, var(--media-popover-available-width, 6rem));
831
- max-width: var(--media-popover-available-width, none);
832
- max-height: var(--media-popover-available-height, none);
833
- padding: 0.375rem;
834
- overflow: auto;
835
- overscroll-behavior: none;
836
- border-radius: 1.25rem;
837
-
838
- &::before {
839
- display: none;
840
- }
841
- }
842
-
843
- .media-default-skin .media-popover.media-menu .media-menu__group {
844
- position: relative;
845
- display: flex;
846
- flex-direction: column;
847
- gap: 0.125rem;
848
-
849
- &::before {
850
- position: absolute;
851
- position-anchor: --media-menu-item-highlight-anchor;
852
- inset: anchor(inside);
853
- pointer-events: none;
854
- content: "";
855
- background-color: oklch(from currentColor l c h / 0.1);
856
- border-radius: calc(infinity * 1px);
857
- transition: inset ease-in-out 100ms;
858
- }
859
-
860
- @supports not (top: anchor(top)) {
861
- &::before {
862
- display: none;
863
- }
864
- }
865
- }
866
-
867
- .media-default-skin .media-popover.media-menu .media-menu__item {
868
- display: flex;
869
- gap: 0.5rem;
870
- align-items: center;
871
- justify-content: space-between;
872
- min-height: 2rem;
873
- padding: 0 0.75rem;
874
- font-variant-numeric: tabular-nums;
875
- color: inherit;
876
- cursor: pointer;
877
- outline: 2px solid transparent;
878
- outline-offset: -2px;
879
- border-radius: calc(infinity * 1px);
880
-
881
- &:hover,
882
- &[data-highlighted] {
883
- anchor-name: --media-menu-item-highlight-anchor;
884
- }
885
-
886
- @supports not (top: anchor(top)) {
887
- &:hover,
888
- &[data-highlighted] {
889
- background-color: oklch(from currentColor l c h / 0.1);
890
- }
891
- }
892
-
893
- &:focus-visible {
894
- outline-color: currentColor;
895
- outline-offset: 2px;
896
- }
897
-
898
- &[aria-checked="true"] .media-menu__indicator {
899
- opacity: 1;
900
- }
901
-
902
- &[aria-disabled="true"] {
903
- pointer-events: none;
904
- cursor: not-allowed;
905
- opacity: 0.5;
906
- }
907
- }
908
-
909
- .media-default-skin .media-popover.media-menu .media-menu__indicator {
910
- flex-shrink: 0;
911
- margin-right: -0.25rem;
912
- opacity: 0;
913
- }
914
-
915
- .media-default-skin .media-popover.media-menu .media-menu__indicator .media-icon {
916
- filter: drop-shadow(0 1px 0 var(--media-current-shadow-color));
917
- }
918
-
919
1136
  /* ==========================================================================
920
1137
  Poster Image
921
1138
  ========================================================================== */
@@ -930,7 +1147,8 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
930
1147
  transition: opacity 0.25s;
931
1148
  }
932
1149
  .media-default-skin media-poster:not([data-visible]),
933
- .media-default-skin > img:not([data-visible]) {
1150
+ .media-default-skin > img:not([data-visible]),
1151
+ .media-default-skin > img[data-visible]:not([data-loaded]) {
934
1152
  opacity: 0;
935
1153
  }
936
1154
  .media-default-skin media-poster ::slotted(img),
@@ -949,6 +1167,30 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
949
1167
  border-radius: inherit;
950
1168
  }
951
1169
 
1170
+ /* Blurred placeholder: HTML path targets media-poster::before, React path targets the skin container::before */
1171
+ .media-default-skin media-poster::before,
1172
+ .media-default-skin::before {
1173
+ position: absolute;
1174
+ inset: 0;
1175
+ pointer-events: none;
1176
+ content: "";
1177
+ background-image: var(--media-poster-placeholder, none);
1178
+ background-repeat: no-repeat;
1179
+ background-position: var(--media-object-position, center);
1180
+ background-size: var(--media-object-fit, contain);
1181
+ filter: blur(var(--media-poster-placeholder-blur, 20px));
1182
+ }
1183
+
1184
+ /* React path: hidden by default, transitions in while poster loads */
1185
+ .media-default-skin::before {
1186
+ opacity: 0;
1187
+ transition: opacity 0.25s;
1188
+ }
1189
+ /* Show placeholder while the poster is visible but not yet loaded */
1190
+ .media-default-skin:has(img[data-visible]:not([data-loaded]))::before {
1191
+ opacity: 1;
1192
+ }
1193
+
952
1194
  .media-default-skin:fullscreen media-poster ::slotted(img),
953
1195
  .media-default-skin:fullscreen media-poster img,
954
1196
  .media-default-skin:fullscreen > img {
@@ -956,14 +1198,15 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
956
1198
  }
957
1199
 
958
1200
  /* ==========================================================================
959
- Media preview
1201
+ Media thumbnail
960
1202
  ========================================================================== */
961
- .media-default-skin .media-preview {
1203
+
1204
+ .media-default-skin .media-thumbnail {
962
1205
  pointer-events: none;
963
1206
  background-color: oklch(0 0 0 / 0.9);
964
1207
  border-radius: 0.75rem;
965
1208
 
966
- & .media-preview__thumbnail {
1209
+ & .media-thumbnail__image {
967
1210
  position: relative;
968
1211
  display: block;
969
1212
  overflow: clip;
@@ -978,18 +1221,14 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
978
1221
  }
979
1222
  }
980
1223
 
981
- & .media-preview__time {
1224
+ & .media-thumbnail__time {
982
1225
  position: absolute;
983
1226
  inset-inline: 0;
984
1227
  bottom: 0.5rem;
985
1228
  text-align: center;
986
1229
  }
987
1230
 
988
- & .media-overlay {
989
- opacity: 1;
990
- }
991
-
992
- & .media-preview__spinner {
1231
+ & .media-thumbnail__spinner {
993
1232
  position: absolute;
994
1233
  top: 50%;
995
1234
  left: 50%;
@@ -997,22 +1236,22 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
997
1236
  translate: -50% -50%;
998
1237
  }
999
1238
 
1000
- & .media-preview__thumbnail,
1001
- & .media-preview__spinner {
1239
+ & .media-thumbnail__image,
1240
+ & .media-thumbnail__spinner {
1002
1241
  transition: opacity 150ms ease-out;
1003
1242
  }
1004
1243
 
1005
- &:not(:has(.media-preview__thumbnail[data-loading])) {
1006
- & .media-preview__spinner {
1244
+ &:not(:has(.media-thumbnail__image[data-loading])) {
1245
+ & .media-thumbnail__spinner {
1007
1246
  --media-spinner-animation: none;
1008
1247
  }
1009
1248
  }
1010
1249
 
1011
- &:has(.media-preview__thumbnail[data-loading]) {
1012
- & .media-preview__thumbnail {
1250
+ &:has(.media-thumbnail__image[data-loading]) {
1251
+ & .media-thumbnail__image {
1013
1252
  opacity: 0;
1014
1253
  }
1015
- & .media-preview__spinner {
1254
+ & .media-thumbnail__spinner {
1016
1255
  opacity: 1;
1017
1256
  }
1018
1257
  }
@@ -1075,9 +1314,9 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1075
1314
  background-color: currentColor;
1076
1315
  border-radius: calc(infinity * 1px);
1077
1316
  box-shadow:
1078
- 0 0 0 1px var(--media-current-shadow-color-subtle, oklch(0 0 0 / 0.1)),
1079
- 0 1px 3px 0 oklch(0 0 0 / 0.15),
1080
- 0 1px 2px -1px oklch(0 0 0 / 0.15);
1317
+ 0 0 0 1px var(--media-current-shadow-color, oklch(0 0 0 / 0.1)),
1318
+ 0 1px 3px 0 oklch(0 0 0 / 0.35),
1319
+ 0 1px 2px -1px oklch(0 0 0 / 0.35);
1081
1320
  opacity: 0;
1082
1321
  translate: -50% -50%;
1083
1322
  transition-timing-function: ease-out;
@@ -1096,7 +1335,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1096
1335
 
1097
1336
  &:hover,
1098
1337
  &:focus {
1099
- outline-color: oklch(from currentColor l c h / 0.25);
1338
+ outline-color: oklch(from currentColor l c h / 0.15);
1100
1339
  outline-offset: 0;
1101
1340
  }
1102
1341
 
@@ -1105,7 +1344,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1105
1344
  inset: -4px;
1106
1345
  content: "";
1107
1346
  border-radius: inherit;
1108
- box-shadow: 0 0 0 2px oklch(1 0 0);
1347
+ box-shadow: 0 0 0 2px currentColor;
1109
1348
  transition-timing-function: ease-out;
1110
1349
  transition-duration: 150ms;
1111
1350
  transition-property: opacity, scale;
@@ -1129,6 +1368,49 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1129
1368
  opacity: 1;
1130
1369
  }
1131
1370
 
1371
+ /* Preview */
1372
+ .media-default-skin .media-slider__preview {
1373
+ & .media-slider__value,
1374
+ &::before {
1375
+ opacity: 0;
1376
+ scale: 0.5;
1377
+ transition-timing-function: ease-out;
1378
+ transition-duration: 200ms;
1379
+ transition-property: opacity, scale;
1380
+ }
1381
+
1382
+ & .media-slider__value {
1383
+ position: absolute;
1384
+ bottom: 2.25rem;
1385
+ text-shadow: 0 1px 0 var(--media-current-shadow-color);
1386
+ filter: blur(8px);
1387
+ translate: -50% 0.5rem;
1388
+ transition-property: filter, opacity, scale, translate;
1389
+ }
1390
+
1391
+ &::before {
1392
+ display: block;
1393
+ min-width: 0.25rem;
1394
+ height: 0.25rem;
1395
+ content: "";
1396
+ background-color: currentColor;
1397
+ border-radius: 100%;
1398
+ box-shadow:
1399
+ 0 0 0 1px var(--media-current-shadow-color, oklch(0 0 0 / 0.15)),
1400
+ 0 1px 2px 0 oklch(0 0 0 / 0.35);
1401
+ }
1402
+
1403
+ &[data-pointing] .media-slider__value,
1404
+ &[data-pointing]:not([data-dragging])::before {
1405
+ opacity: 1;
1406
+ scale: 1;
1407
+ }
1408
+ &[data-pointing] .media-slider__value {
1409
+ filter: blur(0);
1410
+ translate: -50% 0;
1411
+ }
1412
+ }
1413
+
1132
1414
  /* Shared track fills */
1133
1415
  .media-default-skin .media-slider__buffer,
1134
1416
  .media-default-skin .media-slider__fill {
@@ -1200,38 +1482,52 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1200
1482
  Popups & Tooltips
1201
1483
  ========================================================================== */
1202
1484
 
1485
+ .media-default-skin {
1486
+ --media-popup-transition:
1487
+ opacity var(--media-popup-transition-timing-function) var(--media-popup-transition-duration),
1488
+ filter var(--media-popup-transition-timing-function) var(--media-popup-transition-duration),
1489
+ transform var(--media-popup-transition-timing-function) var(--media-popup-transition-duration),
1490
+ scale var(--media-popup-transition-timing-function) var(--media-popup-transition-duration);
1491
+ }
1492
+
1203
1493
  .media-default-skin .media-popover,
1204
1494
  .media-default-skin .media-tooltip {
1495
+ --popup-translate-distance: 0.5rem;
1205
1496
  margin: 0;
1206
1497
  overflow: visible;
1207
1498
  color: inherit;
1208
1499
  border: 0;
1209
- filter: blur(0px);
1210
- transition-timing-function: var(--media-popup-transition-timing-function);
1211
- transition-duration: var(--media-popup-transition-duration);
1212
- transition-property: scale, opacity, filter;
1500
+ transition: var(--media-popup-transition);
1213
1501
 
1214
1502
  &[data-starting-style],
1215
1503
  &[data-ending-style] {
1216
1504
  opacity: 0;
1217
- filter: blur(8px);
1218
- scale: 0.85;
1505
+ filter: blur(4px);
1506
+ /* We have to use transform here for translate as the translate property is used for positioning by core. */
1507
+ transform: translate(var(--popup-translate-x-distance, 0), var(--popup-translate-y-distance, 0));
1508
+ scale: 0.95;
1219
1509
  }
1220
1510
 
1221
- &[data-instant] {
1222
- transition-duration: 0ms;
1511
+ &[data-ending-style] {
1512
+ transform: none;
1513
+ /* Speed up the exit transition. */
1514
+ transition-duration: max(0ms, calc(var(--media-popup-transition-duration) - 50ms));
1223
1515
  }
1224
1516
 
1225
1517
  &[data-side="top"] {
1518
+ --popup-translate-y-distance: var(--popup-translate-distance);
1226
1519
  transform-origin: bottom;
1227
1520
  }
1228
1521
  &[data-side="bottom"] {
1522
+ --popup-translate-y-distance: calc(var(--popup-translate-distance) * -1);
1229
1523
  transform-origin: top;
1230
1524
  }
1231
1525
  &[data-side="left"] {
1526
+ --popup-translate-x-distance: var(--popup-translate-distance);
1232
1527
  transform-origin: right;
1233
1528
  }
1234
1529
  &[data-side="right"] {
1530
+ --popup-translate-x-distance: calc(var(--popup-translate-distance) * -1);
1235
1531
  transform-origin: left;
1236
1532
  }
1237
1533
 
@@ -1292,6 +1588,13 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1292
1588
  white-space: nowrap;
1293
1589
  border-radius: calc(infinity * 1px);
1294
1590
 
1591
+ /* `display: flex` must not apply while closed — it overrides UA `[popover]` hiding. */
1592
+ &[data-open] {
1593
+ display: flex;
1594
+ column-gap: 0.25rem;
1595
+ align-items: center;
1596
+ }
1597
+
1295
1598
  &[data-side="top"]::before,
1296
1599
  &[data-side="bottom"]::before {
1297
1600
  height: var(--media-tooltip-side-offset);
@@ -1300,6 +1603,250 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1300
1603
  &[data-side="right"]::before {
1301
1604
  width: var(--media-tooltip-side-offset);
1302
1605
  }
1606
+
1607
+ & .media-tooltip__kbd {
1608
+ min-width: 1.5em;
1609
+ padding: 0.1em;
1610
+ font-family: inherit;
1611
+ font-size: 90%;
1612
+ font-weight: 600;
1613
+ line-height: 1.25;
1614
+ text-align: center;
1615
+ background-color: oklch(from currentColor l c h / 0.3);
1616
+ border-radius: 0.25rem;
1617
+ }
1618
+ }
1619
+
1620
+ /* ==========================================================================
1621
+ Menus
1622
+ Note: Menus use `.media-popover` styles for positioning and transitions.
1623
+ ========================================================================== */
1624
+
1625
+ .media-default-skin .media-menu {
1626
+ --menu-transition-duration: 250ms;
1627
+ --menu-max-height: 14rem;
1628
+ --menu-padding: 0.25rem;
1629
+ --menu-border-radius: 0.75rem;
1630
+ --menu-item-border-radius: calc(var(--menu-border-radius) - var(--menu-padding));
1631
+ box-sizing: border-box;
1632
+ max-width: var(--media-popover-available-width, none);
1633
+ max-height: min(var(--media-popover-available-height, var(--menu-max-height)), var(--menu-max-height));
1634
+ padding: var(--menu-padding);
1635
+ overflow: auto;
1636
+ overscroll-behavior: none;
1637
+ border-radius: var(--menu-border-radius);
1638
+
1639
+ @media (prefers-reduced-motion: reduce) {
1640
+ --menu-transition-duration: 0ms;
1641
+ }
1642
+
1643
+ & .media-menu__panel {
1644
+ position: absolute;
1645
+ inset: 0;
1646
+ padding: var(--menu-padding);
1647
+ overflow: auto;
1648
+ overscroll-behavior: none;
1649
+ outline: none;
1650
+ translate: 0 0;
1651
+ transition-timing-function: ease-in-out;
1652
+ transition-duration: var(--menu-transition-duration);
1653
+ transition-property: translate, filter;
1654
+ will-change: translate, filter;
1655
+
1656
+ &[data-starting-style],
1657
+ &[data-ending-style] {
1658
+ overflow: hidden;
1659
+ }
1660
+
1661
+ /* Root settings view — slides out when a submenu is active */
1662
+ &[data-menu-root-view][data-menu-view-state="inactive"] {
1663
+ filter: blur(8px);
1664
+ translate: -100% 0;
1665
+
1666
+ /* Hide the indicator while transitioning */
1667
+ & .media-menu__group::before {
1668
+ display: none;
1669
+ }
1670
+ }
1671
+
1672
+ /* Submenu panels — slide in/out alongside the root view */
1673
+ &[data-submenu] {
1674
+ z-index: 10;
1675
+
1676
+ &:not([data-open], [data-ending-style]) {
1677
+ translate: -100% 0;
1678
+ transition-property: none;
1679
+ }
1680
+
1681
+ &[data-starting-style],
1682
+ &[data-ending-style] {
1683
+ pointer-events: none;
1684
+ filter: blur(8px);
1685
+ }
1686
+
1687
+ &[data-starting-style][data-direction="forward"],
1688
+ &[data-ending-style][data-direction="back"] {
1689
+ translate: 100% 0;
1690
+ }
1691
+
1692
+ &[data-ending-style][data-direction="forward"],
1693
+ &[data-starting-style][data-direction="back"] {
1694
+ translate: -100% 0;
1695
+ }
1696
+ }
1697
+ }
1698
+
1699
+ & .media-menu__separator {
1700
+ margin-block: 0.25rem;
1701
+ border-bottom: 1px solid oklch(0 0 0 / 0.1);
1702
+ box-shadow: 0 1px 0 0 oklch(1 0 0 / 0.075);
1703
+ }
1704
+
1705
+ & .media-menu__group {
1706
+ display: flex;
1707
+ flex-direction: column;
1708
+ gap: 0.125rem;
1709
+
1710
+ @supports (top: anchor(top)) {
1711
+ &::before {
1712
+ position: absolute;
1713
+ position-anchor: --media-menu-item-highlight-anchor;
1714
+ inset: anchor(inside);
1715
+ pointer-events: none;
1716
+ content: "";
1717
+ background-color: oklch(from currentColor l c h / 0.1);
1718
+ border-radius: var(--menu-item-border-radius);
1719
+ transition: inset ease-in-out 100ms;
1720
+ }
1721
+ }
1722
+ }
1723
+
1724
+ & .media-menu__item,
1725
+ & .media-menu__back {
1726
+ display: flex;
1727
+ gap: 0.375rem;
1728
+ align-items: center;
1729
+ padding: 0.375rem 0.5rem;
1730
+ text-align: left;
1731
+ text-shadow: 0 1px 0 var(--media-current-shadow-color);
1732
+ cursor: pointer;
1733
+ user-select: none;
1734
+ outline: 2px solid transparent;
1735
+ outline-offset: -2px;
1736
+ border-radius: var(--menu-item-border-radius);
1737
+ transition: background-color, color;
1738
+ transition-timing-function: ease-out;
1739
+ transition-duration: 100ms;
1740
+
1741
+ &:focus-visible {
1742
+ outline-color: currentColor;
1743
+ outline-offset: 2px;
1744
+ }
1745
+
1746
+ &:hover,
1747
+ &[data-highlighted] {
1748
+ background-color: oklch(from currentColor l c h / 0.1);
1749
+
1750
+ @supports (top: anchor(top)) {
1751
+ anchor-name: --media-menu-item-highlight-anchor;
1752
+ background-color: transparent;
1753
+ }
1754
+ }
1755
+
1756
+ & .media-icon {
1757
+ flex-shrink: 0;
1758
+ color: oklch(from currentColor l c h / 0.65);
1759
+ filter: drop-shadow(0 1px 0 var(--media-current-shadow-color));
1760
+ }
1761
+ }
1762
+
1763
+ & .media-menu__indicator {
1764
+ flex-shrink: 0;
1765
+ margin-right: -0.25rem;
1766
+ margin-left: auto;
1767
+ opacity: 0;
1768
+
1769
+ & .media-icon {
1770
+ filter: drop-shadow(0 1px 0 var(--media-current-shadow-color));
1771
+ }
1772
+ }
1773
+
1774
+ & .media-menu__item {
1775
+ justify-content: space-between;
1776
+ font-variant-numeric: tabular-nums;
1777
+ color: inherit;
1778
+
1779
+ &[aria-disabled="true"] {
1780
+ pointer-events: none;
1781
+ cursor: not-allowed;
1782
+ opacity: 0.5;
1783
+ }
1784
+
1785
+ &[aria-checked="true"] .media-menu__indicator {
1786
+ opacity: 1;
1787
+ }
1788
+
1789
+ &[data-availability="unavailable"],
1790
+ &[data-availability="unsupported"] {
1791
+ display: none;
1792
+ }
1793
+ }
1794
+
1795
+ & .media-menu__tier {
1796
+ padding-top: 1px;
1797
+ padding-left: 0.125rem;
1798
+ font-size: 0.5625rem;
1799
+ font-weight: 600;
1800
+ line-height: 1;
1801
+ color: oklch(from currentColor l c h / 0.7);
1802
+ }
1803
+
1804
+ & .media-menu__back {
1805
+ width: 100%;
1806
+ margin-bottom: 0.125rem;
1807
+ }
1808
+
1809
+ & .media-menu__hint {
1810
+ display: inline-flex;
1811
+ gap: 0.25rem;
1812
+ align-items: center;
1813
+ min-width: 0;
1814
+ padding-left: 0.5rem;
1815
+ margin-left: auto;
1816
+ font-size: 0.75rem;
1817
+ color: oklch(from currentColor l c h / 0.65);
1818
+ }
1819
+
1820
+ & .media-menu__hint-label {
1821
+ max-width: 6rem;
1822
+ overflow: hidden;
1823
+ text-overflow: ellipsis;
1824
+ white-space: nowrap;
1825
+ }
1826
+
1827
+ & .media-menu__chevron {
1828
+ width: 0.875rem;
1829
+ height: 0.875rem;
1830
+ }
1831
+
1832
+ /* Settings menu */
1833
+ &.media-menu--settings {
1834
+ width: var(--media-menu-width);
1835
+ min-width: 12rem;
1836
+ height: var(--media-menu-height);
1837
+ overflow: hidden;
1838
+ /* Add height and width transitions. */
1839
+ transition:
1840
+ var(--media-popup-transition),
1841
+ height var(--media-popup-transition-timing-function) var(--menu-transition-duration),
1842
+ width var(--media-popup-transition-timing-function) var(--menu-transition-duration);
1843
+
1844
+ /* Don't transition width and height on open/close. */
1845
+ &[data-starting-style],
1846
+ &[data-ending-style] {
1847
+ transition: var(--media-popup-transition);
1848
+ }
1849
+ }
1303
1850
  }
1304
1851
 
1305
1852
  /* ==========================================================================
@@ -1438,126 +1985,127 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1438
1985
  border-radius: inherit;
1439
1986
  transition: --media-progress-fill 200ms linear;
1440
1987
  }
1441
- }
1442
1988
 
1443
- .media-default-skin .media-input-feedback-island--volume[data-level="high"] .media-icon--volume-high,
1444
- .media-default-skin .media-input-feedback-island--volume[data-level="low"] .media-icon--volume-low,
1445
- .media-default-skin .media-input-feedback-island--volume[data-level="off"] .media-icon--volume-off {
1446
- display: block;
1447
- }
1989
+ &[data-level="high"] .media-icon--volume-high,
1990
+ &[data-level="low"] .media-icon--volume-low,
1991
+ &[data-level="off"] .media-icon--volume-off {
1992
+ display: block;
1993
+ }
1448
1994
 
1449
- .media-default-skin .media-input-feedback-island--status[data-status="captions-on"] .media-icon--captions-on,
1450
- .media-default-skin .media-input-feedback-island--status[data-status="captions-off"] .media-icon--captions-off,
1451
- .media-default-skin .media-input-feedback-island--status[data-status="fullscreen"] .media-icon--fullscreen-enter,
1452
- .media-default-skin .media-input-feedback-island--status[data-status="exit-fullscreen"] .media-icon--fullscreen-exit,
1453
- .media-default-skin .media-input-feedback-island--status[data-status="pip"] .media-icon--pip-enter,
1454
- .media-default-skin .media-input-feedback-island--status[data-status="exit-pip"] .media-icon--pip-exit {
1455
- display: block;
1995
+ @media (prefers-reduced-motion: no-preference) {
1996
+ &[data-min],
1997
+ &[data-max] {
1998
+ animation: media-shake 300ms ease-in-out;
1999
+ }
2000
+ }
1456
2001
  }
1457
2002
 
1458
- /* --- Boundary shake ------------------------------------------------------- */
1459
-
1460
- @media (prefers-reduced-motion: no-preference) {
1461
- .media-default-skin .media-input-feedback-island--volume[data-min],
1462
- .media-default-skin .media-input-feedback-island--volume[data-max] {
1463
- animation: media-shake 300ms ease-in-out;
2003
+ .media-default-skin .media-input-feedback-island--status {
2004
+ &[data-status="captions-on"] .media-icon--captions-on,
2005
+ &[data-status="captions-off"] .media-icon--captions-off,
2006
+ &[data-status="fullscreen"] .media-icon--fullscreen-enter,
2007
+ &[data-status="exit-fullscreen"] .media-icon--fullscreen-exit,
2008
+ &[data-status="pip"] .media-icon--pip-enter,
2009
+ &[data-status="exit-pip"] .media-icon--pip-exit {
2010
+ display: block;
1464
2011
  }
1465
2012
  }
1466
2013
 
1467
2014
  /* --- Bubble ---------------------------------------------------------------- */
1468
2015
 
1469
2016
  .media-default-skin .media-input-feedback-bubble {
1470
- display: flex;
1471
- flex-direction: column;
2017
+ display: grid;
1472
2018
  grid-row: 1;
1473
- grid-column: 2; /* default to center for status bubbles and undirected seeks */
1474
- align-items: center;
1475
- justify-content: center;
2019
+ grid-column: 2;
2020
+ place-content: center;
1476
2021
  padding: 1rem;
1477
- transition: opacity 250ms ease-out;
1478
-
1479
- @container media-root (width > 24rem) {
1480
- padding: 2rem;
1481
- }
2022
+ text-align: center;
1482
2023
 
1483
- &[data-starting-style],
1484
- &[data-ending-style] {
1485
- opacity: 0;
1486
- transition-timing-function: ease-in;
2024
+ /* Central bubble (play, pause) */
2025
+ &:not([data-direction]) {
2026
+ background: oklch(0 0 0 / 0.35);
2027
+ border-radius: 100%;
2028
+ backdrop-filter: blur(8px);
2029
+ transition-timing-function: ease-out;
1487
2030
  transition-duration: 200ms;
1488
- }
1489
- }
2031
+ transition-property: opacity, scale;
1490
2032
 
1491
- /* Direction placement — seek bubbles move to the side implied by their direction. */
1492
- .media-default-skin .media-input-feedback-bubble[data-direction="backward"] {
1493
- grid-column: 1;
1494
- justify-self: left;
1495
- }
2033
+ &[data-starting-style],
2034
+ &[data-ending-style] {
2035
+ opacity: 0;
2036
+ scale: 0.85;
2037
+ }
1496
2038
 
1497
- .media-default-skin .media-input-feedback-bubble:not([data-direction]) {
1498
- grid-column: 2;
1499
- transition-timing-function:
1500
- ease-out, linear(0, 0.12 1.5%, 1.35 9.7%, 2.2 13.9%, 3 19.9%, 2.7 21.8%, 0.62 37.5%, 0.96 50.9%, 1);
1501
- transition-duration: 600ms;
1502
- transition-property: opacity, scale;
2039
+ &[data-ending-style] {
2040
+ transition-timing-function: ease-in;
2041
+ transition-duration: 100ms;
2042
+ }
1503
2043
 
1504
- @media (prefers-reduced-motion: reduce) {
1505
- transition: opacity 100ms ease-out;
2044
+ @media (prefers-reduced-motion: reduce) {
2045
+ transition-duration: 50ms;
2046
+ transition-property: opacity;
2047
+ }
1506
2048
  }
1507
2049
 
1508
- &[data-starting-style],
1509
- &[data-ending-style] {
1510
- opacity: 0;
1511
- scale: 0.8;
1512
- transition-timing-function: ease-in;
1513
- transition-duration: 200ms;
2050
+ /* Directional bubbles (seek) */
2051
+ &[data-direction] {
2052
+ gap: 0.25rem;
2053
+
2054
+ @container media-root (width > 24rem) {
2055
+ padding: 1.5rem;
2056
+ }
1514
2057
  }
1515
- }
1516
2058
 
1517
- .media-default-skin .media-input-feedback-bubble[data-direction="forward"] {
1518
- grid-column: 3;
1519
- justify-self: right;
1520
- }
2059
+ &[data-direction="backward"] {
2060
+ grid-column: 1;
2061
+ justify-self: left;
2062
+ }
1521
2063
 
1522
- /* --- Bubble icons ---------------------------------------------------------- */
2064
+ &[data-direction="forward"] {
2065
+ grid-column: 3;
2066
+ justify-self: right;
2067
+ }
1523
2068
 
1524
- .media-default-skin .media-input-feedback-bubble .media-icon {
1525
- display: none;
1526
- width: 36px;
1527
- height: 36px;
1528
- }
2069
+ /* Icons */
2070
+ .media-icon {
2071
+ display: none;
2072
+ width: calc(var(--media-icon-size) * 1.5);
2073
+ height: calc(var(--media-icon-size) * 1.5);
1529
2074
 
1530
- /* seek: seek icon, flipped for backward */
1531
- .media-default-skin .media-input-feedback-bubble[data-direction] .media-icon--seek {
1532
- display: block;
1533
- }
2075
+ &.media-icon--play {
2076
+ translate: 1px 0;
2077
+ }
2078
+ }
1534
2079
 
1535
- .media-default-skin .media-input-feedback-bubble[data-direction="backward"] .media-icon--seek {
1536
- transform: scaleX(-1);
1537
- }
2080
+ &[data-direction] .media-icon--seek,
2081
+ &[data-status="pause"] .media-icon--pause,
2082
+ &[data-status="play"] .media-icon--play {
2083
+ display: block;
2084
+ }
1538
2085
 
1539
- @media (prefers-reduced-motion: no-preference) {
1540
- .media-default-skin
1541
- .media-input-feedback-bubble[data-direction="forward"]:not([data-starting-style])
1542
- .media-icon--seek {
1543
- animation: media-slide-in-forward 300ms ease-in-out;
2086
+ &[data-direction="backward"] .media-icon--seek {
2087
+ scale: -1 1;
1544
2088
  }
1545
2089
 
1546
- .media-default-skin
1547
- .media-input-feedback-bubble[data-direction="backward"]:not([data-starting-style])
2090
+ @media (prefers-reduced-motion: no-preference) {
1548
2091
  .media-icon--seek {
1549
- animation: media-slide-in-backward 300ms ease-in-out;
1550
- }
2092
+ transition-timing-function: ease-in-out;
2093
+ transition-duration: 200ms;
2094
+ transition-property: translate, opacity;
2095
+ }
1551
2096
 
1552
- .media-default-skin .media-input-feedback-island--status[data-status]:not([data-starting-style]) .media-icon,
1553
- .media-default-skin .media-input-feedback-bubble[data-status]:not([data-starting-style]) .media-icon {
1554
- animation: media-pop-in 250ms ease-out;
1555
- }
1556
- }
2097
+ &[data-starting-style] .media-icon--seek,
2098
+ &[data-ending-style] .media-icon--seek {
2099
+ opacity: 0;
2100
+ }
1557
2101
 
1558
- .media-default-skin .media-input-feedback-bubble[data-status="pause"] .media-icon--pause,
1559
- .media-default-skin .media-input-feedback-bubble[data-status="play"] .media-icon--play {
1560
- display: block;
2102
+ &[data-direction="forward"][data-starting-style] .media-icon--seek {
2103
+ translate: -60% 0;
2104
+ }
2105
+ &[data-direction="backward"][data-starting-style] .media-icon--seek {
2106
+ translate: 60% 0;
2107
+ }
2108
+ }
1561
2109
  }
1562
2110
 
1563
2111
  /* ==========================================================================
@@ -1582,6 +2130,8 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1582
2130
  .media-button--pip .media-icon--pip-exit,
1583
2131
  .media-button--cast .media-icon--cast-enter,
1584
2132
  .media-button--cast .media-icon--cast-exit,
2133
+ .media-button--airplay .media-icon--airplay-enter,
2134
+ .media-button--airplay .media-icon--airplay-exit,
1585
2135
  .media-button--captions .media-icon--captions-off,
1586
2136
  .media-button--captions .media-icon--captions-on {
1587
2137
  display: none;
@@ -1592,10 +2142,11 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1592
2142
 
1593
2143
  /* Play: ended → restart */
1594
2144
  .media-button--play[data-ended] .media-icon--restart,
1595
- /* Play: paused (not ended) → play */
2145
+ /* Play: paused or not yet started (not ended) → play */
1596
2146
  .media-button--play:not([data-ended])[data-paused] .media-icon--play,
1597
- /* Play: playing (not paused, not ended) → pause */
1598
- .media-button--play:not([data-paused]):not([data-ended]) .media-icon--pause,
2147
+ .media-button--play:not([data-ended]):not([data-started]) .media-icon--play,
2148
+ /* Play: started and not paused/ended pause */
2149
+ .media-button--play[data-started]:not([data-paused]):not([data-ended]) .media-icon--pause,
1599
2150
  /* Mute: muted → volume off */
1600
2151
  .media-button--mute[data-muted] .media-icon--volume-off,
1601
2152
  /* Mute: volume low (not muted) → volume low */
@@ -1614,6 +2165,10 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1614
2165
  .media-button--cast:not([data-cast-state="connected"]) .media-icon--cast-enter,
1615
2166
  /* Cast: connected → exit */
1616
2167
  .media-button--cast[data-cast-state="connected"] .media-icon--cast-exit,
2168
+ /* AirPlay: not connected → enter */
2169
+ .media-button--airplay:not([data-airplay-state="connected"]) .media-icon--airplay-enter,
2170
+ /* AirPlay: connected → exit */
2171
+ .media-button--airplay[data-airplay-state="connected"] .media-icon--airplay-exit,
1617
2172
  /* Captions: not active → captions off */
1618
2173
  .media-button--captions:not([data-active]) .media-icon--captions-off,
1619
2174
  /* Captions: active → captions on */
@@ -1622,6 +2177,17 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1622
2177
  opacity: 1;
1623
2178
  }
1624
2179
 
2180
+ /* --- Pause keyframe animations on inactive icons --- */
2181
+
2182
+ /* The airplay-exit SVG defines its keyframes against CSS variables (mirroring
2183
+ the spinner pattern). When the AirPlay session isn't active the SVG is
2184
+ still in the DOM — just `display: none` — so its animations would keep
2185
+ running. Set the variables to `none` to short-circuit the keyframes. */
2186
+ .media-button--airplay:not([data-airplay-state="connected"]) {
2187
+ --media-icon--airplay__fill-animation: none;
2188
+ --media-icon--airplay__triangle-animation: none;
2189
+ }
2190
+
1625
2191
  /* -------------------------------------------------------------------------- */
1626
2192
  /* Global @keyframes for all video skins (CSS & Tailwind) */
1627
2193
  /* -------------------------------------------------------------------------- */
@@ -1645,27 +2211,6 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1645
2211
  }
1646
2212
  }
1647
2213
 
1648
- @keyframes media-slide-in-forward {
1649
- from {
1650
- translate: -60% 0;
1651
- opacity: 0;
1652
- }
1653
- }
1654
-
1655
- @keyframes media-slide-in-backward {
1656
- from {
1657
- translate: 60% 0;
1658
- opacity: 0;
1659
- }
1660
- }
1661
-
1662
- @keyframes media-pop-in {
1663
- from {
1664
- scale: 0.8;
1665
- opacity: 0;
1666
- }
1667
- }
1668
-
1669
2214
  /* -------------------------------------------------------------------------- */
1670
2215
  /* Global @properties for all video skins (CSS & Tailwind) */
1671
2216
  /* -------------------------------------------------------------------------- */
@@ -1711,6 +2256,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1711
2256
  --media-tooltip-boundary-offset: 0.5rem;
1712
2257
  --media-popover-side-offset: 0.5rem;
1713
2258
  --media-popover-boundary-offset: 0.5rem;
2259
+ overflow: clip;
1714
2260
  background: oklch(0 0 0);
1715
2261
 
1716
2262
  @media (prefers-reduced-motion: reduce) {
@@ -1818,8 +2364,6 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1818
2364
  bottom: 0.5rem;
1819
2365
  z-index: 10;
1820
2366
  flex-wrap: wrap;
1821
- max-width: 56rem;
1822
- margin-inline: auto;
1823
2367
  color: var(--media-color-primary, oklch(1 0 0));
1824
2368
  transform-origin: bottom;
1825
2369
  transition-timing-function: var(--media-controls-transition-timing-function);
@@ -1902,21 +2446,33 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1902
2446
  box-shadow: 0 0 0 1px oklch(0 0 0 / 0.05);
1903
2447
  }
1904
2448
 
1905
- .media-default-skin--video .media-slider__preview {
1906
- --media-preview-max-width: 11rem;
1907
- --media-preview-padding: -1.125rem;
2449
+ .media-default-skin--video .media-slider__thumbnail {
2450
+ --media-slider-thumbnail-max-width: 11rem;
2451
+ --media-slider-thumbnail-max-height: 8rem;
2452
+ --media-slider-thumbnail-padding: -1.125rem;
1908
2453
  /**
1909
2454
  Inset is the difference between the container width and the slider (100%) width.
1910
2455
  Divided by 2 as we render the time on both sides.
1911
2456
  */
1912
- --media-preview-inset: calc((100cqi - 100%) / 2);
2457
+ --media-slider-thumbnail-inset: calc((100cqi - 100%) / 2);
1913
2458
 
1914
2459
  position: absolute;
1915
2460
  bottom: calc(100% + 1.2rem);
1916
2461
  left: clamp(
1917
- calc(var(--media-preview-max-width) / 2 + var(--media-preview-padding) - var(--media-preview-inset)),
2462
+ calc(
2463
+ var(--media-slider-thumbnail-max-width) /
2464
+ 2 +
2465
+ var(--media-slider-thumbnail-padding) -
2466
+ var(--media-slider-thumbnail-inset)
2467
+ ),
1918
2468
  var(--media-slider-pointer),
1919
- calc(100% - var(--media-preview-max-width) / 2 - var(--media-preview-padding) + var(--media-preview-inset))
2469
+ calc(
2470
+ 100% -
2471
+ var(--media-slider-thumbnail-max-width) /
2472
+ 2 -
2473
+ var(--media-slider-thumbnail-padding) +
2474
+ var(--media-slider-thumbnail-inset)
2475
+ )
1920
2476
  );
1921
2477
  pointer-events: none;
1922
2478
  opacity: 0;
@@ -1928,19 +2484,22 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1928
2484
  transition-duration: 150ms;
1929
2485
  transition-property: scale, opacity, filter;
1930
2486
 
1931
- & .media-preview__thumbnail {
1932
- max-width: var(--media-preview-max-width);
1933
- }
1934
-
1935
- &:has(.media-preview__thumbnail[data-loading]) {
1936
- max-height: 6rem;
2487
+ & .media-thumbnail__image {
2488
+ max-width: var(--media-slider-thumbnail-max-width);
2489
+ max-height: var(--media-slider-thumbnail-max-height);
1937
2490
  }
1938
2491
  }
1939
- .media-default-skin--video .media-slider[data-pointing] .media-slider__preview:has([role="img"]:not([data-hidden])) {
2492
+ .media-default-skin--video .media-slider[data-pointing] .media-slider__thumbnail:has([role="img"]:not([data-hidden])) {
1940
2493
  opacity: 1;
1941
2494
  filter: blur(0);
1942
2495
  scale: 1;
1943
2496
  }
2497
+ .media-default-skin--video
2498
+ .media-slider__thumbnail:has([role="img"]:not([data-hidden]))
2499
+ + .media-slider__preview
2500
+ .media-slider__value {
2501
+ display: none;
2502
+ }
1944
2503
 
1945
2504
  ```
1946
2505
 
@@ -1948,7 +2507,7 @@ function isRenderProp(value: unknown): value is RenderProp<unknown> {
1948
2507
 
1949
2508
  Each skin is built with specific [features](./features.md) in mind. For example, a video skin renders fullscreen and picture-in-picture controls. An audio skin doesn’t.
1950
2509
 
1951
- You’ll find both a skin and the feature bundle it expects exported from the same path. We call these paths **presets** .
2510
+ You’ll find both a skin and the feature bundle it expects exported from the same path. We call these paths **presets**.
1952
2511
 
1953
2512
  Import
1954
2513
 
@@ -1968,11 +2527,17 @@ Feature bundle
1968
2527
 
1969
2528
  Features
1970
2529
 
1971
- [playback](../reference/feature-playback.md), [playbackRate](../reference/feature-playback-rate.md), [volume](../reference/feature-volume.md), [time](../reference/feature-time.md), [source](../reference/feature-source.md), [buffer](../reference/feature-buffer.md), [fullscreen](../reference/feature-fullscreen.md), [pip](../reference/feature-pip.md), [remotePlayback](../reference/feature-remote-playback.md), [controls](../reference/feature-controls.md), [textTrack](../reference/feature-text-tracks.md), [error](../reference/feature-error.md)
2530
+ [playback](../reference/feature-playback.md), [playbackRate](../reference/feature-playback-rate.md), [quality](../reference/feature-quality.md), [audioTrack](../reference/feature-audio-track.md), [volume](../reference/feature-volume.md), [time](../reference/feature-time.md), [source](../reference/feature-source.md), [buffer](../reference/feature-buffer.md), [fullscreen](../reference/feature-fullscreen.md), [pip](../reference/feature-pip.md), [remotePlayback](../reference/feature-remote-playback.md), [controls](../reference/feature-controls.md), [textTrack](../reference/feature-text-tracks.md), [error](../reference/feature-error.md)
1972
2531
 
1973
2532
  Skins
1974
2533
 
1975
- `<MinimalVideoSkin>`, `<VideoSkin>`
2534
+ `<MinimalVideoSkin>`
2535
+
2536
+ `import '@videojs/react/video/minimal-skin.css';`
2537
+
2538
+ `<VideoSkin>`
2539
+
2540
+ `import '@videojs/react/video/skin.css';`
1976
2541
 
1977
2542
  Default media element
1978
2543
 
@@ -1994,7 +2559,13 @@ Features
1994
2559
 
1995
2560
  Skins
1996
2561
 
1997
- `<MinimalAudioSkin>`, `<AudioSkin>`
2562
+ `<MinimalAudioSkin>`
2563
+
2564
+ `import '@videojs/react/audio/minimal-skin.css';`
2565
+
2566
+ `<AudioSkin>`
2567
+
2568
+ `import '@videojs/react/audio/skin.css';`
1998
2569
 
1999
2570
  Default media element
2000
2571
 
@@ -2018,6 +2589,8 @@ Skins
2018
2589
 
2019
2590
  `<BackgroundVideoSkin>`
2020
2591
 
2592
+ `import '@videojs/react/background/skin.css';`
2593
+
2021
2594
  Default media element
2022
2595
 
2023
2596
  `<BackgroundVideo>`
@@ -2038,7 +2611,13 @@ Features
2038
2611
 
2039
2612
  Skins
2040
2613
 
2041
- `<MinimalLiveAudioSkin>`, `<LiveAudioSkin>`
2614
+ `<MinimalLiveAudioSkin>`
2615
+
2616
+ `import '@videojs/react/live-audio/minimal-skin.css';`
2617
+
2618
+ `<LiveAudioSkin>`
2619
+
2620
+ `import '@videojs/react/live-audio/skin.css';`
2042
2621
 
2043
2622
  Default media element
2044
2623
 
@@ -2060,7 +2639,13 @@ Features
2060
2639
 
2061
2640
  Skins
2062
2641
 
2063
- `<MinimalLiveVideoSkin>`, `<LiveVideoSkin>`
2642
+ `<MinimalLiveVideoSkin>`
2643
+
2644
+ `import '@videojs/react/live-video/minimal-skin.css';`
2645
+
2646
+ `<LiveVideoSkin>`
2647
+
2648
+ `import '@videojs/react/live-video/skin.css';`
2064
2649
 
2065
2650
  Default media element
2066
2651
 
@@ -2074,7 +2659,7 @@ Presets are a topic quite a bit bigger than just this guide. To learn more, chec
2074
2659
 
2075
2660
  There are currently two options for styling:
2076
2661
 
2077
- * Vanilla CSS where you import the stylesheet in your app. This is the default.
2662
+ * Vanilla CSS import the stylesheet listed for each skin in the [preset table](#skins-features-and-presets). This is the default.
2078
2663
  * Tailwind where you [eject](../how-to/customize-skins#ejecting) the skin and use Tailwind classnames in your app.
2079
2664
 
2080
2665
  ### Current limitations