@sparkstudio/storage-ui 1.0.20 → 1.0.22

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.cjs CHANGED
@@ -294,20 +294,20 @@ var UploadDropzone = ({
294
294
  style,
295
295
  children
296
296
  }) => {
297
- const baseClass = "rounded-3 d-flex flex-column align-items-center justify-content-center ";
298
- const stateClass = isDragging ? "bg-light border-primary" : "border-secondary border-dashed";
299
- const combinedClassName = `${baseClass}${stateClass} ${className}`.trim();
297
+ const baseClass = "rounded-3 d-flex flex-column align-items-center justify-content-center";
298
+ const stateClass = isDragging ? "bg-body-secondary border-dashed border-2 border-secondary" : "bg-body-trasparent border-solid border-transparent border-2";
299
+ const combinedClassName = `${baseClass} ${stateClass} ${className}`.trim();
300
300
  const handleDragOver = (e) => {
301
301
  e.preventDefault();
302
- if (onDragOver) onDragOver(e);
302
+ onDragOver?.(e);
303
303
  };
304
304
  const handleDragLeave = (e) => {
305
305
  e.preventDefault();
306
- if (onDragLeave) onDragLeave(e);
306
+ onDragLeave?.(e);
307
307
  };
308
308
  const handleDrop = (e) => {
309
309
  e.preventDefault();
310
- if (onDrop) onDrop(e);
310
+ onDrop?.(e);
311
311
  };
312
312
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
313
313
  "div",
@@ -498,7 +498,7 @@ var UploadProgressList = ({
498
498
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
499
499
  "div",
500
500
  {
501
- className: "bg-white border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
501
+ className: "border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
502
502
  style: {
503
503
  width: 64,
504
504
  height: 64
@@ -741,7 +741,7 @@ var DesktopFileIcon = ({
741
741
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
742
742
  "div",
743
743
  {
744
- className: "bg-white border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
744
+ className: "border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
745
745
  style: {
746
746
  width: 64,
747
747
  height: 64
@@ -856,70 +856,97 @@ var UploadContainer = ({
856
856
  a.click();
857
857
  document.body.removeChild(a);
858
858
  };
859
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
860
- UploadDropzone,
861
- {
862
- isDragging,
863
- onDragOver: handleDragOver,
864
- onDragLeave: handleDragLeave,
865
- onDrop: handleDrop,
866
- className: "w-100",
867
- style: { minHeight: "260px", alignItems: "stretch" },
868
- children: [
869
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-100 mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "d-flex flex-column flex-md-row align-items-start align-items-md-center justify-content-between gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex-grow-1 w-100", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UploadProgressList, { uploads }) }) }) }),
870
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
871
- "div",
872
- {
873
- className: "w-100 d-flex flex-wrap gap-4 align-content-start",
874
- style: { minHeight: "140px" },
875
- children: existingFilesLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-100 d-flex justify-content-center align-items-center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "spinner-border text-secondary", role: "status" }) }) : existingFiles.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
876
- "div",
877
- {
878
- className: "w-100 d-flex flex-column align-items-center justify-content-center text-muted",
879
- style: {
880
- minHeight: "160px",
881
- padding: "20px",
882
- cursor: "pointer",
883
- transition: "background 0.12s, border-color 0.12s"
884
- },
885
- onClick: () => document.getElementById("filePicker")?.click(),
886
- onMouseEnter: (e) => e.currentTarget.style.borderColor = "#888",
887
- onMouseLeave: (e) => e.currentTarget.style.borderColor = "#ccc",
888
- children: [
889
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
890
- "input",
891
- {
892
- id: "filePicker",
893
- type: "file",
894
- multiple: true,
895
- hidden: true,
896
- onChange: (e) => {
897
- if (!e.target.files) return;
898
- onFilesSelected?.(e.target.files);
899
- startUploadsIfNeeded(e.target.files);
900
- }
901
- }
902
- ),
903
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Drag & drop files here" }),
904
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("small", { className: "mt-1", children: "\u2026or click to browse" })
905
- ]
906
- }
907
- ) : existingFiles.map((file) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
908
- DesktopFileIcon,
909
- {
910
- name: file.Name,
911
- sizeBytes: file.FileSize,
912
- downloadUrl: file.PublicUrl,
913
- onOpen: () => handleExistingFileOpen(file),
914
- onDelete: () => onDeleteFile?.(file)
915
- },
916
- file.Id
917
- ))
859
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
860
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "w-100", children: [
861
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
862
+ "input",
863
+ {
864
+ id: "filePicker",
865
+ type: "file",
866
+ multiple: true,
867
+ className: "d-none",
868
+ onChange: (e) => {
869
+ if (!e.target.files) return;
870
+ onFilesSelected?.(e.target.files);
871
+ startUploadsIfNeeded(e.target.files);
918
872
  }
919
- )
920
- ]
921
- }
922
- );
873
+ }
874
+ ),
875
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "text-start", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
876
+ "button",
877
+ {
878
+ type: "button",
879
+ className: "btn btn-primary float-start",
880
+ onClick: () => document.getElementById("filePicker")?.click(),
881
+ children: "Browse files\u2026"
882
+ }
883
+ ) })
884
+ ] }),
885
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
886
+ UploadDropzone,
887
+ {
888
+ isDragging,
889
+ onDragOver: handleDragOver,
890
+ onDragLeave: handleDragLeave,
891
+ onDrop: handleDrop,
892
+ className: "w-100",
893
+ style: { minHeight: "100px", alignItems: "stretch" },
894
+ children: [
895
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-100 mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "d-flex flex-column flex-md-row align-items-start align-items-md-center justify-content-between gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex-grow-1 w-100", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UploadProgressList, { uploads }) }) }) }),
896
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
897
+ "div",
898
+ {
899
+ className: "w-100 d-flex flex-wrap gap-4 align-content-start",
900
+ style: { minHeight: "140px" },
901
+ children: existingFilesLoading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-100 d-flex justify-content-center align-items-center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "spinner-border text-secondary", role: "status" }) }) : existingFiles.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
902
+ "div",
903
+ {
904
+ className: "w-100 d-flex flex-column align-items-center justify-content-center text-muted",
905
+ style: {
906
+ minHeight: "160px",
907
+ padding: "20px",
908
+ cursor: "pointer",
909
+ transition: "background 0.12s, border-color 0.12s"
910
+ },
911
+ onClick: () => document.getElementById("filePicker")?.click(),
912
+ onMouseEnter: (e) => e.currentTarget.style.borderColor = "#888",
913
+ onMouseLeave: (e) => e.currentTarget.style.borderColor = "#ccc",
914
+ children: [
915
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
916
+ "input",
917
+ {
918
+ id: "filePicker",
919
+ type: "file",
920
+ multiple: true,
921
+ hidden: true,
922
+ onChange: (e) => {
923
+ if (!e.target.files) return;
924
+ onFilesSelected?.(e.target.files);
925
+ startUploadsIfNeeded(e.target.files);
926
+ }
927
+ }
928
+ ),
929
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("strong", { children: "Drag & drop files here" }),
930
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("small", { className: "mt-1", children: "\u2026or click to browse" })
931
+ ]
932
+ }
933
+ ) : existingFiles.map((file) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
934
+ DesktopFileIcon,
935
+ {
936
+ name: file.Name,
937
+ sizeBytes: file.FileSize,
938
+ downloadUrl: file.PublicUrl,
939
+ onOpen: () => handleExistingFileOpen(file),
940
+ onDelete: () => onDeleteFile?.(file)
941
+ },
942
+ file.Id
943
+ ))
944
+ }
945
+ )
946
+ ]
947
+ }
948
+ )
949
+ ] });
923
950
  };
