@useupup/react 3.3.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +72 -0
  3. package/dist/AudioUploader-2WITC5YR.js +298 -0
  4. package/dist/AudioUploader-2WITC5YR.js.map +1 -0
  5. package/dist/AudioUploader-HWP4U6UJ.cjs +298 -0
  6. package/dist/AudioUploader-HWP4U6UJ.cjs.map +1 -0
  7. package/dist/BoxUploader-NEGZOMR4.cjs +172 -0
  8. package/dist/BoxUploader-NEGZOMR4.cjs.map +1 -0
  9. package/dist/BoxUploader-VE5LRJ7M.js +172 -0
  10. package/dist/BoxUploader-VE5LRJ7M.js.map +1 -0
  11. package/dist/CameraUploader-BJ3AU3VS.cjs +200 -0
  12. package/dist/CameraUploader-BJ3AU3VS.cjs.map +1 -0
  13. package/dist/CameraUploader-WF5A6UIS.js +200 -0
  14. package/dist/CameraUploader-WF5A6UIS.js.map +1 -0
  15. package/dist/DropboxUploader-INTOYHJP.cjs +174 -0
  16. package/dist/DropboxUploader-INTOYHJP.cjs.map +1 -0
  17. package/dist/DropboxUploader-VMUYG3OP.js +174 -0
  18. package/dist/DropboxUploader-VMUYG3OP.js.map +1 -0
  19. package/dist/GoogleDriveUploader-CXZUZI6R.cjs +177 -0
  20. package/dist/GoogleDriveUploader-CXZUZI6R.cjs.map +1 -0
  21. package/dist/GoogleDriveUploader-YA56X3QR.js +177 -0
  22. package/dist/GoogleDriveUploader-YA56X3QR.js.map +1 -0
  23. package/dist/ImageEditorInline-GJ3HCPPZ.cjs +185 -0
  24. package/dist/ImageEditorInline-GJ3HCPPZ.cjs.map +1 -0
  25. package/dist/ImageEditorInline-N2NSAODR.js +185 -0
  26. package/dist/ImageEditorInline-N2NSAODR.js.map +1 -0
  27. package/dist/ImageEditorModal-CWKMDVPY.js +236 -0
  28. package/dist/ImageEditorModal-CWKMDVPY.js.map +1 -0
  29. package/dist/ImageEditorModal-XJKPBTVQ.cjs +236 -0
  30. package/dist/ImageEditorModal-XJKPBTVQ.cjs.map +1 -0
  31. package/dist/OneDriveUploader-4RPTY7KT.cjs +175 -0
  32. package/dist/OneDriveUploader-4RPTY7KT.cjs.map +1 -0
  33. package/dist/OneDriveUploader-I25Y6AJP.js +175 -0
  34. package/dist/OneDriveUploader-I25Y6AJP.js.map +1 -0
  35. package/dist/ScreenCaptureUploader-7K6QPD42.cjs +281 -0
  36. package/dist/ScreenCaptureUploader-7K6QPD42.cjs.map +1 -0
  37. package/dist/ScreenCaptureUploader-WKDO4S75.js +281 -0
  38. package/dist/ScreenCaptureUploader-WKDO4S75.js.map +1 -0
  39. package/dist/chunk-6TFTTLOD.js +852 -0
  40. package/dist/chunk-6TFTTLOD.js.map +1 -0
  41. package/dist/chunk-DZQBTC6T.cjs +39 -0
  42. package/dist/chunk-DZQBTC6T.cjs.map +1 -0
  43. package/dist/chunk-GNMEQB32.cjs +195 -0
  44. package/dist/chunk-GNMEQB32.cjs.map +1 -0
  45. package/dist/chunk-IG62MHVQ.cjs +276 -0
  46. package/dist/chunk-IG62MHVQ.cjs.map +1 -0
  47. package/dist/chunk-L3E5OMY7.cjs +852 -0
  48. package/dist/chunk-L3E5OMY7.cjs.map +1 -0
  49. package/dist/chunk-LCMDDPUD.js +276 -0
  50. package/dist/chunk-LCMDDPUD.js.map +1 -0
  51. package/dist/chunk-N4XGN66E.cjs +79 -0
  52. package/dist/chunk-N4XGN66E.cjs.map +1 -0
  53. package/dist/chunk-N7TWHP5Z.js +195 -0
  54. package/dist/chunk-N7TWHP5Z.js.map +1 -0
  55. package/dist/chunk-OXWVO7Z6.cjs +70 -0
  56. package/dist/chunk-OXWVO7Z6.cjs.map +1 -0
  57. package/dist/chunk-PLGHK2Y4.js +79 -0
  58. package/dist/chunk-PLGHK2Y4.js.map +1 -0
  59. package/dist/chunk-SSLP3MEC.js +39 -0
  60. package/dist/chunk-SSLP3MEC.js.map +1 -0
  61. package/dist/chunk-WYMKISZI.js +70 -0
  62. package/dist/chunk-WYMKISZI.js.map +1 -0
  63. package/dist/index.cjs +4219 -0
  64. package/dist/index.cjs.map +1 -0
  65. package/dist/index.d.cts +240 -0
  66. package/dist/index.d.ts +240 -0
  67. package/dist/index.js +4219 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/styles.d.ts +4 -0
  70. package/dist/tailwind-prefixed.css +2529 -0
  71. package/package.json +110 -0
