@xhub-short/ui 0.1.0-beta.0 → 0.1.0-beta.2

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 (39) hide show
  1. package/dist/CommentSheet.css-DR3Wcn0F.d.ts +207 -0
  2. package/dist/{chunk-WKX2WBVO.js → chunk-3XPJHUYL.js} +1 -39
  3. package/dist/{chunk-YW23IBKF.js → chunk-5U3NZZGG.js} +45 -4
  4. package/dist/{chunk-UECU42WC.js → chunk-6LKRB7CM.js} +30 -15
  5. package/dist/{chunk-MMTAPG2C.js → chunk-ANCP53F3.js} +10 -4
  6. package/dist/chunk-DHQJBXQW.js +562 -0
  7. package/dist/chunk-EDWS2IPH.js +1 -0
  8. package/dist/chunk-GGQNSM6R.js +2016 -0
  9. package/dist/{chunk-OXY5JHVJ.js → chunk-JDNPQHFE.js} +28 -13
  10. package/dist/{chunk-ZZDQKP4R.js → chunk-KGMGUOLY.js} +93 -154
  11. package/dist/{chunk-4MN72OZH.js → chunk-N62QNEY5.js} +3 -3
  12. package/dist/chunk-NIFL42PC.js +740 -0
  13. package/dist/chunk-RE62D5GG.js +430 -0
  14. package/dist/{chunk-QKQUXR3H.js → chunk-WLJCY7W3.js} +258 -57
  15. package/dist/components/ActionBar/index.d.ts +1 -1
  16. package/dist/components/ActionBar/index.js +1 -1
  17. package/dist/components/AuthorInfo/index.d.ts +278 -0
  18. package/dist/components/AuthorInfo/index.js +1 -0
  19. package/dist/components/CommentSheet/index.d.ts +12 -0
  20. package/dist/components/CommentSheet/index.js +1 -0
  21. package/dist/components/ProgressBar/index.d.ts +30 -2
  22. package/dist/components/ProgressBar/index.js +1 -1
  23. package/dist/components/Skeleton/index.js +1 -1
  24. package/dist/components/VideoFeed/index.d.ts +11 -0
  25. package/dist/components/VideoFeed/index.js +1 -1
  26. package/dist/components/VideoInfo/index.d.ts +160 -0
  27. package/dist/components/VideoInfo/index.js +1 -0
  28. package/dist/components/VideoPlayer/index.d.ts +35 -41
  29. package/dist/components/VideoPlayer/index.js +1 -1
  30. package/dist/components/VideoSlot/index.d.ts +124 -64
  31. package/dist/components/VideoSlot/index.js +1 -1
  32. package/dist/components/VirtualSlider/index.d.ts +339 -0
  33. package/dist/components/VirtualSlider/index.js +1 -0
  34. package/dist/components/icons/index.d.ts +3 -1
  35. package/dist/components/icons/index.js +1 -1
  36. package/dist/index.d.ts +294 -98
  37. package/dist/index.js +437 -12
  38. package/package.json +51 -7
  39. package/dist/use-gesture-react.esm-3SV4QLEJ.js +0 -1893
