@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.
- package/dist/CommentSheet.css-DuBy01rU.d.ts +219 -0
- package/dist/VideoSlotPlayIndicator-DPs8Xt5C.d.ts +51 -0
- package/dist/chunk-3OB3OVYR.js +349 -0
- package/dist/chunk-4RIMQOBR.js +58 -0
- package/dist/chunk-5MKYDI4X.js +1 -0
- package/dist/chunk-5Y43HNRG.js +296 -0
- package/dist/chunk-7WXAQHJI.js +350 -0
- package/dist/chunk-BADA7OLG.js +564 -0
- package/dist/chunk-BEJAJFV6.js +191 -0
- package/dist/chunk-BNI7CYRI.js +334 -0
- package/dist/{chunk-RMLTPW5S.js → chunk-CAWE42LH.js} +4 -3
- package/dist/chunk-DGKMO3AE.js +717 -0
- package/dist/chunk-DR7KR7OT.js +103 -0
- package/dist/chunk-GSNIZ6DF.js +605 -0
- package/dist/chunk-HXQPEZRG.js +105 -0
- package/dist/{chunk-FNXTPQ6L.js → chunk-IC2KUU4V.js} +31 -1340
- package/dist/chunk-IWSBYOSS.js +91 -0
- package/dist/chunk-MFJS65C5.js +368 -0
- package/dist/{chunk-AC2IFAJR.js → chunk-NJXIYSDZ.js} +12 -1
- package/dist/{chunk-CL6BS7GB.js → chunk-OM4L7RE5.js} +12 -2
- package/dist/chunk-QCRRF76W.js +75 -0
- package/dist/chunk-QUEJHA24.js +508 -0
- package/dist/chunk-UYBQTE4M.js +337 -0
- package/dist/chunk-VJ744W5N.js +603 -0
- package/dist/chunk-VXW7AOGM.js +285 -0
- package/dist/{chunk-AQHD6LPS.js → chunk-YB7AXTX7.js} +1 -1
- package/dist/components/ActionBar/index.d.ts +7 -2
- package/dist/components/ActionBar/index.js +1 -1
- package/dist/components/AdvanceMenu/index.d.ts +80 -0
- package/dist/components/AdvanceMenu/index.js +1 -0
- package/dist/components/ArticleSlot/index.d.ts +213 -0
- package/dist/components/ArticleSlot/index.js +1 -0
- package/dist/components/AuthorInfo/index.js +1 -1
- package/dist/components/BottomSheet/index.d.ts +87 -0
- package/dist/components/BottomSheet/index.js +1 -0
- package/dist/components/CleanModeOverlay/index.d.ts +60 -0
- package/dist/components/CleanModeOverlay/index.js +1 -0
- package/dist/components/CommentSheet/index.d.ts +1 -1
- package/dist/components/CommentSheet/index.js +1 -1
- package/dist/components/DetailView/index.d.ts +314 -0
- package/dist/components/DetailView/index.js +1 -0
- package/dist/components/ErrorBoundary/index.js +1 -1
- package/dist/components/{VideoFeed → Feed}/index.d.ts +64 -45
- package/dist/components/Feed/index.js +1 -0
- package/dist/components/ImageCarousel/index.d.ts +50 -0
- package/dist/components/ImageCarousel/index.js +1 -0
- package/dist/components/Playlist/index.d.ts +117 -0
- package/dist/components/Playlist/index.js +1 -0
- package/dist/components/ProgressBar/index.js +1 -1
- package/dist/components/QualityPicker/index.d.ts +35 -0
- package/dist/components/QualityPicker/index.js +1 -0
- package/dist/components/ReportSheet/index.d.ts +74 -0
- package/dist/components/ReportSheet/index.js +1 -0
- package/dist/components/Skeleton/index.js +1 -1
- package/dist/components/SpeedPicker/index.d.ts +32 -0
- package/dist/components/SpeedPicker/index.js +1 -0
- package/dist/components/VideoInfo/index.d.ts +7 -3
- package/dist/components/VideoInfo/index.js +1 -1
- package/dist/components/VideoPlayer/index.js +1 -1
- package/dist/components/VideoSlot/index.d.ts +31 -68
- package/dist/components/VideoSlot/index.js +2 -1
- package/dist/components/VirtualSlider/index.js +1 -1
- package/dist/index.d.ts +40 -10
- package/dist/index.js +23 -13
- package/package.json +8 -4
- package/dist/CommentSheet.css-BeCrEaUG.d.ts +0 -221
- package/dist/chunk-2FSDVYER.js +0 -737
- package/dist/chunk-ECR42RKK.js +0 -571
- package/dist/chunk-KWHMZ6H5.js +0 -562
- package/dist/chunk-SZXFH334.js +0 -204
- package/dist/chunk-UNV3NWN6.js +0 -148
- package/dist/chunk-WCRDTBCZ.js +0 -357
- package/dist/chunk-XDIH66C4.js +0 -1519
- package/dist/components/VideoFeed/index.js +0 -1
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { Article, MusicInfo } from '@xhub-short/contracts';
|
|
4
|
+
import { b as VideoSlotPlayIndicatorInnerProps } from '../../VideoSlotPlayIndicator-DPs8Xt5C.js';
|
|
5
|
+
|
|
6
|
+
/** CSS class for article slot */
|
|
7
|
+
declare const ARTICLE_SLOT_CLASS = "sv-article-slot";
|
|
8
|
+
/** CSS class for active state */
|
|
9
|
+
declare const ARTICLE_SLOT_ACTIVE_CLASS = "sv-article-slot--active";
|
|
10
|
+
/** CSS class for clean mode */
|
|
11
|
+
declare const ARTICLE_SLOT_CLEAN_MODE_CLASS = "sv-article-slot--clean-mode";
|
|
12
|
+
/** Data attribute for article ID */
|
|
13
|
+
declare const ARTICLE_ID_ATTR = "data-article-id";
|
|
14
|
+
/** Data attribute for active state */
|
|
15
|
+
declare const ARTICLE_ACTIVE_ATTR = "data-active";
|
|
16
|
+
interface ArticleSlotContextValue {
|
|
17
|
+
/** The article data */
|
|
18
|
+
article: Article;
|
|
19
|
+
/** Current image index in carousel */
|
|
20
|
+
currentImageIndex: number;
|
|
21
|
+
/** Total number of images */
|
|
22
|
+
totalImages: number;
|
|
23
|
+
/** Whether this slot is active (visible) */
|
|
24
|
+
isActive: boolean;
|
|
25
|
+
/** Whether in clean mode */
|
|
26
|
+
isCleanMode: boolean;
|
|
27
|
+
/** Timestamp of last user music toggle (for PlayIndicator) */
|
|
28
|
+
lastMusicToggleTime: number;
|
|
29
|
+
/** Music info (if any) */
|
|
30
|
+
music?: MusicInfo;
|
|
31
|
+
/** Whether music is playing */
|
|
32
|
+
isMusicPlaying: boolean;
|
|
33
|
+
/** Toggle music playback */
|
|
34
|
+
toggleMusic: () => void;
|
|
35
|
+
/** Navigate to specific image */
|
|
36
|
+
goToImage: (index: number) => void;
|
|
37
|
+
/** Go to next image */
|
|
38
|
+
nextImage: () => void;
|
|
39
|
+
/** Go to previous image */
|
|
40
|
+
prevImage: () => void;
|
|
41
|
+
/** Expand caption / open detail view */
|
|
42
|
+
expandCaption: () => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Hook to access ArticleSlot context
|
|
46
|
+
* @throws if used outside ArticleSlotHeadless
|
|
47
|
+
*/
|
|
48
|
+
declare function useArticleSlotContext(): ArticleSlotContextValue;
|
|
49
|
+
/**
|
|
50
|
+
* Hook to optionally access ArticleSlot context
|
|
51
|
+
* Returns null if used outside ArticleSlotHeadless
|
|
52
|
+
*/
|
|
53
|
+
declare function useOptionalArticleSlotContext(): ArticleSlotContextValue | null;
|
|
54
|
+
interface ArticleSlotHeadlessProps {
|
|
55
|
+
/** The article data */
|
|
56
|
+
article: Article;
|
|
57
|
+
/** Whether this slot is active (visible in viewport) */
|
|
58
|
+
isActive?: boolean;
|
|
59
|
+
/** Current image index (controlled) */
|
|
60
|
+
currentImageIndex?: number;
|
|
61
|
+
/** Called when image index changes */
|
|
62
|
+
onImageIndexChange?: (index: number) => void;
|
|
63
|
+
/** Music info for this post */
|
|
64
|
+
music?: MusicInfo;
|
|
65
|
+
/** Whether music is playing */
|
|
66
|
+
isMusicPlaying?: boolean;
|
|
67
|
+
/** Toggle music playback */
|
|
68
|
+
onToggleMusic?: () => void;
|
|
69
|
+
/**
|
|
70
|
+
* Last music toggle timestamp (controlled from parent for PlayIndicator sync).
|
|
71
|
+
* If provided, overrides internal tracking.
|
|
72
|
+
*/
|
|
73
|
+
lastMusicToggleTime?: number;
|
|
74
|
+
/** Whether in clean mode (hide overlay) */
|
|
75
|
+
isCleanMode?: boolean;
|
|
76
|
+
/** Handle single tap */
|
|
77
|
+
onTap?: () => void;
|
|
78
|
+
/** Handle double tap (usually for like) */
|
|
79
|
+
onDoubleTap?: () => void;
|
|
80
|
+
/** Handle long press */
|
|
81
|
+
onLongPress?: () => void;
|
|
82
|
+
/** Called when "Read More" is clicked */
|
|
83
|
+
onReadMoreClick?: () => void;
|
|
84
|
+
/** Disable tap gestures */
|
|
85
|
+
disableTap?: boolean;
|
|
86
|
+
/** Enable pinch-to-zoom on images */
|
|
87
|
+
enableZoom?: boolean;
|
|
88
|
+
/** Custom placeholder renderer for images */
|
|
89
|
+
renderPlaceholder?: (index: number) => ReactNode;
|
|
90
|
+
/** Show image counter (1/5) */
|
|
91
|
+
showCounter?: boolean;
|
|
92
|
+
/** Show pagination dots */
|
|
93
|
+
showIndicators?: boolean;
|
|
94
|
+
/** Additional class name */
|
|
95
|
+
className?: string;
|
|
96
|
+
/** Called when swipe direction changes (for gesture locking) */
|
|
97
|
+
onSwipeDirectionChange?: (direction: 'horizontal' | 'vertical' | null) => void;
|
|
98
|
+
/** Children (render prop or ReactNode) */
|
|
99
|
+
children?: ReactNode | ((context: ArticleSlotContextValue) => ReactNode);
|
|
100
|
+
/** Custom styles */
|
|
101
|
+
style?: React.CSSProperties;
|
|
102
|
+
}
|
|
103
|
+
declare function ArticleSlotHeadlessBase({ article, isActive, currentImageIndex: controlledIndex, onImageIndexChange, music, isMusicPlaying, onToggleMusic, lastMusicToggleTime: controlledToggleTime, isCleanMode, onTap, onDoubleTap, onLongPress, onReadMoreClick, disableTap, enableZoom, renderPlaceholder, showCounter, showIndicators, className, onSwipeDirectionChange, children, style, }: ArticleSlotHeadlessProps): ReactElement;
|
|
104
|
+
declare const ArticleSlotHeadless: react.MemoExoticComponent<typeof ArticleSlotHeadlessBase>;
|
|
105
|
+
/**
|
|
106
|
+
* Overlay container for author, caption, actions
|
|
107
|
+
*/
|
|
108
|
+
interface ArticleSlotOverlayProps {
|
|
109
|
+
children?: ReactNode;
|
|
110
|
+
className?: string;
|
|
111
|
+
}
|
|
112
|
+
declare function ArticleSlotOverlay({ children, className }: ArticleSlotOverlayProps): ReactElement;
|
|
113
|
+
/**
|
|
114
|
+
* Bottom content area (author, caption, read more)
|
|
115
|
+
*/
|
|
116
|
+
interface ArticleSlotBottomProps {
|
|
117
|
+
children?: ReactNode;
|
|
118
|
+
className?: string;
|
|
119
|
+
/** Click handler */
|
|
120
|
+
onClick?: () => void;
|
|
121
|
+
}
|
|
122
|
+
declare function ArticleSlotBottom({ children, className, onClick, }: ArticleSlotBottomProps): ReactElement;
|
|
123
|
+
/**
|
|
124
|
+
* Actions container (right side)
|
|
125
|
+
*/
|
|
126
|
+
interface ArticleSlotActionsProps {
|
|
127
|
+
children?: ReactNode;
|
|
128
|
+
className?: string;
|
|
129
|
+
}
|
|
130
|
+
declare function ArticleSlotActions({ children, className }: ArticleSlotActionsProps): ReactElement;
|
|
131
|
+
/**
|
|
132
|
+
* Caption component with optional expansion
|
|
133
|
+
*/
|
|
134
|
+
interface ArticleSlotCaptionProps {
|
|
135
|
+
/** Maximum lines to show (default: 2) */
|
|
136
|
+
maxLines?: number;
|
|
137
|
+
/** Whether caption is expanded */
|
|
138
|
+
expanded?: boolean;
|
|
139
|
+
/** Class name */
|
|
140
|
+
className?: string;
|
|
141
|
+
}
|
|
142
|
+
declare function ArticleSlotCaption({ maxLines, expanded, className, }: ArticleSlotCaptionProps): ReactElement;
|
|
143
|
+
/**
|
|
144
|
+
* Read More button
|
|
145
|
+
*/
|
|
146
|
+
interface ArticleSlotReadMoreProps {
|
|
147
|
+
/** Button label */
|
|
148
|
+
label?: string;
|
|
149
|
+
/** Class name */
|
|
150
|
+
className?: string;
|
|
151
|
+
/** Click handler (overrides context) */
|
|
152
|
+
onClick?: () => void;
|
|
153
|
+
}
|
|
154
|
+
declare function ArticleSlotReadMore({ label, className, onClick, }: ArticleSlotReadMoreProps): ReactElement;
|
|
155
|
+
/**
|
|
156
|
+
* Music bar component
|
|
157
|
+
*/
|
|
158
|
+
interface ArticleSlotMusicProps {
|
|
159
|
+
/** Class name */
|
|
160
|
+
className?: string;
|
|
161
|
+
/**
|
|
162
|
+
* Click handler
|
|
163
|
+
*/
|
|
164
|
+
onClick?: () => void;
|
|
165
|
+
/**
|
|
166
|
+
* Custom fallback element when cover image fails to load or is not provided.
|
|
167
|
+
* If not provided, a default vinyl disc SVG will be used.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```tsx
|
|
171
|
+
* <ArticleSlotMusic
|
|
172
|
+
* fallbackCover={<MyCustomMusicIcon className="my-icon" />}
|
|
173
|
+
* />
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
fallbackCover?: ReactNode;
|
|
177
|
+
}
|
|
178
|
+
declare function ArticleSlotMusic({ className, onClick, fallbackCover, }: ArticleSlotMusicProps): ReactElement | null;
|
|
179
|
+
/**
|
|
180
|
+
* Props for ArticleSlotPlayIndicator
|
|
181
|
+
* Uses same props as VideoSlotPlayIndicatorInner, minus context-derived props
|
|
182
|
+
*/
|
|
183
|
+
type ArticleSlotPlayIndicatorProps = Omit<VideoSlotPlayIndicatorInnerProps, 'lastUserToggleTime' | 'isPlaying'>;
|
|
184
|
+
/**
|
|
185
|
+
* ArticleSlotPlayIndicator - Shows play/pause icon when user toggles music
|
|
186
|
+
*
|
|
187
|
+
* Reuses the same visual component as VideoSlot but reads from ArticleSlot context.
|
|
188
|
+
* This ensures UI consistency across Video and Article posts.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```tsx
|
|
192
|
+
* <ArticleSlotHeadless article={article}>
|
|
193
|
+
* <ArticleSlotPlayIndicator persistWhenPaused />
|
|
194
|
+
* </ArticleSlotHeadless>
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
declare function ArticleSlotPlayIndicator(props: ArticleSlotPlayIndicatorProps): ReactElement | null;
|
|
198
|
+
declare namespace ArticleSlotPlayIndicator {
|
|
199
|
+
var displayName: string;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* ArticleSlot CSS - Injected at runtime
|
|
204
|
+
*
|
|
205
|
+
* Features:
|
|
206
|
+
* - Full-screen article display
|
|
207
|
+
* - Overlay for author, caption, actions
|
|
208
|
+
* - Music bar (optional)
|
|
209
|
+
* - Read more button
|
|
210
|
+
*/
|
|
211
|
+
declare const ARTICLE_SLOT_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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ARTICLE SLOT - 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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n background: var(--sv-article-bg, #000);\n touch-action: pan-y;\n user-select: none;\n -webkit-user-select: none;\n}\n\n.sv-article-slot--active {\n z-index: 1;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n IMAGE 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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__images {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n OVERLAY (Author, Caption, Actions)\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n display: flex;\n flex-direction: column;\n z-index: 2;\n}\n\n.sv-article-slot__overlay > * {\n pointer-events: auto;\n}\n\n/* Gradient background for better text visibility */\n.sv-article-slot__gradient {\n position: absolute;\n left: 0;\n right: 0;\n pointer-events: none;\n}\n\n.sv-article-slot__gradient--top {\n top: 0;\n height: 120px;\n background: linear-gradient(\n to bottom,\n rgba(0, 0, 0, 0.5) 0%,\n rgba(0, 0, 0, 0.3) 50%,\n transparent 100%\n );\n}\n\n.sv-article-slot__gradient--bottom {\n bottom: 0;\n height: 200px;\n background: linear-gradient(\n to top,\n rgba(0, 0, 0, 0.7) 0%,\n rgba(0, 0, 0, 0.4) 50%,\n transparent 100%\n );\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n TOP BAR (Counter, Badge)\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__top-bar {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n padding: var(--sv-article-top-padding, 16px);\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n z-index: 10;\n}\n\n.sv-article-slot__counter {\n padding: 4px 10px;\n background: var(--sv-article-counter-bg, rgba(0, 0, 0, 0.6));\n border-radius: 12px;\n font-size: var(--sv-article-counter-font-size, 12px);\n font-weight: 500;\n color: var(--sv-article-counter-color, #fff);\n}\n\n/* Image badge (e.g., \"Photo\") */\n.sv-article-slot__badge {\n padding: 4px 8px;\n background: var(--sv-article-badge-bg, rgba(255, 255, 255, 0.2));\n border-radius: 4px;\n font-size: var(--sv-article-badge-font-size, 11px);\n font-weight: 500;\n color: var(--sv-article-badge-color, #fff);\n text-transform: uppercase;\n letter-spacing: 0.5px;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n BOTTOM CONTENT (Author, Caption, Music, Read More)\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__bottom {\n position: absolute;\n bottom: calc(var(--sv-safe-area-bottom, 0px) + var(--sv-playlist-bar-offset, 0px));\n left: 0;\n right: var(--sv-article-action-bar-width, 72px);\n padding: var(--sv-article-bottom-padding, 16px);\n display: flex;\n flex-direction: column;\n gap: 12px;\n z-index: 5;\n transition: bottom 0.3s ease-in-out;\n}\n\n/* Author section */\n.sv-article-slot__author {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sv-article-slot__author-avatar {\n width: var(--sv-article-avatar-size, 40px);\n height: var(--sv-article-avatar-size, 40px);\n border-radius: 50%;\n object-fit: cover;\n border: 2px solid var(--sv-article-avatar-border, rgba(255, 255, 255, 0.3));\n}\n\n.sv-article-slot__author-name {\n font-size: var(--sv-article-author-font-size, 15px);\n font-weight: 600;\n color: var(--sv-article-author-color, #fff);\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);\n}\n\n/* Caption section */\n.sv-article-slot__caption {\n font-size: var(--sv-article-caption-font-size, 14px);\n line-height: 1.4;\n color: var(--sv-article-caption-color, #fff);\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);\n display: -webkit-box;\n -webkit-line-clamp: var(--sv-article-caption-lines, 2);\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n.sv-article-slot__caption--expanded {\n -webkit-line-clamp: unset;\n overflow: visible;\n}\n\n/* Read more button */\n.sv-article-slot__read-more {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 8px 16px;\n background: var(--sv-article-read-more-bg, rgba(255, 255, 255, 0.2));\n border: none;\n border-radius: 20px;\n font-size: var(--sv-article-read-more-font-size, 13px);\n font-weight: 500;\n color: var(--sv-article-read-more-color, #fff);\n cursor: pointer;\n transition: background 0.2s ease;\n width: fit-content;\n}\n\n.sv-article-slot__read-more:hover {\n background: var(--sv-article-read-more-hover-bg, rgba(255, 255, 255, 0.3));\n}\n\n.sv-article-slot__read-more svg {\n width: 16px;\n height: 16px;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ACTION BAR (Right side)\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__actions {\n position: absolute;\n right: 0;\n bottom: calc(var(--sv-safe-area-bottom, 0px) + var(--sv-playlist-bar-offset, 0px));\n width: var(--sv-article-action-bar-width, 72px);\n padding: var(--sv-article-actions-padding, 16px 8px);\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 20px;\n z-index: 5;\n transition: bottom 0.3s ease-in-out;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n MUSIC BAR\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__music {\n overflow: hidden;\n aspect-ratio: 1/1;\n background: transparent;\n width: fit-content;\n height: fit-content;\n border: none;\n}\n\n.sv-article-slot__music-cover {\n width: 44px;\n height: 44px;\n object-fit: cover;\n border-radius: 999px;\n border: 2px solid var(--sv-article-music-border, rgba(255, 255, 255, 0.3));\n}\n\n.sv-article-slot__music-cover--playing {\n animation: sv-music-rotate 4s linear infinite;\n}\n\n@keyframes sv-music-rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n LIKE ANIMATION\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot__like-animation {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 20;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n CLEAN MODE (Hide overlay)\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot--clean-mode .sv-article-slot__overlay,\n.sv-article-slot--clean-mode .sv-article-slot__top-bar,\n.sv-article-slot--clean-mode .sv-article-slot__bottom,\n.sv-article-slot--clean-mode .sv-article-slot__actions,\n.sv-article-slot--clean-mode .sv-article-slot__gradient {\n opacity: 0;\n transition: opacity 0.3s ease;\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n LOADING STATE\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot--loading .sv-article-slot__skeleton {\n position: absolute;\n inset: 0;\n background: linear-gradient(\n 90deg,\n rgba(255, 255, 255, 0.05) 25%,\n rgba(255, 255, 255, 0.1) 50%,\n rgba(255, 255, 255, 0.05) 75%\n );\n background-size: 200% 100%;\n animation: sv-article-shimmer 1.5s infinite;\n}\n\n@keyframes sv-article-shimmer {\n 0% {\n background-position: 200% 0;\n }\n 100% {\n background-position: -200% 0;\n }\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n ACCESSIBILITY\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 */\n\n.sv-article-slot:focus-visible {\n outline: 2px solid var(--sv-article-focus-color, #4dabff);\n outline-offset: -2px;\n}\n\n.sv-article-slot__sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n";
|
|
212
|
+
|
|
213
|
+
export { ARTICLE_ACTIVE_ATTR, ARTICLE_ID_ATTR, ARTICLE_SLOT_ACTIVE_CLASS, ARTICLE_SLOT_CLASS, ARTICLE_SLOT_CLEAN_MODE_CLASS, ARTICLE_SLOT_CSS, ArticleSlotActions, type ArticleSlotActionsProps, ArticleSlotBottom, type ArticleSlotBottomProps, ArticleSlotCaption, type ArticleSlotCaptionProps, type ArticleSlotContextValue, ArticleSlotHeadless, type ArticleSlotHeadlessProps, ArticleSlotMusic, type ArticleSlotMusicProps, ArticleSlotOverlay, type ArticleSlotOverlayProps, ArticleSlotPlayIndicator, type ArticleSlotPlayIndicatorProps, ArticleSlotReadMore, type ArticleSlotReadMoreProps, ARTICLE_ACTIVE_ATTR as IMAGE_POST_ACTIVE_ATTR, ARTICLE_ID_ATTR as IMAGE_POST_ID_ATTR, ARTICLE_SLOT_ACTIVE_CLASS as IMAGE_POST_SLOT_ACTIVE_CLASS, ARTICLE_SLOT_CLASS as IMAGE_POST_SLOT_CLASS, ARTICLE_SLOT_CLEAN_MODE_CLASS as IMAGE_POST_SLOT_CLEAN_MODE_CLASS, ARTICLE_SLOT_CSS as IMAGE_POST_SLOT_CSS, ArticleSlotActions as ImagePostSlotActions, type ArticleSlotActionsProps as ImagePostSlotActionsProps, ArticleSlotBottom as ImagePostSlotBottom, type ArticleSlotBottomProps as ImagePostSlotBottomProps, ArticleSlotCaption as ImagePostSlotCaption, type ArticleSlotCaptionProps as ImagePostSlotCaptionProps, type ArticleSlotContextValue as ImagePostSlotContextValue, ArticleSlotHeadless as ImagePostSlotHeadless, type ArticleSlotHeadlessProps as ImagePostSlotHeadlessProps, ArticleSlotMusic as ImagePostSlotMusic, type ArticleSlotMusicProps as ImagePostSlotMusicProps, ArticleSlotOverlay as ImagePostSlotOverlay, type ArticleSlotOverlayProps as ImagePostSlotOverlayProps, ArticleSlotPlayIndicator as ImagePostSlotPlayIndicator, type ArticleSlotPlayIndicatorProps as ImagePostSlotPlayIndicatorProps, ArticleSlotReadMore as ImagePostSlotReadMore, type ArticleSlotReadMoreProps as ImagePostSlotReadMoreProps, useArticleSlotContext, useArticleSlotContext as useImagePostSlotContext, useOptionalArticleSlotContext, useOptionalArticleSlotContext as useOptionalImagePostSlotContext };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ARTICLE_ACTIVE_ATTR, ARTICLE_ID_ATTR, ARTICLE_SLOT_ACTIVE_CLASS, ARTICLE_SLOT_CLASS, ARTICLE_SLOT_CLEAN_MODE_CLASS, ARTICLE_SLOT_CSS, ArticleSlotActions, ArticleSlotBottom, ArticleSlotCaption, ArticleSlotHeadless, ArticleSlotMusic, ArticleSlotOverlay, ArticleSlotPlayIndicator, ArticleSlotReadMore, ARTICLE_ACTIVE_ATTR as IMAGE_POST_ACTIVE_ATTR, ARTICLE_ID_ATTR as IMAGE_POST_ID_ATTR, ARTICLE_SLOT_ACTIVE_CLASS as IMAGE_POST_SLOT_ACTIVE_CLASS, ARTICLE_SLOT_CLASS as IMAGE_POST_SLOT_CLASS, ARTICLE_SLOT_CLEAN_MODE_CLASS as IMAGE_POST_SLOT_CLEAN_MODE_CLASS, ARTICLE_SLOT_CSS as IMAGE_POST_SLOT_CSS, ArticleSlotActions as ImagePostSlotActions, ArticleSlotBottom as ImagePostSlotBottom, ArticleSlotCaption as ImagePostSlotCaption, ArticleSlotHeadless as ImagePostSlotHeadless, ArticleSlotMusic as ImagePostSlotMusic, ArticleSlotOverlay as ImagePostSlotOverlay, ArticleSlotPlayIndicator as ImagePostSlotPlayIndicator, ArticleSlotReadMore as ImagePostSlotReadMore, useArticleSlotContext, useArticleSlotContext as useImagePostSlotContext, useOptionalArticleSlotContext, useOptionalArticleSlotContext as useOptionalImagePostSlotContext } from '../../chunk-BNI7CYRI.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { AUTHOR_INFO_CSS, AuthorAvatar, AuthorDescription, AuthorInfoContext, AuthorInfoHeadless, AuthorName, FollowButton, useAuthorInfoContext, useOptionalAuthorInfoContext } from '../../chunk-
|
|
1
|
+
export { AUTHOR_INFO_CSS, AuthorAvatar, AuthorDescription, AuthorInfoContext, AuthorInfoHeadless, AuthorName, FollowButton, useAuthorInfoContext, useOptionalAuthorInfoContext } from '../../chunk-3OB3OVYR.js';
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
interface BottomSheetContextValue {
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Hook to access bottom sheet context
|
|
10
|
+
* Must be used within BottomSheetHeadless
|
|
11
|
+
*/
|
|
12
|
+
declare function useBottomSheetContext(): BottomSheetContextValue;
|
|
13
|
+
interface BottomSheetHeadlessProps {
|
|
14
|
+
/** Whether sheet is open */
|
|
15
|
+
isOpen: boolean;
|
|
16
|
+
/** Close callback */
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
/** Sheet content */
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
/** Sheet height (CSS value: "auto", "50vh", "80%", "400px") */
|
|
21
|
+
height?: string;
|
|
22
|
+
/** Root class name for sheet */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Backdrop class name */
|
|
25
|
+
backdropClassName?: string;
|
|
26
|
+
/** Content wrapper class name */
|
|
27
|
+
contentClassName?: string;
|
|
28
|
+
/** Close on backdrop click (default: true) */
|
|
29
|
+
closeOnBackdropClick?: boolean;
|
|
30
|
+
/** Close on escape key (default: true) */
|
|
31
|
+
closeOnEscape?: boolean;
|
|
32
|
+
/** Show drag handle (default: false) */
|
|
33
|
+
showDragHandle?: boolean;
|
|
34
|
+
/** Enable drag-to-dismiss (default: true) */
|
|
35
|
+
enableDragToDismiss?: boolean;
|
|
36
|
+
/** Drag threshold to close in pixels (default: 150) */
|
|
37
|
+
dragCloseThreshold?: number;
|
|
38
|
+
/** Custom aria-label */
|
|
39
|
+
ariaLabel?: string;
|
|
40
|
+
/** Custom z-index */
|
|
41
|
+
zIndex?: number;
|
|
42
|
+
/** Animation duration in ms (default: 300) */
|
|
43
|
+
animationDuration?: number;
|
|
44
|
+
/**
|
|
45
|
+
* CSS selector for drag handle element(s).
|
|
46
|
+
* Default: ".sv-bottom-sheet__handle"
|
|
47
|
+
* Example: ".sv-comment-sheet__header" for CommentSheet
|
|
48
|
+
*/
|
|
49
|
+
dragHandleSelector?: string;
|
|
50
|
+
/**
|
|
51
|
+
* CSS selector for scroll container (for overscroll-to-dismiss).
|
|
52
|
+
* Default: ".sv-bottom-sheet__content"
|
|
53
|
+
* Example: ".sv-comment-sheet__list" for CommentSheet
|
|
54
|
+
*/
|
|
55
|
+
scrollContainerSelector?: string;
|
|
56
|
+
/**
|
|
57
|
+
* CSS selector for elements that should NOT trigger drag.
|
|
58
|
+
* Example: ".sv-comment-sheet__input-container" for CommentSheet
|
|
59
|
+
*/
|
|
60
|
+
dragExcludeSelector?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Callback to lock/unlock global gestures (e.g., Feed swipe).
|
|
63
|
+
* Used to replace global touchmove blockers with centralized lock.
|
|
64
|
+
*/
|
|
65
|
+
onGestureLock?: (isLocked: boolean) => void;
|
|
66
|
+
}
|
|
67
|
+
declare function BottomSheetHeadlessComponent({ isOpen, onClose, children, height, className, backdropClassName, contentClassName, closeOnBackdropClick, closeOnEscape, showDragHandle, enableDragToDismiss, dragCloseThreshold, ariaLabel, zIndex, animationDuration, dragHandleSelector, scrollContainerSelector, dragExcludeSelector, onGestureLock, }: BottomSheetHeadlessProps): ReactElement | null;
|
|
68
|
+
declare const BottomSheetHeadless: react.MemoExoticComponent<typeof BottomSheetHeadlessComponent>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* BottomSheet CSS
|
|
72
|
+
*
|
|
73
|
+
* Base bottom sheet component styles.
|
|
74
|
+
* Features:
|
|
75
|
+
* - Portal-based rendering support
|
|
76
|
+
* - Slide-up/down animations
|
|
77
|
+
* - Backdrop with fade
|
|
78
|
+
* - Drag handle
|
|
79
|
+
* - iOS-safe scroll lock via body class
|
|
80
|
+
*/
|
|
81
|
+
declare const BOTTOM_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\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 /* Bottom sheet theming */\n --sv-sheet-bg: #ffffff;\n --sv-sheet-backdrop-bg: rgba(0, 0, 0, 0.5);\n --sv-sheet-handle-bg: rgba(0, 0, 0, 0.2);\n --sv-sheet-border-radius: 24px;\n --sv-sheet-z-index: 1000;\n --sv-sheet-animation-duration: 300ms;\n --sv-sheet-animation-easing: cubic-bezier(0.32, 0.72, 0, 1);\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\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-bottom-sheet-backdrop {\n position: fixed;\n inset: 0;\n background: var(--sv-sheet-backdrop-bg);\n z-index: 50;\n opacity: 0;\n visibility: hidden;\n pointer-events: none;\n transition: \n opacity var(--sv-sheet-animation-duration) ease,\n visibility 0s linear var(--sv-sheet-animation-duration);\n}\n\n.sv-bottom-sheet-backdrop[data-state=\"open\"] {\n opacity: 1;\n visibility: visible;\n pointer-events: auto;\n transition: \n opacity var(--sv-sheet-animation-duration) ease,\n visibility 0s linear 0s;\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 SHEET 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/* Keyframes */\n@keyframes sv-sheet-slide-up {\n from { transform: translateY(100vh); }\n to { transform: translateY(0); }\n}\n\n@keyframes sv-sheet-slide-down {\n from { transform: translateY(0); }\n to { transform: translateY(100vh); }\n}\n\n.sv-bottom-sheet {\n position: fixed;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--sv-sheet-bg);\n border-radius: var(--sv-sheet-border-radius) var(--sv-sheet-border-radius) 0 0;\n z-index: 51;\n display: flex;\n flex-direction: column;\n max-height: var(--sv-sheet-max-height, 80vh);\n transform: translateY(100vh);\n overflow: hidden;\n touch-action: pan-y;\n isolation: isolate;\n pointer-events: none;\n will-change: transform;\n outline: none;\n}\n\n.sv-bottom-sheet[data-state=\"open\"] {\n transform: translateY(0);\n pointer-events: auto;\n animation: sv-sheet-slide-up var(--sv-sheet-animation-duration) \n var(--sv-sheet-animation-easing) forwards;\n}\n\n.sv-bottom-sheet[data-state=\"closing\"] {\n pointer-events: none;\n animation: sv-sheet-slide-down var(--sv-sheet-animation-duration) \n var(--sv-sheet-animation-easing) forwards !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 DRAG HANDLE\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-bottom-sheet__handle {\n display: flex;\n justify-content: center;\n padding: 12px 0 8px;\n cursor: grab;\n touch-action: none;\n flex-shrink: 0;\n}\n\n.sv-bottom-sheet__handle:active {\n cursor: grabbing;\n}\n\n.sv-bottom-sheet__handle-bar {\n width: 36px;\n height: 4px;\n background: var(--sv-sheet-handle-bg);\n border-radius: 2px;\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 CONTENT\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-bottom-sheet__content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior: contain;\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 BODY SCROLL LOCK\n Disable scroll on underlying content when sheet is open\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\nbody.sv-bottom-sheet-open {\n overflow: hidden !important;\n position: fixed !important;\n width: 100% !important;\n /* top is set dynamically via JS to preserve scroll position */\n}\n\n/* CRITICAL: Disable VirtualSlider/VideoFeed swipe when sheet is open */\nbody.sv-bottom-sheet-open .sv-slider,\nbody.sv-bottom-sheet-open .sv-video-feed {\n pointer-events: none !important;\n touch-action: none !important;\n}\n\nbody.sv-bottom-sheet-open .sv-bottom-sheet,\nbody.sv-bottom-sheet-open .sv-bottom-sheet-backdrop {\n touch-action: auto !important;\n}\n";
|
|
82
|
+
/**
|
|
83
|
+
* Inject BottomSheet CSS into document
|
|
84
|
+
*/
|
|
85
|
+
declare function injectBottomSheetCSS(): void;
|
|
86
|
+
|
|
87
|
+
export { BOTTOM_SHEET_CSS, type BottomSheetContextValue, BottomSheetHeadless, type BottomSheetHeadlessProps, injectBottomSheetCSS, useBottomSheetContext };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BOTTOM_SHEET_CSS, BottomSheetHeadless, injectBottomSheetCSS, useBottomSheetContext } from '../../chunk-UYBQTE4M.js';
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
interface CleanModeOverlayHeadlessProps {
|
|
5
|
+
/** Whether clean mode is active */
|
|
6
|
+
isActive: boolean;
|
|
7
|
+
/** Whether video is playing */
|
|
8
|
+
isPlaying: boolean;
|
|
9
|
+
/** Current playback speed */
|
|
10
|
+
speed: number;
|
|
11
|
+
/** Current playback time in seconds */
|
|
12
|
+
currentTime: number;
|
|
13
|
+
/** Total duration in seconds */
|
|
14
|
+
duration: number;
|
|
15
|
+
/** Callback to toggle play/pause */
|
|
16
|
+
onTogglePlay: () => void;
|
|
17
|
+
/** Callback when speed changes */
|
|
18
|
+
onSpeedChange: (speed: number) => void;
|
|
19
|
+
/** Callback when user seeks */
|
|
20
|
+
onSeek: (time: number) => void;
|
|
21
|
+
/** Callback to exit clean mode */
|
|
22
|
+
onExit: () => void;
|
|
23
|
+
/** Available speed options (default: [0.5, 0.75, 1, 1.25, 1.5, 2]) */
|
|
24
|
+
speeds?: readonly number[];
|
|
25
|
+
/** Auto-hide delay in ms (default: 3000, 0 to disable) */
|
|
26
|
+
hideDelay?: number;
|
|
27
|
+
/** Custom exit icon */
|
|
28
|
+
exitIcon?: ReactNode;
|
|
29
|
+
/** Custom play icon */
|
|
30
|
+
playIcon?: ReactNode;
|
|
31
|
+
/** Custom pause icon */
|
|
32
|
+
pauseIcon?: ReactNode;
|
|
33
|
+
/** Custom class name */
|
|
34
|
+
className?: string;
|
|
35
|
+
/** Aria label for the overlay */
|
|
36
|
+
ariaLabel?: string;
|
|
37
|
+
}
|
|
38
|
+
declare function CleanModeOverlayHeadlessComponent({ isActive, isPlaying, speed, currentTime, duration, onTogglePlay, onSpeedChange, onSeek, onExit, speeds, hideDelay, exitIcon, playIcon, pauseIcon, className, ariaLabel, }: CleanModeOverlayHeadlessProps): ReactElement | null;
|
|
39
|
+
declare const CleanModeOverlayHeadless: react.MemoExoticComponent<typeof CleanModeOverlayHeadlessComponent>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* CleanModeOverlay CSS-in-TS
|
|
43
|
+
*
|
|
44
|
+
* Floating control bar for clean mode (TikTok-style).
|
|
45
|
+
* Layout: [Exit] ─── [Progress Bar] ─── [Play/Pause | Speed]
|
|
46
|
+
*
|
|
47
|
+
* NOTE: This CSS is injected WITHOUT @layer to ensure it resists
|
|
48
|
+
* global resets like `* { margin: 0; padding: 0; }`.
|
|
49
|
+
* Host app can still override via higher specificity selectors.
|
|
50
|
+
*/
|
|
51
|
+
declare const CLEAN_MODE_OVERLAY_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\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-clean-mode-container {\n /* Colors */\n --sv-clean-mode-bg: rgba(40, 40, 40, 0.85);\n --sv-clean-mode-text: rgba(255, 255, 255, 0.95);\n --sv-clean-mode-divider: rgba(255, 255, 255, 0.2);\n --sv-clean-mode-progress-bg: rgba(255, 255, 255, 0.3);\n --sv-clean-mode-progress-fill: rgba(255, 255, 255, 0.9);\n --sv-clean-mode-progress-thumb: #ffffff;\n \n /* Layout */\n --sv-clean-mode-radius: 50px;\n --sv-clean-mode-button-size: 48px;\n --sv-clean-mode-progress-height: 4px;\n \n /* Animation */\n --sv-clean-mode-duration: 200ms;\n --sv-clean-mode-easing: cubic-bezier(0.4, 0, 0.2, 1);\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 MAIN CONTAINER - Full width bar at bottom\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-clean-mode-container {\n position: absolute;\n bottom: 24px;\n left: 16px;\n right: 16px;\n z-index: 80;\n \n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0;\n padding: 0;\n \n /* Animation */\n opacity: 1;\n transition: opacity var(--sv-clean-mode-duration) var(--sv-clean-mode-easing);\n \n /* Prevent text selection */\n user-select: none;\n -webkit-user-select: none;\n pointer-events: none;\n}\n\n.sv-clean-mode-container[data-hidden=\"true\"] {\n opacity: 0;\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 LEFT PILL - Exit button\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-clean-mode-left {\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n \n width: var(--sv-clean-mode-button-size);\n height: var(--sv-clean-mode-button-size);\n margin: 0;\n padding: 0;\n \n background: var(--sv-clean-mode-bg);\n border-radius: var(--sv-clean-mode-radius);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n \n pointer-events: auto;\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 CENTER - Progress Bar\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-clean-mode-center {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n margin: 0;\n padding: 0;\n \n pointer-events: auto;\n}\n\n.sv-clean-mode-progress {\n position: relative;\n width: 100%;\n height: 24px;\n margin: 0;\n padding: 0;\n display: flex;\n align-items: center;\n cursor: pointer;\n touch-action: none;\n}\n\n.sv-clean-mode-progress-track {\n position: absolute;\n left: 0;\n right: 0;\n height: var(--sv-clean-mode-progress-height);\n margin: 0;\n padding: 0;\n background: var(--sv-clean-mode-progress-bg);\n border-radius: calc(var(--sv-clean-mode-progress-height) / 2);\n overflow: hidden;\n}\n\n.sv-clean-mode-progress-fill {\n height: 100%;\n margin: 0;\n padding: 0;\n background: var(--sv-clean-mode-progress-fill);\n border-radius: inherit;\n transition: width 100ms linear;\n}\n\n.sv-clean-mode-progress-thumb {\n position: absolute;\n width: 14px;\n height: 14px;\n margin: 0;\n padding: 0;\n background: var(--sv-clean-mode-progress-thumb);\n border-radius: 50%;\n transform: translateX(-50%);\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);\n opacity: 0;\n transition: opacity 150ms ease;\n}\n\n.sv-clean-mode-progress:hover .sv-clean-mode-progress-thumb,\n.sv-clean-mode-progress[data-dragging=\"true\"] .sv-clean-mode-progress-thumb {\n opacity: 1;\n}\n\n.sv-clean-mode-progress[data-dragging=\"true\"] .sv-clean-mode-progress-track {\n height: 6px;\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 RIGHT PILL - Play/Pause + Speed\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-clean-mode-right {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n \n height: var(--sv-clean-mode-button-size);\n margin: 0;\n padding: 0 4px;\n \n background: var(--sv-clean-mode-bg);\n border-radius: var(--sv-clean-mode-radius);\n backdrop-filter: blur(12px);\n -webkit-backdrop-filter: blur(12px);\n \n pointer-events: auto;\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 BUTTONS\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-clean-mode-button {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n \n height: 40px;\n margin: 0;\n padding: 0 14px;\n \n background: transparent;\n border: none;\n \n color: var(--sv-clean-mode-text);\n font-size: 15px;\n font-weight: 600;\n white-space: nowrap;\n \n cursor: pointer;\n transition: opacity 150ms ease;\n}\n\n.sv-clean-mode-button:active {\n opacity: 0.7;\n}\n\n.sv-clean-mode-button svg {\n width: 22px;\n height: 22px;\n margin: 0;\n padding: 0;\n flex-shrink: 0;\n}\n\n/* Exit button - icon only */\n.sv-clean-mode-exit {\n width: 40px;\n height: 40px;\n padding: 0;\n}\n\n.sv-clean-mode-exit svg {\n width: 20px;\n height: 20px;\n}\n\n/* Play/Pause button - icon only */\n.sv-clean-mode-play {\n width: 40px;\n padding: 0;\n}\n\n/* Speed button */\n.sv-clean-mode-speed {\n padding: 0 16px 0 8px;\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 DIVIDER\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-clean-mode-divider {\n width: 1px;\n height: 24px;\n margin: 0;\n padding: 0;\n background: var(--sv-clean-mode-divider);\n flex-shrink: 0;\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 TAP AREA (for showing hidden bar)\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-clean-mode-tap-area {\n position: absolute;\n inset: 0;\n z-index: 70;\n margin: 0;\n padding: 0;\n cursor: pointer;\n}\n\n/* Hide tap area when bar is visible */\n.sv-clean-mode-tap-area[data-visible=\"true\"] {\n pointer-events: none;\n}\n";
|
|
52
|
+
/**
|
|
53
|
+
* Inject CleanModeOverlay CSS into document.
|
|
54
|
+
*
|
|
55
|
+
* NOTE: Injected WITHOUT @layer (layered: false) so it resists
|
|
56
|
+
* global resets. Host app can still override with higher specificity.
|
|
57
|
+
*/
|
|
58
|
+
declare function injectCleanModeOverlayCSS(): void;
|
|
59
|
+
|
|
60
|
+
export { CLEAN_MODE_OVERLAY_CSS, CleanModeOverlayHeadless, type CleanModeOverlayHeadlessProps, injectCleanModeOverlayCSS };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CLEAN_MODE_OVERLAY_CSS, CleanModeOverlayHeadless, injectCleanModeOverlayCSS } from '../../chunk-QUEJHA24.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { C as COMMENT_SHEET_CSS, a as CommentInput, b as CommentInputProps, c as CommentItemComponent, d as CommentItemProps, e as CommentList, f as CommentListProps, g as CommentSheet, h as CommentSheetContext, i as CommentSheetContextValue, j as CommentSheetHeadless, k as CommentSheetHeadlessProps, l as CommentSheetI18n, R as ReplyTarget, S as SheetHeader, m as SheetHeaderProps, u as useCommentSheetContext, n as useOptionalCommentSheetContext } from '../../CommentSheet.css-DuBy01rU.js';
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import { ReactNode, ReactElement } from 'react';
|
|
4
4
|
import { CommentItem, ReplyItem } from '@xhub-short/contracts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { COMMENT_SHEET_CSS, CommentInput, CommentItemComponent, CommentItemSkeleton, CommentList, CommentListSkeleton, CommentMenu, CommentSheet, CommentSheetContext, CommentSheetHeadless, DeleteConfirmDialog, SheetHeader, useCommentMenuContext, useCommentSheetContext, useOptionalCommentSheetContext } from '../../chunk-
|
|
1
|
+
export { COMMENT_SHEET_CSS, CommentInput, CommentItemComponent, CommentItemSkeleton, CommentList, CommentListSkeleton, CommentMenu, CommentSheet, CommentSheetContext, CommentSheetHeadless, DeleteConfirmDialog, SheetHeader, useCommentMenuContext, useCommentSheetContext, useOptionalCommentSheetContext } from '../../chunk-IC2KUU4V.js';
|