@videojs/react 10.0.0-alpha.7 → 10.0.0-alpha.9

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 (225) hide show
  1. package/dist/default/index.js +11 -7
  2. package/dist/default/media/hls-video/index.js +4 -3
  3. package/dist/default/media/hls-video/index.js.map +1 -1
  4. package/dist/default/player/create-player.js +3 -2
  5. package/dist/default/player/create-player.js.map +1 -1
  6. package/dist/default/presets/video/error-dialog.js +51 -0
  7. package/dist/default/presets/video/error-dialog.js.map +1 -0
  8. package/dist/default/presets/video/minimal-skin.css +18 -26
  9. package/dist/default/presets/video/minimal-skin.js +11 -30
  10. package/dist/default/presets/video/minimal-skin.js.map +1 -1
  11. package/dist/default/presets/video/minimal-skin.tailwind.js +10 -29
  12. package/dist/default/presets/video/minimal-skin.tailwind.js.map +1 -1
  13. package/dist/default/presets/video/skin.css +18 -25
  14. package/dist/default/presets/video/skin.js +11 -30
  15. package/dist/default/presets/video/skin.js.map +1 -1
  16. package/dist/default/presets/video/skin.tailwind.js +11 -30
  17. package/dist/default/presets/video/skin.tailwind.js.map +1 -1
  18. package/dist/default/skins/dist/default/video/default.tailwind.js +3 -3
  19. package/dist/default/skins/dist/default/video/default.tailwind.js.map +1 -1
  20. package/dist/default/skins/dist/default/video/minimal.tailwind.js +3 -3
  21. package/dist/default/skins/dist/default/video/minimal.tailwind.js.map +1 -1
  22. package/dist/default/ui/alert-dialog/alert-dialog-close.js +31 -0
  23. package/dist/default/ui/alert-dialog/alert-dialog-close.js.map +1 -0
  24. package/dist/default/ui/alert-dialog/alert-dialog-description.js +16 -0
  25. package/dist/default/ui/alert-dialog/alert-dialog-description.js.map +1 -0
  26. package/dist/default/ui/alert-dialog/alert-dialog-popup.js +32 -0
  27. package/dist/default/ui/alert-dialog/alert-dialog-popup.js.map +1 -0
  28. package/dist/default/ui/alert-dialog/alert-dialog-root.js +59 -0
  29. package/dist/default/ui/alert-dialog/alert-dialog-root.js.map +1 -0
  30. package/dist/default/ui/alert-dialog/alert-dialog-title.js +16 -0
  31. package/dist/default/ui/alert-dialog/alert-dialog-title.js.map +1 -0
  32. package/dist/default/ui/alert-dialog/context.js +16 -0
  33. package/dist/default/ui/alert-dialog/context.js.map +1 -0
  34. package/dist/default/ui/alert-dialog/index.js +4 -0
  35. package/dist/default/ui/alert-dialog/index.parts.js +19 -0
  36. package/dist/default/ui/alert-dialog/index.parts.js.map +1 -0
  37. package/dist/default/ui/captions-button/captions-button.js +10 -27
  38. package/dist/default/ui/captions-button/captions-button.js.map +1 -1
  39. package/dist/default/ui/create-context-part.js +7 -2
  40. package/dist/default/ui/create-context-part.js.map +1 -1
  41. package/dist/default/ui/hooks/use-slider.js +6 -17
  42. package/dist/default/ui/hooks/use-slider.js.map +1 -1
  43. package/dist/default/ui/popover/popover-arrow.js +1 -1
  44. package/dist/default/ui/popover/popover-popup.js +4 -2
  45. package/dist/default/ui/popover/popover-popup.js.map +1 -1
  46. package/dist/default/ui/popover/popover-root.js +3 -2
  47. package/dist/default/ui/popover/popover-root.js.map +1 -1
  48. package/dist/default/ui/popover/popover-trigger.js +4 -5
  49. package/dist/default/ui/popover/popover-trigger.js.map +1 -1
  50. package/dist/default/ui/slider/index.parts.js +4 -0
  51. package/dist/default/ui/slider/index.parts.js.map +1 -1
  52. package/dist/default/ui/slider/slider-preview.js +40 -0
  53. package/dist/default/ui/slider/slider-preview.js.map +1 -0
  54. package/dist/default/ui/slider/slider-thumbnail.js +20 -0
  55. package/dist/default/ui/slider/slider-thumbnail.js.map +1 -0
  56. package/dist/default/ui/thumbnail/thumbnail.js +3 -5
  57. package/dist/default/ui/thumbnail/thumbnail.js.map +1 -1
  58. package/dist/default/ui/time-slider/index.parts.js +2 -0
  59. package/dist/default/ui/time-slider/index.parts.js.map +1 -1
  60. package/dist/default/ui/tooltip/context.js +16 -0
  61. package/dist/default/ui/tooltip/context.js.map +1 -0
  62. package/dist/default/ui/tooltip/group-context.js +15 -0
  63. package/dist/default/ui/tooltip/group-context.js.map +1 -0
  64. package/dist/default/ui/tooltip/index.js +4 -0
  65. package/dist/default/ui/tooltip/index.parts.js +19 -0
  66. package/dist/default/ui/tooltip/index.parts.js.map +1 -0
  67. package/dist/default/ui/tooltip/tooltip-arrow.js +17 -0
  68. package/dist/default/ui/tooltip/tooltip-arrow.js.map +1 -0
  69. package/dist/default/ui/tooltip/tooltip-popup.js +97 -0
  70. package/dist/default/ui/tooltip/tooltip-popup.js.map +1 -0
  71. package/dist/default/ui/tooltip/tooltip-provider.js +28 -0
  72. package/dist/default/ui/tooltip/tooltip-provider.js.map +1 -0
  73. package/dist/default/ui/tooltip/tooltip-root.js +71 -0
  74. package/dist/default/ui/tooltip/tooltip-root.js.map +1 -0
  75. package/dist/default/ui/tooltip/tooltip-trigger.js +42 -0
  76. package/dist/default/ui/tooltip/tooltip-trigger.js.map +1 -0
  77. package/dist/default/ui/volume-slider/index.parts.js +2 -0
  78. package/dist/default/ui/volume-slider/index.parts.js.map +1 -1
  79. package/dist/default/ui/volume-slider/volume-slider-root.js +4 -4
  80. package/dist/default/ui/volume-slider/volume-slider-root.js.map +1 -1
  81. package/dist/default/utils/use-destroy.js +33 -0
  82. package/dist/default/utils/use-destroy.js.map +1 -0
  83. package/dist/dev/index.d.ts +15 -8
  84. package/dist/dev/index.js +11 -7
  85. package/dist/dev/media/hls-video/index.d.ts.map +1 -1
  86. package/dist/dev/media/hls-video/index.js +4 -3
  87. package/dist/dev/media/hls-video/index.js.map +1 -1
  88. package/dist/dev/player/create-player.d.ts.map +1 -1
  89. package/dist/dev/player/create-player.js +3 -2
  90. package/dist/dev/player/create-player.js.map +1 -1
  91. package/dist/dev/presets/video/error-dialog.js +51 -0
  92. package/dist/dev/presets/video/error-dialog.js.map +1 -0
  93. package/dist/dev/presets/video/minimal-skin.css +18 -26
  94. package/dist/dev/presets/video/minimal-skin.d.ts.map +1 -1
  95. package/dist/dev/presets/video/minimal-skin.js +11 -30
  96. package/dist/dev/presets/video/minimal-skin.js.map +1 -1
  97. package/dist/dev/presets/video/minimal-skin.tailwind.d.ts.map +1 -1
  98. package/dist/dev/presets/video/minimal-skin.tailwind.js +10 -29
  99. package/dist/dev/presets/video/minimal-skin.tailwind.js.map +1 -1
  100. package/dist/dev/presets/video/skin.css +18 -25
  101. package/dist/dev/presets/video/skin.d.ts.map +1 -1
  102. package/dist/dev/presets/video/skin.js +11 -30
  103. package/dist/dev/presets/video/skin.js.map +1 -1
  104. package/dist/dev/presets/video/skin.tailwind.d.ts.map +1 -1
  105. package/dist/dev/presets/video/skin.tailwind.js +11 -30
  106. package/dist/dev/presets/video/skin.tailwind.js.map +1 -1
  107. package/dist/dev/skins/dist/default/video/default.tailwind.js +3 -3
  108. package/dist/dev/skins/dist/default/video/default.tailwind.js.map +1 -1
  109. package/dist/dev/skins/dist/default/video/minimal.tailwind.js +3 -3
  110. package/dist/dev/skins/dist/default/video/minimal.tailwind.js.map +1 -1
  111. package/dist/dev/ui/alert-dialog/alert-dialog-close.d.ts +14 -0
  112. package/dist/dev/ui/alert-dialog/alert-dialog-close.d.ts.map +1 -0
  113. package/dist/dev/ui/alert-dialog/alert-dialog-close.js +31 -0
  114. package/dist/dev/ui/alert-dialog/alert-dialog-close.js.map +1 -0
  115. package/dist/dev/ui/alert-dialog/alert-dialog-description.d.ts +14 -0
  116. package/dist/dev/ui/alert-dialog/alert-dialog-description.d.ts.map +1 -0
  117. package/dist/dev/ui/alert-dialog/alert-dialog-description.js +16 -0
  118. package/dist/dev/ui/alert-dialog/alert-dialog-description.js.map +1 -0
  119. package/dist/dev/ui/alert-dialog/alert-dialog-popup.d.ts +14 -0
  120. package/dist/dev/ui/alert-dialog/alert-dialog-popup.d.ts.map +1 -0
  121. package/dist/dev/ui/alert-dialog/alert-dialog-popup.js +32 -0
  122. package/dist/dev/ui/alert-dialog/alert-dialog-popup.js.map +1 -0
  123. package/dist/dev/ui/alert-dialog/alert-dialog-root.d.ts +24 -0
  124. package/dist/dev/ui/alert-dialog/alert-dialog-root.d.ts.map +1 -0
  125. package/dist/dev/ui/alert-dialog/alert-dialog-root.js +59 -0
  126. package/dist/dev/ui/alert-dialog/alert-dialog-root.js.map +1 -0
  127. package/dist/dev/ui/alert-dialog/alert-dialog-title.d.ts +14 -0
  128. package/dist/dev/ui/alert-dialog/alert-dialog-title.d.ts.map +1 -0
  129. package/dist/dev/ui/alert-dialog/alert-dialog-title.js +16 -0
  130. package/dist/dev/ui/alert-dialog/alert-dialog-title.js.map +1 -0
  131. package/dist/dev/ui/alert-dialog/context.d.ts +15 -0
  132. package/dist/dev/ui/alert-dialog/context.d.ts.map +1 -0
  133. package/dist/dev/ui/alert-dialog/context.js +16 -0
  134. package/dist/dev/ui/alert-dialog/context.js.map +1 -0
  135. package/dist/dev/ui/alert-dialog/index.d.ts +3 -0
  136. package/dist/dev/ui/alert-dialog/index.js +4 -0
  137. package/dist/dev/ui/alert-dialog/index.parts.d.ts +13 -0
  138. package/dist/dev/ui/alert-dialog/index.parts.d.ts.map +1 -0
  139. package/dist/dev/ui/alert-dialog/index.parts.js +19 -0
  140. package/dist/dev/ui/alert-dialog/index.parts.js.map +1 -0
  141. package/dist/dev/ui/captions-button/captions-button.d.ts +6 -27
  142. package/dist/dev/ui/captions-button/captions-button.d.ts.map +1 -1
  143. package/dist/dev/ui/captions-button/captions-button.js +10 -27
  144. package/dist/dev/ui/captions-button/captions-button.js.map +1 -1
  145. package/dist/dev/ui/captions-button/index.d.ts +2 -2
  146. package/dist/dev/ui/create-context-part.js +7 -2
  147. package/dist/dev/ui/create-context-part.js.map +1 -1
  148. package/dist/dev/ui/hooks/use-slider.d.ts.map +1 -1
  149. package/dist/dev/ui/hooks/use-slider.js +6 -17
  150. package/dist/dev/ui/hooks/use-slider.js.map +1 -1
  151. package/dist/dev/ui/popover/popover-arrow.js +1 -1
  152. package/dist/dev/ui/popover/popover-popup.d.ts.map +1 -1
  153. package/dist/dev/ui/popover/popover-popup.js +4 -2
  154. package/dist/dev/ui/popover/popover-popup.js.map +1 -1
  155. package/dist/dev/ui/popover/popover-root.d.ts.map +1 -1
  156. package/dist/dev/ui/popover/popover-root.js +3 -2
  157. package/dist/dev/ui/popover/popover-root.js.map +1 -1
  158. package/dist/dev/ui/popover/popover-trigger.js +4 -5
  159. package/dist/dev/ui/popover/popover-trigger.js.map +1 -1
  160. package/dist/dev/ui/slider/index.parts.d.ts +3 -1
  161. package/dist/dev/ui/slider/index.parts.js +4 -0
  162. package/dist/dev/ui/slider/index.parts.js.map +1 -1
  163. package/dist/dev/ui/slider/slider-preview.d.ts +18 -0
  164. package/dist/dev/ui/slider/slider-preview.d.ts.map +1 -0
  165. package/dist/dev/ui/slider/slider-preview.js +40 -0
  166. package/dist/dev/ui/slider/slider-preview.js.map +1 -0
  167. package/dist/dev/ui/slider/slider-thumbnail.d.ts +14 -0
  168. package/dist/dev/ui/slider/slider-thumbnail.d.ts.map +1 -0
  169. package/dist/dev/ui/slider/slider-thumbnail.js +20 -0
  170. package/dist/dev/ui/slider/slider-thumbnail.js.map +1 -0
  171. package/dist/dev/ui/thumbnail/thumbnail.d.ts.map +1 -1
  172. package/dist/dev/ui/thumbnail/thumbnail.js +3 -5
  173. package/dist/dev/ui/thumbnail/thumbnail.js.map +1 -1
  174. package/dist/dev/ui/time-slider/index.parts.d.ts +2 -1
  175. package/dist/dev/ui/time-slider/index.parts.js +2 -0
  176. package/dist/dev/ui/time-slider/index.parts.js.map +1 -1
  177. package/dist/dev/ui/tooltip/context.d.ts +17 -0
  178. package/dist/dev/ui/tooltip/context.d.ts.map +1 -0
  179. package/dist/dev/ui/tooltip/context.js +16 -0
  180. package/dist/dev/ui/tooltip/context.js.map +1 -0
  181. package/dist/dev/ui/tooltip/group-context.js +15 -0
  182. package/dist/dev/ui/tooltip/group-context.js.map +1 -0
  183. package/dist/dev/ui/tooltip/index.d.ts +3 -0
  184. package/dist/dev/ui/tooltip/index.js +4 -0
  185. package/dist/dev/ui/tooltip/index.parts.d.ts +13 -0
  186. package/dist/dev/ui/tooltip/index.parts.d.ts.map +1 -0
  187. package/dist/dev/ui/tooltip/index.parts.js +19 -0
  188. package/dist/dev/ui/tooltip/index.parts.js.map +1 -0
  189. package/dist/dev/ui/tooltip/tooltip-arrow.d.ts +15 -0
  190. package/dist/dev/ui/tooltip/tooltip-arrow.d.ts.map +1 -0
  191. package/dist/dev/ui/tooltip/tooltip-arrow.js +17 -0
  192. package/dist/dev/ui/tooltip/tooltip-arrow.js.map +1 -0
  193. package/dist/dev/ui/tooltip/tooltip-popup.d.ts +15 -0
  194. package/dist/dev/ui/tooltip/tooltip-popup.d.ts.map +1 -0
  195. package/dist/dev/ui/tooltip/tooltip-popup.js +97 -0
  196. package/dist/dev/ui/tooltip/tooltip-popup.js.map +1 -0
  197. package/dist/dev/ui/tooltip/tooltip-provider.d.ts +19 -0
  198. package/dist/dev/ui/tooltip/tooltip-provider.d.ts.map +1 -0
  199. package/dist/dev/ui/tooltip/tooltip-provider.js +28 -0
  200. package/dist/dev/ui/tooltip/tooltip-provider.js.map +1 -0
  201. package/dist/dev/ui/tooltip/tooltip-root.d.ts +30 -0
  202. package/dist/dev/ui/tooltip/tooltip-root.d.ts.map +1 -0
  203. package/dist/dev/ui/tooltip/tooltip-root.js +71 -0
  204. package/dist/dev/ui/tooltip/tooltip-root.js.map +1 -0
  205. package/dist/dev/ui/tooltip/tooltip-trigger.d.ts +15 -0
  206. package/dist/dev/ui/tooltip/tooltip-trigger.d.ts.map +1 -0
  207. package/dist/dev/ui/tooltip/tooltip-trigger.js +42 -0
  208. package/dist/dev/ui/tooltip/tooltip-trigger.js.map +1 -0
  209. package/dist/dev/ui/volume-slider/index.parts.d.ts +2 -1
  210. package/dist/dev/ui/volume-slider/index.parts.js +2 -0
  211. package/dist/dev/ui/volume-slider/index.parts.js.map +1 -1
  212. package/dist/dev/ui/volume-slider/volume-slider-root.js +4 -4
  213. package/dist/dev/ui/volume-slider/volume-slider-root.js.map +1 -1
  214. package/dist/dev/utils/use-destroy.js +33 -0
  215. package/dist/dev/utils/use-destroy.js.map +1 -0
  216. package/package.json +37 -10
  217. package/dist/default/ui/error-dialog/error-dialog.js +0 -54
  218. package/dist/default/ui/error-dialog/error-dialog.js.map +0 -1
  219. package/dist/default/ui/error-dialog/index.js +0 -3
  220. package/dist/dev/ui/error-dialog/error-dialog.d.ts +0 -35
  221. package/dist/dev/ui/error-dialog/error-dialog.d.ts.map +0 -1
  222. package/dist/dev/ui/error-dialog/error-dialog.js +0 -54
  223. package/dist/dev/ui/error-dialog/error-dialog.js.map +0 -1
  224. package/dist/dev/ui/error-dialog/index.d.ts +0 -2
  225. package/dist/dev/ui/error-dialog/index.js +0 -3