@@ -0,0 +1,207 @@
1
+ import * as react from 'react';
2
+ import react__default, { ReactElement, ReactNode } from 'react';
3
+ import { CommentItem, UICommentState, UICommentActions, CommentConfig } from '@xhub-short/contracts';
4
+
5
+ interface CommentInputProps {
6
+ /** Placeholder text */
7
+ placeholder?: string;
8
+ /** Quick emojis */
9
+ emojis?: string[];
10
+ /** Max input length */
11
+ maxLength?: number;
12
+ /** Custom class */
13
+ className?: string;
14
+ /** On submit callback */
15
+ onSubmitSuccess?: () => void;
16
+ /** On media button click */
17
+ onMediaClick?: () => void;
18
+ /** Reply to text (default: "Replying to") */
19
+ replyingToText?: string;
20
+ /** Reply placeholder template (default: "Reply to @{name}...") - {name} will be replaced */
21
+ replyPlaceholderTemplate?: string;
22
+ /** Cancel reply aria-label (default: "Cancel reply") */
23
+ cancelReplyAriaLabel?: string;
24
+ /** Add media aria-label (default: "Add media") */
25
+ addMediaAriaLabel?: string;
26
+ /** Submit comment aria-label (default: "Submit comment") */
27
+ submitAriaLabel?: string;
28
+ /** Open emoji aria-label (default: "Open emoji") */
29
+ emojiAriaLabel?: string;
30
+ /** Emoji button aria-label template (default: "Add {emoji}") */
31
+ addEmojiAriaLabel?: string;
32
+ }
33
+ declare const CommentInput: react.NamedExoticComponent<CommentInputProps>;
34
+
35
+ interface CommentItemProps {
36
+ comment: CommentItem;
37
+ className?: string;
38
+ }
39
+ declare const CommentItemComponent: react.NamedExoticComponent<CommentItemProps>;
40
+
41
+ interface CommentListProps {
42
+ /** Custom empty state */
43
+ emptyState?: ReactElement;
44
+ /** Custom loading state */
45
+ loadingState?: ReactElement;
46
+ /** Custom error state */
47
+ errorState?: (error: Error, retry: () => void) => ReactElement;
48
+ /** Custom class */
49
+ className?: string;
50
+ /** Error text (default: "Failed to load comments") */
51
+ errorText?: string;
52
+ /** Retry button text (default: "Try again") */
53
+ retryText?: string;
54
+ /** Empty state text (default: "No comments yet. Be the first!") */
55
+ emptyText?: string;
56
+ /** Load more button text (default: "Load more comments") */
57
+ loadMoreText?: string;
58
+ }
59
+ declare const CommentList: react.NamedExoticComponent<CommentListProps>;
60
+
61
+ /**
62
+ * i18n strings for CommentSheet internal components
63
+ */
64
+ interface CommentSheetI18n {
65
+ /** Text for "See more" button (default: "See more") */
66
+ expandText?: string;
67
+ /** Text for "See less" button (default: "See less") */
68
+ collapseText?: string;
69
+ /** Text for view replies - use {count} placeholder (default: "View {count} more replies") */
70
+ viewRepliesText?: string;
71
+ /** Text for hide replies (default: "Hide replies") */
72
+ hideRepliesText?: string;
73
+ /** Text for load replies (default: "Load replies") */
74
+ loadRepliesText?: string;
75
+ /** Text for view more replies (default: "View more replies") */
76
+ viewMoreRepliesText?: string;
77
+ /** Function to format relative time */
78
+ formatRelativeTime?: (dateStr: string) => string;
79
+ }
80
+ /**
81
+ * CommentSheet context value
82
+ */
83
+ interface CommentSheetContextValue {
84
+ /** Comment state */
85
+ state: UICommentState;
86
+ /** Comment actions */
87
+ actions: UICommentActions;
88
+ /** Video ID */
89
+ videoId: string;
90
+ /** Config */
91
+ config: CommentConfig;
92
+ /** Whether sheet is open */
93
+ isOpen: boolean;
94
+ /** Close sheet */
95
+ onClose: () => void;
96
+ /** Reply target (when replying to a comment) */
97
+ replyTarget: ReplyTarget | null;
98
+ /** Set reply target */
99
+ setReplyTarget: (target: ReplyTarget | null) => void;
100
+ /** Initial count from video data (used before API loads) */
101
+ initialCount?: number;
102
+ /** i18n strings for internal components */
103
+ i18n: CommentSheetI18n;
104
+ }
105
+ /**
106
+ * Reply target info
107
+ */
108
+ interface ReplyTarget {
109
+ /** Parent comment ID */
110
+ commentId: string;
111
+ /** Author name for @mention */
112
+ authorName: string;
113
+ /** Author ID */
114
+ authorId: string;
115
+ }
116
+ /**
117
+ * CommentSheet context
118
+ */
119
+ declare const CommentSheetContext: react.Context<CommentSheetContextValue | undefined>;
120
+ /**
121
+ * Hook to use CommentSheet context
122
+ * @throws if used outside of CommentSheetHeadless
123
+ */
124
+ declare function useCommentSheetContext(): CommentSheetContextValue;
125
+ /**
126
+ * Hook to optionally use CommentSheet context
127
+ * @returns context or undefined if not within CommentSheetHeadless
128
+ */
129
+ declare function useOptionalCommentSheetContext(): CommentSheetContextValue | undefined;
130
+
131
+ interface SheetHeaderProps {
132
+ /** Custom title label (default: "Comments") */
133
+ titleLabel?: string;
134
+ /** Show drag handle */
135
+ showHandle?: boolean;
136
+ /** Show sort button */
137
+ showSort?: boolean;
138
+ /** Sort click handler */
139
+ onSortClick?: () => void;
140
+ /** Custom close icon */
141
+ closeIcon?: ReactElement;
142
+ /** Custom class */
143
+ className?: string;
144
+ /** Sort button aria-label (default: "Sort comments") */
145
+ sortAriaLabel?: string;
146
+ /** Close button aria-label (default: "Close comments") */
147
+ closeAriaLabel?: string;
148
+ }
149
+ declare const SheetHeader: react__default.NamedExoticComponent<SheetHeaderProps>;
150
+
151
+ interface CommentSheetHeadlessProps {
152
+ /** Whether sheet is open */
153
+ isOpen: boolean;
154
+ /** Close callback */
155
+ onClose: () => void;
156
+ /** Video ID for comments */
157
+ videoId: string;
158
+ /** Comment state from SDK */
159
+ state: UICommentState;
160
+ /** Comment actions from SDK */
161
+ actions: UICommentActions;
162
+ /** Config */
163
+ config?: Partial<CommentConfig>;
164
+ /** Initial count from video data (displayed before API loads) */
165
+ initialCount?: number;
166
+ /** Custom children (compound pattern) */
167
+ children?: ReactNode;
168
+ /** Root class name */
169
+ className?: string;
170
+ /** Backdrop class name */
171
+ backdropClassName?: string;
172
+ /** Close on backdrop click */
173
+ closeOnBackdropClick?: boolean;
174
+ /** Close on escape key */
175
+ closeOnEscape?: boolean;
176
+ /** Enable drag-to-dismiss */
177
+ enableDragToDismiss?: boolean;
178
+ /** Drag threshold to close (px) */
179
+ dragCloseThreshold?: number;
180
+ /** i18n strings for internal components (CommentItem, etc.) */
181
+ i18n?: CommentSheetI18n;
182
+ }
183
+ declare const CommentSheetHeadless: react.NamedExoticComponent<CommentSheetHeadlessProps>;
184
+ declare const CommentSheet: react.NamedExoticComponent<CommentSheetHeadlessProps> & {
185
+ Header: react.NamedExoticComponent<SheetHeaderProps>;
186
+ List: react.NamedExoticComponent<CommentListProps>;
187
+ Input: react.NamedExoticComponent<CommentInputProps>;
188
+ Item: react.NamedExoticComponent<CommentItemProps>;
189
+ };
190
+
191
+ /**
192
+ * CommentSheet CSS
193
+ *
194
+ * Modern bottom sheet for comments (Light Theme)
195
+ * Based on Figma design: https://figma.com/design/Kd1lJUJ4B3Kuw3dV9UcUok
196
+ * Features:
197
+ * - Light theme with clean aesthetics
198
+ * - Slide-up animation
199
+ * - Backdrop with click-to-close
200
+ * - Keyboard-aware input positioning
201
+ * - Scrollable comment list
202
+ * - Pinned comment support
203
+ * - Vertical reply thread lines
204
+ */
205
+ declare const COMMENT_SHEET_CSS = "\n/* \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\n CSS VARIABLES (Light Theme)\n \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 */\n\n:root {\n /* Primary colors */\n --sv-comment-primary: #164d8e;\n --sv-comment-primary-light: #1354ae;\n --sv-comment-primary-dark: #003477;\n \n /* Contrast colors */\n --sv-comment-bg: #ffffff;\n --sv-comment-text: #121212;\n --sv-comment-text-secondary: #6b7271;\n --sv-comment-border: rgba(18, 18, 18, 0.08);\n \n /* Accent colors */\n --sv-comment-like-color: #ff434e;\n --sv-comment-verified-color: #1ea031;\n --sv-comment-mention-color: #164d8e;\n \n /* Component specific */\n --sv-comment-avatar-bg: #e5e6e6;\n --sv-comment-input-border: #a3a3a3;\n --sv-comment-reply-line: #e5e6e6;\n}\n\n/* \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\n BACKDROP & CONTAINER\n \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 */\n\n.sv-comment-sheet-backdrop {\n position: fixed;\n inset: 0;\n background: var(--sv-comment-backdrop-bg, rgba(0, 0, 0, 0.5));\n z-index: var(--sv-comment-sheet-z-index, 1000);\n opacity: 0;\n visibility: hidden;\n pointer-events: none;\n transition: opacity var(--sv-comment-animation-duration, 400ms) ease,\n visibility 0s linear var(--sv-comment-animation-duration, 400ms);\n}\n\n.sv-comment-sheet-backdrop--open {\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n transition: opacity var(--sv-comment-animation-duration, 400ms) ease,\n visibility 0s linear 0s;\n}\n\n/* Keyframes for slide animations */\n@keyframes sv-sheet-slide-up {\n from { transform: translateY(100%); }\n to { transform: translateY(0); }\n}\n\n@keyframes sv-sheet-slide-down {\n from { transform: translateY(0); }\n to { transform: translateY(100%); }\n}\n\n.sv-comment-sheet {\n position: fixed;\n margin: 16px;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--sv-comment-bg, #ffffff);\n border-radius: var(--sv-comment-sheet-radius, 24px);\n z-index: var(--sv-comment-sheet-z-index, 1001);\n display: flex;\n flex-direction: column;\n max-height: var(--sv-comment-sheet-height, 55vh);\n transform: translateY(100%);\n overflow: hidden;\n touch-action: pan-y;\n isolation: isolate;\n pointer-events: none;\n will-change: transform;\n}\n\n.sv-comment-sheet--open {\n transform: translateY(0);\n pointer-events: auto;\n animation: sv-sheet-slide-up var(--sv-comment-animation-duration, 400ms) \n var(--sv-comment-animation-easing, cubic-bezier(0.32, 0.72, 0, 1)) forwards;\n}\n\n.sv-comment-sheet--open.sv-comment-sheet--closing {\n pointer-events: none;\n animation: sv-sheet-slide-down var(--sv-comment-animation-duration, 400ms) \n var(--sv-comment-animation-easing, cubic-bezier(0.32, 0.72, 0, 1)) forwards !important;\n}\n\n/* CRITICAL: Disable VirtualSlider/VideoFeed swipe when CommentSheet is open */\nbody.sv-comment-sheet-open .sv-slider,\nbody.sv-comment-sheet-open .sv-video-feed {\n pointer-events: none !important;\n touch-action: none !important;\n}\n\nbody.sv-comment-sheet-open .sv-comment-sheet,\nbody.sv-comment-sheet-open .sv-comment-sheet-backdrop {\n touch-action: auto !important;\n}\n\n/* \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\n HEADER\n \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 */\n\n.sv-comment-sheet__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px;\n border-bottom: 1px solid var(--sv-comment-border);\n flex-shrink: 0;\n position: relative;\n cursor: grab;\n touch-action: none;\n}\n\n.sv-comment-sheet__header:active {\n cursor: grabbing;\n}\n\n.sv-comment-sheet__header-handle {\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 36px;\n height: 4px;\n background: var(--sv-comment-text-secondary);\n border-radius: 2px;\n opacity: 0.3;\n}\n\n.sv-comment-sheet__header-left {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n\n.sv-comment-sheet__title {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 18px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--sv-comment-text);\n opacity: 0.9;\n margin: 0;\n}\n\n.sv-comment-sheet__sort-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--sv-comment-text);\n}\n\n.sv-comment-sheet__sort-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-sheet__close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border: none;\n border-radius: 100px;\n background: linear-gradient(180deg, var(--sv-comment-primary-light) 0%, var(--sv-comment-primary-dark) 100%);\n cursor: pointer;\n transition: opacity 0.15s ease;\n}\n\n.sv-comment-sheet__close-btn:hover {\n opacity: 0.9;\n}\n\n.sv-comment-sheet__close-btn svg {\n width: 20px;\n height: 20px;\n color: #ffffff;\n}\n\n/* \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\n COMMENT LIST\n \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 */\n\n.sv-comment-sheet__list {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 8px 16px 28px 16px;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior: contain;\n touch-action: pan-y;\n}\n\n.sv-comment-sheet__list::-webkit-scrollbar {\n width: 0px;\n}\n\n.sv-comment-sheet__list::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.0);\n border-radius: 0px;\n}\n\n/* \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\n COMMENT ITEM\n \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 */\n\n.sv-comment-item {\n display: flex;\n gap: 6px;\n padding: 16px 0;\n position: relative;\n}\n\n.sv-comment-item--pending {\n opacity: 0.6;\n}\n\n.sv-comment-item--pinned {\n background: var(--sv-comment-bg);\n}\n\n.sv-comment-item__avatar {\n width: 40px;\n height: 40px;\n border-radius: 120px;\n flex-shrink: 0;\n object-fit: cover;\n background: var(--sv-comment-avatar-bg);\n}\n\n.sv-comment-item__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.sv-comment-item__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 4px;\n}\n\n.sv-comment-item__header-left {\n display: flex;\n align-items: center;\n gap: 4px;\n min-width: 0;\n}\n\n.sv-comment-item__pin-icon {\n width: 16px;\n height: 16px;\n flex-shrink: 0;\n color: var(--sv-comment-primary);\n}\n\n.sv-comment-item__author {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 14px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--sv-comment-text);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.sv-comment-item__verified {\n width: 12px;\n height: 12px;\n flex-shrink: 0;\n color: var(--sv-comment-verified-color);\n}\n\n.sv-comment-item__badge {\n font-size: 10px;\n padding: 2px 6px;\n background: var(--sv-comment-primary);\n color: #ffffff;\n border-radius: 4px;\n flex-shrink: 0;\n}\n\n.sv-comment-item__menu-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-item__menu-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-item__text {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 400;\n line-height: 1.4;\n color: var(--sv-comment-text);\n word-break: break-word;\n margin: 0;\n padding-right: 16px;\n}\n\n/* Text collapse */\n.sv-comment-item__text--collapsed {\n display: -webkit-box;\n -webkit-line-clamp: var(--sv-comment-max-lines, 3);\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.sv-comment-item__expand-btn {\n background: none;\n border: none;\n padding: 0;\n font-size: 12px;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n margin-top: 4px;\n}\n\n.sv-comment-item__expand-btn:hover {\n color: var(--sv-comment-text);\n}\n\n/* Actions row */\n.sv-comment-item__actions {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.sv-comment-item__time {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.2;\n color: var(--sv-comment-text-secondary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.sv-comment-item__action-btn {\n display: flex;\n align-items: center;\n gap: 4px;\n background: none;\n border: none;\n padding: 0;\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-weight: 500;\n line-height: 1.2;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n transition: color 0.15s ease;\n}\n\n.sv-comment-item__action-btn:hover {\n color: var(--sv-comment-text);\n}\n\n.sv-comment-item__action-btn--active {\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-item__action-btn--active:hover {\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-item__action-icon {\n width: 20px;\n height: 20px;\n}\n\n/* \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\n REPLIES\n \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 */\n\n.sv-comment-replies {\n margin-top: 12px;\n position: relative;\n}\n\n/* Vertical connecting line */\n.sv-comment-item--has-replies::before {\n content: '';\n position: absolute;\n left: 20px;\n top: 56px;\n bottom: 0;\n width: 1px;\n background: var(--sv-comment-reply-line);\n}\n\n.sv-comment-replies__toggle {\n display: flex;\n align-items: center;\n gap: 0;\n background: none;\n border: none;\n padding: 4px 0;\n cursor: pointer;\n}\n\n.sv-comment-replies__toggle-line {\n width: 24px;\n height: 1px;\n background: #a3a3a3;\n margin-right: 0;\n}\n\n.sv-comment-replies__toggle-text {\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 13px;\n font-weight: 600;\n line-height: 1.4;\n color: var(--sv-comment-text-secondary);\n white-space: nowrap;\n}\n\n.sv-comment-replies__toggle-icon {\n width: 20px;\n height: 20px;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-replies__list {\n margin-top: 12px;\n}\n\n.sv-comment-reply {\n display: flex;\n gap: 6px;\n padding: 0 0 12px 0;\n position: relative;\n}\n\n.sv-comment-reply__avatar {\n width: 24px;\n height: 24px;\n border-radius: 100px;\n flex-shrink: 0;\n object-fit: cover;\n background: var(--sv-comment-avatar-bg);\n}\n\n.sv-comment-reply__mention {\n color: var(--sv-comment-mention-color);\n font-weight: 500;\n}\n\n/* \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\n INPUT AREA\n \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 */\n\n.sv-comment-sheet__input-area {\n padding: 0 16px 36px 16px;\n flex-shrink: 0;\n}\n\n.sv-comment-sheet__reply-to {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 0;\n margin-bottom: 8px;\n font-size: 12px;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-sheet__reply-to-author-name {\n font-size: 12px;\n color: var(--sv-comment-text);\n font-weight: 500;\n}\n\n.sv-comment-sheet__reply-to-clear {\n background: none;\n border: none;\n padding: 4px;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n font-size: 12px;\n}\n\n.sv-comment-sheet__input-wrapper {\n display: flex;\n align-items: center;\n gap: 8px;\n height: 44px;\n padding: 16px;\n background: var(--sv-comment-bg);\n border: 1px solid var(--sv-comment-input-border);\n border-radius: 12px;\n backdrop-filter: blur(50px);\n}\n\n.sv-comment-sheet__input-left {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: 1;\n min-width: 0;\n}\n\n.sv-comment-sheet__media-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.sv-comment-sheet__media-btn svg {\n width: 20px;\n height: 20px;\n}\n\n.sv-comment-sheet__input {\n flex: 1;\n background: none;\n border: none;\n outline: none;\n resize: none;\n font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 12px;\n font-style: italic;\n font-weight: 400;\n line-height: 1.4;\n color: var(--sv-comment-text);\n padding: 0;\n min-width: 0;\n}\n\n.sv-comment-sheet__input::placeholder {\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-sheet__input:not(:placeholder-shown) {\n font-style: normal;\n}\n\n.sv-comment-sheet__emoji-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n background: none;\n border: none;\n padding: 0;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.sv-comment-sheet__emoji-btn svg {\n width: 20px;\n height: 20px;\n color: var(--sv-comment-primary);\n}\n\n/* Hidden emoji bar (can be toggled) */\n.sv-comment-sheet__emoji-bar {\n display: none;\n gap: 8px;\n padding: 8px 0;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.sv-comment-sheet__emoji-bar--visible {\n display: flex;\n}\n\n.sv-comment-sheet__emoji-bar::-webkit-scrollbar {\n display: none;\n}\n\n.sv-comment-sheet__emoji-bar-btn {\n background: none;\n border: none;\n padding: 4px;\n font-size: 20px;\n cursor: pointer;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.sv-comment-sheet__emoji-bar-btn:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n/* \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\n STATES\n \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 */\n\n.sv-comment-sheet__loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n color: var(--sv-comment-text-secondary);\n}\n\n.sv-comment-sheet__loading-spinner {\n width: 24px;\n height: 24px;\n border: 2px solid rgba(0, 0, 0, 0.1);\n border-top-color: var(--sv-comment-primary);\n border-radius: 50%;\n animation: sv-comment-spin 0.8s linear infinite;\n}\n\n@keyframes sv-comment-spin {\n to { transform: rotate(360deg); }\n}\n\n.sv-comment-sheet__empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 32px;\n text-align: center;\n}\n\n.sv-comment-sheet__empty-icon {\n font-size: 48px;\n margin-bottom: 12px;\n}\n\n.sv-comment-sheet__empty-text {\n color: var(--sv-comment-text-secondary);\n font-size: 14px;\n}\n\n.sv-comment-sheet__error {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n text-align: center;\n color: var(--sv-comment-like-color);\n}\n\n.sv-comment-sheet__error-btn {\n margin-top: 12px;\n padding: 8px 16px;\n background: rgba(0, 0, 0, 0.05);\n border: none;\n border-radius: 8px;\n color: var(--sv-comment-text);\n cursor: pointer;\n}\n\n/* Load more */\n.sv-comment-sheet__load-more {\n display: flex;\n justify-content: center;\n padding: 12px;\n}\n\n.sv-comment-sheet__load-more-btn {\n background: none;\n border: none;\n padding: 8px 16px;\n color: var(--sv-comment-text-secondary);\n cursor: pointer;\n font-size: 13px;\n}\n\n.sv-comment-sheet__load-more-btn:hover {\n color: var(--sv-comment-text);\n}\n\n/* \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\n DELETE CONFIRMATION\n \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 */\n\n.sv-comment-delete-confirm {\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(0, 0, 0, 0.5);\n z-index: var(--sv-comment-modal-z-index, 1100);\n}\n\n.sv-comment-delete-confirm__dialog {\n background: var(--sv-comment-bg);\n border-radius: 12px;\n padding: 16px;\n max-width: 280px;\n text-align: center;\n}\n\n.sv-comment-delete-confirm__title {\n font-size: 16px;\n font-weight: 600;\n color: var(--sv-comment-text);\n margin-bottom: 8px;\n}\n\n.sv-comment-delete-confirm__text {\n font-size: 14px;\n color: var(--sv-comment-text-secondary);\n margin-bottom: 16px;\n}\n\n.sv-comment-delete-confirm__actions {\n display: flex;\n gap: 8px;\n}\n\n.sv-comment-delete-confirm__btn {\n flex: 1;\n padding: 8px 12px;\n border: none;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n}\n\n.sv-comment-delete-confirm__btn--cancel {\n background: rgba(0, 0, 0, 0.05);\n color: var(--sv-comment-text);\n}\n\n.sv-comment-delete-confirm__btn--delete {\n background: var(--sv-comment-like-color);\n color: #ffffff;\n}\n\n/* \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\n SKELETON LOADING\n \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 */\n\n@keyframes sv-skeleton-shimmer {\n 0% { background-position: -200% 0; }\n 100% { background-position: 200% 0; }\n}\n\n.sv-comment-skeleton-list {\n display: flex;\n flex-direction: column;\n}\n\n.sv-comment-skeleton {\n animation: sv-skeleton-fade-in 0.3s ease;\n}\n\n@keyframes sv-skeleton-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.sv-comment-skeleton__avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.sv-comment-skeleton__content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sv-comment-skeleton__header {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.sv-comment-skeleton__author {\n width: 80px;\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n animation-delay: 0.1s;\n}\n\n.sv-comment-skeleton__time {\n width: 40px;\n height: 12px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n animation-delay: 0.15s;\n}\n\n.sv-comment-skeleton__text {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.sv-comment-skeleton__line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n}\n\n.sv-comment-skeleton__line--full {\n width: 100%;\n animation-delay: 0.2s;\n}\n\n.sv-comment-skeleton__line--medium {\n width: 65%;\n animation-delay: 0.25s;\n}\n\n.sv-comment-skeleton__actions {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-top: 4px;\n}\n\n.sv-comment-skeleton__action {\n width: 50px;\n height: 12px;\n border-radius: 4px;\n background: linear-gradient(\n 90deg,\n rgba(0, 0, 0, 0.04) 25%,\n rgba(0, 0, 0, 0.08) 50%,\n rgba(0, 0, 0, 0.04) 75%\n );\n background-size: 200% 100%;\n animation: sv-skeleton-shimmer 1.5s ease-in-out infinite;\n animation-delay: 0.3s;\n}\n";
206
+
207
+ export { CommentSheet as C, type ReplyTarget as R, SheetHeader as S, CommentSheetHeadless as a, type CommentSheetHeadlessProps as b, type SheetHeaderProps as c, CommentList as d, type CommentListProps as e, CommentInput as f, type CommentInputProps as g, CommentItemComponent as h, type CommentItemProps as i, CommentSheetContext as j, useOptionalCommentSheetContext as k, type CommentSheetContextValue as l, type CommentSheetI18n as m, COMMENT_SHEET_CSS as n, useCommentSheetContext as u };
@@ -1,30 +1,3 @@
1
- // src/utils/lazyGesture.ts
2
- var gestureModule = null;
3
- var loadPromise = null;
4
- async function loadGesture() {
5
- if (gestureModule) {
6
- return gestureModule;
7
- }
8
- if (loadPromise) {
9
- return loadPromise;
10
- }
11
- loadPromise = import('./use-gesture-react.esm-3SV4QLEJ.js').then((mod) => {
12
- gestureModule = mod;
13
- return mod;
14
- }).catch((error) => {
15
- loadPromise = null;
16
- throw error;
17
- });
18
- return loadPromise;
19
- }
20
- function isGestureLoaded() {
21
- return gestureModule !== null;
22
- }
23
- function preloadGesture() {
24
- loadGesture().catch(() => {
25
- });
26
- }
27
-
28
1
  // src/utils/formatCount.ts
