@hanifhan1f/vidstack-react 1.12.33 → 1.12.35

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 (188) hide show
  1. package/dev/chunks/{vidstack-3rdEWplD.js → vidstack-B-DU-_xu.js} +55 -3
  2. package/dev/chunks/{vidstack-CniPzPQc.js → vidstack-C3VHrHPf.js} +155 -15
  3. package/dev/chunks/{vidstack-BOPSNTgH.js → vidstack-CjLj3q5w.js} +5 -57
  4. package/dev/chunks/{vidstack-BNwnoM-l.js → vidstack-DpWioszb.js} +1 -1
  5. package/dev/chunks/{vidstack-S_S6XDnL.js → vidstack-t48GJbb5.js} +1 -1
  6. package/dev/player/vidstack-default-components.js +4 -4
  7. package/dev/player/vidstack-default-layout.js +4 -4
  8. package/dev/player/vidstack-plyr-layout.js +3 -3
  9. package/dev/vidstack.js +5 -5
  10. package/package.json +1 -1
  11. package/player/layouts/default.d.ts +9 -1
  12. package/prod/chunks/{vidstack-BlPINAXN.js → vidstack-BI5-IK9v.js} +55 -3
  13. package/prod/chunks/{vidstack-CbejzCJs.js → vidstack-BgAMJr1Y.js} +155 -15
  14. package/prod/chunks/{vidstack-Bh7M8kL6.js → vidstack-DKWmxvB4.js} +5 -57
  15. package/prod/chunks/{vidstack-DhSvljmQ.js → vidstack-NR84X5HE.js} +1 -1
  16. package/prod/chunks/{vidstack-BS445j5D.js → vidstack-jSJ0Meez.js} +1 -1
  17. package/prod/player/vidstack-default-components.js +4 -4
  18. package/prod/player/vidstack-default-layout.js +4 -4
  19. package/prod/player/vidstack-plyr-layout.js +3 -3
  20. package/prod/vidstack.js +5 -5
  21. package/{dev/chunks/vidstack-DTow20pt.js → server/chunks/vidstack-CSX6ausI.js} +55 -3
  22. package/server/chunks/{vidstack-CoGzBr_V.js → vidstack-CePUWLrW.js} +5 -57
  23. package/{dev/chunks/vidstack-CvWDiSTs.js → server/chunks/vidstack-D7sOBYbw.js} +1 -1
  24. package/server/chunks/{vidstack-VGPw_CQP.js → vidstack-DqUb8JgU.js} +1 -1
  25. package/server/chunks/{vidstack-i9a2TQLO.js → vidstack-Dvh6BtYs.js} +155 -15
  26. package/server/player/vidstack-default-components.js +4 -4
  27. package/server/player/vidstack-default-layout.js +4 -4
  28. package/server/player/vidstack-plyr-layout.js +3 -3
  29. package/server/vidstack.js +5 -5
  30. package/dev/chunks/vidstack-B-FM4-oZ.js +0 -668
  31. package/dev/chunks/vidstack-B92UncBI.js +0 -61
  32. package/dev/chunks/vidstack-BDiAEW1N.js +0 -11691
  33. package/dev/chunks/vidstack-BPymmnxm.js +0 -551
  34. package/dev/chunks/vidstack-BSZY6sbC.js +0 -180
  35. package/dev/chunks/vidstack-BSpAxhO6.js +0 -643
  36. package/dev/chunks/vidstack-BVVxkUlq.js +0 -288
  37. package/dev/chunks/vidstack-BXgKy_7V.js +0 -11693
  38. package/dev/chunks/vidstack-BalWqr4j.js +0 -1422
  39. package/dev/chunks/vidstack-Bfi_jCvb.js +0 -476
  40. package/dev/chunks/vidstack-BoLZuw80.js +0 -34
  41. package/dev/chunks/vidstack-BrqDQG-r.js +0 -643
  42. package/dev/chunks/vidstack-C3QPOZNd.js +0 -476
  43. package/dev/chunks/vidstack-C7BwfK5c.js +0 -1537
  44. package/dev/chunks/vidstack-CEUjDh4x.js +0 -34
  45. package/dev/chunks/vidstack-CFOPpDTy.js +0 -476
  46. package/dev/chunks/vidstack-CFZ0rYJz.js +0 -34
  47. package/dev/chunks/vidstack-CKsUl4ll.js +0 -1384
  48. package/dev/chunks/vidstack-CM82l-7o.js +0 -551
  49. package/dev/chunks/vidstack-CQSHFVu7.js +0 -401
  50. package/dev/chunks/vidstack-CXrXBlpD.js +0 -11692
  51. package/dev/chunks/vidstack-CevuS08D.js +0 -1504
  52. package/dev/chunks/vidstack-CkRXb9Ia.js +0 -1537
  53. package/dev/chunks/vidstack-CqNX679o.js +0 -669
  54. package/dev/chunks/vidstack-Csfg08VS.js +0 -551
  55. package/dev/chunks/vidstack-CzU-uC5f.js +0 -189
  56. package/dev/chunks/vidstack-D2Bi2Td9.js +0 -1537
  57. package/dev/chunks/vidstack-D3ZXOE4d.js +0 -643
  58. package/dev/chunks/vidstack-D6_9yy0x.js +0 -643
  59. package/dev/chunks/vidstack-DJQOTrl6.js +0 -180
  60. package/dev/chunks/vidstack-DNbKNc4R.js +0 -288
  61. package/dev/chunks/vidstack-DOtIyh4c.js +0 -288
  62. package/dev/chunks/vidstack-DY2iivhG.js +0 -84
  63. package/dev/chunks/vidstack-DjqYvkVp.js +0 -84
  64. package/dev/chunks/vidstack-Dov8gjdq.js +0 -401
  65. package/dev/chunks/vidstack-DqaqkU4T.js +0 -9
  66. package/dev/chunks/vidstack-DwdhbP5c.js +0 -189
  67. package/dev/chunks/vidstack-DweQYzVw.js +0 -180
  68. package/dev/chunks/vidstack-FuCbl228.js +0 -226
  69. package/dev/chunks/vidstack-H9OdEKUQ.js +0 -375
  70. package/dev/chunks/vidstack-KntYDWMe.js +0 -668
  71. package/dev/chunks/vidstack-L5mw2iPb.js +0 -375
  72. package/dev/chunks/vidstack-NCBSBZE-.js +0 -61
  73. package/dev/chunks/vidstack-PREbBNMG.js +0 -125
  74. package/dev/chunks/vidstack-UWMPvwsa.js +0 -1537
  75. package/dev/chunks/vidstack-f6WXkmfP.js +0 -375
  76. package/dev/chunks/vidstack-gqKBE4xH.js +0 -376
  77. package/dev/chunks/vidstack-iRuTLfhk.js +0 -61
  78. package/dev/chunks/vidstack-lYFZKRUc.js +0 -401
  79. package/dev/chunks/vidstack-oOGofWSl.js +0 -668
  80. package/dev/chunks/vidstack-vh0BKYWJ.js +0 -84
  81. package/prod/chunks/vidstack-0Foyib2F.js +0 -34
  82. package/prod/chunks/vidstack-58ZavMvv.js +0 -159
  83. package/prod/chunks/vidstack-B0SSIHIv.js +0 -1537
  84. package/prod/chunks/vidstack-B9nEslvl.js +0 -11197
  85. package/prod/chunks/vidstack-BCBskRpc.js +0 -664
  86. package/prod/chunks/vidstack-BOObgZd8.js +0 -504
  87. package/prod/chunks/vidstack-BZVrgeRF.js +0 -9
  88. package/prod/chunks/vidstack-B_9VGrZQ.js +0 -504
  89. package/prod/chunks/vidstack-B_wD853-.js +0 -386
  90. package/prod/chunks/vidstack-BbPEqH3g.js +0 -11196
  91. package/prod/chunks/vidstack-Bm2UemPE.js +0 -470
  92. package/prod/chunks/vidstack-Bp_hAwzI.js +0 -61
  93. package/prod/chunks/vidstack-C4tNkfXj.js +0 -470
  94. package/prod/chunks/vidstack-C4tuISYG.js +0 -1504
  95. package/prod/chunks/vidstack-C5Rzkyfp.js +0 -375
  96. package/prod/chunks/vidstack-CKapDFwB.js +0 -376
  97. package/prod/chunks/vidstack-CNJwYQRW.js +0 -84
  98. package/prod/chunks/vidstack-CQll06Hv.js +0 -34
  99. package/prod/chunks/vidstack-CVzVtf1j.js +0 -61
  100. package/prod/chunks/vidstack-CYK75vJF.js +0 -1382
  101. package/prod/chunks/vidstack-CZNlvfmV.js +0 -288
  102. package/prod/chunks/vidstack-CiQEyk_l.js +0 -189
  103. package/prod/chunks/vidstack-CiTWSpv_.js +0 -34
  104. package/prod/chunks/vidstack-CikQpsuo.js +0 -1537
  105. package/prod/chunks/vidstack-CtxjO6HG.js +0 -84
  106. package/prod/chunks/vidstack-CzjHdPIT.js +0 -375
  107. package/prod/chunks/vidstack-D0XCUWbp.js +0 -159
  108. package/prod/chunks/vidstack-D3cSYtez.js +0 -663
  109. package/prod/chunks/vidstack-D91K36KQ.js +0 -206
  110. package/prod/chunks/vidstack-DJThTSEm.js +0 -125
  111. package/prod/chunks/vidstack-DTyDOhwS.js +0 -504
  112. package/prod/chunks/vidstack-DVMwXUgY.js +0 -189
  113. package/prod/chunks/vidstack-DXSNXDnS.js +0 -1384
  114. package/prod/chunks/vidstack-D_Sd7838.js +0 -663
  115. package/prod/chunks/vidstack-D_ijTIbV.js +0 -11198
  116. package/prod/chunks/vidstack-DdiGCJVp.js +0 -504
  117. package/prod/chunks/vidstack-DgGDsAKh.js +0 -375
  118. package/prod/chunks/vidstack-DgsBXr1J.js +0 -84
  119. package/prod/chunks/vidstack-DhC5F6c8.js +0 -470
  120. package/prod/chunks/vidstack-Djmla_FM.js +0 -545
  121. package/prod/chunks/vidstack-DpQw1Y33.js +0 -663
  122. package/prod/chunks/vidstack-DrEorv9m.js +0 -189
  123. package/prod/chunks/vidstack-Ma9rwtR0.js +0 -386
  124. package/prod/chunks/vidstack-VTpvHAdU.js +0 -1537
  125. package/prod/chunks/vidstack-dbLRgf2L.js +0 -159
  126. package/prod/chunks/vidstack-ehqxnvc9.js +0 -1537
  127. package/prod/chunks/vidstack-jIPoNqhj.js +0 -545
  128. package/prod/chunks/vidstack-lc8NHly9.js +0 -288
  129. package/prod/chunks/vidstack-rHvQ8f6c.js +0 -288
  130. package/prod/chunks/vidstack-rKV98aQH.js +0 -545
  131. package/prod/chunks/vidstack-uA7h-Bsq.js +0 -386
  132. package/prod/chunks/vidstack-xo_SmgiV.js +0 -84
  133. package/prod/chunks/vidstack-xvxeRtaN.js +0 -61
  134. package/server/chunks/vidstack--ufi23Q6.js +0 -1537
  135. package/server/chunks/vidstack-B3AXUfgF.js +0 -189
  136. package/server/chunks/vidstack-B4rJ1ZKK.js +0 -376
  137. package/server/chunks/vidstack-BJCx78pm.js +0 -386
  138. package/server/chunks/vidstack-BTdEfKqV.js +0 -84
  139. package/server/chunks/vidstack-BV_VpWlJ.js +0 -1537
  140. package/server/chunks/vidstack-BtitkRvR.js +0 -11198
  141. package/server/chunks/vidstack-BtqWstSj.js +0 -375
  142. package/server/chunks/vidstack-BweZhuNd.js +0 -1537
  143. package/server/chunks/vidstack-ByG5MvLs.js +0 -545
  144. package/server/chunks/vidstack-C-HdFsZi.js +0 -84
  145. package/server/chunks/vidstack-C0xOpWYR.js +0 -470
  146. package/server/chunks/vidstack-C481iXqe.js +0 -386
  147. package/server/chunks/vidstack-C4iWXMC-.js +0 -545
  148. package/server/chunks/vidstack-C5zFBMwg.js +0 -386
  149. package/server/chunks/vidstack-CEh38XpD.js +0 -288
  150. package/server/chunks/vidstack-CSiPajWY.js +0 -470
  151. package/server/chunks/vidstack-CbNRZgUA.js +0 -11197
  152. package/server/chunks/vidstack-CgXa6YO3.js +0 -61
  153. package/server/chunks/vidstack-CkMAeO-e.js +0 -34
  154. package/server/chunks/vidstack-Cm0qnRvu.js +0 -11196
  155. package/server/chunks/vidstack-Ct1NFlBa.js +0 -1537
  156. package/server/chunks/vidstack-CyFwkPiu.js +0 -470
  157. package/server/chunks/vidstack-D4t_SZbb.js +0 -1416
  158. package/server/chunks/vidstack-D7D9kiW6.js +0 -34
  159. package/server/chunks/vidstack-DH6N0AoF.js +0 -375
  160. package/server/chunks/vidstack-DJJmNib6.js +0 -504
  161. package/server/chunks/vidstack-DKr7br9D.js +0 -34
  162. package/server/chunks/vidstack-DM-5dPT-.js +0 -663
  163. package/server/chunks/vidstack-DOIUveQF.js +0 -504
  164. package/server/chunks/vidstack-DTn72IA8.js +0 -1504
  165. package/server/chunks/vidstack-DWfS9vAY.js +0 -84
  166. package/server/chunks/vidstack-DWt5LAKE.js +0 -375
  167. package/server/chunks/vidstack-DY51lx0R.js +0 -189
  168. package/server/chunks/vidstack-DbNoKLjz.js +0 -664
  169. package/server/chunks/vidstack-Dbs_rXUT.js +0 -663
  170. package/server/chunks/vidstack-DeS67_gx.js +0 -9
  171. package/server/chunks/vidstack-DiHlnSws.js +0 -1384
  172. package/server/chunks/vidstack-DnoqxmOs.js +0 -125
  173. package/server/chunks/vidstack-DsZKgA8y.js +0 -663
  174. package/server/chunks/vidstack-DtQSvsQr.js +0 -189
  175. package/server/chunks/vidstack-E7eUOyFt.js +0 -288
  176. package/server/chunks/vidstack-JkJEYEQM.js +0 -159
  177. package/server/chunks/vidstack-KhtuR229.js +0 -504
  178. package/server/chunks/vidstack-NXcLNXxO.js +0 -84
  179. package/server/chunks/vidstack-OKdxH1xx.js +0 -189
  180. package/server/chunks/vidstack-SkX-mSrw.js +0 -206
  181. package/server/chunks/vidstack-X1Hex9PH.js +0 -84
  182. package/server/chunks/vidstack-iVN8uBAv.js +0 -288
  183. package/server/chunks/vidstack-jlaBqZq5.js +0 -61
  184. package/server/chunks/vidstack-m8aA99tE.js +0 -159
  185. package/server/chunks/vidstack-rUHVQoo3.js +0 -61
  186. package/server/chunks/vidstack-rWs25cS9.js +0 -159
  187. package/server/chunks/vidstack-uyCXITen.js +0 -504
  188. package/server/chunks/vidstack-yf18YVAb.js +0 -545
