@hanifhan1f/vidstack-react 1.12.13

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 (284) hide show
  1. package/.templates/sandbox/document.css +27 -0
  2. package/.templates/sandbox/favicon-32x32.png +0 -0
  3. package/.templates/sandbox/index.html +21 -0
  4. package/.templates/sandbox/main.tsx +12 -0
  5. package/.templates/sandbox/player.css +39 -0
  6. package/.templates/sandbox/player.tsx +121 -0
  7. package/.templates/sandbox/tracks.ts +23 -0
  8. package/LICENSE +21 -0
  9. package/README.md +23 -0
  10. package/analyze.config.ts +7 -0
  11. package/build/build-icons.js +62 -0
  12. package/npm/analyze.json.d.ts +7 -0
  13. package/package.json +162 -0
  14. package/rollup.config.ts +256 -0
  15. package/src/components/announcer.tsx +47 -0
  16. package/src/components/layouts/default/audio-layout.tsx +231 -0
  17. package/src/components/layouts/default/context.ts +28 -0
  18. package/src/components/layouts/default/hooks.ts +13 -0
  19. package/src/components/layouts/default/icons.tsx +225 -0
  20. package/src/components/layouts/default/index.ts +11 -0
  21. package/src/components/layouts/default/media-layout.tsx +259 -0
  22. package/src/components/layouts/default/slots.tsx +98 -0
  23. package/src/components/layouts/default/ui/announcer.tsx +22 -0
  24. package/src/components/layouts/default/ui/buttons.tsx +301 -0
  25. package/src/components/layouts/default/ui/captions.tsx +16 -0
  26. package/src/components/layouts/default/ui/controls.tsx +12 -0
  27. package/src/components/layouts/default/ui/keyboard-display.tsx +132 -0
  28. package/src/components/layouts/default/ui/menus/accessibility-menu.tsx +100 -0
  29. package/src/components/layouts/default/ui/menus/audio-menu.tsx +167 -0
  30. package/src/components/layouts/default/ui/menus/captions-menu.tsx +61 -0
  31. package/src/components/layouts/default/ui/menus/chapters-menu.tsx +132 -0
  32. package/src/components/layouts/default/ui/menus/font-menu.tsx +331 -0
  33. package/src/components/layouts/default/ui/menus/items/menu-checkbox.tsx +72 -0
  34. package/src/components/layouts/default/ui/menus/items/menu-items.tsx +135 -0
  35. package/src/components/layouts/default/ui/menus/items/menu-slider.tsx +92 -0
  36. package/src/components/layouts/default/ui/menus/playback-menu.tsx +232 -0
  37. package/src/components/layouts/default/ui/menus/settings-menu.tsx +114 -0
  38. package/src/components/layouts/default/ui/menus/utils.ts +12 -0
  39. package/src/components/layouts/default/ui/sliders.tsx +136 -0
  40. package/src/components/layouts/default/ui/time.tsx +73 -0
  41. package/src/components/layouts/default/ui/title.tsx +24 -0
  42. package/src/components/layouts/default/ui/tooltip.tsx +27 -0
  43. package/src/components/layouts/default/ui.ts +8 -0
  44. package/src/components/layouts/default/video-layout.tsx +344 -0
  45. package/src/components/layouts/plyr/context.ts +26 -0
  46. package/src/components/layouts/plyr/icons/plyr-airplay.js +1 -0
  47. package/src/components/layouts/plyr/icons/plyr-captions-off.js +1 -0
  48. package/src/components/layouts/plyr/icons/plyr-captions-on.js +1 -0
  49. package/src/components/layouts/plyr/icons/plyr-download.js +1 -0
  50. package/src/components/layouts/plyr/icons/plyr-enter-fullscreen.js +1 -0
  51. package/src/components/layouts/plyr/icons/plyr-exit-fullscreen.js +1 -0
  52. package/src/components/layouts/plyr/icons/plyr-fast-forward.js +1 -0
  53. package/src/components/layouts/plyr/icons/plyr-muted.js +1 -0
  54. package/src/components/layouts/plyr/icons/plyr-pause.js +1 -0
  55. package/src/components/layouts/plyr/icons/plyr-pip.js +1 -0
  56. package/src/components/layouts/plyr/icons/plyr-play.js +1 -0
  57. package/src/components/layouts/plyr/icons/plyr-restart.js +1 -0
  58. package/src/components/layouts/plyr/icons/plyr-rewind.js +1 -0
  59. package/src/components/layouts/plyr/icons/plyr-settings.js +1 -0
  60. package/src/components/layouts/plyr/icons/plyr-volume.js +1 -0
  61. package/src/components/layouts/plyr/icons.tsx +71 -0
  62. package/src/components/layouts/plyr/index.ts +11 -0
  63. package/src/components/layouts/plyr/layout.tsx +1024 -0
  64. package/src/components/layouts/plyr/props.ts +104 -0
  65. package/src/components/layouts/plyr/slots.tsx +52 -0
  66. package/src/components/layouts/remotion-ui.ts +13 -0
  67. package/src/components/layouts/utils.ts +17 -0
  68. package/src/components/player-callbacks.ts +67 -0
  69. package/src/components/player.tsx +67 -0
  70. package/src/components/primitives/instances.ts +92 -0
  71. package/src/components/primitives/nodes.tsx +58 -0
  72. package/src/components/primitives/slot.tsx +132 -0
  73. package/src/components/provider.tsx +187 -0
  74. package/src/components/text-track.tsx +106 -0
  75. package/src/components/ui/buttons/airplay-button.tsx +53 -0
  76. package/src/components/ui/buttons/caption-button.tsx +55 -0
  77. package/src/components/ui/buttons/fullscreen-button.tsx +55 -0
  78. package/src/components/ui/buttons/google-cast-button.tsx +53 -0
  79. package/src/components/ui/buttons/live-button.tsx +56 -0
  80. package/src/components/ui/buttons/mute-button.tsx +60 -0
  81. package/src/components/ui/buttons/pip-button.tsx +54 -0
  82. package/src/components/ui/buttons/play-button.tsx +53 -0
  83. package/src/components/ui/buttons/seek-button.tsx +55 -0
  84. package/src/components/ui/buttons/toggle-button.tsx +51 -0
  85. package/src/components/ui/caption.tsx +70 -0
  86. package/src/components/ui/captions.tsx +41 -0
  87. package/src/components/ui/chapter-title.tsx +40 -0
  88. package/src/components/ui/controls.tsx +90 -0
  89. package/src/components/ui/gesture.tsx +43 -0
  90. package/src/components/ui/menu.tsx +251 -0
  91. package/src/components/ui/poster.tsx +101 -0
  92. package/src/components/ui/radio-group.tsx +88 -0
  93. package/src/components/ui/sliders/audio-gain-slider.tsx +55 -0
  94. package/src/components/ui/sliders/quality-slider.tsx +54 -0
  95. package/src/components/ui/sliders/slider-callbacks.ts +14 -0
  96. package/src/components/ui/sliders/slider-value.tsx +13 -0
  97. package/src/components/ui/sliders/slider.tsx +254 -0
  98. package/src/components/ui/sliders/speed-slider.tsx +54 -0
  99. package/src/components/ui/sliders/time-slider.tsx +379 -0
  100. package/src/components/ui/sliders/volume-slider.tsx +55 -0
  101. package/src/components/ui/spinner.tsx +105 -0
  102. package/src/components/ui/thumbnail.tsx +82 -0
  103. package/src/components/ui/time.tsx +77 -0
  104. package/src/components/ui/title.tsx +32 -0
  105. package/src/components/ui/tooltip.tsx +135 -0
  106. package/src/globals.d.ts +3 -0
  107. package/src/hooks/create-text-track.ts +22 -0
  108. package/src/hooks/options/use-audio-gain-options.ts +75 -0
  109. package/src/hooks/options/use-audio-options.ts +71 -0
  110. package/src/hooks/options/use-caption-options.ts +95 -0
  111. package/src/hooks/options/use-chapter-options.ts +97 -0
  112. package/src/hooks/options/use-playback-rate-options.ts +75 -0
  113. package/src/hooks/options/use-video-quality-options.ts +123 -0
  114. package/src/hooks/use-active-text-cues.ts +28 -0
  115. package/src/hooks/use-active-text-track.ts +19 -0
  116. package/src/hooks/use-chapter-title.ts +12 -0
  117. package/src/hooks/use-dom.ts +121 -0
  118. package/src/hooks/use-media-context.ts +6 -0
  119. package/src/hooks/use-media-player.ts +19 -0
  120. package/src/hooks/use-media-provider.ts +31 -0
  121. package/src/hooks/use-media-remote.ts +37 -0
  122. package/src/hooks/use-media-state.ts +58 -0
  123. package/src/hooks/use-signals.ts +24 -0
  124. package/src/hooks/use-slider-preview.ts +126 -0
  125. package/src/hooks/use-slider-state.ts +63 -0
  126. package/src/hooks/use-state.ts +47 -0
  127. package/src/hooks/use-text-cues.ts +33 -0
  128. package/src/hooks/use-thumbnails.ts +69 -0
  129. package/src/icon.ts +37 -0
  130. package/src/icons.ts +754 -0
  131. package/src/index.ts +181 -0
  132. package/src/providers/remotion/index.ts +10 -0
  133. package/src/providers/remotion/layout-engine.ts +123 -0
  134. package/src/providers/remotion/loader.ts +35 -0
  135. package/src/providers/remotion/playback-engine.ts +142 -0
  136. package/src/providers/remotion/provider.tsx +514 -0
  137. package/src/providers/remotion/type-check.ts +13 -0
  138. package/src/providers/remotion/types.ts +94 -0
  139. package/src/providers/remotion/ui/context.tsx +120 -0
  140. package/src/providers/remotion/ui/error-boundary.tsx +57 -0
  141. package/src/providers/remotion/ui/poster.tsx +33 -0
  142. package/src/providers/remotion/ui/slider-thumbnail.tsx +41 -0
  143. package/src/providers/remotion/ui/thumbnail.tsx +166 -0
  144. package/src/providers/remotion/validate.ts +220 -0
  145. package/src/source.ts +5 -0
  146. package/src/utils.ts +27 -0
  147. package/tsconfig.build.json +10 -0
  148. package/tsconfig.json +11 -0
  149. package/types/react/src/components/announcer.d.ts +16 -0
  150. package/types/react/src/components/layouts/default/audio-layout.d.ts +27 -0
  151. package/types/react/src/components/layouts/default/context.d.ts +14 -0
  152. package/types/react/src/components/layouts/default/hooks.d.ts +2 -0
  153. package/types/react/src/components/layouts/default/icons.d.ts +95 -0
  154. package/types/react/src/components/layouts/default/index.d.ts +5 -0
  155. package/types/react/src/components/layouts/default/media-layout.d.ts +133 -0
  156. package/types/react/src/components/layouts/default/slots.d.ts +22 -0
  157. package/types/react/src/components/layouts/default/ui/announcer.d.ts +6 -0
  158. package/types/react/src/components/layouts/default/ui/buttons.d.ts +54 -0
  159. package/types/react/src/components/layouts/default/ui/captions.d.ts +6 -0
  160. package/types/react/src/components/layouts/default/ui/controls.d.ts +6 -0
  161. package/types/react/src/components/layouts/default/ui/keyboard-display.d.ts +8 -0
  162. package/types/react/src/components/layouts/default/ui/menus/accessibility-menu.d.ts +10 -0
  163. package/types/react/src/components/layouts/default/ui/menus/audio-menu.d.ts +10 -0
  164. package/types/react/src/components/layouts/default/ui/menus/captions-menu.d.ts +10 -0
  165. package/types/react/src/components/layouts/default/ui/menus/chapters-menu.d.ts +7 -0
  166. package/types/react/src/components/layouts/default/ui/menus/font-menu.d.ts +6 -0
  167. package/types/react/src/components/layouts/default/ui/menus/items/menu-checkbox.d.ts +13 -0
  168. package/types/react/src/components/layouts/default/ui/menus/items/menu-items.d.ts +49 -0
  169. package/types/react/src/components/layouts/default/ui/menus/items/menu-slider.d.ts +26 -0
  170. package/types/react/src/components/layouts/default/ui/menus/playback-menu.d.ts +10 -0
  171. package/types/react/src/components/layouts/default/ui/menus/settings-menu.d.ts +15 -0
  172. package/types/react/src/components/layouts/default/ui/menus/utils.d.ts +1 -0
  173. package/types/react/src/components/layouts/default/ui/sliders.d.ts +24 -0
  174. package/types/react/src/components/layouts/default/ui/time.d.ts +30 -0
  175. package/types/react/src/components/layouts/default/ui/title.d.ts +6 -0
  176. package/types/react/src/components/layouts/default/ui/tooltip.d.ts +12 -0
  177. package/types/react/src/components/layouts/default/ui.d.ts +8 -0
  178. package/types/react/src/components/layouts/default/video-layout.d.ts +47 -0
  179. package/types/react/src/components/layouts/plyr/context.d.ts +12 -0
  180. package/types/react/src/components/layouts/plyr/icons/plyr-airplay.d.ts +2 -0
  181. package/types/react/src/components/layouts/plyr/icons/plyr-captions-off.d.ts +2 -0
  182. package/types/react/src/components/layouts/plyr/icons/plyr-captions-on.d.ts +2 -0
  183. package/types/react/src/components/layouts/plyr/icons/plyr-download.d.ts +2 -0
  184. package/types/react/src/components/layouts/plyr/icons/plyr-enter-fullscreen.d.ts +2 -0
  185. package/types/react/src/components/layouts/plyr/icons/plyr-exit-fullscreen.d.ts +2 -0
  186. package/types/react/src/components/layouts/plyr/icons/plyr-fast-forward.d.ts +2 -0
  187. package/types/react/src/components/layouts/plyr/icons/plyr-muted.d.ts +2 -0
  188. package/types/react/src/components/layouts/plyr/icons/plyr-pause.d.ts +2 -0
  189. package/types/react/src/components/layouts/plyr/icons/plyr-pip.d.ts +2 -0
  190. package/types/react/src/components/layouts/plyr/icons/plyr-play.d.ts +2 -0
  191. package/types/react/src/components/layouts/plyr/icons/plyr-restart.d.ts +2 -0
  192. package/types/react/src/components/layouts/plyr/icons/plyr-rewind.d.ts +2 -0
  193. package/types/react/src/components/layouts/plyr/icons/plyr-settings.d.ts +2 -0
  194. package/types/react/src/components/layouts/plyr/icons/plyr-volume.d.ts +2 -0
  195. package/types/react/src/components/layouts/plyr/icons.d.ts +25 -0
  196. package/types/react/src/components/layouts/plyr/index.d.ts +6 -0
  197. package/types/react/src/components/layouts/plyr/layout.d.ts +17 -0
  198. package/types/react/src/components/layouts/plyr/props.d.ts +71 -0
  199. package/types/react/src/components/layouts/plyr/slots.d.ts +9 -0
  200. package/types/react/src/components/layouts/remotion-ui.d.ts +3 -0
  201. package/types/react/src/components/layouts/utils.d.ts +1 -0
  202. package/types/react/src/components/player-callbacks.d.ts +6 -0
  203. package/types/react/src/components/player.d.ts +32 -0
  204. package/types/react/src/components/primitives/instances.d.ts +83 -0
  205. package/types/react/src/components/primitives/nodes.d.ts +15 -0
  206. package/types/react/src/components/primitives/slot.d.ts +11 -0
  207. package/types/react/src/components/provider.d.ts +26 -0
  208. package/types/react/src/components/text-track.d.ts +100 -0
  209. package/types/react/src/components/ui/buttons/airplay-button.d.ts +22 -0
  210. package/types/react/src/components/ui/buttons/caption-button.d.ts +24 -0
  211. package/types/react/src/components/ui/buttons/fullscreen-button.d.ts +24 -0
  212. package/types/react/src/components/ui/buttons/google-cast-button.d.ts +22 -0
  213. package/types/react/src/components/ui/buttons/live-button.d.ts +26 -0
  214. package/types/react/src/components/ui/buttons/mute-button.d.ts +30 -0
  215. package/types/react/src/components/ui/buttons/pip-button.d.ts +24 -0
  216. package/types/react/src/components/ui/buttons/play-button.d.ts +23 -0
  217. package/types/react/src/components/ui/buttons/seek-button.d.ts +25 -0
  218. package/types/react/src/components/ui/buttons/toggle-button.d.ts +22 -0
  219. package/types/react/src/components/ui/caption.d.ts +11 -0
  220. package/types/react/src/components/ui/captions.d.ts +20 -0
  221. package/types/react/src/components/ui/chapter-title.d.ts +20 -0
  222. package/types/react/src/components/ui/controls.d.ts +40 -0
  223. package/types/react/src/components/ui/gesture.d.ts +20 -0
  224. package/types/react/src/components/ui/menu.d.ts +102 -0
  225. package/types/react/src/components/ui/poster.d.ts +25 -0
  226. package/types/react/src/components/ui/radio-group.d.ts +39 -0
  227. package/types/react/src/components/ui/sliders/audio-gain-slider.d.ts +29 -0
  228. package/types/react/src/components/ui/sliders/quality-slider.d.ts +28 -0
  229. package/types/react/src/components/ui/sliders/slider-callbacks.d.ts +6 -0
  230. package/types/react/src/components/ui/sliders/slider-value.d.ts +9 -0
  231. package/types/react/src/components/ui/sliders/slider.d.ts +134 -0
  232. package/types/react/src/components/ui/sliders/speed-slider.d.ts +28 -0
  233. package/types/react/src/components/ui/sliders/time-slider.d.ts +124 -0
  234. package/types/react/src/components/ui/sliders/volume-slider.d.ts +29 -0
  235. package/types/react/src/components/ui/spinner.d.ts +31 -0
  236. package/types/react/src/components/ui/thumbnail.d.ts +26 -0
  237. package/types/react/src/components/ui/time.d.ts +20 -0
  238. package/types/react/src/components/ui/title.d.ts +15 -0
  239. package/types/react/src/components/ui/tooltip.d.ts +63 -0
  240. package/types/react/src/hooks/create-text-track.d.ts +7 -0
  241. package/types/react/src/hooks/options/use-audio-gain-options.d.ts +22 -0
  242. package/types/react/src/hooks/options/use-audio-options.d.ts +17 -0
  243. package/types/react/src/hooks/options/use-caption-options.d.ts +24 -0
  244. package/types/react/src/hooks/options/use-chapter-options.d.ts +18 -0
  245. package/types/react/src/hooks/options/use-playback-rate-options.d.ts +22 -0
  246. package/types/react/src/hooks/options/use-video-quality-options.d.ts +35 -0
  247. package/types/react/src/hooks/use-active-text-cues.d.ts +6 -0
  248. package/types/react/src/hooks/use-active-text-track.d.ts +5 -0
  249. package/types/react/src/hooks/use-chapter-title.d.ts +4 -0
  250. package/types/react/src/hooks/use-dom.d.ts +9 -0
  251. package/types/react/src/hooks/use-media-context.d.ts +1 -0
  252. package/types/react/src/hooks/use-media-player.d.ts +7 -0
  253. package/types/react/src/hooks/use-media-provider.d.ts +7 -0
  254. package/types/react/src/hooks/use-media-remote.d.ts +12 -0
  255. package/types/react/src/hooks/use-media-state.d.ts +15 -0
  256. package/types/react/src/hooks/use-signals.d.ts +5 -0
  257. package/types/react/src/hooks/use-slider-preview.d.ts +27 -0
  258. package/types/react/src/hooks/use-slider-state.d.ts +16 -0
  259. package/types/react/src/hooks/use-state.d.ts +18 -0
  260. package/types/react/src/hooks/use-text-cues.d.ts +6 -0
  261. package/types/react/src/hooks/use-thumbnails.d.ts +16 -0
  262. package/types/react/src/icon.d.ts +17 -0
  263. package/types/react/src/icons.d.ts +215 -0
  264. package/types/react/src/index.d.ts +78 -0
  265. package/types/react/src/providers/remotion/index.d.ts +7 -0
  266. package/types/react/src/providers/remotion/layout-engine.d.ts +8 -0
  267. package/types/react/src/providers/remotion/loader.d.ts +9 -0
  268. package/types/react/src/providers/remotion/playback-engine.d.ts +11 -0
  269. package/types/react/src/providers/remotion/provider.d.ts +26 -0
  270. package/types/react/src/providers/remotion/type-check.d.ts +6 -0
  271. package/types/react/src/providers/remotion/types.d.ts +91 -0
  272. package/types/react/src/providers/remotion/ui/context.d.ts +17 -0
  273. package/types/react/src/providers/remotion/ui/error-boundary.d.ts +21 -0
  274. package/types/react/src/providers/remotion/ui/poster.d.ts +18 -0
  275. package/types/react/src/providers/remotion/ui/slider-thumbnail.d.ts +17 -0
  276. package/types/react/src/providers/remotion/ui/thumbnail.d.ts +32 -0
  277. package/types/react/src/providers/remotion/validate.d.ts +12 -0
  278. package/types/react/src/source.d.ts +3 -0
  279. package/types/react/src/utils.d.ts +3 -0
  280. package/types/vidstack/src/core/api/src-types.d.ts +50 -0
  281. package/types/vidstack/src/utils/mime.d.ts +15 -0
  282. package/types/vidstack/src/utils/network.d.ts +17 -0
  283. package/types/vidstack/src/utils/support.d.ts +72 -0
  284. package/vite.config.ts +23 -0