@@ -0,0 +1,59 @@
1
+ 'use client';
2
+
3
+ import { useDestroy } from "../../utils/use-destroy.js";
4
+ import { AlertDialogContextProvider } from "./context.js";
5
+ import { useLatestRef } from "../../utils/use-latest-ref.js";
6
+ import { useSafeId } from "../../utils/use-safe-id.js";
7
+ import { createAlertDialog, createTransition } from "@videojs/core/dom";
8
+ import { useSnapshot } from "@videojs/store/react";
9
+ import { useEffect, useState } from "react";
10
+ import { jsx } from "react/jsx-runtime";
11
+ import { AlertDialogCore, AlertDialogDataAttrs } from "@videojs/core";
12
+
13
+ //#region src/ui/alert-dialog/alert-dialog-root.tsx
14
+ function AlertDialogRoot({ open: controlledOpen, defaultOpen = AlertDialogCore.defaultProps.defaultOpen, onOpenChange: onOpenChangeProp, onOpenChangeComplete: onOpenChangeCompleteProp, children }) {
15
+ const [core] = useState(() => new AlertDialogCore());
16
+ const isControlled = controlledOpen !== void 0;
17
+ const onOpenChangeRef = useLatestRef(onOpenChangeProp);
18
+ const onOpenChangeCompleteRef = useLatestRef(onOpenChangeCompleteProp);
19
+ const [dialog] = useState(() => {
20
+ const instance = createAlertDialog({
21
+ transition: createTransition(),
22
+ onOpenChange: (nextOpen) => {
23
+ onOpenChangeRef.current?.(nextOpen);
24
+ },
25
+ onOpenChangeComplete: (nextOpen) => {
26
+ onOpenChangeCompleteRef.current?.(nextOpen);
27
+ }
28
+ });
29
+ if (!isControlled && defaultOpen) instance.open();
30
+ return instance;
31
+ });
32
+ const titleId = useSafeId("alert-dialog-title-");
33
+ const descriptionId = useSafeId("alert-dialog-desc-");
34
+ core.setTitleId(titleId);
35
+ core.setDescriptionId(descriptionId);
36
+ useEffect(() => {
37
+ if (controlledOpen === void 0) return;
38
+ const { active: inputOpen } = dialog.input.current;
39
+ if (controlledOpen === inputOpen) return;
40
+ if (controlledOpen) dialog.open();
41
+ else dialog.close();
42
+ }, [controlledOpen, dialog]);
43
+ useDestroy(dialog);
44
+ const input = useSnapshot(dialog.input);
45
+ core.setInput(input);
46
+ return /* @__PURE__ */ jsx(AlertDialogContextProvider, {
47
+ value: {
48
+ core,
49
+ dialog,
50
+ state: core.getState(),
51
+ stateAttrMap: AlertDialogDataAttrs
52
+ },
53
+ children
54
+ });
55
+ }
56
+
57
+ //#endregion
58
+ export { AlertDialogRoot };
59
+ //# sourceMappingURL=alert-dialog-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-dialog-root.js","names":[],"sources":["../../../../src/ui/alert-dialog/alert-dialog-root.tsx"],"sourcesContent":["'use client';\n\nimport { AlertDialogCore, AlertDialogDataAttrs, type AlertDialogProps } from '@videojs/core';\nimport { createAlertDialog, createTransition } from '@videojs/core/dom';\nimport { useSnapshot } from '@videojs/store/react';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { useDestroy } from '../../utils/use-destroy';\nimport { useLatestRef } from '../../utils/use-latest-ref';\nimport { useSafeId } from '../../utils/use-safe-id';\nimport { AlertDialogContextProvider } from './context';\n\nexport interface AlertDialogRootProps extends AlertDialogProps {\n /** Called when the open state changes (fires immediately, before animations). */\n onOpenChange?: (open: boolean) => void;\n /** Called after open/close animations complete. */\n onOpenChangeComplete?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function AlertDialogRoot({\n open: controlledOpen,\n defaultOpen = AlertDialogCore.defaultProps.defaultOpen,\n onOpenChange: onOpenChangeProp,\n onOpenChangeComplete: onOpenChangeCompleteProp,\n children,\n}: AlertDialogRootProps): ReactNode {\n const [core] = useState(() => new AlertDialogCore());\n\n const isControlled = controlledOpen !== undefined;\n\n const onOpenChangeRef = useLatestRef(onOpenChangeProp);\n const onOpenChangeCompleteRef = useLatestRef(onOpenChangeCompleteProp);\n\n const [dialog] = useState(() => {\n const instance = createAlertDialog({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean) => {\n onOpenChangeRef.current?.(nextOpen);\n },\n onOpenChangeComplete: (nextOpen: boolean) => {\n onOpenChangeCompleteRef.current?.(nextOpen);\n },\n });\n\n if (!isControlled && defaultOpen) {\n instance.open();\n }\n\n return instance;\n });\n\n const titleId = useSafeId('alert-dialog-title-');\n const descriptionId = useSafeId('alert-dialog-desc-');\n\n core.setTitleId(titleId);\n core.setDescriptionId(descriptionId);\n\n // Sync controlled open prop -> internal input state.\n useEffect(() => {\n if (controlledOpen === undefined) return;\n\n const { active: inputOpen } = dialog.input.current;\n if (controlledOpen === inputOpen) return;\n\n if (controlledOpen) {\n dialog.open();\n } else {\n dialog.close();\n }\n }, [controlledOpen, dialog]);\n\n useDestroy(dialog);\n\n const input = useSnapshot(dialog.input);\n core.setInput(input);\n const state = core.getState();\n\n return (\n <AlertDialogContextProvider value={{ core, dialog, state, stateAttrMap: AlertDialogDataAttrs }}>\n {children}\n </AlertDialogContextProvider>\n );\n}\n\nexport namespace AlertDialogRoot {\n export type Props = AlertDialogRootProps;\n}\n"],"mappings":";;;;;;;;;;;;;AAqBA,SAAgB,gBAAgB,EAC9B,MAAM,gBACN,cAAc,gBAAgB,aAAa,aAC3C,cAAc,kBACd,sBAAsB,0BACtB,YACkC;CAClC,MAAM,CAAC,QAAQ,eAAe,IAAI,iBAAiB,CAAC;CAEpD,MAAM,eAAe,mBAAmB;CAExC,MAAM,kBAAkB,aAAa,iBAAiB;CACtD,MAAM,0BAA0B,aAAa,yBAAyB;CAEtE,MAAM,CAAC,UAAU,eAAe;EAC9B,MAAM,WAAW,kBAAkB;GACjC,YAAY,kBAAkB;GAC9B,eAAe,aAAsB;AACnC,oBAAgB,UAAU,SAAS;;GAErC,uBAAuB,aAAsB;AAC3C,4BAAwB,UAAU,SAAS;;GAE9C,CAAC;AAEF,MAAI,CAAC,gBAAgB,YACnB,UAAS,MAAM;AAGjB,SAAO;GACP;CAEF,MAAM,UAAU,UAAU,sBAAsB;CAChD,MAAM,gBAAgB,UAAU,qBAAqB;AAErD,MAAK,WAAW,QAAQ;AACxB,MAAK,iBAAiB,cAAc;AAGpC,iBAAgB;AACd,MAAI,mBAAmB,OAAW;EAElC,MAAM,EAAE,QAAQ,cAAc,OAAO,MAAM;AAC3C,MAAI,mBAAmB,UAAW;AAElC,MAAI,eACF,QAAO,MAAM;MAEb,QAAO,OAAO;IAEf,CAAC,gBAAgB,OAAO,CAAC;AAE5B,YAAW,OAAO;CAElB,MAAM,QAAQ,YAAY,OAAO,MAAM;AACvC,MAAK,SAAS,MAAM;AAGpB,QACE,oBAAC;EAA2B,OAAO;GAAE;GAAM;GAAQ,OAHvC,KAAK,UAAU;GAG+B,cAAc;GAAsB;EAC3F;GAC0B"}
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+
3
+ import { useAlertDialogContext } from "./context.js";
4
+ import { createContextPart } from "../create-context-part.js";
5
+
6
+ //#region src/ui/alert-dialog/alert-dialog-title.tsx
7
+ const AlertDialogTitle = createContextPart({
8
+ displayName: "AlertDialogTitle",
9
+ tag: "h2",
10
+ useContext: useAlertDialogContext,
11
+ getProps: (state) => ({ id: state.titleId })
12
+ });
13
+
14
+ //#endregion
15
+ export { AlertDialogTitle };
16
+ //# sourceMappingURL=alert-dialog-title.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-dialog-title.js","names":[],"sources":["../../../../src/ui/alert-dialog/alert-dialog-title.tsx"],"sourcesContent":["'use client';\n\nimport type { AlertDialogCore } from '@videojs/core';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createContextPart } from '../create-context-part';\nimport { useAlertDialogContext } from './context';\n\nexport interface AlertDialogTitleProps extends UIComponentProps<'h2', AlertDialogCore.State> {}\n\nexport const AlertDialogTitle = createContextPart<AlertDialogTitleProps, AlertDialogCore.State>({\n displayName: 'AlertDialogTitle',\n tag: 'h2',\n useContext: useAlertDialogContext,\n getProps: (state) => ({ id: state.titleId }),\n});\n\nexport namespace AlertDialogTitle {\n export type Props = AlertDialogTitleProps;\n export type State = AlertDialogCore.State;\n}\n"],"mappings":";;;;;;AAUA,MAAa,mBAAmB,kBAAgE;CAC9F,aAAa;CACb,KAAK;CACL,YAAY;CACZ,WAAW,WAAW,EAAE,IAAI,MAAM,SAAS;CAC5C,CAAC"}
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext } from "react";
4
+
5
+ //#region src/ui/alert-dialog/context.tsx
6
+ const AlertDialogContext = createContext(null);
7
+ const AlertDialogContextProvider = AlertDialogContext.Provider;
8
+ function useAlertDialogContext() {
9
+ const ctx = useContext(AlertDialogContext);
10
+ if (!ctx) throw new Error("AlertDialog compound components must be used within an AlertDialog.Root");
11
+ return ctx;
12
+ }
13
+
14
+ //#endregion
15
+ export { AlertDialogContextProvider, useAlertDialogContext };
16
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../../src/ui/alert-dialog/context.tsx"],"sourcesContent":["'use client';\n\nimport type { AlertDialogCore, StateAttrMap } from '@videojs/core';\nimport type { AlertDialogApi } from '@videojs/core/dom';\nimport { createContext, useContext } from 'react';\n\nexport interface AlertDialogContextValue {\n core: AlertDialogCore;\n dialog: AlertDialogApi;\n state: AlertDialogCore.State;\n stateAttrMap: StateAttrMap<AlertDialogCore.State>;\n}\n\nconst AlertDialogContext = createContext<AlertDialogContextValue | null>(null);\n\nexport const AlertDialogContextProvider = AlertDialogContext.Provider;\n\nexport function useAlertDialogContext(): AlertDialogContextValue {\n const ctx = useContext(AlertDialogContext);\n if (!ctx) throw new Error('AlertDialog compound components must be used within an AlertDialog.Root');\n return ctx;\n}\n"],"mappings":";;;;;AAaA,MAAM,qBAAqB,cAA8C,KAAK;AAE9E,MAAa,6BAA6B,mBAAmB;AAE7D,SAAgB,wBAAiD;CAC/D,MAAM,MAAM,WAAW,mBAAmB;AAC1C,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,0EAA0E;AACpG,QAAO"}
@@ -0,0 +1,4 @@
1
+ import { useAlertDialogContext } from "./context.js";
2
+ import { index_parts_exports } from "./index.parts.js";
3
+
4
+ export { index_parts_exports as AlertDialog, useAlertDialogContext };
@@ -0,0 +1,19 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { AlertDialogClose } from "./alert-dialog-close.js";
3
+ import { AlertDialogDescription } from "./alert-dialog-description.js";
4
+ import { AlertDialogPopup } from "./alert-dialog-popup.js";
5
+ import { AlertDialogRoot } from "./alert-dialog-root.js";
6
+ import { AlertDialogTitle } from "./alert-dialog-title.js";
7
+
8
+ //#region src/ui/alert-dialog/index.parts.ts
9
+ var index_parts_exports = /* @__PURE__ */ __exportAll({
10
+ Close: () => AlertDialogClose,
11
+ Description: () => AlertDialogDescription,
12
+ Popup: () => AlertDialogPopup,
13
+ Root: () => AlertDialogRoot,
14
+ Title: () => AlertDialogTitle
15
+ });
16
+
17
+ //#endregion
18
+ export { index_parts_exports };
19
+ //# sourceMappingURL=index.parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.parts.js","names":[],"sources":["../../../../src/ui/alert-dialog/index.parts.ts"],"sourcesContent":["export { AlertDialogClose as Close, type AlertDialogCloseProps as CloseProps } from './alert-dialog-close';\nexport {\n AlertDialogDescription as Description,\n type AlertDialogDescriptionProps as DescriptionProps,\n} from './alert-dialog-description';\nexport { AlertDialogPopup as Popup, type AlertDialogPopupProps as PopupProps } from './alert-dialog-popup';\nexport { AlertDialogRoot as Root, type AlertDialogRootProps as RootProps } from './alert-dialog-root';\nexport { AlertDialogTitle as Title, type AlertDialogTitleProps as TitleProps } from './alert-dialog-title';\n"],"mappings":""}
@@ -1,34 +1,17 @@
1
1
  'use client';