@@ -1,1384 +0,0 @@
1
- "use client"
2
-
3
- import * as React from 'react';
4
- import { useSignal, composeRefs, isBoolean, uppercaseFirstChar, isUndefined, isString, isArray, camelToKebabCase, isKeyboardClick, listenEvent, toggleClass, useContext } from './vidstack-D4t_SZbb.js';
5
- import { createComputed, createSignal, MediaAnnouncer, Root, Trigger, Content, GoogleCastButton, Captions, useChapterOptions, Root$1 as Root$5, Root$2 as Root$6, Root$3 as Root$7, useScoped, Root$4 as Root$a, Group, useChapterTitle, createEffect, useActiveTextTrack, ChapterTitle as ChapterTitle$1, Title, Root$5 as Root$b, Track as Track$1, TrackFill as TrackFill$1 } from './vidstack-B4rJ1ZKK.js';
6
- import { useColorSchemePreference, useActive, useResizeObserver, useLayoutName, useTransitionActive } from './vidstack-BTdEfKqV.js';
7
- import { useMediaContext, MuteButton, SeekButton, LiveButton, PlayButton, CaptionButton, appendParamsToURL, PIPButton, FullscreenButton, AirPlayButton, Items, Root$3 as Root$1, Item, Root as Root$2, Img, Root$2 as Root$3, Button, Portal, Track, TrackFill, Thumb, Steps, useMediaPlayer, Root$5 as Root$4, useAudioOptions, useCaptionOptions, Root$4 as Root$8, Preview, Value, Root$1 as Root$9, Chapters, Progress, Thumbnail, ChapterTitle, Time, Gesture } from './vidstack-DbNoKLjz.js';
8
- import { useMediaState, isRemotionSrc, Primitive } from './vidstack-SkX-mSrw.js';
9
- import { isTrackCaptionKind, getDownloadFile, sortVideoQualities, mediaContext } from 'vidstack';
10
- import { flushSync } from 'react-dom';
11
- import { RemotionThumbnail, RemotionSliderThumbnail } from './vidstack-DeS67_gx.js';
12
- import { FONT_FAMILY_OPTION, FONT_SIZE_OPTION, FONT_COLOR_OPTION, FONT_TEXT_SHADOW_OPTION, FONT_OPACITY_OPTION, onFontReset, FONT_SIGNALS, updateFontCssVars } from 'vidstack/exports/font.ts';
13
-
14
- const DefaultLayoutContext = React.createContext({});
15
- DefaultLayoutContext.displayName = "DefaultLayoutContext";
16
- function useDefaultLayoutContext() {
17
- return React.useContext(DefaultLayoutContext);
18
- }
19
- function useDefaultLayoutWord(word) {
20
- const { translations } = useDefaultLayoutContext();
21
- return i18n(translations, word);
22
- }
23
- function i18n(translations, word) {
24
- return translations?.[word] ?? word;
25
- }
26
-
27
- function useColorSchemeClass(colorScheme) {
28
- const systemColorPreference = useColorSchemePreference();
29
- if (colorScheme === "default") {
30
- return null;
31
- } else if (colorScheme === "system") {
32
- return systemColorPreference;
33
- } else {
34
- return colorScheme;
35
- }
36
- }
37
-
38
- function createDefaultMediaLayout({
39
- type,
40
- smLayoutWhen,
41
- renderLayout
42
- }) {
43
- const Layout = React.forwardRef(
44
- ({
45
- children,
46
- className,
47
- disableTimeSlider = false,
48
- hideQualityBitrate = false,
49
- icons,
50
- colorScheme = "system",
51
- download = null,
52
- menuContainer = null,
53
- menuGroup = "bottom",
54
- noAudioGain = false,
55
- audioGains = { min: 0, max: 300, step: 25 },
56
- noGestures = false,
57
- noKeyboardAnimations = false,
58
- noModal = false,
59
- noScrubGesture,
60
- playbackRates = { min: 0, max: 2, step: 0.25 },
61
- seekStep = 10,
62
- episodes = null,
63
- episodesTitle = "Episodes",
64
- showMenuDelay,
65
- showTooltipDelay = 700,
66
- sliderChaptersMinWidth = 325,
67
- slots,
68
- smallLayoutWhen = smLayoutWhen,
69
- thumbnails = null,
70
- translations,
71
- ...props
72
- }, forwardRef) => {
73
- const media = useMediaContext(), $load = useSignal(media.$props.load), $canLoad = useMediaState("canLoad"), $viewType = useMediaState("viewType"), $streamType = useMediaState("streamType"), $smallWhen = createComputed(() => {
74
- return isBoolean(smallLayoutWhen) ? smallLayoutWhen : smallLayoutWhen(media.player.state);
75
- }, [smallLayoutWhen]), userPrefersAnnouncements = createSignal(true), userPrefersKeyboardAnimations = createSignal(true), isMatch = $viewType === type, isSmallLayout = $smallWhen(), isForcedLayout = isBoolean(smallLayoutWhen), isLoadLayout = $load === "play" && !$canLoad, canRender = $canLoad || isForcedLayout || isLoadLayout, colorSchemeClass = useColorSchemeClass(colorScheme), layoutEl = createSignal(null);
76
- useSignal($smallWhen);
77
- return /* @__PURE__ */ React.createElement(
78
- "div",
79
- {
80
- ...props,
81
- className: `vds-${type}-layout` + (colorSchemeClass ? ` ${colorSchemeClass}` : "") + (className ? ` ${className}` : ""),
82
- "data-match": isMatch ? "" : null,
83
- "data-sm": isSmallLayout ? "" : null,
84
- "data-lg": !isSmallLayout ? "" : null,
85
- "data-size": isSmallLayout ? "sm" : "lg",
86
- "data-no-scrub-gesture": noScrubGesture ? "" : null,
87
- ref: composeRefs(layoutEl.set, forwardRef)
88
- },
89
- canRender && isMatch ? /* @__PURE__ */ React.createElement(
90
- DefaultLayoutContext.Provider,
91
- {
92
- value: {
93
- disableTimeSlider,
94
- hideQualityBitrate,
95
- icons,
96
- colorScheme,
97
- download,
98
- isSmallLayout,
99
- menuContainer,
100
- menuGroup,
101
- noAudioGain,
102
- audioGains,
103
- layoutEl,
104
- noGestures,
105
- noKeyboardAnimations,
106
- noModal,
107
- noScrubGesture,
108
- showMenuDelay,
109
- showTooltipDelay,
110
- sliderChaptersMinWidth,
111
- slots,
112
- seekStep,
113
- episodes,
114
- episodesTitle,
115
- playbackRates,
116
- thumbnails,
117
- translations,
118
- userPrefersAnnouncements,
119
- userPrefersKeyboardAnimations
120
- }
121
- },
122
- renderLayout({ streamType: $streamType, isSmallLayout, isLoadLayout }),
123
- children
124
- ) : null
125
- );
126
- }
127
- );
128
- Layout.displayName = "DefaultMediaLayout";
129
- return Layout;
130
- }
131
-
132
- function useDefaultAudioLayoutSlots() {
133
- return React.useContext(DefaultLayoutContext).slots;
134
- }
135
- function useDefaultVideoLayoutSlots() {
136
- return React.useContext(DefaultLayoutContext).slots;
137
- }
138
- function slot(slots, name, defaultValue) {
139
- const slot2 = slots?.[name], capitalizedName = uppercaseFirstChar(name);
140
- return /* @__PURE__ */ React.createElement(React.Fragment, null, slots?.[`before${capitalizedName}`], isUndefined(slot2) ? defaultValue : slot2, slots?.[`after${capitalizedName}`]);
141
- }
142
-
143
- function DefaultAnnouncer() {
144
- const { userPrefersAnnouncements, translations } = useDefaultLayoutContext(), $userPrefersAnnouncements = useSignal(userPrefersAnnouncements);
145
- if (!$userPrefersAnnouncements) return null;
146
- return /* @__PURE__ */ React.createElement(MediaAnnouncer, { translations });
147
- }
148
- DefaultAnnouncer.displayName = "DefaultAnnouncer";
149
-
150
- function DefaultTooltip({ content, placement, children }) {
151
- const { showTooltipDelay } = useDefaultLayoutContext();
152
- return /* @__PURE__ */ React.createElement(Root, { showDelay: showTooltipDelay }, /* @__PURE__ */ React.createElement(Trigger, { asChild: true }, children), /* @__PURE__ */ React.createElement(Content, { className: "vds-tooltip-content", placement }, content));
153
- }
154
- DefaultTooltip.displayName = "DefaultTooltip";
155
-
156
- function DefaultPlayButton({ tooltip }) {
157
- const { icons: Icons } = useDefaultLayoutContext(), playText = useDefaultLayoutWord("Play"), pauseText = useDefaultLayoutWord("Pause"), $paused = useMediaState("paused"), $ended = useMediaState("ended");
158
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $paused ? playText : pauseText, placement: tooltip }, /* @__PURE__ */ React.createElement(PlayButton, { className: "vds-play-button vds-button", "aria-label": playText }, $ended ? /* @__PURE__ */ React.createElement(Icons.PlayButton.Replay, { className: "vds-icon" }) : $paused ? /* @__PURE__ */ React.createElement(Icons.PlayButton.Play, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.PlayButton.Pause, { className: "vds-icon" })));
159
- }
160
- DefaultPlayButton.displayName = "DefaultPlayButton";
161
- const DefaultMuteButton = React.forwardRef(
162
- ({ tooltip }, forwardRef) => {
163
- const { icons: Icons } = useDefaultLayoutContext(), muteText = useDefaultLayoutWord("Mute"), unmuteText = useDefaultLayoutWord("Unmute"), $muted = useMediaState("muted"), $volume = useMediaState("volume");
164
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $muted ? unmuteText : muteText, placement: tooltip }, /* @__PURE__ */ React.createElement(MuteButton, { className: "vds-mute-button vds-button", "aria-label": muteText, ref: forwardRef }, $muted || $volume == 0 ? /* @__PURE__ */ React.createElement(Icons.MuteButton.Mute, { className: "vds-icon" }) : $volume < 0.5 ? /* @__PURE__ */ React.createElement(Icons.MuteButton.VolumeLow, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.MuteButton.VolumeHigh, { className: "vds-icon" })));
165
- }
166
- );
167
- DefaultMuteButton.displayName = "DefaultMuteButton";
168
- function DefaultCaptionButton({ tooltip }) {
169
- const { icons: Icons } = useDefaultLayoutContext(), captionsText = useDefaultLayoutWord("Captions"), onText = useDefaultLayoutWord("Closed-Captions On"), offText = useDefaultLayoutWord("Closed-Captions Off"), $track = useMediaState("textTrack"), isOn = $track && isTrackCaptionKind($track);
170
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: isOn ? onText : offText, placement: tooltip }, /* @__PURE__ */ React.createElement(CaptionButton, { className: "vds-caption-button vds-button", "aria-label": captionsText }, isOn ? /* @__PURE__ */ React.createElement(Icons.CaptionButton.On, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.CaptionButton.Off, { className: "vds-icon" })));
171
- }
172
- DefaultCaptionButton.displayName = "DefaultCaptionButton";
173
- function DefaultPIPButton({ tooltip }) {
174
- const { icons: Icons } = useDefaultLayoutContext(), pipText = useDefaultLayoutWord("PiP"), enterText = useDefaultLayoutWord("Enter PiP"), exitText = useDefaultLayoutWord("Exit PiP"), $pip = useMediaState("pictureInPicture");
175
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $pip ? exitText : enterText, placement: tooltip }, /* @__PURE__ */ React.createElement(PIPButton, { className: "vds-pip-button vds-button", "aria-label": pipText }, $pip ? /* @__PURE__ */ React.createElement(Icons.PIPButton.Exit, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.PIPButton.Enter, { className: "vds-icon" })));
176
- }
177
- DefaultPIPButton.displayName = "DefaultPIPButton";
178
- function DefaultFullscreenButton({ tooltip }) {
179
- const { icons: Icons } = useDefaultLayoutContext(), fullscreenText = useDefaultLayoutWord("Fullscreen"), enterText = useDefaultLayoutWord("Enter Fullscreen"), exitText = useDefaultLayoutWord("Exit Fullscreen"), $fullscreen = useMediaState("fullscreen");
180
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: $fullscreen ? exitText : enterText, placement: tooltip }, /* @__PURE__ */ React.createElement(FullscreenButton, { className: "vds-fullscreen-button vds-button", "aria-label": fullscreenText }, $fullscreen ? /* @__PURE__ */ React.createElement(Icons.FullscreenButton.Exit, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.FullscreenButton.Enter, { className: "vds-icon" })));
181
- }
182
- DefaultFullscreenButton.displayName = "DefaultFullscreenButton";
183
- function DefaultSeekButton({
184
- backward,
185
- tooltip
186
- }) {
187
- const { icons: Icons, seekStep } = useDefaultLayoutContext(), seekForwardText = useDefaultLayoutWord("Seek Forward"), seekBackwardText = useDefaultLayoutWord("Seek Backward"), seconds = (backward ? -1 : 1) * seekStep, label = seconds >= 0 ? seekForwardText : seekBackwardText;
188
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: label, placement: tooltip }, /* @__PURE__ */ React.createElement(SeekButton, { className: "vds-seek-button vds-button", seconds, "aria-label": label }, seconds >= 0 ? /* @__PURE__ */ React.createElement(Icons.SeekButton.Forward, { className: "vds-icon" }) : /* @__PURE__ */ React.createElement(Icons.SeekButton.Backward, { className: "vds-icon" })));
189
- }
190
- DefaultSeekButton.displayName = "DefaultSeekButton";
191
- function DefaultEpisodeButton({ tooltip, onPress }) {
192
- const { icons: Icons } = useDefaultLayoutContext(), episodesText = useDefaultLayoutWord("Episodes");
193
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: episodesText, placement: tooltip }, /* @__PURE__ */ React.createElement(
194
- "button",
195
- {
196
- type: "button",
197
- className: "vds-episode-button vds-button",
198
- "aria-label": episodesText,
199
- onPointerUp: (event) => {
200
- event.stopPropagation();
201
- onPress?.(event);
202
- }
203
- },
204
- /* @__PURE__ */ React.createElement(Icons.Menu.Chapters, { className: "vds-icon" })
205
- ));
206
- }
207
- DefaultEpisodeButton.displayName = "DefaultEpisodeButton";
208
- function DefaultAirPlayButton({ tooltip }) {
209
- const { icons: Icons } = useDefaultLayoutContext(), airPlayText = useDefaultLayoutWord("AirPlay"), $state = useMediaState("remotePlaybackState"), stateText = useDefaultLayoutWord(uppercaseFirstChar($state)), label = `${airPlayText} ${stateText}`, Icon = ($state === "connecting" ? Icons.AirPlayButton.Connecting : $state === "connected" ? Icons.AirPlayButton.Connected : null) ?? Icons.AirPlayButton.Default;
210
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: airPlayText, placement: tooltip }, /* @__PURE__ */ React.createElement(AirPlayButton, { className: "vds-airplay-button vds-button", "aria-label": label }, /* @__PURE__ */ React.createElement(Icon, { className: "vds-icon" })));
211
- }
212
- DefaultAirPlayButton.displayName = "DefaultAirPlayButton";
213
- function DefaultGoogleCastButton({ tooltip }) {
214
- const { icons: Icons } = useDefaultLayoutContext(), googleCastText = useDefaultLayoutWord("Google Cast"), $state = useMediaState("remotePlaybackState"), stateText = useDefaultLayoutWord(uppercaseFirstChar($state)), label = `${googleCastText} ${stateText}`, Icon = ($state === "connecting" ? Icons.GoogleCastButton.Connecting : $state === "connected" ? Icons.GoogleCastButton.Connected : null) ?? Icons.GoogleCastButton.Default;
215
- return /* @__PURE__ */ React.createElement(DefaultTooltip, { content: googleCastText, placement: tooltip }, /* @__PURE__ */ React.createElement(GoogleCastButton, { className: "vds-google-cast-button vds-button", "aria-label": label }, /* @__PURE__ */ React.createElement(Icon, { className: "vds-icon" })));
216
- }
217
- DefaultGoogleCastButton.displayName = "DefaultGoogleCastButton";
218
- function DefaultLiveButton() {
219
- const $live = useMediaState("live"), label = useDefaultLayoutWord("Skip To Live"), liveText = useDefaultLayoutWord("LIVE");
220
- return $live ? /* @__PURE__ */ React.createElement(LiveButton, { className: "vds-live-button", "aria-label": label }, /* @__PURE__ */ React.createElement("span", { className: "vds-live-button-text" }, liveText)) : null;
221
- }
222
- DefaultLiveButton.displayName = "DefaultLiveButton";
223
- function DefaultDownloadButton() {
224
- const { download, icons: Icons } = useDefaultLayoutContext(), $src = useMediaState("source"), $title = useMediaState("title"), file = getDownloadFile({
225
- title: $title,
226
- src: $src,
227
- download
228
- }), downloadText = useDefaultLayoutWord("Download");
229
- return isString(file?.url) ? /* @__PURE__ */ React.createElement(DefaultTooltip, { content: downloadText, placement: "top" }, /* @__PURE__ */ React.createElement(
230
- "a",
231
- {
232
- role: "button",
233
- className: "vds-download-button vds-button",
234
- "aria-label": downloadText,
235
- href: appendParamsToURL(file.url, { download: file.name }),
236
- download: file.name,
237
- target: "_blank"
238
- },
239
- Icons.DownloadButton ? /* @__PURE__ */ React.createElement(Icons.DownloadButton.Default, { className: "vds-icon" }) : null
240
- )) : null;
241
- }
242
- DefaultDownloadButton.displayName = "DefaultDownloadButton";
243
-
244
- function DefaultCaptions() {
245
- const exampleText = useDefaultLayoutWord("Captions look like this");
246
- return /* @__PURE__ */ React.createElement(Captions, { className: "vds-captions", exampleText });
247
- }
248
- DefaultCaptions.displayName = "DefaultCaptions";
249
-
250
- function DefaultControlsSpacer() {
251
- return /* @__PURE__ */ React.createElement("div", { className: "vds-controls-spacer" });
252
- }
253
- DefaultControlsSpacer.displayName = "DefaultControlsSpacer";
254
-
255
- function useParentDialogEl() {
256
- const { layoutEl } = useDefaultLayoutContext(), $layoutEl = useSignal(layoutEl);
257
- return React.useMemo(() => $layoutEl?.closest("dialog"), [$layoutEl]);
258
- }
259
-
260
- function DefaultChaptersMenu({ tooltip, placement, portalClass = "" }) {
261
- const {
262
- showMenuDelay,
263
- noModal,
264
- isSmallLayout,
265
- icons: Icons,
266
- menuGroup,
267
- menuContainer,
268
- colorScheme
269
- } = useDefaultLayoutContext(), chaptersText = useDefaultLayoutWord("Chapters"), options = useChapterOptions(), disabled = !options.length, { thumbnails } = useDefaultLayoutContext(), $src = useMediaState("currentSrc"), $viewType = useMediaState("viewType"), $offset = !isSmallLayout && menuGroup === "bottom" && $viewType === "video" ? 26 : 0, $RemotionThumbnail = useSignal(RemotionThumbnail), colorSchemeClass = useColorSchemeClass(colorScheme), [isOpen, setIsOpen] = React.useState(false), dialogEl = useParentDialogEl();
270
- if (disabled) return null;
271
- function onOpen() {
272
- flushSync(() => {
273
- setIsOpen(true);
274
- });
275
- }
276
- function onClose() {
277
- setIsOpen(false);
278
- }
279
- const Content = /* @__PURE__ */ React.createElement(
280
- Items,
281
- {
282
- className: "vds-chapters-menu-items vds-menu-items",
283
- placement,
284
- offset: $offset
285
- },
286
- isOpen ? /* @__PURE__ */ React.createElement(
287
- Root$1,
288
- {
289
- className: "vds-chapters-radio-group vds-radio-group",
290
- value: options.selectedValue,
291
- "data-thumbnails": thumbnails ? "" : null
292
- },
293
- options.map(
294
- ({ cue, label, value, startTimeText, durationText, select, setProgressVar }) => /* @__PURE__ */ React.createElement(
295
- Item,
296
- {
297
- className: "vds-chapter-radio vds-radio",
298
- value,
299
- key: value,
300
- onSelect: select,
301
- ref: setProgressVar
302
- },
303
- thumbnails ? /* @__PURE__ */ React.createElement(Root$2, { src: thumbnails, className: "vds-thumbnail", time: cue.startTime }, /* @__PURE__ */ React.createElement(Img, null)) : $RemotionThumbnail && isRemotionSrc($src) ? /* @__PURE__ */ React.createElement($RemotionThumbnail, { className: "vds-thumbnail", frame: cue.startTime * $src.fps }) : null,
304
- /* @__PURE__ */ React.createElement("div", { className: "vds-chapter-radio-content" }, /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-radio-label" }, label), /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-radio-start-time" }, startTimeText), /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-radio-duration" }, durationText))
305
- )
306
- )
307
- ) : null
308
- );
309
- return /* @__PURE__ */ React.createElement(
310
- Root$3,
311
- {
312
- className: "vds-chapters-menu vds-menu",
313
- showDelay: showMenuDelay,
314
- onOpen,
315
- onClose
316
- },
317
- /* @__PURE__ */ React.createElement(DefaultTooltip, { content: chaptersText, placement: tooltip }, /* @__PURE__ */ React.createElement(
318
- Button,
319
- {
320
- className: "vds-menu-button vds-button",
321
- disabled,
322
- "aria-label": chaptersText
323
- },
324
- /* @__PURE__ */ React.createElement(Icons.Menu.Chapters, { className: "vds-icon" })
325
- )),
326
- noModal || !isSmallLayout ? Content : /* @__PURE__ */ React.createElement(
327
- Portal,
328
- {
329
- container: menuContainer ?? dialogEl,
330
- className: portalClass + (colorSchemeClass ? ` ${colorSchemeClass}` : ""),
331
- disabled: "fullscreen",
332
- "data-sm": isSmallLayout ? "" : null,
333
- "data-lg": !isSmallLayout ? "" : null,
334
- "data-size": isSmallLayout ? "sm" : "lg"
335
- },
336
- Content
337
- )
338
- );
339
- }
340
- DefaultChaptersMenu.displayName = "DefaultChaptersMenu";
341
-
342
- function DefaultMenuSection({ label, value, children }) {
343
- const id = React.useId();
344
- if (!label) {
345
- return /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section" }, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-body" }, children));
346
- }
347
- return /* @__PURE__ */ React.createElement("section", { className: "vds-menu-section", role: "group", "aria-labelledby": id }, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-title" }, /* @__PURE__ */ React.createElement("header", { id }, label), value ? /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-value" }, value) : null), /* @__PURE__ */ React.createElement("div", { className: "vds-menu-section-body" }, children));
348
- }
349
- DefaultMenuSection.displayName = "DefaultMenuSection";
350
- function DefaultMenuButton({ label, hint = "", Icon, disabled = false }) {
351
- const { icons: Icons } = React.useContext(DefaultLayoutContext);
352
- return /* @__PURE__ */ React.createElement(Button, { className: "vds-menu-item", disabled }, /* @__PURE__ */ React.createElement(Icons.Menu.ArrowLeft, { className: "vds-menu-close-icon vds-icon" }), Icon ? /* @__PURE__ */ React.createElement(Icon, { className: "vds-menu-item-icon vds-icon" }) : null, /* @__PURE__ */ React.createElement("span", { className: "vds-menu-item-label" }, label), /* @__PURE__ */ React.createElement("span", { className: "vds-menu-item-hint" }, hint), /* @__PURE__ */ React.createElement(Icons.Menu.ArrowRight, { className: "vds-menu-open-icon vds-icon" }));
353
- }
354
- DefaultMenuButton.displayName = "DefaultMenuButton";
355
- function DefaultMenuItem({ label, children }) {
356
- return /* @__PURE__ */ React.createElement("div", { className: "vds-menu-item" }, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-item-label" }, label), children);
357
- }
358
- DefaultMenuItem.displayName = "DefaultMenuItem";
359
- function DefaultMenuRadioGroup({ value, options, onChange }) {
360
- const { icons: Icons } = useDefaultLayoutContext();
361
- return /* @__PURE__ */ React.createElement(Root$1, { className: "vds-radio-group", value, onChange }, options.map((option) => /* @__PURE__ */ React.createElement(Item, { className: "vds-radio", value: option.value, key: option.value }, /* @__PURE__ */ React.createElement(Icons.Menu.RadioCheck, { className: "vds-icon" }), /* @__PURE__ */ React.createElement("span", { className: "vds-radio-label", "data-part": "label" }, option.label))));
362
- }
363
- DefaultMenuRadioGroup.displayName = "DefaultMenuRadioGroup";
364
- function createRadioOptions(entries) {
365
- return React.useMemo(
366
- () => isArray(entries) ? entries.map((entry) => ({ label: entry, value: entry.toLowerCase() })) : Object.keys(entries).map((label) => ({ label, value: entries[label] })),
367
- [entries]
368
- );
369
- }
370
-
371
- function DefaultMenuSliderItem({
372
- label,
373
- value,
374
- UpIcon,
375
- DownIcon,
376
- children,
377
- isMin,
378
- isMax
379
- }) {
380
- const hasTitle = label || value, Content = /* @__PURE__ */ React.createElement(React.Fragment, null, DownIcon ? /* @__PURE__ */ React.createElement(DownIcon, { className: "vds-icon down" }) : null, children, UpIcon ? /* @__PURE__ */ React.createElement(UpIcon, { className: "vds-icon up" }) : null);
381
- return /* @__PURE__ */ React.createElement(
382
- "div",
383
- {
384
- className: `vds-menu-item vds-menu-slider-item${hasTitle ? " group" : ""}`,
385
- "data-min": isMin ? "" : null,
386
- "data-max": isMax ? "" : null
387
- },
388
- hasTitle ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "vds-menu-slider-title" }, label ? /* @__PURE__ */ React.createElement("div", null, label) : null, value ? /* @__PURE__ */ React.createElement("div", null, value) : null), /* @__PURE__ */ React.createElement("div", { className: "vds-menu-slider-body" }, Content)) : Content
389
- );
390
- }
391
- DefaultMenuSliderItem.displayName = "DefaultMenuSliderItem";
392
- function DefaultSliderParts() {
393
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Track, { className: "vds-slider-track" }), /* @__PURE__ */ React.createElement(TrackFill, { className: "vds-slider-track-fill vds-slider-track" }), /* @__PURE__ */ React.createElement(Thumb, { className: "vds-slider-thumb" }));
394
- }
395
- DefaultSliderParts.displayName = "DefaultSliderParts";
396
- function DefaultSliderSteps() {
397
- return /* @__PURE__ */ React.createElement(Steps, { className: "vds-slider-steps" }, (step) => /* @__PURE__ */ React.createElement("div", { className: "vds-slider-step", key: String(step) }));
398
- }
399
- DefaultSliderSteps.displayName = "DefaultSliderSteps";
400
-
401
- function DefaultFontMenu() {
402
- const label = useDefaultLayoutWord("Caption Styles"), $hasCaptions = useMediaState("hasCaptions"), fontSectionLabel = useDefaultLayoutWord("Font"), textSectionLabel = useDefaultLayoutWord("Text"), textBgSectionLabel = useDefaultLayoutWord("Text Background"), displayBgSectionLabel = useDefaultLayoutWord("Display Background");
403
- if (!$hasCaptions) return null;
404
- return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-font-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label }), /* @__PURE__ */ React.createElement(Items, { className: "vds-font-style-items vds-menu-items" }, /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: fontSectionLabel }, /* @__PURE__ */ React.createElement(DefaultFontFamilyMenu, null), /* @__PURE__ */ React.createElement(DefaultFontSizeSlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: textSectionLabel }, /* @__PURE__ */ React.createElement(DefaultTextColorInput, null), /* @__PURE__ */ React.createElement(DefaultTextShadowMenu, null), /* @__PURE__ */ React.createElement(DefaultTextOpacitySlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: textBgSectionLabel }, /* @__PURE__ */ React.createElement(DefaultTextBgInput, null), /* @__PURE__ */ React.createElement(DefaultTextBgOpacitySlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, { label: displayBgSectionLabel }, /* @__PURE__ */ React.createElement(DefaultDisplayBgInput, null), /* @__PURE__ */ React.createElement(DefaultDisplayBgOpacitySlider, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, /* @__PURE__ */ React.createElement(DefaultResetMenuItem, null))));
405
- }
406
- DefaultFontMenu.displayName = "DefaultFontMenu";
407
- function DefaultFontFamilyMenu() {
408
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Family", type: "fontFamily", option: FONT_FAMILY_OPTION });
409
- }
410
- DefaultFontFamilyMenu.displayName = "DefaultFontFamilyMenu";
411
- function DefaultFontSizeSlider() {
412
- const { icons: Icons } = useDefaultLayoutContext(), option = {
413
- ...FONT_SIZE_OPTION,
414
- upIcon: Icons.Menu.FontSizeUp,
415
- downIcon: Icons.Menu.FontSizeDown
416
- };
417
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Size", type: "fontSize", option });
418
- }
419
- DefaultFontSizeSlider.displayName = "DefaultFontSizeSlider";
420
- function DefaultTextColorInput() {
421
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Color", type: "textColor", option: FONT_COLOR_OPTION });
422
- }
423
- DefaultTextColorInput.displayName = "DefaultTextColorInput";
424
- function DefaultTextOpacitySlider() {
425
- const { icons: Icons } = useDefaultLayoutContext(), option = {
426
- ...FONT_OPACITY_OPTION,
427
- upIcon: Icons.Menu.OpacityUp,
428
- downIcon: Icons.Menu.OpacityDown
429
- };
430
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Opacity", type: "textOpacity", option });
431
- }
432
- DefaultTextOpacitySlider.displayName = "DefaultTextOpacitySlider";
433
- function DefaultTextShadowMenu() {
434
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Shadow", type: "textShadow", option: FONT_TEXT_SHADOW_OPTION });
435
- }
436
- DefaultTextShadowMenu.displayName = "DefaultTextShadowMenu";
437
- function DefaultTextBgInput() {
438
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Color", type: "textBg", option: FONT_COLOR_OPTION });
439
- }
440
- DefaultTextBgInput.displayName = "DefaultTextBgInput";
441
- function DefaultTextBgOpacitySlider() {
442
- const { icons: Icons } = useDefaultLayoutContext(), option = {
443
- ...FONT_OPACITY_OPTION,
444
- upIcon: Icons.Menu.OpacityUp,
445
- downIcon: Icons.Menu.OpacityDown
446
- };
447
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Opacity", type: "textBgOpacity", option });
448
- }
449
- DefaultTextBgOpacitySlider.displayName = "DefaultTextBgOpacitySlider";
450
- function DefaultDisplayBgInput() {
451
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Color", type: "displayBg", option: FONT_COLOR_OPTION });
452
- }
453
- DefaultDisplayBgInput.displayName = "DefaultDisplayBgInput";
454
- function DefaultDisplayBgOpacitySlider() {
455
- const { icons: Icons } = useDefaultLayoutContext(), option = {
456
- ...FONT_OPACITY_OPTION,
457
- upIcon: Icons.Menu.OpacityUp,
458
- downIcon: Icons.Menu.OpacityDown
459
- };
460
- return /* @__PURE__ */ React.createElement(DefaultFontSetting, { label: "Opacity", type: "displayBgOpacity", option });
461
- }
462
- DefaultDisplayBgOpacitySlider.displayName = "DefaultDisplayBgOpacitySlider";
463
- function DefaultFontSetting({ label, option, type }) {
464
- const player = useMediaPlayer(), $currentValue = FONT_SIGNALS[type], $value = useSignal($currentValue), translatedLabel = useDefaultLayoutWord(label);
465
- const notify = React.useCallback(() => {
466
- player?.dispatchEvent(new Event("vds-font-change"));
467
- }, [player]);
468
- const onChange = React.useCallback(
469
- (newValue) => {
470
- $currentValue.set(newValue);
471
- notify();
472
- },
473
- [$currentValue, notify]
474
- );
475
- if (option.type === "color") {
476
- let onColorChange2 = function(event) {
477
- onChange(event.target.value);
478
- };
479
- return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label: translatedLabel }, /* @__PURE__ */ React.createElement("input", { className: "vds-color-picker", type: "color", value: $value, onChange: onColorChange2 }));
480
- }
481
- if (option.type === "slider") {
482
- let onSliderValueChange2 = function(value) {
483
- onChange(value + "%");
484
- };
485
- const { min, max, step, upIcon, downIcon } = option;
486
- return /* @__PURE__ */ React.createElement(
487
- DefaultMenuSliderItem,
488
- {
489
- label: translatedLabel,
490
- value: $value,
491
- UpIcon: upIcon,
492
- DownIcon: downIcon,
493
- isMin: $value === min + "%",
494
- isMax: $value === max + "%"
495
- },
496
- /* @__PURE__ */ React.createElement(
497
- Root$4,
498
- {
499
- className: "vds-slider",
500
- min,
501
- max,
502
- step,
503
- keyStep: step,
504
- value: parseInt($value),
505
- "aria-label": translatedLabel,
506
- onValueChange: onSliderValueChange2,
507
- onDragValueChange: onSliderValueChange2
508
- },
509
- /* @__PURE__ */ React.createElement(DefaultSliderParts, null),
510
- /* @__PURE__ */ React.createElement(DefaultSliderSteps, null)
511
- )
512
- );
513
- }
514
- if (option.type === "radio") {
515
- return /* @__PURE__ */ React.createElement(
516
- DefaultFontRadioGroup,
517
- {
518
- id: camelToKebabCase(type),
519
- label: translatedLabel,
520
- value: $value,
521
- values: option.values,
522
- onChange
523
- }
524
- );
525
- }
526
- return null;
527
- }
528
- DefaultFontSetting.displayName = "DefaultFontSetting";
529
- function DefaultFontRadioGroup({ id, label, value, values, onChange }) {
530
- const radioOptions = createRadioOptions(values), { translations } = useDefaultLayoutContext(), hint = React.useMemo(() => {
531
- const label2 = radioOptions.find((radio) => radio.value === value)?.label || "";
532
- return i18n(translations, label2);
533
- }, [value, radioOptions]);
534
- return /* @__PURE__ */ React.createElement(Root$3, { className: `vds-${id}-menu vds-menu` }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, hint }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, /* @__PURE__ */ React.createElement(DefaultMenuRadioGroup, { value, options: radioOptions, onChange })));
535
- }
536
- DefaultFontRadioGroup.displayName = "DefaultFontRadioGroup";
537
- function DefaultResetMenuItem() {
538
- const resetText = useDefaultLayoutWord("Reset");
539
- return /* @__PURE__ */ React.createElement("button", { className: "vds-menu-item", role: "menuitem", onClick: onFontReset }, /* @__PURE__ */ React.createElement("span", { className: "vds-menu-item-label" }, resetText));
540
- }
541
- DefaultResetMenuItem.displayName = "DefaultResetMenuItem";
542
-
543
- function DefaultMenuCheckbox({
544
- label,
545
- checked,
546
- storageKey,
547
- defaultChecked = false,
548
- onChange
549
- }) {
550
- const [isChecked, setIsChecked] = React.useState(defaultChecked), [isActive, setIsActive] = React.useState(false);
551
- React.useEffect(() => {
552
- const savedValue = storageKey ? localStorage.getItem(storageKey) : null, checked2 = !!(savedValue ?? defaultChecked);
553
- setIsChecked(checked2);
554
- onChange?.(checked2);
555
- }, []);
556
- React.useEffect(() => {
557
- if (isBoolean(checked)) setIsChecked(checked);
558
- }, [checked]);
559
- function onPress(event) {
560
- if (event && "button" in event && event?.button === 1) return;
561
- const toggledCheck = !isChecked;
562
- setIsChecked(toggledCheck);
563
- if (storageKey) localStorage.setItem(storageKey, toggledCheck ? "1" : "");
564
- onChange?.(toggledCheck, event?.nativeEvent);
565
- setIsActive(false);
566
- }
567
- function onActive(event) {
568
- if (event.button !== 0) return;
569
- setIsActive(true);
570
- }
571
- function onKeyDown(event) {
572
- if (isKeyboardClick(event.nativeEvent)) onPress();
573
- }
574
- return /* @__PURE__ */ React.createElement(
575
- "div",
576
- {
577
- className: "vds-menu-checkbox",
578
- role: "menuitemcheckbox",
579
- tabIndex: 0,
580
- "aria-label": label,
581
- "aria-checked": isChecked ? "true" : "false",
582
- "data-active": isActive ? "" : null,
583
- onPointerUp: onPress,
584
- onPointerDown: onActive,
585
- onKeyDown
586
- }
587
- );
588
- }
589
- DefaultMenuCheckbox.displayName = "DefaultMenuCheckbox";
590
-
591
- function DefaultAccessibilityMenu({ slots }) {
592
- const label = useDefaultLayoutWord("Accessibility"), { icons: Icons } = useDefaultLayoutContext();
593
- return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-accessibility-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, Icon: Icons.Menu.Accessibility }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "accessibilityMenuItemsStart", null), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, /* @__PURE__ */ React.createElement(DefaultAnnouncementsMenuCheckbox, null), /* @__PURE__ */ React.createElement(DefaultKeyboardAnimationsMenuCheckbox, null)), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, /* @__PURE__ */ React.createElement(DefaultFontMenu, null)), slot(slots, "accessibilityMenuItemsEnd", null)));
594
- }
595
- DefaultAccessibilityMenu.displayName = "DefaultAccessibilityMenu";
596
- function DefaultAnnouncementsMenuCheckbox() {
597
- const { userPrefersAnnouncements } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Announcements");
598
- function onChange(checked) {
599
- userPrefersAnnouncements.set(checked);
600
- }
601
- return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(
602
- DefaultMenuCheckbox,
603
- {
604
- label,
605
- defaultChecked: true,
606
- storageKey: "vds-player::announcements",
607
- onChange
608
- }
609
- ));
610
- }
611
- DefaultAnnouncementsMenuCheckbox.displayName = "DefaultAnnouncementsMenuCheckbox";
612
- function DefaultKeyboardAnimationsMenuCheckbox() {
613
- const $viewType = useMediaState("viewType"), { userPrefersKeyboardAnimations, noKeyboardAnimations } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Keyboard Animations");
614
- if ($viewType !== "video" || noKeyboardAnimations) return null;
615
- function onChange(checked) {
616
- userPrefersKeyboardAnimations.set(checked);
617
- }
618
- return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(
619
- DefaultMenuCheckbox,
620
- {
621
- label,
622
- defaultChecked: true,
623
- storageKey: "vds-player::keyboard-animations",
624
- onChange
625
- }
626
- ));
627
- }
628
- DefaultKeyboardAnimationsMenuCheckbox.displayName = "DefaultKeyboardAnimationsMenuCheckbox";
629
-
630
- function DefaultAudioMenu({ slots }) {
631
- const label = useDefaultLayoutWord("Audio"), $canSetAudioGain = useMediaState("canSetAudioGain"), $audioTracks = useMediaState("audioTracks"), { noAudioGain, icons: Icons } = useDefaultLayoutContext(), hasGainSlider = $canSetAudioGain && !noAudioGain, $disabled = !hasGainSlider && $audioTracks.length <= 1;
632
- if ($disabled) return null;
633
- return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-audio-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, Icon: Icons.Menu.Audio }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "audioMenuItemsStart", null), /* @__PURE__ */ React.createElement(DefaultAudioTracksMenu, null), hasGainSlider ? /* @__PURE__ */ React.createElement(DefaultAudioBoostMenuSection, null) : null, slot(slots, "audioMenuItemsEnd", null)));
634
- }
635
- DefaultAudioMenu.displayName = "DefaultAudioMenu";
636
- function DefaultAudioBoostMenuSection() {
637
- const $audioGain = useMediaState("audioGain"), label = useDefaultLayoutWord("Boost"), value = Math.round((($audioGain ?? 1) - 1) * 100) + "%", $canSetAudioGain = useMediaState("canSetAudioGain"), { noAudioGain, icons: Icons } = useDefaultLayoutContext(), $disabled = !$canSetAudioGain || noAudioGain, min = useGainMin(), max = useGainMax();
638
- if ($disabled) return null;
639
- return /* @__PURE__ */ React.createElement(DefaultMenuSection, { label, value }, /* @__PURE__ */ React.createElement(
640
- DefaultMenuSliderItem,
641
- {
642
- UpIcon: Icons.Menu.AudioBoostUp,
643
- DownIcon: Icons.Menu.AudioBoostDown,
644
- isMin: (($audioGain ?? 1) - 1) * 100 <= min,
645
- isMax: (($audioGain ?? 1) - 1) * 100 === max
646
- },
647
- /* @__PURE__ */ React.createElement(DefaultAudioGainSlider, null)
648
- ));
649
- }
650
- DefaultAudioBoostMenuSection.displayName = "DefaultAudioBoostMenuSection";
651
- function useGainMin() {
652
- const { audioGains } = useDefaultLayoutContext(), min = isArray(audioGains) ? audioGains[0] : audioGains?.min;
653
- return min ?? 0;
654
- }
655
- function useGainMax() {
656
- const { audioGains } = useDefaultLayoutContext(), max = isArray(audioGains) ? audioGains[audioGains.length - 1] : audioGains?.max;
657
- return max ?? 300;
658
- }
659
- function useGainStep() {
660
- const { audioGains } = useDefaultLayoutContext(), step = isArray(audioGains) ? audioGains[1] - audioGains[0] : audioGains?.step;
661
- return step || 25;
662
- }
663
- function DefaultAudioGainSlider() {
664
- const label = useDefaultLayoutWord("Audio Boost"), min = useGainMin(), max = useGainMax(), step = useGainStep();
665
- return /* @__PURE__ */ React.createElement(
666
- Root$5,
667
- {
668
- className: "vds-audio-gain-slider vds-slider",
669
- "aria-label": label,
670
- min,
671
- max,
672
- step,
673
- keyStep: step
674
- },
675
- /* @__PURE__ */ React.createElement(DefaultSliderParts, null),
676
- /* @__PURE__ */ React.createElement(DefaultSliderSteps, null)
677
- );
678
- }
679
- DefaultAudioGainSlider.displayName = "DefaultAudioGainSlider";
680
- function DefaultAudioTracksMenu() {
681
- const { icons: Icons } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Track"), defaultText = useDefaultLayoutWord("Default"), $track = useMediaState("audioTrack"), options = useAudioOptions();
682
- if (options.disabled) return null;
683
- return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-audio-track-menu vds-menu" }, /* @__PURE__ */ React.createElement(
684
- DefaultMenuButton,
685
- {
686
- label,
687
- hint: $track?.label ?? defaultText,
688
- disabled: options.disabled,
689
- Icon: Icons.Menu.Audio
690
- }
691
- ), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, /* @__PURE__ */ React.createElement(
692
- Root$1,
693
- {
694
- className: "vds-audio-radio-group vds-radio-group",
695
- value: options.selectedValue
696
- },
697
- options.map(({ label: label2, value, select }) => /* @__PURE__ */ React.createElement(
698
- Item,
699
- {
700
- className: "vds-audio-radio vds-radio",
701
- value,
702
- onSelect: select,
703
- key: value
704
- },
705
- /* @__PURE__ */ React.createElement(Icons.Menu.RadioCheck, { className: "vds-icon" }),
706
- /* @__PURE__ */ React.createElement("span", { className: "vds-radio-label" }, label2)
707
- ))
708
- )));
709
- }
710
- DefaultAudioTracksMenu.displayName = "DefaultAudioTracksMenu";
711
-
712
- function DefaultCaptionMenu({ slots }) {
713
- const { icons: Icons } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Captions"), offText = useDefaultLayoutWord("Off"), options = useCaptionOptions({ off: offText }), hint = options.selectedTrack?.label ?? offText;
714
- if (options.disabled) return null;
715
- return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-captions-menu vds-menu" }, /* @__PURE__ */ React.createElement(
716
- DefaultMenuButton,
717
- {
718
- label,
719
- hint,
720
- disabled: options.disabled,
721
- Icon: Icons.Menu.Captions
722
- }
723
- ), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "captionsMenuItemsStart", null), /* @__PURE__ */ React.createElement(
724
- Root$1,
725
- {
726
- className: "vds-captions-radio-group vds-radio-group",
727
- value: options.selectedValue
728
- },
729
- options.map(({ label: label2, value, select }) => /* @__PURE__ */ React.createElement(
730
- Item,
731
- {
732
- className: "vds-caption-radio vds-radio",
733
- value,
734
- onSelect: select,
735
- key: value
736
- },
737
- /* @__PURE__ */ React.createElement(Icons.Menu.RadioCheck, { className: "vds-icon" }),
738
- /* @__PURE__ */ React.createElement("span", { className: "vds-radio-label" }, label2)
739
- ))
740
- ), slot(slots, "captionsMenuItemsEnd", null)));
741
- }
742
- DefaultCaptionMenu.displayName = "DefaultCaptionMenu";
743
-
744
- function DefaultPlaybackMenu({ slots }) {
745
- const label = useDefaultLayoutWord("Playback"), { icons: Icons } = useDefaultLayoutContext();
746
- return /* @__PURE__ */ React.createElement(Root$3, { className: "vds-playback-menu vds-menu" }, /* @__PURE__ */ React.createElement(DefaultMenuButton, { label, Icon: Icons.Menu.Playback }), /* @__PURE__ */ React.createElement(Items, { className: "vds-menu-items" }, slot(slots, "playbackMenuItemsStart", null), /* @__PURE__ */ React.createElement(DefaultMenuSection, null, slot(slots, "playbackMenuLoop", /* @__PURE__ */ React.createElement(DefaultLoopMenuCheckbox, null))), /* @__PURE__ */ React.createElement(DefaultSpeedMenuSection, null), /* @__PURE__ */ React.createElement(DefaultQualityMenuSection, null), slot(slots, "playbackMenuItemsEnd", null)));
747
- }
748
- DefaultPlaybackMenu.displayName = "DefaultPlaybackMenu";
749
- function DefaultLoopMenuCheckbox() {
750
- const { remote } = useMediaContext(), label = useDefaultLayoutWord("Loop");
751
- function onChange(checked, trigger) {
752
- remote.userPrefersLoopChange(checked, trigger);
753
- }
754
- return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(DefaultMenuCheckbox, { label, storageKey: "vds-player::user-loop", onChange }));
755
- }
756
- DefaultLoopMenuCheckbox.displayName = "DefaultLoopMenuCheckbox";
757
- function DefaultAutoQualityMenuCheckbox() {
758
- const { remote, qualities } = useMediaContext(), $autoQuality = useMediaState("autoQuality"), label = useDefaultLayoutWord("Auto");
759
- function onChange(checked, trigger) {
760
- if (checked) {
761
- remote.requestAutoQuality(trigger);
762
- } else {
763
- remote.changeQuality(qualities.selectedIndex, trigger);
764
- }
765
- }
766
- return /* @__PURE__ */ React.createElement(DefaultMenuItem, { label }, /* @__PURE__ */ React.createElement(
767
- DefaultMenuCheckbox,
768
- {
769
- label,
770
- checked: $autoQuality,
771
- onChange,
772
- defaultChecked: $autoQuality
773
- }
774
- ));
775
- }
776
- DefaultAutoQualityMenuCheckbox.displayName = "DefaultAutoQualityMenuCheckbox";
777
- function DefaultQualityMenuSection() {
778
- const { hideQualityBitrate, icons: Icons } = useDefaultLayoutContext(), $canSetQuality = useMediaState("canSetQuality"), $qualities = useMediaState("qualities"), $quality = useMediaState("quality"), label = useDefaultLayoutWord("Quality"), autoText = useDefaultLayoutWord("Auto"), sortedQualities = React.useMemo(() => sortVideoQualities($qualities), [$qualities]);
779
- if (!$canSetQuality || $qualities.length <= 1) return null;
780
- const height = $quality?.height, bitrate = !hideQualityBitrate ? $quality?.bitrate : null, bitrateText = bitrate && bitrate > 0 ? `${(bitrate / 1e6).toFixed(2)} Mbps` : null, value = height ? `${height}p${bitrateText ? ` (${bitrateText})` : ""}` : autoText, isMin = sortedQualities[0] === $quality, isMax = sortedQualities.at(-1) === $quality;
781
- return /* @__PURE__ */ React.createElement(DefaultMenuSection, { label, value }, /* @__PURE__ */ React.createElement(
782
- DefaultMenuSliderItem,
783
- {
784
- UpIcon: Icons.Menu.QualityUp,
785
- DownIcon: Icons.Menu.QualityDown,
786
- isMin,
787
- isMax
788
- },
789
- /* @__PURE__ */ React.createElement(DefaultQualitySlider, null)
790
- ), /* @__PURE__ */ React.createElement(DefaultAutoQualityMenuCheckbox, null));
791
- }
792
- DefaultQualityMenuSection.displayName = "DefaultQualityMenuSection";
793
- function DefaultQualitySlider() {
794
- const label = useDefaultLayoutWord("Quality");
795
- return /* @__PURE__ */ React.createElement(Root$7, { className: "vds-quality-slider vds-slider", "aria-label": label }, /* @__PURE__ */ React.createElement(DefaultSliderParts, null), /* @__PURE__ */ React.createElement(DefaultSliderSteps, null));
796
- }
797
- DefaultQualitySlider.displayName = "DefaultQualitySlider";
798
- function DefaultSpeedMenuSection() {
799
- const { icons: Icons } = useDefaultLayoutContext(), $playbackRate = useMediaState("playbackRate"), $canSetPlaybackRate = useMediaState("canSetPlaybackRate"), label = useDefaultLayoutWord("Speed"), normalText = useDefaultLayoutWord("Normal"), min = useSpeedMin(), max = useSpeedMax(), value = $playbackRate === 1 ? normalText : $playbackRate + "x";
800
- if (!$canSetPlaybackRate) return null;
801
- return /* @__PURE__ */ React.createElement(DefaultMenuSection, { label, value }, /* @__PURE__ */ React.createElement(
802
- DefaultMenuSliderItem,
803
- {
804
- UpIcon: Icons.Menu.SpeedUp,
805
- DownIcon: Icons.Menu.SpeedDown,
806
- isMin: $playbackRate === min,
807
- isMax: $playbackRate === max
808
- },
809
- /* @__PURE__ */ React.createElement(DefaultSpeedSlider, null)
810
- ));
811
- }
812
- function useSpeedMin() {
813
- const { playbackRates } = useDefaultLayoutContext(), rates = playbackRates;
814
- return (isArray(rates) ? rates[0] : rates?.min) ?? 0;
815
- }
816
- function useSpeedMax() {
817
- const { playbackRates } = useDefaultLayoutContext(), rates = playbackRates;
818
- return (isArray(rates) ? rates[rates.length - 1] : rates?.max) ?? 2;
819
- }
820
- function useSpeedStep() {
821
- const { playbackRates } = useDefaultLayoutContext(), rates = playbackRates;
822
- return (isArray(rates) ? rates[1] - rates[0] : rates?.step) || 0.25;
823
- }
824
- function DefaultSpeedSlider() {
825
- const label = useDefaultLayoutWord("Speed"), min = useSpeedMin(), max = useSpeedMax(), step = useSpeedStep();
826
- return /* @__PURE__ */ React.createElement(
827
- Root$6,
828
- {
829
- className: "vds-speed-slider vds-slider",
830
- "aria-label": label,
831
- min,
832
- max,
833
- step,
834
- keyStep: step
835
- },
836
- /* @__PURE__ */ React.createElement(DefaultSliderParts, null),
837
- /* @__PURE__ */ React.createElement(DefaultSliderSteps, null)
838
- );
839
- }
840
- DefaultSpeedSlider.displayName = "DefaultSpeedSlider";
841
-
842
- function DefaultSettingsMenu({
843
- tooltip,
844
- placement,
845
- portalClass = "",
846
- slots
847
- }) {
848
- const {
849
- showMenuDelay,
850
- icons: Icons,
851
- isSmallLayout,
852
- menuContainer,
853
- menuGroup,
854
- noModal,
855
- colorScheme
856
- } = useDefaultLayoutContext(), settingsText = useDefaultLayoutWord("Settings"), $viewType = useMediaState("viewType"), $offset = !isSmallLayout && menuGroup === "bottom" && $viewType === "video" ? 26 : 0, colorSchemeClass = useColorSchemeClass(colorScheme), [isOpen, setIsOpen] = React.useState(false), dialogEl = useParentDialogEl();
857
- useScoped(updateFontCssVars);
858
- function onOpen() {
859
- flushSync(() => {
860
- setIsOpen(true);
861
- });
862
- }
863
- function onClose() {
864
- setIsOpen(false);
865
- }
866
- const Content = /* @__PURE__ */ React.createElement(
867
- Items,
868
- {
869
- className: "vds-settings-menu-items vds-menu-items",
870
- placement,
871
- offset: $offset
872
- },
873
- isOpen ? /* @__PURE__ */ React.createElement(React.Fragment, null, slot(slots, "settingsMenuItemsStart", null), slot(slots, "settingsMenuStartItems", null), /* @__PURE__ */ React.createElement(DefaultPlaybackMenu, { slots }), /* @__PURE__ */ React.createElement(DefaultAccessibilityMenu, { slots }), /* @__PURE__ */ React.createElement(DefaultAudioMenu, { slots }), /* @__PURE__ */ React.createElement(DefaultCaptionMenu, { slots }), slot(slots, "settingsMenuEndItems", null), slot(slots, "settingsMenuItemsEnd", null)) : null
874
- );
875
- return /* @__PURE__ */ React.createElement(
876
- Root$3,
877
- {
878
- className: "vds-settings-menu vds-menu",
879
- showDelay: showMenuDelay,
880
- onOpen,
881
- onClose
882
- },
883
- /* @__PURE__ */ React.createElement(DefaultTooltip, { content: settingsText, placement: tooltip }, /* @__PURE__ */ React.createElement(Button, { className: "vds-menu-button vds-button", "aria-label": settingsText }, /* @__PURE__ */ React.createElement(Icons.Menu.Settings, { className: "vds-icon vds-rotate-icon" }))),
884
- noModal || !isSmallLayout ? Content : /* @__PURE__ */ React.createElement(
885
- Portal,
886
- {
887
- className: portalClass + (colorSchemeClass ? ` ${colorSchemeClass}` : ""),
888
- container: menuContainer ?? dialogEl,
889
- disabled: "fullscreen",
890
- "data-sm": isSmallLayout ? "" : null,
891
- "data-lg": !isSmallLayout ? "" : null,
892
- "data-size": isSmallLayout ? "sm" : "lg",
893
- "data-view-type": $viewType
894
- },
895
- Content
896
- )
897
- );
898
- }
899
- DefaultSettingsMenu.displayName = "DefaultSettingsMenu";
900
-
901
- function DefaultVolumePopup({ tooltip, orientation, slots }) {
902
- const $pointer = useMediaState("pointer"), $muted = useMediaState("muted"), $canSetVolume = useMediaState("canSetVolume"), [rootEl, setRootEl] = React.useState(null), isRootActive = useActive(rootEl), muteButton = slot(slots, "muteButton", /* @__PURE__ */ React.createElement(DefaultMuteButton, { tooltip }));
903
- if (!$canSetVolume) {
904
- return muteButton;
905
- }
906
- return $pointer === "coarse" && !$muted ? null : /* @__PURE__ */ React.createElement("div", { className: "vds-volume", "data-active": isRootActive ? "" : null, ref: setRootEl }, muteButton, /* @__PURE__ */ React.createElement("div", { className: "vds-volume-popup" }, slot(slots, "volumeSlider", /* @__PURE__ */ React.createElement(DefaultVolumeSlider, { orientation }))));
907
- }
908
- DefaultVolumePopup.displayName = "DefaultVolumePopup";
909
- function DefaultVolumeSlider(props) {
910
- const label = useDefaultLayoutWord("Volume");
911
- return /* @__PURE__ */ React.createElement(Root$8, { className: "vds-volume-slider vds-slider", "aria-label": label, ...props }, /* @__PURE__ */ React.createElement(Track, { className: "vds-slider-track" }), /* @__PURE__ */ React.createElement(TrackFill, { className: "vds-slider-track-fill vds-slider-track" }), /* @__PURE__ */ React.createElement(Thumb, { className: "vds-slider-thumb" }), /* @__PURE__ */ React.createElement(Preview, { className: "vds-slider-preview", noClamp: true }, /* @__PURE__ */ React.createElement(Value, { className: "vds-slider-value" })));
912
- }
913
- DefaultVolumeSlider.displayName = "DefaultVolumeSlider";
914
- function DefaultTimeSlider() {
915
- const [instance, setInstance] = React.useState(null), [width, setWidth] = React.useState(0), $src = useMediaState("currentSrc"), { thumbnails, sliderChaptersMinWidth, disableTimeSlider, seekStep, noScrubGesture } = useDefaultLayoutContext(), label = useDefaultLayoutWord("Seek"), $RemotionSliderThumbnail = useSignal(RemotionSliderThumbnail);
916
- const onResize = React.useCallback(() => {
917
- const el = instance?.el;
918
- el && setWidth(el.clientWidth);
919
- }, [instance]);
920
- useResizeObserver(instance?.el, onResize);
921
- return /* @__PURE__ */ React.createElement(
922
- Root$9,
923
- {
924
- className: "vds-time-slider vds-slider",
925
- "aria-label": label,
926
- disabled: disableTimeSlider,
927
- noSwipeGesture: noScrubGesture,
928
- keyStep: seekStep,
929
- ref: setInstance
930
- },
931
- /* @__PURE__ */ React.createElement(
932
- Chapters,
933
- {
934
- className: "vds-slider-chapters",
935
- disabled: width < sliderChaptersMinWidth
936
- },
937
- (cues, forwardRef) => cues.map((cue) => /* @__PURE__ */ React.createElement("div", { className: "vds-slider-chapter", key: cue.startTime, ref: forwardRef }, /* @__PURE__ */ React.createElement(Track, { className: "vds-slider-track" }), /* @__PURE__ */ React.createElement(TrackFill, { className: "vds-slider-track-fill vds-slider-track" }), /* @__PURE__ */ React.createElement(Progress, { className: "vds-slider-progress vds-slider-track" })))
938
- ),
939
- /* @__PURE__ */ React.createElement(Thumb, { className: "vds-slider-thumb" }),
940
- /* @__PURE__ */ React.createElement(Preview, { className: "vds-slider-preview" }, thumbnails ? /* @__PURE__ */ React.createElement(
941
- Thumbnail.Root,
942
- {
943
- src: thumbnails,
944
- className: "vds-slider-thumbnail vds-thumbnail"
945
- },
946
- /* @__PURE__ */ React.createElement(Thumbnail.Img, null)
947
- ) : $RemotionSliderThumbnail && isRemotionSrc($src) ? /* @__PURE__ */ React.createElement($RemotionSliderThumbnail, { className: "vds-slider-thumbnail vds-thumbnail" }) : null, /* @__PURE__ */ React.createElement(ChapterTitle, { className: "vds-slider-chapter-title" }), /* @__PURE__ */ React.createElement(Value, { className: "vds-slider-value" }))
948
- );
949
- }
950
- DefaultTimeSlider.displayName = "DefaultTimeSlider";
951
-
952
- function DefaultTimeGroup({ slots }) {
953
- const $duration = useMediaState("duration");
954
- if (!$duration) return null;
955
- return /* @__PURE__ */ React.createElement("div", { className: "vds-time-group" }, slot(slots, "currentTime", /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "current" })), slot(slots, "timeDivider", /* @__PURE__ */ React.createElement("div", { className: "vds-time-divider" }, "/")), slot(slots, "endTime", /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "duration" })));
956
- }
957
- DefaultTimeGroup.displayName = "DefaultTimeGroup";
958
- function DefaultTimeInfo({ slots }) {
959
- const $live = useMediaState("live");
960
- return $live ? slot(slots, "liveButton", /* @__PURE__ */ React.createElement(DefaultLiveButton, null)) : /* @__PURE__ */ React.createElement(DefaultTimeGroup, { slots });
961
- }
962
- DefaultTimeInfo.displayName = "DefaultTimeInfo";
963
- function DefaultTimeInvert({ slots }) {
964
- const $live = useMediaState("live"), $duration = useMediaState("duration");
965
- return $live ? slot(slots, "liveButton", /* @__PURE__ */ React.createElement(DefaultLiveButton, null)) : slot(
966
- slots,
967
- "endTime",
968
- $duration ? /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "current", toggle: true, remainder: true }) : null
969
- );
970
- }
971
- DefaultTimeInvert.displayName = "DefaultTimeInvert";
972
-
973
- const MediaLayout$1 = createDefaultMediaLayout({
974
- type: "audio",
975
- smLayoutWhen({ width }) {
976
- return width < 576;
977
- },
978
- renderLayout: () => /* @__PURE__ */ React.createElement(AudioLayout, null)
979
- });
980
- function DefaultAudioLayout(props) {
981
- const [scrubbing, setScrubbing] = React.useState(false), $pointer = useMediaState("pointer");
982
- const onStartScrubbing = React.useCallback((event) => {
983
- const { target } = event, hasTimeSlider = !!(target instanceof HTMLElement && target.closest(".vds-time-slider"));
984
- if (!hasTimeSlider) return;
985
- event.nativeEvent.stopImmediatePropagation();
986
- setScrubbing(true);
987
- }, []);
988
- const onStopScrubbing = React.useCallback(() => {
989
- setScrubbing(false);
990
- }, []);
991
- React.useEffect(() => {
992
- if (scrubbing) return listenEvent(window, "pointerdown", onStopScrubbing);
993
- }, [scrubbing, onStopScrubbing]);
994
- return /* @__PURE__ */ React.createElement(
995
- MediaLayout$1,
996
- {
997
- ...props,
998
- "data-scrubbing": scrubbing ? "" : null,
999
- onPointerDown: scrubbing ? (e) => e.stopPropagation() : void 0,
1000
- onPointerDownCapture: $pointer === "coarse" && !scrubbing ? onStartScrubbing : void 0
1001
- }
1002
- );
1003
- }
1004
- DefaultAudioLayout.displayName = "DefaultAudioLayout";
1005
- function AudioLayout() {
1006
- const slots = useDefaultAudioLayoutSlots();
1007
- useLayoutName("audio");
1008
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DefaultAnnouncer, null), /* @__PURE__ */ React.createElement(DefaultCaptions, null), /* @__PURE__ */ React.createElement(Root$a, { className: "vds-controls" }, /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "seekBackwardButton", /* @__PURE__ */ React.createElement(DefaultSeekButton, { backward: true, tooltip: "top start" })), slot(slots, "playButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top center" })), slot(slots, "seekForwardButton", /* @__PURE__ */ React.createElement(DefaultSeekButton, { tooltip: "top center" })), /* @__PURE__ */ React.createElement(DefaultAudioTitle, null), slot(slots, "timeSlider", /* @__PURE__ */ React.createElement(DefaultTimeSlider, null)), /* @__PURE__ */ React.createElement(DefaultTimeInvert, { slots }), /* @__PURE__ */ React.createElement(DefaultVolumePopup, { orientation: "vertical", tooltip: "top", slots }), slot(slots, "captionButton", /* @__PURE__ */ React.createElement(DefaultCaptionButton, { tooltip: "top center" })), slot(slots, "downloadButton", /* @__PURE__ */ React.createElement(DefaultDownloadButton, null)), /* @__PURE__ */ React.createElement(DefaultAudioMenus, { slots }))));
1009
- }
1010
- AudioLayout.displayName = "AudioLayout";
1011
- function DefaultAudioMenus({ slots }) {
1012
- const { isSmallLayout, noModal } = useDefaultLayoutContext(), placement = noModal ? "top end" : !isSmallLayout ? "top end" : null;
1013
- return /* @__PURE__ */ React.createElement(React.Fragment, null, slot(
1014
- slots,
1015
- "chaptersMenu",
1016
- /* @__PURE__ */ React.createElement(DefaultChaptersMenu, { tooltip: "top", placement, portalClass: "vds-audio-layout" })
1017
- ), slot(
1018
- slots,
1019
- "settingsMenu",
1020
- /* @__PURE__ */ React.createElement(
1021
- DefaultSettingsMenu,
1022
- {
1023
- tooltip: "top end",
1024
- placement,
1025
- portalClass: "vds-audio-layout",
1026
- slots
1027
- }
1028
- )
1029
- ));
1030
- }
1031
- DefaultAudioMenus.displayName = "DefaultAudioMenus";
1032
- function DefaultAudioTitle() {
1033
- const [rootEl, setRootEl] = React.useState(null), media = useMediaContext(), { translations } = useDefaultLayoutContext(), [isTextOverflowing, setIsTextOverflowing] = React.useState(false);
1034
- const isContinued = createComputed(() => {
1035
- const { started, currentTime } = media.$state;
1036
- return started() || currentTime() > 0;
1037
- });
1038
- const $title = useSignal(
1039
- createComputed(() => {
1040
- const { title, ended } = media.$state;
1041
- if (!title()) return "";
1042
- const word = ended() ? "Replay" : isContinued() ? "Continue" : "Play";
1043
- return `${i18n(translations, word)}: ${title()}`;
1044
- })
1045
- );
1046
- const chapterTitle = useChapterTitle(), $isContinued = useSignal(isContinued), $chapterTitle = $isContinued ? chapterTitle : "", isTransitionActive = useTransitionActive(rootEl);
1047
- React.useEffect(() => {
1048
- if (isTransitionActive && document.activeElement === document.body) {
1049
- media.player.el?.focus({ preventScroll: true });
1050
- }
1051
- }, []);
1052
- const onResize = React.useCallback(() => {
1053
- const el = rootEl, isOverflowing = !!el && !isTransitionActive && el.clientWidth < el.children[0].clientWidth;
1054
- if (el) toggleClass(el, "vds-marquee", isOverflowing);
1055
- setIsTextOverflowing(isOverflowing);
1056
- }, [rootEl, isTransitionActive]);
1057
- useResizeObserver(rootEl, onResize);
1058
- return $title ? /* @__PURE__ */ React.createElement("span", { className: "vds-title", title: $title, ref: setRootEl }, /* @__PURE__ */ React.createElement(AudioTitle, { title: $title, chapterTitle: $chapterTitle }), isTextOverflowing && !isTransitionActive ? /* @__PURE__ */ React.createElement(AudioTitle, { title: $title, chapterTitle: $chapterTitle }) : null) : /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null);
1059
- }
1060
- DefaultAudioTitle.displayName = "DefaultAudioTitle";
1061
- function AudioTitle({ title, chapterTitle }) {
1062
- const slots = useDefaultAudioLayoutSlots();
1063
- return /* @__PURE__ */ React.createElement("span", { className: "vds-title-text" }, slot(slots, "title", title), slot(slots, "chapterTitle", /* @__PURE__ */ React.createElement("span", { className: "vds-chapter-title" }, chapterTitle)));
1064
- }
1065
- AudioTitle.displayName = "AudioTitle";
1066
-
1067
- const DefaultKeyboardDisplay = React.forwardRef(
1068
- ({ icons: Icons, ...props }, forwardRef) => {
1069
- const [visible, setVisible] = React.useState(false), [Icon, setIcon] = React.useState(null), [count, setCount] = React.useState(0), $lastKeyboardAction = useMediaState("lastKeyboardAction");
1070
- React.useEffect(() => {
1071
- setCount((n) => n + 1);
1072
- }, [$lastKeyboardAction]);
1073
- const actionDataAttr = React.useMemo(() => {
1074
- const action = $lastKeyboardAction?.action;
1075
- return action && visible ? camelToKebabCase(action) : null;
1076
- }, [visible, $lastKeyboardAction]);
1077
- const className = React.useMemo(
1078
- () => `vds-kb-action${!visible ? " hidden" : ""}${props.className ? ` ${props.className}` : ""}`,
1079
- [visible]
1080
- );
1081
- const $$text = createComputed(getText), $text = useSignal($$text);
1082
- createEffect(() => {
1083
- const Icon2 = getIcon(Icons);
1084
- setIcon(() => Icon2);
1085
- }, [Icons]);
1086
- React.useEffect(() => {
1087
- setVisible(!!$lastKeyboardAction);
1088
- const id = setTimeout(() => setVisible(false), 500);
1089
- return () => {
1090
- setVisible(false);
1091
- window.clearTimeout(id);
1092
- };
1093
- }, [$lastKeyboardAction]);
1094
- return Icon ? /* @__PURE__ */ React.createElement(
1095
- Primitive.div,
1096
- {
1097
- ...props,
1098
- className,
1099
- "data-action": actionDataAttr,
1100
- ref: forwardRef
1101
- },
1102
- /* @__PURE__ */ React.createElement("div", { className: "vds-kb-text-wrapper" }, /* @__PURE__ */ React.createElement("div", { className: "vds-kb-text" }, $text)),
1103
- /* @__PURE__ */ React.createElement("div", { className: "vds-kb-bezel", key: count }, /* @__PURE__ */ React.createElement("div", { className: "vds-kb-icon" }, /* @__PURE__ */ React.createElement(Icon, null)))
1104
- ) : null;
1105
- }
1106
- );
1107
- DefaultKeyboardDisplay.displayName = "DefaultKeyboardDisplay";
1108
- function getText() {
1109
- const { $state } = useContext(mediaContext), action = $state.lastKeyboardAction()?.action, audioGain = $state.audioGain() ?? 1;
1110
- switch (action) {
1111
- case "toggleMuted":
1112
- return $state.muted() ? "0%" : getVolumeText($state.volume(), audioGain);
1113
- case "volumeUp":
1114
- case "volumeDown":
1115
- return getVolumeText($state.volume(), audioGain);
1116
- default:
1117
- return "";
1118
- }
1119
- }
1120
- function getVolumeText(volume, gain) {
1121
- return `${Math.round(volume * gain * 100)}%`;
1122
- }
1123
- function getIcon(Icons) {
1124
- const { $state } = useContext(mediaContext), action = $state.lastKeyboardAction()?.action;
1125
- switch (action) {
1126
- case "togglePaused":
1127
- return !$state.paused() ? Icons.Play : Icons.Pause;
1128
- case "toggleMuted":
1129
- return $state.muted() || $state.volume() === 0 ? Icons.Mute : $state.volume() >= 0.5 ? Icons.VolumeUp : Icons.VolumeDown;
1130
- case "toggleFullscreen":
1131
- return $state.fullscreen() ? Icons.EnterFullscreen : Icons.ExitFullscreen;
1132
- case "togglePictureInPicture":
1133
- return $state.pictureInPicture() ? Icons.EnterPiP : Icons.ExitPiP;
1134
- case "toggleCaptions":
1135
- return $state.hasCaptions() ? $state.textTrack() ? Icons.CaptionsOn : Icons.CaptionsOff : null;
1136
- case "volumeUp":
1137
- return Icons.VolumeUp;
1138
- case "volumeDown":
1139
- return Icons.VolumeDown;
1140
- case "seekForward":
1141
- return Icons.SeekForward;
1142
- case "seekBackward":
1143
- return Icons.SeekBackward;
1144
- default:
1145
- return null;
1146
- }
1147
- }
1148
-
1149
- function DefaultTitle() {
1150
- const $started = useMediaState("started"), $title = useMediaState("title"), $hasChapters = useActiveTextTrack("chapters");
1151
- return $hasChapters && ($started || !$title) ? /* @__PURE__ */ React.createElement(ChapterTitle$1, { className: "vds-chapter-title" }) : /* @__PURE__ */ React.createElement(Title, { className: "vds-chapter-title" });
1152
- }
1153
- DefaultTitle.displayName = "DefaultTitle";
1154
-
1155
- const MediaLayout = createDefaultMediaLayout({
1156
- type: "video",
1157
- smLayoutWhen({ width, height }) {
1158
- return width < 576 || height < 380;
1159
- },
1160
- renderLayout(props) {
1161
- return /* @__PURE__ */ React.createElement(VideoLayout, { ...props });
1162
- }
1163
- });
1164
- function DefaultVideoLayout(props) {
1165
- return /* @__PURE__ */ React.createElement(MediaLayout, { ...props });
1166
- }
1167
- DefaultVideoLayout.displayName = "DefaultVideoLayout";
1168
- function VideoLayout({ streamType, isLoadLayout, isSmallLayout }) {
1169
- useLayoutName("video");
1170
- return isLoadLayout ? /* @__PURE__ */ React.createElement(DefaultVideoLoadLayout, null) : streamType === "unknown" ? /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null) : isSmallLayout ? /* @__PURE__ */ React.createElement(DefaultVideoSmallLayout, null) : /* @__PURE__ */ React.createElement(DefaultVideoLargeLayout, null);
1171
- }
1172
- VideoLayout.displayName = "VideoLayout";
1173
- function DefaultVideoLargeLayout() {
1174
- const { menuGroup, episodes, episodesTitle, isSmallLayout } = useDefaultLayoutContext(), baseSlots = useDefaultVideoLayoutSlots(), slots = { ...baseSlots, ...baseSlots?.largeLayout }, $fullscreen = useMediaState("fullscreen"), [episodesOpen, setEpisodesOpen] = React.useState(false), list = episodes ?? [];
1175
- React.useEffect(() => {
1176
- if (!$fullscreen) setEpisodesOpen(false);
1177
- }, [$fullscreen]);
1178
- const canOpenEpisodes = $fullscreen && list.length > 0;
1179
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DefaultAnnouncer, null), /* @__PURE__ */ React.createElement(DefaultVideoGestures, null), /* @__PURE__ */ React.createElement(DefaultVideoKeyboardDisplay, null), slot(slots, "bufferingIndicator", /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null)), slot(slots, "captions", /* @__PURE__ */ React.createElement(DefaultCaptions, null)), /* @__PURE__ */ React.createElement(Root$a, { className: "vds-controls" }, /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "topControlsGroupStart", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "topControlsGroupCenter", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "topControlsGroupEnd", null), menuGroup === "top" && /* @__PURE__ */ React.createElement(DefaultVideoMenus, { slots })), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "centerControlsGroupStart", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "centerControlsGroupCenter", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "centerControlsGroupEnd", null)), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "timeSlider", /* @__PURE__ */ React.createElement(DefaultTimeSlider, null))), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "playButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top start" })), /* @__PURE__ */ React.createElement(DefaultSeekButton, { backward: true, tooltip: "top" }), /* @__PURE__ */ React.createElement(DefaultSeekButton, { tooltip: "top" }), /* @__PURE__ */ React.createElement(DefaultVolumePopup, { orientation: "horizontal", tooltip: "top", slots }), /* @__PURE__ */ React.createElement(DefaultTimeInfo, { slots }), slot(slots, "chapterTitle", /* @__PURE__ */ React.createElement(DefaultTitle, null)), canOpenEpisodes ? /* @__PURE__ */ React.createElement(DefaultEpisodeButton, { tooltip: "top", onPress: () => setEpisodesOpen((open) => !open) }) : null, slot(slots, "captionButton", /* @__PURE__ */ React.createElement(DefaultCaptionButton, { tooltip: "top" })), menuGroup === "bottom" && /* @__PURE__ */ React.createElement(DefaultVideoMenus, { slots }), slot(slots, "airPlayButton", /* @__PURE__ */ React.createElement(DefaultAirPlayButton, { tooltip: "top" })), slot(slots, "googleCastButton", /* @__PURE__ */ React.createElement(DefaultGoogleCastButton, { tooltip: "top" })), slot(slots, "downloadButton", /* @__PURE__ */ React.createElement(DefaultDownloadButton, null)), slot(slots, "pipButton", /* @__PURE__ */ React.createElement(DefaultPIPButton, { tooltip: "top" })), slot(slots, "fullscreenButton", /* @__PURE__ */ React.createElement(DefaultFullscreenButton, { tooltip: "top end" })))), /* @__PURE__ */ React.createElement(
1180
- DefaultEpisodesSidebar,
1181
- {
1182
- open: episodesOpen,
1183
- onClose: () => setEpisodesOpen(false),
1184
- episodes: list,
1185
- episodesTitle: episodesTitle ?? "Episodes"
1186
- }
1187
- ));
1188
- }
1189
- DefaultVideoLargeLayout.displayName = "DefaultVideoLargeLayout";
1190
- function DefaultVideoSmallLayout() {
1191
- const { episodes, episodesTitle, isSmallLayout } = useDefaultLayoutContext(), baseSlots = useDefaultVideoLayoutSlots(), slots = { ...baseSlots, ...baseSlots?.smallLayout }, $fullscreen = useMediaState("fullscreen"), [episodesOpen, setEpisodesOpen] = React.useState(false), list = episodes ?? [];
1192
- React.useEffect(() => {
1193
- if (!$fullscreen) setEpisodesOpen(false);
1194
- }, [$fullscreen]);
1195
- const canOpenEpisodes = $fullscreen && list.length > 0;
1196
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DefaultAnnouncer, null), /* @__PURE__ */ React.createElement(DefaultVideoGestures, null), /* @__PURE__ */ React.createElement(DefaultVideoKeyboardDisplay, null), slot(slots, "bufferingIndicator", /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null)), slot(slots, "captions", /* @__PURE__ */ React.createElement(DefaultCaptions, null)), /* @__PURE__ */ React.createElement(Root$a, { className: "vds-controls" }, /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "topControlsGroupStart", null), slot(slots, "airPlayButton", /* @__PURE__ */ React.createElement(DefaultAirPlayButton, { tooltip: "top start" })), slot(slots, "googleCastButton", /* @__PURE__ */ React.createElement(DefaultGoogleCastButton, { tooltip: "top start" })), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "topControlsGroupCenter", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "captionButton", /* @__PURE__ */ React.createElement(DefaultCaptionButton, { tooltip: "bottom" })), slot(slots, "downloadButton", /* @__PURE__ */ React.createElement(DefaultDownloadButton, null)), /* @__PURE__ */ React.createElement(DefaultVideoMenus, { slots }), /* @__PURE__ */ React.createElement(DefaultVolumePopup, { orientation: "vertical", tooltip: "bottom end", slots }), slot(slots, "topControlsGroupEnd", null)), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "centerControlsGroupStart", null), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(DefaultSeekButton, { backward: true, tooltip: "top" }), slot(slots, "centerControlsGroupCenter", null), slot(slots, "playButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top" })), /* @__PURE__ */ React.createElement(DefaultSeekButton, { tooltip: "top" }), canOpenEpisodes ? /* @__PURE__ */ React.createElement(DefaultEpisodeButton, { tooltip: "top", onPress: () => setEpisodesOpen((open) => !open) }) : null, /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), slot(slots, "centerControlsGroupEnd", null)), /* @__PURE__ */ React.createElement(DefaultControlsSpacer, null), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, /* @__PURE__ */ React.createElement(DefaultTimeInfo, { slots }), slot(slots, "chapterTitle", /* @__PURE__ */ React.createElement(DefaultTitle, null)), slot(slots, "fullscreenButton", /* @__PURE__ */ React.createElement(DefaultFullscreenButton, { tooltip: "top end" }))), /* @__PURE__ */ React.createElement(Group, { className: "vds-controls-group" }, slot(slots, "timeSlider", /* @__PURE__ */ React.createElement(DefaultTimeSlider, null)))), slot(slots, "startDuration", /* @__PURE__ */ React.createElement(DefaultVideoStartDuration, null)), /* @__PURE__ */ React.createElement(
1197
- DefaultEpisodesSidebar,
1198
- {
1199
- open: episodesOpen,
1200
- onClose: () => setEpisodesOpen(false),
1201
- episodes: list,
1202
- episodesTitle: episodesTitle ?? "Episodes"
1203
- }
1204
- ));
1205
- }
1206
- DefaultVideoSmallLayout.displayName = "DefaultVideoSmallLayout";
1207
- function DefaultVideoStartDuration() {
1208
- const $duration = useMediaState("duration");
1209
- if ($duration === 0) return null;
1210
- return /* @__PURE__ */ React.createElement("div", { className: "vds-start-duration" }, /* @__PURE__ */ React.createElement(Time, { className: "vds-time", type: "duration" }));
1211
- }
1212
- DefaultVideoStartDuration.displayName = "DefaultVideoStartDuration";
1213
- function DefaultVideoGestures() {
1214
- const { noGestures } = useDefaultLayoutContext();
1215
- if (noGestures) return null;
1216
- return /* @__PURE__ */ React.createElement("div", { className: "vds-gestures" }, /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "pointerup", action: "toggle:paused" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "pointerup", action: "toggle:controls" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "dblpointerup", action: "toggle:fullscreen" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "dblpointerup", action: "seek:-10" }), /* @__PURE__ */ React.createElement(Gesture, { className: "vds-gesture", event: "dblpointerup", action: "seek:10" }));
1217
- }
1218
- DefaultVideoGestures.displayName = "DefaultVideoGestures";
1219
- function DefaultBufferingIndicator() {
1220
- return /* @__PURE__ */ React.createElement("div", { className: "vds-buffering-indicator" }, /* @__PURE__ */ React.createElement(Root$b, { className: "vds-buffering-spinner" }, /* @__PURE__ */ React.createElement(Track$1, { className: "vds-buffering-track" }), /* @__PURE__ */ React.createElement(TrackFill$1, { className: "vds-buffering-track-fill" })));
1221
- }
1222
- DefaultBufferingIndicator.displayName = "DefaultBufferingIndicator";
1223
- function DefaultVideoMenus({ slots }) {
1224
- const { isSmallLayout, noModal, menuGroup } = useDefaultLayoutContext(), side = menuGroup === "top" || isSmallLayout ? "bottom" : "top", tooltip = `${side} end`, placement = noModal ? `${side} end` : !isSmallLayout ? `${side} end` : null;
1225
- return /* @__PURE__ */ React.createElement(React.Fragment, null, slot(
1226
- slots,
1227
- "chaptersMenu",
1228
- /* @__PURE__ */ React.createElement(
1229
- DefaultChaptersMenu,
1230
- {
1231
- tooltip,
1232
- placement,
1233
- portalClass: "vds-video-layout"
1234
- }
1235
- )
1236
- ), slot(
1237
- slots,
1238
- "settingsMenu",
1239
- /* @__PURE__ */ React.createElement(
1240
- DefaultSettingsMenu,
1241
- {
1242
- tooltip,
1243
- placement,
1244
- portalClass: "vds-video-layout",
1245
- slots
1246
- }
1247
- )
1248
- ));
1249
- }
1250
- DefaultVideoMenus.displayName = "DefaultVideoMenus";
1251
- function formatMinutesLeftLabel(secondsLeft) {
1252
- if (secondsLeft <= 0) return null;
1253
- if (secondsLeft < 60) return "<1m left";
1254
- const m = Math.floor(secondsLeft / 60);
1255
- return `${m}m left`;
1256
- }
1257
- function DefaultEpisodesSidebar({
1258
- open,
1259
- onClose,
1260
- episodes,
1261
- episodesTitle
1262
- }) {
1263
- const $fullscreen = useMediaState("fullscreen"), currentTime = useMediaState("currentTime"), duration = useMediaState("duration"), listRef = React.useRef(null), wasEpisodesOpenRef = React.useRef(false);
1264
- React.useLayoutEffect(() => {
1265
- const justOpened = open && !wasEpisodesOpenRef.current;
1266
- wasEpisodesOpenRef.current = open;
1267
- if (!justOpened || !$fullscreen) return;
1268
- const root = listRef.current;
1269
- if (!root) return;
1270
- requestAnimationFrame(() => {
1271
- root.querySelector('[data-active="true"]')?.scrollIntoView({
1272
- block: "nearest",
1273
- behavior: "smooth"
1274
- });
1275
- });
1276
- }, [open, $fullscreen]);
1277
- if (!$fullscreen || episodes.length === 0) return null;
1278
- return /* @__PURE__ */ React.createElement(
1279
- "div",
1280
- {
1281
- className: "vds-episodes-backdrop",
1282
- "data-open": open ? "true" : "false",
1283
- onPointerUp: (event) => {
1284
- if (event.target === event.currentTarget) onClose();
1285
- }
1286
- },
1287
- /* @__PURE__ */ React.createElement(
1288
- "aside",
1289
- {
1290
- className: "vds-episodes-panel",
1291
- "data-open": open ? "true" : "false",
1292
- onKeyDown: (event) => {
1293
- if (event.key === "Escape") onClose();
1294
- }
1295
- },
1296
- /* @__PURE__ */ React.createElement("header", { className: "vds-episodes-panel-header" }, /* @__PURE__ */ React.createElement("h3", { className: "vds-episodes-panel-title" }, episodesTitle), /* @__PURE__ */ React.createElement(
1297
- "button",
1298
- {
1299
- type: "button",
1300
- className: "vds-episodes-close-btn",
1301
- "aria-label": "Close episodes",
1302
- onPointerUp: (event) => {
1303
- event.stopPropagation();
1304
- onClose();
1305
- }
1306
- },
1307
- /* @__PURE__ */ React.createElement("span", { "aria-hidden": "true" }, "\u2715")
1308
- )),
1309
- /* @__PURE__ */ React.createElement("div", { ref: listRef, className: "vds-episodes-list", role: "list" }, episodes.map((episode, index) => {
1310
- const episodeName = episode.episodeTitle || `Episode ${episode.episodeNumber ?? index + 1}`;
1311
- const seasonEpLabel = episode.seasonNumber != null && episode.episodeNumber != null ? `S${String(episode.seasonNumber).padStart(2, "0")} \xB7 E${String(episode.episodeNumber).padStart(2, "0")}` : episodeName;
1312
- const isActive = !!episode.isActive;
1313
- const onEpisodeSelect = (event) => {
1314
- event.stopPropagation();
1315
- if (isActive) return;
1316
- event.currentTarget.dispatchEvent(
1317
- new CustomEvent("vds-episode-select", {
1318
- bubbles: true,
1319
- composed: true,
1320
- detail: { episode, index }
1321
- })
1322
- );
1323
- onClose();
1324
- };
1325
- let runtimeText = null;
1326
- if (isActive && duration > 0) {
1327
- const secsLeft = Math.max(0, duration - currentTime);
1328
- runtimeText = formatMinutesLeftLabel(secsLeft);
1329
- } else if (episode.timeLeft != null && episode.timeLeft > 0) {
1330
- runtimeText = `${episode.timeLeft}m left`;
1331
- } else if (Number.isFinite(episode.runtime) && (episode.runtime ?? 0) > 0) {
1332
- runtimeText = `${episode.runtime}m`;
1333
- }
1334
- let progressPct = 0;
1335
- if (isActive && duration > 0) {
1336
- progressPct = Math.min(100, currentTime / duration * 100);
1337
- } else if (episode.progressPercent != null && episode.progressPercent > 0) {
1338
- progressPct = Math.min(100, episode.progressPercent);
1339
- }
1340
- const showSubtitle = !!episode.episodeTitle && episode.episodeTitle.trim() !== "" && episode.episodeTitle !== episode.title;
1341
- return /* @__PURE__ */ React.createElement(
1342
- "article",
1343
- {
1344
- key: `${episode.episodeNumber ?? index}-${episode.title ?? ""}`,
1345
- className: "vds-episode-item",
1346
- "data-active": isActive ? "true" : "false",
1347
- "aria-current": isActive ? "true" : void 0,
1348
- role: "button",
1349
- tabIndex: 0,
1350
- "aria-label": episode.title || episodeName,
1351
- onPointerUp: onEpisodeSelect,
1352
- onKeyDown: (event) => {
1353
- if (event.key === "Enter" || event.key === " ") onEpisodeSelect(event);
1354
- }
1355
- },
1356
- /* @__PURE__ */ React.createElement("div", { className: "vds-episode-thumb-wrap" }, episode.thumbnail ? /* @__PURE__ */ React.createElement(
1357
- "img",
1358
- {
1359
- className: "vds-episode-thumb",
1360
- src: episode.thumbnail,
1361
- alt: episode.title || episodeName,
1362
- loading: "lazy",
1363
- decoding: "async"
1364
- }
1365
- ) : /* @__PURE__ */ React.createElement("div", { className: "vds-episode-thumb vds-episode-thumb-placeholder" }), progressPct > 0 ? /* @__PURE__ */ React.createElement("div", { className: "vds-episode-progress-track", "aria-hidden": "true" }, /* @__PURE__ */ React.createElement("div", { className: "vds-episode-progress-fill", style: { width: `${progressPct}%` } })) : null),
1366
- /* @__PURE__ */ React.createElement("div", { className: "vds-episode-body" }, /* @__PURE__ */ React.createElement("div", { className: "vds-episode-meta-row" }, /* @__PURE__ */ React.createElement("div", { className: "vds-episode-meta-primary" }, isActive ? /* @__PURE__ */ React.createElement("span", { className: "vds-episode-now-chip" }, "Playing") : null, /* @__PURE__ */ React.createElement("span", { className: "vds-episode-label" }, seasonEpLabel)), runtimeText ? /* @__PURE__ */ React.createElement("span", { className: "vds-episode-runtime" }, runtimeText) : null), /* @__PURE__ */ React.createElement("h4", { className: "vds-episode-title", title: episode.title || "" }, episode.title || "-"), showSubtitle ? /* @__PURE__ */ React.createElement("p", { className: "vds-episode-subtitle", title: episode.episodeTitle }, episode.episodeTitle) : null, episode.overview ? /* @__PURE__ */ React.createElement("p", { className: "vds-episode-desc", title: episode.overview }, episode.overview) : null)
1367
- );
1368
- }))
1369
- )
1370
- );
1371
- }
1372
- function DefaultVideoLoadLayout() {
1373
- const { isSmallLayout } = useDefaultLayoutContext(), baseSlots = useDefaultVideoLayoutSlots(), slots = { ...baseSlots, ...baseSlots?.[isSmallLayout ? "smallLayout" : "largeLayout"] };
1374
- return /* @__PURE__ */ React.createElement("div", { className: "vds-load-container" }, slot(slots, "bufferingIndicator", /* @__PURE__ */ React.createElement(DefaultBufferingIndicator, null)), slot(slots, "loadButton", /* @__PURE__ */ React.createElement(DefaultPlayButton, { tooltip: "top" })));
1375
- }
1376
- DefaultVideoLoadLayout.displayName = "DefaultVideoLoadLayout";
1377
- function DefaultVideoKeyboardDisplay() {
1378
- const { noKeyboardAnimations, icons, userPrefersKeyboardAnimations } = useDefaultLayoutContext(), $userPrefersKeyboardAnimations = useSignal(userPrefersKeyboardAnimations), disabled = noKeyboardAnimations || !$userPrefersKeyboardAnimations;
1379
- if (disabled || !icons.KeyboardDisplay) return null;
1380
- return /* @__PURE__ */ React.createElement(DefaultKeyboardDisplay, { icons: icons.KeyboardDisplay });
1381
- }
1382
- DefaultVideoKeyboardDisplay.displayName = "DefaultVideoKeyboardDisplay";
1383
-
1384
- export { DefaultAudioLayout, DefaultBufferingIndicator, DefaultKeyboardDisplay, DefaultLayoutContext, DefaultMenuButton, DefaultMenuCheckbox, DefaultMenuItem, DefaultMenuRadioGroup, DefaultMenuSection, DefaultMenuSliderItem, DefaultSliderParts, DefaultSliderSteps, DefaultTooltip, DefaultVideoGestures, DefaultVideoLargeLayout, DefaultVideoLayout, DefaultVideoSmallLayout, createRadioOptions, i18n, useDefaultLayoutContext, useDefaultLayoutWord };