924
951
 
925
952
  // src/hooks/UseContainers.ts
@@ -1033,7 +1060,7 @@ var ContainerUploadPanel = ({
1033
1060
  // src/components/SingleFileProcessUploader.tsx
1034
1061
  var import_react8 = require("react");
1035
1062
  var import_jsx_runtime6 = require("react/jsx-runtime");
1036
- var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, label, disabled }) => {
1063
+ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, disabled }) => {
1037
1064
  const [selectedFile, setSelectedFile] = (0, import_react8.useState)(null);
1038
1065
  const [isDragging, setIsDragging] = (0, import_react8.useState)(false);
1039
1066
  const [progress, setProgress] = (0, import_react8.useState)(null);
@@ -1079,7 +1106,11 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1079
1106
  setProgress(0);
1080
1107
  setErrorMessage(null);
1081
1108
  const presignedUrl = await getPresignedUrl(selectedFile);
1082
- await UploadFileToS3(selectedFile, presignedUrl?.PresignedUrl ?? "", (p) => setProgress(p));
1109
+ await UploadFileToS3(
1110
+ selectedFile,
1111
+ presignedUrl?.PresignedUrl ?? "",
1112
+ (p) => setProgress(p)
1113
+ );
1083
1114
  setStatus("success");
1084
1115
  onUploadComplete?.(selectedFile, presignedUrl);
1085
1116
  } catch (err) {
@@ -1095,23 +1126,27 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1095
1126
  return "Unknown error during upload.";
1096
1127
  }
1097
1128
  const isUploading = status === "uploading";
1098
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
1099
- label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { style: { fontWeight: 600 }, children: label }),
1129
+ const dropzoneClasses = [
1130
+ "border",
1131
+ "border-2",
1132
+ "rounded",
1133
+ "p-3",
1134
+ "text-center",
1135
+ "user-select-none",
1136
+ disabled ? "opacity-50" : "cursor-pointer",
1137
+ isDragging ? "bg-body-secondary border-dashed border-2 border-secondary" : "bg-body-trasparent border-transparent border-2"
1138
+ ].join(" ");
1139
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "d-flex flex-column gap-2", children: [
1100
1140
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1101
1141
  "div",
1102
1142
  {
1143
+ className: dropzoneClasses,
1103
1144
  onDragOver: handleDragOver,
1104
1145
  onDragLeave: handleDragLeave,
1105
1146
  onDrop: handleDrop,
1106
1147
  onClick: handleBrowseClick,
1107
- style: {
1108
- border: "2px dashed #ccc",
1109
- borderRadius: 8,
1110
- padding: 16,
1111
- textAlign: "center",
1112
- cursor: disabled ? "not-allowed" : "pointer",
1113
- backgroundColor: isDragging ? "#f0f8ff" : "#fafafa"
1114
- },
1148
+ role: "button",
1149
+ "aria-disabled": disabled,
1115
1150
  children: [
1116
1151
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1117
1152
  "input",
@@ -1119,55 +1154,50 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1119
1154
  ref: fileInputRef,
1120
1155
  type: "file",
1121
1156
  accept,
1122
- style: { display: "none" },
1157
+ className: "d-none",
1123
1158
  onChange: handleInputChange,
1124
1159
  disabled
1125
1160
  }
1126
1161
  ),
1127
- selectedFile ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1162
+ selectedFile ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "small", children: [
1128
1163
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1129
1164
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Selected file:" }),
1130
1165
  " ",
1131
1166
  selectedFile.name
1132
1167
  ] }),
1133
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 12, color: "#666" }, children: "Click here to change file or drag a new one." })
1134
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1168
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-muted", children: "Click here to change file or drag a new one." })
1169
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "small", children: [
1135
1170
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: "Drag & drop a file here" }),
1136
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 12, color: "#666" }, children: "or click to browse" })
1171
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-muted", children: "or click to browse" })
1137
1172
  ] })
1138
1173
  ]
1139
1174
  }
1140
1175
  ),
1141
- isUploading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: 12 }, children: [
1142
- "Uploading... ",
1143
- progress ?? 0,
1144
- "%",
1145
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1176
+ isUploading && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "small", children: [
1177
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "d-flex justify-content-between mb-1", children: [
1178
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1179
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "spinner-border spinner-border-sm text-primary" }),
1180
+ " Uploading..."
1181
+ ] }),
1182
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1183
+ progress ?? 0,
1184
+ "%"
1185
+ ] })
1186
+ ] }),
1187
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "progress", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1146
1188
  "div",
1147
1189
  {
1148
- style: {
1149
- marginTop: 4,
1150
- height: 6,
1151
- borderRadius: 999,
1152
- backgroundColor: "#eee",
1153
- overflow: "hidden"
1154
- },
1155
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1156
- "div",
1157
- {
1158
- style: {
1159
- height: "100%",
1160
- width: `${progress ?? 0}%`,
1161
- backgroundColor: "#007bff",
1162
- transition: "width 0.2s ease-out"
1163
- }
1164
- }
1165
- )
1190
+ className: "progress-bar progress-bar-striped progress-bar-animated",
1191
+ role: "progressbar",
1192
+ "aria-valuemin": 0,
1193
+ "aria-valuemax": 100,
1194
+ "aria-valuenow": progress ?? 0,
1195
+ style: { width: `${progress ?? 0}%` }
1166
1196
  }
1167
- )
1197
+ ) })
1168
1198
  ] }),
1169
- status === "success" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 12, color: "green" }, children: "Upload complete \u2705" }),
1170
- status === "error" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { fontSize: 12, color: "red" }, children: [
1199
+ status === "success" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "small text-success", children: "Upload complete \u2705" }),
1200
+ status === "error" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "small text-danger", children: [
1171
1201
  "Upload failed: ",
1172
1202
  errorMessage
1173
1203
  ] }),
@@ -1177,15 +1207,7 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1177
1207
  type: "button",
