@geekapps/silo-elements-nextjs 0.0.9 → 0.1.0

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/index.d.ts CHANGED
@@ -86,4 +86,26 @@ interface FileIconProps {
86
86
  }
87
87
  declare function FileIcon({ mimeType, name, size, iconSize, showName, showSize, className, style, }: FileIconProps): react_jsx_runtime.JSX.Element;
88
88
 
89
- export { Avatar, type AvatarProps, Background, type BackgroundProps, FileIcon, type FileIconProps, Thumbnail, type ThumbnailProps };
89
+ interface FileCardProps {
90
+ fileId: string;
91
+ /** Poll for status updates while processing (ms, default: 3000) */
92
+ pollInterval?: number;
93
+ /** Show action buttons */
94
+ actions?: Array<"preview" | "copy-url" | "download" | "delete">;
95
+ onPreview?: (fileId: string) => void;
96
+ onCopyUrl?: (url: string) => void;
97
+ onDelete?: (fileId: string) => void;
98
+ className?: string;
99
+ style?: CSSProperties;
100
+ }
101
+ declare function FileCard({ fileId, pollInterval, actions, onPreview, onCopyUrl, onDelete, className, style, }: FileCardProps): react_jsx_runtime.JSX.Element | null;
102
+
103
+ interface FilePreviewProps {
104
+ fileId: string | null;
105
+ onClose: () => void;
106
+ /** Poll interval while processing (ms, default: 3000) */
107
+ pollInterval?: number;
108
+ }
109
+ declare function FilePreview({ fileId, onClose, pollInterval }: FilePreviewProps): react_jsx_runtime.JSX.Element | null;
110
+
111
+ export { Avatar, type AvatarProps, Background, type BackgroundProps, FileCard, type FileCardProps, FileIcon, type FileIconProps, FilePreview, type FilePreviewProps, Thumbnail, type ThumbnailProps };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useRef, useCallback, useMemo, useEffect } from 'react';
2
- import { useMultipartUpload, useBatchUpload, useSignedUrl } from '@geekapps/silo-nextjs';
2
+ import { useMultipartUpload, useBatchUpload, useSignedUrl, useFileStatus } from '@geekapps/silo-nextjs';
3
3
  export { SiloProvider, useBatchUpload, useFileStatus, useMultipartUpload, useSignedUrl, useSiloClient } from '@geekapps/silo-nextjs';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import gsap from 'gsap';
@@ -1873,7 +1873,366 @@ function FileIcon({
1873
1873
  }
1874
1874
  );
1875
1875
  }
