@mieweb/ui 0.11.0-dev.44 → 0.11.0-dev.45

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 (183) hide show
  1. package/dist/ag-grid.cjs +2 -2
  2. package/dist/ag-grid.js +1 -1
  3. package/dist/{chunk-AHYDJN4H.cjs → chunk-2XHPPOXY.cjs} +32 -32
  4. package/dist/{chunk-AHYDJN4H.cjs.map → chunk-2XHPPOXY.cjs.map} +1 -1
  5. package/dist/{chunk-3IKIRGHI.cjs → chunk-3H6BQV2D.cjs} +6 -6
  6. package/dist/{chunk-3IKIRGHI.cjs.map → chunk-3H6BQV2D.cjs.map} +1 -1
  7. package/dist/{chunk-IIV5GNSK.cjs → chunk-3PT4B4JT.cjs} +4 -4
  8. package/dist/{chunk-IIV5GNSK.cjs.map → chunk-3PT4B4JT.cjs.map} +1 -1
  9. package/dist/{chunk-GLG6UE2H.cjs → chunk-3SEQVGLH.cjs} +4 -4
  10. package/dist/{chunk-GLG6UE2H.cjs.map → chunk-3SEQVGLH.cjs.map} +1 -1
  11. package/dist/{chunk-JUY2JLFL.js → chunk-3XDU7XIC.js} +3 -3
  12. package/dist/{chunk-JUY2JLFL.js.map → chunk-3XDU7XIC.js.map} +1 -1
  13. package/dist/{chunk-LQ22CY7X.js → chunk-46ZUORUE.js} +5 -5
  14. package/dist/{chunk-LQ22CY7X.js.map → chunk-46ZUORUE.js.map} +1 -1
  15. package/dist/{chunk-CKECOCYJ.js → chunk-4IOIDS2Z.js} +3 -3
  16. package/dist/{chunk-CKECOCYJ.js.map → chunk-4IOIDS2Z.js.map} +1 -1
  17. package/dist/{chunk-F7SZSOB3.js → chunk-6PCA5H47.js} +3 -3
  18. package/dist/{chunk-F7SZSOB3.js.map → chunk-6PCA5H47.js.map} +1 -1
  19. package/dist/{chunk-ULEX7OOJ.js → chunk-6Y6W5DUY.js} +4 -4
  20. package/dist/{chunk-ULEX7OOJ.js.map → chunk-6Y6W5DUY.js.map} +1 -1
  21. package/dist/{chunk-S7AMZ4RD.cjs → chunk-7K6SW4VB.cjs} +4 -4
  22. package/dist/{chunk-S7AMZ4RD.cjs.map → chunk-7K6SW4VB.cjs.map} +1 -1
  23. package/dist/{chunk-KY67AMQ5.cjs → chunk-7MF3O3BU.cjs} +4 -4
  24. package/dist/{chunk-KY67AMQ5.cjs.map → chunk-7MF3O3BU.cjs.map} +1 -1
  25. package/dist/{chunk-Z3WMDVMR.cjs → chunk-7QNBPB7F.cjs} +9 -5
  26. package/dist/chunk-7QNBPB7F.cjs.map +1 -0
  27. package/dist/{chunk-YFWDS6MX.js → chunk-AB24H2RM.js} +3 -3
  28. package/dist/{chunk-YFWDS6MX.js.map → chunk-AB24H2RM.js.map} +1 -1
  29. package/dist/{chunk-DIIXY6EB.js → chunk-AQBZEN43.js} +5 -5
  30. package/dist/{chunk-DIIXY6EB.js.map → chunk-AQBZEN43.js.map} +1 -1
  31. package/dist/{chunk-2W73UQ3T.js → chunk-BPYI7BDC.js} +3 -3
  32. package/dist/{chunk-2W73UQ3T.js.map → chunk-BPYI7BDC.js.map} +1 -1
  33. package/dist/{chunk-7U7SONM5.js → chunk-CVCUQ2MZ.js} +3 -3
  34. package/dist/{chunk-7U7SONM5.js.map → chunk-CVCUQ2MZ.js.map} +1 -1
  35. package/dist/{chunk-PWXDRFJL.cjs → chunk-DHEOWRIE.cjs} +6 -6
  36. package/dist/{chunk-PWXDRFJL.cjs.map → chunk-DHEOWRIE.cjs.map} +1 -1
  37. package/dist/{chunk-OYUIEJPN.js → chunk-GTRYDFMT.js} +38 -10
  38. package/dist/chunk-GTRYDFMT.js.map +1 -0
  39. package/dist/{chunk-2FZYZ4HT.cjs → chunk-HDSYYQYM.cjs} +4 -4
  40. package/dist/{chunk-2FZYZ4HT.cjs.map → chunk-HDSYYQYM.cjs.map} +1 -1
  41. package/dist/{chunk-HH7PWD5I.cjs → chunk-HOE2U27V.cjs} +21 -21
  42. package/dist/{chunk-HH7PWD5I.cjs.map → chunk-HOE2U27V.cjs.map} +1 -1
  43. package/dist/{chunk-JCIQIR5V.js → chunk-IGUDEWIW.js} +4 -4
  44. package/dist/{chunk-JCIQIR5V.js.map → chunk-IGUDEWIW.js.map} +1 -1
  45. package/dist/{chunk-2KK4WZ7Y.cjs → chunk-IKHK4GTF.cjs} +4 -4
  46. package/dist/{chunk-2KK4WZ7Y.cjs.map → chunk-IKHK4GTF.cjs.map} +1 -1
  47. package/dist/{chunk-YVKBXNPK.js → chunk-JBNQ2L3K.js} +10 -6
  48. package/dist/chunk-JBNQ2L3K.js.map +1 -0
  49. package/dist/{chunk-GU6TPVXF.cjs → chunk-JK2IWOI7.cjs} +6 -6
  50. package/dist/{chunk-GU6TPVXF.cjs.map → chunk-JK2IWOI7.cjs.map} +1 -1
  51. package/dist/{chunk-TZKBW4GA.cjs → chunk-K76UNS22.cjs} +6 -6
  52. package/dist/{chunk-TZKBW4GA.cjs.map → chunk-K76UNS22.cjs.map} +1 -1
  53. package/dist/{chunk-DAAJ3B2T.js → chunk-KP72MDFB.js} +4 -4
  54. package/dist/{chunk-DAAJ3B2T.js.map → chunk-KP72MDFB.js.map} +1 -1
  55. package/dist/{chunk-MLCIINXT.js → chunk-LBUXS6FJ.js} +4 -4
  56. package/dist/{chunk-MLCIINXT.js.map → chunk-LBUXS6FJ.js.map} +1 -1
  57. package/dist/{chunk-GG3IK5TL.cjs → chunk-MQK2D6I6.cjs} +9 -9
  58. package/dist/{chunk-GG3IK5TL.cjs.map → chunk-MQK2D6I6.cjs.map} +1 -1
  59. package/dist/{chunk-IPHJQ6CF.js → chunk-MQSGJB2B.js} +5 -5
  60. package/dist/{chunk-IPHJQ6CF.js.map → chunk-MQSGJB2B.js.map} +1 -1
  61. package/dist/{chunk-2GBVJHWN.cjs → chunk-NH5JOZLG.cjs} +13 -13
  62. package/dist/{chunk-2GBVJHWN.cjs.map → chunk-NH5JOZLG.cjs.map} +1 -1
  63. package/dist/{chunk-NWU634SO.cjs → chunk-O2EAHOXM.cjs} +4 -4
  64. package/dist/{chunk-NWU634SO.cjs.map → chunk-O2EAHOXM.cjs.map} +1 -1
  65. package/dist/{chunk-JUYBJLPI.cjs → chunk-O7Y56J4R.cjs} +4 -4
  66. package/dist/{chunk-JUYBJLPI.cjs.map → chunk-O7Y56J4R.cjs.map} +1 -1
  67. package/dist/{chunk-EAAVFTKI.cjs → chunk-OJ2NCQ2R.cjs} +14 -14
  68. package/dist/{chunk-EAAVFTKI.cjs.map → chunk-OJ2NCQ2R.cjs.map} +1 -1
  69. package/dist/{chunk-GLRKXJCR.js → chunk-OX32ITWC.js} +3 -3
  70. package/dist/{chunk-GLRKXJCR.js.map → chunk-OX32ITWC.js.map} +1 -1
  71. package/dist/{chunk-L4APW65W.cjs → chunk-PJ4XEBMU.cjs} +4 -4
  72. package/dist/{chunk-L4APW65W.cjs.map → chunk-PJ4XEBMU.cjs.map} +1 -1
  73. package/dist/{chunk-OZKJYLN6.js → chunk-PSCSU63K.js} +3 -3
  74. package/dist/{chunk-OZKJYLN6.js.map → chunk-PSCSU63K.js.map} +1 -1
  75. package/dist/{chunk-EI4JU5JF.js → chunk-RKM4VGAN.js} +3 -3
  76. package/dist/{chunk-EI4JU5JF.js.map → chunk-RKM4VGAN.js.map} +1 -1
  77. package/dist/{chunk-ME7EVT6F.js → chunk-RYGVILUR.js} +3 -3
  78. package/dist/{chunk-ME7EVT6F.js.map → chunk-RYGVILUR.js.map} +1 -1
  79. package/dist/{chunk-EGPDT7SM.js → chunk-S7NJV335.js} +3 -3
  80. package/dist/{chunk-EGPDT7SM.js.map → chunk-S7NJV335.js.map} +1 -1
  81. package/dist/{chunk-AHT2HRHC.cjs → chunk-TNRANQVI.cjs} +16 -16
  82. package/dist/{chunk-AHT2HRHC.cjs.map → chunk-TNRANQVI.cjs.map} +1 -1
  83. package/dist/{chunk-TERHGQ73.cjs → chunk-U7XWWU5H.cjs} +5 -5
  84. package/dist/{chunk-TERHGQ73.cjs.map → chunk-U7XWWU5H.cjs.map} +1 -1
  85. package/dist/{chunk-G35LXI2A.js → chunk-UIFN2LYT.js} +3 -3
  86. package/dist/{chunk-G35LXI2A.js.map → chunk-UIFN2LYT.js.map} +1 -1
  87. package/dist/{chunk-L3CAWGBU.js → chunk-UQAWXY6R.js} +3 -3
  88. package/dist/{chunk-L3CAWGBU.js.map → chunk-UQAWXY6R.js.map} +1 -1
  89. package/dist/{chunk-ZULFKL3C.js → chunk-VOPRL4RF.js} +7 -7
  90. package/dist/{chunk-ZULFKL3C.js.map → chunk-VOPRL4RF.js.map} +1 -1
  91. package/dist/{chunk-KB2PLV5Q.js → chunk-VQGRMCVT.js} +4 -4
  92. package/dist/{chunk-KB2PLV5Q.js.map → chunk-VQGRMCVT.js.map} +1 -1
  93. package/dist/{chunk-MD55WRGN.cjs → chunk-X6THHGTZ.cjs} +37 -37
  94. package/dist/{chunk-MD55WRGN.cjs.map → chunk-X6THHGTZ.cjs.map} +1 -1
  95. package/dist/{chunk-Q6QLGCL7.cjs → chunk-XCCH5KHW.cjs} +9 -9
  96. package/dist/{chunk-Q6QLGCL7.cjs.map → chunk-XCCH5KHW.cjs.map} +1 -1
  97. package/dist/{chunk-KQXD6BFO.cjs → chunk-XM3D4KAF.cjs} +9 -9
  98. package/dist/{chunk-KQXD6BFO.cjs.map → chunk-XM3D4KAF.cjs.map} +1 -1
  99. package/dist/{chunk-PINIBEIU.cjs → chunk-XRXOGMMG.cjs} +39 -11
  100. package/dist/chunk-XRXOGMMG.cjs.map +1 -0
  101. package/dist/{chunk-XPWFIDZM.cjs → chunk-XU3X2AUL.cjs} +4 -4
  102. package/dist/{chunk-XPWFIDZM.cjs.map → chunk-XU3X2AUL.cjs.map} +1 -1
  103. package/dist/{chunk-3A4N5E6P.js → chunk-XZ65FX6T.js} +3 -3
  104. package/dist/{chunk-3A4N5E6P.js.map → chunk-XZ65FX6T.js.map} +1 -1
  105. package/dist/{chunk-CRR7AE5D.js → chunk-Z6I4XFPC.js} +3 -3
  106. package/dist/{chunk-CRR7AE5D.js.map → chunk-Z6I4XFPC.js.map} +1 -1
  107. package/dist/{chunk-LTCHD3K5.cjs → chunk-Z7ZOSENN.cjs} +5 -5
  108. package/dist/{chunk-LTCHD3K5.cjs.map → chunk-Z7ZOSENN.cjs.map} +1 -1
  109. package/dist/{chunk-NZUQL42A.cjs → chunk-ZDA6FEKA.cjs} +5 -5
  110. package/dist/{chunk-NZUQL42A.cjs.map → chunk-ZDA6FEKA.cjs.map} +1 -1
  111. package/dist/{chunk-UY2EZYIC.js → chunk-ZSBG6C3P.js} +3 -3
  112. package/dist/{chunk-UY2EZYIC.js.map → chunk-ZSBG6C3P.js.map} +1 -1
  113. package/dist/{chunk-KAQNYX7B.js → chunk-ZVRJVUFX.js} +3 -3
  114. package/dist/{chunk-KAQNYX7B.js.map → chunk-ZVRJVUFX.js.map} +1 -1
  115. package/dist/components/AudioPlayer/index.cjs +7 -7
  116. package/dist/components/AudioPlayer/index.js +2 -2
  117. package/dist/components/BoardView/index.cjs +5 -5
  118. package/dist/components/BoardView/index.js +2 -2
  119. package/dist/components/CollabStatus/index.cjs +5 -5
  120. package/dist/components/CollabStatus/index.js +2 -2
  121. package/dist/components/Dropdown/index.cjs +9 -9
  122. package/dist/components/Dropdown/index.d.cts +6 -1
  123. package/dist/components/Dropdown/index.d.ts +6 -1
  124. package/dist/components/Dropdown/index.js +2 -2
  125. package/dist/components/EmailEditor/index.cjs +16 -16
  126. package/dist/components/EmailEditor/index.js +7 -7
  127. package/dist/components/MediaEditor/index.cjs +10 -10
  128. package/dist/components/MediaEditor/index.js +5 -5
  129. package/dist/components/MediaFeed/index.cjs +6 -6
  130. package/dist/components/MediaFeed/index.js +5 -5
  131. package/dist/components/MediaPlayer/index.cjs +8 -8
  132. package/dist/components/MediaPlayer/index.js +4 -4
  133. package/dist/components/MegaMenu/index.cjs +5 -5
  134. package/dist/components/MegaMenu/index.js +2 -2
  135. package/dist/components/RecordHeader/index.cjs +5 -5
  136. package/dist/components/RecordHeader/index.js +3 -3
  137. package/dist/components/RecordLayout/index.cjs +5 -5
  138. package/dist/components/RecordLayout/index.js +3 -3
  139. package/dist/components/RichTextEditor/index.cjs +6 -6
  140. package/dist/components/RichTextEditor/index.js +3 -3
  141. package/dist/components/Slider/index.cjs +6 -6
  142. package/dist/components/Slider/index.js +2 -2
  143. package/dist/components/SliderCalculator/index.cjs +5 -5
  144. package/dist/components/SliderCalculator/index.js +3 -3
  145. package/dist/components/SuperChat/index.cjs +23 -23
  146. package/dist/components/SuperChat/index.js +8 -8
  147. package/dist/components/SuperChat/plugins/index.cjs +5 -5
  148. package/dist/components/SuperChat/plugins/index.js +4 -4
  149. package/dist/components/Tabs/index.cjs +8 -8
  150. package/dist/components/Tabs/index.js +2 -2
  151. package/dist/components/Textarea/index.cjs +8 -8
  152. package/dist/components/Textarea/index.js +5 -5
  153. package/dist/components/ThemeProvider/index.cjs +9 -9
  154. package/dist/components/ThemeProvider/index.js +3 -3
  155. package/dist/components/Tooltip/index.cjs +3 -3
  156. package/dist/components/Tooltip/index.js +2 -2
  157. package/dist/components/ViewSet/index.cjs +5 -5
  158. package/dist/components/ViewSet/index.js +4 -4
  159. package/dist/components/ViewSwitcher/index.cjs +4 -4
  160. package/dist/components/ViewSwitcher/index.js +2 -2
  161. package/dist/deck.cjs +3 -3
  162. package/dist/deck.js +1 -1
  163. package/dist/esheet.cjs +107 -107
  164. package/dist/esheet.js +10 -10
  165. package/dist/hooks/index.cjs +5 -5
  166. package/dist/hooks/index.js +1 -1
  167. package/dist/index.cjs +284 -284
  168. package/dist/index.d.cts +6 -1
  169. package/dist/index.d.ts +6 -1
  170. package/dist/index.js +40 -40
  171. package/dist/kerebron.cjs +6 -6
  172. package/dist/kerebron.js +4 -4
  173. package/dist/{model-5PB6KNYH.cjs → model-2TISYEYF.cjs} +20 -20
  174. package/dist/{model-5PB6KNYH.cjs.map → model-2TISYEYF.cjs.map} +1 -1
  175. package/dist/{model-OGWTZEXR.js → model-BCS5BUK3.js} +6 -6
  176. package/dist/{model-OGWTZEXR.js.map → model-BCS5BUK3.js.map} +1 -1
  177. package/dist/org-chart.cjs +2 -2
  178. package/dist/org-chart.js +1 -1
  179. package/package.json +1 -1
  180. package/dist/chunk-OYUIEJPN.js.map +0 -1
  181. package/dist/chunk-PINIBEIU.cjs.map +0 -1
  182. package/dist/chunk-YVKBXNPK.js.map +0 -1
  183. package/dist/chunk-Z3WMDVMR.cjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkNZUQL42A_cjs = require('./chunk-NZUQL42A.cjs');