@@ -0,0 +1,136 @@
1
+ import * as React from 'react';
2
+
3
+ import { useSignal } from 'maverick.js/react';
4
+ import type { SliderOrientation, TooltipPlacement } from 'vidstack';
5
+
6
+ import { useActive, useResizeObserver } from '../../../../hooks/use-dom';
7
+ import { useMediaState } from '../../../../hooks/use-media-state';
8
+ import { isRemotionSrc } from '../../../../providers/remotion/type-check';
9
+ import type { TimeSliderInstance } from '../../../primitives/instances';
10
+ import * as TimeSlider from '../../../ui/sliders/time-slider';
11
+ import * as VolumeSlider from '../../../ui/sliders/volume-slider';
12
+ import { RemotionSliderThumbnail } from '../../remotion-ui';
13
+ import { useDefaultLayoutContext, useDefaultLayoutWord } from '../context';
14
+ import { slot, type DefaultLayoutSlots } from '../slots';
15
+ import { DefaultMuteButton } from './buttons';
16
+
17
+ /* -------------------------------------------------------------------------------------------------
18
+ * DefaultVolumePopup
19
+ * -----------------------------------------------------------------------------------------------*/
20
+
21
+ export interface DefaultVolumePopupProps {
22
+ slots?: DefaultLayoutSlots;
23
+ tooltip: TooltipPlacement;
24
+ orientation: SliderOrientation;
25
+ }
26
+
27
+ function DefaultVolumePopup({ tooltip, orientation, slots }: DefaultVolumePopupProps) {
28
+ const $pointer = useMediaState('pointer'),
29
+ $muted = useMediaState('muted'),
30
+ $canSetVolume = useMediaState('canSetVolume'),
31
+ [rootEl, setRootEl] = React.useState<HTMLElement | null>(null),
32
+ isRootActive = useActive(rootEl),
33
+ muteButton = slot(slots, 'muteButton', <DefaultMuteButton tooltip={tooltip} />);
34
+
35
+ if (!$canSetVolume) {
36
+ return muteButton;
37
+ }
38
+
39
+ return $pointer === 'coarse' && !$muted ? null : (
40
+ <div className="vds-volume" data-active={isRootActive ? '' : null} ref={setRootEl}>
41
+ {muteButton}
42
+ <div className="vds-volume-popup">
43
+ {slot(slots, 'volumeSlider', <DefaultVolumeSlider orientation={orientation} />)}
44
+ </div>
45
+ </div>
46
+ );
47
+ }
48
+
49
+ DefaultVolumePopup.displayName = 'DefaultVolumePopup';
50
+ export { DefaultVolumePopup };
51
+
52
+ /* -------------------------------------------------------------------------------------------------
53
+ * DefaultVolumeSlider
54
+ * -----------------------------------------------------------------------------------------------*/
55
+
56
+ function DefaultVolumeSlider(props: VolumeSlider.RootProps) {
57
+ const label = useDefaultLayoutWord('Volume');
58
+ return (
59
+ <VolumeSlider.Root className="vds-volume-slider vds-slider" aria-label={label} {...props}>
60
+ <VolumeSlider.Track className="vds-slider-track" />
61
+ <VolumeSlider.TrackFill className="vds-slider-track-fill vds-slider-track" />
62
+ <VolumeSlider.Thumb className="vds-slider-thumb" />
63
+ <VolumeSlider.Preview className="vds-slider-preview" noClamp>
64
+ <VolumeSlider.Value className="vds-slider-value" />
65
+ </VolumeSlider.Preview>
66
+ </VolumeSlider.Root>
67
+ );
68
+ }
69
+
70
+ DefaultVolumeSlider.displayName = 'DefaultVolumeSlider';
71
+ export { DefaultVolumeSlider };
72
+
73
+ /* -------------------------------------------------------------------------------------------------
74
+ * DefaultTimeSlider
75
+ * -----------------------------------------------------------------------------------------------*/
76
+
77
+ function DefaultTimeSlider() {
78
+ const [instance, setInstance] = React.useState<TimeSliderInstance | null>(null),
79
+ [width, setWidth] = React.useState(0),
80
+ $src = useMediaState('currentSrc'),
81
+ { thumbnails, sliderChaptersMinWidth, disableTimeSlider, seekStep, noScrubGesture } =
82
+ useDefaultLayoutContext(),
83
+ label = useDefaultLayoutWord('Seek'),
84
+ $RemotionSliderThumbnail = useSignal(RemotionSliderThumbnail);
85
+
86
+ const onResize = React.useCallback(() => {
87
+ const el = instance?.el;
88
+ el && setWidth(el.clientWidth);
89
+ }, [instance]);
90
+
91
+ useResizeObserver(instance?.el, onResize);
92
+
93
+ return (
94
+ <TimeSlider.Root
95
+ className="vds-time-slider vds-slider"
96
+ aria-label={label}
97
+ disabled={disableTimeSlider}
98
+ noSwipeGesture={noScrubGesture}
99
+ keyStep={seekStep}
100
+ ref={setInstance}
101
+ >
102
+ <TimeSlider.Chapters
103
+ className="vds-slider-chapters"
104
+ disabled={width < sliderChaptersMinWidth!}
105
+ >
106
+ {(cues, forwardRef) =>
107
+ cues.map((cue) => (
108
+ <div className="vds-slider-chapter" key={cue.startTime} ref={forwardRef}>
109
+ <TimeSlider.Track className="vds-slider-track" />
110
+ <TimeSlider.TrackFill className="vds-slider-track-fill vds-slider-track" />
111
+ <TimeSlider.Progress className="vds-slider-progress vds-slider-track" />
112
+ </div>
113
+ ))
114
+ }
115
+ </TimeSlider.Chapters>
116
+ <TimeSlider.Thumb className="vds-slider-thumb" />
117
+ <TimeSlider.Preview className="vds-slider-preview">
118
+ {thumbnails ? (
119
+ <TimeSlider.Thumbnail.Root
120
+ src={thumbnails}
121
+ className="vds-slider-thumbnail vds-thumbnail"
122
+ >
123
+ <TimeSlider.Thumbnail.Img />
124
+ </TimeSlider.Thumbnail.Root>
125
+ ) : $RemotionSliderThumbnail && isRemotionSrc($src) ? (
126
+ <$RemotionSliderThumbnail className="vds-slider-thumbnail vds-thumbnail" />
127
+ ) : null}
128
+ <TimeSlider.ChapterTitle className="vds-slider-chapter-title" />
129
+ <TimeSlider.Value className="vds-slider-value" />
130
+ </TimeSlider.Preview>
131
+ </TimeSlider.Root>
132
+ );
133
+ }
134
+
135
+ DefaultTimeSlider.displayName = 'DefaultTimeSlider';
136
+ export { DefaultTimeSlider };
@@ -0,0 +1,73 @@
1
+ import * as React from 'react';
2
+
3
+ /* -------------------------------------------------------------------------------------------------
4
+ * DefaultTimeGroup
5
+ * -----------------------------------------------------------------------------------------------*/
6
+
7
+ import { useMediaState } from '../../../../hooks/use-media-state';
8
+ import { Time } from '../../../ui/time';
9
+ import { slot } from '../slots';
10
+ import { DefaultLiveButton } from './buttons';
11
+
12
+ interface DefaultTimeGroupSlots {
13
+ currentTime?: React.ReactNode;
14
+ timeDivider?: React.ReactNode;
15
+ endTime?: React.ReactNode;
16
+ }
17
+
18
+ function DefaultTimeGroup({ slots }: { slots?: DefaultTimeGroupSlots }) {
19
+ const $duration = useMediaState('duration');
20
+
21
+ if (!$duration) return null;
22
+
23
+ return (
24
+ <div className="vds-time-group">
25
+ {slot(slots, 'currentTime', <Time className="vds-time" type="current" />)}
26
+ {slot(slots, 'timeDivider', <div className="vds-time-divider">/</div>)}
27
+ {slot(slots, 'endTime', <Time className="vds-time" type="duration" />)}
28
+ </div>
29
+ );
30
+ }
31
+
32
+ DefaultTimeGroup.displayName = 'DefaultTimeGroup';
33
+ export { DefaultTimeGroup };
34
+
35
+ /* -------------------------------------------------------------------------------------------------
36
+ * DefaultTimeInfo
37
+ * -----------------------------------------------------------------------------------------------*/
38
+
39
+ interface DefaultTimeInfoSlots extends DefaultTimeGroupSlots {
40
+ liveButton?: React.ReactNode;
41
+ }
42
+
43
+ function DefaultTimeInfo({ slots }: { slots?: DefaultTimeInfoSlots }) {
44
+ const $live = useMediaState('live');
45
+ return $live ? (
46
+ slot(slots, 'liveButton', <DefaultLiveButton />)
47
+ ) : (
48
+ <DefaultTimeGroup slots={slots} />
49
+ );
50
+ }
51
+
52
+ DefaultTimeInfo.displayName = 'DefaultTimeInfo';
53
+ export { DefaultTimeInfo };
54
+
55
+ /* -------------------------------------------------------------------------------------------------
56
+ * DefaultTimeInvert
57
+ * -----------------------------------------------------------------------------------------------*/
58
+
59
+ function DefaultTimeInvert({ slots }: { slots?: DefaultTimeInfoSlots }) {
60
+ const $live = useMediaState('live'),
61
+ $duration = useMediaState('duration');
62
+
63
+ return $live
64
+ ? slot(slots, 'liveButton', <DefaultLiveButton />)
65
+ : slot(
66
+ slots,
67
+ 'endTime',
68
+ $duration ? <Time className="vds-time" type="current" toggle remainder /> : null,
69
+ );
70
+ }
71
+
72
+ DefaultTimeInvert.displayName = 'DefaultTimeInvert';
73
+ export { DefaultTimeInvert };
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+
3
+ import { useActiveTextTrack } from '../../../../hooks/use-active-text-track';
4
+ import { useMediaState } from '../../../../hooks/use-media-state';
5
+ import { ChapterTitle } from '../../../ui/chapter-title';
6
+ import { Title } from '../../../ui/title';
7
+
8
+ /* -------------------------------------------------------------------------------------------------
9
+ * DefaultTitle
10
+ * -----------------------------------------------------------------------------------------------*/
11
+
12
+ function DefaultTitle() {
13
+ const $started = useMediaState('started'),
14
+ $title = useMediaState('title'),
15
+ $hasChapters = useActiveTextTrack('chapters');
16
+ return $hasChapters && ($started || !$title) ? (
17
+ <ChapterTitle className="vds-chapter-title" />
18
+ ) : (
19
+ <Title className="vds-chapter-title" />
20
+ );
21
+ }
22
+
23
+ DefaultTitle.displayName = 'DefaultTitle';
24
+ export { DefaultTitle };
@@ -0,0 +1,27 @@
1
+ import * as React from 'react';
2
+
3
+ import type { TooltipPlacement } from 'vidstack';
4
+
5
+ import * as Tooltip from '../../../ui/tooltip';
6
+ import { useDefaultLayoutContext } from '../context';
7
+
8
+ export interface DefaultTooltipProps {
9
+ content: string;
10
+ placement?: TooltipPlacement;
11
+ children: React.ReactNode;
12
+ }
13
+
14
+ function DefaultTooltip({ content, placement, children }: DefaultTooltipProps) {
15
+ const { showTooltipDelay } = useDefaultLayoutContext();
16
+ return (
17
+ <Tooltip.Root showDelay={showTooltipDelay}>
18
+ <Tooltip.Trigger asChild>{children}</Tooltip.Trigger>
19
+ <Tooltip.Content className="vds-tooltip-content" placement={placement}>
20
+ {content}
21
+ </Tooltip.Content>
22
+ </Tooltip.Root>
23
+ );
24
+ }
25
+
26
+ DefaultTooltip.displayName = 'DefaultTooltip';
27
+ export { DefaultTooltip };
@@ -0,0 +1,8 @@
1
+ export * from './audio-layout';
2
+ export * from './video-layout';
3
+ export * from './ui/menus/items/menu-checkbox';
4
+ export * from './ui/menus/items/menu-items';
5
+ export * from './ui/menus/items/menu-slider';
6
+ export * from './ui/tooltip';
7
+ export * from './icons';
8
+ export { DefaultKeyboardDisplay, type DefaultKeyboardDisplayProps } from './ui/keyboard-display';
@@ -0,0 +1,344 @@
1
+ import * as React from 'react';
2
+
3
+ import { useSignal } from 'maverick.js/react';
4
+
5
+ import { useMediaState } from '../../../hooks/use-media-state';
6
+ import * as Controls from '../../ui/controls';
7
+ import { Gesture } from '../../ui/gesture';
8
+ import * as Spinner from '../../ui/spinner';
9
+ import { Time } from '../../ui/time';
10
+ import { useLayoutName } from '../utils';
11
+ import { useDefaultLayoutContext } from './context';
12
+ import { createDefaultMediaLayout, type DefaultLayoutProps } from './media-layout';
13
+ import {
14
+ slot,
15
+ useDefaultVideoLayoutSlots,
16
+ type DefaultLayoutMenuSlotName,
17
+ type DefaultVideoLayoutSlots,
18
+ type Slots,
19
+ } from './slots';
20
+ import { DefaultAnnouncer } from './ui/announcer';
21
+ import {
22
+ DefaultAirPlayButton,
23
+ DefaultCaptionButton,
24
+ DefaultDownloadButton,
25
+ DefaultFullscreenButton,
26
+ DefaultGoogleCastButton,
27
+ DefaultPIPButton,
28
+ DefaultPlayButton,
29
+ } from './ui/buttons';
30
+ import { DefaultCaptions } from './ui/captions';
31
+ import { DefaultControlsSpacer } from './ui/controls';
32
+ import { DefaultKeyboardDisplay } from './ui/keyboard-display';
33
+ import { DefaultChaptersMenu } from './ui/menus/chapters-menu';
34
+ import { DefaultSettingsMenu } from './ui/menus/settings-menu';
35
+ import { DefaultTimeSlider, DefaultVolumePopup } from './ui/sliders';
36
+ import { DefaultTimeInfo } from './ui/time';
37
+ import { DefaultTitle } from './ui/title';
38
+
39
+ /* -------------------------------------------------------------------------------------------------
40
+ * DefaultVideoLayout
41
+ * -----------------------------------------------------------------------------------------------*/
42
+
43
+ const MediaLayout = createDefaultMediaLayout({
44
+ type: 'video',
45
+ smLayoutWhen({ width, height }) {
46
+ return width < 576 || height < 380;
47
+ },
48
+ renderLayout(props) {
49
+ return <VideoLayout {...props} />;
50
+ },
51
+ });
52
+
53
+ export interface DefaultVideoLayoutProps extends DefaultLayoutProps<DefaultVideoLayoutSlots> {}
54
+
55
+ /**
56
+ * The video layout is our production-ready UI that's displayed when the media view type is set to
57
+ * 'video'. It includes support for picture-in-picture, fullscreen, slider chapters, slider
58
+ * previews, captions, audio/quality settings, live streams, and more out of the box.
59
+ *
60
+ * @attr data-match - Whether this layout is being used.
61
+ * @attr data-sm - The small layout is active
62
+ * @attr data-lg - The large layout is active.
63
+ * @attr data-size - The active layout size (sm or lg).
64
+ * @example
65
+ * ```tsx
66
+ * <MediaPlayer src="video.mp4">
67
+ * <MediaProvider />
68
+ * <DefaultVideoLayout thumbnails="/thumbnails.vtt" icons={defaultLayoutIcons} />
69
+ * </MediaPlayer>
70
+ * ```
71
+ */
72
+ function DefaultVideoLayout(props: DefaultVideoLayoutProps) {
73
+ return <MediaLayout {...props} />;
74
+ }
75
+
76
+ DefaultVideoLayout.displayName = 'DefaultVideoLayout';
77
+ export { DefaultVideoLayout };
78
+
79
+ /* -------------------------------------------------------------------------------------------------
80
+ * VideoLayout
81
+ * -----------------------------------------------------------------------------------------------*/
82
+
83
+ function VideoLayout({ streamType, isLoadLayout, isSmallLayout }) {
84
+ useLayoutName('video');
85
+
86
+ return isLoadLayout ? (
87
+ <DefaultVideoLoadLayout />
88
+ ) : streamType === 'unknown' ? (
89
+ <DefaultBufferingIndicator />
90
+ ) : isSmallLayout ? (
91
+ <DefaultVideoSmallLayout />
92
+ ) : (
93
+ <DefaultVideoLargeLayout />
94
+ );
95
+ }
96
+
97
+ VideoLayout.displayName = 'VideoLayout';
98
+
99
+ /* -------------------------------------------------------------------------------------------------
100
+ * DefaultVideoLargeLayout
101
+ * -----------------------------------------------------------------------------------------------*/
102
+
103
+ function DefaultVideoLargeLayout() {
104
+ const { menuGroup } = useDefaultLayoutContext(),
105
+ baseSlots = useDefaultVideoLayoutSlots(),
106
+ slots = { ...baseSlots, ...baseSlots?.largeLayout };
107
+ return (
108
+ <>
109
+ <DefaultAnnouncer />
110
+ <DefaultVideoGestures />
111
+ <DefaultVideoKeyboardDisplay />
112
+ {slot(slots, 'bufferingIndicator', <DefaultBufferingIndicator />)}
113
+ {slot(slots, 'captions', <DefaultCaptions />)}
114
+ <Controls.Root className="vds-controls">
115
+ <Controls.Group className="vds-controls-group">
116
+ {slot(slots, 'topControlsGroupStart', null)}
117
+ <DefaultControlsSpacer />
118
+ {slot(slots, 'topControlsGroupCenter', null)}
119
+ <DefaultControlsSpacer />
120
+ {slot(slots, 'topControlsGroupEnd', null)}
121
+ {menuGroup === 'top' && <DefaultVideoMenus slots={slots} />}
122
+ </Controls.Group>
123
+
124
+ <DefaultControlsSpacer />
125
+
126
+ <Controls.Group className="vds-controls-group">
127
+ {slot(slots, 'centerControlsGroupStart', null)}
128
+ <DefaultControlsSpacer />
129
+ {slot(slots, 'centerControlsGroupCenter', null)}
130
+ <DefaultControlsSpacer />
131
+ {slot(slots, 'centerControlsGroupEnd', null)}
132
+ </Controls.Group>
133
+
134
+ <DefaultControlsSpacer />
135
+
136
+ <Controls.Group className="vds-controls-group">
137
+ {slot(slots, 'timeSlider', <DefaultTimeSlider />)}
138
+ </Controls.Group>
139
+
140
+ <Controls.Group className="vds-controls-group">
141
+ {slot(slots, 'playButton', <DefaultPlayButton tooltip="top start" />)}
142
+ <DefaultVolumePopup orientation="horizontal" tooltip="top" slots={slots} />
143
+ <DefaultTimeInfo slots={slots} />
144
+ {slot(slots, 'chapterTitle', <DefaultTitle />)}
145
+ {slot(slots, 'captionButton', <DefaultCaptionButton tooltip="top" />)}
146
+ {menuGroup === 'bottom' && <DefaultVideoMenus slots={slots} />}
147
+ {slot(slots, 'airPlayButton', <DefaultAirPlayButton tooltip="top" />)}
148
+ {slot(slots, 'googleCastButton', <DefaultGoogleCastButton tooltip="top" />)}
149
+ {slot(slots, 'downloadButton', <DefaultDownloadButton />)}
150
+ {slot(slots, 'pipButton', <DefaultPIPButton tooltip="top" />)}
151
+ {slot(slots, 'fullscreenButton', <DefaultFullscreenButton tooltip="top end" />)}
152
+ </Controls.Group>
153
+ </Controls.Root>
154
+ </>
155
+ );
156
+ }
157
+
158
+ DefaultVideoLargeLayout.displayName = 'DefaultVideoLargeLayout';
159
+ export { DefaultVideoLargeLayout };
160
+
161
+ /* -------------------------------------------------------------------------------------------------
162
+ * DefaultVideoSmallLayout
163
+ * -----------------------------------------------------------------------------------------------*/
164
+
165
+ function DefaultVideoSmallLayout() {
166
+ const baseSlots = useDefaultVideoLayoutSlots(),
167
+ slots = { ...baseSlots, ...baseSlots?.smallLayout };
168
+ return (
169
+ <>
170
+ <DefaultAnnouncer />
171
+ <DefaultVideoGestures />
172
+ <DefaultVideoKeyboardDisplay />
173
+ {slot(slots, 'bufferingIndicator', <DefaultBufferingIndicator />)}
174
+ {slot(slots, 'captions', <DefaultCaptions />)}
175
+ <Controls.Root className="vds-controls">
176
+ <Controls.Group className="vds-controls-group">
177
+ {slot(slots, 'topControlsGroupStart', null)}
178
+ {slot(slots, 'airPlayButton', <DefaultAirPlayButton tooltip="top start" />)}
179
+ {slot(slots, 'googleCastButton', <DefaultGoogleCastButton tooltip="top start" />)}
180
+ <DefaultControlsSpacer />
181
+ {slot(slots, 'topControlsGroupCenter', null)}
182
+ <DefaultControlsSpacer />
183
+ {slot(slots, 'captionButton', <DefaultCaptionButton tooltip="bottom" />)}
184
+ {slot(slots, 'downloadButton', <DefaultDownloadButton />)}
185
+ <DefaultVideoMenus slots={slots} />
186
+ <DefaultVolumePopup orientation="vertical" tooltip="bottom end" slots={slots} />
187
+ {slot(slots, 'topControlsGroupEnd', null)}
188
+ </Controls.Group>
189
+ <DefaultControlsSpacer />
190
+ <Controls.Group className="vds-controls-group" style={{ pointerEvents: 'none' }}>
191
+ {slot(slots, 'centerControlsGroupStart', null)}
192
+ <DefaultControlsSpacer />
193
+ {slot(slots, 'centerControlsGroupCenter', null)}
194
+ {slot(slots, 'playButton', <DefaultPlayButton tooltip="top" />)}
195
+ <DefaultControlsSpacer />
196
+ {slot(slots, 'centerControlsGroupEnd', null)}
197
+ </Controls.Group>
198
+ <DefaultControlsSpacer />
199
+ <Controls.Group className="vds-controls-group">
200
+ <DefaultTimeInfo slots={slots} />
201
+ {slot(slots, 'chapterTitle', <DefaultTitle />)}
202
+ {slot(slots, 'fullscreenButton', <DefaultFullscreenButton tooltip="top end" />)}
203
+ </Controls.Group>
204
+ <Controls.Group className="vds-controls-group">
205
+ {slot(slots, 'timeSlider', <DefaultTimeSlider />)}
206
+ </Controls.Group>
207
+ </Controls.Root>
208
+ {slot(slots, 'startDuration', <DefaultVideoStartDuration />)}
209
+ </>
210
+ );
211
+ }
212
+
213
+ DefaultVideoSmallLayout.displayName = 'DefaultVideoSmallLayout';
214
+ export { DefaultVideoSmallLayout };
215
+
216
+ /* -------------------------------------------------------------------------------------------------
217
+ * DefaultVideoStartDuration
218
+ * -----------------------------------------------------------------------------------------------*/
219
+
220
+ function DefaultVideoStartDuration() {
221
+ const $duration = useMediaState('duration');
222
+ if ($duration === 0) return null;
223
+ return (
224
+ <div className="vds-start-duration">
225
+ <Time className="vds-time" type="duration" />
226
+ </div>
227
+ );
228
+ }
229
+
230
+ DefaultVideoStartDuration.displayName = 'DefaultVideoStartDuration';
231
+ /* -------------------------------------------------------------------------------------------------
232
+ * DefaultVideoGestures
233
+ * -----------------------------------------------------------------------------------------------*/
234
+
235
+ function DefaultVideoGestures() {
236
+ const { noGestures } = useDefaultLayoutContext();
237
+
238
+ if (noGestures) return null;
239
+
240
+ return (
241
+ <div className="vds-gestures">
242
+ <Gesture className="vds-gesture" event="pointerup" action="toggle:paused" />
243
+ <Gesture className="vds-gesture" event="pointerup" action="toggle:controls" />
244
+ <Gesture className="vds-gesture" event="dblpointerup" action="toggle:fullscreen" />
245
+ <Gesture className="vds-gesture" event="dblpointerup" action="seek:-10" />
246
+ <Gesture className="vds-gesture" event="dblpointerup" action="seek:10" />
247
+ </div>
248
+ );
249
+ }
250
+
251
+ DefaultVideoGestures.displayName = 'DefaultVideoGestures';
252
+ export { DefaultVideoGestures };
253
+
254
+ /* -------------------------------------------------------------------------------------------------
255
+ * DefaultBufferingIndicator
256
+ * -----------------------------------------------------------------------------------------------*/
257
+
258
+ function DefaultBufferingIndicator() {
259
+ return (
260
+ <div className="vds-buffering-indicator">
261
+ <Spinner.Root className="vds-buffering-spinner">
262
+ <Spinner.Track className="vds-buffering-track" />
263
+ <Spinner.TrackFill className="vds-buffering-track-fill" />
264
+ </Spinner.Root>
265
+ </div>
266
+ );
267
+ }
268
+
269
+ DefaultBufferingIndicator.displayName = 'DefaultBufferingIndicator';
270
+ export { DefaultBufferingIndicator };
271
+
272
+ /* -------------------------------------------------------------------------------------------------
273
+ * DefaultVideoMenus
274
+ * -----------------------------------------------------------------------------------------------*/
275
+
276
+ function DefaultVideoMenus({ slots }: { slots?: Slots<DefaultLayoutMenuSlotName> }) {
277
+ const { isSmallLayout, noModal, menuGroup } = useDefaultLayoutContext(),
278
+ side = menuGroup === 'top' || isSmallLayout ? 'bottom' : ('top' as const),
279
+ tooltip = `${side} end` as const,
280
+ placement = noModal
281
+ ? (`${side} end` as const)
282
+ : !isSmallLayout
283
+ ? (`${side} end` as const)
284
+ : null;
285
+ return (
286
+ <>
287
+ {slot(
288
+ slots,
289
+ 'chaptersMenu',
290
+ <DefaultChaptersMenu
291
+ tooltip={tooltip}
292
+ placement={placement}
293
+ portalClass="vds-video-layout"
294
+ />,
295
+ )}
296
+ {slot(
297
+ slots,
298
+ 'settingsMenu',
299
+ <DefaultSettingsMenu
300
+ tooltip={tooltip}
301
+ placement={placement}
302
+ portalClass="vds-video-layout"
303
+ slots={slots}
304
+ />,
305
+ )}
306
+ </>
307
+ );
308
+ }
309
+
310
+ DefaultVideoMenus.displayName = 'DefaultVideoMenus';
311
+
312
+ /* -------------------------------------------------------------------------------------------------
313
+ * DefaultVideoLoadLayout
314
+ * -----------------------------------------------------------------------------------------------*/
315
+
316
+ function DefaultVideoLoadLayout() {
317
+ const { isSmallLayout } = useDefaultLayoutContext(),
318
+ baseSlots = useDefaultVideoLayoutSlots(),
319
+ slots = { ...baseSlots, ...baseSlots?.[isSmallLayout ? 'smallLayout' : 'largeLayout'] };
320
+ return (
321
+ <div className="vds-load-container">
322
+ {slot(slots, 'bufferingIndicator', <DefaultBufferingIndicator />)}
323
+ {slot(slots, 'loadButton', <DefaultPlayButton tooltip="top" />)}
324
+ </div>
325
+ );
326
+ }
327
+
328
+ DefaultVideoLoadLayout.displayName = 'DefaultVideoLoadLayout';
329
+
330
+ /* -------------------------------------------------------------------------------------------------
331
+ * DefaultVideoKeyboardDisplay
332
+ * -----------------------------------------------------------------------------------------------*/
333
+
334
+ function DefaultVideoKeyboardDisplay() {
335
+ const { noKeyboardAnimations, icons, userPrefersKeyboardAnimations } = useDefaultLayoutContext(),
336
+ $userPrefersKeyboardAnimations = useSignal(userPrefersKeyboardAnimations),
337
+ disabled = noKeyboardAnimations || !$userPrefersKeyboardAnimations;
338
+
339
+ if (disabled || !icons.KeyboardDisplay) return null;
340
+
341
+ return <DefaultKeyboardDisplay icons={icons.KeyboardDisplay} />;
342
+ }
343
+
344
+ DefaultVideoKeyboardDisplay.displayName = 'DefaultVideoKeyboardDisplay';
@@ -0,0 +1,26 @@
1
+ import * as React from 'react';
2
+
3
+ import { type WriteSignal } from 'maverick.js';
4
+ import type { PlyrLayoutWord } from 'vidstack';
5
+
6
+ import type { PlyrLayoutProps } from './props';
7
+
8
+ interface PlyrLayoutContext extends PlyrLayoutProps {
9
+ previewTime: WriteSignal<number>;
10
+ }
11
+
12
+ export const PlyrLayoutContext = React.createContext<PlyrLayoutContext>({} as any);
13
+ PlyrLayoutContext.displayName = 'PlyrLayoutContext';
14
+
15
+ export function usePlyrLayoutContext() {
16
+ return React.useContext(PlyrLayoutContext);
17
+ }
18
+
19
+ export function usePlyrLayoutWord(word: PlyrLayoutWord) {
20
+ const { translations } = usePlyrLayoutContext();
21
+ return i18n(translations, word);
22
+ }
23
+
24
+ export function i18n(translations: any, word: string) {
25
+ return translations?.[word] ?? word;
26
+ }
@@ -0,0 +1 @@
1
+ export default `<g><path d="M16,1 L2,1 C1.447,1 1,1.447 1,2 L1,12 C1,12.553 1.447,13 2,13 L5,13 L5,11 L3,11 L3,3 L15,3 L15,11 L13,11 L13,13 L16,13 C16.553,13 17,12.553 17,12 L17,2 C17,1.447 16.553,1 16,1 L16,1 Z"></path><polygon points="4 17 14 17 9 11"></polygon></g>`;
@@ -0,0 +1 @@
1
+ export default `<g fill-rule="evenodd" fill-opacity="0.5"><path d="M1,1 C0.4,1 0,1.4 0,2 L0,13 C0,13.6 0.4,14 1,14 L5.6,14 L8.3,16.7 C8.5,16.9 8.7,17 9,17 C9.3,17 9.5,16.9 9.7,16.7 L12.4,14 L17,14 C17.6,14 18,13.6 18,13 L18,2 C18,1.4 17.6,1 17,1 L1,1 Z M5.52,11.15 C7.51,11.15 8.53,9.83 8.8,8.74 L7.51,8.35 C7.32,9.01 6.73,9.8 5.52,9.8 C4.38,9.8 3.32,8.97 3.32,7.46 C3.32,5.85 4.44,5.09 5.5,5.09 C6.73,5.09 7.28,5.84 7.45,6.52 L8.75,6.11 C8.47,4.96 7.46,3.76 5.5,3.76 C3.6,3.76 1.89,5.2 1.89,7.46 C1.89,9.72 3.54,11.15 5.52,11.15 Z M13.09,11.15 C15.08,11.15 16.1,9.83 16.37,8.74 L15.08,8.35 C14.89,9.01 14.3,9.8 13.09,9.8 C11.95,9.8 10.89,8.97 10.89,7.46 C10.89,5.85 12.01,5.09 13.07,5.09 C14.3,5.09 14.85,5.84 15.02,6.52 L16.32,6.11 C16.04,4.96 15.03,3.76 13.07,3.76 C11.17,3.76 9.46,5.2 9.46,7.46 C9.46,9.72 11.11,11.15 13.09,11.15 Z"></path></g>`;
@@ -0,0 +1 @@
1
+ export default `<g fill-rule="evenodd"><path d="M1,1 C0.4,1 0,1.4 0,2 L0,13 C0,13.6 0.4,14 1,14 L5.6,14 L8.3,16.7 C8.5,16.9 8.7,17 9,17 C9.3,17 9.5,16.9 9.7,16.7 L12.4,14 L17,14 C17.6,14 18,13.6 18,13 L18,2 C18,1.4 17.6,1 17,1 L1,1 Z M5.52,11.15 C7.51,11.15 8.53,9.83 8.8,8.74 L7.51,8.35 C7.32,9.01 6.73,9.8 5.52,9.8 C4.38,9.8 3.32,8.97 3.32,7.46 C3.32,5.85 4.44,5.09 5.5,5.09 C6.73,5.09 7.28,5.84 7.45,6.52 L8.75,6.11 C8.47,4.96 7.46,3.76 5.5,3.76 C3.6,3.76 1.89,5.2 1.89,7.46 C1.89,9.72 3.54,11.15 5.52,11.15 Z M13.09,11.15 C15.08,11.15 16.1,9.83 16.37,8.74 L15.08,8.35 C14.89,9.01 14.3,9.8 13.09,9.8 C11.95,9.8 10.89,8.97 10.89,7.46 C10.89,5.85 12.01,5.09 13.07,5.09 C14.3,5.09 14.85,5.84 15.02,6.52 L16.32,6.11 C16.04,4.96 15.03,3.76 13.07,3.76 C11.17,3.76 9.46,5.2 9.46,7.46 C9.46,9.72 11.11,11.15 13.09,11.15 Z"></path></g>`;
@@ -0,0 +1 @@
1
+ export default `<g transform="translate(2 1)"><path d="M7,12 C7.3,12 7.5,11.9 7.7,11.7 L13.4,6 L12,4.6 L8,8.6 L8,0 L6,0 L6,8.6 L2,4.6 L0.6,6 L6.3,11.7 C6.5,11.9 6.7,12 7,12 Z" /><rect width="14" height="2" y="14" /></g>`;
@@ -0,0 +1 @@
1
+ export default `<polygon points="10 3 13.6 3 9.6 7 11 8.4 15 4.4 15 8 17 8 17 1 10 1"></polygon><polygon points="7 9.6 3 13.6 3 10 1 10 1 17 8 17 8 15 4.4 15 8.4 11"></polygon>`;
@@ -0,0 +1 @@
1
+ export default `<polygon points="1 12 4.6 12 0.6 16 2 17.4 6 13.4 6 17 8 17 8 10 1 10"></polygon><polygon points="16 0.6 12 4.6 12 1 10 1 10 8 17 8 17 6 13.4 6 17.4 2"></polygon>`;
@@ -0,0 +1 @@
1
+ export default `<polygon points="7.875 7.17142857 0 1 0 17 7.875 10.8285714 7.875 17 18 9 7.875 1"></polygon>`;
@@ -0,0 +1 @@
1
+ export default `<polygon points="12.4 12.5 14.5 10.4 16.6 12.5 18 11.1 15.9 9 18 6.9 16.6 5.5 14.5 7.6 12.4 5.5 11 6.9 13.1 9 11 11.1"></polygon><path d="M3.78571429,6.00820648 L0.714285714,6.00820648 C0.285714286,6.00820648 0,6.30901277 0,6.76022222 L0,11.2723167 C0,11.7235261 0.285714286,12.0243324 0.714285714,12.0243324 L3.78571429,12.0243324 L7.85714286,15.8819922 C8.35714286,16.1827985 9,15.8819922 9,15.2803796 L9,2.75215925 C9,2.15054666 8.35714286,1.77453879 7.85714286,2.15054666 L3.78571429,6.00820648 Z"></path>`;