1178
1208
  onClick: handleProcessClick,
1179
1209
  disabled: !selectedFile || isUploading || disabled,
1180
- style: {
1181
- padding: "8px 16px",
1182
- borderRadius: 4,
1183
- border: "none",
1184
- backgroundColor: !selectedFile || isUploading || disabled ? "#ccc" : "#007bff",
1185
- color: "#fff",
1186
- fontWeight: 600,
1187
- cursor: !selectedFile || isUploading || disabled ? "not-allowed" : "pointer"
1188
- },
1210
+ className: "btn btn-primary mt-2",
1189
1211
  children: isUploading ? "Processing..." : "Process"
1190
1212
  }
1191
1213
  )
package/dist/index.js CHANGED
@@ -251,20 +251,20 @@ var UploadDropzone = ({
251
251
  style,
252
252
  children
253
253
  }) => {
254
- const baseClass = "rounded-3 d-flex flex-column align-items-center justify-content-center ";
255
- const stateClass = isDragging ? "bg-light border-primary" : "border-secondary border-dashed";
256
- const combinedClassName = `${baseClass}${stateClass} ${className}`.trim();
254
+ const baseClass = "rounded-3 d-flex flex-column align-items-center justify-content-center";
255
+ const stateClass = isDragging ? "bg-body-secondary border-dashed border-2 border-secondary" : "bg-body-trasparent border-solid border-transparent border-2";
256
+ const combinedClassName = `${baseClass} ${stateClass} ${className}`.trim();
257
257
  const handleDragOver = (e) => {
258
258
  e.preventDefault();
259
- if (onDragOver) onDragOver(e);
259
+ onDragOver?.(e);
260
260
  };
261
261
  const handleDragLeave = (e) => {
262
262
  e.preventDefault();
263
- if (onDragLeave) onDragLeave(e);
263
+ onDragLeave?.(e);
264
264
  };
265
265
  const handleDrop = (e) => {
266
266
  e.preventDefault();
267
- if (onDrop) onDrop(e);
267
+ onDrop?.(e);
268
268
  };
269
269
  return /* @__PURE__ */ jsx(
270
270
  "div",
@@ -455,7 +455,7 @@ var UploadProgressList = ({
455
455
  /* @__PURE__ */ jsxs(
456
456
  "div",
457
457
  {
458
- className: "bg-white border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
458
+ className: "border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
459
459
  style: {
460
460
  width: 64,
461
461
  height: 64
@@ -708,7 +708,7 @@ var DesktopFileIcon = ({
708
708
  /* @__PURE__ */ jsxs2(
709
709
  "div",
710
710
  {
711
- className: "bg-white border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
711
+ className: "border rounded-3 d-flex align-items-center justify-content-center mb-1 shadow-sm position-relative",
712
712
  style: {
713
713
  width: 64,
714
714
  height: 64
@@ -774,7 +774,7 @@ var DesktopFileIcon = ({
774
774
  };
775
775
 
776
776
  // src/components/UploadContainer.tsx
777
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
777
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
778
778
  var UploadContainer = ({
779
779
  onFilesSelected,
780
780
  existingFiles = [],
@@ -823,70 +823,97 @@ var UploadContainer = ({
823
823
  a.click();
824
824
  document.body.removeChild(a);
825
825
  };
826
- return /* @__PURE__ */ jsxs3(
827
- UploadDropzone,
828
- {
829
- isDragging,
830
- onDragOver: handleDragOver,
831
- onDragLeave: handleDragLeave,
832
- onDrop: handleDrop,
833
- className: "w-100",
834
- style: { minHeight: "260px", alignItems: "stretch" },
835
- children: [
836
- /* @__PURE__ */ jsx4("div", { className: "w-100 mb-3", children: /* @__PURE__ */ jsx4("div", { className: "d-flex flex-column flex-md-row align-items-start align-items-md-center justify-content-between gap-3", children: /* @__PURE__ */ jsx4("div", { className: "flex-grow-1 w-100", children: /* @__PURE__ */ jsx4(UploadProgressList, { uploads }) }) }) }),
837
- /* @__PURE__ */ jsx4(
838
- "div",
839
- {
840
- className: "w-100 d-flex flex-wrap gap-4 align-content-start",
841
- style: { minHeight: "140px" },
842
- children: existingFilesLoading ? /* @__PURE__ */ jsx4("div", { className: "w-100 d-flex justify-content-center align-items-center", children: /* @__PURE__ */ jsx4("div", { className: "spinner-border text-secondary", role: "status" }) }) : existingFiles.length === 0 ? /* @__PURE__ */ jsxs3(
843
- "div",
844
- {
845
- className: "w-100 d-flex flex-column align-items-center justify-content-center text-muted",
846
- style: {
847
- minHeight: "160px",
848
- padding: "20px",
849
- cursor: "pointer",
850
- transition: "background 0.12s, border-color 0.12s"
851
- },
852
- onClick: () => document.getElementById("filePicker")?.click(),
853
- onMouseEnter: (e) => e.currentTarget.style.borderColor = "#888",
854
- onMouseLeave: (e) => e.currentTarget.style.borderColor = "#ccc",
855
- children: [
856
- /* @__PURE__ */ jsx4(
857
- "input",
858
- {
859
- id: "filePicker",
860
- type: "file",
861
- multiple: true,
862
- hidden: true,
863
- onChange: (e) => {
864
- if (!e.target.files) return;
865
- onFilesSelected?.(e.target.files);
866
- startUploadsIfNeeded(e.target.files);
867
- }
868
- }
869
- ),
870
- /* @__PURE__ */ jsx4("strong", { children: "Drag & drop files here" }),
871
- /* @__PURE__ */ jsx4("small", { className: "mt-1", children: "\u2026or click to browse" })
872
- ]
873
- }
874
- ) : existingFiles.map((file) => /* @__PURE__ */ jsx4(
875
- DesktopFileIcon,
876
- {
877
- name: file.Name,
878
- sizeBytes: file.FileSize,
879
- downloadUrl: file.PublicUrl,
880
- onOpen: () => handleExistingFileOpen(file),
881
- onDelete: () => onDeleteFile?.(file)
882
- },
883
- file.Id
884
- ))
826
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
827
+ /* @__PURE__ */ jsxs3("div", { className: "w-100", children: [
828
+ /* @__PURE__ */ jsx4(
829
+ "input",
830
+ {
831
+ id: "filePicker",
832
+ type: "file",
833
+ multiple: true,
834
+ className: "d-none",
835
+ onChange: (e) => {
836
+ if (!e.target.files) return;
837
+ onFilesSelected?.(e.target.files);
838
+ startUploadsIfNeeded(e.target.files);
885
839
  }
886
- )
887
- ]
888
- }
889
- );
840
+ }
841
+ ),
842
+ /* @__PURE__ */ jsx4("div", { className: "text-start", children: /* @__PURE__ */ jsx4(
843
+ "button",
844
+ {
845
+ type: "button",
846
+ className: "btn btn-primary float-start",
847
+ onClick: () => document.getElementById("filePicker")?.click(),
848
+ children: "Browse files\u2026"
849
+ }
850
+ ) })
851
+ ] }),
852
+ /* @__PURE__ */ jsxs3(
853
+ UploadDropzone,
854
+ {
855
+ isDragging,
856
+ onDragOver: handleDragOver,
857
+ onDragLeave: handleDragLeave,
858
+ onDrop: handleDrop,
859
+ className: "w-100",
860
+ style: { minHeight: "100px", alignItems: "stretch" },
861
+ children: [
862
+ /* @__PURE__ */ jsx4("div", { className: "w-100 mb-3", children: /* @__PURE__ */ jsx4("div", { className: "d-flex flex-column flex-md-row align-items-start align-items-md-center justify-content-between gap-3", children: /* @__PURE__ */ jsx4("div", { className: "flex-grow-1 w-100", children: /* @__PURE__ */ jsx4(UploadProgressList, { uploads }) }) }) }),
863
+ /* @__PURE__ */ jsx4(
864
+ "div",
865
+ {
866
+ className: "w-100 d-flex flex-wrap gap-4 align-content-start",
867
+ style: { minHeight: "140px" },
868
+ children: existingFilesLoading ? /* @__PURE__ */ jsx4("div", { className: "w-100 d-flex justify-content-center align-items-center", children: /* @__PURE__ */ jsx4("div", { className: "spinner-border text-secondary", role: "status" }) }) : existingFiles.length === 0 ? /* @__PURE__ */ jsxs3(
869
+ "div",
870
+ {
871
+ className: "w-100 d-flex flex-column align-items-center justify-content-center text-muted",
872
+ style: {
873
+ minHeight: "160px",
874
+ padding: "20px",
875
+ cursor: "pointer",
876
+ transition: "background 0.12s, border-color 0.12s"
877
+ },
878
+ onClick: () => document.getElementById("filePicker")?.click(),
879
+ onMouseEnter: (e) => e.currentTarget.style.borderColor = "#888",
880
+ onMouseLeave: (e) => e.currentTarget.style.borderColor = "#ccc",
881
+ children: [
882
+ /* @__PURE__ */ jsx4(
883
+ "input",
884
+ {
885
+ id: "filePicker",
886
+ type: "file",
887
+ multiple: true,
888
+ hidden: true,
889
+ onChange: (e) => {
890
+ if (!e.target.files) return;
891
+ onFilesSelected?.(e.target.files);
892
+ startUploadsIfNeeded(e.target.files);
893
+ }
894
+ }
895
+ ),
896
+ /* @__PURE__ */ jsx4("strong", { children: "Drag & drop files here" }),
897
+ /* @__PURE__ */ jsx4("small", { className: "mt-1", children: "\u2026or click to browse" })
898
+ ]
899
+ }
900
+ ) : existingFiles.map((file) => /* @__PURE__ */ jsx4(
901
+ DesktopFileIcon,
902
+ {
903
+ name: file.Name,
904
+ sizeBytes: file.FileSize,
905
+ downloadUrl: file.PublicUrl,
906
+ onOpen: () => handleExistingFileOpen(file),
907
+ onDelete: () => onDeleteFile?.(file)
908
+ },
909
+ file.Id
910
+ ))
911
+ }
912
+ )
913
+ ]
914
+ }
915
+ )
916
+ ] });
890
917
  };
891
918
 
892
919
  // src/hooks/UseContainers.ts
@@ -1000,7 +1027,7 @@ var ContainerUploadPanel = ({
1000
1027
  // src/components/SingleFileProcessUploader.tsx
1001
1028
  import { useCallback as useCallback2, useRef as useRef2, useState as useState5 } from "react";
1002
1029
  import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1003
- var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, label, disabled }) => {
1030
+ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, disabled }) => {
1004
1031
  const [selectedFile, setSelectedFile] = useState5(null);
1005
1032
  const [isDragging, setIsDragging] = useState5(false);
1006
1033
  const [progress, setProgress] = useState5(null);
@@ -1046,7 +1073,11 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1046
1073
  setProgress(0);
1047
1074
  setErrorMessage(null);
1048
1075
  const presignedUrl = await getPresignedUrl(selectedFile);
1049
- await UploadFileToS3(selectedFile, presignedUrl?.PresignedUrl ?? "", (p) => setProgress(p));
1076
+ await UploadFileToS3(
1077
+ selectedFile,
1078
+ presignedUrl?.PresignedUrl ?? "",
1079
+ (p) => setProgress(p)
1080
+ );
1050
1081
  setStatus("success");
1051
1082
  onUploadComplete?.(selectedFile, presignedUrl);
1052
1083
  } catch (err) {
@@ -1062,23 +1093,27 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1062
1093
  return "Unknown error during upload.";
1063
1094
  }
1064
1095
  const isUploading = status === "uploading";
1065
- return /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
1066
- label && /* @__PURE__ */ jsx6("label", { style: { fontWeight: 600 }, children: label }),
1096
+ const dropzoneClasses = [
1097
+ "border",
1098
+ "border-2",
1099
+ "rounded",
1100
+ "p-3",
1101
+ "text-center",
1102
+ "user-select-none",
1103
+ disabled ? "opacity-50" : "cursor-pointer",
1104
+ isDragging ? "bg-body-secondary border-dashed border-2 border-secondary" : "bg-body-trasparent border-transparent border-2"
1105
+ ].join(" ");
1106
+ return /* @__PURE__ */ jsxs4("div", { className: "d-flex flex-column gap-2", children: [
1067
1107
  /* @__PURE__ */ jsxs4(
1068
1108
  "div",
1069
1109
  {
1110
+ className: dropzoneClasses,
1070
1111
  onDragOver: handleDragOver,
1071
1112
  onDragLeave: handleDragLeave,
1072
1113
  onDrop: handleDrop,
1073
1114
  onClick: handleBrowseClick,
1074
- style: {
1075
- border: "2px dashed #ccc",
1076
- borderRadius: 8,
1077
- padding: 16,
1078
- textAlign: "center",
1079
- cursor: disabled ? "not-allowed" : "pointer",
1080
- backgroundColor: isDragging ? "#f0f8ff" : "#fafafa"
1081
- },
1115
+ role: "button",
1116
+ "aria-disabled": disabled,
1082
1117
  children: [
1083
1118
  /* @__PURE__ */ jsx6(
1084
1119
  "input",
@@ -1086,55 +1121,50 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1086
1121
  ref: fileInputRef,
1087
1122
  type: "file",
1088
1123
  accept,
1089
- style: { display: "none" },
1124
+ className: "d-none",
1090
1125
  onChange: handleInputChange,
1091
1126
  disabled
1092
1127
  }
1093
1128
  ),
1094
- selectedFile ? /* @__PURE__ */ jsxs4("div", { children: [
1129
+ selectedFile ? /* @__PURE__ */ jsxs4("div", { className: "small", children: [
1095
1130
  /* @__PURE__ */ jsxs4("div", { children: [
1096
1131
  /* @__PURE__ */ jsx6("strong", { children: "Selected file:" }),
1097
1132
  " ",
1098
1133
  selectedFile.name
1099
1134
  ] }),
1100
- /* @__PURE__ */ jsx6("div", { style: { fontSize: 12, color: "#666" }, children: "Click here to change file or drag a new one." })
1101
- ] }) : /* @__PURE__ */ jsxs4("div", { children: [
1135
+ /* @__PURE__ */ jsx6("div", { className: "text-muted", children: "Click here to change file or drag a new one." })
1136
+ ] }) : /* @__PURE__ */ jsxs4("div", { className: "small", children: [
1102
1137
  /* @__PURE__ */ jsx6("div", { children: "Drag & drop a file here" }),
1103
- /* @__PURE__ */ jsx6("div", { style: { fontSize: 12, color: "#666" }, children: "or click to browse" })
1138
+ /* @__PURE__ */ jsx6("div", { className: "text-muted", children: "or click to browse" })
1104
1139
  ] })
1105
1140
  ]
1106
1141
  }
1107
1142
  ),
1108
- isUploading && /* @__PURE__ */ jsxs4("div", { style: { fontSize: 12 }, children: [
1109
- "Uploading... ",
1110
- progress ?? 0,
1111
- "%",
1112
- /* @__PURE__ */ jsx6(
1143
+ isUploading && /* @__PURE__ */ jsxs4("div", { className: "small", children: [
1144
+ /* @__PURE__ */ jsxs4("div", { className: "d-flex justify-content-between mb-1", children: [
1145
+ /* @__PURE__ */ jsxs4("span", { children: [
1146
+ /* @__PURE__ */ jsx6("div", { className: "spinner-border spinner-border-sm text-primary" }),
1147
+ " Uploading..."
1148
+ ] }),
1149
+ /* @__PURE__ */ jsxs4("span", { children: [
1150
+ progress ?? 0,
1151
+ "%"
1152
+ ] })
1153
+ ] }),
1154
+ /* @__PURE__ */ jsx6("div", { className: "progress", children: /* @__PURE__ */ jsx6(
1113
1155
  "div",
1114
1156
  {
1115
- style: {
1116
- marginTop: 4,
1117
- height: 6,
1118
- borderRadius: 999,
1119
- backgroundColor: "#eee",
1120
- overflow: "hidden"
1121
- },
1122
- children: /* @__PURE__ */ jsx6(
1123
- "div",
1124
- {
1125
- style: {
1126
- height: "100%",
1127
- width: `${progress ?? 0}%`,
1128
- backgroundColor: "#007bff",
1129
- transition: "width 0.2s ease-out"
1130
- }
1131
- }
1132
- )
1157
+ className: "progress-bar progress-bar-striped progress-bar-animated",
1158
+ role: "progressbar",
1159
+ "aria-valuemin": 0,
1160
+ "aria-valuemax": 100,
1161
+ "aria-valuenow": progress ?? 0,
1162
+ style: { width: `${progress ?? 0}%` }
1133
1163
  }
1134
- )
1164
+ ) })
1135
1165
  ] }),
1136
- status === "success" && /* @__PURE__ */ jsx6("div", { style: { fontSize: 12, color: "green" }, children: "Upload complete \u2705" }),
1137
- status === "error" && /* @__PURE__ */ jsxs4("div", { style: { fontSize: 12, color: "red" }, children: [
1166
+ status === "success" && /* @__PURE__ */ jsx6("div", { className: "small text-success", children: "Upload complete \u2705" }),
1167
+ status === "error" && /* @__PURE__ */ jsxs4("div", { className: "small text-danger", children: [
1138
1168
  "Upload failed: ",
1139
1169
  errorMessage
1140
1170
  ] }),
@@ -1144,15 +1174,7 @@ var SingleFileProcessUploader = ({ getPresignedUrl, onUploadComplete, accept, la
1144
1174
  type: "button",
1145
1175
  onClick: handleProcessClick,
1146
1176
  disabled: !selectedFile || isUploading || disabled,
1147
- style: {
1148
- padding: "8px 16px",
1149
- borderRadius: 4,
1150
- border: "none",
1151
- backgroundColor: !selectedFile || isUploading || disabled ? "#ccc" : "#007bff",
1152
- color: "#fff",
1153
- fontWeight: 600,
1154
- cursor: !selectedFile || isUploading || disabled ? "not-allowed" : "pointer"
1155
- },
1177
+ className: "btn btn-primary mt-2",
1156
1178
  children: isUploading ? "Processing..." : "Process"
1157
1179
  }
1158
1180
  )
@@ -1166,7 +1188,7 @@ import {
1166
1188
  UserInfoCard,
1167
1189
  useUser
1168
1190
  } from "@sparkstudio/authentication-ui";
1169
- import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1191
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1170
1192
  function HomeView() {
1171
1193
  return /* @__PURE__ */ jsx7(
1172
1194
  AuthenticatorProvider,
@@ -1189,9 +1211,9 @@ function HomeContent() {
1189
1211
  const result = await res.s3.GetTemporaryPreSignedUrl(new TemporaryFileDTO({ Name: file.name, ContentType: contentType }));
1190
1212
  return result;
1191
1213
  }
1192
- return /* @__PURE__ */ jsxs5(Fragment2, { children: [
1214
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
1193
1215
  /* @__PURE__ */ jsx7(UserInfoCard, {}),
1194
- user && /* @__PURE__ */ jsxs5(Fragment2, { children: [
1216
+ user && /* @__PURE__ */ jsxs5(Fragment3, { children: [
1195
1217
  /* @__PURE__ */ jsx7(
1196
1218
  SingleFileProcessUploader,
1197
1219
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkstudio/storage-ui",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -40,7 +40,7 @@
40
40
  "@fortawesome/free-solid-svg-icons": "^7.1.0",
41
41
  "@fortawesome/react-fontawesome": "^3.1.1",
42
42
  "@sparkstudio/authentication-ui": "^1.0.29",
43
- "@sparkstudio/common-ui": "^1.0.14",
43
+ "@sparkstudio/common-ui": "^1.0.29",
44
44
  "barrelsby": "^2.8.1"
45
45
  },
46
46
  "devDependencies": {
package/dist/index.css DELETED
@@ -1,3 +0,0 @@
1
- @import "/node_modules/@sparkstudio/common-ui/dist/index.css";
2
-
3
- /*# sourceMappingURL=index.css.map */
@@ -1 +0,0 @@
1
- {"version":3,"sourceRoot":"","sources":["../src/index.scss"],"names":[],"mappings":"AAAQ","file":"index.css"}
package/dist/index.d.cts DELETED
@@ -1,228 +0,0 @@
1
- import * as React from 'react';
2
- import React__default from 'react';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
4
-
5
- declare enum ContainerType {
6
- File = 0,
7
- Folder = 1,
8
- Root = 2
9
- }
10
-
11
- /**
12
- * Represents an Auto-generated model for ContainerDTO.
13
- */
14
- interface IContainerDTO {
15
- Id: string;
16
- ContainerType: ContainerType;
17
- Name?: string;
18
- ContentType?: string;
19
- PublicUrl?: string;
20
- CreatedDate: string;
21
- FileSize: number;
22
- UserId: string;
23
- ParentContainerId: string;
24
- }
25
- type ContainerDTOInit = Partial<IContainerDTO> & Pick<IContainerDTO, "Id" | "ContainerType" | "CreatedDate" | "FileSize" | "UserId" | "ParentContainerId">;
26
- declare class ContainerDTO implements IContainerDTO {
27
- Id: string;
28
- ContainerType: ContainerType;
29
- Name?: string;
30
- ContentType?: string;
31
- PublicUrl?: string;
32
- CreatedDate: string;
33
- FileSize: number;
34
- UserId: string;
35
- ParentContainerId: string;
36
- constructor(init: ContainerDTOInit);
37
- }
38
-
39
- /**
40
- * Auto-generated client for the Container controller.
41
- */
42
- declare class Container {
43
- private baseUrl;
44
- constructor(baseUrl: string);
45
- ReadChildrenByContainerId(parentId: string): Promise<ContainerDTO[]>;
46
- ReadRootContainers(): Promise<ContainerDTO[]>;
47
- Read(id: string): Promise<ContainerDTO>;
48
- Create(containerDTO: ContainerDTO): Promise<ContainerDTO>;
49
- Update(containerDTO: ContainerDTO): Promise<ContainerDTO>;
50
- DeleteContainer(id: string): Promise<ContainerDTO>;
51
- CreateFileContainer(fileName: string, size: number, contentType: string): Promise<ContainerDTO>;
52
- }
53
-
54
- /**
55
- * Auto-generated client for the Home controller.
56
- */
57
- declare class Home {
58
- private baseUrl;
59
- constructor(baseUrl: string);
60
- }
61
-
62
- /**
63
- * Represents an Auto-generated model for AWSPresignedUrlDTO.
64
- */
65
- interface IAWSPresignedUrlDTO {
66
- PresignedUrl?: string;
67
- PublicUrl?: string;
68
- Key?: string;
69
- }
70
- type AWSPresignedUrlDTOInit = Partial<IAWSPresignedUrlDTO>;
71
- declare class AWSPresignedUrlDTO implements IAWSPresignedUrlDTO {
72
- PresignedUrl?: string;
73
- PublicUrl?: string;
74
- Key?: string;
75
- constructor(init: AWSPresignedUrlDTOInit);
76
- }
77
-
78
- /**
79
- * Represents an Auto-generated model for TemporaryFileDTO.
80
- */
81
- interface ITemporaryFileDTO {
82
- Name?: string;
83
- ContentType?: string;
84
- }
85
- type TemporaryFileDTOInit = Partial<ITemporaryFileDTO>;
86
- declare class TemporaryFileDTO implements ITemporaryFileDTO {
87
- Name?: string;
88
- ContentType?: string;
89
- constructor(init: TemporaryFileDTOInit);
90
- }
91
-
92
- /**
93
- * Auto-generated client for the S3 controller.
94
- */
95
- declare class S3 {
96
- private baseUrl;
97
- constructor(baseUrl: string);
98
- DeleteS3(containerDTO: ContainerDTO): Promise<ContainerDTO>;
99
- GetPreSignedUrl(containerDTO: ContainerDTO): Promise<AWSPresignedUrlDTO>;
100
- GetTemporaryPreSignedUrl(temporaryFileDTO: TemporaryFileDTO): Promise<AWSPresignedUrlDTO>;
101
- }
102
-
103
- /**
104
- * Auto-generated API client.
105
- */
106
- declare class SparkStudioStorageSDK {
107
- container: Container;
108
- home: Home;
109
- s3: S3;
110
- constructor(baseUrl: string);
111
- }
112
-
113
- interface ContainerUploadPanelProps {
114
- /** Base URL for the Container API (the SDK you pasted). */
115
- containerApiBaseUrl: string;
116
- /** Base URL for your storage / presign endpoint (used by getPresignedUrl). */
117
- storageApiBaseUrl: string;
118
- /** Optional parent container – if set, we query children instead of roots. */
119
- parentContainerId?: string;
120
- }
121
- declare const ContainerUploadPanel: React__default.FC<ContainerUploadPanelProps>;
122
-
123
- interface DesktopFileIconProps {
124
- name?: string | null;
125
- sizeBytes?: number | null;
126
- downloadUrl?: string | null;
127
- /** Double-click / open action */
128
- onOpen?: () => void;
129
- /** Delete action (can be async) */
130
- onDelete?: () => Promise<void> | void;
131
- }
132
- declare const DesktopFileIcon: React__default.FC<DesktopFileIconProps>;
133
-
134
- interface SingleFileProcessUploaderProps {
135
- /** Called to get a presigned S3 URL for the selected file. */
136
- getPresignedUrl: (file: File) => Promise<AWSPresignedUrlDTO>;
137
- /**
138
- * Called after the upload succeeds.
139
- * You can use s3Url (the presigned URL you provided) in another component
140
- * or have your backend process the file from S3.
141
- */
142
- onUploadComplete?: (file: File, s3Url: AWSPresignedUrlDTO) => void;
143
- /** Optional: restrict file types, e.g. "image/*" or ".png,.jpg" */
144
- accept?: string;
145
- /** Optional: label shown above the control */
146
- label?: string;
147
- /** Optional: disable the control entirely */
148
- disabled?: boolean;
149
- }
150
- declare const SingleFileProcessUploader: React__default.FC<SingleFileProcessUploaderProps>;
151
-
152
- interface UploadContainerProps {
153
- multiple?: boolean;
154
- accept?: string;
155
- onFilesSelected?: (files: FileList) => void;
156
- existingFiles?: ContainerDTO[];
157
- existingFilesLoading?: boolean;
158
- onExistingFileClick?: (file: ContainerDTO) => void;
159
- /** Called when user chooses "Delete file" from the context menu */
160
- onDeleteFile?: (file: ContainerDTO) => void;
161
- autoUpload?: boolean;
162
- getPresignedUrl?: (file: File) => Promise<AWSPresignedUrlDTO>;
163
- onUploadComplete?: (file: File, s3Url: string) => void;
164
- onUploadError?: (file: File, error: Error) => void;
165
- }
166
- declare const UploadContainer: React__default.FC<UploadContainerProps>;
167
-
168
- interface UploadDropzoneProps {
169
- isDragging: boolean;
170
- onDragOver?: (e: React__default.DragEvent<HTMLDivElement>) => void;
171
- onDragLeave?: (e: React__default.DragEvent<HTMLDivElement>) => void;
172
- onDrop?: (e: React__default.DragEvent<HTMLDivElement>) => void;
173
- /** Extra className so you can make this the root wrapper */
174
- className?: string;
175
- style?: React__default.CSSProperties;
176
- /** Custom content to render inside the dropzone */
177
- children?: React__default.ReactNode;
178
- }
179
- declare const UploadDropzone: React__default.FC<UploadDropzoneProps>;
180
-
181
- type UploadStatus = "pending" | "uploading" | "success" | "error";
182
- interface UploadState {
183
- id: string;
184
- file: File;
185
- progress: number;
186
- status: UploadStatus;
187
- error?: string;
188
- s3Url?: string;
189
- publicUrl?: string;
190
- }
191
-
192
- interface UploadProgressListProps {
193
- uploads: UploadState[];
194
- }
195
- declare const UploadProgressList: React__default.FC<UploadProgressListProps>;
196
-
197
- /**
198
- * Helper: upload a file to a pre-signed S3 URL with progress + retries.
199
- */
200
- declare function UploadFileToS3(file: File, presignedUrl: string, onProgress: (progress: number) => void, maxRetries?: number): Promise<void>;
201
-
202
- interface UseContainersOptions {
203
- apiBaseUrl: string;
204
- parentId?: string;
205
- }
206
- declare function UseContainers({ apiBaseUrl, parentId }: UseContainersOptions): {
207
- containers: ContainerDTO[];
208
- setContainers: React.Dispatch<React.SetStateAction<ContainerDTO[]>>;
209
- loading: boolean;
210
- error: Error | null;
211
- reload: () => Promise<void>;
212
- };
213
-
214
- interface UseUploadManagerOptions {
215
- autoUpload?: boolean;
216
- getPresignedUrl?: (file: File) => Promise<AWSPresignedUrlDTO>;
217
- onUploadComplete?: (file: File, s3Url: string) => void;
218
- onUploadError?: (file: File, error: Error) => void;
219
- }
220
- declare function UseUploadManager({ autoUpload, getPresignedUrl, onUploadComplete, onUploadError, }: UseUploadManagerOptions): {
221
- uploads: UploadState[];
222
- startUploadsIfNeeded: (files: FileList) => void;
223
- resetUploads: () => void;
224
- };
225
-
226
- declare function HomeView(): react_jsx_runtime.JSX.Element;
227
-
228
- export { AWSPresignedUrlDTO, Container, ContainerDTO, ContainerType, ContainerUploadPanel, DesktopFileIcon, type DesktopFileIconProps, Home, HomeView, type IAWSPresignedUrlDTO, type IContainerDTO, type ITemporaryFileDTO, S3, SingleFileProcessUploader, type SingleFileProcessUploaderProps, SparkStudioStorageSDK, TemporaryFileDTO, UploadContainer, type UploadContainerProps, UploadDropzone, UploadFileToS3, UploadProgressList, type UploadState, type UploadStatus, UseContainers, UseUploadManager };
package/dist/index.d.ts DELETED
@@ -1,228 +0,0 @@
1
- import * as React from 'react';
2
- import React__default from 'react';
3
- import * as react_jsx_runtime from 'react/jsx-runtime';
4
-
5
- declare enum ContainerType {
6
- File = 0,
7
- Folder = 1,
8
- Root = 2
9
- }
10
-
11
- /**
12
- * Represents an Auto-generated model for ContainerDTO.
13
- */
14
- interface IContainerDTO {
15
- Id: string;
16
- ContainerType: ContainerType;
17
- Name?: string;
18
- ContentType?: string;
19
- PublicUrl?: string;
20
- CreatedDate: string;
21
- FileSize: number;
22
- UserId: string;
23
- ParentContainerId: string;
24
- }
25
- type ContainerDTOInit = Partial<IContainerDTO> & Pick<IContainerDTO, "Id" | "ContainerType" | "CreatedDate" | "FileSize" | "UserId" | "ParentContainerId">;
26
- declare class ContainerDTO implements IContainerDTO {
27
- Id: string;
28
- ContainerType: ContainerType;
29
- Name?: string;
30
- ContentType?: string;
31
- PublicUrl?: string;
32
- CreatedDate: string;
33
- FileSize: number;
34
- UserId: string;
35
- ParentContainerId: string;
36
- constructor(init: ContainerDTOInit);
37
- }
38
-
39
- /**
40
- * Auto-generated client for the Container controller.
41
- */
42
- declare class Container {
43
- private baseUrl;
44
- constructor(baseUrl: string);
45
- ReadChildrenByContainerId(parentId: string): Promise<ContainerDTO[]>;
46
- ReadRootContainers(): Promise<ContainerDTO[]>;
47
- Read(id: string): Promise<ContainerDTO>;
48
- Create(containerDTO: ContainerDTO): Promise<ContainerDTO>;
49
- Update(containerDTO: ContainerDTO): Promise<ContainerDTO>;
50
- DeleteContainer(id: string): Promise<ContainerDTO>;
51
- CreateFileContainer(fileName: string, size: number, contentType: string): Promise<ContainerDTO>;
52
- }
53
-
54
- /**
55
- * Auto-generated client for the Home controller.
56
- */
57
- declare class Home {
58
- private baseUrl;
59
- constructor(baseUrl: string);
60
- }
61
-
62
- /**
63
- * Represents an Auto-generated model for AWSPresignedUrlDTO.
64
- */
65
- interface IAWSPresignedUrlDTO {
66
- PresignedUrl?: string;
67
- PublicUrl?: string;
68
- Key?: string;
69
- }
70
- type AWSPresignedUrlDTOInit = Partial<IAWSPresignedUrlDTO>;
71
- declare class AWSPresignedUrlDTO implements IAWSPresignedUrlDTO {
72
- PresignedUrl?: string;
73
- PublicUrl?: string;
74
- Key?: string;
75
- constructor(init: AWSPresignedUrlDTOInit);
76
- }
77
-
78
- /**
79
- * Represents an Auto-generated model for TemporaryFileDTO.
80
- */
81
- interface ITemporaryFileDTO {
82
- Name?: string;
83
- ContentType?: string;
84
- }
85
- type TemporaryFileDTOInit = Partial<ITemporaryFileDTO>;
86
- declare class TemporaryFileDTO implements ITemporaryFileDTO {
87
- Name?: string;
88
- ContentType?: string;
89
- constructor(init: TemporaryFileDTOInit);
90
- }
91
-
92
- /**
93
- * Auto-generated client for the S3 controller.
94
- */
95
- declare class S3 {
96
- private baseUrl;
97
- constructor(baseUrl: string);
98
- DeleteS3(containerDTO: ContainerDTO): Promise<ContainerDTO>;
99
- GetPreSignedUrl(containerDTO: ContainerDTO): Promise<AWSPresignedUrlDTO>;
100
- GetTemporaryPreSignedUrl(temporaryFileDTO: TemporaryFileDTO): Promise<AWSPresignedUrlDTO>;
101
- }
102
-
103
- /**
104
- * Auto-generated API client.
105
- */
106
- declare class SparkStudioStorageSDK {
107
- container: Container;
108
- home: Home;
109
- s3: S3;
110
- constructor(baseUrl: string);
111
- }
112
-
113
- interface ContainerUploadPanelProps {
114
- /** Base URL for the Container API (the SDK you pasted). */
115
- containerApiBaseUrl: string;
116
- /** Base URL for your storage / presign endpoint (used by getPresignedUrl). */
117
- storageApiBaseUrl: string;
118
- /** Optional parent container – if set, we query children instead of roots. */
119
- parentContainerId?: string;
120
- }
121
- declare const ContainerUploadPanel: React__default.FC<ContainerUploadPanelProps>;
122
-
123
- interface DesktopFileIconProps {
124
- name?: string | null;
125
- sizeBytes?: number | null;
126
- downloadUrl?: string | null;
127
- /** Double-click / open action */
128
- onOpen?: () => void;
129
- /** Delete action (can be async) */
130
- onDelete?: () => Promise<void> | void;
131
- }
132
- declare const DesktopFileIcon: React__default.FC<DesktopFileIconProps>;
133
-
134
- interface SingleFileProcessUploaderProps {
135
- /** Called to get a presigned S3 URL for the selected file. */
136
- getPresignedUrl: (file: File) => Promise<AWSPresignedUrlDTO>;
137
- /**
138
- * Called after the upload succeeds.
139
- * You can use s3Url (the presigned URL you provided) in another component
140
- * or have your backend process the file from S3.
141
- */
142
- onUploadComplete?: (file: File, s3Url: AWSPresignedUrlDTO) => void;
143
- /** Optional: restrict file types, e.g. "image/*" or ".png,.jpg" */
144
- accept?: string;
145
- /** Optional: label shown above the control */
146
- label?: string;
147
- /** Optional: disable the control entirely */
148
- disabled?: boolean;
149
- }
150
- declare const SingleFileProcessUploader: React__default.FC<SingleFileProcessUploaderProps>;
151
-
152
- interface UploadContainerProps {
153
- multiple?: boolean;
154
- accept?: string;
155
- onFilesSelected?: (files: FileList) => void;
156
- existingFiles?: ContainerDTO[];
157
- existingFilesLoading?: boolean;
158
- onExistingFileClick?: (file: ContainerDTO) => void;
159
- /** Called when user chooses "Delete file" from the context menu */
160
- onDeleteFile?: (file: ContainerDTO) => void;
161
- autoUpload?: boolean;
162
- getPresignedUrl?: (file: File) => Promise<AWSPresignedUrlDTO>;
163
- onUploadComplete?: (file: File, s3Url: string) => void;
164
- onUploadError?: (file: File, error: Error) => void;
165
- }
166
- declare const UploadContainer: React__default.FC<UploadContainerProps>;
167
-
168
- interface UploadDropzoneProps {
169
- isDragging: boolean;
170
- onDragOver?: (e: React__default.DragEvent<HTMLDivElement>) => void;
171
- onDragLeave?: (e: React__default.DragEvent<HTMLDivElement>) => void;
172
- onDrop?: (e: React__default.DragEvent<HTMLDivElement>) => void;
173
- /** Extra className so you can make this the root wrapper */
174
- className?: string;
175
- style?: React__default.CSSProperties;
176
- /** Custom content to render inside the dropzone */
177
- children?: React__default.ReactNode;
178
- }
179
- declare const UploadDropzone: React__default.FC<UploadDropzoneProps>;
180
-
181
- type UploadStatus = "pending" | "uploading" | "success" | "error";
182
- interface UploadState {
183
- id: string;
184
- file: File;
185
- progress: number;
186
- status: UploadStatus;
187
- error?: string;
188
- s3Url?: string;
189
- publicUrl?: string;
190
- }
191
-
192
- interface UploadProgressListProps {
193
- uploads: UploadState[];
194
- }
195
- declare const UploadProgressList: React__default.FC<UploadProgressListProps>;
196
-
197
- /**
198
- * Helper: upload a file to a pre-signed S3 URL with progress + retries.
199
- */
200
- declare function UploadFileToS3(file: File, presignedUrl: string, onProgress: (progress: number) => void, maxRetries?: number): Promise<void>;
201
-
202
- interface UseContainersOptions {
203
- apiBaseUrl: string;
204
- parentId?: string;
205
- }
206
- declare function UseContainers({ apiBaseUrl, parentId }: UseContainersOptions): {
207
- containers: ContainerDTO[];
208
- setContainers: React.Dispatch<React.SetStateAction<ContainerDTO[]>>;
209
- loading: boolean;
210
- error: Error | null;
211
- reload: () => Promise<void>;
212
- };
213
-
214
- interface UseUploadManagerOptions {
215
- autoUpload?: boolean;
216
- getPresignedUrl?: (file: File) => Promise<AWSPresignedUrlDTO>;
217
- onUploadComplete?: (file: File, s3Url: string) => void;
218
- onUploadError?: (file: File, error: Error) => void;
219
- }
220
- declare function UseUploadManager({ autoUpload, getPresignedUrl, onUploadComplete, onUploadError, }: UseUploadManagerOptions): {
221
- uploads: UploadState[];
222
- startUploadsIfNeeded: (files: FileList) => void;
223
- resetUploads: () => void;
224
- };
225
-
226
- declare function HomeView(): react_jsx_runtime.JSX.Element;
227
-
228
- export { AWSPresignedUrlDTO, Container, ContainerDTO, ContainerType, ContainerUploadPanel, DesktopFileIcon, type DesktopFileIconProps, Home, HomeView, type IAWSPresignedUrlDTO, type IContainerDTO, type ITemporaryFileDTO, S3, SingleFileProcessUploader, type SingleFileProcessUploaderProps, SparkStudioStorageSDK, TemporaryFileDTO, UploadContainer, type UploadContainerProps, UploadDropzone, UploadFileToS3, UploadProgressList, type UploadState, type UploadStatus, UseContainers, UseUploadManager };