2
2
 
3
- import { useButton } from "../hooks/use-button.js";
4
- import { forwardRef, useState } from "react";
3
+ import { createMediaButton } from "../create-media-button.js";
4
+ import { selectTextTrack } from "@videojs/core/dom";
5
+ import { CaptionsButtonCore, CaptionsButtonDataAttrs } from "@videojs/core";
5
6
 
6
7
  //#region src/ui/captions-button/captions-button.tsx
7
- /**
8
- * A button that toggles captions.
9
- *
10
- * @example
11
- * ```tsx
12
- * <CaptionsButton />
13
- *
14
- * <CaptionsButton
15
- * render={(props, state) => (
16
- * <button {...props}>
17
- * {state.active ? <CaptionsOnIcon /> : <CaptionsOffIcon />}
18
- * </button>
19
- * )}
20
- * />
21
- * ```
22
- */
23
- const CaptionsButton = forwardRef(function CaptionsButton(componentProps, forwardedRef) {
24
- const { render, className, style, label, disabled, ...elementProps } = componentProps;
25
- const [isActive, setIsActive] = useState(false);
26
- const { getButtonProps, buttonRef } = useButton({
27
- displayName: "CaptionsButton",
28
- onActivate: () => setIsActive((active) => !active),
29
- isDisabled: () => disabled ?? false
30
- });
31
- return null;
8
+ /** A button that toggles captions. */
9
+ const CaptionsButton = createMediaButton({
10
+ displayName: "CaptionsButton",
11
+ core: CaptionsButtonCore,
12
+ stateAttrMap: CaptionsButtonDataAttrs,
13
+ selector: selectTextTrack,
14
+ action: (core, state) => core.toggle(state)
32
15
  });
33
16
 
34
17
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"captions-button.js","names":[],"sources":["../../../../src/ui/captions-button/captions-button.tsx"],"sourcesContent":["'use client';\n\nimport type { StateAttrMap } from '@videojs/core';\nimport type { ForwardedRef } from 'react';\nimport { forwardRef, useState } from 'react';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\nimport { useButton } from '../hooks/use-button';\n\n// FIXME: Replace with state/props from core.\nexport type CaptionsButtonState = {\n active: boolean;\n};\ntype CaptionButtonCoreProps = {\n /** Custom label for the button. */\n label?: string | ((state: CaptionsButtonState) => string) | undefined;\n /** Whether the button is disabled. */\n disabled?: boolean | undefined;\n};\nconst CaptionButtonDataAttrs = {\n /** Present when the captions are active. */\n active: 'data-active',\n} as const satisfies StateAttrMap<CaptionsButtonState>;\n\nexport interface CaptionsButtonProps extends UIComponentProps<'button', CaptionsButtonState>, CaptionButtonCoreProps {}\n\nconst DEBUG = false;\n\n/**\n * A button that toggles captions.\n *\n * @example\n * ```tsx\n * <CaptionsButton />\n *\n * <CaptionsButton\n * render={(props, state) => (\n * <button {...props}>\n * {state.active ? <CaptionsOnIcon /> : <CaptionsOffIcon />}\n * </button>\n * )}\n * />\n * ```\n */\nexport const CaptionsButton = forwardRef(function CaptionsButton(\n componentProps: CaptionsButtonProps,\n forwardedRef: ForwardedRef<HTMLButtonElement>\n) {\n const { render, className, style, label, disabled, ...elementProps } = componentProps;\n\n // FIXME: Replace with actual captions state\n const [isActive, setIsActive] = useState(false);\n\n const { getButtonProps, buttonRef } = useButton({\n displayName: 'CaptionsButton',\n onActivate: () => setIsActive((active) => !active), // FIXME: Replace with actual toggle logic\n isDisabled: () => disabled ?? false,\n });\n\n if (!DEBUG) return null;\n\n return renderElement(\n 'button',\n { render, className, style },\n {\n state: { active: isActive }, // FIXME: Replace with actual toggle logic\n stateAttrMap: CaptionButtonDataAttrs,\n ref: [forwardedRef, buttonRef],\n props: [elementProps, getButtonProps(), { 'aria-pressed': isActive }],\n }\n );\n});\n\nexport namespace CaptionsButton {\n export type Props = CaptionsButtonProps;\n export type State = CaptionsButtonState;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAa,iBAAiB,WAAW,SAAS,eAChD,gBACA,cACA;CACA,MAAM,EAAE,QAAQ,WAAW,OAAO,OAAO,UAAU,GAAG,iBAAiB;CAGvE,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;CAE/C,MAAM,EAAE,gBAAgB,cAAc,UAAU;EAC9C,aAAa;EACb,kBAAkB,aAAa,WAAW,CAAC,OAAO;EAClD,kBAAkB,YAAY;EAC/B,CAAC;AAEU,QAAO;EAYnB"}
1
+ {"version":3,"file":"captions-button.js","names":[],"sources":["../../../../src/ui/captions-button/captions-button.tsx"],"sourcesContent":["'use client';\n\nimport { CaptionsButtonCore, CaptionsButtonDataAttrs } from '@videojs/core';\nimport { selectTextTrack } from '@videojs/core/dom';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { createMediaButton } from '../create-media-button';\n\nexport interface CaptionsButtonProps\n extends UIComponentProps<'button', CaptionsButtonCore.State>,\n CaptionsButtonCore.Props {}\n\n/** A button that toggles captions. */\nexport const CaptionsButton = createMediaButton<CaptionsButtonCore, CaptionsButtonProps>({\n displayName: 'CaptionsButton',\n core: CaptionsButtonCore,\n stateAttrMap: CaptionsButtonDataAttrs,\n selector: selectTextTrack,\n action: (core, state) => core.toggle(state),\n});\n\nexport namespace CaptionsButton {\n export type Props = CaptionsButtonProps;\n export type State = CaptionsButtonCore.State;\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,iBAAiB,kBAA2D;CACvF,aAAa;CACb,MAAM;CACN,cAAc;CACd,UAAU;CACV,SAAS,MAAM,UAAU,KAAK,OAAO,MAAM;CAC5C,CAAC"}
@@ -5,10 +5,11 @@ import { forwardRef } from "react";
5
5
 
6
6
  //#region src/ui/create-context-part.tsx
7
7
  function createContextPart(config) {
8
- const { displayName, tag, useContext, staticProps } = config;
8
+ const { displayName, tag, useContext, staticProps, getProps } = config;
9
9
  const Component = forwardRef(function ContextPart(componentProps, forwardedRef) {
10
10
  const { render, className, style, ...elementProps } = componentProps;
11
11
  const context = useContext();
12
+ const dynamicProps = getProps?.(context.state);
12
13
  return renderElement(tag, {
13
14
  render,
14
15
  className,
@@ -17,7 +18,11 @@ function createContextPart(config) {
17
18
  state: context.state,
18
19
  stateAttrMap: context.stateAttrMap,
19
20
  ref: forwardedRef,
20
- props: staticProps ? [staticProps, elementProps] : [elementProps]
21
+ props: [
22
+ staticProps,
23
+ dynamicProps,
24
+ elementProps
25
+ ].filter(Boolean)
21
26
  });
22
27
  });
23
28
  Component.displayName = displayName;
@@ -1 +1 @@
1
- {"version":3,"file":"create-context-part.js","names":[],"sources":["../../../src/ui/create-context-part.tsx"],"sourcesContent":["'use client';\n\nimport type { StateAttrMap } from '@videojs/core';\nimport type { ForwardRefExoticComponent } from 'react';\nimport { forwardRef } from 'react';\nimport type { UIComponentProps } from '@/utils/types';\nimport type { renderElement as renderElementFn } from '../utils/use-render';\nimport { renderElement } from '../utils/use-render';\n\ninterface ContextPartConfig<Props extends object, State extends object> {\n displayName: string;\n tag: keyof React.JSX.IntrinsicElements;\n useContext: () => { state: State; stateAttrMap: StateAttrMap<State> };\n staticProps?: Partial<Props>;\n}\n\nexport function createContextPart<Props extends UIComponentProps<any, any>, State extends object>(\n config: ContextPartConfig<Props, State>\n): ForwardRefExoticComponent<Props> {\n const { displayName, tag, useContext, staticProps } = config;\n\n const Component = forwardRef<HTMLElement, Props>(function ContextPart(componentProps, forwardedRef) {\n const { render, className, style, ...elementProps } = componentProps;\n const context = useContext();\n\n return renderElement(tag, { render, className, style } as renderElementFn.ComponentProps<State>, {\n state: context.state,\n stateAttrMap: context.stateAttrMap,\n ref: forwardedRef,\n props: staticProps ? [staticProps, elementProps] : [elementProps],\n });\n });\n\n Component.displayName = displayName;\n\n return Component as ForwardRefExoticComponent<Props>;\n}\n"],"mappings":";;;;;;AAgBA,SAAgB,kBACd,QACkC;CAClC,MAAM,EAAE,aAAa,KAAK,YAAY,gBAAgB;CAEtD,MAAM,YAAY,WAA+B,SAAS,YAAY,gBAAgB,cAAc;EAClG,MAAM,EAAE,QAAQ,WAAW,OAAO,GAAG,iBAAiB;EACtD,MAAM,UAAU,YAAY;AAE5B,SAAO,cAAc,KAAK;GAAE;GAAQ;GAAW;GAAO,EAA2C;GAC/F,OAAO,QAAQ;GACf,cAAc,QAAQ;GACtB,KAAK;GACL,OAAO,cAAc,CAAC,aAAa,aAAa,GAAG,CAAC,aAAa;GAClE,CAAC;GACF;AAEF,WAAU,cAAc;AAExB,QAAO"}
1
+ {"version":3,"file":"create-context-part.js","names":[],"sources":["../../../src/ui/create-context-part.tsx"],"sourcesContent":["'use client';\n\nimport type { StateAttrMap } from '@videojs/core';\nimport type { ForwardRefExoticComponent } from 'react';\nimport { forwardRef } from 'react';\nimport type { UIComponentProps } from '@/utils/types';\nimport type { renderElement as renderElementFn } from '../utils/use-render';\nimport { renderElement } from '../utils/use-render';\n\ninterface ContextPartConfig<Props extends object, State extends object> {\n displayName: string;\n tag: keyof React.JSX.IntrinsicElements;\n useContext: () => { state: State; stateAttrMap: StateAttrMap<State> };\n staticProps?: Partial<Props>;\n /** Derive props from state on each render (e.g. `id` from a state field). */\n getProps?: (state: State) => Record<string, unknown>;\n}\n\nexport function createContextPart<Props extends UIComponentProps<any, any>, State extends object>(\n config: ContextPartConfig<Props, State>\n): ForwardRefExoticComponent<Props> {\n const { displayName, tag, useContext, staticProps, getProps } = config;\n\n const Component = forwardRef<HTMLElement, Props>(function ContextPart(componentProps, forwardedRef) {\n const { render, className, style, ...elementProps } = componentProps;\n const context = useContext();\n const dynamicProps = getProps?.(context.state);\n\n return renderElement(tag, { render, className, style } as renderElementFn.ComponentProps<State>, {\n state: context.state,\n stateAttrMap: context.stateAttrMap,\n ref: forwardedRef,\n props: [staticProps, dynamicProps, elementProps].filter(Boolean),\n });\n });\n\n Component.displayName = displayName;\n\n return Component as ForwardRefExoticComponent<Props>;\n}\n"],"mappings":";;;;;;AAkBA,SAAgB,kBACd,QACkC;CAClC,MAAM,EAAE,aAAa,KAAK,YAAY,aAAa,aAAa;CAEhE,MAAM,YAAY,WAA+B,SAAS,YAAY,gBAAgB,cAAc;EAClG,MAAM,EAAE,QAAQ,WAAW,OAAO,GAAG,iBAAiB;EACtD,MAAM,UAAU,YAAY;EAC5B,MAAM,eAAe,WAAW,QAAQ,MAAM;AAE9C,SAAO,cAAc,KAAK;GAAE;GAAQ;GAAW;GAAO,EAA2C;GAC/F,OAAO,QAAQ;GACf,cAAc,QAAQ;GACtB,KAAK;GACL,OAAO;IAAC;IAAa;IAAc;IAAa,CAAC,OAAO,QAAQ;GACjE,CAAC;GACF;AAEF,WAAU,cAAc;AAExB,QAAO"}
@@ -1,10 +1,11 @@
1
1
  'use client';
2
2
 
3
- import { useForceRender } from "../../utils/use-force-render.js";
3
+ import { useDestroy } from "../../utils/use-destroy.js";
4
4
  import { useLatestRef } from "../../utils/use-latest-ref.js";
5
+ import { useForceRender } from "../../utils/use-force-render.js";
5
6
  import { createSlider } from "@videojs/core/dom";
6
7
  import { useSnapshot } from "@videojs/store/react";
7
- import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
8
+ import { useCallback, useLayoutEffect, useRef, useState } from "react";
8
9
  import { isRTL } from "@videojs/utils/dom";
9
10
 
10
11
  //#region src/ui/hooks/use-slider.ts
@@ -31,34 +32,22 @@ function useSlider(options) {
31
32
  getStepPercent: () => optionsRef.current.getStepPercent(),
32
33
  getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),
33
34
  commitThrottle: optionsRef.current.commitThrottle,
35
+ adjustPercent: optionsRef.current.adjustPercent,
34
36
  onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),
35
37
  onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),
36
38
  onDragStart: () => optionsRef.current.onDragStart?.(),
37
39
  onDragEnd: () => optionsRef.current.onDragEnd?.()
38
40
  });
39
41
  });