@@ -0,0 +1,852 @@
1
+ import {
2
+ Icon_default,
3
+ SourceViewHeaderExtraContext,
4
+ searchDriveFiles
5
+ } from "./chunk-PLGHK2Y4.js";
6
+ import {
7
+ SourceViewContainer
8
+ } from "./chunk-SSLP3MEC.js";
9
+ import {
10
+ useUploaderI18n,
11
+ useUploaderOptions,
12
+ useUploaderRuntime,
13
+ useUploaderSource,
14
+ useUploaderTheme
15
+ } from "./chunk-LCMDDPUD.js";
16
+
17
+ // src/components/shared/DriveAuthFallback.tsx
18
+ import { useEffect, useRef } from "react";
19
+ import { formatUiMessage as t } from "@useupup/core";
20
+ import { cn } from "@useupup/core/internal";
21
+ import { jsx, jsxs } from "react/jsx-runtime";
22
+ function DriveAuthFallback({
23
+ providerName,
24
+ onRetry,
25
+ error,
26
+ "data-upup-slot": dataUpupSlot = "drive-auth-fallback"
27
+ }) {
28
+ const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme();
29
+ const { translations: tr } = useUploaderI18n();
30
+ const attemptedRef = useRef(false);
31
+ useEffect(() => {
32
+ if (attemptedRef.current || error) return;
33
+ attemptedRef.current = true;
34
+ onRetry();
35
+ }, [error, onRetry]);
36
+ return /* @__PURE__ */ jsx(SourceViewContainer, { "data-upup-slot": dataUpupSlot, children: /* @__PURE__ */ jsxs("div", { className: "upup-flex upup-h-full upup-w-full upup-flex-col upup-items-center upup-justify-center upup-gap-4 upup-p-6 upup-text-center", children: [
37
+ !!error && /* @__PURE__ */ jsx(
38
+ "p",
39
+ {
40
+ "data-testid": "upup-drive-error",
41
+ "data-upup-slot": "drive-error",
42
+ role: "alert",
43
+ className: "upup-p-4 upup-text-sm upup-text-red-600 dark:upup-text-red-400",
44
+ children: t(tr.driveLoadError, { message: error.message })
45
+ }
46
+ ),
47
+ /* @__PURE__ */ jsx(
48
+ "p",
49
+ {
50
+ className: cn(
51
+ "upup-text-sm upup-text-[#333]",
52
+ {
53
+ "upup-text-[#FAFAFA] dark:upup-text-[#FAFAFA]": dark
54
+ },
55
+ slotClasses.sourceView
56
+ ),
57
+ children: t(tr.authenticatePrompt, { provider: providerName })
58
+ }
59
+ ),
60
+ /* @__PURE__ */ jsx(
61
+ "button",
62
+ {
63
+ type: "button",
64
+ className: cn(
65
+ "upup-rounded-md upup-bg-[#0ea5e9] upup-px-4 upup-py-2 upup-text-sm upup-font-medium upup-text-white upup-transition-all upup-duration-300 hover:upup-bg-[#0284c7]",
66
+ {
67
+ "upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8] dark:hover:upup-bg-[#0ea5e9]": dark
68
+ }
69
+ ),
70
+ onClick: onRetry,
71
+ children: t(tr.signInWith, { provider: providerName })
72
+ }
73
+ )
74
+ ] }) });
75
+ }
76
+
77
+ // src/components/shared/DriveBrowser.tsx
78
+ import { useMemo, useState as useState2 } from "react";
79
+ import {
80
+ formatUiMessage as t2,
81
+ pluralUiMessage as plural
82
+ } from "@useupup/core";
83
+ import { cn as cn5 } from "@useupup/core/internal";
84
+
85
+ // src/components/shared/DriveBrowserHeader.tsx
86
+ import {
87
+ useContext,
88
+ useEffect as useEffect2,
89
+ useRef as useRef2,
90
+ useState
91
+ } from "react";
92
+ import { createPortal } from "react-dom";
93
+ import { cn as cn2 } from "@useupup/core/internal";
94
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
95
+ function DriveBrowserHeader({
96
+ path,
97
+ setPath,
98
+ user,
99
+ handleSignOut,
100
+ showSearch,
101
+ onSearch,
102
+ searchTerm
103
+ }) {
104
+ const { setActiveSource } = useUploaderSource();
105
+ const { translations: tr } = useUploaderI18n();
106
+ const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme();
107
+ const headerExtraHost = useContext(SourceViewHeaderExtraContext);
108
+ const [searchOpen, setSearchOpen] = useState(false);
109
+ const searchInputRef = useRef2(null);
110
+ useEffect2(() => {
111
+ var _a;
112
+ if (searchOpen) (_a = searchInputRef.current) == null ? void 0 : _a.focus();
113
+ }, [searchOpen]);
114
+ if (!user) return null;
115
+ const navigated = path.length > 1;
116
+ const currentFolder = path[path.length - 1];
117
+ const hasFilter = searchTerm.trim().length > 0;
118
+ const searchField = (expand) => /* @__PURE__ */ jsxs2(
119
+ "div",
120
+ {
121
+ className: cn2(
122
+ "upup-relative upup-min-w-0 upup-flex-1",
123
+ expand && "upup-fx-search-expand",
124
+ slotClasses.driveSearchContainer
125
+ ),
126
+ children: [
127
+ /* @__PURE__ */ jsx2(
128
+ "input",
129
+ {
130
+ ref: searchInputRef,
131
+ type: "search",
132
+ name: "upup-drive-search",
133
+ "data-testid": "upup-drive-search-input",
134
+ "data-upup-slot": "drive-search-input",
135
+ "aria-label": tr.search,
136
+ className: cn2(
137
+ "upup-w-full upup-rounded-lg upup-px-3 upup-py-1.5 upup-pl-8 upup-text-xs upup-outline-none upup-ring-1 upup-transition-shadow focus:upup-ring-2 focus:upup-ring-[#38bdf8]",
138
+ dark ? "upup-bg-white/[0.06] upup-text-[#e2e8f0] upup-ring-white/[0.1] placeholder:upup-text-[#64748b]" : "upup-bg-white upup-text-[#0f172a] upup-ring-black/[0.08] placeholder:upup-text-[#94a3b8]",
139
+ slotClasses.driveSearchInput
140
+ ),
141
+ placeholder: tr.search,
142
+ value: searchTerm,
143
+ onChange: (e) => {
144
+ onSearch(e.currentTarget.value);
145
+ },
146
+ onKeyDown: (e) => {
147
+ if (e.key === "Escape") setSearchOpen(false);
148
+ },
149
+ onBlur: () => {
150
+ if (!searchTerm) setSearchOpen(false);
151
+ }
152
+ }
153
+ ),
154
+ /* @__PURE__ */ jsx2(
155
+ Icon_default,
156
+ {
157
+ name: "search",
158
+ className: "upup-absolute upup-left-2.5 upup-top-1/2 upup--translate-y-1/2 upup-text-[#939393]"
159
+ }
160
+ )
161
+ ]
162
+ }
163
+ );
164
+ return /* @__PURE__ */ jsxs2("div", { "data-upup-slot": "drive-browser-header", children: [
165
+ !!headerExtraHost && createPortal(
166
+ /* @__PURE__ */ jsxs2(Fragment, { children: [
167
+ /* @__PURE__ */ jsxs2("div", { className: "upup-relative upup-flex upup-h-6 upup-w-6 upup-items-center upup-justify-center upup-overflow-hidden upup-rounded-full", children: [
168
+ !!user.picture && /* @__PURE__ */ jsx2(
169
+ "img",
170
+ {
171
+ alt: user.name,
172
+ src: user.picture,
173
+ className: "upup-bg-center upup-object-cover"
174
+ }
175
+ ),
176
+ !user.picture && /* @__PURE__ */ jsx2(Icon_default, { name: "user", className: "upup-text-xl" })
177
+ ] }),
178
+ /* @__PURE__ */ jsx2(
179
+ "button",
180
+ {
181
+ className: cn2(
182
+ "upup-hover:upup-underline upup-text-xs upup-font-medium upup-text-[#0284c7]",
183
+ {
184
+ "upup-text-[#38bdf8] dark:upup-text-[#38bdf8]": dark
185
+ },
186
+ slotClasses.driveLogoutButton
187
+ ),
188
+ onClick: () => {
189
+ void handleSignOut();
190
+ setActiveSource(void 0);
191
+ },
192
+ children: tr.logOut
193
+ }
194
+ ),
195
+ /* @__PURE__ */ jsx2(
196
+ "span",
197
+ {
198
+ "aria-hidden": "true",
199
+ className: cn2(
200
+ "upup-h-4 upup-w-px",
201
+ dark ? "upup-bg-white/15" : "upup-bg-black/15"
202
+ )
203
+ }
204
+ )
205
+ ] }),
206
+ headerExtraHost
207
+ ),
208
+ (navigated || showSearch) && /* @__PURE__ */ jsx2(
209
+ "div",
210
+ {
211
+ className: cn2(
212
+ "upup-flex upup-items-center upup-gap-2.5 upup-px-3 upup-py-2 upup-text-xs upup-font-medium upup-text-[#333]",
213
+ {
214
+ "upup-text-[#FAFAFA] dark:upup-text-[#FAFAFA]": dark
215
+ },
216
+ slotClasses.driveHeader
217
+ ),
218
+ children: navigated ? /* @__PURE__ */ jsxs2(Fragment, { children: [
219
+ /* @__PURE__ */ jsx2(
220
+ "button",
221
+ {
222
+ type: "button",
223
+ "data-testid": "upup-drive-back",
224
+ "data-upup-slot": "drive-back",
225
+ "aria-label": tr.overlayBack,
226
+ onClick: () => {
227
+ setPath((prev) => prev.slice(0, -1));
228
+ },
229
+ className: cn2(
230
+ "upup-fx-hover-lift upup-fx-press upup-flex upup-h-7 upup-w-7 upup-shrink-0 upup-items-center upup-justify-center upup-rounded-lg",
231
+ dark ? "upup-text-[#e2e8f0] hover:upup-bg-white/[0.08]" : "upup-text-[#334155] hover:upup-bg-black/[0.05]"
232
+ ),
233
+ children: /* @__PURE__ */ jsx2(Icon_default, { name: "chevron-left" })
234
+ }
235
+ ),
236
+ !searchOpen && /* @__PURE__ */ jsx2(
237
+ "span",
238
+ {
239
+ "data-upup-slot": "drive-current-folder",
240
+ title: currentFolder == null ? void 0 : currentFolder.name,
241
+ className: "upup-min-w-0 upup-flex-1 upup-truncate upup-font-medium",
242
+ children: currentFolder == null ? void 0 : currentFolder.name
243
+ }
244
+ ),
245
+ showSearch && !searchOpen && /* @__PURE__ */ jsx2(
246
+ "button",
247
+ {
248
+ type: "button",
249
+ "data-testid": "upup-drive-search-toggle",
250
+ "data-upup-slot": "drive-search-toggle",
251
+ "aria-label": tr.search,
252
+ "aria-expanded": false,
253
+ onClick: () => {
254
+ setSearchOpen(true);
255
+ },
256
+ className: cn2(
257
+ "upup-fx-hover-lift upup-fx-press upup-ml-auto upup-flex upup-h-7 upup-w-7 upup-shrink-0 upup-items-center upup-justify-center upup-rounded-lg",
258
+ hasFilter ? "upup-text-[#0ea5e9]" : dark ? "upup-text-[#94a3b8] hover:upup-bg-white/[0.08]" : "upup-text-[#64748b] hover:upup-bg-black/[0.05]"
259
+ ),
260
+ children: /* @__PURE__ */ jsx2(Icon_default, { name: "search" })
261
+ }
262
+ ),
263
+ showSearch && searchOpen && searchField(true)
264
+ ] }) : showSearch && searchField(false)
265
+ }
266
+ )
267
+ ] });
268
+ }
269
+
270
+ // src/components/shared/DriveBrowserItem.tsx
271
+ import { cn as cn4 } from "@useupup/core/internal";
272
+
273
+ // src/components/shared/DriveBrowserIcon.tsx
274
+ import { b64EncodeUnicode, cn as cn3 } from "@useupup/core/internal";
275
+ import { jsx as jsx3 } from "react/jsx-runtime";
276
+ var handleImgError = (e) => {
277
+ const svg = `<svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M14 3v4a1 1 0 0 0 1 1h4"></path><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z"></path></svg>`;
278
+ e.currentTarget.src = `data:image/svg+xml;base64,${b64EncodeUnicode(svg)}`;
279
+ e.currentTarget.onerror = null;
280
+ };
281
+ function DriveBrowserIcon({
282
+ file
283
+ }) {
284
+ const { isDark: dark } = useUploaderTheme();
285
+ const isFolder = file.isFolder;
286
+ const src = file.thumbnail;
287
+ if (isFolder)
288
+ return /* @__PURE__ */ jsx3("i", { className: "upup-flex-grow upup-text-lg", children: /* @__PURE__ */ jsx3(Icon_default, { name: "folder-filled", className: "upup-text-[#fbbf24]" }) });
289
+ if (!src)
290
+ return /* @__PURE__ */ jsx3("i", { className: "upup-flex-grow upup-text-lg", children: /* @__PURE__ */ jsx3(
291
+ Icon_default,
292
+ {
293
+ name: "file",
294
+ className: cn3({
295
+ "upup-text-[#6D6D6D] dark:upup-text-[#6D6D6D]": dark
296
+ })
297
+ }
298
+ ) });
299
+ return /* @__PURE__ */ jsx3(
300
+ "img",
301
+ {
302
+ src,
303
+ alt: file.name,
304
+ className: "upup-h-5 upup-w-5 upup-flex-grow upup-rounded-md upup-shadow",
305
+ onError: handleImgError
306
+ }
307
+ );
308
+ }
309
+
310
+ // src/components/shared/DriveBrowserItem.tsx
311
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
312
+ function DriveBrowserItem({
313
+ file,
314
+ selectedFiles,
315
+ handleClick
316
+ }) {
317
+ var _a, _b;
318
+ const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme();
319
+ const isFolder = file.isFolder;
320
+ const isFileSelected = selectedFiles.filter((f) => f.id === file.id).length;
321
+ return /* @__PURE__ */ jsx4(
322
+ "div",
323
+ {
324
+ "data-upup-slot": "drive-browser-item",
325
+ className: cn4(
326
+ // Panel-chrome row (states-tour-3 .st3-prow): translucent card +
327
+ // hairline ring, sky-tinted selection, subtle lift on hover.
328
+ "upup-fx-hover-lift upup-group upup-mb-1.5 upup-flex upup-cursor-pointer upup-items-center upup-justify-between upup-gap-2 upup-rounded-[11px] upup-px-3 upup-py-2.5 upup-ring-1",
329
+ {
330
+ "upup-font-medium": isFolder
331
+ },
332
+ isFileSelected ? dark ? "upup-bg-[#0ea5e9]/10 upup-ring-[#38bdf8]/35" : "upup-bg-[#0ea5e9]/10 upup-ring-[#0ea5e9]/40" : dark ? "upup-bg-white/[0.04] upup-ring-white/[0.06] hover:upup-bg-white/[0.07]" : "upup-bg-white upup-ring-black/[0.07] hover:upup-bg-slate-50",
333
+ {
334
+ [(_a = slotClasses.driveItemContainerDefault) != null ? _a : ""]: !isFileSelected && slotClasses.driveItemContainerDefault,
335
+ [(_b = slotClasses.driveItemContainerSelected) != null ? _b : ""]: isFileSelected && slotClasses.driveItemContainerSelected
336
+ }
337
+ ),
338
+ onClick: () => {
339
+ void handleClick(file);
340
+ },
341
+ children: /* @__PURE__ */ jsxs3(
342
+ "div",
343
+ {
344
+ className: cn4(
345
+ "upup-flex upup-items-center upup-gap-2",
346
+ slotClasses.driveItemContainerInner
347
+ ),
348
+ children: [
349
+ /* @__PURE__ */ jsx4(DriveBrowserIcon, { file }),
350
+ /* @__PURE__ */ jsx4(
351
+ "h1",
352
+ {
353
+ className: cn4(
354
+ "upup-text-wrap upup-break-all upup-text-xs",
355
+ {
356
+ "upup-text-[#e0e0e0] dark:upup-text-[#e0e0e0]": dark
357
+ },
358
+ slotClasses.driveItemInnerText
359
+ ),
360
+ children: file.name
361
+ }
362
+ )
363
+ ]
364
+ }
365
+ )
366
+ }
367
+ );
368
+ }
369
+
370
+ // src/components/shared/DriveBrowser.tsx
371
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
372
+ function filterItems(item, accept) {
373
+ if (item.isFolder) return true;
374
+ if (!accept || accept === "*") return true;
375
+ return accept.split(",").some((pattern) => {
376
+ const p = pattern.trim();
377
+ if (p.startsWith(".")) return item.name.endsWith(p);
378
+ if (p.endsWith("/*"))
379
+ return item.mimeType.startsWith(p.replace("/*", "/"));
380
+ return item.mimeType === p;
381
+ });
382
+ }
383
+ function DriveBrowser({
384
+ isClickLoading = false,
385
+ driveFiles,
386
+ path,
387
+ setPath,
388
+ handleClick,
389
+ selectedFiles,
390
+ showLoader,
391
+ handleSubmit,
392
+ handleCancelDownload,
393
+ onSelectCurrentFolder,
394
+ error,
395
+ hasMore = false,
396
+ isLoadingMore = false,
397
+ loadMore,
398
+ "data-upup-slot": dataUpupSlot = "drive-browser",
399
+ ...rest
400
+ }) {
401
+ var _a, _b;
402
+ const {
403
+ allowedFileTypes,
404
+ icons: { LoaderIcon }
405
+ } = useUploaderOptions();
406
+ const { isDark: dark, slotOverrides: slotClasses } = useUploaderTheme();
407
+ const { translations: tr } = useUploaderI18n();
408
+ const [searchTerm, setSearchTerm] = useState2("");
409
+ const items = (_b = (_a = path[path.length - 1]) == null ? void 0 : _a.children) == null ? void 0 : _b.filter(
410
+ (item) => filterItems(item, allowedFileTypes)
411
+ );
412
+ const displayedItems = useMemo(
413
+ () => searchDriveFiles(items != null ? items : [], searchTerm) || [],
414
+ [searchTerm, items]
415
+ );
416
+ const isLoading = !error && (isClickLoading || !driveFiles);
417
+ return /* @__PURE__ */ jsx5(
418
+ SourceViewContainer,
419
+ {
420
+ isLoading,
421
+ "data-upup-slot": dataUpupSlot,
422
+ children: isLoading ? /* @__PURE__ */ jsx5(LoaderIcon, {}) : /* @__PURE__ */ jsxs4(
423
+ "div",
424
+ {
425
+ "data-testid": "upup-drive-browser",
426
+ className: "upup-grid upup-h-full upup-w-full upup-grid-rows-[auto,1fr,auto] upup-overflow-auto",
427
+ children: [
428
+ /* @__PURE__ */ jsx5(
429
+ DriveBrowserHeader,
430
+ {
431
+ showSearch: !!(items == null ? void 0 : items.length),
432
+ path,
433
+ setPath,
434
+ searchTerm,
435
+ onSearch: setSearchTerm,
436
+ ...rest
437
+ }
438
+ ),
439
+ !!path && /* @__PURE__ */ jsxs4(
440
+ "div",
441
+ {
442
+ className: cn5(
443
+ "upup-h-full upup-overflow-y-auto upup-pt-2",
444
+ {
445
+ "upup-text-[#fafafa] dark:upup-text-[#fafafa]": dark
446
+ },
447
+ slotClasses.driveBody
448
+ ),
449
+ children: [
450
+ !!error && /* @__PURE__ */ jsx5("div", { className: "upup-flex upup-h-full upup-flex-col upup-items-center upup-justify-center upup-px-6 upup-text-center", children: /* @__PURE__ */ jsx5(
451
+ "p",
452
+ {
453
+ "data-testid": "upup-drive-error",
454
+ "data-upup-slot": "drive-error",
455
+ role: "alert",
456
+ className: "upup-text-sm upup-text-red-600 dark:upup-text-red-400",
457
+ children: t2(tr.driveLoadError, {
458
+ message: error.message
459
+ })
460
+ }
461
+ ) }),
462
+ !!displayedItems.length && /* @__PURE__ */ jsx5("ul", { className: "upup-p-2", children: displayedItems.map((file) => {
463
+ return /* @__PURE__ */ jsx5(
464
+ DriveBrowserItem,
465
+ {
466
+ file,
467
+ handleClick: isClickLoading || showLoader ? () => {
468
+ } : handleClick,
469
+ selectedFiles
470
+ },
471
+ file.id
472
+ );
473
+ }) }),
474
+ !displayedItems.length && !error && /* @__PURE__ */ jsx5("div", { className: "upup-flex upup-h-full upup-flex-col upup-items-center upup-justify-center", children: /* @__PURE__ */ jsx5("p", { className: "upup-text-xs upup-opacity-70", children: tr.noAcceptedFilesFound }) }),
475
+ hasMore && /* @__PURE__ */ jsx5(
476
+ "button",
477
+ {
478
+ "data-testid": "upup-drive-load-more",
479
+ "data-upup-slot": "drive-load-more",
480
+ onClick: () => {
481
+ void (loadMore == null ? void 0 : loadMore());
482
+ },
483
+ disabled: isLoadingMore,
484
+ className: "upup-mx-auto upup-my-2 upup-block upup-rounded-md upup-px-3 upup-py-1.5 upup-text-sm upup-text-[#0284c7] disabled:upup-opacity-50",
485
+ children: isLoadingMore ? tr.loading : tr.loadMore
486
+ }
487
+ )
488
+ ]
489
+ }
490
+ ),
491
+ (!!selectedFiles.length || !!onSelectCurrentFolder) && !error && /* @__PURE__ */ jsxs4(
492
+ "div",
493
+ {
494
+ className: cn5(
495
+ "upup-flex upup-origin-bottom upup-items-center upup-justify-start upup-gap-4 upup-border-t upup-px-3 upup-py-2",
496
+ dark ? "upup-border-white/[0.08] upup-text-[#fafafa]" : "upup-border-black/[0.06]",
497
+ slotClasses.driveFooter
498
+ ),
499
+ children: [
500
+ !!onSelectCurrentFolder && /* @__PURE__ */ jsx5(
501
+ "button",
502
+ {
503
+ className: cn5(
504
+ "upup-rounded-md upup-bg-transparent upup-px-3 upup-py-2 upup-text-sm upup-font-medium upup-text-[#0284c7] upup-transition-all upup-duration-300",
505
+ {
506
+ "upup-text-[#38bdf8] dark:upup-text-[#38bdf8]": dark
507
+ }
508
+ ),
509
+ onClick: () => {
510
+ void (onSelectCurrentFolder == null ? void 0 : onSelectCurrentFolder());
511
+ },
512
+ disabled: showLoader,
513
+ children: tr.selectThisFolder
514
+ }
515
+ ),
516
+ /* @__PURE__ */ jsx5(
517
+ "button",
518
+ {
519
+ className: cn5(
520
+ "upup-rounded-md upup-bg-[#0ea5e9] upup-px-3 upup-py-2 upup-text-sm upup-font-medium upup-text-white upup-transition-all upup-duration-300",
521
+ {
522
+ "upup-animate-pulse": showLoader,
523
+ "upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]": dark
524
+ },
525
+ slotClasses.driveAddFilesButton
526
+ ),
527
+ onClick: () => {
528
+ void handleSubmit();
529
+ },
530
+ disabled: showLoader,
531
+ children: t2(
532
+ plural(
533
+ tr,
534
+ "addFiles",
535
+ selectedFiles.length
536
+ ),
537
+ { count: selectedFiles.length }
538
+ )
539
+ }
540
+ ),
541
+ /* @__PURE__ */ jsx5(
542
+ "button",
543
+ {
544
+ className: cn5(
545
+ "upup-ml-auto upup-rounded-md upup-p-1 upup-text-sm upup-text-[#0284c7] upup-transition-all upup-duration-300",
546
+ {
547
+ "upup-text-[#38bdf8] dark:upup-text-[#38bdf8]": dark
548
+ },
549
+ slotClasses.driveCancelFilesButton
550
+ ),
551
+ onClick: handleCancelDownload,
552
+ disabled: showLoader,
553
+ children: tr.cancel
554
+ }
555
+ )
556
+ ]
557
+ }
558
+ )
559
+ ]
560
+ }
561
+ )
562
+ }
563
+ );
564
+ }
565
+
566
+ // src/components/ServerModeDriveUploader.tsx
567
+ import { useState as useState3 } from "react";
568
+
569
+ // src/hooks/useServerModeDrive.ts
570
+ import { useEffect as useEffect3, useRef as useRef3, useSyncExternalStore } from "react";
571
+ import { ServerModeDriveController } from "@useupup/core/internal";
572
+ function useServerModeDrive(provider) {
573
+ const { serverUrl } = useUploaderRuntime();
574
+ const latest = useRef3({ serverUrl });
575
+ latest.current = { serverUrl };
576
+ const controllerRef = useRef3(
577
+ void 0
578
+ );
579
+ if (!controllerRef.current) {
580
+ controllerRef.current = new ServerModeDriveController({
581
+ provider,
582
+ serverUrl: () => latest.current.serverUrl
583
+ });
584
+ }
585
+ const controller = controllerRef.current;
586
+ const snap = useSyncExternalStore(
587
+ controller.subscribe,
588
+ controller.getSnapshot
589
+ );
590
+ useEffect3(() => {
591
+ controller.init();
592
+ return () => {
593
+ controller.destroy();
594
+ };
595
+ }, [controller]);
596
+ return {
597
+ state: snap.state,
598
+ folderId: snap.folderId,
599
+ setFolderId: (id) => {
600
+ controller.setFolderId(id);
601
+ void controller.refresh();
602
+ },
603
+ search: snap.search,
604
+ setSearch: (s) => {
605
+ controller.setSearch(s);
606
+ void controller.refresh();
607
+ },
608
+ refresh: (opts) => controller.refresh(opts),
609
+ transfer: (file) => controller.transfer(file),
610
+ startAuth: () => {
611
+ controller.startAuth();
612
+ }
613
+ };
614
+ }
615
+
616
+ // src/components/ServerModeDriveUploader.tsx
617
+ import { errorCodeToMessageKey } from "@useupup/core";
618
+ import { cn as cn6 } from "@useupup/core/internal";
619
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
620
+ var PROVIDER_LABEL = {
621
+ "google-drive": "Google Drive",
622
+ "one-drive": "OneDrive",
623
+ dropbox: "Dropbox",
624
+ box: "Box"
625
+ };
626
+ function ServerModeDriveUploader({
627
+ provider,
628
+ onBack,
629
+ "data-upup-slot": dataUpupSlot = `drive-browser-${provider}`
630
+ }) {
631
+ const { isDark: dark } = useUploaderTheme();
632
+ const {
633
+ icons: { LoaderIcon }
634
+ } = useUploaderOptions();
635
+ const { translator } = useUploaderI18n();
636
+ const { state, search, setSearch, refresh, transfer, startAuth } = useServerModeDrive(provider);
637
+ const [selected, setSelected] = useState3(/* @__PURE__ */ new Set());
638
+ const [transferring, setTransferring] = useState3(false);
639
+ if (state.status === "reauth") {
640
+ return /* @__PURE__ */ jsx6(
641
+ DriveAuthFallback,
642
+ {
643
+ providerName: PROVIDER_LABEL[provider],
644
+ onRetry: startAuth
645
+ }
646
+ );
647
+ }
648
+ const isLoading = state.status === "loading" || state.status === "idle";
649
+ const files = state.status === "ready" ? state.files : [];
650
+ const toggle = (id) => {
651
+ setSelected((prev) => {
652
+ const next = new Set(prev);
653
+ if (next.has(id)) next.delete(id);
654
+ else next.add(id);
655
+ return next;
656
+ });
657
+ };
658
+ const handleTransfer = async () => {
659
+ setTransferring(true);
660
+ try {
661
+ for (const file of files.filter((f) => selected.has(f.id))) {
662
+ const result = await transfer(file);
663
+ if (result.status === "reauth") {
664
+ startAuth();
665
+ return;
666
+ }
667
+ }
668
+ setSelected(/* @__PURE__ */ new Set());
669
+ onBack == null ? void 0 : onBack();
670
+ } finally {
671
+ setTransferring(false);
672
+ }
673
+ };
674
+ return /* @__PURE__ */ jsx6(
675
+ SourceViewContainer,
676
+ {
677
+ isLoading,
678
+ "data-upup-slot": dataUpupSlot,
679
+ children: isLoading ? /* @__PURE__ */ jsx6(LoaderIcon, {}) : /* @__PURE__ */ jsxs5(
680
+ "div",
681
+ {
682
+ "data-testid": "upup-server-drive-browser",
683
+ className: "upup-grid upup-h-full upup-w-full upup-grid-rows-[auto,1fr,auto] upup-overflow-auto",
684
+ children: [
685
+ /* @__PURE__ */ jsxs5(
686
+ "div",
687
+ {
688
+ className: cn6(
689
+ "upup-flex upup-items-center upup-gap-2 upup-border-b upup-px-3 upup-py-2.5",
690
+ dark ? "upup-border-white/[0.06] upup-text-[#e2e8f0]" : "upup-border-black/[0.06] upup-text-gray-800"
691
+ ),
692
+ "data-upup-slot": "drive-browser-header",
693
+ children: [
694
+ /* @__PURE__ */ jsx6("span", { className: "upup-text-sm upup-font-medium", children: PROVIDER_LABEL[provider] }),
695
+ /* @__PURE__ */ jsx6(
696
+ "input",
697
+ {
698
+ type: "search",
699
+ name: "upup-drive-search",
700
+ "aria-label": "Search",
701
+ value: search,
702
+ onChange: (e) => {
703
+ setSearch(e.target.value);
704
+ },
705
+ onKeyDown: (e) => {
706
+ if (e.key === "Enter") {
707
+ void refresh({
708
+ search: e.currentTarget.value
709
+ });
710
+ }
711
+ },
712
+ placeholder: "Search\u2026",
713
+ className: cn6(
714
+ "upup-ml-auto upup-rounded upup-border upup-px-2 upup-py-1 upup-text-xs",
715
+ dark ? "upup-border-gray-700 upup-bg-gray-800 upup-text-gray-100" : "upup-border-gray-300 upup-bg-white"
716
+ )
717
+ }
718
+ )
719
+ ]
720
+ }
721
+ ),
722
+ /* @__PURE__ */ jsxs5("div", { className: "upup-overflow-auto upup-p-2", children: [
723
+ state.status === "error" && /* @__PURE__ */ jsx6(
724
+ "p",
725
+ {
726
+ "data-testid": "upup-drive-error",
727
+ "data-upup-slot": "drive-error",
728
+ role: "alert",
729
+ className: cn6(
730
+ "upup-p-4 upup-text-sm",
731
+ dark ? "upup-text-red-400" : "upup-text-red-600"
732
+ ),
733
+ children: state.code && translator ? translator(
734
+ `errors.${errorCodeToMessageKey(state.code)}`,
735
+ { code: state.code }
736
+ ) : state.message
737
+ }
738
+ ),
739
+ files.map((file) => {
740
+ const isSelected = selected.has(file.id);
741
+ return /* @__PURE__ */ jsxs5(
742
+ "button",
743
+ {
744
+ type: "button",
745
+ onClick: () => {
746
+ file.isFolder ? void refresh({
747
+ folderId: file.id
748
+ }) : toggle(file.id);
749
+ },
750
+ "data-upup-slot": "drive-browser-item",
751
+ "data-selected": isSelected,
752
+ className: cn6(
753
+ // Panel-chrome row (states-tour-3 .st3-prow).
754
+ "upup-fx-hover-lift upup-mb-1.5 upup-flex upup-w-full upup-items-center upup-gap-3 upup-rounded-[11px] upup-px-3 upup-py-2.5 upup-text-left upup-text-sm upup-ring-1",
755
+ isSelected ? "upup-bg-[#0ea5e9]/10 upup-ring-[#38bdf8]/35" : dark ? "upup-bg-white/[0.04] upup-text-[#e2e8f0] upup-ring-white/[0.06] hover:upup-bg-white/[0.07]" : "upup-bg-black/[0.03] upup-text-gray-800 upup-ring-black/[0.06] hover:upup-bg-black/[0.05]"
756
+ ),
757
+ children: [
758
+ /* @__PURE__ */ jsx6(
759
+ "span",
760
+ {
761
+ className: "upup-flex upup-h-[30px] upup-w-[30px] upup-flex-none upup-items-center upup-justify-center upup-rounded-[8px] upup-bg-white/[0.05]",
762
+ "aria-hidden": "true",
763
+ children: file.isFolder ? /* @__PURE__ */ jsx6(
764
+ "svg",
765
+ {
766
+ viewBox: "0 0 24 24",
767
+ width: "17",
768
+ height: "17",
769
+ fill: "none",
770
+ stroke: "#38bdf8",
771
+ strokeWidth: "1.7",
772
+ strokeLinecap: "round",
773
+ strokeLinejoin: "round",
774
+ children: /* @__PURE__ */ jsx6("path", { d: "M3 7a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" })
775
+ }
776
+ ) : /* @__PURE__ */ jsxs5(
777
+ "svg",
778
+ {
779
+ viewBox: "0 0 24 24",
780
+ width: "17",
781
+ height: "17",
782
+ fill: "none",
783
+ stroke: dark ? "#94a3b8" : "#64748b",
784
+ strokeWidth: "1.6",
785
+ strokeLinecap: "round",
786
+ strokeLinejoin: "round",
787
+ children: [
788
+ /* @__PURE__ */ jsx6("path", { d: "M6 3h8l4 4v13a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z" }),
789
+ /* @__PURE__ */ jsx6("path", { d: "M14 3v4h4" })
790
+ ]
791
+ }
792
+ )
793
+ }
794
+ ),
795
+ /* @__PURE__ */ jsx6("span", { className: "upup-flex-1 upup-truncate", children: file.name }),
796
+ file.size != null && !file.isFolder && /* @__PURE__ */ jsx6("span", { className: "upup-text-xs upup-opacity-60", children: formatBytes(file.size) })
797
+ ]
798
+ },
799
+ file.id
800
+ );
801
+ })
802
+ ] }),
803
+ /* @__PURE__ */ jsxs5(
804
+ "div",
805
+ {
806
+ className: cn6(
807
+ "upup-flex upup-items-center upup-justify-between upup-gap-2 upup-border-t upup-p-3",
808
+ dark ? "upup-border-white/[0.06]" : "upup-border-black/[0.06]"
809
+ ),
810
+ children: [
811
+ /* @__PURE__ */ jsx6(
812
+ "button",
813
+ {
814
+ type: "button",
815
+ onClick: onBack,
816
+ className: "upup-text-sm upup-opacity-70 hover:upup-opacity-100",
817
+ children: "Cancel"
818
+ }
819
+ ),
820
+ /* @__PURE__ */ jsx6(
821
+ "button",
822
+ {
823
+ type: "button",
824
+ disabled: selected.size === 0 || transferring,
825
+ onClick: () => void handleTransfer(),
826
+ className: "upup-fx-press upup-rounded-lg upup-bg-[#0ea5e9] upup-px-3 upup-py-1.5 upup-text-sm upup-font-medium upup-text-white hover:upup-bg-[#0284c7] disabled:upup-opacity-50",
827
+ children: transferring ? "Uploading\u2026" : `Add files${selected.size ? ` (${selected.size})` : ""}`
828
+ }
829
+ )
830
+ ]
831
+ }
832
+ )
833
+ ]
834
+ }
835
+ )
836
+ }
837
+ );
838
+ }
839
+ function formatBytes(bytes) {
840
+ if (bytes < 1024) return `${bytes} B`;
841
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
842
+ if (bytes < 1024 * 1024 * 1024)
843
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
844
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
845
+ }
846
+
847
+ export {
848
+ DriveAuthFallback,
849
+ DriveBrowser,
850
+ ServerModeDriveUploader
851
+ };
852
+ //# sourceMappingURL=chunk-6TFTTLOD.js.map