@xhub-short/ui 0.1.0-beta.9 → 1.0.0-beta.18

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 (74) hide show
  1. package/dist/CommentSheet.css-DuBy01rU.d.ts +219 -0
  2. package/dist/VideoSlotPlayIndicator-DPs8Xt5C.d.ts +51 -0
  3. package/dist/chunk-3OB3OVYR.js +349 -0
  4. package/dist/chunk-4RIMQOBR.js +58 -0
  5. package/dist/chunk-5MKYDI4X.js +1 -0
  6. package/dist/chunk-5Y43HNRG.js +296 -0
  7. package/dist/chunk-7WXAQHJI.js +350 -0
  8. package/dist/chunk-BADA7OLG.js +564 -0
  9. package/dist/chunk-BEJAJFV6.js +191 -0
  10. package/dist/chunk-BNI7CYRI.js +334 -0
  11. package/dist/{chunk-RMLTPW5S.js → chunk-CAWE42LH.js} +4 -3
  12. package/dist/chunk-DGKMO3AE.js +717 -0
  13. package/dist/chunk-DR7KR7OT.js +103 -0
  14. package/dist/chunk-GSNIZ6DF.js +605 -0
  15. package/dist/chunk-HXQPEZRG.js +105 -0
  16. package/dist/{chunk-FNXTPQ6L.js → chunk-IC2KUU4V.js} +31 -1340
  17. package/dist/chunk-IWSBYOSS.js +91 -0
  18. package/dist/chunk-MFJS65C5.js +368 -0
  19. package/dist/{chunk-AC2IFAJR.js → chunk-NJXIYSDZ.js} +12 -1
  20. package/dist/{chunk-CL6BS7GB.js → chunk-OM4L7RE5.js} +12 -2
  21. package/dist/chunk-QCRRF76W.js +75 -0
  22. package/dist/chunk-QUEJHA24.js +508 -0
  23. package/dist/chunk-UYBQTE4M.js +337 -0
  24. package/dist/chunk-VJ744W5N.js +603 -0
  25. package/dist/chunk-VXW7AOGM.js +285 -0
  26. package/dist/{chunk-AQHD6LPS.js → chunk-YB7AXTX7.js} +1 -1
  27. package/dist/components/ActionBar/index.d.ts +7 -2
  28. package/dist/components/ActionBar/index.js +1 -1
  29. package/dist/components/AdvanceMenu/index.d.ts +80 -0
  30. package/dist/components/AdvanceMenu/index.js +1 -0
  31. package/dist/components/ArticleSlot/index.d.ts +213 -0
  32. package/dist/components/ArticleSlot/index.js +1 -0
  33. package/dist/components/AuthorInfo/index.js +1 -1
  34. package/dist/components/BottomSheet/index.d.ts +87 -0
  35. package/dist/components/BottomSheet/index.js +1 -0
  36. package/dist/components/CleanModeOverlay/index.d.ts +60 -0
  37. package/dist/components/CleanModeOverlay/index.js +1 -0
  38. package/dist/components/CommentSheet/index.d.ts +1 -1
  39. package/dist/components/CommentSheet/index.js +1 -1
  40. package/dist/components/DetailView/index.d.ts +314 -0
  41. package/dist/components/DetailView/index.js +1 -0
  42. package/dist/components/ErrorBoundary/index.js +1 -1
  43. package/dist/components/{VideoFeed → Feed}/index.d.ts +64 -45
  44. package/dist/components/Feed/index.js +1 -0
  45. package/dist/components/ImageCarousel/index.d.ts +50 -0
  46. package/dist/components/ImageCarousel/index.js +1 -0
  47. package/dist/components/Playlist/index.d.ts +117 -0
  48. package/dist/components/Playlist/index.js +1 -0
  49. package/dist/components/ProgressBar/index.js +1 -1
  50. package/dist/components/QualityPicker/index.d.ts +35 -0
  51. package/dist/components/QualityPicker/index.js +1 -0
  52. package/dist/components/ReportSheet/index.d.ts +74 -0
  53. package/dist/components/ReportSheet/index.js +1 -0
  54. package/dist/components/Skeleton/index.js +1 -1
  55. package/dist/components/SpeedPicker/index.d.ts +32 -0
  56. package/dist/components/SpeedPicker/index.js +1 -0
  57. package/dist/components/VideoInfo/index.d.ts +7 -3
  58. package/dist/components/VideoInfo/index.js +1 -1
  59. package/dist/components/VideoPlayer/index.js +1 -1
  60. package/dist/components/VideoSlot/index.d.ts +31 -68
  61. package/dist/components/VideoSlot/index.js +2 -1
  62. package/dist/components/VirtualSlider/index.js +1 -1
  63. package/dist/index.d.ts +40 -10
  64. package/dist/index.js +23 -13
  65. package/package.json +8 -4
  66. package/dist/CommentSheet.css-BeCrEaUG.d.ts +0 -221
  67. package/dist/chunk-2FSDVYER.js +0 -737
  68. package/dist/chunk-ECR42RKK.js +0 -571
  69. package/dist/chunk-KWHMZ6H5.js +0 -562
  70. package/dist/chunk-SZXFH334.js +0 -204
  71. package/dist/chunk-UNV3NWN6.js +0 -148
  72. package/dist/chunk-WCRDTBCZ.js +0 -357
  73. package/dist/chunk-XDIH66C4.js +0 -1519
  74. package/dist/components/VideoFeed/index.js +0 -1