29
2
  var DEFAULT_SUFFIXES = {
30
3
  thousand: "K",
@@ -83,16 +56,5 @@ function parseFormattedCount(formatted) {
83
56
  return num;
84
57
  }
85
58
  }
86
- function cn(...inputs) {
87
- return inputs.filter(Boolean).map((input) => {
88
- if (typeof input === "string") {
89
- return input;
90
- }
91
- if (typeof input === "object" && input !== null) {
92
- return Object.entries(input).filter(([, value]) => value).map(([key]) => key).join(" ");
93
- }
94
- return "";
95
- }).join(" ").trim();
96
- }
97
59
 
98
- export { cn, formatCount, formatCountWithSeparators, isGestureLoaded, loadGesture, parseFormattedCount, preloadGesture };
60
+ export { formatCount, formatCountWithSeparators, parseFormattedCount };
@@ -1,6 +1,6 @@
1
- import { cn } from './chunk-WKX2WBVO.js';
1
+ import { clsx2 } from './chunk-EDWS2IPH.js';
2
2
  import { injectComponentCSS } from './chunk-UXMA4KJZ.js';
3
- import { useInsertionEffect, useMemo, useEffect, useCallback, useRef, useState } from 'react';
3
+ import { memo, useInsertionEffect, useMemo, useEffect, useCallback, useRef, useState } from 'react';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
5
5
 