40
- useEffect(() => () => slider.destroy(), [slider]);
42
+ useDestroy(slider);
41
43
  const input = useSnapshot(slider.input);
42
44
  const state = options.computeState(input);
43
45
  useLayoutEffect(() => {
44
46
  if (state.thumbAlignment === "edge" && rootElementRef.current && thumbElementRef.current) forceRender();
45
47
  }, [state.thumbAlignment]);
46
- const rootEl = rootElementRef.current;
47
- const thumbEl = thumbElementRef.current;
48
- let cssState = state;
49
- if (state.thumbAlignment === "edge" && rootEl && thumbEl && options.adjustPercent) {
50
- const isHorizontal = state.orientation === "horizontal";
51
- const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;
52
- const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;
53
- cssState = {
54
- ...state,
55
- fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),
56
- pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize)
57
- };
58
- }
59
48
  return {
60
49
  state,
61
- cssVars: options.getCSSVars(cssState),
50
+ cssVars: options.getCSSVars(slider.adjustForAlignment(state)),
62
51
  rootRef: useCallback((element) => {
63
52
  rootElementRef.current = element;
64
53
  }, []),
@@ -1 +1 @@
1
- {"version":3,"file":"use-slider.js","names":[],"sources":["../../../../src/ui/hooks/use-slider.ts"],"sourcesContent":["'use client';\n\nimport type { SliderInput, SliderState } from '@videojs/core';\nimport {\n createSlider,\n type SliderApi,\n type SliderOptions,\n type SliderRootProps,\n type SliderThumbProps,\n} from '@videojs/core/dom';\nimport { useSnapshot } from '@videojs/store/react';\nimport { isRTL } from '@videojs/utils/dom';\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport { useForceRender } from '../../utils/use-force-render';\nimport { useLatestRef } from '../../utils/use-latest-ref';\n\nexport interface UseSliderOptions<State extends SliderState = SliderState>\n extends Pick<\n SliderOptions,\n | 'getPercent'\n | 'getStepPercent'\n | 'getLargeStepPercent'\n | 'commitThrottle'\n | 'onValueChange'\n | 'onValueCommit'\n | 'onDragStart'\n | 'onDragEnd'\n > {\n computeState: (input: SliderInput) => State;\n orientation?: 'horizontal' | 'vertical' | undefined;\n disabled?: boolean | undefined;\n /** Adjust a raw 0–100 percent for thumb alignment. Called for fill and pointer percents. */\n adjustPercent?: ((rawPercent: number, thumbSize: number, trackSize: number) => number) | undefined;\n /** Compute CSS variable map from the (possibly alignment-adjusted) state. */\n getCSSVars: (state: State) => Record<string, string>;\n}\n\nexport interface UseSliderReturnValue<State extends SliderState = SliderState> {\n state: State;\n cssVars: Record<string, string>;\n rootRef: React.RefCallback<HTMLElement>;\n thumbRef: React.RefCallback<HTMLElement>;\n rootProps: SliderRootProps;\n thumbProps: SliderThumbProps;\n}\n\n/**\n * Manages slider input lifecycle for React.\n *\n * Wraps `createSlider()` from `@videojs/core/dom` and subscribes to its\n * input state via `useSnapshot`. Returns split props for the root\n * (pointer events) and thumb (keyboard/focus) elements.\n */\nexport function useSlider<State extends SliderState = SliderState>(\n options: UseSliderOptions<State>\n): UseSliderReturnValue<State> {\n const optionsRef = useLatestRef(options);\n\n const rootElementRef = useRef<HTMLElement | null>(null);\n const thumbElementRef = useRef<HTMLElement | null>(null);\n const forceRender = useForceRender();\n\n // Lazy-init the slider handle. Stable across re-renders.\n const [slider] = useState<SliderApi>(() => {\n const stableOptions: SliderOptions = {\n getElement: () => rootElementRef.current!,\n getThumbElement: () => thumbElementRef.current,\n getOrientation: () => optionsRef.current.orientation ?? 'horizontal',\n isRTL: () => (rootElementRef.current ? isRTL(rootElementRef.current) : false),\n isDisabled: () => optionsRef.current.disabled ?? false,\n getPercent: () => optionsRef.current.getPercent(),\n getStepPercent: () => optionsRef.current.getStepPercent(),\n getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),\n commitThrottle: optionsRef.current.commitThrottle,\n onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),\n onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),\n onDragStart: () => optionsRef.current.onDragStart?.(),\n onDragEnd: () => optionsRef.current.onDragEnd?.(),\n };\n\n return createSlider(stableOptions);\n });\n\n // Cleanup on unmount.\n useEffect(() => () => slider.destroy(), [slider]);\n\n // Subscribe to slider input state.\n const input = useSnapshot(slider.input);\n\n // Compute derived state from input + caller-provided projection.\n const state = options.computeState(input);\n\n // Force a synchronous re-render after mount so edge thumb alignment\n // can read DOM measurements from the now-populated element refs.\n useLayoutEffect(() => {\n if (state.thumbAlignment === 'edge' && rootElementRef.current && thumbElementRef.current) {\n forceRender();\n }\n }, [state.thumbAlignment]);\n\n // Adjust CSS var percents for edge thumb alignment when DOM elements are available.\n const rootEl = rootElementRef.current;\n const thumbEl = thumbElementRef.current;\n let cssState = state;\n\n if (state.thumbAlignment === 'edge' && rootEl && thumbEl && options.adjustPercent) {\n const isHorizontal = state.orientation === 'horizontal';\n const thumbSize = isHorizontal ? thumbEl.offsetWidth : thumbEl.offsetHeight;\n const trackSize = isHorizontal ? rootEl.offsetWidth : rootEl.offsetHeight;\n cssState = {\n ...state,\n fillPercent: options.adjustPercent(state.fillPercent, thumbSize, trackSize),\n pointerPercent: options.adjustPercent(state.pointerPercent, thumbSize, trackSize),\n };\n }\n\n const cssVars = options.getCSSVars(cssState);\n\n // Ref callbacks for root and thumb elements.\n const rootRef = useCallback((element: HTMLElement | null) => {\n rootElementRef.current = element;\n }, []);\n\n const thumbRef = useCallback((element: HTMLElement | null) => {\n thumbElementRef.current = element;\n }, []);\n\n return {\n state,\n cssVars,\n rootRef,\n thumbRef,\n rootProps: slider.rootProps,\n thumbProps: slider.thumbProps,\n };\n}\n\nexport namespace useSlider {\n export type Options = UseSliderOptions;\n export type ReturnValue = UseSliderReturnValue;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqDA,SAAgB,UACd,SAC6B;CAC7B,MAAM,aAAa,aAAa,QAAQ;CAExC,MAAM,iBAAiB,OAA2B,KAAK;CACvD,MAAM,kBAAkB,OAA2B,KAAK;CACxD,MAAM,cAAc,gBAAgB;CAGpC,MAAM,CAAC,UAAU,eAA0B;AAiBzC,SAAO,aAhB8B;GACnC,kBAAkB,eAAe;GACjC,uBAAuB,gBAAgB;GACvC,sBAAsB,WAAW,QAAQ,eAAe;GACxD,aAAc,eAAe,UAAU,MAAM,eAAe,QAAQ,GAAG;GACvE,kBAAkB,WAAW,QAAQ,YAAY;GACjD,kBAAkB,WAAW,QAAQ,YAAY;GACjD,sBAAsB,WAAW,QAAQ,gBAAgB;GACzD,2BAA2B,WAAW,QAAQ,qBAAqB;GACnE,gBAAgB,WAAW,QAAQ;GACnC,gBAAgB,YAAY,WAAW,QAAQ,gBAAgB,QAAQ;GACvE,gBAAgB,YAAY,WAAW,QAAQ,gBAAgB,QAAQ;GACvE,mBAAmB,WAAW,QAAQ,eAAe;GACrD,iBAAiB,WAAW,QAAQ,aAAa;GAClD,CAEiC;GAClC;AAGF,uBAAsB,OAAO,SAAS,EAAE,CAAC,OAAO,CAAC;CAGjD,MAAM,QAAQ,YAAY,OAAO,MAAM;CAGvC,MAAM,QAAQ,QAAQ,aAAa,MAAM;AAIzC,uBAAsB;AACpB,MAAI,MAAM,mBAAmB,UAAU,eAAe,WAAW,gBAAgB,QAC/E,cAAa;IAEd,CAAC,MAAM,eAAe,CAAC;CAG1B,MAAM,SAAS,eAAe;CAC9B,MAAM,UAAU,gBAAgB;CAChC,IAAI,WAAW;AAEf,KAAI,MAAM,mBAAmB,UAAU,UAAU,WAAW,QAAQ,eAAe;EACjF,MAAM,eAAe,MAAM,gBAAgB;EAC3C,MAAM,YAAY,eAAe,QAAQ,cAAc,QAAQ;EAC/D,MAAM,YAAY,eAAe,OAAO,cAAc,OAAO;AAC7D,aAAW;GACT,GAAG;GACH,aAAa,QAAQ,cAAc,MAAM,aAAa,WAAW,UAAU;GAC3E,gBAAgB,QAAQ,cAAc,MAAM,gBAAgB,WAAW,UAAU;GAClF;;AAcH,QAAO;EACL;EACA,SAbc,QAAQ,WAAW,SAAS;EAc1C,SAXc,aAAa,YAAgC;AAC3D,kBAAe,UAAU;KACxB,EAAE,CAAC;EAUJ,UARe,aAAa,YAAgC;AAC5D,mBAAgB,UAAU;KACzB,EAAE,CAAC;EAOJ,WAAW,OAAO;EAClB,YAAY,OAAO;EACpB"}
1
+ {"version":3,"file":"use-slider.js","names":[],"sources":["../../../../src/ui/hooks/use-slider.ts"],"sourcesContent":["'use client';\n\nimport type { SliderInput, SliderState } from '@videojs/core';\nimport {\n createSlider,\n type SliderApi,\n type SliderOptions,\n type SliderRootProps,\n type SliderThumbProps,\n} from '@videojs/core/dom';\nimport { useSnapshot } from '@videojs/store/react';\nimport { isRTL } from '@videojs/utils/dom';\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react';\nimport { useDestroy } from '../../utils/use-destroy';\nimport { useForceRender } from '../../utils/use-force-render';\nimport { useLatestRef } from '../../utils/use-latest-ref';\n\nexport interface UseSliderOptions<State extends SliderState = SliderState>\n extends Pick<\n SliderOptions,\n | 'getPercent'\n | 'getStepPercent'\n | 'getLargeStepPercent'\n | 'commitThrottle'\n | 'onValueChange'\n | 'onValueCommit'\n | 'onDragStart'\n | 'onDragEnd'\n > {\n computeState: (input: SliderInput) => State;\n orientation?: 'horizontal' | 'vertical' | undefined;\n disabled?: boolean | undefined;\n /** Adjust a raw 0–100 percent for thumb alignment. Called for fill and pointer percents. */\n adjustPercent?: ((rawPercent: number, thumbSize: number, trackSize: number) => number) | undefined;\n /** Compute CSS variable map from the (possibly alignment-adjusted) state. */\n getCSSVars: (state: State) => Record<string, string>;\n}\n\nexport interface UseSliderReturnValue<State extends SliderState = SliderState> {\n state: State;\n cssVars: Record<string, string>;\n rootRef: React.RefCallback<HTMLElement>;\n thumbRef: React.RefCallback<HTMLElement>;\n rootProps: SliderRootProps;\n thumbProps: SliderThumbProps;\n}\n\n/**\n * Manages slider input lifecycle for React.\n *\n * Wraps `createSlider()` from `@videojs/core/dom` and subscribes to its\n * input state via `useSnapshot`. Returns split props for the root\n * (pointer events) and thumb (keyboard/focus) elements.\n */\nexport function useSlider<State extends SliderState = SliderState>(\n options: UseSliderOptions<State>\n): UseSliderReturnValue<State> {\n const optionsRef = useLatestRef(options);\n\n const rootElementRef = useRef<HTMLElement | null>(null);\n const thumbElementRef = useRef<HTMLElement | null>(null);\n const forceRender = useForceRender();\n\n // Lazy-init the slider handle. Stable across re-renders.\n const [slider] = useState<SliderApi>(() => {\n const stableOptions: SliderOptions = {\n getElement: () => rootElementRef.current!,\n getThumbElement: () => thumbElementRef.current,\n getOrientation: () => optionsRef.current.orientation ?? 'horizontal',\n isRTL: () => (rootElementRef.current ? isRTL(rootElementRef.current) : false),\n isDisabled: () => optionsRef.current.disabled ?? false,\n getPercent: () => optionsRef.current.getPercent(),\n getStepPercent: () => optionsRef.current.getStepPercent(),\n getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),\n commitThrottle: optionsRef.current.commitThrottle,\n adjustPercent: optionsRef.current.adjustPercent,\n onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),\n onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),\n onDragStart: () => optionsRef.current.onDragStart?.(),\n onDragEnd: () => optionsRef.current.onDragEnd?.(),\n };\n\n return createSlider(stableOptions);\n });\n\n useDestroy(slider);\n\n // Subscribe to slider input state.\n const input = useSnapshot(slider.input);\n\n // Compute derived state from input + caller-provided projection.\n const state = options.computeState(input);\n\n // Force a synchronous re-render after mount so edge thumb alignment\n // can read DOM measurements from the now-populated element refs.\n useLayoutEffect(() => {\n if (state.thumbAlignment === 'edge' && rootElementRef.current && thumbElementRef.current) {\n forceRender();\n }\n }, [state.thumbAlignment]);\n\n // Adjust CSS var percents for edge thumb alignment using live DOM measurements.\n const cssVars = options.getCSSVars(slider.adjustForAlignment(state));\n\n // Ref callbacks for root and thumb elements.\n const rootRef = useCallback((element: HTMLElement | null) => {\n rootElementRef.current = element;\n }, []);\n\n const thumbRef = useCallback((element: HTMLElement | null) => {\n thumbElementRef.current = element;\n }, []);\n\n return {\n state,\n cssVars,\n rootRef,\n thumbRef,\n rootProps: slider.rootProps,\n thumbProps: slider.thumbProps,\n };\n}\n\nexport namespace useSlider {\n export type Options = UseSliderOptions;\n export type ReturnValue = UseSliderReturnValue;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsDA,SAAgB,UACd,SAC6B;CAC7B,MAAM,aAAa,aAAa,QAAQ;CAExC,MAAM,iBAAiB,OAA2B,KAAK;CACvD,MAAM,kBAAkB,OAA2B,KAAK;CACxD,MAAM,cAAc,gBAAgB;CAGpC,MAAM,CAAC,UAAU,eAA0B;AAkBzC,SAAO,aAjB8B;GACnC,kBAAkB,eAAe;GACjC,uBAAuB,gBAAgB;GACvC,sBAAsB,WAAW,QAAQ,eAAe;GACxD,aAAc,eAAe,UAAU,MAAM,eAAe,QAAQ,GAAG;GACvE,kBAAkB,WAAW,QAAQ,YAAY;GACjD,kBAAkB,WAAW,QAAQ,YAAY;GACjD,sBAAsB,WAAW,QAAQ,gBAAgB;GACzD,2BAA2B,WAAW,QAAQ,qBAAqB;GACnE,gBAAgB,WAAW,QAAQ;GACnC,eAAe,WAAW,QAAQ;GAClC,gBAAgB,YAAY,WAAW,QAAQ,gBAAgB,QAAQ;GACvE,gBAAgB,YAAY,WAAW,QAAQ,gBAAgB,QAAQ;GACvE,mBAAmB,WAAW,QAAQ,eAAe;GACrD,iBAAiB,WAAW,QAAQ,aAAa;GAClD,CAEiC;GAClC;AAEF,YAAW,OAAO;CAGlB,MAAM,QAAQ,YAAY,OAAO,MAAM;CAGvC,MAAM,QAAQ,QAAQ,aAAa,MAAM;AAIzC,uBAAsB;AACpB,MAAI,MAAM,mBAAmB,UAAU,eAAe,WAAW,gBAAgB,QAC/E,cAAa;IAEd,CAAC,MAAM,eAAe,CAAC;AAc1B,QAAO;EACL;EACA,SAbc,QAAQ,WAAW,OAAO,mBAAmB,MAAM,CAAC;EAclE,SAXc,aAAa,YAAgC;AAC3D,kBAAe,UAAU;KACxB,EAAE,CAAC;EAUJ,UARe,aAAa,YAAgC;AAC5D,mBAAgB,UAAU;KACzB,EAAE,CAAC;EAOJ,WAAW,OAAO;EAClB,YAAY,OAAO;EACpB"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { usePopoverContext } from "./context.js";
4
3
  import { createContextPart } from "../create-context-part.js";
4
+ import { usePopoverContext } from "./context.js";
5
5
 
6
6
  //#region src/ui/popover/popover-arrow.tsx
7
7
  /** Decorative arrow pointing from the popup toward the trigger. Hidden from assistive technology. */
@@ -19,14 +19,16 @@ const PopoverPopup = forwardRef(function PopoverPopup({ render, className, style
19
19
  const internalRef = useRef(null);
20
20
  const composedRef = useComposedRefs(forwardedRef, useCallback((el) => {
21
21
  popover.setPopupElement(el);
22
- }, [popover]), internalRef);
22
+ if (el && supportsAnchorPositioning()) el.style.setProperty("position-anchor", `--${anchorName}`);
23
+ }, [popover, anchorName]), internalRef);
23
24
  const posOpts = useMemo(() => ({
24
25
  side: state.side,
25
26
  align: state.align
26
27
  }), [state.side, state.align]);
27
28
  const anchorStyle = useMemo(() => {
28
29
  if (!supportsAnchorPositioning()) return null;
29
- return getAnchorPositionStyle(anchorName, posOpts);
30
+ const { positionAnchor: _, ...rest } = getAnchorPositionStyle(anchorName, posOpts);
31
+ return rest;
30
32
  }, [anchorName, posOpts]);
31
33
  const [manualStyle, setManualStyle] = useState(null);
32
34
  useLayoutEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"popover-popup.js","names":[],"sources":["../../../../src/ui/popover/popover-popup.tsx"],"sourcesContent":["'use client';\n\nimport type { PopoverState } from '@videojs/core';\nimport { getAnchorPositionStyle, resolveOffsets } from '@videojs/core/dom';\nimport { supportsAnchorPositioning } from '@videojs/utils/dom';\nimport type { CSSProperties } from 'react';\nimport { forwardRef, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { useComposedRefs } from '../../utils/use-composed-refs';\nimport { renderElement } from '../../utils/use-render';\nimport { usePopoverContext } from './context';\n\nexport interface PopoverPopupProps extends UIComponentProps<'div', PopoverState> {}\n\nconst POPOVER_RESET: CSSProperties = { position: 'fixed', inset: 'auto', margin: 0 };\n\n/** Container for the popover content. Positioned relative to the trigger using CSS anchor positioning with a JavaScript fallback. */\nexport const PopoverPopup = forwardRef<HTMLDivElement, PopoverPopupProps>(function PopoverPopup(\n { render, className, style, ...elementProps },\n forwardedRef\n) {\n const { core, popover, state, stateAttrMap, anchorName, popupId } = usePopoverContext();\n const internalRef = useRef<HTMLDivElement>(null);\n\n const popupRef = useCallback(\n (el: HTMLDivElement | null) => {\n popover.setPopupElement(el);\n },\n [popover]\n );\n\n const composedRef = useComposedRefs(forwardedRef, popupRef, internalRef);\n\n // --- Positioning ---\n\n const posOpts = useMemo(() => ({ side: state.side, align: state.align }), [state.side, state.align]);\n\n // CSS Anchor Positioning — computed from state, no measurement needed.\n // getAnchorPositionStyle returns camelCase keys, directly compatible\n // with React's style prop.\n const anchorStyle = useMemo(() => {\n if (!supportsAnchorPositioning()) return null;\n return getAnchorPositionStyle(anchorName, posOpts) as CSSProperties;\n }, [anchorName, posOpts]);\n\n // Manual fallback — measure rects after layout, before paint.\n const [manualStyle, setManualStyle] = useState<CSSProperties | null>(null);\n\n useLayoutEffect(() => {\n if (supportsAnchorPositioning()) return;\n if (!state.open) {\n setManualStyle(null);\n return;\n }\n\n function measure(): void {\n const triggerEl = popover.triggerElement;\n const popupEl = internalRef.current;\n if (!triggerEl || !popupEl) return;\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const popupRect = popupEl.getBoundingClientRect();\n const boundaryRect = document.documentElement.getBoundingClientRect();\n const offsets = resolveOffsets(popupEl);\n\n setManualStyle(\n getAnchorPositionStyle(anchorName, posOpts, triggerRect, popupRect, boundaryRect, offsets) as CSSProperties\n );\n }\n\n measure();\n\n // Recompute on scroll/resize so the popover tracks its trigger.\n let rafId = 0;\n function reposition(): void {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(measure);\n }\n\n window.addEventListener('scroll', reposition, { capture: true, passive: true });\n window.addEventListener('resize', reposition);\n\n return () => {\n cancelAnimationFrame(rafId);\n window.removeEventListener('scroll', reposition, true);\n window.removeEventListener('resize', reposition);\n };\n }, [state.open, anchorName, posOpts, popover]);\n\n // Anchor path uses computed styles; manual path uses measured styles;\n // fallback resets UA [popover] defaults until positioning is computed.\n const positioningStyle = anchorStyle ?? manualStyle ?? POPOVER_RESET;\n\n // --- Visibility ---\n\n if (!state.open) {\n return null;\n }\n\n // Remap DOM focus events to React synthetic event names.\n const { onFocusOut, ...restPopupProps } = popover.popupProps;\n\n return renderElement(\n 'div',\n { render, className, style },\n {\n state,\n stateAttrMap,\n ref: composedRef,\n props: [\n {\n id: popupId,\n style: positioningStyle,\n ...core.getPopupAttrs(state),\n },\n { ...restPopupProps, onBlur: onFocusOut },\n elementProps,\n ],\n }\n );\n});\n\nexport namespace PopoverPopup {\n export type Props = PopoverPopupProps;\n export type State = PopoverState;\n}\n"],"mappings":";;;;;;;;;;AAeA,MAAM,gBAA+B;CAAE,UAAU;CAAS,OAAO;CAAQ,QAAQ;CAAG;;AAGpF,MAAa,eAAe,WAA8C,SAAS,aACjF,EAAE,QAAQ,WAAW,OAAO,GAAG,gBAC/B,cACA;CACA,MAAM,EAAE,MAAM,SAAS,OAAO,cAAc,YAAY,YAAY,mBAAmB;CACvF,MAAM,cAAc,OAAuB,KAAK;CAShD,MAAM,cAAc,gBAAgB,cAPnB,aACd,OAA8B;AAC7B,UAAQ,gBAAgB,GAAG;IAE7B,CAAC,QAAQ,CACV,EAE2D,YAAY;CAIxE,MAAM,UAAU,eAAe;EAAE,MAAM,MAAM;EAAM,OAAO,MAAM;EAAO,GAAG,CAAC,MAAM,MAAM,MAAM,MAAM,CAAC;CAKpG,MAAM,cAAc,cAAc;AAChC,MAAI,CAAC,2BAA2B,CAAE,QAAO;AACzC,SAAO,uBAAuB,YAAY,QAAQ;IACjD,CAAC,YAAY,QAAQ,CAAC;CAGzB,MAAM,CAAC,aAAa,kBAAkB,SAA+B,KAAK;AAE1E,uBAAsB;AACpB,MAAI,2BAA2B,CAAE;AACjC,MAAI,CAAC,MAAM,MAAM;AACf,kBAAe,KAAK;AACpB;;EAGF,SAAS,UAAgB;GACvB,MAAM,YAAY,QAAQ;GAC1B,MAAM,UAAU,YAAY;AAC5B,OAAI,CAAC,aAAa,CAAC,QAAS;AAO5B,kBACE,uBAAuB,YAAY,SANjB,UAAU,uBAAuB,EACnC,QAAQ,uBAAuB,EAC5B,SAAS,gBAAgB,uBAAuB,EACrD,eAAe,QAAQ,CAGqD,CAC3F;;AAGH,WAAS;EAGT,IAAI,QAAQ;EACZ,SAAS,aAAmB;AAC1B,wBAAqB,MAAM;AAC3B,WAAQ,sBAAsB,QAAQ;;AAGxC,SAAO,iBAAiB,UAAU,YAAY;GAAE,SAAS;GAAM,SAAS;GAAM,CAAC;AAC/E,SAAO,iBAAiB,UAAU,WAAW;AAE7C,eAAa;AACX,wBAAqB,MAAM;AAC3B,UAAO,oBAAoB,UAAU,YAAY,KAAK;AACtD,UAAO,oBAAoB,UAAU,WAAW;;IAEjD;EAAC,MAAM;EAAM;EAAY;EAAS;EAAQ,CAAC;CAI9C,MAAM,mBAAmB,eAAe,eAAe;AAIvD,KAAI,CAAC,MAAM,KACT,QAAO;CAIT,MAAM,EAAE,YAAY,GAAG,mBAAmB,QAAQ;AAElD,QAAO,cACL,OACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA;EACA,KAAK;EACL,OAAO;GACL;IACE,IAAI;IACJ,OAAO;IACP,GAAG,KAAK,cAAc,MAAM;IAC7B;GACD;IAAE,GAAG;IAAgB,QAAQ;IAAY;GACzC;GACD;EACF,CACF;EACD"}
1
+ {"version":3,"file":"popover-popup.js","names":[],"sources":["../../../../src/ui/popover/popover-popup.tsx"],"sourcesContent":["'use client';\n\nimport type { PopoverState } from '@videojs/core';\nimport { getAnchorPositionStyle, resolveOffsets } from '@videojs/core/dom';\nimport { supportsAnchorPositioning } from '@videojs/utils/dom';\nimport type { CSSProperties } from 'react';\nimport { forwardRef, useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { useComposedRefs } from '../../utils/use-composed-refs';\nimport { renderElement } from '../../utils/use-render';\nimport { usePopoverContext } from './context';\n\nexport interface PopoverPopupProps extends UIComponentProps<'div', PopoverState> {}\n\nconst POPOVER_RESET: CSSProperties = { position: 'fixed', inset: 'auto', margin: 0 };\n\n/** Container for the popover content. Positioned relative to the trigger using CSS anchor positioning with a JavaScript fallback. */\nexport const PopoverPopup = forwardRef<HTMLDivElement, PopoverPopupProps>(function PopoverPopup(\n { render, className, style, ...elementProps },\n forwardedRef\n) {\n const { core, popover, state, stateAttrMap, anchorName, popupId } = usePopoverContext();\n const internalRef = useRef<HTMLDivElement>(null);\n\n const popupRef = useCallback(\n (el: HTMLDivElement | null) => {\n popover.setPopupElement(el);\n if (el && supportsAnchorPositioning()) {\n el.style.setProperty('position-anchor', `--${anchorName}`);\n }\n },\n [popover, anchorName]\n );\n\n const composedRef = useComposedRefs(forwardedRef, popupRef, internalRef);\n\n // --- Positioning ---\n\n const posOpts = useMemo(() => ({ side: state.side, align: state.align }), [state.side, state.align]);\n\n // CSS Anchor Positioning — computed from state, no measurement needed.\n // `position-anchor` is set imperatively in the ref callback above\n // because React's style prop silently drops unrecognised CSS properties.\n const anchorStyle = useMemo(() => {\n if (!supportsAnchorPositioning()) return null;\n const { positionAnchor: _, ...rest } = getAnchorPositionStyle(anchorName, posOpts);\n return rest as CSSProperties;\n }, [anchorName, posOpts]);\n\n // Manual fallback — measure rects after layout, before paint.\n const [manualStyle, setManualStyle] = useState<CSSProperties | null>(null);\n\n useLayoutEffect(() => {\n if (supportsAnchorPositioning()) return;\n if (!state.open) {\n setManualStyle(null);\n return;\n }\n\n function measure(): void {\n const triggerEl = popover.triggerElement;\n const popupEl = internalRef.current;\n if (!triggerEl || !popupEl) return;\n\n const triggerRect = triggerEl.getBoundingClientRect();\n const popupRect = popupEl.getBoundingClientRect();\n const boundaryRect = document.documentElement.getBoundingClientRect();\n const offsets = resolveOffsets(popupEl);\n\n setManualStyle(\n getAnchorPositionStyle(anchorName, posOpts, triggerRect, popupRect, boundaryRect, offsets) as CSSProperties\n );\n }\n\n measure();\n\n // Recompute on scroll/resize so the popover tracks its trigger.\n let rafId = 0;\n function reposition(): void {\n cancelAnimationFrame(rafId);\n rafId = requestAnimationFrame(measure);\n }\n\n window.addEventListener('scroll', reposition, { capture: true, passive: true });\n window.addEventListener('resize', reposition);\n\n return () => {\n cancelAnimationFrame(rafId);\n window.removeEventListener('scroll', reposition, true);\n window.removeEventListener('resize', reposition);\n };\n }, [state.open, anchorName, posOpts, popover]);\n\n // Anchor path uses computed styles; manual path uses measured styles;\n // fallback resets UA [popover] defaults until positioning is computed.\n const positioningStyle = anchorStyle ?? manualStyle ?? POPOVER_RESET;\n\n // --- Visibility ---\n\n if (!state.open) {\n return null;\n }\n\n // Remap DOM focus events to React synthetic event names.\n const { onFocusOut, ...restPopupProps } = popover.popupProps;\n\n return renderElement(\n 'div',\n { render, className, style },\n {\n state,\n stateAttrMap,\n ref: composedRef,\n props: [\n {\n id: popupId,\n style: positioningStyle,\n ...core.getPopupAttrs(state),\n },\n { ...restPopupProps, onBlur: onFocusOut },\n elementProps,\n ],\n }\n );\n});\n\nexport namespace PopoverPopup {\n export type Props = PopoverPopupProps;\n export type State = PopoverState;\n}\n"],"mappings":";;;;;;;;;;AAeA,MAAM,gBAA+B;CAAE,UAAU;CAAS,OAAO;CAAQ,QAAQ;CAAG;;AAGpF,MAAa,eAAe,WAA8C,SAAS,aACjF,EAAE,QAAQ,WAAW,OAAO,GAAG,gBAC/B,cACA;CACA,MAAM,EAAE,MAAM,SAAS,OAAO,cAAc,YAAY,YAAY,mBAAmB;CACvF,MAAM,cAAc,OAAuB,KAAK;CAYhD,MAAM,cAAc,gBAAgB,cAVnB,aACd,OAA8B;AAC7B,UAAQ,gBAAgB,GAAG;AAC3B,MAAI,MAAM,2BAA2B,CACnC,IAAG,MAAM,YAAY,mBAAmB,KAAK,aAAa;IAG9D,CAAC,SAAS,WAAW,CACtB,EAE2D,YAAY;CAIxE,MAAM,UAAU,eAAe;EAAE,MAAM,MAAM;EAAM,OAAO,MAAM;EAAO,GAAG,CAAC,MAAM,MAAM,MAAM,MAAM,CAAC;CAKpG,MAAM,cAAc,cAAc;AAChC,MAAI,CAAC,2BAA2B,CAAE,QAAO;EACzC,MAAM,EAAE,gBAAgB,GAAG,GAAG,SAAS,uBAAuB,YAAY,QAAQ;AAClF,SAAO;IACN,CAAC,YAAY,QAAQ,CAAC;CAGzB,MAAM,CAAC,aAAa,kBAAkB,SAA+B,KAAK;AAE1E,uBAAsB;AACpB,MAAI,2BAA2B,CAAE;AACjC,MAAI,CAAC,MAAM,MAAM;AACf,kBAAe,KAAK;AACpB;;EAGF,SAAS,UAAgB;GACvB,MAAM,YAAY,QAAQ;GAC1B,MAAM,UAAU,YAAY;AAC5B,OAAI,CAAC,aAAa,CAAC,QAAS;AAO5B,kBACE,uBAAuB,YAAY,SANjB,UAAU,uBAAuB,EACnC,QAAQ,uBAAuB,EAC5B,SAAS,gBAAgB,uBAAuB,EACrD,eAAe,QAAQ,CAGqD,CAC3F;;AAGH,WAAS;EAGT,IAAI,QAAQ;EACZ,SAAS,aAAmB;AAC1B,wBAAqB,MAAM;AAC3B,WAAQ,sBAAsB,QAAQ;;AAGxC,SAAO,iBAAiB,UAAU,YAAY;GAAE,SAAS;GAAM,SAAS;GAAM,CAAC;AAC/E,SAAO,iBAAiB,UAAU,WAAW;AAE7C,eAAa;AACX,wBAAqB,MAAM;AAC3B,UAAO,oBAAoB,UAAU,YAAY,KAAK;AACtD,UAAO,oBAAoB,UAAU,WAAW;;IAEjD;EAAC,MAAM;EAAM;EAAY;EAAS;EAAQ,CAAC;CAI9C,MAAM,mBAAmB,eAAe,eAAe;AAIvD,KAAI,CAAC,MAAM,KACT,QAAO;CAIT,MAAM,EAAE,YAAY,GAAG,mBAAmB,QAAQ;AAElD,QAAO,cACL,OACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA;EACA,KAAK;EACL,OAAO;GACL;IACE,IAAI;IACJ,OAAO;IACP,GAAG,KAAK,cAAc,MAAM;IAC7B;GACD;IAAE,GAAG;IAAgB,QAAQ;IAAY;GACzC;GACD;EACF,CACF;EACD"}
@@ -1,8 +1,9 @@
1
1
  'use client';
2
2
 
3
+ import { useDestroy } from "../../utils/use-destroy.js";
3
4
  import { useLatestRef } from "../../utils/use-latest-ref.js";
4
- import { PopoverContextProvider } from "./context.js";
5
5
  import { useSafeId } from "../../utils/use-safe-id.js";
6
+ import { PopoverContextProvider } from "./context.js";
6
7
  import { createPopover, createTransition } from "@videojs/core/dom";
7
8
  import { useSnapshot } from "@videojs/store/react";
8
9
  import { useEffect, useState } from "react";
@@ -48,7 +49,7 @@ function PopoverRoot({ open: controlledOpen, defaultOpen = PopoverCore.defaultPr
48
49
  if (controlledOpen) popover.open("click");
49
50
  else popover.close("click");
50
51
  }, [controlledOpen, popover]);
51
- useEffect(() => () => popover.destroy(), [popover]);
52
+ useDestroy(popover);
52
53
  const input = useSnapshot(popover.input);
53
54
  core.setInput(input);
54
55
  return /* @__PURE__ */ jsx(PopoverContextProvider, {
@@ -1 +1 @@
1
- {"version":3,"file":"popover-root.js","names":[],"sources":["../../../../src/ui/popover/popover-root.tsx"],"sourcesContent":["'use client';\n\nimport { type PopoverProps as CorePopoverProps, PopoverCore, PopoverDataAttrs } from '@videojs/core';\nimport { createPopover, createTransition, type PopoverChangeDetails } from '@videojs/core/dom';\nimport { useSnapshot } from '@videojs/store/react';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { useLatestRef } from '../../utils/use-latest-ref';\nimport { useSafeId } from '../../utils/use-safe-id';\nimport { PopoverContextProvider } from './context';\n\nexport interface PopoverRootProps extends CorePopoverProps {\n /** Called when the popover open state changes (fires immediately, before animations). */\n onOpenChange?: (open: boolean, details: PopoverChangeDetails) => void;\n /** Called after open/close animations complete. */\n onOpenChangeComplete?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function PopoverRoot({\n open: controlledOpen,\n defaultOpen = PopoverCore.defaultProps.defaultOpen,\n onOpenChange: onOpenChangeProp,\n onOpenChangeComplete: onOpenChangeCompleteProp,\n openOnHover = PopoverCore.defaultProps.openOnHover,\n delay = PopoverCore.defaultProps.delay,\n closeDelay = PopoverCore.defaultProps.closeDelay,\n children,\n ...coreProps\n}: PopoverRootProps): ReactNode {\n const [core] = useState(() => new PopoverCore(coreProps));\n core.setProps(coreProps);\n\n const isControlled = controlledOpen !== undefined;\n\n // Keep refs that always point to the latest values so the\n // createPopover closure never reads stale props.\n const onOpenChangeRef = useLatestRef(onOpenChangeProp);\n const onOpenChangeCompleteRef = useLatestRef(onOpenChangeCompleteProp);\n const closeOnEscapeRef = useLatestRef(coreProps.closeOnEscape);\n const closeOnOutsideClickRef = useLatestRef(coreProps.closeOnOutsideClick);\n const openOnHoverRef = useLatestRef(openOnHover);\n const delayRef = useLatestRef(delay);\n const closeDelayRef = useLatestRef(closeDelay);\n\n const [popover] = useState(() => {\n const instance = createPopover({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean, details: PopoverChangeDetails) => {\n onOpenChangeRef.current?.(nextOpen, details);\n },\n onOpenChangeComplete: (nextOpen: boolean) => {\n onOpenChangeCompleteRef.current?.(nextOpen);\n },\n closeOnEscape: () => closeOnEscapeRef.current ?? PopoverCore.defaultProps.closeOnEscape,\n closeOnOutsideClick: () => closeOnOutsideClickRef.current ?? PopoverCore.defaultProps.closeOnOutsideClick,\n openOnHover: () => openOnHoverRef.current,\n delay: () => delayRef.current,\n closeDelay: () => closeDelayRef.current,\n });\n\n // Apply defaultOpen on creation (uncontrolled only)\n if (!isControlled && defaultOpen) {\n instance.open('click');\n }\n\n return instance;\n });\n\n const anchorName = useSafeId();\n const popupId = useSafeId('popup-');\n\n // Sync controlled open prop -> internal input state.\n useEffect(() => {\n if (controlledOpen === undefined) return;\n\n const { active: inputOpen } = popover.input.current;\n if (controlledOpen === inputOpen) return;\n\n if (controlledOpen) {\n popover.open('click');\n } else {\n popover.close('click');\n }\n }, [controlledOpen, popover]);\n\n // Cleanup on unmount\n useEffect(() => () => popover.destroy(), [popover]);\n\n const input = useSnapshot(popover.input);\n core.setInput(input);\n const state = core.getState();\n\n return (\n <PopoverContextProvider value={{ core, popover, state, stateAttrMap: PopoverDataAttrs, anchorName, popupId }}>\n {children}\n </PopoverContextProvider>\n );\n}\n\nexport namespace PopoverRoot {\n export type Props = PopoverRootProps;\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,SAAgB,YAAY,EAC1B,MAAM,gBACN,cAAc,YAAY,aAAa,aACvC,cAAc,kBACd,sBAAsB,0BACtB,cAAc,YAAY,aAAa,aACvC,QAAQ,YAAY,aAAa,OACjC,aAAa,YAAY,aAAa,YACtC,UACA,GAAG,aAC2B;CAC9B,MAAM,CAAC,QAAQ,eAAe,IAAI,YAAY,UAAU,CAAC;AACzD,MAAK,SAAS,UAAU;CAExB,MAAM,eAAe,mBAAmB;CAIxC,MAAM,kBAAkB,aAAa,iBAAiB;CACtD,MAAM,0BAA0B,aAAa,yBAAyB;CACtE,MAAM,mBAAmB,aAAa,UAAU,cAAc;CAC9D,MAAM,yBAAyB,aAAa,UAAU,oBAAoB;CAC1E,MAAM,iBAAiB,aAAa,YAAY;CAChD,MAAM,WAAW,aAAa,MAAM;CACpC,MAAM,gBAAgB,aAAa,WAAW;CAE9C,MAAM,CAAC,WAAW,eAAe;EAC/B,MAAM,WAAW,cAAc;GAC7B,YAAY,kBAAkB;GAC9B,eAAe,UAAmB,YAAkC;AAClE,oBAAgB,UAAU,UAAU,QAAQ;;GAE9C,uBAAuB,aAAsB;AAC3C,4BAAwB,UAAU,SAAS;;GAE7C,qBAAqB,iBAAiB,WAAW,YAAY,aAAa;GAC1E,2BAA2B,uBAAuB,WAAW,YAAY,aAAa;GACtF,mBAAmB,eAAe;GAClC,aAAa,SAAS;GACtB,kBAAkB,cAAc;GACjC,CAAC;AAGF,MAAI,CAAC,gBAAgB,YACnB,UAAS,KAAK,QAAQ;AAGxB,SAAO;GACP;CAEF,MAAM,aAAa,WAAW;CAC9B,MAAM,UAAU,UAAU,SAAS;AAGnC,iBAAgB;AACd,MAAI,mBAAmB,OAAW;EAElC,MAAM,EAAE,QAAQ,cAAc,QAAQ,MAAM;AAC5C,MAAI,mBAAmB,UAAW;AAElC,MAAI,eACF,SAAQ,KAAK,QAAQ;MAErB,SAAQ,MAAM,QAAQ;IAEvB,CAAC,gBAAgB,QAAQ,CAAC;AAG7B,uBAAsB,QAAQ,SAAS,EAAE,CAAC,QAAQ,CAAC;CAEnD,MAAM,QAAQ,YAAY,QAAQ,MAAM;AACxC,MAAK,SAAS,MAAM;AAGpB,QACE,oBAAC;EAAuB,OAAO;GAAE;GAAM;GAAS,OAHpC,KAAK,UAAU;GAG4B,cAAc;GAAkB;GAAY;GAAS;EACzG;GACsB"}
1
+ {"version":3,"file":"popover-root.js","names":[],"sources":["../../../../src/ui/popover/popover-root.tsx"],"sourcesContent":["'use client';\n\nimport { type PopoverProps as CorePopoverProps, PopoverCore, PopoverDataAttrs } from '@videojs/core';\nimport { createPopover, createTransition, type PopoverChangeDetails } from '@videojs/core/dom';\nimport { useSnapshot } from '@videojs/store/react';\nimport type { ReactNode } from 'react';\nimport { useEffect, useState } from 'react';\n\nimport { useDestroy } from '../../utils/use-destroy';\nimport { useLatestRef } from '../../utils/use-latest-ref';\nimport { useSafeId } from '../../utils/use-safe-id';\nimport { PopoverContextProvider } from './context';\n\nexport interface PopoverRootProps extends CorePopoverProps {\n /** Called when the popover open state changes (fires immediately, before animations). */\n onOpenChange?: (open: boolean, details: PopoverChangeDetails) => void;\n /** Called after open/close animations complete. */\n onOpenChangeComplete?: (open: boolean) => void;\n children?: ReactNode;\n}\n\nexport function PopoverRoot({\n open: controlledOpen,\n defaultOpen = PopoverCore.defaultProps.defaultOpen,\n onOpenChange: onOpenChangeProp,\n onOpenChangeComplete: onOpenChangeCompleteProp,\n openOnHover = PopoverCore.defaultProps.openOnHover,\n delay = PopoverCore.defaultProps.delay,\n closeDelay = PopoverCore.defaultProps.closeDelay,\n children,\n ...coreProps\n}: PopoverRootProps): ReactNode {\n const [core] = useState(() => new PopoverCore(coreProps));\n core.setProps(coreProps);\n\n const isControlled = controlledOpen !== undefined;\n\n // Keep refs that always point to the latest values so the\n // createPopover closure never reads stale props.\n const onOpenChangeRef = useLatestRef(onOpenChangeProp);\n const onOpenChangeCompleteRef = useLatestRef(onOpenChangeCompleteProp);\n const closeOnEscapeRef = useLatestRef(coreProps.closeOnEscape);\n const closeOnOutsideClickRef = useLatestRef(coreProps.closeOnOutsideClick);\n const openOnHoverRef = useLatestRef(openOnHover);\n const delayRef = useLatestRef(delay);\n const closeDelayRef = useLatestRef(closeDelay);\n\n const [popover] = useState(() => {\n const instance = createPopover({\n transition: createTransition(),\n onOpenChange: (nextOpen: boolean, details: PopoverChangeDetails) => {\n onOpenChangeRef.current?.(nextOpen, details);\n },\n onOpenChangeComplete: (nextOpen: boolean) => {\n onOpenChangeCompleteRef.current?.(nextOpen);\n },\n closeOnEscape: () => closeOnEscapeRef.current ?? PopoverCore.defaultProps.closeOnEscape,\n closeOnOutsideClick: () => closeOnOutsideClickRef.current ?? PopoverCore.defaultProps.closeOnOutsideClick,\n openOnHover: () => openOnHoverRef.current,\n delay: () => delayRef.current,\n closeDelay: () => closeDelayRef.current,\n });\n\n // Apply defaultOpen on creation (uncontrolled only)\n if (!isControlled && defaultOpen) {\n instance.open('click');\n }\n\n return instance;\n });\n\n const anchorName = useSafeId();\n const popupId = useSafeId('popup-');\n\n // Sync controlled open prop -> internal input state.\n useEffect(() => {\n if (controlledOpen === undefined) return;\n\n const { active: inputOpen } = popover.input.current;\n if (controlledOpen === inputOpen) return;\n\n if (controlledOpen) {\n popover.open('click');\n } else {\n popover.close('click');\n }\n }, [controlledOpen, popover]);\n\n useDestroy(popover);\n\n const input = useSnapshot(popover.input);\n core.setInput(input);\n const state = core.getState();\n\n return (\n <PopoverContextProvider value={{ core, popover, state, stateAttrMap: PopoverDataAttrs, anchorName, popupId }}>\n {children}\n </PopoverContextProvider>\n );\n}\n\nexport namespace PopoverRoot {\n export type Props = PopoverRootProps;\n}\n"],"mappings":";;;;;;;;;;;;;AAqBA,SAAgB,YAAY,EAC1B,MAAM,gBACN,cAAc,YAAY,aAAa,aACvC,cAAc,kBACd,sBAAsB,0BACtB,cAAc,YAAY,aAAa,aACvC,QAAQ,YAAY,aAAa,OACjC,aAAa,YAAY,aAAa,YACtC,UACA,GAAG,aAC2B;CAC9B,MAAM,CAAC,QAAQ,eAAe,IAAI,YAAY,UAAU,CAAC;AACzD,MAAK,SAAS,UAAU;CAExB,MAAM,eAAe,mBAAmB;CAIxC,MAAM,kBAAkB,aAAa,iBAAiB;CACtD,MAAM,0BAA0B,aAAa,yBAAyB;CACtE,MAAM,mBAAmB,aAAa,UAAU,cAAc;CAC9D,MAAM,yBAAyB,aAAa,UAAU,oBAAoB;CAC1E,MAAM,iBAAiB,aAAa,YAAY;CAChD,MAAM,WAAW,aAAa,MAAM;CACpC,MAAM,gBAAgB,aAAa,WAAW;CAE9C,MAAM,CAAC,WAAW,eAAe;EAC/B,MAAM,WAAW,cAAc;GAC7B,YAAY,kBAAkB;GAC9B,eAAe,UAAmB,YAAkC;AAClE,oBAAgB,UAAU,UAAU,QAAQ;;GAE9C,uBAAuB,aAAsB;AAC3C,4BAAwB,UAAU,SAAS;;GAE7C,qBAAqB,iBAAiB,WAAW,YAAY,aAAa;GAC1E,2BAA2B,uBAAuB,WAAW,YAAY,aAAa;GACtF,mBAAmB,eAAe;GAClC,aAAa,SAAS;GACtB,kBAAkB,cAAc;GACjC,CAAC;AAGF,MAAI,CAAC,gBAAgB,YACnB,UAAS,KAAK,QAAQ;AAGxB,SAAO;GACP;CAEF,MAAM,aAAa,WAAW;CAC9B,MAAM,UAAU,UAAU,SAAS;AAGnC,iBAAgB;AACd,MAAI,mBAAmB,OAAW;EAElC,MAAM,EAAE,QAAQ,cAAc,QAAQ,MAAM;AAC5C,MAAI,mBAAmB,UAAW;AAElC,MAAI,eACF,SAAQ,KAAK,QAAQ;MAErB,SAAQ,MAAM,QAAQ;IAEvB,CAAC,gBAAgB,QAAQ,CAAC;AAE7B,YAAW,QAAQ;CAEnB,MAAM,QAAQ,YAAY,QAAQ,MAAM;AACxC,MAAK,SAAS,MAAM;AAGpB,QACE,oBAAC;EAAuB,OAAO;GAAE;GAAM;GAAS,OAHpC,KAAK,UAAU;GAG4B,cAAc;GAAkB;GAAY;GAAS;EACzG;GACsB"}
@@ -2,8 +2,8 @@
2
2
 
3
3
  import { renderElement } from "../../utils/use-render.js";
4
4
  import { usePopoverContext } from "./context.js";
5
- import { getAnchorNameStyle } from "@videojs/core/dom";
6
- import { forwardRef, useCallback, useMemo } from "react";
5
+ import { forwardRef, useCallback } from "react";
6
+ import { supportsAnchorPositioning } from "@videojs/utils/dom";
7
7
 
8
8
  //#region src/ui/popover/popover-trigger.tsx
9
9
  /** Button that toggles the popover visibility. Renders a `<button>` element. */
@@ -11,8 +11,8 @@ const PopoverTrigger = forwardRef(function PopoverTrigger({ render, className, s
11
11
  const { core, popover, state, stateAttrMap, anchorName, popupId } = usePopoverContext();
12
12
  const triggerRef = useCallback((el) => {
13
13
  popover.setTriggerElement(el);
14
- }, [popover]);
15
- const anchorStyle = useMemo(() => getAnchorNameStyle(anchorName), [anchorName]);
14
+ if (el && supportsAnchorPositioning()) el.style.setProperty("anchor-name", `--${anchorName}`);
15
+ }, [popover, anchorName]);
16
16
  const { onFocusIn, onFocusOut, ...restTriggerProps } = popover.triggerProps;
17
17
  return renderElement("button", {
18
18
  render,
@@ -25,7 +25,6 @@ const PopoverTrigger = forwardRef(function PopoverTrigger({ render, className, s
25
25
  props: [
26
26
  {
27
27
  type: "button",
28
- style: anchorStyle,
29
28
  ...core.getTriggerAttrs(state, popupId)
30
29
  },
31
30
  {
@@ -1 +1 @@
1
- {"version":3,"file":"popover-trigger.js","names":[],"sources":["../../../../src/ui/popover/popover-trigger.tsx"],"sourcesContent":["'use client';\n\nimport type { PopoverState } from '@videojs/core';\nimport { getAnchorNameStyle } from '@videojs/core/dom';\nimport { forwardRef, useCallback, useMemo } from 'react';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\nimport { usePopoverContext } from './context';\n\nexport interface PopoverTriggerProps extends UIComponentProps<'button', PopoverState> {}\n\n/** Button that toggles the popover visibility. Renders a `<button>` element. */\nexport const PopoverTrigger = forwardRef<HTMLButtonElement, PopoverTriggerProps>(function PopoverTrigger(\n { render, className, style, ...elementProps },\n forwardedRef\n) {\n const { core, popover, state, stateAttrMap, anchorName, popupId } = usePopoverContext();\n\n const triggerRef = useCallback(\n (el: HTMLButtonElement | null) => {\n popover.setTriggerElement(el);\n },\n [popover]\n );\n\n const anchorStyle = useMemo(() => getAnchorNameStyle(anchorName), [anchorName]);\n\n // Remap DOM focus events to React synthetic event names.\n // createPopover() uses onFocusIn/onFocusOut (matching DOM focusin/focusout),\n // but React maps those to onFocus/onBlur.\n const { onFocusIn, onFocusOut, ...restTriggerProps } = popover.triggerProps;\n\n return renderElement(\n 'button',\n { render, className, style },\n {\n state,\n stateAttrMap,\n ref: [forwardedRef, triggerRef],\n props: [\n {\n type: 'button' as const,\n style: anchorStyle,\n ...core.getTriggerAttrs(state, popupId),\n },\n { ...restTriggerProps, onFocus: onFocusIn, onBlur: onFocusOut },\n elementProps,\n ],\n }\n );\n});\n\nexport namespace PopoverTrigger {\n export type Props = PopoverTriggerProps;\n export type State = PopoverState;\n}\n"],"mappings":";;;;;;;;;AAaA,MAAa,iBAAiB,WAAmD,SAAS,eACxF,EAAE,QAAQ,WAAW,OAAO,GAAG,gBAC/B,cACA;CACA,MAAM,EAAE,MAAM,SAAS,OAAO,cAAc,YAAY,YAAY,mBAAmB;CAEvF,MAAM,aAAa,aAChB,OAAiC;AAChC,UAAQ,kBAAkB,GAAG;IAE/B,CAAC,QAAQ,CACV;CAED,MAAM,cAAc,cAAc,mBAAmB,WAAW,EAAE,CAAC,WAAW,CAAC;CAK/E,MAAM,EAAE,WAAW,YAAY,GAAG,qBAAqB,QAAQ;AAE/D,QAAO,cACL,UACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA;EACA,KAAK,CAAC,cAAc,WAAW;EAC/B,OAAO;GACL;IACE,MAAM;IACN,OAAO;IACP,GAAG,KAAK,gBAAgB,OAAO,QAAQ;IACxC;GACD;IAAE,GAAG;IAAkB,SAAS;IAAW,QAAQ;IAAY;GAC/D;GACD;EACF,CACF;EACD"}
1
+ {"version":3,"file":"popover-trigger.js","names":[],"sources":["../../../../src/ui/popover/popover-trigger.tsx"],"sourcesContent":["'use client';\n\nimport type { PopoverState } from '@videojs/core';\nimport { supportsAnchorPositioning } from '@videojs/utils/dom';\nimport { forwardRef, useCallback } from 'react';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\nimport { usePopoverContext } from './context';\n\nexport interface PopoverTriggerProps extends UIComponentProps<'button', PopoverState> {}\n\n/** Button that toggles the popover visibility. Renders a `<button>` element. */\nexport const PopoverTrigger = forwardRef<HTMLButtonElement, PopoverTriggerProps>(function PopoverTrigger(\n { render, className, style, ...elementProps },\n forwardedRef\n) {\n const { core, popover, state, stateAttrMap, anchorName, popupId } = usePopoverContext();\n\n const triggerRef = useCallback(\n (el: HTMLButtonElement | null) => {\n popover.setTriggerElement(el);\n if (el && supportsAnchorPositioning()) {\n el.style.setProperty('anchor-name', `--${anchorName}`);\n }\n },\n [popover, anchorName]\n );\n\n // Remap DOM focus events to React synthetic event names.\n // createPopover() uses onFocusIn/onFocusOut (matching DOM focusin/focusout),\n // but React maps those to onFocus/onBlur.\n const { onFocusIn, onFocusOut, ...restTriggerProps } = popover.triggerProps;\n\n return renderElement(\n 'button',\n { render, className, style },\n {\n state,\n stateAttrMap,\n ref: [forwardedRef, triggerRef],\n props: [\n {\n type: 'button' as const,\n ...core.getTriggerAttrs(state, popupId),\n },\n { ...restTriggerProps, onFocus: onFocusIn, onBlur: onFocusOut },\n elementProps,\n ],\n }\n );\n});\n\nexport namespace PopoverTrigger {\n export type Props = PopoverTriggerProps;\n export type State = PopoverState;\n}\n"],"mappings":";;;;;;;;;AAaA,MAAa,iBAAiB,WAAmD,SAAS,eACxF,EAAE,QAAQ,WAAW,OAAO,GAAG,gBAC/B,cACA;CACA,MAAM,EAAE,MAAM,SAAS,OAAO,cAAc,YAAY,YAAY,mBAAmB;CAEvF,MAAM,aAAa,aAChB,OAAiC;AAChC,UAAQ,kBAAkB,GAAG;AAC7B,MAAI,MAAM,2BAA2B,CACnC,IAAG,MAAM,YAAY,eAAe,KAAK,aAAa;IAG1D,CAAC,SAAS,WAAW,CACtB;CAKD,MAAM,EAAE,WAAW,YAAY,GAAG,qBAAqB,QAAQ;AAE/D,QAAO,cACL,UACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA;EACA,KAAK,CAAC,cAAc,WAAW;EAC/B,OAAO;GACL;IACE,MAAM;IACN,GAAG,KAAK,gBAAgB,OAAO,QAAQ;IACxC;GACD;IAAE,GAAG;IAAkB,SAAS;IAAW,QAAQ;IAAY;GAC/D;GACD;EACF,CACF;EACD"}
@@ -1,8 +1,10 @@
1
1
  import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { SliderBuffer } from "./slider-buffer.js";
3
3
  import { SliderFill } from "./slider-fill.js";
4
+ import { SliderPreview } from "./slider-preview.js";
4
5
  import { SliderRoot } from "./slider-root.js";
5
6
  import { SliderThumb } from "./slider-thumb.js";
7
+ import { SliderThumbnail } from "./slider-thumbnail.js";
6
8
  import { SliderTrack } from "./slider-track.js";
7
9
  import { SliderValue } from "./slider-value.js";
8
10
 
@@ -10,8 +12,10 @@ import { SliderValue } from "./slider-value.js";
10
12
  var index_parts_exports = /* @__PURE__ */ __exportAll({
11
13
  Buffer: () => SliderBuffer,
12
14
  Fill: () => SliderFill,
15
+ Preview: () => SliderPreview,
13
16
  Root: () => SliderRoot,
14
17
  Thumb: () => SliderThumb,
18
+ Thumbnail: () => SliderThumbnail,
15
19
  Track: () => SliderTrack,
16
20
  Value: () => SliderValue
17
21
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.parts.js","names":[],"sources":["../../../../src/ui/slider/index.parts.ts"],"sourcesContent":["export { SliderBuffer as Buffer, type SliderBufferProps as BufferProps } from './slider-buffer';\nexport { SliderFill as Fill, type SliderFillProps as FillProps } from './slider-fill';\nexport { SliderRoot as Root, type SliderRootProps as RootProps } from './slider-root';\nexport { SliderThumb as Thumb, type SliderThumbProps as ThumbProps } from './slider-thumb';\nexport { SliderTrack as Track, type SliderTrackProps as TrackProps } from './slider-track';\nexport { SliderValue as Value, type SliderValueProps as ValueProps } from './slider-value';\n"],"mappings":""}
1
+ {"version":3,"file":"index.parts.js","names":[],"sources":["../../../../src/ui/slider/index.parts.ts"],"sourcesContent":["export { SliderBuffer as Buffer, type SliderBufferProps as BufferProps } from './slider-buffer';\nexport { SliderFill as Fill, type SliderFillProps as FillProps } from './slider-fill';\nexport { SliderPreview as Preview, type SliderPreviewProps as PreviewProps } from './slider-preview';\nexport { SliderRoot as Root, type SliderRootProps as RootProps } from './slider-root';\nexport { SliderThumb as Thumb, type SliderThumbProps as ThumbProps } from './slider-thumb';\nexport { SliderThumbnail as Thumbnail, type SliderThumbnailProps as ThumbnailProps } from './slider-thumbnail';\nexport { SliderTrack as Track, type SliderTrackProps as TrackProps } from './slider-track';\nexport { SliderValue as Value, type SliderValueProps as ValueProps } from './slider-value';\n"],"mappings":""}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+
3
+ import { renderElement } from "../../utils/use-render.js";
4
+ import { useSliderContext } from "./context.js";
5
+ import { getSliderPreviewStyle } from "@videojs/core/dom";
6
+ import { forwardRef, useEffect, useRef, useState } from "react";
7
+
8
+ //#region src/ui/slider/slider-preview.tsx
9
+ /** Positioning container for preview content that tracks the pointer along the slider. */
10
+ const SliderPreview = forwardRef(function SliderPreview(componentProps, forwardedRef) {
11
+ const { render, className, style, overflow = "clamp", ...elementProps } = componentProps;
12
+ const context = useSliderContext();
13
+ const { state } = context;
14
+ const measureRef = useRef(null);
15
+ const [width, setWidth] = useState(0);
16
+ useEffect(() => {
17
+ const el = measureRef.current;
18
+ if (!el) return;
19
+ const observer = new ResizeObserver(([entry]) => {
20
+ setWidth(entry.contentRect.width);
21
+ });
22
+ observer.observe(el);
23
+ return () => observer.disconnect();
24
+ }, []);
25
+ const positionStyle = getSliderPreviewStyle(width, overflow);
26
+ return renderElement("div", {
27
+ render,
28
+ className,
29
+ style
30
+ }, {
31
+ state,
32
+ stateAttrMap: context.stateAttrMap,
33
+ ref: [forwardedRef, measureRef],
34
+ props: [{ style: positionStyle }, elementProps]
35
+ });
36
+ });
37
+
38
+ //#endregion
39
+ export { SliderPreview };
40
+ //# sourceMappingURL=slider-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider-preview.js","names":[],"sources":["../../../../src/ui/slider/slider-preview.tsx"],"sourcesContent":["'use client';\n\nimport type { SliderState } from '@videojs/core';\nimport type { SliderPreviewOverflow } from '@videojs/core/dom';\nimport { getSliderPreviewStyle } from '@videojs/core/dom';\nimport type { ForwardedRef } from 'react';\nimport { forwardRef, useEffect, useRef, useState } from 'react';\n\nimport type { UIComponentProps } from '../../utils/types';\nimport { renderElement } from '../../utils/use-render';\nimport { useSliderContext } from './context';\n\nexport interface SliderPreviewProps extends UIComponentProps<'div', SliderState> {\n /** How the preview handles the slider boundaries. `'clamp'` keeps the preview within bounds, `'visible'` allows it to extend beyond the edges. */\n overflow?: SliderPreviewOverflow | undefined;\n}\n\n/** Positioning container for preview content that tracks the pointer along the slider. */\nexport const SliderPreview = forwardRef(function SliderPreview(\n componentProps: SliderPreviewProps,\n forwardedRef: ForwardedRef<HTMLDivElement>\n) {\n const { render, className, style, overflow = 'clamp', ...elementProps } = componentProps;\n\n const context = useSliderContext();\n const { state } = context;\n\n const measureRef = useRef<HTMLDivElement>(null);\n const [width, setWidth] = useState(0);\n\n useEffect(() => {\n const el = measureRef.current;\n if (!el) return;\n\n const observer = new ResizeObserver(([entry]) => {\n setWidth(entry!.contentRect.width);\n });\n\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n const positionStyle = getSliderPreviewStyle(width, overflow);\n\n return renderElement(\n 'div',\n { render, className, style },\n {\n state,\n stateAttrMap: context.stateAttrMap,\n ref: [forwardedRef, measureRef],\n props: [{ style: positionStyle }, elementProps],\n }\n );\n});\n\nexport namespace SliderPreview {\n export type Props = SliderPreviewProps;\n}\n"],"mappings":";;;;;;;;;AAkBA,MAAa,gBAAgB,WAAW,SAAS,cAC/C,gBACA,cACA;CACA,MAAM,EAAE,QAAQ,WAAW,OAAO,WAAW,SAAS,GAAG,iBAAiB;CAE1E,MAAM,UAAU,kBAAkB;CAClC,MAAM,EAAE,UAAU;CAElB,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;AAErC,iBAAgB;EACd,MAAM,KAAK,WAAW;AACtB,MAAI,CAAC,GAAI;EAET,MAAM,WAAW,IAAI,gBAAgB,CAAC,WAAW;AAC/C,YAAS,MAAO,YAAY,MAAM;IAClC;AAEF,WAAS,QAAQ,GAAG;AACpB,eAAa,SAAS,YAAY;IACjC,EAAE,CAAC;CAEN,MAAM,gBAAgB,sBAAsB,OAAO,SAAS;AAE5D,QAAO,cACL,OACA;EAAE;EAAQ;EAAW;EAAO,EAC5B;EACE;EACA,cAAc,QAAQ;EACtB,KAAK,CAAC,cAAc,WAAW;EAC/B,OAAO,CAAC,EAAE,OAAO,eAAe,EAAE,aAAa;EAChD,CACF;EACD"}
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+
3
+ import { useSliderContext } from "./context.js";
4
+ import { Thumbnail } from "../thumbnail/thumbnail.js";
5
+ import { forwardRef } from "react";
6
+ import { jsx } from "react/jsx-runtime";
7
+
8
+ //#region src/ui/slider/slider-thumbnail.tsx
9
+ const SliderThumbnail = forwardRef(function SliderThumbnail(componentProps, forwardedRef) {
10
+ const { pointerValue } = useSliderContext();
11
+ return /* @__PURE__ */ jsx(Thumbnail, {
12
+ ref: forwardedRef,
13
+ ...componentProps,
14
+ time: pointerValue
15
+ });
16
+ });
17
+
18
+ //#endregion
19
+ export { SliderThumbnail };
20
+ //# sourceMappingURL=slider-thumbnail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider-thumbnail.js","names":[],"sources":["../../../../src/ui/slider/slider-thumbnail.tsx"],"sourcesContent":["'use client';\n\nimport type { ThumbnailCore } from '@videojs/core';\nimport { forwardRef } from 'react';\n\nimport { Thumbnail, type ThumbnailProps } from '../thumbnail/thumbnail';\nimport { useSliderContext } from './context';\n\nexport interface SliderThumbnailProps extends Omit<ThumbnailProps, 'time'> {}\n\nexport const SliderThumbnail = forwardRef<HTMLDivElement, SliderThumbnailProps>(\n function SliderThumbnail(componentProps, forwardedRef) {\n const { pointerValue } = useSliderContext();\n return <Thumbnail ref={forwardedRef} {...componentProps} time={pointerValue} />;\n }\n);\n\nexport namespace SliderThumbnail {\n export type Props = SliderThumbnailProps;\n export type State = ThumbnailCore.State;\n}\n"],"mappings":";;;;;;;;AAUA,MAAa,kBAAkB,WAC7B,SAAS,gBAAgB,gBAAgB,cAAc;CACrD,MAAM,EAAE,iBAAiB,kBAAkB;AAC3C,QAAO,oBAAC;EAAU,KAAK;EAAc,GAAI;EAAgB,MAAM;GAAgB;EAElF"}