@geekapps/silo-elements-nextjs 0.0.2 → 0.0.4

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.
@@ -0,0 +1,137 @@
1
+ import { useState, useRef, useCallback } from 'react';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+
4
+ // src/utils/theme.ts
5
+ var defaultTheme = {
6
+ borderColor: "#e2e8f0",
7
+ borderColorActive: "#6366f1",
8
+ backgroundColor: "#f8fafc",
9
+ backgroundColorHover: "#f1f5f9",
10
+ textColor: "#0f172a",
11
+ textColorMuted: "#64748b",
12
+ accentColor: "#6366f1",
13
+ accentColorHover: "#4f46e5",
14
+ errorColor: "#ef4444",
15
+ successColor: "#22c55e",
16
+ borderRadius: "12px",
17
+ fontFamily: "inherit"
18
+ };
19
+ function resolveTheme(theme) {
20
+ return { ...defaultTheme, ...theme };
21
+ }
22
+ function themeToVars(theme) {
23
+ return {
24
+ "--silo-border": theme.borderColor,
25
+ "--silo-border-active": theme.borderColorActive,
26
+ "--silo-bg": theme.backgroundColor,
27
+ "--silo-bg-hover": theme.backgroundColorHover,
28
+ "--silo-text": theme.textColor,
29
+ "--silo-text-muted": theme.textColorMuted,
30
+ "--silo-accent": theme.accentColor,
31
+ "--silo-accent-hover": theme.accentColorHover,
32
+ "--silo-error": theme.errorColor,
33
+ "--silo-success": theme.successColor,
34
+ "--silo-radius": theme.borderRadius,
35
+ "--silo-font": theme.fontFamily
36
+ };
37
+ }
38
+ function DropZone({
39
+ accept,
40
+ multiple = false,
41
+ disabled = false,
42
+ maxSize,
43
+ onFiles,
44
+ onError,
45
+ className = "",
46
+ style,
47
+ theme,
48
+ children
49
+ }) {
50
+ const [dragging, setDragging] = useState(false);
51
+ const inputRef = useRef(null);
52
+ const t = resolveTheme(theme);
53
+ const vars = themeToVars(t);
54
+ const validate = useCallback(
55
+ (files) => {
56
+ return files.filter((f) => {
57
+ if (maxSize && f.size > maxSize) {
58
+ onError?.(new Error(`File "${f.name}" exceeds max size of ${maxSize} bytes`));
59
+ return false;
60
+ }
61
+ return true;
62
+ });
63
+ },
64
+ [maxSize, onError]
65
+ );
66
+ const handleDrop = useCallback(
67
+ (e) => {
68
+ e.preventDefault();
69
+ setDragging(false);
70
+ if (disabled) return;
71
+ const files = Array.from(e.dataTransfer.files);
72
+ const valid = validate(files);
73
+ if (valid.length) onFiles(valid);
74
+ },
75
+ [disabled, validate, onFiles]
76
+ );
77
+ const handleChange = useCallback(
78
+ (e) => {
79
+ const files = Array.from(e.target.files ?? []);
80
+ const valid = validate(files);
81
+ if (valid.length) onFiles(valid);
82
+ e.target.value = "";
83
+ },
84
+ [validate, onFiles]
85
+ );
86
+ const rootStyle = {
87
+ ...vars,
88
+ fontFamily: "var(--silo-font)",
89
+ border: `2px dashed ${dragging ? "var(--silo-border-active)" : "var(--silo-border)"}`,
90
+ borderRadius: "var(--silo-radius)",
91
+ backgroundColor: dragging ? "var(--silo-bg-hover)" : "var(--silo-bg)",
92
+ color: "var(--silo-text)",
93
+ cursor: disabled ? "not-allowed" : "pointer",
94
+ transition: "border-color 0.15s, background-color 0.15s",
95
+ opacity: disabled ? 0.5 : 1,
96
+ ...style
97
+ };
98
+ return /* @__PURE__ */ jsxs(
99
+ "div",
100
+ {
101
+ className: `silo-dropzone${className ? ` ${className}` : ""}`,
102
+ style: rootStyle,
103
+ onDragOver: (e) => {
104
+ e.preventDefault();
105
+ if (!disabled) setDragging(true);
106
+ },
107
+ onDragLeave: () => setDragging(false),
108
+ onDrop: handleDrop,
109
+ onClick: () => !disabled && inputRef.current?.click(),
110
+ role: "button",
111
+ tabIndex: disabled ? -1 : 0,
112
+ onKeyDown: (e) => {
113
+ if (e.key === "Enter" || e.key === " ") inputRef.current?.click();
114
+ },
115
+ "aria-label": "Upload area",
116
+ children: [
117
+ /* @__PURE__ */ jsx(
118
+ "input",
119
+ {
120
+ ref: inputRef,
121
+ type: "file",
122
+ accept,
123
+ multiple,
124
+ style: { display: "none" },
125
+ onChange: handleChange,
126
+ disabled
127
+ }
128
+ ),
129
+ children
130
+ ]
131
+ }
132
+ );
133
+ }
134
+
135
+ export { DropZone };
136
+ //# sourceMappingURL=DropZone.js.map
137
+ //# sourceMappingURL=DropZone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/theme.ts","../../src/components/DropZone.tsx"],"names":[],"mappings":"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","file":"DropZone.js","sourcesContent":["import type { SiloTheme } from \"../types.js\";\n\nexport const defaultTheme: Required<SiloTheme> = {\n borderColor: \"#e2e8f0\",\n borderColorActive: \"#6366f1\",\n backgroundColor: \"#f8fafc\",\n backgroundColorHover: \"#f1f5f9\",\n textColor: \"#0f172a\",\n textColorMuted: \"#64748b\",\n accentColor: \"#6366f1\",\n accentColorHover: \"#4f46e5\",\n errorColor: \"#ef4444\",\n successColor: \"#22c55e\",\n borderRadius: \"12px\",\n fontFamily: \"inherit\",\n};\n\nexport function resolveTheme(theme?: SiloTheme): Required<SiloTheme> {\n return { ...defaultTheme, ...theme };\n}\n\nexport function themeToVars(theme: Required<SiloTheme>): Record<string, string> {\n return {\n \"--silo-border\": theme.borderColor,\n \"--silo-border-active\": theme.borderColorActive,\n \"--silo-bg\": theme.backgroundColor,\n \"--silo-bg-hover\": theme.backgroundColorHover,\n \"--silo-text\": theme.textColor,\n \"--silo-text-muted\": theme.textColorMuted,\n \"--silo-accent\": theme.accentColor,\n \"--silo-accent-hover\": theme.accentColorHover,\n \"--silo-error\": theme.errorColor,\n \"--silo-success\": theme.successColor,\n \"--silo-radius\": theme.borderRadius,\n \"--silo-font\": theme.fontFamily,\n };\n}\n","\"use client\";\n\nimport {\n useState,\n useRef,\n useCallback,\n type DragEvent,\n type ChangeEvent,\n type ReactNode,\n type CSSProperties,\n} from \"react\";\nimport type { SiloTheme } from \"../types.js\";\nimport { resolveTheme, themeToVars } from \"../utils/theme.js\";\n\ninterface DropZoneProps {\n accept?: string;\n multiple?: boolean;\n disabled?: boolean;\n maxSize?: number;\n onFiles: (files: File[]) => void;\n onError?: (error: Error) => void;\n className?: string;\n style?: CSSProperties;\n theme?: SiloTheme;\n children: ReactNode;\n}\n\nexport function DropZone({\n accept,\n multiple = false,\n disabled = false,\n maxSize,\n onFiles,\n onError,\n className = \"\",\n style,\n theme,\n children,\n}: DropZoneProps) {\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n const t = resolveTheme(theme);\n const vars = themeToVars(t);\n\n const validate = useCallback(\n (files: File[]): File[] => {\n return files.filter((f) => {\n if (maxSize && f.size > maxSize) {\n onError?.(new Error(`File \"${f.name}\" exceeds max size of ${maxSize} bytes`));\n return false;\n }\n return true;\n });\n },\n [maxSize, onError]\n );\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n setDragging(false);\n if (disabled) return;\n const files = Array.from(e.dataTransfer.files);\n const valid = validate(files);\n if (valid.length) onFiles(valid);\n },\n [disabled, validate, onFiles]\n );\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(e.target.files ?? []);\n const valid = validate(files);\n if (valid.length) onFiles(valid);\n e.target.value = \"\";\n },\n [validate, onFiles]\n );\n\n const rootStyle: CSSProperties = {\n ...vars as CSSProperties,\n fontFamily: \"var(--silo-font)\",\n border: `2px dashed ${dragging ? \"var(--silo-border-active)\" : \"var(--silo-border)\"}`,\n borderRadius: \"var(--silo-radius)\",\n backgroundColor: dragging ? \"var(--silo-bg-hover)\" : \"var(--silo-bg)\",\n color: \"var(--silo-text)\",\n cursor: disabled ? \"not-allowed\" : \"pointer\",\n transition: \"border-color 0.15s, background-color 0.15s\",\n opacity: disabled ? 0.5 : 1,\n ...style,\n };\n\n return (\n <div\n className={`silo-dropzone${className ? ` ${className}` : \"\"}`}\n style={rootStyle}\n onDragOver={(e) => { e.preventDefault(); if (!disabled) setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n onClick={() => !disabled && inputRef.current?.click()}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onKeyDown={(e) => { if (e.key === \"Enter\" || e.key === \" \") inputRef.current?.click(); }}\n aria-label=\"Upload area\"\n >\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n style={{ display: \"none\" }}\n onChange={handleChange}\n disabled={disabled}\n />\n {children}\n </div>\n );\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { CSSProperties } from 'react';
3
+
4
+ interface ProgressBarProps {
5
+ progress: number;
6
+ className?: string;
7
+ style?: CSSProperties;
8
+ }
9
+ declare function ProgressBar({ progress, className, style }: ProgressBarProps): react_jsx_runtime.JSX.Element;
10
+
11
+ export { ProgressBar };
@@ -0,0 +1,38 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+
3
+ function ProgressBar({ progress, className = "", style }) {
4
+ return /* @__PURE__ */ jsx(
5
+ "div",
6
+ {
7
+ className: `silo-progress-track${className ? ` ${className}` : ""}`,
8
+ style: {
9
+ height: "6px",
10
+ borderRadius: "3px",
11
+ backgroundColor: "rgba(99,102,241,0.15)",
12
+ overflow: "hidden",
13
+ ...style
14
+ },
15
+ role: "progressbar",
16
+ "aria-valuenow": progress,
17
+ "aria-valuemin": 0,
18
+ "aria-valuemax": 100,
19
+ children: /* @__PURE__ */ jsx(
20
+ "div",
21
+ {
22
+ className: "silo-progress-fill",
23
+ style: {
24
+ height: "100%",
25
+ width: `${progress}%`,
26
+ backgroundColor: "var(--silo-accent, #6366f1)",
27
+ borderRadius: "3px",
28
+ transition: "width 0.2s ease"
29
+ }
30
+ }
31
+ )
32
+ }
33
+ );
34
+ }
35
+
36
+ export { ProgressBar };
37
+ //# sourceMappingURL=ProgressBar.js.map
38
+ //# sourceMappingURL=ProgressBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/ProgressBar.tsx"],"names":[],"mappings":";;AAUO,SAAS,YAAY,EAAE,QAAA,EAAU,SAAA,GAAY,EAAA,EAAI,OAAM,EAAqB;AACjF,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAW,CAAA,mBAAA,EAAsB,SAAA,GAAY,CAAA,CAAA,EAAI,SAAS,KAAK,EAAE,CAAA,CAAA;AAAA,MACjE,KAAA,EAAO;AAAA,QACL,MAAA,EAAQ,KAAA;AAAA,QACR,YAAA,EAAc,KAAA;AAAA,QACd,eAAA,EAAiB,uBAAA;AAAA,QACjB,QAAA,EAAU,QAAA;AAAA,QACV,GAAG;AAAA,OACL;AAAA,MACA,IAAA,EAAK,aAAA;AAAA,MACL,eAAA,EAAe,QAAA;AAAA,MACf,eAAA,EAAe,CAAA;AAAA,MACf,eAAA,EAAe,GAAA;AAAA,MAEf,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,SAAA,EAAU,oBAAA;AAAA,UACV,KAAA,EAAO;AAAA,YACL,MAAA,EAAQ,MAAA;AAAA,YACR,KAAA,EAAO,GAAG,QAAQ,CAAA,CAAA,CAAA;AAAA,YAClB,eAAA,EAAiB,6BAAA;AAAA,YACjB,YAAA,EAAc,KAAA;AAAA,YACd,UAAA,EAAY;AAAA;AACd;AAAA;AACF;AAAA,GACF;AAEJ","file":"ProgressBar.js","sourcesContent":["\"use client\";\n\nimport type { CSSProperties } from \"react\";\n\ninterface ProgressBarProps {\n progress: number;\n className?: string;\n style?: CSSProperties;\n}\n\nexport function ProgressBar({ progress, className = \"\", style }: ProgressBarProps) {\n return (\n <div\n className={`silo-progress-track${className ? ` ${className}` : \"\"}`}\n style={{\n height: \"6px\",\n borderRadius: \"3px\",\n backgroundColor: \"rgba(99,102,241,0.15)\",\n overflow: \"hidden\",\n ...style,\n }}\n role=\"progressbar\"\n aria-valuenow={progress}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className=\"silo-progress-fill\"\n style={{\n height: \"100%\",\n width: `${progress}%`,\n backgroundColor: \"var(--silo-accent, #6366f1)\",\n borderRadius: \"3px\",\n transition: \"width 0.2s ease\",\n }}\n />\n </div>\n );\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,220 +1,12 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { UploadResult } from '@geekapps/silo-nextjs';
1
+ export { ImageUploader } from './ImageUploader.js';
2
+ export { VideoUploader } from './VideoUploader.js';
3
+ export { FileUploader } from './FileUploader.js';
4
+ export { MediaUploader } from './MediaUploader.js';
5
+ export { Source, SourceProps, Sources, SourcesProps, Storyboard, StoryboardFrame, StoryboardFrameProps, StoryboardProps, Subtitle, SubtitleProps, Subtitles, SubtitlesProps, Video, VideoPlayer, VideoSourceType } from './VideoPlayer.js';
6
+ export { DropZone } from './components/DropZone.js';
7
+ export { ProgressBar } from './components/ProgressBar.js';
8
+ export { defaultTheme, resolveTheme } from './utils/theme.js';
9
+ export { BaseUploaderProps, FileUploaderProps, ImageUploaderProps, MediaUploaderProps, SiloTheme, VideoPlayerControls, VideoPlayerProps, VideoUploaderProps } from './types.js';
3
10
  export { SiloProvider, useFileStatus, useSignedUrl, useSiloClient, useUpload } from '@geekapps/silo-nextjs';