6
6
  // src/components/ProgressBar/ProgressBar.css.ts
@@ -244,6 +244,40 @@ var PROGRESS_BAR_CSS = `
244
244
  display: none;
245
245
  }
246
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
+ * Auto-hide Variant
249
+ * Shows progress bar only when video is paused or user is seeking/hovering
250
+ * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
251
+
252
+ .sv-progress-bar--auto-hide {
253
+ /* Smooth transition for show/hide */
254
+ transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s ease;
255
+ opacity: 1;
256
+ visibility: visible;
257
+ transform: translateY(0);
258
+ }
259
+
260
+ .sv-progress-bar--auto-hide.sv-progress-bar--hidden {
261
+ opacity: 0;
262
+ visibility: hidden;
263
+ transform: translateY(8px);
264
+ pointer-events: none;
265
+ }
266
+
267
+ /* Show on hover even when auto-hide is enabled */
268
+ .sv-progress-bar--auto-hide:hover {
269
+ opacity: 1;
270
+ visibility: visible;
271
+ transform: translateY(0);
272
+ }
273
+
274
+ /* Always show when seeking */
275
+ .sv-progress-bar--auto-hide.sv-progress-bar--seeking {
276
+ opacity: 1;
277
+ visibility: visible;
278
+ transform: translateY(0);
279
+ }
280
+
247
281
  /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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
282
  * Reduced Motion (Accessibility)
249
283
  * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
@@ -379,7 +413,7 @@ function useSeekHandlers({
379
413
  handlePointerLeave
380
414
  };
381
415
  }
382
- function ProgressBarHeadless({
416
+ function ProgressBarHeadlessBase({
383
417
  currentTime,
384
418
  duration,
385
419
  buffered = 0,
@@ -391,6 +425,8 @@ function ProgressBarHeadless({
391
425
  showTime = false,
392
426
  showTooltip,
393
427
  minimal = false,
428
+ autoHide = true,
429
+ visible,
394
430
  fillRef: externalFillRef,
395
431
  bufferedRef: externalBufferedRef,
396
432
  handleRef: externalHandleRef,
@@ -440,14 +476,17 @@ function ProgressBarHeadless({
440
476
  const stopBubble = useCallback((e) => {
441
477
  e.stopPropagation();
442
478
  }, []);
479
+ const isHidden = visible !== void 0 ? !visible : autoHide && !isSeeking && hoverTime === null;
443
480
  return /* @__PURE__ */ jsxs(
444
481
  "div",
445
482
  {
446
- className: cn(
483
+ className: clsx2(
447
484
  CSS_PREFIX,
448
485
  !isSeekable && `${CSS_PREFIX}--disabled`,
449
486
  isSeeking && `${CSS_PREFIX}--seeking`,
450
487
  minimal && `${CSS_PREFIX}--minimal`,
488
+ autoHide && `${CSS_PREFIX}--auto-hide`,
489
+ isHidden && `${CSS_PREFIX}--hidden`,
451
490
  className
452
491
  ),
453
492
  onClick: stopBubble,
@@ -526,5 +565,7 @@ function ProgressBarHeadless({
526
565
  }
527
566
  );
528
567
  }
568
+ var ProgressBarHeadless = memo(ProgressBarHeadlessBase);
569
+ ProgressBarHeadless.displayName = "ProgressBarHeadless";
529
570
 
530
571
  export { PROGRESS_BAR_CSS, ProgressBarHeadless, calculateProgress, formatTime };
@@ -1,6 +1,6 @@
1
- import { cn } from './chunk-WKX2WBVO.js';
1
+ import { clsx2 } from './chunk-EDWS2IPH.js';
2
2
  import { injectComponentCSS } from './chunk-UXMA4KJZ.js';
3
- import { useRef, useCallback, useEffect, useState, useInsertionEffect, useMemo } from 'react';
3
+ import { memo, useInsertionEffect, useCallback, useMemo, useRef, useState, useEffect } from 'react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  // src/components/VideoPlayer/VideoPlayer.css.ts
@@ -35,6 +35,7 @@ var VIDEO_PLAYER_CSS = (
35
35
  align-items: center;
36
36
  justify-content: center;
37
37
  z-index: var(--sv-player-video-z);
38
+ background: var(--sv-bg-primary, #0ff);
38
39
  }
39
40
 
40
41
  /* \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\u2550\u2550\u2550\u2550
@@ -601,17 +602,21 @@ function supportsNativeHLS() {
601
602
  function isHlsErrorData(d) {
602
603
  return typeof d === "object" && d !== null && "fatal" in d;
603
604
  }
604
- async function setupHlsSource(video, src, hlsRef, onHlsError) {
605
+ async function setupHlsSource(video, src, hlsRef, onHlsError, startTime) {
605
606
  if (supportsNativeHLS()) {
606
- video.src = src;
607
+ video.src = startTime && startTime > 0 ? `${src}#t=${startTime}` : src;
607
608
  return;
