@commercetools-demo/puck-image-picker 0.2.2

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.mjs ADDED
@@ -0,0 +1,714 @@
1
+ // src/ImagePickerField.tsx
2
+ import {
3
+ useCallback as useCallback2,
4
+ useEffect,
5
+ useRef,
6
+ useState as useState2
7
+ } from "react";
8
+
9
+ // src/hooks/useMediaLibrary.ts
10
+ import { useCallback, useState } from "react";
11
+
12
+ // src/api/media-library.api.ts
13
+ var fetchMediaLibraryApi = async (baseURL, projectKey, businessUnitKey, jwtToken, extensions = [], page = 1, limit = 20) => {
14
+ const params = new URLSearchParams();
15
+ if (extensions.length > 0) params.set("extensions", extensions.join(","));
16
+ params.set("page", String(page));
17
+ params.set("limit", String(limit));
18
+ const headers = {
19
+ "x-project-key": projectKey
20
+ };
21
+ if (jwtToken) headers["Authorization"] = `Bearer ${jwtToken}`;
22
+ const res = await fetch(
23
+ `${baseURL}/${businessUnitKey}/media-library?${params}`,
24
+ { headers }
25
+ );
26
+ if (!res.ok) {
27
+ const body = await res.text();
28
+ throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);
29
+ }
30
+ return res.json();
31
+ };
32
+ var uploadMediaFileApi = async (baseURL, projectKey, businessUnitKey, jwtToken, file, title, description) => {
33
+ const formData = new FormData();
34
+ formData.append("file", file);
35
+ if (title) formData.append("title", title);
36
+ if (description) formData.append("description", description);
37
+ const res = await fetch(
38
+ `${baseURL}/${businessUnitKey}/upload-file`,
39
+ {
40
+ method: "POST",
41
+ headers: {
42
+ "x-project-key": projectKey,
43
+ Authorization: `Bearer ${jwtToken}`
44
+ },
45
+ body: formData
46
+ }
47
+ );
48
+ if (!res.ok) {
49
+ const body = await res.text();
50
+ throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);
51
+ }
52
+ return res.json();
53
+ };
54
+
55
+ // src/context/ImagePickerContext.tsx
56
+ import { createContext, useContext } from "react";
57
+ var ImagePickerContext = createContext(null);
58
+ var useImagePickerContext = () => {
59
+ const ctx = useContext(ImagePickerContext);
60
+ if (!ctx) {
61
+ throw new Error(
62
+ "useImagePickerContext must be used inside <ImagePickerProvider>. Wrap your component tree with <ImagePickerProvider>."
63
+ );
64
+ }
65
+ return ctx;
66
+ };
67
+
68
+ // src/hooks/useMediaLibrary.ts
69
+ var initialPagination = {
70
+ totalItems: 0,
71
+ totalPages: 0,
72
+ currentPage: 1,
73
+ limit: 20
74
+ };
75
+ var useMediaLibrary = () => {
76
+ const { baseURL, projectKey, businessUnitKey, jwtToken } = useImagePickerContext();
77
+ const [state, setState] = useState({
78
+ files: [],
79
+ pagination: initialPagination,
80
+ loading: false,
81
+ uploading: false,
82
+ error: null
83
+ });
84
+ const fetchMedia = useCallback(
85
+ async (extensions = [], page = 1, limit = 20) => {
86
+ setState((s) => ({ ...s, loading: true, error: null }));
87
+ try {
88
+ const result = await fetchMediaLibraryApi(
89
+ baseURL,
90
+ projectKey,
91
+ businessUnitKey,
92
+ jwtToken,
93
+ extensions,
94
+ page,
95
+ limit
96
+ );
97
+ setState((s) => ({
98
+ ...s,
99
+ files: result.files,
100
+ pagination: result.pagination,
101
+ loading: false
102
+ }));
103
+ } catch (err) {
104
+ setState((s) => ({
105
+ ...s,
106
+ loading: false,
107
+ error: err.message
108
+ }));
109
+ }
110
+ },
111
+ [baseURL, projectKey, businessUnitKey, jwtToken]
112
+ );
113
+ const uploadFile = useCallback(
114
+ async (file, title, description) => {
115
+ if (!jwtToken) throw new Error("jwtToken is required to upload files");
116
+ setState((s) => ({ ...s, uploading: true, error: null }));
117
+ try {
118
+ const result = await uploadMediaFileApi(
119
+ baseURL,
120
+ projectKey,
121
+ businessUnitKey,
122
+ jwtToken,
123
+ file,
124
+ title,
125
+ description
126
+ );
127
+ const mediaFile = {
128
+ url: result.url,
129
+ name: file.name,
130
+ title: title ?? file.name,
131
+ description,
132
+ isImage: file.type.startsWith("image/"),
133
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
134
+ size: file.size
135
+ };
136
+ setState((s) => ({
137
+ ...s,
138
+ files: [mediaFile, ...s.files],
139
+ pagination: {
140
+ ...s.pagination,
141
+ totalItems: s.pagination.totalItems + 1
142
+ },
143
+ uploading: false
144
+ }));
145
+ return mediaFile;
146
+ } catch (err) {
147
+ setState((s) => ({
148
+ ...s,
149
+ uploading: false,
150
+ error: err.message
151
+ }));
152
+ throw err;
153
+ }
154
+ },
155
+ [baseURL, projectKey, businessUnitKey, jwtToken]
156
+ );
157
+ const loadNextPage = useCallback(
158
+ async (extensions = []) => {
159
+ const next = state.pagination.currentPage + 1;
160
+ if (next <= state.pagination.totalPages) {
161
+ await fetchMedia(extensions, next, state.pagination.limit);
162
+ }
163
+ },
164
+ [fetchMedia, state.pagination]
165
+ );
166
+ const loadPreviousPage = useCallback(
167
+ async (extensions = []) => {
168
+ const prev = state.pagination.currentPage - 1;
169
+ if (prev >= 1) {
170
+ await fetchMedia(extensions, prev, state.pagination.limit);
171
+ }
172
+ },
173
+ [fetchMedia, state.pagination]
174
+ );
175
+ const hasNextPage = useCallback(
176
+ () => state.pagination.currentPage < state.pagination.totalPages,
177
+ [state.pagination]
178
+ );
179
+ const hasPreviousPage = useCallback(
180
+ () => state.pagination.currentPage > 1,
181
+ [state.pagination]
182
+ );
183
+ return {
184
+ files: state.files,
185
+ pagination: state.pagination,
186
+ loading: state.loading,
187
+ uploading: state.uploading,
188
+ error: state.error,
189
+ fetchMedia,
190
+ uploadFile,
191
+ loadNextPage,
192
+ loadPreviousPage,
193
+ hasNextPage,
194
+ hasPreviousPage
195
+ };
196
+ };
197
+
198
+ // src/ImagePickerField.tsx
199
+ import PrimaryButton from "@commercetools-uikit/primary-button";
200
+ import SecondaryButton from "@commercetools-uikit/secondary-button";
201
+ import FlatButton from "@commercetools-uikit/flat-button";
202
+ import SecondaryIconButton from "@commercetools-uikit/secondary-icon-button";
203
+ import TextInput from "@commercetools-uikit/text-input";
204
+ import Label from "@commercetools-uikit/label";
205
+ import LoadingSpinner from "@commercetools-uikit/loading-spinner";
206
+ import Spacings from "@commercetools-uikit/spacings";
207
+ import Text from "@commercetools-uikit/text";
208
+ import { CloseIcon } from "@commercetools-uikit/icons";
209
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
210
+ var UploadModal = ({
211
+ uploading,
212
+ error,
213
+ imagesOnly,
214
+ onUpload,
215
+ onClose
216
+ }) => {
217
+ const [file, setFile] = useState2(null);
218
+ const [title, setTitle] = useState2("");
219
+ const [description, setDescription] = useState2("");
220
+ const [dragging, setDragging] = useState2(false);
221
+ const inputRef = useRef(null);
222
+ const handleFile = (f) => {
223
+ setFile(f);
224
+ if (!title) setTitle(f.name);
225
+ };
226
+ const handleDrop = (e) => {
227
+ e.preventDefault();
228
+ setDragging(false);
229
+ const f = e.dataTransfer.files[0];
230
+ if (f) handleFile(f);
231
+ };
232
+ return /* @__PURE__ */ jsx(
233
+ "div",
234
+ {
235
+ style: {
236
+ position: "fixed",
237
+ inset: 0,
238
+ background: "rgba(0,0,0,0.5)",
239
+ zIndex: 9999,
240
+ display: "flex",
241
+ alignItems: "center",
242
+ justifyContent: "center"
243
+ },
244
+ onClick: (e) => e.target === e.currentTarget && onClose(),
245
+ children: /* @__PURE__ */ jsxs(
246
+ "div",
247
+ {
248
+ style: {
249
+ background: "#fff",
250
+ borderRadius: "8px",
251
+ width: "640px",
252
+ maxWidth: "95vw",
253
+ maxHeight: "85vh",
254
+ display: "flex",
255
+ flexDirection: "column",
256
+ boxShadow: "0 20px 60px rgba(0,0,0,0.3)"
257
+ },
258
+ children: [
259
+ /* @__PURE__ */ jsxs(
260
+ "div",
261
+ {
262
+ style: {
263
+ display: "flex",
264
+ alignItems: "center",
265
+ justifyContent: "space-between",
266
+ padding: "16px 20px",
267
+ borderBottom: "1px solid #e5e7eb"
268
+ },
269
+ children: [
270
+ /* @__PURE__ */ jsx(Text.Subheadline, { as: "h4", isBold: true, children: "Upload a file" }),
271
+ /* @__PURE__ */ jsx(
272
+ SecondaryIconButton,
273
+ {
274
+ icon: /* @__PURE__ */ jsx(CloseIcon, {}),
275
+ label: "Close",
276
+ onClick: onClose,
277
+ size: "small"
278
+ }
279
+ )
280
+ ]
281
+ }
282
+ ),
283
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "m", children: [
284
+ /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "xs", children: [
285
+ /* @__PURE__ */ jsx(Label, { htmlFor: "upload-title", children: "Title" }),
286
+ /* @__PURE__ */ jsx(
287
+ TextInput,
288
+ {
289
+ id: "upload-title",
290
+ value: title,
291
+ onChange: (e) => setTitle(e.target.value),
292
+ placeholder: "File title"
293
+ }
294
+ )
295
+ ] }),
296
+ /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "xs", children: [
297
+ /* @__PURE__ */ jsx(Label, { htmlFor: "upload-description", children: "Description" }),
298
+ /* @__PURE__ */ jsx(
299
+ TextInput,
300
+ {
301
+ id: "upload-description",
302
+ value: description,
303
+ onChange: (e) => setDescription(e.target.value),
304
+ placeholder: "Optional description"
305
+ }
306
+ )
307
+ ] }),
308
+ /* @__PURE__ */ jsxs(
309
+ "div",
310
+ {
311
+ style: {
312
+ border: dragging ? "2px dashed #3b82f6" : "2px dashed #d1d5db",
313
+ borderRadius: "6px",
314
+ padding: "24px",
315
+ textAlign: "center",
316
+ cursor: "pointer",
317
+ color: dragging ? "#3b82f6" : "#6b7280",
318
+ fontSize: "13px",
319
+ transition: "border-color .2s"
320
+ },
321
+ onClick: () => inputRef.current?.click(),
322
+ onDragOver: (e) => {
323
+ e.preventDefault();
324
+ setDragging(true);
325
+ },
326
+ onDragLeave: () => setDragging(false),
327
+ onDrop: handleDrop,
328
+ children: [
329
+ file ? /* @__PURE__ */ jsxs(Fragment, { children: [
330
+ /* @__PURE__ */ jsxs("div", { children: [
331
+ "\u{1F4CE} ",
332
+ file.name
333
+ ] }),
334
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: "11px", marginTop: "4px", color: "#9ca3af" }, children: [
335
+ (file.size / 1024).toFixed(0),
336
+ " KB"
337
+ ] })
338
+ ] }) : /* @__PURE__ */ jsx("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
339
+ /* @__PURE__ */ jsx(
340
+ "input",
341
+ {
342
+ ref: inputRef,
343
+ type: "file",
344
+ accept: imagesOnly ? "image/*" : "*/*",
345
+ style: { display: "none" },
346
+ onChange: (e) => {
347
+ const f = e.target.files?.[0];
348
+ if (f) handleFile(f);
349
+ }
350
+ }
351
+ )
352
+ ]
353
+ }
354
+ ),
355
+ error && /* @__PURE__ */ jsx(Text.Body, { tone: "negative", children: error })
356
+ ] }) }),
357
+ /* @__PURE__ */ jsxs(
358
+ "div",
359
+ {
360
+ style: {
361
+ display: "flex",
362
+ justifyContent: "space-between",
363
+ alignItems: "center",
364
+ padding: "12px 20px",
365
+ borderTop: "1px solid #e5e7eb",
366
+ gap: "12px"
367
+ },
368
+ children: [
369
+ /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: file?.name ?? "No file selected" }),
370
+ /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
371
+ /* @__PURE__ */ jsx(SecondaryButton, { label: "Cancel", onClick: onClose }),
372
+ /* @__PURE__ */ jsx(
373
+ PrimaryButton,
374
+ {
375
+ label: uploading ? "Uploading\u2026" : "Upload",
376
+ isDisabled: !file || uploading,
377
+ onClick: () => file && onUpload(file, title, description)
378
+ }
379
+ )
380
+ ] })
381
+ ]
382
+ }
383
+ )
384
+ ]
385
+ }
386
+ )
387
+ }
388
+ );
389
+ };
390
+ var LibraryModal = ({
391
+ files,
392
+ pagination,
393
+ loading,
394
+ error,
395
+ onNextPage,
396
+ onPrevPage,
397
+ onSelect,
398
+ onClose
399
+ }) => {
400
+ const [selected, setSelected] = useState2(null);
401
+ const handleConfirm = () => {
402
+ if (selected) onSelect(selected);
403
+ };
404
+ return /* @__PURE__ */ jsx(
405
+ "div",
406
+ {
407
+ style: {
408
+ position: "fixed",
409
+ inset: 0,
410
+ background: "rgba(0,0,0,0.5)",
411
+ zIndex: 9999,
412
+ display: "flex",
413
+ alignItems: "center",
414
+ justifyContent: "center"
415
+ },
416
+ onClick: (e) => e.target === e.currentTarget && onClose(),
417
+ children: /* @__PURE__ */ jsxs(
418
+ "div",
419
+ {
420
+ style: {
421
+ background: "#fff",
422
+ borderRadius: "8px",
423
+ width: "640px",
424
+ maxWidth: "95vw",
425
+ maxHeight: "85vh",
426
+ display: "flex",
427
+ flexDirection: "column",
428
+ boxShadow: "0 20px 60px rgba(0,0,0,0.3)"
429
+ },
430
+ children: [
431
+ /* @__PURE__ */ jsxs(
432
+ "div",
433
+ {
434
+ style: {
435
+ display: "flex",
436
+ alignItems: "center",
437
+ justifyContent: "space-between",
438
+ padding: "16px 20px",
439
+ borderBottom: "1px solid #e5e7eb"
440
+ },
441
+ children: [
442
+ /* @__PURE__ */ jsx(Text.Subheadline, { as: "h4", isBold: true, children: "Select from Media Library" }),
443
+ /* @__PURE__ */ jsx(
444
+ SecondaryIconButton,
445
+ {
446
+ icon: /* @__PURE__ */ jsx(CloseIcon, {}),
447
+ label: "Close",
448
+ onClick: onClose,
449
+ size: "small"
450
+ }
451
+ )
452
+ ]
453
+ }
454
+ ),
455
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: [
456
+ loading ? /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }) : files.length === 0 ? /* @__PURE__ */ jsx(Text.Body, { tone: "secondary", children: "No files found." }) : /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "m", children: [
457
+ /* @__PURE__ */ jsx(
458
+ "div",
459
+ {
460
+ style: {
461
+ display: "grid",
462
+ gridTemplateColumns: "repeat(auto-fill, minmax(110px, 1fr))",
463
+ gap: "12px"
464
+ },
465
+ children: files.map((file) => /* @__PURE__ */ jsxs(
466
+ "div",
467
+ {
468
+ style: {
469
+ display: "flex",
470
+ flexDirection: "column",
471
+ alignItems: "center",
472
+ cursor: "pointer",
473
+ border: `2px solid ${selected?.url === file.url ? "#3b82f6" : "transparent"}`,
474
+ borderRadius: "6px",
475
+ padding: "6px",
476
+ background: selected?.url === file.url ? "rgba(59,130,246,0.07)" : "#f9fafb"
477
+ },
478
+ onClick: () => setSelected(file),
479
+ title: file.title ?? file.name,
480
+ children: [
481
+ file.isImage ? /* @__PURE__ */ jsx(
482
+ "img",
483
+ {
484
+ src: file.url,
485
+ alt: file.name,
486
+ style: { width: "80px", height: "80px", objectFit: "cover", borderRadius: "4px", background: "#e5e7eb" }
487
+ }
488
+ ) : /* @__PURE__ */ jsx(
489
+ "div",
490
+ {
491
+ style: {
492
+ width: "80px",
493
+ height: "80px",
494
+ borderRadius: "4px",
495
+ background: "#e5e7eb",
496
+ display: "flex",
497
+ alignItems: "center",
498
+ justifyContent: "center",
499
+ fontSize: "28px"
500
+ },
501
+ children: "\u{1F4C4}"
502
+ }
503
+ ),
504
+ /* @__PURE__ */ jsx(
505
+ "div",
506
+ {
507
+ style: {
508
+ marginTop: "6px",
509
+ fontSize: "11px",
510
+ textAlign: "center",
511
+ maxWidth: "100%",
512
+ overflow: "hidden",
513
+ textOverflow: "ellipsis",
514
+ whiteSpace: "nowrap",
515
+ color: "#374151"
516
+ },
517
+ children: file.title ?? file.name
518
+ }
519
+ )
520
+ ]
521
+ },
522
+ file.url
523
+ ))
524
+ }
525
+ ),
526
+ pagination.totalPages > 1 && /* @__PURE__ */ jsxs(Spacings.Inline, { alignItems: "center", justifyContent: "center", scale: "s", children: [
527
+ /* @__PURE__ */ jsx(
528
+ SecondaryButton,
529
+ {
530
+ label: "\u2190 Prev",
531
+ isDisabled: pagination.currentPage <= 1,
532
+ onClick: onPrevPage,
533
+ size: "small"
534
+ }
535
+ ),
536
+ /* @__PURE__ */ jsxs(Text.Detail, { tone: "secondary", children: [
537
+ pagination.currentPage,
538
+ " / ",
539
+ pagination.totalPages
540
+ ] }),
541
+ /* @__PURE__ */ jsx(
542
+ SecondaryButton,
543
+ {
544
+ label: "Next \u2192",
545
+ isDisabled: pagination.currentPage >= pagination.totalPages,
546
+ onClick: onNextPage,
547
+ size: "small"
548
+ }
549
+ )
550
+ ] })
551
+ ] }),
552
+ error && /* @__PURE__ */ jsx(Text.Body, { tone: "negative", children: error })
553
+ ] }),
554
+ /* @__PURE__ */ jsxs(
555
+ "div",
556
+ {
557
+ style: {
558
+ display: "flex",
559
+ justifyContent: "space-between",
560
+ alignItems: "center",
561
+ padding: "12px 20px",
562
+ borderTop: "1px solid #e5e7eb",
563
+ gap: "12px"
564
+ },
565
+ children: [
566
+ /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
567
+ /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
568
+ /* @__PURE__ */ jsx(SecondaryButton, { label: "Cancel", onClick: onClose }),
569
+ /* @__PURE__ */ jsx(
570
+ PrimaryButton,
571
+ {
572
+ label: "Select",
573
+ isDisabled: !selected,
574
+ onClick: handleConfirm
575
+ }
576
+ )
577
+ ] })
578
+ ]
579
+ }
580
+ )
581
+ ]
582
+ }
583
+ )
584
+ }
585
+ );
586
+ };
587
+ var ImagePickerField = ({
588
+ value,
589
+ onChange,
590
+ imagesOnly = true
591
+ }) => {
592
+ const {
593
+ files,
594
+ pagination,
595
+ loading,
596
+ uploading,
597
+ error,
598
+ fetchMedia,
599
+ uploadFile,
600
+ loadNextPage,
601
+ loadPreviousPage
602
+ } = useMediaLibrary();
603
+ const [showUpload, setShowUpload] = useState2(false);
604
+ const [showLibrary, setShowLibrary] = useState2(false);
605
+ const extensions = imagesOnly ? ["jpg", "jpeg", "png", "gif", "webp", "svg"] : [];
606
+ const openLibrary = useCallback2(() => {
607
+ void fetchMedia(extensions, 1, 20);
608
+ setShowLibrary(true);
609
+ }, [fetchMedia, extensions]);
610
+ const handleUpload = useCallback2(
611
+ async (file, title, description) => {
612
+ const mediaFile = await uploadFile(file, title, description);
613
+ onChange(mediaFile.url);
614
+ setShowUpload(false);
615
+ },
616
+ [uploadFile, onChange]
617
+ );
618
+ const handleSelect = useCallback2(
619
+ (file) => {
620
+ onChange(file.url);
621
+ setShowLibrary(false);
622
+ },
623
+ [onChange]
624
+ );
625
+ useEffect(() => {
626
+ const onKey = (e) => {
627
+ if (e.key === "Escape") {
628
+ setShowUpload(false);
629
+ setShowLibrary(false);
630
+ }
631
+ };
632
+ window.addEventListener("keydown", onKey);
633
+ return () => window.removeEventListener("keydown", onKey);
634
+ }, []);
635
+ return /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "s", children: [
636
+ value ? /* @__PURE__ */ jsxs(
637
+ "div",
638
+ {
639
+ style: {
640
+ display: "flex",
641
+ alignItems: "center",
642
+ gap: "10px",
643
+ padding: "8px",
644
+ border: "1px solid #d1d5db",
645
+ borderRadius: "6px",
646
+ background: "#f9fafb"
647
+ },
648
+ children: [
649
+ /* @__PURE__ */ jsx(
650
+ "img",
651
+ {
652
+ src: value,
653
+ alt: "",
654
+ style: { width: "48px", height: "48px", objectFit: "cover", borderRadius: "4px", flexShrink: 0 }
655
+ }
656
+ ),
657
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: value }) }),
658
+ /* @__PURE__ */ jsx(FlatButton, { tone: "critical", label: "Remove", onClick: () => onChange("") })
659
+ ]
660
+ }
661
+ ) : /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", children: "No image selected" }),
662
+ /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
663
+ /* @__PURE__ */ jsx(SecondaryButton, { label: "Upload", onClick: () => setShowUpload(true) }),
664
+ /* @__PURE__ */ jsx(PrimaryButton, { label: "Media Library", onClick: openLibrary })
665
+ ] }),
666
+ showUpload && /* @__PURE__ */ jsx(
667
+ UploadModal,
668
+ {
669
+ uploading,
670
+ error,
671
+ imagesOnly,
672
+ onUpload: (file, title, desc) => void handleUpload(file, title, desc),
673
+ onClose: () => setShowUpload(false)
674
+ }
675
+ ),
676
+ showLibrary && /* @__PURE__ */ jsx(
677
+ LibraryModal,
678
+ {
679
+ files,
680
+ pagination,
681
+ loading,
682
+ error,
683
+ onNextPage: () => void loadNextPage(extensions),
684
+ onPrevPage: () => void loadPreviousPage(extensions),
685
+ onSelect: handleSelect,
686
+ onClose: () => setShowLibrary(false)
687
+ }
688
+ )
689
+ ] });
690
+ };
691
+
692
+ // src/context/ImagePickerProvider.tsx
693
+ import { jsx as jsx2 } from "react/jsx-runtime";
694
+ var ImagePickerProvider = ({
695
+ children,
696
+ baseURL,
697
+ projectKey,
698
+ businessUnitKey,
699
+ jwtToken
700
+ }) => {
701
+ return /* @__PURE__ */ jsx2(
702
+ ImagePickerContext.Provider,
703
+ {
704
+ value: { baseURL, projectKey, businessUnitKey, jwtToken },
705
+ children
706
+ }
707
+ );
708
+ };
709
+ export {
710
+ ImagePickerField,
711
+ ImagePickerProvider,
712
+ useMediaLibrary
713
+ };
714
+ //# sourceMappingURL=index.mjs.map