@xhub-short/ui 0.1.0-beta.1 → 0.1.0-beta.11

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 (76) hide show
  1. package/dist/CommentSheet.css-DyEc3Sro.d.ts +217 -0
  2. package/dist/VideoSlotPlayIndicator-DPs8Xt5C.d.ts +51 -0
  3. package/dist/chunk-3OB3OVYR.js +349 -0
  4. package/dist/{chunk-WKX2WBVO.js → chunk-3XPJHUYL.js} +1 -39
  5. package/dist/chunk-4RIMQOBR.js +58 -0
  6. package/dist/chunk-4TUBNA2X.js +180 -0
  7. package/dist/{chunk-4YDIRPIN.js → chunk-ANCP53F3.js} +3 -3
  8. package/dist/{chunk-UXMA4KJZ.js → chunk-CAWE42LH.js} +5 -3
  9. package/dist/{chunk-ANGBSV7L.js → chunk-CIIZ3IHV.js} +10 -5
  10. package/dist/chunk-DR7KR7OT.js +103 -0
  11. package/dist/chunk-DXLCQ4FH.js +102 -0
  12. package/dist/chunk-EDWS2IPH.js +1 -0
  13. package/dist/chunk-FR7UQSZP.js +570 -0
  14. package/dist/chunk-IWSBYOSS.js +91 -0
  15. package/dist/chunk-JEY6R4KJ.js +334 -0
  16. package/dist/chunk-KMJ3PQ7M.js +1262 -0
  17. package/dist/chunk-MFJS65C5.js +368 -0
  18. package/dist/{chunk-HW4LXTFT.js → chunk-OM4L7RE5.js} +18 -6
  19. package/dist/chunk-PBIH2F2Q.js +344 -0
  20. package/dist/chunk-PJ4NMVMY.js +326 -0
  21. package/dist/chunk-Q6MG7AVG.js +531 -0
  22. package/dist/chunk-QCKVF2DR.js +713 -0
  23. package/dist/chunk-QCRRF76W.js +75 -0
  24. package/dist/chunk-QUEJHA24.js +508 -0
  25. package/dist/chunk-VXW7AOGM.js +285 -0
  26. package/dist/chunk-YB7AXTX7.js +430 -0
  27. package/dist/chunk-ZGWSJ6Z5.js +601 -0
  28. package/dist/components/ActionBar/index.js +1 -1
  29. package/dist/components/AdvanceMenu/index.d.ts +78 -0
  30. package/dist/components/AdvanceMenu/index.js +1 -0
  31. package/dist/components/AuthorInfo/index.d.ts +5 -1
  32. package/dist/components/AuthorInfo/index.js +1 -1
  33. package/dist/components/BottomSheet/index.d.ts +82 -0
  34. package/dist/components/BottomSheet/index.js +1 -0
  35. package/dist/components/CleanModeOverlay/index.d.ts +60 -0
  36. package/dist/components/CleanModeOverlay/index.js +1 -0
  37. package/dist/components/CommentSheet/index.d.ts +164 -0
  38. package/dist/components/CommentSheet/index.js +1 -0
  39. package/dist/components/DetailView/index.d.ts +311 -0
  40. package/dist/components/DetailView/index.js +1 -0
  41. package/dist/components/ErrorBoundary/index.js +1 -1
  42. package/dist/components/ImageCarousel/index.d.ts +50 -0
  43. package/dist/components/ImageCarousel/index.js +1 -0
  44. package/dist/components/ImagePostSlot/index.d.ts +207 -0
  45. package/dist/components/ImagePostSlot/index.js +1 -0
  46. package/dist/components/ProgressBar/index.d.ts +30 -2
  47. package/dist/components/ProgressBar/index.js +1 -1
  48. package/dist/components/QualityPicker/index.d.ts +35 -0
  49. package/dist/components/QualityPicker/index.js +1 -0
  50. package/dist/components/ReportSheet/index.d.ts +68 -0
  51. package/dist/components/ReportSheet/index.js +1 -0
  52. package/dist/components/Skeleton/index.js +1 -1
  53. package/dist/components/SpeedPicker/index.d.ts +32 -0
  54. package/dist/components/SpeedPicker/index.js +1 -0
  55. package/dist/components/VideoFeed/index.d.ts +12 -1
  56. package/dist/components/VideoFeed/index.js +1 -1
  57. package/dist/components/VideoInfo/index.d.ts +4 -2
  58. package/dist/components/VideoInfo/index.js +1 -1
  59. package/dist/components/VideoPlayer/index.d.ts +14 -41
  60. package/dist/components/VideoPlayer/index.js +1 -1
  61. package/dist/components/VideoSlot/index.d.ts +84 -65
  62. package/dist/components/VideoSlot/index.js +2 -1
  63. package/dist/components/VirtualSlider/index.d.ts +339 -0
  64. package/dist/components/VirtualSlider/index.js +1 -0
  65. package/dist/components/icons/index.js +1 -1
  66. package/dist/index.d.ts +107 -95
  67. package/dist/index.js +84 -27
  68. package/package.json +51 -7
  69. package/dist/chunk-2PTMP65P.js +0 -738
  70. package/dist/chunk-4MN72OZH.js +0 -148
  71. package/dist/chunk-DHQJBXQW.js +0 -562
  72. package/dist/chunk-SSJDO24Q.js +0 -204
  73. package/dist/chunk-XAOEHLOX.js +0 -1326
  74. package/dist/chunk-YW23IBKF.js +0 -530
  75. package/dist/chunk-ZZDQKP4R.js +0 -418
  76. package/dist/use-gesture-react.esm-3SV4QLEJ.js +0 -1893