4
- var chunkLTCHD3K5_cjs = require('./chunk-LTCHD3K5.cjs');
3
+ var chunkZDA6FEKA_cjs = require('./chunk-ZDA6FEKA.cjs');
4
+ var chunkZ7ZOSENN_cjs = require('./chunk-Z7ZOSENN.cjs');
5
5
  var chunkHDZQLTBP_cjs = require('./chunk-HDZQLTBP.cjs');
6
6
  var chunkFSARTLUE_cjs = require('./chunk-FSARTLUE.cjs');
7
7
  var chunkS5RVSXDV_cjs = require('./chunk-S5RVSXDV.cjs');
@@ -97,7 +97,7 @@ var SEEK_STEP_MS = 100;
97
97
  var KEYBOARD_SEEK_FRACTION = 0.02;
98
98
  var CUE_LINE_HEIGHT_FRACTION = 0.05;
99
99
  var DEFAULT_CUE_LINE = -4;
100
- var formatMs = (ms) => chunkLTCHD3K5_cjs.formatTime(ms / 1e3);
100
+ var formatMs = (ms) => chunkZ7ZOSENN_cjs.formatTime(ms / 1e3);
101
101
  function cueLineAboveBar(video, bar) {
102
102
  const lineHeight = video.getBoundingClientRect().height * CUE_LINE_HEIGHT_FRACTION;
103
103
  if (!bar || lineHeight <= 0) return DEFAULT_CUE_LINE;
@@ -327,7 +327,7 @@ var MediaControls = React__namespace.forwardRef(function MediaControls2({
327
327
  }
328
328
  ),
329
329
  /* @__PURE__ */ jsxRuntime.jsx(
330
- chunkNZUQL42A_cjs.Slider,
330
+ chunkZDA6FEKA_cjs.Slider,
331
331
  {
332
332
  className: "mx-1 min-w-0 flex-1 @max-md:order-first @max-md:mx-2 @max-md:basis-full pointer-coarse:[&_[data-slot=slider-track-wrapper]]:py-4",
333
333
  trackClassName: "bg-white/30 dark:bg-white/30",
@@ -574,5 +574,5 @@ exports.mediaPlayerVariants = mediaPlayerVariants;
574
574
  exports.overlayButtonClass = overlayButtonClass;
575
575
  exports.playBadgeClass = playBadgeClass;
576
576
  exports.playBadgeIconClass = playBadgeIconClass;
577
- //# sourceMappingURL=chunk-TZKBW4GA.cjs.map
578
- //# sourceMappingURL=chunk-TZKBW4GA.cjs.map
577
+ //# sourceMappingURL=chunk-K76UNS22.cjs.map
578
+ //# sourceMappingURL=chunk-K76UNS22.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/MediaPlayer/overlayButton.ts","../src/components/MediaPlayer/pictureInPicture.ts","../src/components/MediaPlayer/MediaControls.tsx","../src/components/MediaPlayer/MediaPlayer.tsx"],"names":["formatTime","React","MediaControls","className","jsx","Button","cn","jsxs","Play","Pause","Slider","Captions","CaptionsOff","VolumeX","Volume2","PictureInPicture2","Minimize","Maximize","cva","React2","useMediaTransport"],"mappings":"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","file":"chunk-TZKBW4GA.cjs","sourcesContent":["// Internal to the media components; not part of the public API.\n\n/**\n * The round, translucent icon button over a video (the feed's Previous/Next,\n * its inactive item's Play). Pass it to `<Button variant=\"ghost\" size=\"icon\">`;\n * it sets the `dark:` colours too, because these buttons sit inside a\n * `data-theme=\"dark\"` surface. Add `bg-transparent` where the button sits on a\n * scrim already, as the player's bar does. The scrim is black on purpose: it\n * has to read over any frame of the video.\n */\nexport const overlayButtonClass = [\n 'rounded-full bg-black/45 text-white backdrop-blur-sm',\n 'hover:bg-black/65 hover:text-white active:bg-black/75',\n 'dark:text-white dark:hover:bg-black/65 dark:active:bg-black/75',\n 'focus-visible:ring-white focus-visible:ring-offset-0',\n 'pointer-fine:h-9 pointer-fine:w-9',\n].join(' ');\n\n/** The large round ▶ in the middle of a paused video, and its glyph. */\nexport const playBadgeClass =\n 'flex h-14 w-14 items-center justify-center rounded-full bg-black/60 text-white';\n// Optical centring; media glyphs don't flip in RTL.\nexport const playBadgeIconClass = 'h-6 w-6 translate-x-0.5 fill-current';\n","// Internal to the media components (MediaControls, MediaFeed); not part of\n// the public API.\n\n/** Safari's own full screen and picture in picture, beside the standard APIs. */\nexport type WebKitVideo = HTMLVideoElement & {\n webkitEnterFullscreen?: () => void;\n webkitSupportsFullscreen?: boolean;\n webkitSupportsPresentationMode?: (mode: string) => boolean;\n webkitSetPresentationMode?: (mode: string) => void;\n webkitPresentationMode?: string;\n};\n\n/** The events that say a video went into or out of picture in picture. */\nexport const PIP_EVENTS: readonly string[] = [\n 'enterpictureinpicture',\n 'leavepictureinpicture',\n 'webkitpresentationmodechanged',\n];\n\n/**\n * How long to wait for Safari to say a video left picture in picture before\n * carrying on: the event may never come.\n */\nconst PIP_EXIT_TIMEOUT_MS = 1000;\n\n/** Whether `video` is floating in picture in picture (either API). */\nexport function isInPictureInPicture(\n video: HTMLMediaElement | null | undefined\n): boolean {\n if (!video || typeof document === 'undefined') return false;\n return (\n document.pictureInPictureElement === video ||\n (video as WebKitVideo).webkitPresentationMode === 'picture-in-picture'\n );\n}\n\n/**\n * Bring `video` back from picture in picture (either API). Resolves once it is\n * back inline, or straight away when it wasn't floating.\n */\nexport function exitPictureInPicture(\n video: HTMLMediaElement | null | undefined\n): Promise<void> {\n if (!video || !isInPictureInPicture(video)) return Promise.resolve();\n if (document.pictureInPictureElement === video)\n return document.exitPictureInPicture().catch(() => {});\n return new Promise((resolve) => {\n // Whichever comes first, the event or the timeout, cleans up the other.\n const done = () => {\n clearTimeout(timer);\n video.removeEventListener('webkitpresentationmodechanged', done);\n resolve();\n };\n const timer = setTimeout(done, PIP_EXIT_TIMEOUT_MS);\n video.addEventListener('webkitpresentationmodechanged', done, {\n once: true,\n });\n (video as WebKitVideo).webkitSetPresentationMode?.('inline');\n });\n}\n\n/** Whether this browser can float `video` in picture in picture. */\nexport function canPictureInPicture(video: WebKitVideo | null): boolean {\n if (!video || typeof document === 'undefined') return false;\n if (video.disablePictureInPicture) return false;\n return (\n document.pictureInPictureEnabled ||\n !!video.webkitSupportsPresentationMode?.('picture-in-picture')\n );\n}\n","import * as React from 'react';\nimport {\n Captions,\n CaptionsOff,\n Maximize,\n Minimize,\n Pause,\n PictureInPicture2,\n Play,\n Volume2,\n VolumeX,\n} from 'lucide-react';\n\nimport { cn } from '../../utils/cn';\nimport type { UseMediaTransportReturn } from '../../hooks/useMediaTransport';\nimport { formatTime } from '../AudioPlayer/AudioPlayer';\nimport { Button } from '../Button';\nimport { Slider } from '../Slider';\nimport {\n overlayButtonClass,\n playBadgeClass,\n playBadgeIconClass,\n} from './overlayButton';\nimport {\n canPictureInPicture,\n exitPictureInPicture,\n isInPictureInPicture,\n PIP_EVENTS,\n type WebKitVideo,\n} from './pictureInPicture';\n\n/** Every string the controls show or announce, for the host to localize. */\nexport interface MediaControlsLabels {\n play: string;\n pause: string;\n mute: string;\n unmute: string;\n seek: string;\n fullscreen: string;\n exitFullscreen: string;\n pictureInPicture: string;\n exitPictureInPicture: string;\n /** The elapsed and total time, already formatted (`1:05`, `4:30`). */\n time: (current: string, duration: string) => string;\n /** The speed button's text for a rate (`1.5×`). */\n rate: (rate: number) => string;\n /** The speed button's accessible name, given its text. */\n speed: (rate: string) => string;\n showCaptions: string;\n hideCaptions: string;\n}\n\n/** The English defaults; MediaFeed reuses them for its player labels. */\nexport const defaultMediaControlsLabels: MediaControlsLabels = {\n play: 'Play',\n pause: 'Pause',\n mute: 'Mute',\n unmute: 'Unmute',\n seek: 'Seek',\n fullscreen: 'Full screen',\n exitFullscreen: 'Exit full screen',\n pictureInPicture: 'Picture in picture',\n exitPictureInPicture: 'Exit picture in picture',\n time: (current, duration) => `${current} / ${duration}`,\n rate: (rate) => `${rate}×`,\n speed: (rate) => `Playback speed ${rate}`,\n showCaptions: 'Show captions',\n hideCaptions: 'Hide captions',\n};\n\nexport interface MediaControlsProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The transport attached to the `<video>` these controls drive. */\n transport: UseMediaTransportReturn;\n /**\n * The box that goes full screen with the controls (the video and these\n * controls' shared parent). Where the browser can't take an element full\n * screen (an iPhone), the video opens in the system's own player instead.\n */\n fullscreenTarget?: React.RefObject<HTMLElement | null>;\n /** Localized text for every control; English by default. */\n labels?: Partial<MediaControlsLabels>;\n /** The speeds the speed button cycles through (default `[1, 1.5, 2]`). */\n playbackRates?: readonly number[];\n}\n\nconst defaultPlaybackRates = [1, 1.5, 2] as const;\n\n/** Controls a small player (under 20rem wide) leaves out: speed and picture in picture. */\nconst SMALL_PLAYER_HIDDEN = '@max-xs:hidden';\n\n/** Where a tap or drag on the seek bar lands: to the tenth of a second. */\nconst SEEK_STEP_MS = 100;\n\n/**\n * How far an arrow key seeks, as a share of the clip (2%): a few presses cross\n * a short clip, and a long one isn't hundreds of presses long.\n */\nconst KEYBOARD_SEEK_FRACTION = 0.02;\n\n/**\n * Browsers size caption text at about 5% of the video's height, and step a\n * cue's `line` by its line box, so this approximates one line's height.\n */\nconst CUE_LINE_HEIGHT_FRACTION = 0.05;\n\n/** The line a cue is lifted to before the video has a size to measure. */\nconst DEFAULT_CUE_LINE = -4;\n\nconst formatMs = (ms: number) => formatTime(ms / 1000);\n\n/**\n * The cue line just above the bar's controls. Lines count up from -1 (the\n * bottom one), so a cue on line -(n + 1) clears n lines. The bar's top padding\n * is the transparent start of its scrim, which captions may cover.\n */\nfunction cueLineAboveBar(\n video: HTMLVideoElement,\n bar: HTMLElement | null\n): number {\n const lineHeight =\n video.getBoundingClientRect().height * CUE_LINE_HEIGHT_FRACTION;\n if (!bar || lineHeight <= 0) return DEFAULT_CUE_LINE;\n const controls =\n bar.getBoundingClientRect().height -\n (parseFloat(getComputedStyle(bar).paddingTop) || 0);\n return -(Math.ceil(Math.max(controls, 0) / lineHeight) + 1);\n}\n\n/** Whether `video` is in picture in picture, following every change. */\nfunction useInPictureInPicture(video: HTMLVideoElement | null): boolean {\n const [inPip, setInPip] = React.useState(false);\n React.useEffect(() => {\n if (!video) return;\n const update = () => setInPip(isInPictureInPicture(video));\n update();\n for (const event of PIP_EVENTS) video.addEventListener(event, update);\n return () => {\n for (const event of PIP_EVENTS) video.removeEventListener(event, update);\n };\n }, [video]);\n return inPip;\n}\n\n/**\n * The video's caption and subtitle tracks, and whether one is showing,\n * following tracks the host adds, removes or switches itself.\n */\nfunction useCaptionTracks(\n video: HTMLVideoElement | null,\n barRef: React.RefObject<HTMLElement | null>\n) {\n const [tracks, setTracks] = React.useState<globalThis.TextTrack[]>([]);\n const [showing, setShowing] = React.useState(false);\n React.useEffect(() => {\n const list = video?.textTracks;\n if (!list) {\n setTracks([]);\n setShowing(false);\n return;\n }\n // Browsers draw cues at the very bottom, under the bar: lift any cue the\n // host left on the default line to just above it. A fixed line count\n // isn't enough, since lines scale with the video and the bar doesn't (it\n // takes two rows in a small card). Cues load lazily, and the player can\n // change size, so this runs again as cues become active and as the video\n // or bar is resized. `lifted` keeps\n // the line each cue was lifted to: a cue still on it is ours to move, and\n // goes back to the default line when these controls unmount (the video\n // may stay, with no bar to clear). One the host has moved since is theirs.\n const lifted = new Map<globalThis.VTTCue, number>();\n const place = (\n track: globalThis.TextTrack | null,\n cue: globalThis.VTTCue,\n line: number | 'auto'\n ) => {\n cue.line = line;\n // A cue already on screen keeps its old place until it's re-added.\n if (track && Array.from(track.activeCues ?? []).includes(cue)) {\n track.removeCue(cue);\n track.addCue(cue);\n }\n };\n const liftCues = (track: globalThis.TextTrack) => {\n const line = video\n ? cueLineAboveBar(video, barRef.current)\n : DEFAULT_CUE_LINE;\n for (const each of Array.from(track.cues ?? [])) {\n if (!('line' in each)) continue;\n const cue = each as globalThis.VTTCue;\n if (cue.line !== 'auto' && lifted.get(cue) !== cue.line) continue;\n if (cue.line === line) continue;\n lifted.set(cue, line);\n place(track, cue, line);\n }\n };\n const lift = (event: Event) =>\n liftCues(event.target as globalThis.TextTrack);\n let watched: globalThis.TextTrack[] = [];\n const update = () => {\n const captions = Array.from(list).filter(\n (track) => track.kind === 'captions' || track.kind === 'subtitles'\n );\n for (const track of watched)\n track.removeEventListener?.('cuechange', lift);\n for (const track of captions) track.addEventListener?.('cuechange', lift);\n watched = captions;\n setTracks(captions);\n setShowing(captions.some((track) => track.mode === 'showing'));\n };\n update();\n const events = ['addtrack', 'removetrack', 'change'];\n for (const name of events) list.addEventListener?.(name, update);\n // A new size (a phone turned, full screen left) needs a new line but\n // brings no cuechange, so the cues move then too, paused or playing.\n const resize =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => watched.forEach(liftCues));\n for (const element of [video, barRef.current])\n if (element) resize?.observe(element);\n return () => {\n resize?.disconnect();\n for (const name of events) list.removeEventListener?.(name, update);\n for (const track of watched)\n track.removeEventListener?.('cuechange', lift);\n for (const [cue, line] of lifted)\n if (cue.line === line) place(cue.track, cue, 'auto');\n };\n }, [video, barRef]);\n return { tracks, showing };\n}\n\n/** Whether `element`'s audio is muted, following every change to it. */\nfunction useMuted(element: HTMLMediaElement | null): boolean {\n const [muted, setMuted] = React.useState(element?.muted ?? false);\n React.useEffect(() => {\n if (!element) return;\n const update = () => setMuted(element.muted);\n update();\n element.addEventListener('volumechange', update);\n return () => element.removeEventListener('volumechange', update);\n }, [element]);\n return muted;\n}\n\n/** Whether `target` is the page's full-screen element. */\nfunction useIsFullscreen(\n target: React.RefObject<HTMLElement | null> | undefined\n): boolean {\n const [fullscreen, setFullscreen] = React.useState(false);\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n const update = () =>\n setFullscreen(\n !!target?.current && document.fullscreenElement === target.current\n );\n // Controls that mount while their box is already full screen say so.\n update();\n document.addEventListener('fullscreenchange', update);\n return () => document.removeEventListener('fullscreenchange', update);\n }, [target]);\n return fullscreen;\n}\n\n/**\n * Touch-first controls laid over a `<video>`, in place of the browser's own.\n * A tap on the picture plays or pauses it, a round ▶ shows while it's paused,\n * and a bar along the bottom has play/pause, the time, a seek bar, playback\n * speed, captions on/off when the video has a caption track, mute, and\n * picture in picture and full screen where the browser supports them.\n *\n * `MediaPlayer` renders it for `controlsStyle=\"overlay\"`. To use it directly,\n * render it in a positioned box with the video, attach\n * `transport.setMediaElement` to the video's `ref` and give the video\n * `playsInline` (without it, an iPhone plays it in the system player, away\n * from these controls).\n */\nexport const MediaControls = React.forwardRef<\n HTMLDivElement,\n MediaControlsProps\n>(function MediaControls(\n {\n transport,\n fullscreenTarget,\n labels: labelOverrides,\n playbackRates = defaultPlaybackRates,\n className,\n ...rest\n },\n ref\n) {\n const labels = { ...defaultMediaControlsLabels, ...labelOverrides };\n const video = transport.mediaElement as WebKitVideo | null;\n const muted = useMuted(video);\n const isFullscreen = useIsFullscreen(fullscreenTarget);\n const inPip = useInPictureInPicture(video);\n const barRef = React.useRef<HTMLDivElement>(null);\n const captions = useCaptionTracks(video, barRef);\n // What this browser can do is read once mounted: the server can't know it,\n // and markup that differs from the server's breaks hydration. Safari only\n // says a video can float once its metadata is in, so read again then (and\n // on each new source).\n const [support, setSupport] = React.useState({ box: false, pip: false });\n React.useEffect(() => {\n const read = () =>\n setSupport({\n box: document.fullscreenEnabled && !!fullscreenTarget,\n pip: canPictureInPicture(video),\n });\n read();\n video?.addEventListener('loadedmetadata', read);\n return () => video?.removeEventListener('loadedmetadata', read);\n }, [video, fullscreenTarget]);\n const playing = transport.isPlaying;\n const durationMs = transport.durationMs;\n\n const togglePlay = transport.togglePlay;\n const toggleMuted = () => {\n if (video) video.muted = !video.muted;\n };\n // The iPhone fallback only where it works: Chromium has the method too, but\n // it does nothing in a frame that isn't allowed full screen.\n const canFullscreen =\n support.box ||\n (!!video?.webkitEnterFullscreen && !!video.webkitSupportsFullscreen);\n // Leaves only a full screen these controls entered: a page that is full\n // screen itself (a kiosk, a presentation) stays that way.\n const toggleFullscreen = () => {\n if (isFullscreen) {\n void document.exitFullscreen?.()?.catch(() => {});\n } else if (support.box && fullscreenTarget?.current) {\n void fullscreenTarget.current.requestFullscreen?.()?.catch(() => {});\n } else {\n video?.webkitEnterFullscreen?.();\n }\n };\n // Each press moves to the next speed, and from the last back to the first.\n const rate = transport.playbackRate;\n const cycleSpeed = () => {\n const index = playbackRates.indexOf(rate);\n transport.setPlaybackRate(\n playbackRates[(index + 1) % playbackRates.length] ?? 1\n );\n };\n // Shows the first caption track, or hides whichever is showing.\n const toggleCaptions = () => {\n const [first] = captions.tracks;\n for (const track of captions.tracks)\n track.mode =\n !captions.showing && track === first ? 'showing' : 'disabled';\n };\n // The standard API, else Safari's presentation mode on an iPhone.\n const togglePictureInPicture = () => {\n if (!video) return;\n if (isInPictureInPicture(video)) {\n void exitPictureInPicture(video);\n } else if (document.pictureInPictureEnabled) {\n void video.requestPictureInPicture().catch(() => {});\n } else {\n video.webkitSetPresentationMode?.('picture-in-picture');\n }\n };\n\n const barButton = (\n label: string,\n onClick: () => void,\n icon: React.ReactElement,\n className?: string\n ) => (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n title={label}\n onClick={onClick}\n className={cn(overlayButtonClass, 'shrink-0 bg-transparent', className)}\n >\n {icon}\n </Button>\n );\n\n return (\n <div\n ref={ref}\n data-slot=\"media-controls\"\n className={cn(\n // A container query: a narrow player (a portrait clip) gives the seek\n // bar a row of its own, so it's always long enough to drag.\n '@container pointer-events-none absolute inset-0 flex flex-col justify-end',\n className\n )}\n {...rest}\n >\n {/* A pointer convenience over the picture, as in every video app. The\n bar's Play is the keyboard and screen-reader control. */}\n <div\n data-slot=\"media-controls-surface\"\n aria-hidden=\"true\"\n className=\"pointer-events-auto absolute inset-0 flex cursor-pointer items-center justify-center\"\n onClick={togglePlay}\n >\n {!playing && (\n <span className={playBadgeClass}>\n <Play className={playBadgeIconClass} />\n </span>\n )}\n </div>\n {/* Left to right in every language: a media timeline follows the\n media, not the reading direction (Material: don't mirror playback\n controls or their progress bar). Labels keep their own direction. */}\n <div\n ref={barRef}\n data-slot=\"media-controls-bar\"\n dir=\"ltr\"\n // A small player (a card in a chat, under 20rem wide) keeps play,\n // time, seek, mute and full screen on two short rows and leaves speed\n // and picture in picture to the larger view, as in-chat players do;\n // its gradient starts lower so the picture stays visible.\n className=\"pointer-events-auto relative flex flex-wrap items-center gap-x-1 bg-gradient-to-t from-black/75 via-black/40 to-transparent px-1 pt-6 pb-1 text-white sm:px-2 @max-xs:pt-2\"\n >\n {barButton(\n playing ? labels.pause : labels.play,\n togglePlay,\n playing ? (\n <Pause className=\"h-5 w-5 fill-current\" aria-hidden=\"true\" />\n ) : (\n <Play className=\"h-5 w-5 fill-current\" aria-hidden=\"true\" />\n )\n )}\n <span\n data-slot=\"media-controls-time\"\n className=\"shrink-0 px-1 text-xs whitespace-nowrap tabular-nums @max-md:me-auto\"\n >\n {/* The label may be RTL text (\"0:01 من 0:04\"): isolate its\n direction without turning the bar's layout around. */}\n <bdi>\n {labels.time(\n formatMs(transport.currentTimeMs),\n formatMs(durationMs)\n )}\n </bdi>\n </span>\n <Slider\n // Taller to grab on a touch screen; the track itself stays thin.\n className=\"mx-1 min-w-0 flex-1 @max-md:order-first @max-md:mx-2 @max-md:basis-full pointer-coarse:[&_[data-slot=slider-track-wrapper]]:py-4\"\n // dark: too, or the dark surface's own track colour wins.\n trackClassName=\"bg-white/30 dark:bg-white/30\"\n size=\"sm\"\n min={0}\n max={durationMs > 0 ? durationMs : 1}\n step={SEEK_STEP_MS}\n keyboardStep={Math.max(\n SEEK_STEP_MS,\n Math.round(durationMs * KEYBOARD_SEEK_FRACTION)\n )}\n value={transport.currentTimeMs}\n onValueChange={transport.seekToMs}\n formatValue={formatMs}\n disabled={durationMs <= 0}\n aria-label={labels.seek}\n />\n {playbackRates.length > 1 &&\n barButton(\n labels.speed(labels.rate(rate)),\n cycleSpeed,\n <span className=\"text-xs font-semibold tabular-nums\">\n {labels.rate(rate)}\n </span>,\n SMALL_PLAYER_HIDDEN\n )}\n {/* The label says what a press does, so it carries the state: no\n aria-pressed as well, or it would read \"Hide captions, pressed\". */}\n {captions.tracks.length > 0 &&\n barButton(\n captions.showing ? labels.hideCaptions : labels.showCaptions,\n toggleCaptions,\n // The icon shows the state, as mute's does.\n captions.showing ? (\n <Captions className=\"h-5 w-5\" aria-hidden=\"true\" />\n ) : (\n <CaptionsOff className=\"h-5 w-5\" aria-hidden=\"true\" />\n )\n )}\n {barButton(\n muted ? labels.unmute : labels.mute,\n toggleMuted,\n muted ? (\n <VolumeX className=\"h-5 w-5\" aria-hidden=\"true\" />\n ) : (\n <Volume2 className=\"h-5 w-5\" aria-hidden=\"true\" />\n )\n )}\n {support.pip &&\n barButton(\n inPip ? labels.exitPictureInPicture : labels.pictureInPicture,\n togglePictureInPicture,\n <PictureInPicture2 className=\"h-5 w-5\" aria-hidden=\"true\" />,\n SMALL_PLAYER_HIDDEN\n )}\n {canFullscreen &&\n barButton(\n isFullscreen ? labels.exitFullscreen : labels.fullscreen,\n toggleFullscreen,\n isFullscreen ? (\n <Minimize className=\"h-5 w-5\" aria-hidden=\"true\" />\n ) : (\n <Maximize className=\"h-5 w-5\" aria-hidden=\"true\" />\n )\n )}\n </div>\n </div>\n );\n});\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { Button } from '../Button';\nimport { useMediaTransport } from '../../hooks/useMediaTransport';\nimport { MediaControls, type MediaControlsLabels } from './MediaControls';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport type MediaPlayerState =\n | 'idle'\n | 'loading'\n | 'playing'\n | 'paused'\n | 'error';\n\nexport type MediaKind = 'video' | 'audio';\n\n/** Ref handle for controlling {@link MediaPlayer} programmatically. */\nexport interface MediaPlayerRef {\n /** Seek to a specific time in milliseconds. */\n seekToMs: (timeMs: number) => void;\n /** Start playback. */\n play: () => void;\n /** Pause playback. */\n pause: () => void;\n /** Get current playback time in milliseconds. */\n getCurrentTimeMs: () => number;\n /** Get total duration in milliseconds. */\n getDurationMs: () => number;\n /** Whether playback is currently paused. */\n isPaused: () => boolean;\n /** Set playback speed multiplier. */\n setPlaybackRate: (rate: number) => void;\n /**\n * The underlying media element.\n * Escape hatch for host integrations (e.g. thumbnail capture); prefer the\n * typed methods above for playback control.\n */\n mediaElement: HTMLVideoElement | HTMLAudioElement | null;\n}\n\nexport interface MediaPlayerProps extends VariantProps<\n typeof mediaPlayerVariants\n> {\n /** Media source URL. */\n src: string;\n /** Force the media kind; when omitted it is inferred from the src extension. */\n kind?: MediaKind;\n /** Whether to show controls (default `true`). */\n controls?: boolean;\n /**\n * Which controls a video gets (default `'native'`, the browser's own).\n * `'overlay'` lays touch-first controls over it ({@link MediaControls}),\n * the same in every browser and in a mobile app's web view. Audio always uses\n * the browser's.\n */\n controlsStyle?: 'native' | 'overlay';\n /** Begin muted; the controls can still unmute it. */\n muted?: boolean;\n /** Repeat playback when the media ends. */\n loop?: boolean;\n /** Video thumbnail displayed before playback. */\n poster?: string;\n /** Browser preload hint (default browser behavior when omitted). */\n preload?: 'none' | 'metadata' | 'auto';\n /** Caption/subtitle `<track>` elements. The `src` attribute is always set\n * on the media element, so alternative `<source>` children are ignored. */\n children?: React.ReactNode;\n /** The speeds the overlay controls' speed button cycles through (default `[1, 1.5, 2]`). */\n playbackRates?: readonly number[];\n /** Localized load-error and retry text, and the overlay controls' labels. */\n labels?: { error?: string; retry?: string } & Partial<MediaControlsLabels>;\n /** Callback when playback state changes. */\n onStateChange?: (state: MediaPlayerState) => void;\n /** Callback when playback ends. */\n onEnded?: () => void;\n /** Callback when an error occurs. */\n onError?: (error: Error) => void;\n /** Callback after the user requests a fresh media load on the error surface. */\n onRetry?: () => void;\n /** Callback on time updates (milliseconds). */\n onTimeUpdate?: (currentTimeMs: number, durationMs: number) => void;\n /** Additional class name. */\n className?: string;\n /** Accessible label for the media element. */\n 'aria-label'?: string;\n /**\n * Transitional: exposes the raw media element to legacy consumers.\n * Prefer {@link MediaPlayerRef} for playback control.\n */\n mediaElementRef?: React.RefObject<HTMLVideoElement | HTMLAudioElement | null>;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst mediaPlayerVariants = cva(\n 'flex h-full w-full items-center justify-center',\n {\n variants: {\n variant: {\n plain: '',\n card: 'rounded-xl border border-border bg-card text-card-foreground p-2',\n },\n },\n defaultVariants: {\n variant: 'plain',\n },\n }\n);\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst VIDEO_EXTENSIONS = /\\.(mp4|mov|avi|webm|mkv|m4v)$/i;\n\n/** Infer media kind from a URL's file extension; defaults to audio. */\nexport function inferMediaKind(src: string): MediaKind {\n // Strip any query string / fragment before matching. Testing the extension\n // against the full URL required a trailing `.*`, which backtracks\n // polynomially on crafted inputs (ReDoS); splitting first is linear.\n const path = src.split(/[?#]/, 1)[0];\n return VIDEO_EXTENSIONS.test(path) ? 'video' : 'audio';\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Media playback surface for audio and video with a shared imperative handle.\n *\n * Renders a native `<video>` or `<audio>` element (kind inferred from the src\n * extension unless forced) with themed error/retry handling. Playback state and\n * controls come from the shared {@link useMediaTransport} hook and are exposed\n * through {@link MediaPlayerRef} (all times in milliseconds) — consumers should\n * not reach into the DOM element directly.\n */\nexport const MediaPlayer = React.forwardRef<MediaPlayerRef, MediaPlayerProps>(\n (\n {\n src,\n kind,\n controls = true,\n controlsStyle = 'native',\n muted,\n loop,\n poster,\n preload,\n children,\n playbackRates,\n labels,\n variant,\n onStateChange,\n onEnded,\n onError,\n onRetry,\n onTimeUpdate,\n className,\n 'aria-label': ariaLabel,\n mediaElementRef,\n },\n ref\n ) => {\n const [error, setError] = React.useState<string | null>(null);\n\n // A failed load must not outlive its src: clearing on change lets a host\n // swap in a corrected URL without being trapped on the error surface\n // (which unmounts the media element, so the new src would never load).\n React.useEffect(() => {\n setError(null);\n }, [src]);\n const resolvedKind = kind ?? inferMediaKind(src);\n\n const transport = useMediaTransport({\n onTimeUpdate,\n onStateChange,\n onEnded,\n onError: (err) => {\n setError(\n labels?.error ??\n 'Unable to load media. The server may be unavailable.'\n );\n onError?.(err);\n },\n endedState: 'paused',\n errorLabel: `media: ${src}`,\n });\n\n const { setMediaElement, mediaElement } = transport;\n\n const setElement = React.useCallback(\n (el: HTMLVideoElement | HTMLAudioElement | null) => {\n setMediaElement(el);\n if (mediaElementRef) {\n (mediaElementRef as React.MutableRefObject<typeof el>).current = el;\n }\n },\n [setMediaElement, mediaElementRef]\n );\n\n React.useImperativeHandle(\n ref,\n (): MediaPlayerRef => ({\n seekToMs: transport.seekToMs,\n play: transport.play,\n pause: transport.pause,\n getCurrentTimeMs: transport.getCurrentTimeMs,\n getDurationMs: transport.getDurationMs,\n isPaused: transport.isPaused,\n setPlaybackRate: transport.setPlaybackRate,\n get mediaElement() {\n return mediaElement;\n },\n }),\n [transport, mediaElement]\n );\n\n const handleRetry = React.useCallback(() => {\n setError(null);\n mediaElement?.load();\n onRetry?.();\n }, [mediaElement, onRetry]);\n\n const overlay = controlsStyle === 'overlay' && resolvedKind === 'video';\n const boxRef = React.useRef<HTMLDivElement>(null);\n const sharedMediaProps = {\n src,\n controls: controls && !overlay,\n muted,\n loop,\n preload,\n 'aria-label': ariaLabel,\n };\n\n // Tracks belong to the caller's media resource and can be supplied as\n // children. The feed also supports a custom renderer for captions.\n const video = (\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <video\n ref={setElement as React.Ref<HTMLVideoElement>}\n playsInline\n poster={poster}\n className={\n overlay\n ? 'h-full w-full object-contain'\n : 'h-auto max-h-full w-auto max-w-full object-contain'\n }\n {...sharedMediaProps}\n >\n {children}\n </video>\n );\n\n if (error) {\n return (\n <div className={mediaPlayerVariants({ variant, className })}>\n <div\n role=\"alert\"\n className=\"border-destructive/30 bg-destructive/10 flex min-h-36 flex-col items-center justify-center gap-3 rounded-lg border p-8 text-center\"\n >\n {/* destructive-700/300 instead of the base token: #dc2626 on the\n destructive/10 tint is 4.14:1 — below WCAG AA (axe: color-contrast). */}\n <p className=\"text-destructive-700 dark:text-destructive-300 m-0 text-sm\">\n {error}\n </p>\n {/* bg-background: the outline button is transparent, and its text on\n the destructive/10 tint sits exactly at the 4.5:1 AA boundary. */}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"bg-background\"\n onClick={handleRetry}\n >\n {labels?.retry ?? 'Retry'}\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <div className={mediaPlayerVariants({ variant, className })}>\n {resolvedKind === 'video' ? (\n // The controls cover the player's box, so the video fills it at its\n // own shape and the bar spans the box. The box is a dark surface in\n // every theme (black letterboxing, as on VideoCard), so library\n // controls inside it take their dark-theme colours. With the\n // browser's controls the box is `contents`, leaving the video laid\n // out as before; it stays in the tree either way, so changing\n // `controlsStyle` keeps the same video, its time and playback.\n <div\n ref={boxRef}\n data-slot={overlay ? 'media-player-box' : undefined}\n data-theme={overlay ? 'dark' : undefined}\n className={overlay ? 'relative h-full w-full bg-black' : 'contents'}\n >\n {video}\n {overlay && controls && (\n <MediaControls\n transport={transport}\n fullscreenTarget={boxRef}\n labels={labels}\n playbackRates={playbackRates}\n />\n )}\n </div>\n ) : (\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <audio\n ref={setElement as React.Ref<HTMLAudioElement>}\n className=\"my-4 w-[90%] max-w-lg\"\n {...sharedMediaProps}\n >\n {children}\n </audio>\n )}\n </div>\n );\n }\n);\n\nMediaPlayer.displayName = 'MediaPlayer';\n\nexport { mediaPlayerVariants };\n"]}
1
+ {"version":3,"sources":["../src/components/MediaPlayer/overlayButton.ts","../src/components/MediaPlayer/pictureInPicture.ts","../src/components/MediaPlayer/MediaControls.tsx","../src/components/MediaPlayer/MediaPlayer.tsx"],"names":["formatTime","React","MediaControls","className","jsx","Button","cn","jsxs","Play","Pause","Slider","Captions","CaptionsOff","VolumeX","Volume2","PictureInPicture2","Minimize","Maximize","cva","React2","useMediaTransport"],"mappings":"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","file":"chunk-K76UNS22.cjs","sourcesContent":["// Internal to the media components; not part of the public API.\n\n/**\n * The round, translucent icon button over a video (the feed's Previous/Next,\n * its inactive item's Play). Pass it to `<Button variant=\"ghost\" size=\"icon\">`;\n * it sets the `dark:` colours too, because these buttons sit inside a\n * `data-theme=\"dark\"` surface. Add `bg-transparent` where the button sits on a\n * scrim already, as the player's bar does. The scrim is black on purpose: it\n * has to read over any frame of the video.\n */\nexport const overlayButtonClass = [\n 'rounded-full bg-black/45 text-white backdrop-blur-sm',\n 'hover:bg-black/65 hover:text-white active:bg-black/75',\n 'dark:text-white dark:hover:bg-black/65 dark:active:bg-black/75',\n 'focus-visible:ring-white focus-visible:ring-offset-0',\n 'pointer-fine:h-9 pointer-fine:w-9',\n].join(' ');\n\n/** The large round ▶ in the middle of a paused video, and its glyph. */\nexport const playBadgeClass =\n 'flex h-14 w-14 items-center justify-center rounded-full bg-black/60 text-white';\n// Optical centring; media glyphs don't flip in RTL.\nexport const playBadgeIconClass = 'h-6 w-6 translate-x-0.5 fill-current';\n","// Internal to the media components (MediaControls, MediaFeed); not part of\n// the public API.\n\n/** Safari's own full screen and picture in picture, beside the standard APIs. */\nexport type WebKitVideo = HTMLVideoElement & {\n webkitEnterFullscreen?: () => void;\n webkitSupportsFullscreen?: boolean;\n webkitSupportsPresentationMode?: (mode: string) => boolean;\n webkitSetPresentationMode?: (mode: string) => void;\n webkitPresentationMode?: string;\n};\n\n/** The events that say a video went into or out of picture in picture. */\nexport const PIP_EVENTS: readonly string[] = [\n 'enterpictureinpicture',\n 'leavepictureinpicture',\n 'webkitpresentationmodechanged',\n];\n\n/**\n * How long to wait for Safari to say a video left picture in picture before\n * carrying on: the event may never come.\n */\nconst PIP_EXIT_TIMEOUT_MS = 1000;\n\n/** Whether `video` is floating in picture in picture (either API). */\nexport function isInPictureInPicture(\n video: HTMLMediaElement | null | undefined\n): boolean {\n if (!video || typeof document === 'undefined') return false;\n return (\n document.pictureInPictureElement === video ||\n (video as WebKitVideo).webkitPresentationMode === 'picture-in-picture'\n );\n}\n\n/**\n * Bring `video` back from picture in picture (either API). Resolves once it is\n * back inline, or straight away when it wasn't floating.\n */\nexport function exitPictureInPicture(\n video: HTMLMediaElement | null | undefined\n): Promise<void> {\n if (!video || !isInPictureInPicture(video)) return Promise.resolve();\n if (document.pictureInPictureElement === video)\n return document.exitPictureInPicture().catch(() => {});\n return new Promise((resolve) => {\n // Whichever comes first, the event or the timeout, cleans up the other.\n const done = () => {\n clearTimeout(timer);\n video.removeEventListener('webkitpresentationmodechanged', done);\n resolve();\n };\n const timer = setTimeout(done, PIP_EXIT_TIMEOUT_MS);\n video.addEventListener('webkitpresentationmodechanged', done, {\n once: true,\n });\n (video as WebKitVideo).webkitSetPresentationMode?.('inline');\n });\n}\n\n/** Whether this browser can float `video` in picture in picture. */\nexport function canPictureInPicture(video: WebKitVideo | null): boolean {\n if (!video || typeof document === 'undefined') return false;\n if (video.disablePictureInPicture) return false;\n return (\n document.pictureInPictureEnabled ||\n !!video.webkitSupportsPresentationMode?.('picture-in-picture')\n );\n}\n","import * as React from 'react';\nimport {\n Captions,\n CaptionsOff,\n Maximize,\n Minimize,\n Pause,\n PictureInPicture2,\n Play,\n Volume2,\n VolumeX,\n} from 'lucide-react';\n\nimport { cn } from '../../utils/cn';\nimport type { UseMediaTransportReturn } from '../../hooks/useMediaTransport';\nimport { formatTime } from '../AudioPlayer/AudioPlayer';\nimport { Button } from '../Button';\nimport { Slider } from '../Slider';\nimport {\n overlayButtonClass,\n playBadgeClass,\n playBadgeIconClass,\n} from './overlayButton';\nimport {\n canPictureInPicture,\n exitPictureInPicture,\n isInPictureInPicture,\n PIP_EVENTS,\n type WebKitVideo,\n} from './pictureInPicture';\n\n/** Every string the controls show or announce, for the host to localize. */\nexport interface MediaControlsLabels {\n play: string;\n pause: string;\n mute: string;\n unmute: string;\n seek: string;\n fullscreen: string;\n exitFullscreen: string;\n pictureInPicture: string;\n exitPictureInPicture: string;\n /** The elapsed and total time, already formatted (`1:05`, `4:30`). */\n time: (current: string, duration: string) => string;\n /** The speed button's text for a rate (`1.5×`). */\n rate: (rate: number) => string;\n /** The speed button's accessible name, given its text. */\n speed: (rate: string) => string;\n showCaptions: string;\n hideCaptions: string;\n}\n\n/** The English defaults; MediaFeed reuses them for its player labels. */\nexport const defaultMediaControlsLabels: MediaControlsLabels = {\n play: 'Play',\n pause: 'Pause',\n mute: 'Mute',\n unmute: 'Unmute',\n seek: 'Seek',\n fullscreen: 'Full screen',\n exitFullscreen: 'Exit full screen',\n pictureInPicture: 'Picture in picture',\n exitPictureInPicture: 'Exit picture in picture',\n time: (current, duration) => `${current} / ${duration}`,\n rate: (rate) => `${rate}×`,\n speed: (rate) => `Playback speed ${rate}`,\n showCaptions: 'Show captions',\n hideCaptions: 'Hide captions',\n};\n\nexport interface MediaControlsProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The transport attached to the `<video>` these controls drive. */\n transport: UseMediaTransportReturn;\n /**\n * The box that goes full screen with the controls (the video and these\n * controls' shared parent). Where the browser can't take an element full\n * screen (an iPhone), the video opens in the system's own player instead.\n */\n fullscreenTarget?: React.RefObject<HTMLElement | null>;\n /** Localized text for every control; English by default. */\n labels?: Partial<MediaControlsLabels>;\n /** The speeds the speed button cycles through (default `[1, 1.5, 2]`). */\n playbackRates?: readonly number[];\n}\n\nconst defaultPlaybackRates = [1, 1.5, 2] as const;\n\n/** Controls a small player (under 20rem wide) leaves out: speed and picture in picture. */\nconst SMALL_PLAYER_HIDDEN = '@max-xs:hidden';\n\n/** Where a tap or drag on the seek bar lands: to the tenth of a second. */\nconst SEEK_STEP_MS = 100;\n\n/**\n * How far an arrow key seeks, as a share of the clip (2%): a few presses cross\n * a short clip, and a long one isn't hundreds of presses long.\n */\nconst KEYBOARD_SEEK_FRACTION = 0.02;\n\n/**\n * Browsers size caption text at about 5% of the video's height, and step a\n * cue's `line` by its line box, so this approximates one line's height.\n */\nconst CUE_LINE_HEIGHT_FRACTION = 0.05;\n\n/** The line a cue is lifted to before the video has a size to measure. */\nconst DEFAULT_CUE_LINE = -4;\n\nconst formatMs = (ms: number) => formatTime(ms / 1000);\n\n/**\n * The cue line just above the bar's controls. Lines count up from -1 (the\n * bottom one), so a cue on line -(n + 1) clears n lines. The bar's top padding\n * is the transparent start of its scrim, which captions may cover.\n */\nfunction cueLineAboveBar(\n video: HTMLVideoElement,\n bar: HTMLElement | null\n): number {\n const lineHeight =\n video.getBoundingClientRect().height * CUE_LINE_HEIGHT_FRACTION;\n if (!bar || lineHeight <= 0) return DEFAULT_CUE_LINE;\n const controls =\n bar.getBoundingClientRect().height -\n (parseFloat(getComputedStyle(bar).paddingTop) || 0);\n return -(Math.ceil(Math.max(controls, 0) / lineHeight) + 1);\n}\n\n/** Whether `video` is in picture in picture, following every change. */\nfunction useInPictureInPicture(video: HTMLVideoElement | null): boolean {\n const [inPip, setInPip] = React.useState(false);\n React.useEffect(() => {\n if (!video) return;\n const update = () => setInPip(isInPictureInPicture(video));\n update();\n for (const event of PIP_EVENTS) video.addEventListener(event, update);\n return () => {\n for (const event of PIP_EVENTS) video.removeEventListener(event, update);\n };\n }, [video]);\n return inPip;\n}\n\n/**\n * The video's caption and subtitle tracks, and whether one is showing,\n * following tracks the host adds, removes or switches itself.\n */\nfunction useCaptionTracks(\n video: HTMLVideoElement | null,\n barRef: React.RefObject<HTMLElement | null>\n) {\n const [tracks, setTracks] = React.useState<globalThis.TextTrack[]>([]);\n const [showing, setShowing] = React.useState(false);\n React.useEffect(() => {\n const list = video?.textTracks;\n if (!list) {\n setTracks([]);\n setShowing(false);\n return;\n }\n // Browsers draw cues at the very bottom, under the bar: lift any cue the\n // host left on the default line to just above it. A fixed line count\n // isn't enough, since lines scale with the video and the bar doesn't (it\n // takes two rows in a small card). Cues load lazily, and the player can\n // change size, so this runs again as cues become active and as the video\n // or bar is resized. `lifted` keeps\n // the line each cue was lifted to: a cue still on it is ours to move, and\n // goes back to the default line when these controls unmount (the video\n // may stay, with no bar to clear). One the host has moved since is theirs.\n const lifted = new Map<globalThis.VTTCue, number>();\n const place = (\n track: globalThis.TextTrack | null,\n cue: globalThis.VTTCue,\n line: number | 'auto'\n ) => {\n cue.line = line;\n // A cue already on screen keeps its old place until it's re-added.\n if (track && Array.from(track.activeCues ?? []).includes(cue)) {\n track.removeCue(cue);\n track.addCue(cue);\n }\n };\n const liftCues = (track: globalThis.TextTrack) => {\n const line = video\n ? cueLineAboveBar(video, barRef.current)\n : DEFAULT_CUE_LINE;\n for (const each of Array.from(track.cues ?? [])) {\n if (!('line' in each)) continue;\n const cue = each as globalThis.VTTCue;\n if (cue.line !== 'auto' && lifted.get(cue) !== cue.line) continue;\n if (cue.line === line) continue;\n lifted.set(cue, line);\n place(track, cue, line);\n }\n };\n const lift = (event: Event) =>\n liftCues(event.target as globalThis.TextTrack);\n let watched: globalThis.TextTrack[] = [];\n const update = () => {\n const captions = Array.from(list).filter(\n (track) => track.kind === 'captions' || track.kind === 'subtitles'\n );\n for (const track of watched)\n track.removeEventListener?.('cuechange', lift);\n for (const track of captions) track.addEventListener?.('cuechange', lift);\n watched = captions;\n setTracks(captions);\n setShowing(captions.some((track) => track.mode === 'showing'));\n };\n update();\n const events = ['addtrack', 'removetrack', 'change'];\n for (const name of events) list.addEventListener?.(name, update);\n // A new size (a phone turned, full screen left) needs a new line but\n // brings no cuechange, so the cues move then too, paused or playing.\n const resize =\n typeof ResizeObserver === 'undefined'\n ? null\n : new ResizeObserver(() => watched.forEach(liftCues));\n for (const element of [video, barRef.current])\n if (element) resize?.observe(element);\n return () => {\n resize?.disconnect();\n for (const name of events) list.removeEventListener?.(name, update);\n for (const track of watched)\n track.removeEventListener?.('cuechange', lift);\n for (const [cue, line] of lifted)\n if (cue.line === line) place(cue.track, cue, 'auto');\n };\n }, [video, barRef]);\n return { tracks, showing };\n}\n\n/** Whether `element`'s audio is muted, following every change to it. */\nfunction useMuted(element: HTMLMediaElement | null): boolean {\n const [muted, setMuted] = React.useState(element?.muted ?? false);\n React.useEffect(() => {\n if (!element) return;\n const update = () => setMuted(element.muted);\n update();\n element.addEventListener('volumechange', update);\n return () => element.removeEventListener('volumechange', update);\n }, [element]);\n return muted;\n}\n\n/** Whether `target` is the page's full-screen element. */\nfunction useIsFullscreen(\n target: React.RefObject<HTMLElement | null> | undefined\n): boolean {\n const [fullscreen, setFullscreen] = React.useState(false);\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n const update = () =>\n setFullscreen(\n !!target?.current && document.fullscreenElement === target.current\n );\n // Controls that mount while their box is already full screen say so.\n update();\n document.addEventListener('fullscreenchange', update);\n return () => document.removeEventListener('fullscreenchange', update);\n }, [target]);\n return fullscreen;\n}\n\n/**\n * Touch-first controls laid over a `<video>`, in place of the browser's own.\n * A tap on the picture plays or pauses it, a round ▶ shows while it's paused,\n * and a bar along the bottom has play/pause, the time, a seek bar, playback\n * speed, captions on/off when the video has a caption track, mute, and\n * picture in picture and full screen where the browser supports them.\n *\n * `MediaPlayer` renders it for `controlsStyle=\"overlay\"`. To use it directly,\n * render it in a positioned box with the video, attach\n * `transport.setMediaElement` to the video's `ref` and give the video\n * `playsInline` (without it, an iPhone plays it in the system player, away\n * from these controls).\n */\nexport const MediaControls = React.forwardRef<\n HTMLDivElement,\n MediaControlsProps\n>(function MediaControls(\n {\n transport,\n fullscreenTarget,\n labels: labelOverrides,\n playbackRates = defaultPlaybackRates,\n className,\n ...rest\n },\n ref\n) {\n const labels = { ...defaultMediaControlsLabels, ...labelOverrides };\n const video = transport.mediaElement as WebKitVideo | null;\n const muted = useMuted(video);\n const isFullscreen = useIsFullscreen(fullscreenTarget);\n const inPip = useInPictureInPicture(video);\n const barRef = React.useRef<HTMLDivElement>(null);\n const captions = useCaptionTracks(video, barRef);\n // What this browser can do is read once mounted: the server can't know it,\n // and markup that differs from the server's breaks hydration. Safari only\n // says a video can float once its metadata is in, so read again then (and\n // on each new source).\n const [support, setSupport] = React.useState({ box: false, pip: false });\n React.useEffect(() => {\n const read = () =>\n setSupport({\n box: document.fullscreenEnabled && !!fullscreenTarget,\n pip: canPictureInPicture(video),\n });\n read();\n video?.addEventListener('loadedmetadata', read);\n return () => video?.removeEventListener('loadedmetadata', read);\n }, [video, fullscreenTarget]);\n const playing = transport.isPlaying;\n const durationMs = transport.durationMs;\n\n const togglePlay = transport.togglePlay;\n const toggleMuted = () => {\n if (video) video.muted = !video.muted;\n };\n // The iPhone fallback only where it works: Chromium has the method too, but\n // it does nothing in a frame that isn't allowed full screen.\n const canFullscreen =\n support.box ||\n (!!video?.webkitEnterFullscreen && !!video.webkitSupportsFullscreen);\n // Leaves only a full screen these controls entered: a page that is full\n // screen itself (a kiosk, a presentation) stays that way.\n const toggleFullscreen = () => {\n if (isFullscreen) {\n void document.exitFullscreen?.()?.catch(() => {});\n } else if (support.box && fullscreenTarget?.current) {\n void fullscreenTarget.current.requestFullscreen?.()?.catch(() => {});\n } else {\n video?.webkitEnterFullscreen?.();\n }\n };\n // Each press moves to the next speed, and from the last back to the first.\n const rate = transport.playbackRate;\n const cycleSpeed = () => {\n const index = playbackRates.indexOf(rate);\n transport.setPlaybackRate(\n playbackRates[(index + 1) % playbackRates.length] ?? 1\n );\n };\n // Shows the first caption track, or hides whichever is showing.\n const toggleCaptions = () => {\n const [first] = captions.tracks;\n for (const track of captions.tracks)\n track.mode =\n !captions.showing && track === first ? 'showing' : 'disabled';\n };\n // The standard API, else Safari's presentation mode on an iPhone.\n const togglePictureInPicture = () => {\n if (!video) return;\n if (isInPictureInPicture(video)) {\n void exitPictureInPicture(video);\n } else if (document.pictureInPictureEnabled) {\n void video.requestPictureInPicture().catch(() => {});\n } else {\n video.webkitSetPresentationMode?.('picture-in-picture');\n }\n };\n\n const barButton = (\n label: string,\n onClick: () => void,\n icon: React.ReactElement,\n className?: string\n ) => (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n title={label}\n onClick={onClick}\n className={cn(overlayButtonClass, 'shrink-0 bg-transparent', className)}\n >\n {icon}\n </Button>\n );\n\n return (\n <div\n ref={ref}\n data-slot=\"media-controls\"\n className={cn(\n // A container query: a narrow player (a portrait clip) gives the seek\n // bar a row of its own, so it's always long enough to drag.\n '@container pointer-events-none absolute inset-0 flex flex-col justify-end',\n className\n )}\n {...rest}\n >\n {/* A pointer convenience over the picture, as in every video app. The\n bar's Play is the keyboard and screen-reader control. */}\n <div\n data-slot=\"media-controls-surface\"\n aria-hidden=\"true\"\n className=\"pointer-events-auto absolute inset-0 flex cursor-pointer items-center justify-center\"\n onClick={togglePlay}\n >\n {!playing && (\n <span className={playBadgeClass}>\n <Play className={playBadgeIconClass} />\n </span>\n )}\n </div>\n {/* Left to right in every language: a media timeline follows the\n media, not the reading direction (Material: don't mirror playback\n controls or their progress bar). Labels keep their own direction. */}\n <div\n ref={barRef}\n data-slot=\"media-controls-bar\"\n dir=\"ltr\"\n // A small player (a card in a chat, under 20rem wide) keeps play,\n // time, seek, mute and full screen on two short rows and leaves speed\n // and picture in picture to the larger view, as in-chat players do;\n // its gradient starts lower so the picture stays visible.\n className=\"pointer-events-auto relative flex flex-wrap items-center gap-x-1 bg-gradient-to-t from-black/75 via-black/40 to-transparent px-1 pt-6 pb-1 text-white sm:px-2 @max-xs:pt-2\"\n >\n {barButton(\n playing ? labels.pause : labels.play,\n togglePlay,\n playing ? (\n <Pause className=\"h-5 w-5 fill-current\" aria-hidden=\"true\" />\n ) : (\n <Play className=\"h-5 w-5 fill-current\" aria-hidden=\"true\" />\n )\n )}\n <span\n data-slot=\"media-controls-time\"\n className=\"shrink-0 px-1 text-xs whitespace-nowrap tabular-nums @max-md:me-auto\"\n >\n {/* The label may be RTL text (\"0:01 من 0:04\"): isolate its\n direction without turning the bar's layout around. */}\n <bdi>\n {labels.time(\n formatMs(transport.currentTimeMs),\n formatMs(durationMs)\n )}\n </bdi>\n </span>\n <Slider\n // Taller to grab on a touch screen; the track itself stays thin.\n className=\"mx-1 min-w-0 flex-1 @max-md:order-first @max-md:mx-2 @max-md:basis-full pointer-coarse:[&_[data-slot=slider-track-wrapper]]:py-4\"\n // dark: too, or the dark surface's own track colour wins.\n trackClassName=\"bg-white/30 dark:bg-white/30\"\n size=\"sm\"\n min={0}\n max={durationMs > 0 ? durationMs : 1}\n step={SEEK_STEP_MS}\n keyboardStep={Math.max(\n SEEK_STEP_MS,\n Math.round(durationMs * KEYBOARD_SEEK_FRACTION)\n )}\n value={transport.currentTimeMs}\n onValueChange={transport.seekToMs}\n formatValue={formatMs}\n disabled={durationMs <= 0}\n aria-label={labels.seek}\n />\n {playbackRates.length > 1 &&\n barButton(\n labels.speed(labels.rate(rate)),\n cycleSpeed,\n <span className=\"text-xs font-semibold tabular-nums\">\n {labels.rate(rate)}\n </span>,\n SMALL_PLAYER_HIDDEN\n )}\n {/* The label says what a press does, so it carries the state: no\n aria-pressed as well, or it would read \"Hide captions, pressed\". */}\n {captions.tracks.length > 0 &&\n barButton(\n captions.showing ? labels.hideCaptions : labels.showCaptions,\n toggleCaptions,\n // The icon shows the state, as mute's does.\n captions.showing ? (\n <Captions className=\"h-5 w-5\" aria-hidden=\"true\" />\n ) : (\n <CaptionsOff className=\"h-5 w-5\" aria-hidden=\"true\" />\n )\n )}\n {barButton(\n muted ? labels.unmute : labels.mute,\n toggleMuted,\n muted ? (\n <VolumeX className=\"h-5 w-5\" aria-hidden=\"true\" />\n ) : (\n <Volume2 className=\"h-5 w-5\" aria-hidden=\"true\" />\n )\n )}\n {support.pip &&\n barButton(\n inPip ? labels.exitPictureInPicture : labels.pictureInPicture,\n togglePictureInPicture,\n <PictureInPicture2 className=\"h-5 w-5\" aria-hidden=\"true\" />,\n SMALL_PLAYER_HIDDEN\n )}\n {canFullscreen &&\n barButton(\n isFullscreen ? labels.exitFullscreen : labels.fullscreen,\n toggleFullscreen,\n isFullscreen ? (\n <Minimize className=\"h-5 w-5\" aria-hidden=\"true\" />\n ) : (\n <Maximize className=\"h-5 w-5\" aria-hidden=\"true\" />\n )\n )}\n </div>\n </div>\n );\n});\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { Button } from '../Button';\nimport { useMediaTransport } from '../../hooks/useMediaTransport';\nimport { MediaControls, type MediaControlsLabels } from './MediaControls';\n\n// ============================================================================\n// Types & Interfaces\n// ============================================================================\n\nexport type MediaPlayerState =\n | 'idle'\n | 'loading'\n | 'playing'\n | 'paused'\n | 'error';\n\nexport type MediaKind = 'video' | 'audio';\n\n/** Ref handle for controlling {@link MediaPlayer} programmatically. */\nexport interface MediaPlayerRef {\n /** Seek to a specific time in milliseconds. */\n seekToMs: (timeMs: number) => void;\n /** Start playback. */\n play: () => void;\n /** Pause playback. */\n pause: () => void;\n /** Get current playback time in milliseconds. */\n getCurrentTimeMs: () => number;\n /** Get total duration in milliseconds. */\n getDurationMs: () => number;\n /** Whether playback is currently paused. */\n isPaused: () => boolean;\n /** Set playback speed multiplier. */\n setPlaybackRate: (rate: number) => void;\n /**\n * The underlying media element.\n * Escape hatch for host integrations (e.g. thumbnail capture); prefer the\n * typed methods above for playback control.\n */\n mediaElement: HTMLVideoElement | HTMLAudioElement | null;\n}\n\nexport interface MediaPlayerProps extends VariantProps<\n typeof mediaPlayerVariants\n> {\n /** Media source URL. */\n src: string;\n /** Force the media kind; when omitted it is inferred from the src extension. */\n kind?: MediaKind;\n /** Whether to show controls (default `true`). */\n controls?: boolean;\n /**\n * Which controls a video gets (default `'native'`, the browser's own).\n * `'overlay'` lays touch-first controls over it ({@link MediaControls}),\n * the same in every browser and in a mobile app's web view. Audio always uses\n * the browser's.\n */\n controlsStyle?: 'native' | 'overlay';\n /** Begin muted; the controls can still unmute it. */\n muted?: boolean;\n /** Repeat playback when the media ends. */\n loop?: boolean;\n /** Video thumbnail displayed before playback. */\n poster?: string;\n /** Browser preload hint (default browser behavior when omitted). */\n preload?: 'none' | 'metadata' | 'auto';\n /** Caption/subtitle `<track>` elements. The `src` attribute is always set\n * on the media element, so alternative `<source>` children are ignored. */\n children?: React.ReactNode;\n /** The speeds the overlay controls' speed button cycles through (default `[1, 1.5, 2]`). */\n playbackRates?: readonly number[];\n /** Localized load-error and retry text, and the overlay controls' labels. */\n labels?: { error?: string; retry?: string } & Partial<MediaControlsLabels>;\n /** Callback when playback state changes. */\n onStateChange?: (state: MediaPlayerState) => void;\n /** Callback when playback ends. */\n onEnded?: () => void;\n /** Callback when an error occurs. */\n onError?: (error: Error) => void;\n /** Callback after the user requests a fresh media load on the error surface. */\n onRetry?: () => void;\n /** Callback on time updates (milliseconds). */\n onTimeUpdate?: (currentTimeMs: number, durationMs: number) => void;\n /** Additional class name. */\n className?: string;\n /** Accessible label for the media element. */\n 'aria-label'?: string;\n /**\n * Transitional: exposes the raw media element to legacy consumers.\n * Prefer {@link MediaPlayerRef} for playback control.\n */\n mediaElementRef?: React.RefObject<HTMLVideoElement | HTMLAudioElement | null>;\n}\n\n// ============================================================================\n// Variants\n// ============================================================================\n\nconst mediaPlayerVariants = cva(\n 'flex h-full w-full items-center justify-center',\n {\n variants: {\n variant: {\n plain: '',\n card: 'rounded-xl border border-border bg-card text-card-foreground p-2',\n },\n },\n defaultVariants: {\n variant: 'plain',\n },\n }\n);\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst VIDEO_EXTENSIONS = /\\.(mp4|mov|avi|webm|mkv|m4v)$/i;\n\n/** Infer media kind from a URL's file extension; defaults to audio. */\nexport function inferMediaKind(src: string): MediaKind {\n // Strip any query string / fragment before matching. Testing the extension\n // against the full URL required a trailing `.*`, which backtracks\n // polynomially on crafted inputs (ReDoS); splitting first is linear.\n const path = src.split(/[?#]/, 1)[0];\n return VIDEO_EXTENSIONS.test(path) ? 'video' : 'audio';\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * Media playback surface for audio and video with a shared imperative handle.\n *\n * Renders a native `<video>` or `<audio>` element (kind inferred from the src\n * extension unless forced) with themed error/retry handling. Playback state and\n * controls come from the shared {@link useMediaTransport} hook and are exposed\n * through {@link MediaPlayerRef} (all times in milliseconds) — consumers should\n * not reach into the DOM element directly.\n */\nexport const MediaPlayer = React.forwardRef<MediaPlayerRef, MediaPlayerProps>(\n (\n {\n src,\n kind,\n controls = true,\n controlsStyle = 'native',\n muted,\n loop,\n poster,\n preload,\n children,\n playbackRates,\n labels,\n variant,\n onStateChange,\n onEnded,\n onError,\n onRetry,\n onTimeUpdate,\n className,\n 'aria-label': ariaLabel,\n mediaElementRef,\n },\n ref\n ) => {\n const [error, setError] = React.useState<string | null>(null);\n\n // A failed load must not outlive its src: clearing on change lets a host\n // swap in a corrected URL without being trapped on the error surface\n // (which unmounts the media element, so the new src would never load).\n React.useEffect(() => {\n setError(null);\n }, [src]);\n const resolvedKind = kind ?? inferMediaKind(src);\n\n const transport = useMediaTransport({\n onTimeUpdate,\n onStateChange,\n onEnded,\n onError: (err) => {\n setError(\n labels?.error ??\n 'Unable to load media. The server may be unavailable.'\n );\n onError?.(err);\n },\n endedState: 'paused',\n errorLabel: `media: ${src}`,\n });\n\n const { setMediaElement, mediaElement } = transport;\n\n const setElement = React.useCallback(\n (el: HTMLVideoElement | HTMLAudioElement | null) => {\n setMediaElement(el);\n if (mediaElementRef) {\n (mediaElementRef as React.MutableRefObject<typeof el>).current = el;\n }\n },\n [setMediaElement, mediaElementRef]\n );\n\n React.useImperativeHandle(\n ref,\n (): MediaPlayerRef => ({\n seekToMs: transport.seekToMs,\n play: transport.play,\n pause: transport.pause,\n getCurrentTimeMs: transport.getCurrentTimeMs,\n getDurationMs: transport.getDurationMs,\n isPaused: transport.isPaused,\n setPlaybackRate: transport.setPlaybackRate,\n get mediaElement() {\n return mediaElement;\n },\n }),\n [transport, mediaElement]\n );\n\n const handleRetry = React.useCallback(() => {\n setError(null);\n mediaElement?.load();\n onRetry?.();\n }, [mediaElement, onRetry]);\n\n const overlay = controlsStyle === 'overlay' && resolvedKind === 'video';\n const boxRef = React.useRef<HTMLDivElement>(null);\n const sharedMediaProps = {\n src,\n controls: controls && !overlay,\n muted,\n loop,\n preload,\n 'aria-label': ariaLabel,\n };\n\n // Tracks belong to the caller's media resource and can be supplied as\n // children. The feed also supports a custom renderer for captions.\n const video = (\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <video\n ref={setElement as React.Ref<HTMLVideoElement>}\n playsInline\n poster={poster}\n className={\n overlay\n ? 'h-full w-full object-contain'\n : 'h-auto max-h-full w-auto max-w-full object-contain'\n }\n {...sharedMediaProps}\n >\n {children}\n </video>\n );\n\n if (error) {\n return (\n <div className={mediaPlayerVariants({ variant, className })}>\n <div\n role=\"alert\"\n className=\"border-destructive/30 bg-destructive/10 flex min-h-36 flex-col items-center justify-center gap-3 rounded-lg border p-8 text-center\"\n >\n {/* destructive-700/300 instead of the base token: #dc2626 on the\n destructive/10 tint is 4.14:1 — below WCAG AA (axe: color-contrast). */}\n <p className=\"text-destructive-700 dark:text-destructive-300 m-0 text-sm\">\n {error}\n </p>\n {/* bg-background: the outline button is transparent, and its text on\n the destructive/10 tint sits exactly at the 4.5:1 AA boundary. */}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"bg-background\"\n onClick={handleRetry}\n >\n {labels?.retry ?? 'Retry'}\n </Button>\n </div>\n </div>\n );\n }\n\n return (\n <div className={mediaPlayerVariants({ variant, className })}>\n {resolvedKind === 'video' ? (\n // The controls cover the player's box, so the video fills it at its\n // own shape and the bar spans the box. The box is a dark surface in\n // every theme (black letterboxing, as on VideoCard), so library\n // controls inside it take their dark-theme colours. With the\n // browser's controls the box is `contents`, leaving the video laid\n // out as before; it stays in the tree either way, so changing\n // `controlsStyle` keeps the same video, its time and playback.\n <div\n ref={boxRef}\n data-slot={overlay ? 'media-player-box' : undefined}\n data-theme={overlay ? 'dark' : undefined}\n className={overlay ? 'relative h-full w-full bg-black' : 'contents'}\n >\n {video}\n {overlay && controls && (\n <MediaControls\n transport={transport}\n fullscreenTarget={boxRef}\n labels={labels}\n playbackRates={playbackRates}\n />\n )}\n </div>\n ) : (\n // eslint-disable-next-line jsx-a11y/media-has-caption\n <audio\n ref={setElement as React.Ref<HTMLAudioElement>}\n className=\"my-4 w-[90%] max-w-lg\"\n {...sharedMediaProps}\n >\n {children}\n </audio>\n )}\n </div>\n );\n }\n);\n\nMediaPlayer.displayName = 'MediaPlayer';\n\nexport { mediaPlayerVariants };\n"]}
@@ -1,9 +1,9 @@
1
- import { Dropdown, DropdownItem, DropdownSeparator } from './chunk-OYUIEJPN.js';
1
+ import { Dropdown, DropdownItem, DropdownSeparator } from './chunk-GTRYDFMT.js';
2
2
  import { useEscapeKey } from './chunk-T4ME7QCT.js';
3
3
  import { useClickOutside } from './chunk-62ZOA6PX.js';
4
4
  import { useAnchoredPosition } from './chunk-WSNMQQ4P.js';
5
5
  import { AlertTriangle, X2, Paperclip, Plus, Mic, Square, Loader2, ArrowUp, Bot, Check, ChevronUp } from './chunk-BKSPDTX4.js';
6
- import { isRtl } from './chunk-YVKBXNPK.js';
6
+ import { isRtl } from './chunk-JBNQ2L3K.js';
7
7
  import { cn } from './chunk-TQONQSJO.js';
8
8
  import * as React from 'react';
9
9
  import { createPortal } from 'react-dom';
@@ -2020,5 +2020,5 @@ function notifyComposerMigrationOnce(surface) {
2020
2020
  }
2021
2021
 
2022
2022
  export { AttachmentPicker, AttachmentPreviewItem, CameraButton, ChatComposer, ComposerModelSelector, ComposerSelector, DEFAULT_ACCEPTED_FILE_TYPES, DEFAULT_MAX_FILE_SIZE, DragDropZone, generateAttachmentId, getFileType, notifyComposerMigrationOnce, validateFile };
2023
- //# sourceMappingURL=chunk-DAAJ3B2T.js.map
2024
- //# sourceMappingURL=chunk-DAAJ3B2T.js.map
2023
+ //# sourceMappingURL=chunk-KP72MDFB.js.map
2024
+ //# sourceMappingURL=chunk-KP72MDFB.js.map