@@ -0,0 +1,337 @@
1
+ import { clsx } from 'clsx';
2
+ import { createContext, memo, useState, useRef, useEffect, useCallback, useContext } from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/components/BottomSheet/BottomSheet.css.ts
7
+ var BOTTOM_SHEET_CSS = `:root{--sv-sheet-bg:#fff;--sv-sheet-backdrop-bg:rgba(0,0,0,.5);--sv-sheet-handle-bg:rgba(0,0,0,.2);--sv-sheet-border-radius:24px;--sv-sheet-z-index:1000;--sv-sheet-animation-duration:300ms;--sv-sheet-animation-easing:cubic-bezier(.32,.72,0,1)}.sv-bottom-sheet-backdrop{position:fixed;inset:0;background:var(--sv-sheet-backdrop-bg);z-index:50;opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--sv-sheet-animation-duration)ease,visibility 0s linear var(--sv-sheet-animation-duration)}.sv-bottom-sheet-backdrop[data-state="open"]{opacity:1;visibility:visible;pointer-events:auto;transition:opacity var(--sv-sheet-animation-duration)ease,visibility 0s linear 0s}@keyframes sv-sheet-slide-up{from{transform:translateY(100vh)}to{transform:translateY(0)}}@keyframes sv-sheet-slide-down{from{transform:translateY(0)}to{transform:translateY(100vh)}}.sv-bottom-sheet{position:fixed;left:0;right:0;bottom:0;background:var(--sv-sheet-bg);border-radius:var(--sv-sheet-border-radius)var(--sv-sheet-border-radius)0 0;z-index:51;display:flex;flex-direction:column;max-height:var(--sv-sheet-max-height,80vh);transform:translateY(100vh);overflow:hidden;touch-action:pan-y;isolation:isolate;pointer-events:none;will-change:transform;outline:none}.sv-bottom-sheet[data-state="open"]{transform:translateY(0);pointer-events:auto;animation:sv-sheet-slide-up var(--sv-sheet-animation-duration)var(--sv-sheet-animation-easing)forwards}.sv-bottom-sheet[data-state="closing"]{pointer-events:none;animation:sv-sheet-slide-down var(--sv-sheet-animation-duration)var(--sv-sheet-animation-easing)forwards !important}.sv-bottom-sheet__handle{display:flex;justify-content:center;padding:12px 0 8px;cursor:grab;touch-action:none;flex-shrink:0}.sv-bottom-sheet__handle:active{cursor:grabbing}.sv-bottom-sheet__handle-bar{width:36px;height:4px;background:var(--sv-sheet-handle-bg);border-radius:2px}.sv-bottom-sheet__content{flex:1;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}body.sv-bottom-sheet-open{overflow:hidden !important;position:fixed !important;width:100% !important}body.sv-bottom-sheet-open .sv-slider,body.sv-bottom-sheet-open .sv-video-feed{pointer-events:none !important;touch-action:none !important}body.sv-bottom-sheet-open .sv-bottom-sheet,body.sv-bottom-sheet-open .sv-bottom-sheet-backdrop{touch-action:auto !important}`;
8
+ function injectBottomSheetCSS() {
9
+ if (typeof document === "undefined") return;
10
+ const styleId = "sv-bottom-sheet-styles";
11
+ if (!document.getElementById(styleId)) {
12
+ const style = document.createElement("style");
13
+ style.id = styleId;
14
+ style.textContent = BOTTOM_SHEET_CSS;
15
+ document.head.appendChild(style);
16
+ }
17
+ }
18
+ if (typeof document !== "undefined") {
19
+ injectBottomSheetCSS();
20
+ }
21
+ injectBottomSheetCSS();
22
+ var BottomSheetContext = createContext(null);
23
+ function useBottomSheetContext() {
24
+ const ctx = useContext(BottomSheetContext);
25
+ if (!ctx) {
26
+ throw new Error("useBottomSheetContext must be used within BottomSheetHeadless");
27
+ }
28
+ return ctx;
29
+ }
30
+ var DEFAULT_ANIMATION_DURATION = 300;
31
+ function BottomSheetHeadlessComponent({
32
+ isOpen,
33
+ onClose,
34
+ children,
35
+ height = "80vh",
36
+ className,
37
+ backdropClassName,
38
+ contentClassName,
39
+ closeOnBackdropClick = true,
40
+ closeOnEscape = true,
41
+ showDragHandle = false,
42
+ enableDragToDismiss = true,
43
+ dragCloseThreshold = 150,
44
+ ariaLabel = "Bottom sheet",
45
+ zIndex,
46
+ animationDuration = DEFAULT_ANIMATION_DURATION,
47
+ dragHandleSelector = ".sv-bottom-sheet__handle",
48
+ scrollContainerSelector = ".sv-bottom-sheet__content",
49
+ dragExcludeSelector,
50
+ onGestureLock
51
+ }) {
52
+ const [isClosing, setIsClosing] = useState(false);
53
+ const [isVisible, setIsVisible] = useState(false);
54
+ const sheetRef = useRef(null);
55
+ const dragStartY = useRef(0);
56
+ const currentTranslateY = useRef(0);
57
+ const isDragging = useRef(false);
58
+ const isDragClosing = useRef(false);
59
+ const closeTimeoutRef = useRef(null);
60
+ const openedAtRef = useRef(0);
61
+ const scrollYRef = useRef(0);
62
+ const dragSourceRef = useRef(null);
63
+ useEffect(() => {
64
+ if (isOpen) {
65
+ setIsVisible(true);
66
+ openedAtRef.current = Date.now();
67
+ setIsClosing(false);
68
+ if (closeTimeoutRef.current) {
69
+ clearTimeout(closeTimeoutRef.current);
70
+ closeTimeoutRef.current = null;
71
+ }
72
+ }
73
+ }, [isOpen]);
74
+ const handleClose = useCallback(() => {
75
+ if (isClosing) return;
76
+ const timeSinceOpen = Date.now() - openedAtRef.current;
77
+ if (timeSinceOpen < 100) return;
78
+ setIsClosing(true);
79
+ closeTimeoutRef.current = setTimeout(() => {
80
+ setIsClosing(false);
81
+ setIsVisible(false);
82
+ onClose();
83
+ }, animationDuration);
84
+ }, [isClosing, onClose, animationDuration]);
85
+ useEffect(() => {
86
+ return () => {
87
+ if (closeTimeoutRef.current) {
88
+ clearTimeout(closeTimeoutRef.current);
89
+ }
90
+ };
91
+ }, []);
92
+ useEffect(() => {
93
+ if (isOpen && sheetRef.current) {
94
+ requestAnimationFrame(() => {
95
+ sheetRef.current?.focus();
96
+ });
97
+ }
98
+ }, [isOpen]);
99
+ useEffect(() => {
100
+ if (!isOpen || !closeOnEscape) return;
101
+ const handleKeyDown = (e) => {
102
+ if (e.key === "Escape") {
103
+ e.preventDefault();
104
+ handleClose();
105
+ }
106
+ };
107
+ document.addEventListener("keydown", handleKeyDown);
108
+ return () => document.removeEventListener("keydown", handleKeyDown);
109
+ }, [isOpen, closeOnEscape, handleClose]);
110
+ const handleBackdropClick = useCallback(
111
+ (e) => {
112
+ e.stopPropagation();
113
+ if (closeOnBackdropClick && e.target === e.currentTarget) {
114
+ handleClose();
115
+ }
116
+ },
117
+ [closeOnBackdropClick, handleClose]
118
+ );
119
+ const handleEventBlocker = useCallback((e) => {
120
+ e.stopPropagation();
121
+ }, []);
122
+ const handleSheetClick = useCallback((e) => {
123
+ e.stopPropagation();
124
+ }, []);
125
+ const onGestureLockRef = useRef(onGestureLock);
126
+ useEffect(() => {
127
+ onGestureLockRef.current = onGestureLock;
128
+ }, [onGestureLock]);
129
+ useEffect(() => {
130
+ if (!isOpen) return;
131
+ scrollYRef.current = window.scrollY;
132
+ document.body.classList.add("sv-bottom-sheet-open");
133
+ document.body.style.top = `-${scrollYRef.current}px`;
134
+ onGestureLockRef.current?.(true);
135
+ return () => {
136
+ document.body.classList.remove("sv-bottom-sheet-open");
137
+ document.body.style.top = "";
138
+ if (typeof window !== "undefined") {
139
+ window.scrollTo(0, scrollYRef.current);
140
+ }
141
+ onGestureLockRef.current?.(false);
142
+ };
143
+ }, [isOpen]);
144
+ const isScrollContainerAtTop = useCallback(() => {
145
+ const container = sheetRef.current?.querySelector(scrollContainerSelector);
146
+ if (!container) return true;
147
+ return container.scrollTop <= 0;
148
+ }, [scrollContainerSelector]);
149
+ const getDragSource = useCallback(
150
+ (target) => {
151
+ if (dragExcludeSelector && target.closest(dragExcludeSelector)) {
152
+ return null;
153
+ }
154
+ const isHandle = target.closest(dragHandleSelector);
155
+ if (isHandle) return "handle";
156
+ const isInScrollContainer = target.closest(scrollContainerSelector);
157
+ if (isInScrollContainer && isScrollContainerAtTop()) return "overscroll";
158
+ return null;
159
+ },
160
+ [dragHandleSelector, scrollContainerSelector, dragExcludeSelector, isScrollContainerAtTop]
161
+ );
162
+ useEffect(() => {
163
+ if (!isOpen || !sheetRef.current) return;
164
+ sheetRef.current.style.transform = "";
165
+ sheetRef.current.style.transition = "";
166
+ sheetRef.current.style.animation = "";
167
+ currentTranslateY.current = 0;
168
+ isDragging.current = false;
169
+ dragSourceRef.current = null;
170
+ isDragClosing.current = false;
171
+ }, [isOpen]);
172
+ const animateClose = useCallback(
173
+ (sheet) => {
174
+ isDragClosing.current = true;
175
+ sheet.style.transition = `transform ${animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1)`;
176
+ sheet.style.transform = "translateY(100vh)";
177
+ closeTimeoutRef.current = setTimeout(() => {
178
+ isDragClosing.current = false;
179
+ setIsVisible(false);
180
+ onClose();
181
+ }, animationDuration);
182
+ },
183
+ [onClose, animationDuration]
184
+ );
185
+ const animateSnapBack = useCallback(
186
+ (sheet) => {
187
+ sheet.style.transition = `transform ${animationDuration}ms cubic-bezier(0.32, 0.72, 0, 1)`;
188
+ sheet.style.transform = "translateY(0)";
189
+ setTimeout(() => {
190
+ sheet.style.transition = "";
191
+ sheet.style.transform = "";
192
+ }, animationDuration);
193
+ },
194
+ [animationDuration]
195
+ );
196
+ useEffect(() => {
197
+ if (!isVisible || !enableDragToDismiss) return;
198
+ let mounted = true;
199
+ const handlersRef = {
200
+ onTouchStart: null,
201
+ onTouchMove: null,
202
+ onTouchEnd: null
203
+ };
204
+ requestAnimationFrame(() => {
205
+ if (!mounted) return;
206
+ const sheet = sheetRef.current;
207
+ if (!sheet) return;
208
+ const onTouchStart = (e) => {
209
+ dragStartY.current = e.touches[0]?.clientY ?? 0;
210
+ const source = getDragSource(e.target);
211
+ if (!source) return;
212
+ dragSourceRef.current = source;
213
+ isDragging.current = true;
214
+ currentTranslateY.current = 0;
215
+ sheet.style.animation = "none";
216
+ sheet.style.transition = "none";
217
+ void sheet.offsetHeight;
218
+ };
219
+ const onTouchMove = (e) => {
220
+ const clientY = e.touches[0]?.clientY ?? 0;
221
+ const deltaY = clientY - dragStartY.current;
222
+ if (!isDragging.current && deltaY > 0 && isScrollContainerAtTop()) {
223
+ const source = getDragSource(e.target);
224
+ if (source) {
225
+ isDragging.current = true;
226
+ dragSourceRef.current = source;
227
+ dragStartY.current = clientY;
228
+ sheet.style.animation = "none";
229
+ sheet.style.transition = "none";
230
+ void sheet.offsetHeight;
231
+ return;
232
+ }
233
+ }
234
+ if (dragSourceRef.current === "overscroll" && (deltaY <= 0 || !isScrollContainerAtTop())) {
235
+ isDragging.current = false;
236
+ return;
237
+ }
238
+ if (!isDragging.current) return;
239
+ currentTranslateY.current = Math.max(0, deltaY);
240
+ if (currentTranslateY.current > 0) {
241
+ e.preventDefault();
242
+ }
243
+ sheet.style.transform = `translateY(${currentTranslateY.current}px)`;
244
+ };
245
+ const onTouchEnd = () => {
246
+ dragSourceRef.current = null;
247
+ if (!isDragging.current) return;
248
+ isDragging.current = false;
249
+ const dragDistance = currentTranslateY.current;
250
+ currentTranslateY.current = 0;
251
+ if (dragDistance > dragCloseThreshold) {
252
+ animateClose(sheet);
253
+ } else if (dragDistance > 0) {
254
+ animateSnapBack(sheet);
255
+ }
256
+ };
257
+ handlersRef.onTouchStart = onTouchStart;
258
+ handlersRef.onTouchMove = onTouchMove;
259
+ handlersRef.onTouchEnd = onTouchEnd;
260
+ sheet.addEventListener("touchstart", onTouchStart, { passive: false });
261
+ sheet.addEventListener("touchmove", onTouchMove, { passive: false });
262
+ sheet.addEventListener("touchend", onTouchEnd, { passive: false });
263
+ });
264
+ return () => {
265
+ mounted = false;
266
+ const sheet = sheetRef.current;
267
+ if (sheet && handlersRef.onTouchStart && handlersRef.onTouchMove && handlersRef.onTouchEnd) {
268
+ sheet.removeEventListener("touchstart", handlersRef.onTouchStart);
269
+ sheet.removeEventListener("touchmove", handlersRef.onTouchMove);
270
+ sheet.removeEventListener("touchend", handlersRef.onTouchEnd);
271
+ }
272
+ };
273
+ }, [
274
+ isVisible,
275
+ enableDragToDismiss,
276
+ dragCloseThreshold,
277
+ isScrollContainerAtTop,
278
+ getDragSource,
279
+ animateClose,
280
+ animateSnapBack
281
+ ]);
282
+ if (!isVisible || typeof document === "undefined") return null;
283
+ const backdropState = isClosing || isDragClosing.current ? "closing" : isOpen ? "open" : "closed";
284
+ const sheetState = isClosing && !isDragClosing.current ? "closing" : isOpen ? "open" : "closed";
285
+ const sheetStyle = {
286
+ "--sv-sheet-max-height": height,
287
+ ...zIndex !== void 0 && { "--sv-sheet-z-index": zIndex },
288
+ ...animationDuration !== DEFAULT_ANIMATION_DURATION && {
289
+ "--sv-sheet-animation-duration": `${animationDuration}ms`
290
+ }
291
+ };
292
+ const backdropStyle = zIndex !== void 0 ? { "--sv-sheet-z-index": zIndex } : {};
293
+ return createPortal(
294
+ /* @__PURE__ */ jsxs(BottomSheetContext.Provider, { value: { isOpen, onClose: handleClose }, children: [
295
+ /* @__PURE__ */ jsx(
296
+ "div",
297
+ {
298
+ className: clsx("sv-bottom-sheet-backdrop", backdropClassName),
299
+ "data-state": backdropState,
300
+ onClick: handleBackdropClick,
301
+ onPointerDown: handleEventBlocker,
302
+ onPointerUp: handleEventBlocker,
303
+ onTouchStart: handleEventBlocker,
304
+ onTouchEnd: handleEventBlocker,
305
+ style: backdropStyle,
306
+ "aria-hidden": "true"
307
+ }
308
+ ),
309
+ /* @__PURE__ */ jsxs(
310
+ "div",
311
+ {
312
+ ref: sheetRef,
313
+ className: clsx("sv-bottom-sheet", className),
314
+ "data-state": sheetState,
315
+ style: sheetStyle,
316
+ "aria-modal": "true",
317
+ "aria-label": ariaLabel,
318
+ tabIndex: -1,
319
+ onClick: handleSheetClick,
320
+ onPointerDown: handleEventBlocker,
321
+ onPointerUp: handleEventBlocker,
322
+ onTouchStart: handleEventBlocker,
323
+ onTouchEnd: handleEventBlocker,
324
+ children: [
325
+ showDragHandle && /* @__PURE__ */ jsx("div", { className: "sv-bottom-sheet__handle", children: /* @__PURE__ */ jsx("div", { className: "sv-bottom-sheet__handle-bar" }) }),
326
+ /* @__PURE__ */ jsx("div", { className: clsx("sv-bottom-sheet__content", contentClassName), children })
327
+ ]
328
+ }
329
+ )
330
+ ] }),
331
+ document.body
332
+ );
333
+ }
334
+ var BottomSheetHeadless = memo(BottomSheetHeadlessComponent);
335
+ BottomSheetHeadless.displayName = "BottomSheetHeadless";
336
+
337
+ export { BOTTOM_SHEET_CSS, BottomSheetHeadless, injectBottomSheetCSS, useBottomSheetContext };