608
609
  }
609
610
  const Hls = await loadHls();
610
611
  if (!Hls?.isSupported?.()) {
611
- video.src = src;
612
+ video.src = startTime && startTime > 0 ? `${src}#t=${startTime}` : src;
612
613
  return;
613
614
  }
614
- const hls = new Hls.default();
615
+ const hlsConfig = {};
616
+ if (startTime && startTime > 0) {
617
+ hlsConfig.startPosition = startTime;
618
+ }
619
+ const hls = new Hls.default(hlsConfig);
615
620
  hlsRef.current = hls;
616
621
  hls.loadSource(src);
617
622
  hls.attachMedia(video);
@@ -633,6 +638,7 @@ function useVideoElement(config) {
633
638
  loop = true,
634
639
  muted = true,
635
640
  volume = 1,
641
+ startTime,
636
642
  onCanPlay,
637
643
  onPlay,
638
644
  onPlaying,
@@ -678,13 +684,19 @@ function useVideoElement(config) {
678
684
  const setupSource = async () => {
679
685
  try {
680
686
  if (type === "hls") {
681
- await setupHlsSource(video, src, hlsRef, (hlsError) => {
682
- setError(hlsError);
683
- setIsLoading(false);
684
- onError?.(hlsError);
685
- });
687
+ await setupHlsSource(
688
+ video,
689
+ src,
690
+ hlsRef,
691
+ (hlsError) => {
692
+ setError(hlsError);
693
+ setIsLoading(false);
694
+ onError?.(hlsError);
695
+ },
696
+ startTime
697
+ );
686
698
  } else {
687
- video.src = src;
699
+ video.src = startTime && startTime > 0 ? `${src}#t=${startTime}` : src;
688
700
  }
689
701
  video.loop = loop;
690
702
  video.muted = muted;
@@ -708,7 +720,7 @@ function useVideoElement(config) {
708
720
  hlsRef.current = null;
709
721
  }
710
722
  };
711
- }, [src, type, loop, muted, volume, onError, retryTrigger]);
723
+ }, [src, type, loop, muted, volume, startTime, onError, retryTrigger]);
712
724
  useEffect(() => {
713
725
  const video = videoRef.current;
714
726
  if (!video) return;
@@ -909,7 +921,7 @@ function getMediaErrorMessage(code) {
909
921
  return "Unknown video error";
910
922
  }
911
923
  }
912
- function VideoPlayerHeadless({
924
+ function VideoPlayerHeadlessBase({
913
925
  src,
914
926
  type,
915
927
  poster,
@@ -917,6 +929,7 @@ function VideoPlayerHeadless({
917
929
  loop = true,
918
930
  muted = true,
919
931
  volume = 1,
932
+ startTime,
920
933
  className,
921
934
  videoRef: externalVideoRef,
922
935
  videoId,
@@ -947,6 +960,7 @@ function VideoPlayerHeadless({
947
960
  loop,
948
961
  muted,
949
962
  volume,
963
+ startTime,
950
964
  onCanPlay,
951
965
  onPlay,
952
966
  onPlaying,
@@ -1008,7 +1022,7 @@ function VideoPlayerHeadless({
1008
1022
  return /* @__PURE__ */ jsxs(
1009
1023
  "div",
1010
1024
  {
1011
- className: cn(PLAYER_CLASS, stateClasses, className),
1025
+ className: clsx2(PLAYER_CLASS, stateClasses, className),
1012
1026
  ...{ [VIDEO_TYPE_ATTR]: type },
1013
1027
  ...{ [PLAYBACK_STATE_ATTR]: playbackState },
1014
1028
  style: {
@@ -1105,6 +1119,7 @@ function getUserFriendlyErrorMessage(message) {
1105
1119
  }
1106
1120
  return "Failed to load video. Please try again.";
1107
1121
  }
1122
+ var VideoPlayerHeadless = memo(VideoPlayerHeadlessBase);
1108
1123
  VideoPlayerHeadless.displayName = "VideoPlayerHeadless";
1109
1124
 
1110
1125
  export { BUFFERING_STATE_CLASS, DEFAULT_OBJECT_FIT, DEFAULT_PRELOAD, ENDED_CLASS, ERROR_CLASS, ERROR_STATE_CLASS, FIRST_FRAME_MAX_WIDTH, FIRST_FRAME_QUALITY, LOADING_CLASS, LOADING_STATE_ATTR, LOADING_STATE_CLASS, PAUSED_CLASS, PLAYBACK_STATE_ATTR, PLAYER_CLASS, PLAYING_CLASS, POSTER_CLASS, READY_CLASS, VIDEO_CLASS, VIDEO_PLAYER_CSS, VIDEO_TYPE_ATTR, VIDEO_WRAPPER_CLASS, VideoElementError, VideoPlayerHeadless, Z_INDEX, Z_INDEX_CSS_VARS, createFirstFrameCache, firstFrameCache, useAutoFirstFrameCapture, useFirstFrameCapture, useVideoElement };
@@ -110,10 +110,10 @@ function BookmarkFilledIcon(props) {
110
110
  ) });
111
111
  }
112
112
  function PlayIcon(props) {
113
- return /* @__PURE__ */ jsx("svg", { ...getIconProps(props), "aria-hidden": "true", children: /* @__PURE__ */ jsx(
113
+ return /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", fill: "none", ...getIconProps(props), children: /* @__PURE__ */ jsx(
114
114
  "path",
115
115
  {
116
- d: "M17.0089 3.45151C12.3423 0.748041 6.5 4.11533 6.5 9.50852V38.4835C6.5 43.8767 12.3423 47.244 17.0089 44.5405L42.0169 30.053C46.6717 27.3565 46.6717 20.6356 42.0169 17.939L17.0089 3.45151Z",
116
+ d: "M9.92196 2.01322C7.19974 0.436195 3.79175 2.40044 3.79175 5.54647V22.4486C3.79175 25.5946 7.19974 27.5588 9.92195 25.9818L24.5099 17.5308C27.2252 15.9578 27.2252 12.0373 24.5099 10.4643L9.92196 2.01322Z",
117
117
  fill: "currentColor"
118
118
  }
119
119
  ) });
@@ -122,7 +122,7 @@ function PauseIcon(props) {
122
122
  return /* @__PURE__ */ jsx("svg", { ...getIconProps(props), "aria-hidden": "true", children: /* @__PURE__ */ jsx(
123
123
  "path",
124
124
  {
125
- d: "M20.751 3.6V20.4C20.751 21.036 20.751 21.42 20.561 21.794C20.392 22.126 20.127 22.391 19.796 22.559C19.422 22.749 19.038 22.749 18.401 22.749H16.601C15.965 22.749 15.58 22.749 15.206 22.559C14.875 22.391 14.61 22.126 14.441 21.794C14.25 21.419 14.25 21.035 14.25 20.399V3.6C14.25 2.964 14.25 2.58 14.44 2.206C14.609 1.874 14.874 1.609 15.205 1.441C15.579 1.25 15.963 1.25 16.6 1.25H18.4C19.037 1.25 19.421 1.25 19.796 1.441C20.126 1.609 20.391 1.874 20.56 2.205C20.751 2.58 20.751 2.964 20.751 3.6ZM8.796 1.441C8.421 1.25 8.037 1.25 7.4 1.25H5.6C4.963 1.25 4.579 1.25 4.205 1.441C3.873 1.61 3.608 1.875 3.44 2.206C3.25 2.58 3.25 2.964 3.25 3.6V20.4C3.25 21.036 3.25 21.42 3.44 21.793C3.609 22.125 3.874 22.39 4.206 22.559C4.58 22.749 4.964 22.749 5.601 22.749H7.401C8.037 22.749 8.422 22.749 8.796 22.559C9.127 22.391 9.392 22.126 9.561 21.794C9.751 21.42 9.751 21.036 9.751 20.4V3.6C9.751 2.964 9.751 2.58 9.56 2.205C9.391 1.873 9.126 1.609 8.796 1.441Z",
125
+ d: "M24.2096 4.20016V23.8002C24.2096 24.5422 24.2096 24.9902 23.9879 25.4265C23.7907 25.8138 23.4816 26.123 23.0954 26.319C22.6591 26.5407 22.2111 26.5407 21.4679 26.5407H19.3679C18.6259 26.5407 18.1767 26.5407 17.7404 26.319C17.3542 26.123 17.0451 25.8138 16.8479 25.4265C16.6251 24.989 16.6251 24.541 16.6251 23.799V4.20016C16.6251 3.45816 16.6251 3.01016 16.8467 2.57383C17.0439 2.1865 17.3531 1.87733 17.7393 1.68133C18.1756 1.4585 18.6236 1.4585 19.3667 1.4585H21.4667C22.2099 1.4585 22.6579 1.4585 23.0954 1.68133C23.4804 1.87733 23.7896 2.1865 23.9867 2.57266C24.2096 3.01016 24.2096 3.45816 24.2096 4.20016ZM10.2621 1.68133C9.82458 1.4585 9.37658 1.4585 8.63342 1.4585H6.53341C5.79025 1.4585 5.34225 1.4585 4.90591 1.68133C4.51858 1.8785 4.20941 2.18766 4.01341 2.57383C3.79175 3.01016 3.79175 3.45816 3.79175 4.20016V23.8002C3.79175 24.5422 3.79175 24.9902 4.01341 25.4253C4.21058 25.8127 4.51975 26.1218 4.90708 26.319C5.34341 26.5407 5.79141 26.5407 6.53458 26.5407H8.63458C9.37658 26.5407 9.82575 26.5407 10.2621 26.319C10.6482 26.123 10.9574 25.8138 11.1546 25.4265C11.3762 24.9902 11.3762 24.5422 11.3762 23.8002V4.20016C11.3762 3.45816 11.3762 3.01016 11.1534 2.57266C10.9562 2.18533 10.6471 1.87733 10.2621 1.68133Z",
126
126
  fill: "currentColor"
127
127
  }
128
128
  ) });
@@ -197,5 +197,11 @@ function VerifiedIcon(props) {
197
197
  )
198
198
  ] });
199
199
  }
200
+ function PlusIcon(props) {
201
+ return /* @__PURE__ */ jsxs("svg", { ...getIconProps({ ...props, fill: "none", stroke: "currentColor" }), "aria-hidden": "true", children: [
202
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19", strokeWidth: "2.5", strokeLinecap: "round" }),
203
+ /* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12", strokeWidth: "2.5", strokeLinecap: "round" })
204
+ ] });
205
+ }
200
206
 
201
- export { BookmarkFilledIcon, BookmarkIcon, CloseIcon, CommentIcon, HeartFilledIcon, HeartIcon, MoreIcon, MusicIcon, PauseIcon, PlayIcon, ShareIcon, UserCheckIcon, UserPlusIcon, VerifiedIcon, VolumeIcon, VolumeMutedIcon };
207
+ export { BookmarkFilledIcon, BookmarkIcon, CloseIcon, CommentIcon, HeartFilledIcon, HeartIcon, MoreIcon, MusicIcon, PauseIcon, PlayIcon, PlusIcon, ShareIcon, UserCheckIcon, UserPlusIcon, VerifiedIcon, VolumeIcon, VolumeMutedIcon };