@@ -1,530 +0,0 @@
1
- import { cn } from './chunk-WKX2WBVO.js';
2
- import { injectComponentCSS } from './chunk-UXMA4KJZ.js';
3
- import { useInsertionEffect, useMemo, useEffect, useCallback, useRef, useState } from 'react';
4
- import { jsxs, jsx } from 'react/jsx-runtime';
5
-
6
- // src/components/ProgressBar/ProgressBar.css.ts
7
- var PROGRESS_BAR_CSS = `
8
- /* \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
9
- * ProgressBar Container
10
- * \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */
11
-
12
- .sv-progress-bar {
13
- /* Layout */
14
- position: relative;
15
- width: 100%;
16
-
17
- /* Interactive area - larger than visual for easier touch */
18
- height: var(--sv-progress-bar-touch-height, 24px);
19
- display: flex;
20
- align-items: center;
21
-
22
- /* Cursor */
23
- cursor: pointer;
24
-
25
- /* Prevent text selection during seek */
26
- user-select: none;
27
- -webkit-user-select: none;
28
- touch-action: none;
29
- }
30
-
31
- .sv-progress-bar--disabled {
32
- cursor: default;
33
- pointer-events: none;
34
- }
35
-
36
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
37
- * Track Wrapper (contains track + tooltip)
38
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
39
-
40
- .sv-progress-bar__track-wrapper {
41
- position: relative;
42
- flex: 1;
43
- display: flex;
44
- align-items: center;
45
- }
46
-
47
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
48
- * Track (background bar)
49
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
50
-
51
- .sv-progress-bar__track {
52
- position: relative;
53
- width: 100%;
54
- height: var(--sv-progress-bar-height, 3px);
55
-
56
- /* Visual */
57
- background: var(--sv-progress-bar-track-bg, rgba(255, 255, 255, 0.2));
58
- border-radius: var(--sv-progress-bar-radius, 1.5px);
59
- overflow: hidden;
60
- }
61
-
62
- /* Expand track on hover/active for better visibility */
63
- .sv-progress-bar:hover .sv-progress-bar__track,
64
- .sv-progress-bar--seeking .sv-progress-bar__track {
65
- height: var(--sv-progress-bar-height-active, 5px);
66
- }
67
-
68
- /* Disable transition during seeking for immediate feedback */
69
- .sv-progress-bar--seeking .sv-progress-bar__fill,
70
- .sv-progress-bar--seeking .sv-progress-bar__handle {
71
- transition: none;
72
- }
73
-
74
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
75
- * Buffered Fill (shows buffered progress)
76
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
77
-
78
- .sv-progress-bar__buffered {
79
- position: absolute;
80
- top: 0;
81
- left: 0;
82
- height: 100%;
83
-
84
- /* Visual */
85
- background: var(--sv-progress-bar-buffered-bg, rgba(255, 255, 255, 0.3));
86
- border-radius: inherit;
87
-
88
- /* Performance: Use scaleX for GPU acceleration */
89
- transform-origin: left center;
90
- transform: scaleX(0);
91
-
92
- /* Smooth transition for buffered updates */
93
- transition: transform 0.3s ease-out;
94
- }
95
-
96
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
97
- * Progress Fill (shows playback progress)
98
- * IMPORTANT: Designed for Direct DOM Update (ADR 005)
99
- * - Uses scaleX() for 60fps smooth animation
100
- * - Wired component will update transform directly via DOM manipulation
101
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
102
-
103
- .sv-progress-bar__fill {
104
- position: absolute;
105
- top: 0;
106
- left: 0;
107
- height: 100%;
108
- width: 100%;
109
-
110
- /* Visual */
111
- background: var(--sv-progress-bar-fill-bg, var(--sv-color-accent, #fe2c55));
112
- border-radius: inherit;
113
-
114
- /* Performance: Use scaleX for GPU acceleration */
115
- transform-origin: left center;
116
- transform: scaleX(0);
117
-
118
- /* Smooth transition for headless mode (timeupdate ~250ms intervals)
119
- * For RAF-based Direct DOM Update (wired mode), this has minimal impact
120
- * because transform updates every 16ms anyway */
121
- transition: var(--sv-progress-bar-fill-transition, transform 0.25s linear);
122
- will-change: transform;
123
- }
124
-
125
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
126
- * Seek Handle (thumb indicator)
127
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
128
-
129
- .sv-progress-bar__handle {
130
- position: absolute;
131
- top: 50%;
132
-
133
- /* Size */
134
- width: var(--sv-progress-bar-handle-size, 12px);
135
- height: var(--sv-progress-bar-handle-size, 12px);
136
-
137
- /* Positioning - will be set via left % */
138
- left: 0;
139
- transform: translate(-50%, -50%) scale(0);
140
-
141
- /* Visual */
142
- background: var(--sv-progress-bar-handle-bg, #fff);
143
- border-radius: 50%;
144
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
145
-
146
- /* Animation - smooth position + show/hide */
147
- transition: left 0.25s linear, transform 0.15s ease-out;
148
- }
149
-
150
- /* Show handle on hover/seeking */
151
- .sv-progress-bar:hover .sv-progress-bar__handle,
152
- .sv-progress-bar--seeking .sv-progress-bar__handle {
153
- transform: translate(-50%, -50%) scale(1);
154
- }
155
-
156
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
157
- * Time Display (optional, shows current/duration)
158
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
159
-
160
- .sv-progress-bar__time {
161
- display: flex;
162
- justify-content: space-between;
163
- padding: var(--sv-spacing-xs, 4px) 0;
164
-
165
- font-family: var(--sv-font-family, 'Urbanist', sans-serif);
166
- font-size: var(--sv-font-size-xs, 11px);
167
- font-variant-numeric: tabular-nums;
168
- color: var(--sv-text-secondary, rgba(255, 255, 255, 0.7));
169
- }
170
-
171
- .sv-progress-bar__time-current,
172
- .sv-progress-bar__time-duration {
173
- /* Ensure consistent width for changing numbers */
174
- min-width: 2.5em;
175
- }
176
-
177
- .sv-progress-bar__time-current {
178
- text-align: left;
179
- }
180
-
181
- .sv-progress-bar__time-duration {
182
- text-align: right;
183
- }
184
-
185
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
186
- * Seek Tooltip (shows time at cursor position during hover)
187
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
188
-
189
- .sv-progress-bar__tooltip {
190
- position: absolute;
191
- /* Position above the container (not inside track to avoid overflow:hidden) */
192
- top: 0;
193
- left: 0;
194
- transform: translate(-50%, -100%);
195
- margin-top: -8px;
196
-
197
- /* Visual */
198
- padding: 4px 8px;
199
- background: var(--sv-bg-overlay, rgba(0, 0, 0, 0.8));
200
- border-radius: var(--sv-border-radius-sm, 4px);
201
-
202
- /* Typography */
203
- font-family: var(--sv-font-family, 'Urbanist', sans-serif);
204
- font-size: var(--sv-font-size-xs, 11px);
205
- font-variant-numeric: tabular-nums;
206
- color: var(--sv-text-primary, #fff);
207
- white-space: nowrap;
208
-
209
- /* Hidden by default */
210
- opacity: 0;
211
- visibility: hidden;
212
- transition: opacity 0.15s ease, visibility 0.15s ease;
213
-
214
- /* Prevent tooltip from capturing pointer events */
215
- pointer-events: none;
216
-
217
- /* Ensure tooltip is above other elements */
218
- z-index: 10;
219
- }
220
-
221
- .sv-progress-bar:hover .sv-progress-bar__tooltip,
222
- .sv-progress-bar--seeking .sv-progress-bar__tooltip {
223
- opacity: 1;
224
- visibility: visible;
225
- }
226
-
227
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
228
- * Minimal Variant (for use inside VideoSlot overlay)
229
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
230
-
231
- .sv-progress-bar--minimal {
232
- height: auto;
233
- }
234
-
235
- .sv-progress-bar--minimal .sv-progress-bar__track {
236
- height: var(--sv-progress-bar-height-minimal, 2px);
237
- }
238
-
239
- .sv-progress-bar--minimal:hover .sv-progress-bar__track {
240
- height: var(--sv-progress-bar-height-minimal, 2px);
241
- }
242
-
243
- .sv-progress-bar--minimal .sv-progress-bar__handle {
244
- display: none;
245
- }
246
-
247
- /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
248
- * Reduced Motion (Accessibility)
249
- * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
250
-
251
- @media (prefers-reduced-motion: reduce) {
252
- .sv-progress-bar__fill,
253
- .sv-progress-bar__buffered,
254
- .sv-progress-bar__handle,
255
- .sv-progress-bar__tooltip {
256
- transition: none;
257
- }
258
- }
259
- `;
260
- var CSS_PREFIX = "sv-progress-bar";
261
- function formatTime(seconds) {
262
- if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
263
- const h = Math.floor(seconds / 3600);
264
- const m = Math.floor(seconds % 3600 / 60);
265
- const s = Math.floor(seconds % 60);
266
- if (h > 0) {
267
- return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
268
- }
269
- return `${m}:${s.toString().padStart(2, "0")}`;
270
- }
271
- function calculateProgress(currentTime, duration) {
272
- if (!duration || duration <= 0) return 0;
273
- return Math.min(100, Math.max(0, currentTime / duration * 100));
274
- }
275
- function calculateTimeFromPosition(clientX, rect, duration) {
276
- const x = clientX - rect.left;
277
- const percentage = Math.min(1, Math.max(0, x / rect.width));
278
- return percentage * duration;
279
- }
280
- function useProgressBarRefs({
281
- externalFillRef,
282
- externalBufferedRef,
283
- externalHandleRef,
284
- externalCurrentTimeRef,
285
- externalDurationRef
286
- }) {
287
- const containerRef = useRef(null);
288
- const internalFillRef = useRef(null);
289
- const internalBufferedRef = useRef(null);
290
- const internalHandleRef = useRef(null);
291
- const internalCurrentTimeRef = useRef(null);
292
- const internalDurationRef = useRef(null);
293
- const tooltipRef = useRef(null);
294
- return {
295
- containerRef,
296
- tooltipRef,
297
- fillRef: externalFillRef ?? internalFillRef,
298
- bufferedRef: externalBufferedRef ?? internalBufferedRef,
299
- handleRef: externalHandleRef ?? internalHandleRef,
300
- currentTimeRef: externalCurrentTimeRef ?? internalCurrentTimeRef,
301
- durationRef: externalDurationRef ?? internalDurationRef,
302
- hasExternalCurrentTimeRef: !!externalCurrentTimeRef,
303
- hasExternalDurationRef: !!externalDurationRef
304
- };
305
- }
306
- function useSeekHandlers({
307
- containerRef,
308
- duration,
309
- isSeekable,
310
- onSeek,
311
- onSeekStart,
312
- onSeekEnd
313
- }) {
314
- const [isSeeking, setIsSeeking] = useState(false);
315
- const [hoverTime, setHoverTime] = useState(null);
316
- const [hoverPosition, setHoverPosition] = useState(0);
317
- const handleSeek = useCallback(
318
- (clientX) => {
319
- if (!isSeekable || !containerRef.current) return;
320
- const rect = containerRef.current.getBoundingClientRect();
321
- const time = calculateTimeFromPosition(clientX, rect, duration);
322
- onSeek?.(time);
323
- },
324
- [isSeekable, duration, onSeek, containerRef]
325
- );
326
- const handlePointerDown = useCallback(
327
- (e) => {
328
- if (!isSeekable) return;
329
- e.preventDefault();
330
- e.stopPropagation();
331
- if (typeof e.currentTarget.setPointerCapture === "function") {
332
- e.currentTarget.setPointerCapture(e.pointerId);
333
- }
334
- setIsSeeking(true);
335
- onSeekStart?.();
336
- handleSeek(e.clientX);
337
- },
338
- [isSeekable, onSeekStart, handleSeek]
339
- );
340
- const handlePointerMove = useCallback(
341
- (e) => {
342
- if (!containerRef.current) return;
343
- const rect = containerRef.current.getBoundingClientRect();
344
- const time = calculateTimeFromPosition(e.clientX, rect, duration);
345
- const position = (e.clientX - rect.left) / rect.width * 100;
346
- setHoverTime(time);
347
- setHoverPosition(Math.min(100, Math.max(0, position)));
348
- if (isSeeking) handleSeek(e.clientX);
349
- },
350
- [duration, isSeeking, handleSeek, containerRef]
351
- );
352
- const handlePointerUp = useCallback(
353
- (e) => {
354
- e.stopPropagation();
355
- if (isSeeking) {
356
- if (typeof e.currentTarget.releasePointerCapture === "function") {
357
- e.currentTarget.releasePointerCapture(e.pointerId);
358
- }
359
- setIsSeeking(false);
360
- onSeekEnd?.();
361
- }
362
- },
363
- [isSeeking, onSeekEnd]
364
- );
365
- const handlePointerLeave = useCallback(() => {
366
- setHoverTime(null);
367
- if (isSeeking) {
368
- setIsSeeking(false);
369
- onSeekEnd?.();
370
- }
371
- }, [isSeeking, onSeekEnd]);
372
- return {
373
- isSeeking,
374
- hoverTime,
375
- hoverPosition,
376
- handlePointerDown,
377
- handlePointerMove,
378
- handlePointerUp,
379
- handlePointerLeave
380
- };
381
- }
382
- function ProgressBarHeadless({
383
- currentTime,
384
- duration,
385
- buffered = 0,
386
- seekable = false,
387
- className,
388
- onSeek,
389
- onSeekStart,
390
- onSeekEnd,
391
- showTime = false,
392
- showTooltip,
393
- minimal = false,
394
- fillRef: externalFillRef,
395
- bufferedRef: externalBufferedRef,
396
- handleRef: externalHandleRef,
397
- currentTimeRef: externalCurrentTimeRef,
398
- durationRef: externalDurationRef
399
- }) {
400
- useInsertionEffect(() => {
401
- return injectComponentCSS("progress-bar", PROGRESS_BAR_CSS);
402
- }, []);
403
- const refs = useProgressBarRefs({
404
- externalFillRef,
405
- externalBufferedRef,
406
- externalHandleRef,
407
- externalCurrentTimeRef,
408
- externalDurationRef
409
- });
410
- const progress = useMemo(() => calculateProgress(currentTime, duration), [currentTime, duration]);
411
- const bufferedPercent = useMemo(() => Math.min(100, Math.max(0, buffered * 100)), [buffered]);
412
- const isSeekable = seekable && !!onSeek && duration > 0;
413
- const effectiveShowTooltip = showTooltip ?? isSeekable;
414
- const {
415
- isSeeking,
416
- hoverTime,
417
- hoverPosition,
418
- handlePointerDown,
419
- handlePointerMove,
420
- handlePointerUp,
421
- handlePointerLeave
422
- } = useSeekHandlers({
423
- containerRef: refs.containerRef,
424
- duration,
425
- isSeekable,
426
- onSeek,
427
- onSeekStart,
428
- onSeekEnd
429
- });
430
- useEffect(() => {
431
- if (!refs.hasExternalCurrentTimeRef && refs.currentTimeRef.current) {
432
- refs.currentTimeRef.current.textContent = formatTime(currentTime);
433
- }
434
- }, [currentTime, refs]);
435
- useEffect(() => {
436
- if (!refs.hasExternalDurationRef && refs.durationRef.current) {
437
- refs.durationRef.current.textContent = formatTime(duration);
438
- }
439
- }, [duration, refs]);
440
- const stopBubble = useCallback((e) => {
441
- e.stopPropagation();
442
- }, []);
443
- return /* @__PURE__ */ jsxs(
444
- "div",
445
- {
446
- className: cn(
447
- CSS_PREFIX,
448
- !isSeekable && `${CSS_PREFIX}--disabled`,
449
- isSeeking && `${CSS_PREFIX}--seeking`,
450
- minimal && `${CSS_PREFIX}--minimal`,
451
- className
452
- ),
453
- onClick: stopBubble,
454
- onKeyDown: stopBubble,
455
- onPointerDown: stopBubble,
456
- onPointerUp: stopBubble,
457
- onTouchStart: stopBubble,
458
- onTouchEnd: stopBubble,
459
- children: [
460
- /* @__PURE__ */ jsxs("div", { className: `${CSS_PREFIX}__track-wrapper`, children: [
461
- /* @__PURE__ */ jsxs(
462
- "div",
463
- {
464
- ref: refs.containerRef,
465
- className: `${CSS_PREFIX}__track`,
466
- onPointerDown: handlePointerDown,
467
- onPointerMove: handlePointerMove,
468
- onPointerUp: handlePointerUp,
469
- onPointerLeave: handlePointerLeave,
470
- onClick: (e) => e.stopPropagation(),
471
- onKeyDown: (e) => e.stopPropagation(),
472
- role: isSeekable ? "slider" : "progressbar",
473
- "aria-label": "Video progress",
474
- "aria-valuemin": 0,
475
- "aria-valuemax": duration || 100,
476
- "aria-valuenow": currentTime,
477
- "aria-valuetext": `${formatTime(currentTime)} of ${formatTime(duration)}`,
478
- tabIndex: isSeekable ? 0 : -1,
479
- children: [
480
- /* @__PURE__ */ jsx(
481
- "div",
482
- {
483
- ref: refs.bufferedRef,
484
- className: `${CSS_PREFIX}__buffered`,
485
- style: { transform: `scaleX(${bufferedPercent / 100})` },
486
- "aria-hidden": "true"
487
- }
488
- ),
489
- /* @__PURE__ */ jsx(
490
- "div",
491
- {
492
- ref: refs.fillRef,
493
- className: `${CSS_PREFIX}__fill`,
494
- style: { transform: `scaleX(${progress / 100})` },
495
- "aria-hidden": "true"
496
- }
497
- ),
498
- isSeekable && !minimal && /* @__PURE__ */ jsx(
499
- "div",
500
- {
501
- ref: refs.handleRef,
502
- className: `${CSS_PREFIX}__handle`,
503
- style: { left: `${progress}%` },
504
- "aria-hidden": "true"
505
- }
506
- )
507
- ]
508
- }
509
- ),
510
- effectiveShowTooltip && hoverTime !== null && /* @__PURE__ */ jsx(
511
- "div",
512
- {
513
- ref: refs.tooltipRef,
514
- className: `${CSS_PREFIX}__tooltip`,
515
- style: { left: `${hoverPosition}%` },
516
- "aria-hidden": "true",
517
- children: formatTime(hoverTime)
518
- }
519
- )
520
- ] }),
521
- showTime && /* @__PURE__ */ jsxs("div", { className: `${CSS_PREFIX}__time`, children: [
522
- /* @__PURE__ */ jsx("span", { ref: refs.currentTimeRef, className: `${CSS_PREFIX}__time-current`, children: formatTime(currentTime) }),
523
- /* @__PURE__ */ jsx("span", { ref: refs.durationRef, className: `${CSS_PREFIX}__time-duration`, children: formatTime(duration) })
524
- ] })
525
- ]
526
- }
527
- );
528
- }
529
-
530
- export { PROGRESS_BAR_CSS, ProgressBarHeadless, calculateProgress, formatTime };