4
- import { ReactNode, CSSProperties } from 'react';
5
-
6
- interface BaseUploaderProps {
7
- /** Bucket to upload to */
8
- bucket?: string;
9
- /** Seconds until file expires (optional) */
10
- expiresIn?: number;
11
- /** Keep file private (default: true) */
12
- private?: boolean;
13
- /** Called when upload completes */
14
- onUpload?: (result: UploadResult) => void;
15
- /** Called when upload fails */
16
- onError?: (error: Error) => void;
17
- /** Custom className for the root element */
18
- className?: string;
19
- /** Custom styles */
20
- style?: React.CSSProperties;
21
- /** Disable the uploader */
22
- disabled?: boolean;
23
- /** Max file size in bytes */
24
- maxSize?: number;
25
- /** Custom label/content slot */
26
- children?: React.ReactNode;
27
- /** Override inner icon slot */
28
- renderIcon?: () => React.ReactNode;
29
- /** Override progress bar slot */
30
- renderProgress?: (progress: number) => React.ReactNode;
31
- /** Override success state slot */
32
- renderSuccess?: (result: UploadResult) => React.ReactNode;
33
- /** Override error state slot */
34
- renderError?: (error: Error, retry: () => void) => React.ReactNode;
35
- /** Theme tokens */
36
- theme?: SiloTheme;
37
- }
38
- interface SiloTheme {
39
- borderColor?: string;
40
- borderColorActive?: string;
41
- backgroundColor?: string;
42
- backgroundColorHover?: string;
43
- textColor?: string;
44
- textColorMuted?: string;
45
- accentColor?: string;
46
- accentColorHover?: string;
47
- errorColor?: string;
48
- successColor?: string;
49
- borderRadius?: string;
50
- fontFamily?: string;
51
- }
52
- interface ImageUploaderProps extends BaseUploaderProps {
53
- /** Allow cropping before upload */
54
- allowCrop?: boolean;
55
- /** Crop aspect ratio (e.g. 16/9) */
56
- cropAspectRatio?: number;
57
- /** Show preview after selection */
58
- showPreview?: boolean;
59
- /** Accept string (default: image/*) */
60
- accept?: string;
61
- }
62
- interface VideoUploaderProps extends BaseUploaderProps {
63
- /** Show video preview after selection */
64
- showPreview?: boolean;
65
- /** Accept string (default: video/*) */
66
- accept?: string;
67
- }
68
- interface FileUploaderProps extends BaseUploaderProps {
69
- /** Accepted MIME types or extensions */
70
- accept?: string;
71
- /** Allow multiple files */
72
- multiple?: boolean;
73
- }
74
- interface MediaUploaderProps extends BaseUploaderProps {
75
- /** Which tabs to show */
76
- tabs?: Array<"image" | "video" | "file">;
77
- /** Default active tab */
78
- defaultTab?: "image" | "video" | "file";
79
- imageProps?: Partial<ImageUploaderProps>;
80
- videoProps?: Partial<VideoUploaderProps>;
81
- fileProps?: Partial<FileUploaderProps>;
82
- }
83
- interface VideoPlayerProps {
84
- /** HLS playlist URL or direct MP4 URL */
85
- src: string;
86
- /** Poster/thumbnail image URL */
87
- poster?: string;
88
- /** Signed URL for private streams */
89
- token?: string;
90
- /** Auto play */
91
- autoPlay?: boolean;
92
- /** Loop */
93
- loop?: boolean;
94
- /** Mute */
95
- muted?: boolean;
96
- /** Show native controls (default: true) */
97
- controls?: boolean;
98
- /** Custom controls slot — disables native controls */
99
- renderControls?: (player: VideoPlayerControls) => React.ReactNode;
100
- /** Custom className */
101
- className?: string;
102
- /** Custom styles */
103
- style?: React.CSSProperties;
104
- /** Subtitle tracks */
105
- tracks?: Array<{
106
- src: string;
107
- label: string;
108
- srcLang: string;
109
- default?: boolean;
110
- }>;
111
- /** Theme */
112
- theme?: SiloTheme;
113
- /** Called when playback starts */
114
- onPlay?: () => void;
115
- /** Called when playback pauses */
116
- onPause?: () => void;
117
- /** Called on time update */
118
- onTimeUpdate?: (currentTime: number, duration: number) => void;
119
- }
120
- interface VideoPlayerControls {
121
- playing: boolean;
122
- currentTime: number;
123
- duration: number;
124
- volume: number;
125
- muted: boolean;
126
- play: () => void;
127
- pause: () => void;
128
- seek: (time: number) => void;
129
- setVolume: (vol: number) => void;
130
- toggleMute: () => void;
131
- requestFullscreen: () => void;
132
- }
133
-
134
- declare function ImageUploader({ bucket, expiresIn, private: isPrivate, onUpload, onError, className, style, disabled, maxSize, accept, showPreview, theme, renderIcon, renderProgress, renderSuccess, renderError, children, }: ImageUploaderProps): react_jsx_runtime.JSX.Element;
135
-
136
- declare function VideoUploader({ bucket, expiresIn, private: isPrivate, onUpload, onError, className, style, disabled, maxSize, accept, showPreview, theme, renderIcon, renderProgress, renderSuccess, renderError, children, }: VideoUploaderProps): react_jsx_runtime.JSX.Element;
137
-
138
- declare function FileUploader({ bucket, expiresIn, private: isPrivate, onUpload, onError, className, style, disabled, maxSize, accept, multiple, theme, renderIcon, renderProgress, renderSuccess, renderError, children, }: FileUploaderProps): react_jsx_runtime.JSX.Element;
139
-
140
- declare function MediaUploader({ tabs, defaultTab, imageProps, videoProps, fileProps, className, style, theme, onUpload, onError, ...shared }: MediaUploaderProps): react_jsx_runtime.JSX.Element;
141
-
142
- type VideoSourceType = "dash" | "hls" | "file";
143
- type SourceProps = {
144
- id?: string;
145
- src: string;
146
- label?: string;
147
- type?: VideoSourceType;
148
- default?: boolean;
149
- };
150
- type SourcesProps = {
151
- children: ReactNode;
152
- };
153
- type SubtitleProps = {
154
- src: string;
155
- srclang: string;
156
- label: string;
157
- default?: boolean;
158
- };
159
- type SubtitlesProps = {
160
- children: ReactNode;
161
- };
162
- type StoryboardFrameProps = {
163
- start: number;
164
- end: number;
165
- image: string;
166
- x?: number;
167
- y?: number;
168
- w?: number;
169
- h?: number;
170
- };
171
- type StoryboardProps = {
172
- src?: string;
173
- fallbackImage?: string;
174
- width?: number;
175
- height?: number;
176
- children?: ReactNode;
177
- };
178
- type VideoProps = {
179
- title?: string;
180
- description?: string;
181
- poster?: string;
182
- children: ReactNode;
183
- className?: string;
184
- autoHideControls?: boolean;
185
- defaultVolume?: number;
186
- };
187
- declare function Sources(_props: SourcesProps): null;
188
- declare function Source(_props: SourceProps): null;
189
- declare function Subtitles(_props: SubtitlesProps): null;
190
- declare function Subtitle(_props: SubtitleProps): null;
191
- declare function Storyboard(_props: StoryboardProps): null;
192
- declare function StoryboardFrame(_props: StoryboardFrameProps): null;
193
- declare function Video({ title, description, poster, children, className, autoHideControls, defaultVolume, }: VideoProps): react_jsx_runtime.JSX.Element;
194
- declare const VideoPlayer: typeof Video;
195
-
196
- interface DropZoneProps {
197
- accept?: string;
198
- multiple?: boolean;
199
- disabled?: boolean;
200
- maxSize?: number;
201
- onFiles: (files: File[]) => void;
202
- onError?: (error: Error) => void;
203
- className?: string;
204
- style?: CSSProperties;
205
- theme?: SiloTheme;
206
- children: ReactNode;
207
- }
208
- declare function DropZone({ accept, multiple, disabled, maxSize, onFiles, onError, className, style, theme, children, }: DropZoneProps): react_jsx_runtime.JSX.Element;
209
-
210
- interface ProgressBarProps {
211
- progress: number;
212
- className?: string;
213
- style?: CSSProperties;
214
- }
215
- declare function ProgressBar({ progress, className, style }: ProgressBarProps): react_jsx_runtime.JSX.Element;
216
-
217
- declare const defaultTheme: Required<SiloTheme>;
218
- declare function resolveTheme(theme?: SiloTheme): Required<SiloTheme>;
219
-
220
- export { type BaseUploaderProps, DropZone, FileUploader, type FileUploaderProps, ImageUploader, type ImageUploaderProps, MediaUploader, type MediaUploaderProps, ProgressBar, type SiloTheme, Source, type SourceProps, Sources, type SourcesProps, Storyboard, StoryboardFrame, type StoryboardFrameProps, type StoryboardProps, Subtitle, type SubtitleProps, Subtitles, type SubtitlesProps, Video, VideoPlayer, type VideoPlayerControls, type VideoPlayerProps, type VideoSourceType, VideoUploader, type VideoUploaderProps, defaultTheme, resolveTheme };
11
+ import 'react/jsx-runtime';
12
+ import 'react';
package/dist/index.js CHANGED
@@ -686,7 +686,8 @@ function Video({
686
686
  children,
687
687
  className,
688
688
  autoHideControls = true,
689
- defaultVolume = 0.72
689
+ defaultVolume = 0.72,
690
+ maxHeight
690
691
  }) {
691
692
  const parsed = useMemo(() => parseVideoChildren(children), [children]);
692
693
  const initialSourceIndex = useMemo(() => {
@@ -1234,7 +1235,8 @@ function Video({
1234
1235
  setControlsVisible(false);
1235
1236
  }
1236
1237
  },
1237
- className: "relative aspect-video w-full overflow-hidden rounded-[14px] bg-black shadow-[0_30px_90px_rgba(15,15,15,0.22)] outline-none ring-1 ring-black/5",
1238
+ className: "@container relative aspect-video w-full overflow-hidden rounded-[14px] bg-black shadow-[0_30px_90px_rgba(15,15,15,0.22)] outline-none ring-1 ring-black/5",
1239
+ style: maxHeight ? { maxHeight: typeof maxHeight === "number" ? `${maxHeight}px` : maxHeight } : void 0,
1238
1240
  children: [
1239
1241
  /* @__PURE__ */ jsx(
1240
1242
  "video",
@@ -1262,7 +1264,7 @@ function Video({
1262
1264
  "div",
1263
1265
  {
1264
1266
  className: `pointer-events-none absolute inset-0 z-10 grid place-items-center transition ${isPlaying ? "opacity-0" : "opacity-100"}`,
1265
- children: /* @__PURE__ */ jsx("span", { className: "grid size-20 place-items-center rounded-full bg-white/15 text-white backdrop-blur-xl ring-1 ring-white/20", children: /* @__PURE__ */ jsx(PlayIcon, { className: "ml-1 size-9" }) })
1267
+ children: /* @__PURE__ */ jsx("span", { className: "grid size-12 place-items-center rounded-full bg-white/15 text-white backdrop-blur-xl ring-1 ring-white/20 @sm:size-16 @lg:size-20", children: /* @__PURE__ */ jsx(PlayIcon, { className: "ml-1 size-5 @sm:size-7 @lg:size-9" }) })
1266
1268
  }
1267
1269
  ),
1268
1270
  isLoading && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 z-20 grid place-items-center bg-black/10", children: /* @__PURE__ */ jsx("div", { className: "size-9 animate-spin rounded-full border-2 border-white/25 border-t-white" }) }),
@@ -1274,7 +1276,7 @@ function Video({
1274
1276
  onClick: togglePlay,
1275
1277
  className: `absolute inset-0 z-30 flex flex-col justify-between bg-gradient-to-b from-black/55 via-black/10 to-black/75 ${controlsVisible ? "" : "pointer-events-none"}`,
1276
1278
  children: [
1277
- /* @__PURE__ */ jsxs("header", { onClick: (e) => e.stopPropagation(), className: "flex items-start justify-between gap-4 px-7 pt-7 text-white md:px-9 md:pt-8", children: [
1279
+ /* @__PURE__ */ jsxs("header", { onClick: (e) => e.stopPropagation(), className: "flex items-start justify-between gap-4 px-4 pt-4 text-white @sm:px-7 @sm:pt-7 @lg:px-9 @lg:pt-8", children: [
1278
1280
  /* @__PURE__ */ jsxs("div", { children: [
1279
1281
  title && /* @__PURE__ */ jsx("h1", { className: "text-lg font-bold tracking-wide md:text-xl", children: title }),
1280
1282
  description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm font-medium text-white/85", children: description })
@@ -1290,7 +1292,7 @@ function Video({
1290
1292
  }
1291
1293
  )
1292
1294
  ] }),
1293
- /* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "px-7 pb-7 text-white md:px-9 md:pb-8", children: [
1295
+ /* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "px-4 pb-4 text-white @sm:px-7 @sm:pb-7 @lg:px-9 @lg:pb-8", children: [
1294
1296
  /* @__PURE__ */ jsxs(
1295
1297
  "div",
1296
1298
  {