1876
+ var STATUS_LABEL = {
1877
+ CREATED: "Created",
1878
+ UPLOADING: "Uploading",
1879
+ INGESTING: "Ingesting",
1880
+ QUEUED: "Queued",
1881
+ PROCESSING: "Processing",
1882
+ SYNCING: "Syncing",
1883
+ READY: "Ready",
1884
+ FAILED: "Failed",
1885
+ CANCELLED: "Cancelled"
1886
+ };
1887
+ var STATUS_COLOR = {
1888
+ READY: "var(--silo-success, #22c55e)",
1889
+ FAILED: "var(--silo-error, #ef4444)",
1890
+ CANCELLED: "var(--silo-error, #ef4444)"
1891
+ };
1892
+ function statusColor(status) {
1893
+ return STATUS_COLOR[status] ?? "var(--silo-accent, #6366f1)";
1894
+ }
1895
+ function isProcessing(status) {
1896
+ return ["UPLOADING", "INGESTING", "QUEUED", "PROCESSING", "SYNCING"].includes(status);
1897
+ }
1898
+ function FileCard({
1899
+ fileId,
1900
+ pollInterval = 3e3,
1901
+ actions = ["preview", "copy-url"],
1902
+ onPreview,
1903
+ onCopyUrl,
1904
+ onDelete,
1905
+ className = "",
1906
+ style
1907
+ }) {
1908
+ const { file, loading } = useFileStatus(fileId, { pollInterval });
1909
+ const card = {
1910
+ display: "flex",
1911
+ flexDirection: "column",
1912
+ gap: 0,
1913
+ borderRadius: "var(--silo-radius, 12px)",
1914
+ border: "1px solid var(--silo-border, #e2e8f0)",
1915
+ background: "var(--silo-bg, #f8fafc)",
1916
+ overflow: "hidden",
1917
+ fontFamily: "var(--silo-font, inherit)",
1918
+ width: 220,
1919
+ ...style
1920
+ };
1921
+ if (loading && !file) {
1922
+ return /* @__PURE__ */ jsx("div", { className, style: { ...card, padding: 16, color: "var(--silo-text-muted, #94a3b8)", fontSize: 13 }, children: "Loading..." });
1923
+ }
1924
+ if (!file) return null;
1925
+ const status = file.status;
1926
+ const isImg = file.mimeType.startsWith("image/");
1927
+ const isVid = file.mimeType.startsWith("video/");
1928
+ const showThumb = isImg || isVid;
1929
+ const progress = file.progress ?? null;
1930
+ const ext = file.originalName.split(".").pop()?.toUpperCase();
1931
+ return /* @__PURE__ */ jsxs("div", { className, style: card, children: [
1932
+ /* @__PURE__ */ jsxs("div", { style: { position: "relative", height: 130, background: "var(--silo-bg-hover, #f1f5f9)", flexShrink: 0 }, children: [
1933
+ showThumb ? /* @__PURE__ */ jsx(
1934
+ Thumbnail,
1935
+ {
1936
+ fileKey: file.key,
1937
+ mimeType: file.mimeType,
1938
+ width: "100%",
1939
+ height: 130,
1940
+ borderRadius: "0",
1941
+ style: { display: "block" }
1942
+ }
1943
+ ) : /* @__PURE__ */ jsx("div", { style: { height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx(FileIcon, { mimeType: file.mimeType, name: file.originalName, iconSize: 44 }) }),
1944
+ /* @__PURE__ */ jsx(
1945
+ "span",
1946
+ {
1947
+ style: {
1948
+ position: "absolute",
1949
+ top: 8,
1950
+ right: 8,
1951
+ fontSize: 10,
1952
+ fontWeight: 700,
1953
+ letterSpacing: "0.05em",
1954
+ padding: "2px 7px",
1955
+ borderRadius: 99,
1956
+ background: "rgba(0,0,0,0.55)",
1957
+ color: statusColor(status),
1958
+ backdropFilter: "blur(4px)"
1959
+ },
1960
+ children: STATUS_LABEL[status] ?? status
1961
+ }
1962
+ ),
1963
+ ext && /* @__PURE__ */ jsx(
1964
+ "span",
1965
+ {
1966
+ style: {
1967
+ position: "absolute",
1968
+ top: 8,
1969
+ left: 8,
1970
+ fontSize: 9,
1971
+ fontWeight: 700,
1972
+ letterSpacing: "0.06em",
1973
+ padding: "2px 6px",
1974
+ borderRadius: 6,
1975
+ background: "rgba(0,0,0,0.45)",
1976
+ color: "#fff",
1977
+ backdropFilter: "blur(4px)"
1978
+ },
1979
+ children: ext
1980
+ }
1981
+ )
1982
+ ] }),
1983
+ /* @__PURE__ */ jsxs("div", { style: { padding: "10px 12px", display: "flex", flexDirection: "column", gap: 4 }, children: [
1984
+ /* @__PURE__ */ jsx(
1985
+ "span",
1986
+ {
1987
+ style: {
1988
+ fontSize: 13,
1989
+ fontWeight: 600,
1990
+ color: "var(--silo-text, #0f172a)",
1991
+ overflow: "hidden",
1992
+ textOverflow: "ellipsis",
1993
+ whiteSpace: "nowrap"
1994
+ },
1995
+ title: file.originalName,
1996
+ children: file.originalName
1997
+ }
1998
+ ),
1999
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 11, color: "var(--silo-text-muted, #94a3b8)" }, children: [
2000
+ formatBytes(file.size),
2001
+ file.metadata?.width && file.metadata?.height ? ` \xB7 ${file.metadata.width}\xD7${file.metadata.height}` : "",
2002
+ file.metadata?.duration ? ` \xB7 ${Math.round(file.metadata.duration)}s` : ""
2003
+ ] }),
2004
+ isProcessing(status) && /* @__PURE__ */ jsxs("div", { style: { marginTop: 4 }, children: [
2005
+ /* @__PURE__ */ jsx(ProgressBar, { progress: progress ?? 0 }),
2006
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 10, color: "var(--silo-text-muted, #94a3b8)", marginTop: 2, display: "block" }, children: [
2007
+ STATUS_LABEL[status],
2008
+ progress != null ? ` \xB7 ${progress}%` : ""
2009
+ ] })
2010
+ ] }),
2011
+ actions.length > 0 && /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, marginTop: 6, flexWrap: "wrap" }, children: [
2012
+ actions.includes("preview") && onPreview && /* @__PURE__ */ jsx("button", { onClick: () => onPreview(fileId), style: btnStyle, children: "Preview" }),
2013
+ actions.includes("copy-url") && onCopyUrl && /* @__PURE__ */ jsx(
2014
+ "button",
2015
+ {
2016
+ onClick: () => {
2017
+ const url = `${file.key}`;
2018
+ navigator.clipboard.writeText(url).catch(() => void 0);
2019
+ onCopyUrl(url);
2020
+ },
2021
+ style: btnStyle,
2022
+ children: "Copy URL"
2023
+ }
2024
+ ),
2025
+ actions.includes("delete") && onDelete && /* @__PURE__ */ jsx("button", { onClick: () => onDelete(fileId), style: { ...btnStyle, color: "var(--silo-error, #ef4444)" }, children: "Delete" })
2026
+ ] })
2027
+ ] })
2028
+ ] });
2029
+ }
2030
+ var btnStyle = {
2031
+ fontSize: 11,
2032
+ fontWeight: 600,
2033
+ padding: "3px 9px",
2034
+ borderRadius: 6,
2035
+ border: "1px solid var(--silo-border, #e2e8f0)",
2036
+ background: "transparent",
2037
+ color: "var(--silo-text, #0f172a)",
2038
+ cursor: "pointer",
2039
+ lineHeight: 1.6
2040
+ };
2041
+ var STATUS_LABEL2 = {
2042
+ CREATED: "Created",
2043
+ UPLOADING: "Uploading",
2044
+ INGESTING: "Ingesting",
2045
+ QUEUED: "Queued",
2046
+ PROCESSING: "Processing",
2047
+ SYNCING: "Syncing",
2048
+ READY: "Ready",
2049
+ FAILED: "Failed",
2050
+ CANCELLED: "Cancelled"
2051
+ };
2052
+ function isProcessing2(status) {
2053
+ return ["UPLOADING", "INGESTING", "QUEUED", "PROCESSING", "SYNCING"].includes(status);
2054
+ }
2055
+ function formatDate(iso) {
2056
+ return new Date(iso).toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
2057
+ }
2058
+ function FilePreview({ fileId, onClose, pollInterval = 3e3 }) {
2059
+ const { file, loading } = useFileStatus(fileId ?? void 0, {
2060
+ ...fileId ? { pollInterval } : {}
2061
+ });
2062
+ const status = file?.status ?? "";
2063
+ const { url } = useSignedUrl(file?.key ?? null);
2064
+ useEffect(() => {
2065
+ const handler = (e) => {
2066
+ if (e.key === "Escape") onClose();
2067
+ };
2068
+ window.addEventListener("keydown", handler);
2069
+ return () => window.removeEventListener("keydown", handler);
2070
+ }, [onClose]);
2071
+ if (!fileId) return null;
2072
+ const isImg = file?.mimeType.startsWith("image/");
2073
+ const isVid = file?.mimeType.startsWith("video/");
2074
+ const progress = file?.progress ?? null;
2075
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2076
+ /* @__PURE__ */ jsx(
2077
+ "div",
2078
+ {
2079
+ onClick: onClose,
2080
+ "aria-hidden": true,
2081
+ style: {
2082
+ position: "fixed",
2083
+ inset: 0,
2084
+ zIndex: 1e3,
2085
+ background: "rgba(0,0,0,0.6)",
2086
+ backdropFilter: "blur(6px)"
2087
+ }
2088
+ }
2089
+ ),
2090
+ /* @__PURE__ */ jsxs(
2091
+ "div",
2092
+ {
2093
+ role: "dialog",
2094
+ "aria-modal": true,
2095
+ "aria-label": file?.originalName ?? "File preview",
2096
+ style: modal,
2097
+ onKeyDown: (e) => {
2098
+ if (e.key === "Escape") onClose();
2099
+ },
2100
+ children: [
2101
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, padding: "16px 20px", borderBottom: "1px solid var(--silo-border, #e2e8f0)" }, children: [
2102
+ /* @__PURE__ */ jsx("span", { style: { flex: 1, fontSize: 14, fontWeight: 600, color: "var(--silo-text, #0f172a)", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: file?.originalName ?? "Loading..." }),
2103
+ /* @__PURE__ */ jsx("button", { onClick: onClose, "aria-label": "Close", style: closeBtn, children: "\u2715" })
2104
+ ] }),
2105
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", background: "#0f0f0f", minHeight: 240, position: "relative" }, children: [
2106
+ loading && !file && /* @__PURE__ */ jsx("span", { style: { color: "#64748b", fontSize: 13 }, children: "Loading..." }),
2107
+ file && isImg && url && /* @__PURE__ */ jsx(
2108
+ "img",
2109
+ {
2110
+ src: url,
2111
+ alt: file.originalName,
2112
+ style: { maxWidth: "100%", maxHeight: 420, objectFit: "contain", display: "block" }
2113
+ }
2114
+ ),
2115
+ file && isVid && url && /* @__PURE__ */ jsx(
2116
+ "video",
2117
+ {
2118
+ src: url,
2119
+ controls: true,
2120
+ style: { maxWidth: "100%", maxHeight: 420, display: "block" }
2121
+ }
2122
+ ),
2123
+ file && !isImg && !isVid && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, padding: 40 }, children: [
2124
+ /* @__PURE__ */ jsx(FileIcon, { mimeType: file.mimeType, name: file.originalName, iconSize: 64 }),
2125
+ /* @__PURE__ */ jsx("span", { style: { color: "#94a3b8", fontSize: 13 }, children: "No preview available" })
2126
+ ] }),
2127
+ file && isProcessing2(status) && /* @__PURE__ */ jsxs("div", { style: {
2128
+ position: "absolute",
2129
+ inset: 0,
2130
+ display: "flex",
2131
+ flexDirection: "column",
2132
+ alignItems: "center",
2133
+ justifyContent: "center",
2134
+ gap: 12,
2135
+ background: "rgba(0,0,0,0.65)"
2136
+ }, children: [
2137
+ /* @__PURE__ */ jsx("span", { style: { color: "#fff", fontSize: 14, fontWeight: 600 }, children: STATUS_LABEL2[status] }),
2138
+ /* @__PURE__ */ jsx("div", { style: { width: 200 }, children: /* @__PURE__ */ jsx(ProgressBar, { progress: progress ?? 0 }) }),
2139
+ progress != null && /* @__PURE__ */ jsxs("span", { style: { color: "#94a3b8", fontSize: 12 }, children: [
2140
+ progress,
2141
+ "%"
2142
+ ] })
2143
+ ] })
2144
+ ] }),
2145
+ file && /* @__PURE__ */ jsxs("div", { style: { padding: "14px 20px", borderTop: "1px solid var(--silo-border, #e2e8f0)", display: "flex", flexDirection: "column", gap: 8 }, children: [
2146
+ /* @__PURE__ */ jsxs("div", { style: metaGrid, children: [
2147
+ /* @__PURE__ */ jsx(MetaRow, { label: "Size", value: formatBytes(file.size) }),
2148
+ /* @__PURE__ */ jsx(MetaRow, { label: "Type", value: file.mimeType }),
2149
+ /* @__PURE__ */ jsx(MetaRow, { label: "Bucket", value: file.bucket }),
2150
+ /* @__PURE__ */ jsx(MetaRow, { label: "Status", value: STATUS_LABEL2[status] ?? status, highlight: status === "READY" }),
2151
+ file.metadata?.width && /* @__PURE__ */ jsx(MetaRow, { label: "Dimensions", value: `${file.metadata.width}\xD7${file.metadata.height}` }),
2152
+ file.metadata?.duration && /* @__PURE__ */ jsx(MetaRow, { label: "Duration", value: `${Math.round(file.metadata.duration)}s` }),
2153
+ file.metadata?.videoCodec && /* @__PURE__ */ jsx(MetaRow, { label: "Codec", value: file.metadata.videoCodec }),
2154
+ /* @__PURE__ */ jsx(MetaRow, { label: "Uploaded", value: formatDate(file.createdAt) })
2155
+ ] }),
2156
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, flexWrap: "wrap", marginTop: 4 }, children: [
2157
+ file.metadata?.hasHls && /* @__PURE__ */ jsx(Badge, { children: "HLS" }),
2158
+ file.metadata?.hasAv1 && /* @__PURE__ */ jsx(Badge, { children: "AV1" }),
2159
+ file.isPrivate ? /* @__PURE__ */ jsx(Badge, { muted: true, children: "Private" }) : /* @__PURE__ */ jsx(Badge, { children: "Public" })
2160
+ ] }),
2161
+ url && /* @__PURE__ */ jsx(
2162
+ "button",
2163
+ {
2164
+ onClick: () => navigator.clipboard.writeText(url).catch(() => void 0),
2165
+ style: { ...btnStyle2, marginTop: 4, width: "100%", textAlign: "center" },
2166
+ children: "Copy URL"
2167
+ }
2168
+ )
2169
+ ] })
2170
+ ]
2171
+ }
2172
+ )
2173
+ ] });
2174
+ }
2175
+ function MetaRow({ label, value, highlight }) {
2176
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2177
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: "var(--silo-text-muted, #94a3b8)", fontWeight: 500 }, children: label }),
2178
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: highlight ? "var(--silo-success, #22c55e)" : "var(--silo-text, #0f172a)", fontWeight: highlight ? 600 : 400 }, children: value })
2179
+ ] });
2180
+ }
2181
+ function Badge({ children, muted }) {
2182
+ return /* @__PURE__ */ jsx("span", { style: {
2183
+ fontSize: 10,
2184
+ fontWeight: 700,
2185
+ letterSpacing: "0.05em",
2186
+ padding: "2px 7px",
2187
+ borderRadius: 99,
2188
+ border: "1px solid var(--silo-border, #e2e8f0)",
2189
+ color: muted ? "var(--silo-text-muted, #94a3b8)" : "var(--silo-accent, #6366f1)",
2190
+ background: "transparent"
2191
+ }, children });
2192
+ }
2193
+ var modal = {
2194
+ position: "fixed",
2195
+ top: "50%",
2196
+ left: "50%",
2197
+ transform: "translate(-50%, -50%)",
2198
+ zIndex: 1001,
2199
+ width: "min(92vw, 560px)",
2200
+ maxHeight: "90vh",
2201
+ display: "flex",
2202
+ flexDirection: "column",
2203
+ borderRadius: "var(--silo-radius, 16px)",
2204
+ background: "var(--silo-bg, #fff)",
2205
+ boxShadow: "0 24px 80px rgba(0,0,0,0.35)",
2206
+ overflow: "hidden",
2207
+ fontFamily: "var(--silo-font, inherit)"
2208
+ };
2209
+ var closeBtn = {
2210
+ background: "none",
2211
+ border: "none",
2212
+ cursor: "pointer",
2213
+ fontSize: 16,
2214
+ color: "var(--silo-text-muted, #94a3b8)",
2215
+ lineHeight: 1,
2216
+ padding: "2px 4px",
2217
+ flexShrink: 0
2218
+ };
2219
+ var btnStyle2 = {
2220
+ fontSize: 12,
2221
+ fontWeight: 600,
2222
+ padding: "7px 14px",
2223
+ borderRadius: 8,
2224
+ border: "1px solid var(--silo-border, #e2e8f0)",
2225
+ background: "transparent",
2226
+ color: "var(--silo-text, #0f172a)",
2227
+ cursor: "pointer"
2228
+ };
2229
+ var metaGrid = {
2230
+ display: "grid",
2231
+ gridTemplateColumns: "auto 1fr",
2232
+ gap: "5px 16px",
2233
+ alignItems: "baseline"
2234
+ };
1876
2235
 
1877
- export { Avatar, Background, DropZone, FileIcon, FileUploader, ImageUploader, MediaUploader, ProgressBar, Source, Sources, Storyboard, StoryboardFrame, Subtitle, Subtitles, Thumbnail, Video, VideoPlayer, VideoUploader, defaultTheme, resolveTheme };
2236
+ export { Avatar, Background, DropZone, FileCard, FileIcon, FilePreview, FileUploader, ImageUploader, MediaUploader, ProgressBar, Source, Sources, Storyboard, StoryboardFrame, Subtitle, Subtitles, Thumbnail, Video, VideoPlayer, VideoUploader, defaultTheme, resolveTheme };
1878
2237
  //# sourceMappingURL=index.js.map
1879
2238
  //# sourceMappingURL=index.js.map