@commercetools-demo/puck-image-picker 0.4.1 β 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +92 -122
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +86 -98
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -21
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -229,17 +219,19 @@ var useMediaLibrary = () => {
|
|
|
229
219
|
};
|
|
230
220
|
|
|
231
221
|
// src/ImagePickerField.tsx
|
|
232
|
-
var
|
|
233
|
-
var
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
var
|
|
237
|
-
var import_label = __toESM(require("@commercetools-uikit/label"));
|
|
238
|
-
var import_loading_spinner = __toESM(require("@commercetools-uikit/loading-spinner"));
|
|
239
|
-
var import_spacings = __toESM(require("@commercetools-uikit/spacings"));
|
|
240
|
-
var import_text = __toESM(require("@commercetools-uikit/text"));
|
|
241
|
-
var import_icons = require("@commercetools-uikit/icons");
|
|
222
|
+
var import_nimbus2 = require("@commercetools/nimbus");
|
|
223
|
+
var import_nimbus_icons = require("@commercetools/nimbus-icons");
|
|
224
|
+
|
|
225
|
+
// src/EnsureNimbusProvider.tsx
|
|
226
|
+
var import_nimbus = require("@commercetools/nimbus");
|
|
242
227
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
228
|
+
var EnsureNimbusProvider = ({
|
|
229
|
+
locale = "en",
|
|
230
|
+
children
|
|
231
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_nimbus.NimbusProvider, { locale, children });
|
|
232
|
+
|
|
233
|
+
// src/ImagePickerField.tsx
|
|
234
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
243
235
|
var UploadModal = ({
|
|
244
236
|
uploading,
|
|
245
237
|
error,
|
|
@@ -262,7 +254,7 @@ var UploadModal = ({
|
|
|
262
254
|
const f = e.dataTransfer.files[0];
|
|
263
255
|
if (f) handleFile(f);
|
|
264
256
|
};
|
|
265
|
-
return /* @__PURE__ */ (0,
|
|
257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
266
258
|
"div",
|
|
267
259
|
{
|
|
268
260
|
style: {
|
|
@@ -275,7 +267,7 @@ var UploadModal = ({
|
|
|
275
267
|
justifyContent: "center"
|
|
276
268
|
},
|
|
277
269
|
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
278
|
-
children: /* @__PURE__ */ (0,
|
|
270
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
279
271
|
"div",
|
|
280
272
|
{
|
|
281
273
|
style: {
|
|
@@ -289,7 +281,7 @@ var UploadModal = ({
|
|
|
289
281
|
boxShadow: "0 20px 60px rgba(0,0,0,0.3)"
|
|
290
282
|
},
|
|
291
283
|
children: [
|
|
292
|
-
/* @__PURE__ */ (0,
|
|
284
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
293
285
|
"div",
|
|
294
286
|
{
|
|
295
287
|
style: {
|
|
@@ -300,45 +292,35 @@ var UploadModal = ({
|
|
|
300
292
|
borderBottom: "1px solid #e5e7eb"
|
|
301
293
|
},
|
|
302
294
|
children: [
|
|
303
|
-
/* @__PURE__ */ (0,
|
|
304
|
-
/* @__PURE__ */ (0,
|
|
305
|
-
import_secondary_icon_button.default,
|
|
306
|
-
{
|
|
307
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CloseIcon, {}),
|
|
308
|
-
label: "Close",
|
|
309
|
-
onClick: onClose,
|
|
310
|
-
size: "small"
|
|
311
|
-
}
|
|
312
|
-
)
|
|
295
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Upload a file" }),
|
|
296
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.IconButton, { "aria-label": "Close", variant: "ghost", size: "xs", onPress: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus_icons.Close, {}) })
|
|
313
297
|
]
|
|
314
298
|
}
|
|
315
299
|
),
|
|
316
|
-
/* @__PURE__ */ (0,
|
|
317
|
-
/* @__PURE__ */ (0,
|
|
318
|
-
/* @__PURE__ */ (0,
|
|
319
|
-
/* @__PURE__ */ (0,
|
|
320
|
-
|
|
300
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "column", gap: "400", children: [
|
|
301
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.FormField.Root, { children: [
|
|
302
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.FormField.Label, { children: "Title" }),
|
|
303
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
304
|
+
import_nimbus2.TextInput,
|
|
321
305
|
{
|
|
322
|
-
id: "upload-title",
|
|
323
306
|
value: title,
|
|
324
|
-
onChange: (
|
|
307
|
+
onChange: (value) => setTitle(value),
|
|
325
308
|
placeholder: "File title"
|
|
326
309
|
}
|
|
327
|
-
)
|
|
310
|
+
) })
|
|
328
311
|
] }),
|
|
329
|
-
/* @__PURE__ */ (0,
|
|
330
|
-
/* @__PURE__ */ (0,
|
|
331
|
-
/* @__PURE__ */ (0,
|
|
332
|
-
|
|
312
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.FormField.Root, { children: [
|
|
313
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.FormField.Label, { children: "Description" }),
|
|
314
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.FormField.Input, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
315
|
+
import_nimbus2.TextInput,
|
|
333
316
|
{
|
|
334
|
-
id: "upload-description",
|
|
335
317
|
value: description,
|
|
336
|
-
onChange: (
|
|
318
|
+
onChange: (value) => setDescription(value),
|
|
337
319
|
placeholder: "Optional description"
|
|
338
320
|
}
|
|
339
|
-
)
|
|
321
|
+
) })
|
|
340
322
|
] }),
|
|
341
|
-
/* @__PURE__ */ (0,
|
|
323
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
342
324
|
"div",
|
|
343
325
|
{
|
|
344
326
|
style: {
|
|
@@ -359,17 +341,17 @@ var UploadModal = ({
|
|
|
359
341
|
onDragLeave: () => setDragging(false),
|
|
360
342
|
onDrop: handleDrop,
|
|
361
343
|
children: [
|
|
362
|
-
file ? /* @__PURE__ */ (0,
|
|
363
|
-
/* @__PURE__ */ (0,
|
|
344
|
+
file ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
345
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
364
346
|
"\u{1F4CE} ",
|
|
365
347
|
file.name
|
|
366
348
|
] }),
|
|
367
|
-
/* @__PURE__ */ (0,
|
|
349
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11px", marginTop: "4px", color: "#9ca3af" }, children: [
|
|
368
350
|
(file.size / 1024).toFixed(0),
|
|
369
351
|
" KB"
|
|
370
352
|
] })
|
|
371
|
-
] }) : /* @__PURE__ */ (0,
|
|
372
|
-
/* @__PURE__ */ (0,
|
|
353
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
|
|
354
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
373
355
|
"input",
|
|
374
356
|
{
|
|
375
357
|
ref: inputRef,
|
|
@@ -385,9 +367,9 @@ var UploadModal = ({
|
|
|
385
367
|
]
|
|
386
368
|
}
|
|
387
369
|
),
|
|
388
|
-
error && /* @__PURE__ */ (0,
|
|
370
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { color: "critical.11", children: error })
|
|
389
371
|
] }) }),
|
|
390
|
-
/* @__PURE__ */ (0,
|
|
372
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
391
373
|
"div",
|
|
392
374
|
{
|
|
393
375
|
style: {
|
|
@@ -399,15 +381,16 @@ var UploadModal = ({
|
|
|
399
381
|
gap: "12px"
|
|
400
382
|
},
|
|
401
383
|
children: [
|
|
402
|
-
/* @__PURE__ */ (0,
|
|
403
|
-
/* @__PURE__ */ (0,
|
|
404
|
-
/* @__PURE__ */ (0,
|
|
405
|
-
/* @__PURE__ */ (0,
|
|
406
|
-
|
|
384
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: file?.name ?? "No file selected" }),
|
|
385
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "200", children: [
|
|
386
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Button, { variant: "outline", onPress: onClose, children: "Cancel" }),
|
|
387
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
388
|
+
import_nimbus2.Button,
|
|
407
389
|
{
|
|
408
|
-
|
|
390
|
+
variant: "solid",
|
|
409
391
|
isDisabled: !file || uploading,
|
|
410
|
-
|
|
392
|
+
onPress: () => file && onUpload(file, title, description),
|
|
393
|
+
children: uploading ? "Uploading\u2026" : "Upload"
|
|
411
394
|
}
|
|
412
395
|
)
|
|
413
396
|
] })
|
|
@@ -434,7 +417,7 @@ var LibraryModal = ({
|
|
|
434
417
|
const handleConfirm = () => {
|
|
435
418
|
if (selected) onSelect(selected);
|
|
436
419
|
};
|
|
437
|
-
return /* @__PURE__ */ (0,
|
|
420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
438
421
|
"div",
|
|
439
422
|
{
|
|
440
423
|
style: {
|
|
@@ -447,7 +430,7 @@ var LibraryModal = ({
|
|
|
447
430
|
justifyContent: "center"
|
|
448
431
|
},
|
|
449
432
|
onClick: (e) => e.target === e.currentTarget && onClose(),
|
|
450
|
-
children: /* @__PURE__ */ (0,
|
|
433
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
451
434
|
"div",
|
|
452
435
|
{
|
|
453
436
|
style: {
|
|
@@ -461,7 +444,7 @@ var LibraryModal = ({
|
|
|
461
444
|
boxShadow: "0 20px 60px rgba(0,0,0,0.3)"
|
|
462
445
|
},
|
|
463
446
|
children: [
|
|
464
|
-
/* @__PURE__ */ (0,
|
|
447
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
465
448
|
"div",
|
|
466
449
|
{
|
|
467
450
|
style: {
|
|
@@ -472,22 +455,14 @@ var LibraryModal = ({
|
|
|
472
455
|
borderBottom: "1px solid #e5e7eb"
|
|
473
456
|
},
|
|
474
457
|
children: [
|
|
475
|
-
/* @__PURE__ */ (0,
|
|
476
|
-
/* @__PURE__ */ (0,
|
|
477
|
-
import_secondary_icon_button.default,
|
|
478
|
-
{
|
|
479
|
-
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CloseIcon, {}),
|
|
480
|
-
label: "Close",
|
|
481
|
-
onClick: onClose,
|
|
482
|
-
size: "small"
|
|
483
|
-
}
|
|
484
|
-
)
|
|
458
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Select from Media Library" }),
|
|
459
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.IconButton, { "aria-label": "Close", variant: "ghost", size: "xs", onPress: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus_icons.Close, {}) })
|
|
485
460
|
]
|
|
486
461
|
}
|
|
487
462
|
),
|
|
488
|
-
/* @__PURE__ */ (0,
|
|
489
|
-
loading ? /* @__PURE__ */ (0,
|
|
490
|
-
/* @__PURE__ */ (0,
|
|
463
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: [
|
|
464
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.LoadingSpinner, {}) }) : files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { color: "neutral.11", children: "No files found." }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "column", gap: "400", children: [
|
|
465
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
491
466
|
"div",
|
|
492
467
|
{
|
|
493
468
|
style: {
|
|
@@ -495,7 +470,7 @@ var LibraryModal = ({
|
|
|
495
470
|
gridTemplateColumns: "repeat(auto-fill, minmax(110px, 1fr))",
|
|
496
471
|
gap: "12px"
|
|
497
472
|
},
|
|
498
|
-
children: files.map((file) => /* @__PURE__ */ (0,
|
|
473
|
+
children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
499
474
|
"div",
|
|
500
475
|
{
|
|
501
476
|
style: {
|
|
@@ -511,14 +486,14 @@ var LibraryModal = ({
|
|
|
511
486
|
onClick: () => setSelected(file),
|
|
512
487
|
title: file.title ?? file.name,
|
|
513
488
|
children: [
|
|
514
|
-
file.isImage ? /* @__PURE__ */ (0,
|
|
489
|
+
file.isImage ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
515
490
|
"img",
|
|
516
491
|
{
|
|
517
492
|
src: file.url,
|
|
518
493
|
alt: file.name,
|
|
519
494
|
style: { width: "80px", height: "80px", objectFit: "cover", borderRadius: "4px", background: "#e5e7eb" }
|
|
520
495
|
}
|
|
521
|
-
) : /* @__PURE__ */ (0,
|
|
496
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
522
497
|
"div",
|
|
523
498
|
{
|
|
524
499
|
style: {
|
|
@@ -534,7 +509,7 @@ var LibraryModal = ({
|
|
|
534
509
|
children: "\u{1F4C4}"
|
|
535
510
|
}
|
|
536
511
|
),
|
|
537
|
-
/* @__PURE__ */ (0,
|
|
512
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
538
513
|
"div",
|
|
539
514
|
{
|
|
540
515
|
style: {
|
|
@@ -556,35 +531,37 @@ var LibraryModal = ({
|
|
|
556
531
|
))
|
|
557
532
|
}
|
|
558
533
|
),
|
|
559
|
-
pagination.totalPages > 1 && /* @__PURE__ */ (0,
|
|
560
|
-
/* @__PURE__ */ (0,
|
|
561
|
-
|
|
534
|
+
pagination.totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "200", alignItems: "center", justifyContent: "center", children: [
|
|
535
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
536
|
+
import_nimbus2.Button,
|
|
562
537
|
{
|
|
563
|
-
|
|
538
|
+
variant: "outline",
|
|
539
|
+
size: "sm",
|
|
564
540
|
isDisabled: pagination.currentPage <= 1,
|
|
565
|
-
|
|
566
|
-
|
|
541
|
+
onPress: onPrevPage,
|
|
542
|
+
children: "\u2190 Prev"
|
|
567
543
|
}
|
|
568
544
|
),
|
|
569
|
-
/* @__PURE__ */ (0,
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Text, { fontSize: "sm", color: "neutral.11", children: [
|
|
570
546
|
pagination.currentPage,
|
|
571
547
|
" / ",
|
|
572
548
|
pagination.totalPages
|
|
573
549
|
] }),
|
|
574
|
-
/* @__PURE__ */ (0,
|
|
575
|
-
|
|
550
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
551
|
+
import_nimbus2.Button,
|
|
576
552
|
{
|
|
577
|
-
|
|
553
|
+
variant: "outline",
|
|
554
|
+
size: "sm",
|
|
578
555
|
isDisabled: pagination.currentPage >= pagination.totalPages,
|
|
579
|
-
|
|
580
|
-
|
|
556
|
+
onPress: onNextPage,
|
|
557
|
+
children: "Next \u2192"
|
|
581
558
|
}
|
|
582
559
|
)
|
|
583
560
|
] })
|
|
584
561
|
] }),
|
|
585
|
-
error && /* @__PURE__ */ (0,
|
|
562
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { color: "critical.11", children: error })
|
|
586
563
|
] }),
|
|
587
|
-
/* @__PURE__ */ (0,
|
|
564
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
588
565
|
"div",
|
|
589
566
|
{
|
|
590
567
|
style: {
|
|
@@ -596,17 +573,10 @@ var LibraryModal = ({
|
|
|
596
573
|
gap: "12px"
|
|
597
574
|
},
|
|
598
575
|
children: [
|
|
599
|
-
/* @__PURE__ */ (0,
|
|
600
|
-
/* @__PURE__ */ (0,
|
|
601
|
-
/* @__PURE__ */ (0,
|
|
602
|
-
/* @__PURE__ */ (0,
|
|
603
|
-
import_primary_button.default,
|
|
604
|
-
{
|
|
605
|
-
label: "Select",
|
|
606
|
-
isDisabled: !selected,
|
|
607
|
-
onClick: handleConfirm
|
|
608
|
-
}
|
|
609
|
-
)
|
|
576
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
|
|
577
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "200", children: [
|
|
578
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Button, { variant: "outline", onPress: onClose, children: "Cancel" }),
|
|
579
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Button, { variant: "solid", isDisabled: !selected, onPress: handleConfirm, children: "Select" })
|
|
610
580
|
] })
|
|
611
581
|
]
|
|
612
582
|
}
|
|
@@ -665,8 +635,8 @@ var ImagePickerField = ({
|
|
|
665
635
|
window.addEventListener("keydown", onKey);
|
|
666
636
|
return () => window.removeEventListener("keydown", onKey);
|
|
667
637
|
}, []);
|
|
668
|
-
return /* @__PURE__ */ (0,
|
|
669
|
-
value ? /* @__PURE__ */ (0,
|
|
638
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EnsureNimbusProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "column", gap: "200", children: [
|
|
639
|
+
value ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
670
640
|
"div",
|
|
671
641
|
{
|
|
672
642
|
style: {
|
|
@@ -679,7 +649,7 @@ var ImagePickerField = ({
|
|
|
679
649
|
background: "#f9fafb"
|
|
680
650
|
},
|
|
681
651
|
children: [
|
|
682
|
-
/* @__PURE__ */ (0,
|
|
652
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
683
653
|
"img",
|
|
684
654
|
{
|
|
685
655
|
src: value,
|
|
@@ -687,16 +657,16 @@ var ImagePickerField = ({
|
|
|
687
657
|
style: { width: "48px", height: "48px", objectFit: "cover", borderRadius: "4px", flexShrink: 0 }
|
|
688
658
|
}
|
|
689
659
|
),
|
|
690
|
-
/* @__PURE__ */ (0,
|
|
691
|
-
/* @__PURE__ */ (0,
|
|
660
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: value }) }),
|
|
661
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Button, { variant: "ghost", colorPalette: "critical", size: "xs", onPress: () => onChange(""), children: "Remove" })
|
|
692
662
|
]
|
|
693
663
|
}
|
|
694
|
-
) : /* @__PURE__ */ (0,
|
|
695
|
-
/* @__PURE__ */ (0,
|
|
696
|
-
/* @__PURE__ */ (0,
|
|
697
|
-
/* @__PURE__ */ (0,
|
|
664
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { fontSize: "sm", color: "neutral.11", children: "No image selected" }),
|
|
665
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_nimbus2.Stack, { direction: "row", gap: "200", children: [
|
|
666
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Button, { variant: "outline", onPress: () => setShowUpload(true), children: "Upload" }),
|
|
667
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Button, { variant: "solid", onPress: openLibrary, children: "Media Library" })
|
|
698
668
|
] }),
|
|
699
|
-
showUpload && /* @__PURE__ */ (0,
|
|
669
|
+
showUpload && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
700
670
|
UploadModal,
|
|
701
671
|
{
|
|
702
672
|
uploading,
|
|
@@ -706,7 +676,7 @@ var ImagePickerField = ({
|
|
|
706
676
|
onClose: () => setShowUpload(false)
|
|
707
677
|
}
|
|
708
678
|
),
|
|
709
|
-
showLibrary && /* @__PURE__ */ (0,
|
|
679
|
+
showLibrary && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
710
680
|
LibraryModal,
|
|
711
681
|
{
|
|
712
682
|
files,
|
|
@@ -719,11 +689,11 @@ var ImagePickerField = ({
|
|
|
719
689
|
onClose: () => setShowLibrary(false)
|
|
720
690
|
}
|
|
721
691
|
)
|
|
722
|
-
] });
|
|
692
|
+
] }) });
|
|
723
693
|
};
|
|
724
694
|
|
|
725
695
|
// src/context/ImagePickerProvider.tsx
|
|
726
|
-
var
|
|
696
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
727
697
|
var ImagePickerProvider = ({
|
|
728
698
|
children,
|
|
729
699
|
baseURL,
|
|
@@ -731,7 +701,7 @@ var ImagePickerProvider = ({
|
|
|
731
701
|
businessUnitKey,
|
|
732
702
|
jwtToken
|
|
733
703
|
}) => {
|
|
734
|
-
return /* @__PURE__ */ (0,
|
|
704
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
735
705
|
ImagePickerContext.Provider,
|
|
736
706
|
{
|
|
737
707
|
value: { baseURL, projectKey, businessUnitKey, jwtToken },
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/ImagePickerField.tsx","../src/hooks/useMediaLibrary.ts","../src/api/media-library.api.ts","../src/context/ImagePickerContext.tsx","../src/context/ImagePickerProvider.tsx"],"sourcesContent":["export { ImagePickerField } from './ImagePickerField';\nexport type { ImagePickerFieldProps } from './ImagePickerField';\n\nexport { ImagePickerProvider } from './context/ImagePickerProvider';\nexport type { ImagePickerProviderProps } from './context/ImagePickerProvider';\nexport type { ImagePickerConfig } from './context/ImagePickerContext';\n\nexport { useMediaLibrary } from './hooks/useMediaLibrary';\nexport type { UseMediaLibraryReturn } from './hooks/useMediaLibrary';\n\nexport type { MediaFile, MediaLibraryPagination, MediaLibraryResult } from './types';\n","import React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMediaLibrary } from './hooks/useMediaLibrary';\nimport type { MediaFile } from './types';\nimport PrimaryButton from '@commercetools-uikit/primary-button';\nimport SecondaryButton from '@commercetools-uikit/secondary-button';\nimport FlatButton from '@commercetools-uikit/flat-button';\nimport SecondaryIconButton from '@commercetools-uikit/secondary-icon-button';\nimport TextInput from '@commercetools-uikit/text-input';\nimport Label from '@commercetools-uikit/label';\nimport LoadingSpinner from '@commercetools-uikit/loading-spinner';\nimport Spacings from '@commercetools-uikit/spacings';\nimport Text from '@commercetools-uikit/text';\nimport { CloseIcon } from '@commercetools-uikit/icons';\n\n// ---------------------------------------------------------------------------\n// Upload modal\n// ---------------------------------------------------------------------------\n\ninterface UploadModalProps {\n uploading: boolean;\n error: string | null;\n imagesOnly: boolean;\n onUpload: (file: File, title: string, description: string) => void;\n onClose: () => void;\n}\n\nconst UploadModal: React.FC<UploadModalProps> = ({\n uploading,\n error,\n imagesOnly,\n onUpload,\n onClose,\n}) => {\n const [file, setFile] = useState<File | null>(null);\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFile = (f: File) => {\n setFile(f);\n if (!title) setTitle(f.name);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = e.dataTransfer.files[0];\n if (f) handleFile(f);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text.Subheadline as=\"h4\" isBold>Upload a file</Text.Subheadline>\n <SecondaryIconButton\n icon={<CloseIcon />}\n label=\"Close\"\n onClick={onClose}\n size=\"small\"\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n <Spacings.Stack scale=\"m\">\n <Spacings.Stack scale=\"xs\">\n <Label htmlFor=\"upload-title\">Title</Label>\n <TextInput\n id=\"upload-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"File title\"\n />\n </Spacings.Stack>\n <Spacings.Stack scale=\"xs\">\n <Label htmlFor=\"upload-description\">Description</Label>\n <TextInput\n id=\"upload-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n />\n </Spacings.Stack>\n <div\n style={{\n border: dragging ? '2px dashed #3b82f6' : '2px dashed #d1d5db',\n borderRadius: '6px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n color: dragging ? '#3b82f6' : '#6b7280',\n fontSize: '13px',\n transition: 'border-color .2s',\n }}\n onClick={() => inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n >\n {file ? (\n <>\n <div>π {file.name}</div>\n <div style={{ fontSize: '11px', marginTop: '4px', color: '#9ca3af' }}>\n {(file.size / 1024).toFixed(0)} KB\n </div>\n </>\n ) : (\n <div>π Click or drag & drop to select a file</div>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={imagesOnly ? 'image/*' : '*/*'}\n style={{ display: 'none' }}\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) handleFile(f);\n }}\n />\n </div>\n {error && <Text.Body tone=\"negative\">{error}</Text.Body>}\n </Spacings.Stack>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text.Detail tone=\"secondary\" truncate>\n {file?.name ?? 'No file selected'}\n </Text.Detail>\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Cancel\" onClick={onClose} />\n <PrimaryButton\n label={uploading ? 'Uploadingβ¦' : 'Upload'}\n isDisabled={!file || uploading}\n onClick={() => file && onUpload(file, title, description)}\n />\n </Spacings.Inline>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Library modal\n// ---------------------------------------------------------------------------\n\ninterface LibraryModalProps {\n files: MediaFile[];\n pagination: { currentPage: number; totalPages: number };\n loading: boolean;\n error: string | null;\n onNextPage: () => void;\n onPrevPage: () => void;\n onSelect: (file: MediaFile) => void;\n onClose: () => void;\n}\n\nconst LibraryModal: React.FC<LibraryModalProps> = ({\n files,\n pagination,\n loading,\n error,\n onNextPage,\n onPrevPage,\n onSelect,\n onClose,\n}) => {\n const [selected, setSelected] = useState<MediaFile | null>(null);\n\n const handleConfirm = () => {\n if (selected) onSelect(selected);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text.Subheadline as=\"h4\" isBold>Select from Media Library</Text.Subheadline>\n <SecondaryIconButton\n icon={<CloseIcon />}\n label=\"Close\"\n onClick={onClose}\n size=\"small\"\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n {loading ? (\n <div style={{ display: 'flex', justifyContent: 'center', padding: '32px' }}>\n <LoadingSpinner />\n </div>\n ) : files.length === 0 ? (\n <Text.Body tone=\"secondary\">No files found.</Text.Body>\n ) : (\n <Spacings.Stack scale=\"m\">\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))',\n gap: '12px',\n }}\n >\n {files.map((file) => (\n <div\n key={file.url}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n border: `2px solid ${selected?.url === file.url ? '#3b82f6' : 'transparent'}`,\n borderRadius: '6px',\n padding: '6px',\n background: selected?.url === file.url ? 'rgba(59,130,246,0.07)' : '#f9fafb',\n }}\n onClick={() => setSelected(file)}\n title={file.title ?? file.name}\n >\n {file.isImage ? (\n <img\n src={file.url}\n alt={file.name}\n style={{ width: '80px', height: '80px', objectFit: 'cover', borderRadius: '4px', background: '#e5e7eb' }}\n />\n ) : (\n <div\n style={{\n width: '80px',\n height: '80px',\n borderRadius: '4px',\n background: '#e5e7eb',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '28px',\n }}\n >\n π\n </div>\n )}\n <div\n style={{\n marginTop: '6px',\n fontSize: '11px',\n textAlign: 'center',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: '#374151',\n }}\n >\n {file.title ?? file.name}\n </div>\n </div>\n ))}\n </div>\n\n {pagination.totalPages > 1 && (\n <Spacings.Inline alignItems=\"center\" justifyContent=\"center\" scale=\"s\">\n <SecondaryButton\n label=\"β Prev\"\n isDisabled={pagination.currentPage <= 1}\n onClick={onPrevPage}\n size=\"small\"\n />\n <Text.Detail tone=\"secondary\">\n {pagination.currentPage} / {pagination.totalPages}\n </Text.Detail>\n <SecondaryButton\n label=\"Next β\"\n isDisabled={pagination.currentPage >= pagination.totalPages}\n onClick={onNextPage}\n size=\"small\"\n />\n </Spacings.Inline>\n )}\n </Spacings.Stack>\n )}\n {error && <Text.Body tone=\"negative\">{error}</Text.Body>}\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text.Detail tone=\"secondary\" truncate>\n {selected ? (selected.title ?? selected.name) : 'Nothing selected'}\n </Text.Detail>\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Cancel\" onClick={onClose} />\n <PrimaryButton\n label=\"Select\"\n isDisabled={!selected}\n onClick={handleConfirm}\n />\n </Spacings.Inline>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// ImagePickerField β standalone field component\n// ---------------------------------------------------------------------------\n\nexport interface ImagePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n /** Only show images (default: true) */\n imagesOnly?: boolean;\n}\n\nexport const ImagePickerField: React.FC<ImagePickerFieldProps> = ({\n value,\n onChange,\n imagesOnly = true,\n}) => {\n const {\n files,\n pagination,\n loading,\n uploading,\n error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n } = useMediaLibrary();\n\n const [showUpload, setShowUpload] = useState(false);\n const [showLibrary, setShowLibrary] = useState(false);\n\n const extensions = imagesOnly ? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'] : [];\n\n const openLibrary = useCallback(() => {\n void fetchMedia(extensions, 1, 20);\n setShowLibrary(true);\n }, [fetchMedia, extensions]);\n\n const handleUpload = useCallback(\n async (file: File, title: string, description: string) => {\n const mediaFile = await uploadFile(file, title, description);\n onChange(mediaFile.url);\n setShowUpload(false);\n },\n [uploadFile, onChange]\n );\n\n const handleSelect = useCallback(\n (file: MediaFile) => {\n onChange(file.url);\n setShowLibrary(false);\n },\n [onChange]\n );\n\n // Close modals on Escape\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setShowUpload(false);\n setShowLibrary(false);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return (\n <Spacings.Stack scale=\"s\">\n {value ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '8px',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n background: '#f9fafb',\n }}\n >\n <img\n src={value}\n alt=\"\"\n style={{ width: '48px', height: '48px', objectFit: 'cover', borderRadius: '4px', flexShrink: 0 }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <Text.Detail tone=\"secondary\" truncate>{value}</Text.Detail>\n </div>\n <FlatButton tone=\"critical\" label=\"Remove\" onClick={() => onChange('')} />\n </div>\n ) : (\n <Text.Detail tone=\"secondary\">No image selected</Text.Detail>\n )}\n\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Upload\" onClick={() => setShowUpload(true)} />\n <PrimaryButton label=\"Media Library\" onClick={openLibrary} />\n </Spacings.Inline>\n\n {showUpload && (\n <UploadModal\n uploading={uploading}\n error={error}\n imagesOnly={imagesOnly}\n onUpload={(file, title, desc) => void handleUpload(file, title, desc)}\n onClose={() => setShowUpload(false)}\n />\n )}\n\n {showLibrary && (\n <LibraryModal\n files={files}\n pagination={pagination}\n loading={loading}\n error={error}\n onNextPage={() => void loadNextPage(extensions)}\n onPrevPage={() => void loadPreviousPage(extensions)}\n onSelect={handleSelect}\n onClose={() => setShowLibrary(false)}\n />\n )}\n </Spacings.Stack>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type {\n MediaFile,\n MediaLibraryPagination,\n} from '../types';\nimport {\n fetchMediaLibraryApi,\n uploadMediaFileApi,\n} from '../api/media-library.api';\nimport { useImagePickerContext } from '../context/ImagePickerContext';\n\ninterface MediaLibraryState {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n}\n\nconst initialPagination: MediaLibraryPagination = {\n totalItems: 0,\n totalPages: 0,\n currentPage: 1,\n limit: 20,\n};\n\nexport interface UseMediaLibraryReturn {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n fetchMedia: (\n extensions?: string[],\n page?: number,\n limit?: number\n ) => Promise<void>;\n uploadFile: (\n file: File,\n title?: string,\n description?: string\n ) => Promise<MediaFile>;\n loadNextPage: (extensions?: string[]) => Promise<void>;\n loadPreviousPage: (extensions?: string[]) => Promise<void>;\n hasNextPage: () => boolean;\n hasPreviousPage: () => boolean;\n}\n\nexport const useMediaLibrary = (): UseMediaLibraryReturn => {\n const { baseURL, projectKey, businessUnitKey, jwtToken } =\n useImagePickerContext();\n\n const [state, setState] = useState<MediaLibraryState>({\n files: [],\n pagination: initialPagination,\n loading: false,\n uploading: false,\n error: null,\n });\n\n const fetchMedia = useCallback(\n async (\n extensions: string[] = [],\n page = 1,\n limit = 20\n ): Promise<void> => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const result = await fetchMediaLibraryApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n extensions,\n page,\n limit\n );\n setState((s) => ({\n ...s,\n files: result.files,\n pagination: result.pagination,\n loading: false,\n }));\n } catch (err) {\n setState((s) => ({\n ...s,\n loading: false,\n error: (err as Error).message,\n }));\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const uploadFile = useCallback(\n async (\n file: File,\n title?: string,\n description?: string\n ): Promise<MediaFile> => {\n if (!jwtToken) throw new Error('jwtToken is required to upload files');\n setState((s) => ({ ...s, uploading: true, error: null }));\n try {\n const result = await uploadMediaFileApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n file,\n title,\n description\n );\n const mediaFile: MediaFile = {\n url: result.url,\n name: file.name,\n title: title ?? file.name,\n description,\n isImage: file.type.startsWith('image/'),\n createdAt: new Date().toISOString(),\n size: file.size,\n };\n setState((s) => ({\n ...s,\n files: [mediaFile, ...s.files],\n pagination: {\n ...s.pagination,\n totalItems: s.pagination.totalItems + 1,\n },\n uploading: false,\n }));\n return mediaFile;\n } catch (err) {\n setState((s) => ({\n ...s,\n uploading: false,\n error: (err as Error).message,\n }));\n throw err;\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const loadNextPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const next = state.pagination.currentPage + 1;\n if (next <= state.pagination.totalPages) {\n await fetchMedia(extensions, next, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const loadPreviousPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const prev = state.pagination.currentPage - 1;\n if (prev >= 1) {\n await fetchMedia(extensions, prev, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const hasNextPage = useCallback(\n () => state.pagination.currentPage < state.pagination.totalPages,\n [state.pagination]\n );\n\n const hasPreviousPage = useCallback(\n () => state.pagination.currentPage > 1,\n [state.pagination]\n );\n\n return {\n files: state.files,\n pagination: state.pagination,\n loading: state.loading,\n uploading: state.uploading,\n error: state.error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n hasNextPage,\n hasPreviousPage,\n };\n};\n","import type { MediaLibraryResult } from '../types';\n\n/**\n * Fetch media library files for a business unit.\n * Maps to GET /service/:businessUnitKey/media-library\n */\nexport const fetchMediaLibraryApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken?: string,\n extensions: string[] = [],\n page = 1,\n limit = 20\n): Promise<MediaLibraryResult> => {\n const params = new URLSearchParams();\n if (extensions.length > 0) params.set('extensions', extensions.join(','));\n params.set('page', String(page));\n params.set('limit', String(limit));\n\n const headers: Record<string, string> = {\n 'x-project-key': projectKey,\n };\n if (jwtToken) headers['Authorization'] = `Bearer ${jwtToken}`;\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/media-library?${params}`,\n { headers }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<MediaLibraryResult>;\n};\n\n/**\n * Upload a file for a business unit.\n * Maps to POST /service/:businessUnitKey/upload-file\n */\nexport const uploadMediaFileApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken: string,\n file: File,\n title?: string,\n description?: string\n): Promise<{ url: string }> => {\n const formData = new FormData();\n formData.append('file', file);\n if (title) formData.append('title', title);\n if (description) formData.append('description', description);\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/upload-file`,\n {\n method: 'POST',\n headers: {\n 'x-project-key': projectKey,\n Authorization: `Bearer ${jwtToken}`,\n },\n body: formData,\n }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<{ url: string }>;\n};\n","import { createContext, useContext } from 'react';\n\nexport interface ImagePickerConfig {\n baseURL: string;\n projectKey: string;\n businessUnitKey: string;\n jwtToken?: string;\n}\n\nexport const ImagePickerContext = createContext<ImagePickerConfig | null>(null);\n\nexport const useImagePickerContext = (): ImagePickerConfig => {\n const ctx = useContext(ImagePickerContext);\n if (!ctx) {\n throw new Error(\n 'useImagePickerContext must be used inside <ImagePickerProvider>. ' +\n 'Wrap your component tree with <ImagePickerProvider>.'\n );\n }\n return ctx;\n};\n","import React, { type ReactNode } from 'react';\nimport { ImagePickerContext, type ImagePickerConfig } from './ImagePickerContext';\n\nexport interface ImagePickerProviderProps extends ImagePickerConfig {\n children: ReactNode;\n}\n\nexport const ImagePickerProvider: React.FC<ImagePickerProviderProps> = ({\n children,\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n}) => {\n return (\n <ImagePickerContext.Provider\n value={{ baseURL, projectKey, businessUnitKey, jwtToken }}\n >\n {children}\n </ImagePickerContext.Provider>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAKO;;;ACLP,IAAAC,gBAAsC;;;ACM/B,IAAM,uBAAuB,OAClC,SACA,YACA,iBACA,UACA,aAAuB,CAAC,GACxB,OAAO,GACP,QAAQ,OACwB;AAChC,QAAM,SAAS,IAAI,gBAAgB;AACnC,MAAI,WAAW,SAAS,EAAG,QAAO,IAAI,cAAc,WAAW,KAAK,GAAG,CAAC;AACxE,SAAO,IAAI,QAAQ,OAAO,IAAI,CAAC;AAC/B,SAAO,IAAI,SAAS,OAAO,KAAK,CAAC;AAEjC,QAAM,UAAkC;AAAA,IACtC,iBAAiB;AAAA,EACnB;AACA,MAAI,SAAU,SAAQ,eAAe,IAAI,UAAU,QAAQ;AAE3D,QAAM,MAAM,MAAM;AAAA,IAChB,GAAG,OAAO,IAAI,eAAe,kBAAkB,MAAM;AAAA,IACrD,EAAE,QAAQ;AAAA,EACZ;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,IAAI,MAAM,4BAA4B,IAAI,MAAM,KAAK,QAAQ,IAAI,UAAU,EAAE;AAAA,EACrF;AACA,SAAO,IAAI,KAAK;AAClB;AAMO,IAAM,qBAAqB,OAChC,SACA,YACA,iBACA,UACA,MACA,OACA,gBAC6B;AAC7B,QAAM,WAAW,IAAI,SAAS;AAC9B,WAAS,OAAO,QAAQ,IAAI;AAC5B,MAAI,MAAO,UAAS,OAAO,SAAS,KAAK;AACzC,MAAI,YAAa,UAAS,OAAO,eAAe,WAAW;AAE3D,QAAM,MAAM,MAAM;AAAA,IAChB,GAAG,OAAO,IAAI,eAAe;AAAA,IAC7B;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,iBAAiB;AAAA,QACjB,eAAe,UAAU,QAAQ;AAAA,MACnC;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,IAAI,MAAM,4BAA4B,IAAI,MAAM,KAAK,QAAQ,IAAI,UAAU,EAAE;AAAA,EACrF;AACA,SAAO,IAAI,KAAK;AAClB;;;ACxEA,mBAA0C;AASnC,IAAM,yBAAqB,4BAAwC,IAAI;AAEvE,IAAM,wBAAwB,MAAyB;AAC5D,QAAM,UAAM,yBAAW,kBAAkB;AACzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AACA,SAAO;AACT;;;AFDA,IAAM,oBAA4C;AAAA,EAChD,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,OAAO;AACT;AAwBO,IAAM,kBAAkB,MAA6B;AAC1D,QAAM,EAAE,SAAS,YAAY,iBAAiB,SAAS,IACrD,sBAAsB;AAExB,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAA4B;AAAA,IACpD,OAAO,CAAC;AAAA,IACR,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,WAAW;AAAA,IACX,OAAO;AAAA,EACT,CAAC;AAED,QAAM,iBAAa;AAAA,IACjB,OACE,aAAuB,CAAC,GACxB,OAAO,GACP,QAAQ,OACU;AAClB,eAAS,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,MAAM,OAAO,KAAK,EAAE;AACtD,UAAI;AACF,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,iBAAS,CAAC,OAAO;AAAA,UACf,GAAG;AAAA,UACH,OAAO,OAAO;AAAA,UACd,YAAY,OAAO;AAAA,UACnB,SAAS;AAAA,QACX,EAAE;AAAA,MACJ,SAAS,KAAK;AACZ,iBAAS,CAAC,OAAO;AAAA,UACf,GAAG;AAAA,UACH,SAAS;AAAA,UACT,OAAQ,IAAc;AAAA,QACxB,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAC,SAAS,YAAY,iBAAiB,QAAQ;AAAA,EACjD;AAEA,QAAM,iBAAa;AAAA,IACjB,OACE,MACA,OACA,gBACuB;AACvB,UAAI,CAAC,SAAU,OAAM,IAAI,MAAM,sCAAsC;AACrE,eAAS,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,MAAM,OAAO,KAAK,EAAE;AACxD,UAAI;AACF,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,cAAM,YAAuB;AAAA,UAC3B,KAAK,OAAO;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,OAAO,SAAS,KAAK;AAAA,UACrB;AAAA,UACA,SAAS,KAAK,KAAK,WAAW,QAAQ;AAAA,UACtC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC,MAAM,KAAK;AAAA,QACb;AACA,iBAAS,CAAC,OAAO;AAAA,UACf,GAAG;AAAA,UACH,OAAO,CAAC,WAAW,GAAG,EAAE,KAAK;AAAA,UAC7B,YAAY;AAAA,YACV,GAAG,EAAE;AAAA,YACL,YAAY,EAAE,WAAW,aAAa;AAAA,UACxC;AAAA,UACA,WAAW;AAAA,QACb,EAAE;AACF,eAAO;AAAA,MACT,SAAS,KAAK;AACZ,iBAAS,CAAC,OAAO;AAAA,UACf,GAAG;AAAA,UACH,WAAW;AAAA,UACX,OAAQ,IAAc;AAAA,QACxB,EAAE;AACF,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC,SAAS,YAAY,iBAAiB,QAAQ;AAAA,EACjD;AAEA,QAAM,mBAAe;AAAA,IACnB,OAAO,aAAuB,CAAC,MAAqB;AAClD,YAAM,OAAO,MAAM,WAAW,cAAc;AAC5C,UAAI,QAAQ,MAAM,WAAW,YAAY;AACvC,cAAM,WAAW,YAAY,MAAM,MAAM,WAAW,KAAK;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,CAAC,YAAY,MAAM,UAAU;AAAA,EAC/B;AAEA,QAAM,uBAAmB;AAAA,IACvB,OAAO,aAAuB,CAAC,MAAqB;AAClD,YAAM,OAAO,MAAM,WAAW,cAAc;AAC5C,UAAI,QAAQ,GAAG;AACb,cAAM,WAAW,YAAY,MAAM,MAAM,WAAW,KAAK;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,CAAC,YAAY,MAAM,UAAU;AAAA,EAC/B;AAEA,QAAM,kBAAc;AAAA,IAClB,MAAM,MAAM,WAAW,cAAc,MAAM,WAAW;AAAA,IACtD,CAAC,MAAM,UAAU;AAAA,EACnB;AAEA,QAAM,sBAAkB;AAAA,IACtB,MAAM,MAAM,WAAW,cAAc;AAAA,IACrC,CAAC,MAAM,UAAU;AAAA,EACnB;AAEA,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,OAAO,MAAM;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADlLA,4BAA0B;AAC1B,8BAA4B;AAC5B,yBAAuB;AACvB,mCAAgC;AAChC,wBAAsB;AACtB,mBAAkB;AAClB,6BAA2B;AAC3B,sBAAqB;AACrB,kBAAiB;AACjB,mBAA0B;AAiElB;AAnDR,IAAM,cAA0C,CAAC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAsB,IAAI;AAClD,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAS,EAAE;AACrC,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,EAAE;AACjD,QAAM,CAAC,UAAU,WAAW,QAAI,wBAAS,KAAK;AAC9C,QAAM,eAAW,sBAAyB,IAAI;AAE9C,QAAM,aAAa,CAAC,MAAY;AAC9B,YAAQ,CAAC;AACT,QAAI,CAAC,MAAO,UAAS,EAAE,IAAI;AAAA,EAC7B;AAEA,QAAM,aAAa,CAAC,MAAuB;AACzC,MAAE,eAAe;AACjB,gBAAY,KAAK;AACjB,UAAM,IAAI,EAAE,aAAa,MAAM,CAAC;AAChC,QAAI,EAAG,YAAW,CAAC;AAAA,EACrB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,MACA,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,iBAAiB,QAAQ;AAAA,MAExD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,OAAO;AAAA,YACP,UAAU;AAAA,YACV,WAAW;AAAA,YACX,SAAS;AAAA,YACT,eAAe;AAAA,YACf,WAAW;AAAA,UACb;AAAA,UAGA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,SAAS;AAAA,kBACT,cAAc;AAAA,gBAChB;AAAA,gBAEA;AAAA,8DAAC,YAAAC,QAAK,aAAL,EAAiB,IAAG,MAAK,QAAM,MAAC,2BAAa;AAAA,kBAC9C;AAAA,oBAAC,6BAAAC;AAAA,oBAAA;AAAA,sBACC,MAAM,4CAAC,0BAAU;AAAA,sBACjB,OAAM;AAAA,sBACN,SAAS;AAAA,sBACT,MAAK;AAAA;AAAA,kBACP;AAAA;AAAA;AAAA,YACF;AAAA,YAGA,4CAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,QAAQ,SAAS,OAAO,GACvD,uDAAC,gBAAAC,QAAS,OAAT,EAAe,OAAM,KACpB;AAAA,2DAAC,gBAAAA,QAAS,OAAT,EAAe,OAAM,MACpB;AAAA,4DAAC,aAAAC,SAAA,EAAM,SAAQ,gBAAe,mBAAK;AAAA,gBACnC;AAAA,kBAAC,kBAAAC;AAAA,kBAAA;AAAA,oBACC,IAAG;AAAA,oBACH,OAAO;AAAA,oBACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,oBACxC,aAAY;AAAA;AAAA,gBACd;AAAA,iBACF;AAAA,cACA,6CAAC,gBAAAF,QAAS,OAAT,EAAe,OAAM,MACpB;AAAA,4DAAC,aAAAC,SAAA,EAAM,SAAQ,sBAAqB,yBAAW;AAAA,gBAC/C;AAAA,kBAAC,kBAAAC;AAAA,kBAAA;AAAA,oBACC,IAAG;AAAA,oBACH,OAAO;AAAA,oBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,oBAC9C,aAAY;AAAA;AAAA,gBACd;AAAA,iBACF;AAAA,cACA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ,WAAW,uBAAuB;AAAA,oBAC1C,cAAc;AAAA,oBACd,SAAS;AAAA,oBACT,WAAW;AAAA,oBACX,QAAQ;AAAA,oBACR,OAAO,WAAW,YAAY;AAAA,oBAC9B,UAAU;AAAA,oBACV,YAAY;AAAA,kBACd;AAAA,kBACA,SAAS,MAAM,SAAS,SAAS,MAAM;AAAA,kBACvC,YAAY,CAAC,MAAM;AAAE,sBAAE,eAAe;AAAG,gCAAY,IAAI;AAAA,kBAAG;AAAA,kBAC5D,aAAa,MAAM,YAAY,KAAK;AAAA,kBACpC,QAAQ;AAAA,kBAEP;AAAA,2BACC,4EACE;AAAA,mEAAC,SAAI;AAAA;AAAA,wBAAI,KAAK;AAAA,yBAAK;AAAA,sBACnB,6CAAC,SAAI,OAAO,EAAE,UAAU,QAAQ,WAAW,OAAO,OAAO,UAAU,GAC/D;AAAA,8BAAK,OAAO,MAAM,QAAQ,CAAC;AAAA,wBAAE;AAAA,yBACjC;AAAA,uBACF,IAEA,4CAAC,SAAI,6DAA4C;AAAA,oBAEnD;AAAA,sBAAC;AAAA;AAAA,wBACC,KAAK;AAAA,wBACL,MAAK;AAAA,wBACL,QAAQ,aAAa,YAAY;AAAA,wBACjC,OAAO,EAAE,SAAS,OAAO;AAAA,wBACzB,UAAU,CAAC,MAAM;AACf,gCAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AAC5B,8BAAI,EAAG,YAAW,CAAC;AAAA,wBACrB;AAAA;AAAA,oBACF;AAAA;AAAA;AAAA,cACF;AAAA,cACC,SAAS,4CAAC,YAAAJ,QAAK,MAAL,EAAU,MAAK,YAAY,iBAAM;AAAA,eAC9C,GACF;AAAA,YAGA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,gBAAgB;AAAA,kBAChB,YAAY;AAAA,kBACZ,SAAS;AAAA,kBACT,WAAW;AAAA,kBACX,KAAK;AAAA,gBACP;AAAA,gBAEA;AAAA,8DAAC,YAAAA,QAAK,QAAL,EAAY,MAAK,aAAY,UAAQ,MACnC,gBAAM,QAAQ,oBACjB;AAAA,kBACA,6CAAC,gBAAAE,QAAS,QAAT,EAAgB,OAAM,KACrB;AAAA,gEAAC,wBAAAG,SAAA,EAAgB,OAAM,UAAS,SAAS,SAAS;AAAA,oBAClD;AAAA,sBAAC,sBAAAC;AAAA,sBAAA;AAAA,wBACC,OAAO,YAAY,oBAAe;AAAA,wBAClC,YAAY,CAAC,QAAQ;AAAA,wBACrB,SAAS,MAAM,QAAQ,SAAS,MAAM,OAAO,WAAW;AAAA;AAAA,oBAC1D;AAAA,qBACF;AAAA;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAiBA,IAAM,eAA4C,CAAC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,UAAU,WAAW,QAAI,wBAA2B,IAAI;AAE/D,QAAM,gBAAgB,MAAM;AAC1B,QAAI,SAAU,UAAS,QAAQ;AAAA,EACjC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB;AAAA,MACA,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,iBAAiB,QAAQ;AAAA,MAExD;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,OAAO;AAAA,YACP,UAAU;AAAA,YACV,WAAW;AAAA,YACX,SAAS;AAAA,YACT,eAAe;AAAA,YACf,WAAW;AAAA,UACb;AAAA,UAGA;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,YAAY;AAAA,kBACZ,gBAAgB;AAAA,kBAChB,SAAS;AAAA,kBACT,cAAc;AAAA,gBAChB;AAAA,gBAEA;AAAA,8DAAC,YAAAN,QAAK,aAAL,EAAiB,IAAG,MAAK,QAAM,MAAC,uCAAyB;AAAA,kBAC1D;AAAA,oBAAC,6BAAAC;AAAA,oBAAA;AAAA,sBACC,MAAM,4CAAC,0BAAU;AAAA,sBACjB,OAAM;AAAA,sBACN,SAAS;AAAA,sBACT,MAAK;AAAA;AAAA,kBACP;AAAA;AAAA;AAAA,YACF;AAAA,YAGA,6CAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,QAAQ,SAAS,OAAO,GACtD;AAAA,wBACC,4CAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,gBAAgB,UAAU,SAAS,OAAO,GACvE,sDAAC,uBAAAM,SAAA,EAAe,GAClB,IACE,MAAM,WAAW,IACnB,4CAAC,YAAAP,QAAK,MAAL,EAAU,MAAK,aAAY,6BAAe,IAE3C,6CAAC,gBAAAE,QAAS,OAAT,EAAe,OAAM,KACpB;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,SAAS;AAAA,sBACT,qBAAqB;AAAA,sBACrB,KAAK;AAAA,oBACP;AAAA,oBAEC,gBAAM,IAAI,CAAC,SACV;AAAA,sBAAC;AAAA;AAAA,wBAEC,OAAO;AAAA,0BACL,SAAS;AAAA,0BACT,eAAe;AAAA,0BACf,YAAY;AAAA,0BACZ,QAAQ;AAAA,0BACR,QAAQ,aAAa,UAAU,QAAQ,KAAK,MAAM,YAAY,aAAa;AAAA,0BAC3E,cAAc;AAAA,0BACd,SAAS;AAAA,0BACT,YAAY,UAAU,QAAQ,KAAK,MAAM,0BAA0B;AAAA,wBACrE;AAAA,wBACA,SAAS,MAAM,YAAY,IAAI;AAAA,wBAC/B,OAAO,KAAK,SAAS,KAAK;AAAA,wBAEzB;AAAA,+BAAK,UACJ;AAAA,4BAAC;AAAA;AAAA,8BACC,KAAK,KAAK;AAAA,8BACV,KAAK,KAAK;AAAA,8BACV,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,SAAS,cAAc,OAAO,YAAY,UAAU;AAAA;AAAA,0BACzG,IAEA;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAO;AAAA,gCACL,OAAO;AAAA,gCACP,QAAQ;AAAA,gCACR,cAAc;AAAA,gCACd,YAAY;AAAA,gCACZ,SAAS;AAAA,gCACT,YAAY;AAAA,gCACZ,gBAAgB;AAAA,gCAChB,UAAU;AAAA,8BACZ;AAAA,8BACD;AAAA;AAAA,0BAED;AAAA,0BAEF;AAAA,4BAAC;AAAA;AAAA,8BACC,OAAO;AAAA,gCACL,WAAW;AAAA,gCACX,UAAU;AAAA,gCACV,WAAW;AAAA,gCACX,UAAU;AAAA,gCACV,UAAU;AAAA,gCACV,cAAc;AAAA,gCACd,YAAY;AAAA,gCACZ,OAAO;AAAA,8BACT;AAAA,8BAEC,eAAK,SAAS,KAAK;AAAA;AAAA,0BACtB;AAAA;AAAA;AAAA,sBAjDK,KAAK;AAAA,oBAkDZ,CACD;AAAA;AAAA,gBACH;AAAA,gBAEC,WAAW,aAAa,KACvB,6CAAC,gBAAAA,QAAS,QAAT,EAAgB,YAAW,UAAS,gBAAe,UAAS,OAAM,KACjE;AAAA;AAAA,oBAAC,wBAAAG;AAAA,oBAAA;AAAA,sBACC,OAAM;AAAA,sBACN,YAAY,WAAW,eAAe;AAAA,sBACtC,SAAS;AAAA,sBACT,MAAK;AAAA;AAAA,kBACP;AAAA,kBACA,6CAAC,YAAAL,QAAK,QAAL,EAAY,MAAK,aACf;AAAA,+BAAW;AAAA,oBAAY;AAAA,oBAAI,WAAW;AAAA,qBACzC;AAAA,kBACA;AAAA,oBAAC,wBAAAK;AAAA,oBAAA;AAAA,sBACC,OAAM;AAAA,sBACN,YAAY,WAAW,eAAe,WAAW;AAAA,sBACjD,SAAS;AAAA,sBACT,MAAK;AAAA;AAAA,kBACP;AAAA,mBACF;AAAA,iBAEJ;AAAA,cAED,SAAS,4CAAC,YAAAL,QAAK,MAAL,EAAU,MAAK,YAAY,iBAAM;AAAA,eAC9C;AAAA,YAGA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,kBACL,SAAS;AAAA,kBACT,gBAAgB;AAAA,kBAChB,YAAY;AAAA,kBACZ,SAAS;AAAA,kBACT,WAAW;AAAA,kBACX,KAAK;AAAA,gBACP;AAAA,gBAEA;AAAA,8DAAC,YAAAA,QAAK,QAAL,EAAY,MAAK,aAAY,UAAQ,MACnC,qBAAY,SAAS,SAAS,SAAS,OAAQ,oBAClD;AAAA,kBACA,6CAAC,gBAAAE,QAAS,QAAT,EAAgB,OAAM,KACrB;AAAA,gEAAC,wBAAAG,SAAA,EAAgB,OAAM,UAAS,SAAS,SAAS;AAAA,oBAClD;AAAA,sBAAC,sBAAAC;AAAA,sBAAA;AAAA,wBACC,OAAM;AAAA,wBACN,YAAY,CAAC;AAAA,wBACb,SAAS;AAAA;AAAA,oBACX;AAAA,qBACF;AAAA;AAAA;AAAA,YACF;AAAA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAaO,IAAM,mBAAoD,CAAC;AAAA,EAChE;AAAA,EACA;AAAA,EACA,aAAa;AACf,MAAM;AACJ,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,gBAAgB;AAEpB,QAAM,CAAC,YAAY,aAAa,QAAI,wBAAS,KAAK;AAClD,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAS,KAAK;AAEpD,QAAM,aAAa,aAAa,CAAC,OAAO,QAAQ,OAAO,OAAO,QAAQ,KAAK,IAAI,CAAC;AAEhF,QAAM,kBAAc,2BAAY,MAAM;AACpC,SAAK,WAAW,YAAY,GAAG,EAAE;AACjC,mBAAe,IAAI;AAAA,EACrB,GAAG,CAAC,YAAY,UAAU,CAAC;AAE3B,QAAM,mBAAe;AAAA,IACnB,OAAO,MAAY,OAAe,gBAAwB;AACxD,YAAM,YAAY,MAAM,WAAW,MAAM,OAAO,WAAW;AAC3D,eAAS,UAAU,GAAG;AACtB,oBAAc,KAAK;AAAA,IACrB;AAAA,IACA,CAAC,YAAY,QAAQ;AAAA,EACvB;AAEA,QAAM,mBAAe;AAAA,IACnB,CAAC,SAAoB;AACnB,eAAS,KAAK,GAAG;AACjB,qBAAe,KAAK;AAAA,IACtB;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAGA,+BAAU,MAAM;AACd,UAAM,QAAQ,CAAC,MAAqB;AAClC,UAAI,EAAE,QAAQ,UAAU;AACtB,sBAAc,KAAK;AACnB,uBAAe,KAAK;AAAA,MACtB;AAAA,IACF;AACA,WAAO,iBAAiB,WAAW,KAAK;AACxC,WAAO,MAAM,OAAO,oBAAoB,WAAW,KAAK;AAAA,EAC1D,GAAG,CAAC,CAAC;AAEL,SACE,6CAAC,gBAAAJ,QAAS,OAAT,EAAe,OAAM,KACnB;AAAA,YACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,UACL,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,KAAK;AAAA,UACL,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,YAAY;AAAA,QACd;AAAA,QAEA;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAI;AAAA,cACJ,OAAO,EAAE,OAAO,QAAQ,QAAQ,QAAQ,WAAW,SAAS,cAAc,OAAO,YAAY,EAAE;AAAA;AAAA,UACjG;AAAA,UACA,4CAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,GACjC,sDAAC,YAAAF,QAAK,QAAL,EAAY,MAAK,aAAY,UAAQ,MAAE,iBAAM,GAChD;AAAA,UACA,4CAAC,mBAAAQ,SAAA,EAAW,MAAK,YAAW,OAAM,UAAS,SAAS,MAAM,SAAS,EAAE,GAAG;AAAA;AAAA;AAAA,IAC1E,IAEA,4CAAC,YAAAR,QAAK,QAAL,EAAY,MAAK,aAAY,+BAAiB;AAAA,IAGjD,6CAAC,gBAAAE,QAAS,QAAT,EAAgB,OAAM,KACrB;AAAA,kDAAC,wBAAAG,SAAA,EAAgB,OAAM,UAAS,SAAS,MAAM,cAAc,IAAI,GAAG;AAAA,MACpE,4CAAC,sBAAAC,SAAA,EAAc,OAAM,iBAAgB,SAAS,aAAa;AAAA,OAC7D;AAAA,IAEC,cACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,CAAC,MAAM,OAAO,SAAS,KAAK,aAAa,MAAM,OAAO,IAAI;AAAA,QACpE,SAAS,MAAM,cAAc,KAAK;AAAA;AAAA,IACpC;AAAA,IAGD,eACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY,MAAM,KAAK,aAAa,UAAU;AAAA,QAC9C,YAAY,MAAM,KAAK,iBAAiB,UAAU;AAAA,QAClD,UAAU;AAAA,QACV,SAAS,MAAM,eAAe,KAAK;AAAA;AAAA,IACrC;AAAA,KAEJ;AAEJ;;;AInfI,IAAAG,sBAAA;AARG,IAAM,sBAA0D,CAAC;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,OAAO,EAAE,SAAS,YAAY,iBAAiB,SAAS;AAAA,MAEvD;AAAA;AAAA,EACH;AAEJ;","names":["import_react","import_react","Text","SecondaryIconButton","Spacings","Label","TextInput","SecondaryButton","PrimaryButton","LoadingSpinner","FlatButton","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/ImagePickerField.tsx","../src/hooks/useMediaLibrary.ts","../src/api/media-library.api.ts","../src/context/ImagePickerContext.tsx","../src/EnsureNimbusProvider.tsx","../src/context/ImagePickerProvider.tsx"],"sourcesContent":["export { ImagePickerField } from './ImagePickerField';\nexport type { ImagePickerFieldProps } from './ImagePickerField';\n\nexport { ImagePickerProvider } from './context/ImagePickerProvider';\nexport type { ImagePickerProviderProps } from './context/ImagePickerProvider';\nexport type { ImagePickerConfig } from './context/ImagePickerContext';\n\nexport { useMediaLibrary } from './hooks/useMediaLibrary';\nexport type { UseMediaLibraryReturn } from './hooks/useMediaLibrary';\n\nexport type { MediaFile, MediaLibraryPagination, MediaLibraryResult } from './types';\n","import React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMediaLibrary } from './hooks/useMediaLibrary';\nimport type { MediaFile } from './types';\nimport {\n Button,\n FormField,\n IconButton,\n LoadingSpinner,\n Stack,\n Text,\n TextInput,\n} from '@commercetools/nimbus';\nimport { Close } from '@commercetools/nimbus-icons';\nimport { EnsureNimbusProvider } from './EnsureNimbusProvider';\n\n// ---------------------------------------------------------------------------\n// Upload modal\n// ---------------------------------------------------------------------------\n\ninterface UploadModalProps {\n uploading: boolean;\n error: string | null;\n imagesOnly: boolean;\n onUpload: (file: File, title: string, description: string) => void;\n onClose: () => void;\n}\n\nconst UploadModal: React.FC<UploadModalProps> = ({\n uploading,\n error,\n imagesOnly,\n onUpload,\n onClose,\n}) => {\n const [file, setFile] = useState<File | null>(null);\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFile = (f: File) => {\n setFile(f);\n if (!title) setTitle(f.name);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = e.dataTransfer.files[0];\n if (f) handleFile(f);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text as=\"h4\" fontSize=\"xl\" fontWeight=\"700\">Upload a file</Text>\n <IconButton aria-label=\"Close\" variant=\"ghost\" size=\"xs\" onPress={onClose}>\n <Close />\n </IconButton>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n <Stack direction=\"column\" gap=\"400\">\n <FormField.Root>\n <FormField.Label>Title</FormField.Label>\n <FormField.Input>\n <TextInput\n value={title}\n onChange={(value) => setTitle(value)}\n placeholder=\"File title\"\n />\n </FormField.Input>\n </FormField.Root>\n <FormField.Root>\n <FormField.Label>Description</FormField.Label>\n <FormField.Input>\n <TextInput\n value={description}\n onChange={(value) => setDescription(value)}\n placeholder=\"Optional description\"\n />\n </FormField.Input>\n </FormField.Root>\n <div\n style={{\n border: dragging ? '2px dashed #3b82f6' : '2px dashed #d1d5db',\n borderRadius: '6px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n color: dragging ? '#3b82f6' : '#6b7280',\n fontSize: '13px',\n transition: 'border-color .2s',\n }}\n onClick={() => inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n >\n {file ? (\n <>\n <div>π {file.name}</div>\n <div style={{ fontSize: '11px', marginTop: '4px', color: '#9ca3af' }}>\n {(file.size / 1024).toFixed(0)} KB\n </div>\n </>\n ) : (\n <div>π Click or drag & drop to select a file</div>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={imagesOnly ? 'image/*' : '*/*'}\n style={{ display: 'none' }}\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) handleFile(f);\n }}\n />\n </div>\n {error && <Text color=\"critical.11\">{error}</Text>}\n </Stack>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>\n {file?.name ?? 'No file selected'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={onClose}>Cancel</Button>\n <Button\n variant=\"solid\"\n isDisabled={!file || uploading}\n onPress={() => file && onUpload(file, title, description)}\n >\n {uploading ? 'Uploadingβ¦' : 'Upload'}\n </Button>\n </Stack>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Library modal\n// ---------------------------------------------------------------------------\n\ninterface LibraryModalProps {\n files: MediaFile[];\n pagination: { currentPage: number; totalPages: number };\n loading: boolean;\n error: string | null;\n onNextPage: () => void;\n onPrevPage: () => void;\n onSelect: (file: MediaFile) => void;\n onClose: () => void;\n}\n\nconst LibraryModal: React.FC<LibraryModalProps> = ({\n files,\n pagination,\n loading,\n error,\n onNextPage,\n onPrevPage,\n onSelect,\n onClose,\n}) => {\n const [selected, setSelected] = useState<MediaFile | null>(null);\n\n const handleConfirm = () => {\n if (selected) onSelect(selected);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text as=\"h4\" fontSize=\"xl\" fontWeight=\"700\">Select from Media Library</Text>\n <IconButton aria-label=\"Close\" variant=\"ghost\" size=\"xs\" onPress={onClose}>\n <Close />\n </IconButton>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n {loading ? (\n <div style={{ display: 'flex', justifyContent: 'center', padding: '32px' }}>\n <LoadingSpinner />\n </div>\n ) : files.length === 0 ? (\n <Text color=\"neutral.11\">No files found.</Text>\n ) : (\n <Stack direction=\"column\" gap=\"400\">\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))',\n gap: '12px',\n }}\n >\n {files.map((file) => (\n <div\n key={file.url}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n border: `2px solid ${selected?.url === file.url ? '#3b82f6' : 'transparent'}`,\n borderRadius: '6px',\n padding: '6px',\n background: selected?.url === file.url ? 'rgba(59,130,246,0.07)' : '#f9fafb',\n }}\n onClick={() => setSelected(file)}\n title={file.title ?? file.name}\n >\n {file.isImage ? (\n <img\n src={file.url}\n alt={file.name}\n style={{ width: '80px', height: '80px', objectFit: 'cover', borderRadius: '4px', background: '#e5e7eb' }}\n />\n ) : (\n <div\n style={{\n width: '80px',\n height: '80px',\n borderRadius: '4px',\n background: '#e5e7eb',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '28px',\n }}\n >\n π\n </div>\n )}\n <div\n style={{\n marginTop: '6px',\n fontSize: '11px',\n textAlign: 'center',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: '#374151',\n }}\n >\n {file.title ?? file.name}\n </div>\n </div>\n ))}\n </div>\n\n {pagination.totalPages > 1 && (\n <Stack direction=\"row\" gap=\"200\" alignItems=\"center\" justifyContent=\"center\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n isDisabled={pagination.currentPage <= 1}\n onPress={onPrevPage}\n >\n β Prev\n </Button>\n <Text fontSize=\"sm\" color=\"neutral.11\">\n {pagination.currentPage} / {pagination.totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"sm\"\n isDisabled={pagination.currentPage >= pagination.totalPages}\n onPress={onNextPage}\n >\n Next β\n </Button>\n </Stack>\n )}\n </Stack>\n )}\n {error && <Text color=\"critical.11\">{error}</Text>}\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>\n {selected ? (selected.title ?? selected.name) : 'Nothing selected'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={onClose}>Cancel</Button>\n <Button variant=\"solid\" isDisabled={!selected} onPress={handleConfirm}>\n Select\n </Button>\n </Stack>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// ImagePickerField β standalone field component\n// ---------------------------------------------------------------------------\n\nexport interface ImagePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n /** Only show images (default: true) */\n imagesOnly?: boolean;\n}\n\nexport const ImagePickerField: React.FC<ImagePickerFieldProps> = ({\n value,\n onChange,\n imagesOnly = true,\n}) => {\n const {\n files,\n pagination,\n loading,\n uploading,\n error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n } = useMediaLibrary();\n\n const [showUpload, setShowUpload] = useState(false);\n const [showLibrary, setShowLibrary] = useState(false);\n\n const extensions = imagesOnly ? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'] : [];\n\n const openLibrary = useCallback(() => {\n void fetchMedia(extensions, 1, 20);\n setShowLibrary(true);\n }, [fetchMedia, extensions]);\n\n const handleUpload = useCallback(\n async (file: File, title: string, description: string) => {\n const mediaFile = await uploadFile(file, title, description);\n onChange(mediaFile.url);\n setShowUpload(false);\n },\n [uploadFile, onChange]\n );\n\n const handleSelect = useCallback(\n (file: MediaFile) => {\n onChange(file.url);\n setShowLibrary(false);\n },\n [onChange]\n );\n\n // Close modals on Escape\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setShowUpload(false);\n setShowLibrary(false);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return (\n <EnsureNimbusProvider>\n <Stack direction=\"column\" gap=\"200\">\n {value ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '8px',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n background: '#f9fafb',\n }}\n >\n <img\n src={value}\n alt=\"\"\n style={{ width: '48px', height: '48px', objectFit: 'cover', borderRadius: '4px', flexShrink: 0 }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>{value}</Text>\n </div>\n <Button variant=\"ghost\" colorPalette=\"critical\" size=\"xs\" onPress={() => onChange('')}>\n Remove\n </Button>\n </div>\n ) : (\n <Text fontSize=\"sm\" color=\"neutral.11\">No image selected</Text>\n )}\n\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={() => setShowUpload(true)}>Upload</Button>\n <Button variant=\"solid\" onPress={openLibrary}>Media Library</Button>\n </Stack>\n\n {showUpload && (\n <UploadModal\n uploading={uploading}\n error={error}\n imagesOnly={imagesOnly}\n onUpload={(file, title, desc) => void handleUpload(file, title, desc)}\n onClose={() => setShowUpload(false)}\n />\n )}\n\n {showLibrary && (\n <LibraryModal\n files={files}\n pagination={pagination}\n loading={loading}\n error={error}\n onNextPage={() => void loadNextPage(extensions)}\n onPrevPage={() => void loadPreviousPage(extensions)}\n onSelect={handleSelect}\n onClose={() => setShowLibrary(false)}\n />\n )}\n </Stack>\n </EnsureNimbusProvider>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type {\n MediaFile,\n MediaLibraryPagination,\n} from '../types';\nimport {\n fetchMediaLibraryApi,\n uploadMediaFileApi,\n} from '../api/media-library.api';\nimport { useImagePickerContext } from '../context/ImagePickerContext';\n\ninterface MediaLibraryState {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n}\n\nconst initialPagination: MediaLibraryPagination = {\n totalItems: 0,\n totalPages: 0,\n currentPage: 1,\n limit: 20,\n};\n\nexport interface UseMediaLibraryReturn {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n fetchMedia: (\n extensions?: string[],\n page?: number,\n limit?: number\n ) => Promise<void>;\n uploadFile: (\n file: File,\n title?: string,\n description?: string\n ) => Promise<MediaFile>;\n loadNextPage: (extensions?: string[]) => Promise<void>;\n loadPreviousPage: (extensions?: string[]) => Promise<void>;\n hasNextPage: () => boolean;\n hasPreviousPage: () => boolean;\n}\n\nexport const useMediaLibrary = (): UseMediaLibraryReturn => {\n const { baseURL, projectKey, businessUnitKey, jwtToken } =\n useImagePickerContext();\n\n const [state, setState] = useState<MediaLibraryState>({\n files: [],\n pagination: initialPagination,\n loading: false,\n uploading: false,\n error: null,\n });\n\n const fetchMedia = useCallback(\n async (\n extensions: string[] = [],\n page = 1,\n limit = 20\n ): Promise<void> => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const result = await fetchMediaLibraryApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n extensions,\n page,\n limit\n );\n setState((s) => ({\n ...s,\n files: result.files,\n pagination: result.pagination,\n loading: false,\n }));\n } catch (err) {\n setState((s) => ({\n ...s,\n loading: false,\n error: (err as Error).message,\n }));\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const uploadFile = useCallback(\n async (\n file: File,\n title?: string,\n description?: string\n ): Promise<MediaFile> => {\n if (!jwtToken) throw new Error('jwtToken is required to upload files');\n setState((s) => ({ ...s, uploading: true, error: null }));\n try {\n const result = await uploadMediaFileApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n file,\n title,\n description\n );\n const mediaFile: MediaFile = {\n url: result.url,\n name: file.name,\n title: title ?? file.name,\n description,\n isImage: file.type.startsWith('image/'),\n createdAt: new Date().toISOString(),\n size: file.size,\n };\n setState((s) => ({\n ...s,\n files: [mediaFile, ...s.files],\n pagination: {\n ...s.pagination,\n totalItems: s.pagination.totalItems + 1,\n },\n uploading: false,\n }));\n return mediaFile;\n } catch (err) {\n setState((s) => ({\n ...s,\n uploading: false,\n error: (err as Error).message,\n }));\n throw err;\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const loadNextPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const next = state.pagination.currentPage + 1;\n if (next <= state.pagination.totalPages) {\n await fetchMedia(extensions, next, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const loadPreviousPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const prev = state.pagination.currentPage - 1;\n if (prev >= 1) {\n await fetchMedia(extensions, prev, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const hasNextPage = useCallback(\n () => state.pagination.currentPage < state.pagination.totalPages,\n [state.pagination]\n );\n\n const hasPreviousPage = useCallback(\n () => state.pagination.currentPage > 1,\n [state.pagination]\n );\n\n return {\n files: state.files,\n pagination: state.pagination,\n loading: state.loading,\n uploading: state.uploading,\n error: state.error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n hasNextPage,\n hasPreviousPage,\n };\n};\n","import type { MediaLibraryResult } from '../types';\n\n/**\n * Fetch media library files for a business unit.\n * Maps to GET /service/:businessUnitKey/media-library\n */\nexport const fetchMediaLibraryApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken?: string,\n extensions: string[] = [],\n page = 1,\n limit = 20\n): Promise<MediaLibraryResult> => {\n const params = new URLSearchParams();\n if (extensions.length > 0) params.set('extensions', extensions.join(','));\n params.set('page', String(page));\n params.set('limit', String(limit));\n\n const headers: Record<string, string> = {\n 'x-project-key': projectKey,\n };\n if (jwtToken) headers['Authorization'] = `Bearer ${jwtToken}`;\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/media-library?${params}`,\n { headers }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<MediaLibraryResult>;\n};\n\n/**\n * Upload a file for a business unit.\n * Maps to POST /service/:businessUnitKey/upload-file\n */\nexport const uploadMediaFileApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken: string,\n file: File,\n title?: string,\n description?: string\n): Promise<{ url: string }> => {\n const formData = new FormData();\n formData.append('file', file);\n if (title) formData.append('title', title);\n if (description) formData.append('description', description);\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/upload-file`,\n {\n method: 'POST',\n headers: {\n 'x-project-key': projectKey,\n Authorization: `Bearer ${jwtToken}`,\n },\n body: formData,\n }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<{ url: string }>;\n};\n","import { createContext, useContext } from 'react';\n\nexport interface ImagePickerConfig {\n baseURL: string;\n projectKey: string;\n businessUnitKey: string;\n jwtToken?: string;\n}\n\nexport const ImagePickerContext = createContext<ImagePickerConfig | null>(null);\n\nexport const useImagePickerContext = (): ImagePickerConfig => {\n const ctx = useContext(ImagePickerContext);\n if (!ctx) {\n throw new Error(\n 'useImagePickerContext must be used inside <ImagePickerProvider>. ' +\n 'Wrap your component tree with <ImagePickerProvider>.'\n );\n }\n return ctx;\n};\n","import React, { type PropsWithChildren } from 'react';\nimport { NimbusProvider } from '@commercetools/nimbus';\n\n/**\n * Ensures a Nimbus context (theme + Chakra + React Aria i18n) exists for the\n * Nimbus components rendered by this package.\n *\n * NimbusProvider is safe to nest: locale overrides the nearest ancestor, color\n * mode is global, and the Inter font links are deduplicated across instances.\n * That lets this standalone field work on its own while still composing cleanly\n * when a host (e.g. the Puck editor) already mounted a provider.\n */\nexport const EnsureNimbusProvider: React.FC<PropsWithChildren<{ locale?: string }>> = ({\n locale = 'en',\n children,\n}) => <NimbusProvider locale={locale}>{children}</NimbusProvider>;\n","import React, { type ReactNode } from 'react';\nimport { ImagePickerContext, type ImagePickerConfig } from './ImagePickerContext';\n\nexport interface ImagePickerProviderProps extends ImagePickerConfig {\n children: ReactNode;\n}\n\nexport const ImagePickerProvider: React.FC<ImagePickerProviderProps> = ({\n children,\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n}) => {\n return (\n <ImagePickerContext.Provider\n value={{ baseURL, projectKey, businessUnitKey, jwtToken }}\n >\n {children}\n </ImagePickerContext.Provider>\n );\n};\n"],"mappings":"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","names":["import_react","import_react","import_nimbus","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -196,17 +196,27 @@ var useMediaLibrary = () => {
|
|
|
196
196
|
};
|
|
197
197
|
|
|
198
198
|
// src/ImagePickerField.tsx
|
|
199
|
-
import
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
import {
|
|
209
|
-
|
|
199
|
+
import {
|
|
200
|
+
Button,
|
|
201
|
+
FormField,
|
|
202
|
+
IconButton,
|
|
203
|
+
LoadingSpinner,
|
|
204
|
+
Stack,
|
|
205
|
+
Text,
|
|
206
|
+
TextInput
|
|
207
|
+
} from "@commercetools/nimbus";
|
|
208
|
+
import { Close } from "@commercetools/nimbus-icons";
|
|
209
|
+
|
|
210
|
+
// src/EnsureNimbusProvider.tsx
|
|
211
|
+
import { NimbusProvider } from "@commercetools/nimbus";
|
|
212
|
+
import { jsx } from "react/jsx-runtime";
|
|
213
|
+
var EnsureNimbusProvider = ({
|
|
214
|
+
locale = "en",
|
|
215
|
+
children
|
|
216
|
+
}) => /* @__PURE__ */ jsx(NimbusProvider, { locale, children });
|
|
217
|
+
|
|
218
|
+
// src/ImagePickerField.tsx
|
|
219
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
210
220
|
var UploadModal = ({
|
|
211
221
|
uploading,
|
|
212
222
|
error,
|
|
@@ -229,7 +239,7 @@ var UploadModal = ({
|
|
|
229
239
|
const f = e.dataTransfer.files[0];
|
|
230
240
|
if (f) handleFile(f);
|
|
231
241
|
};
|
|
232
|
-
return /* @__PURE__ */
|
|
242
|
+
return /* @__PURE__ */ jsx2(
|
|
233
243
|
"div",
|
|
234
244
|
{
|
|
235
245
|
style: {
|
|
@@ -267,43 +277,33 @@ var UploadModal = ({
|
|
|
267
277
|
borderBottom: "1px solid #e5e7eb"
|
|
268
278
|
},
|
|
269
279
|
children: [
|
|
270
|
-
/* @__PURE__ */
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
SecondaryIconButton,
|
|
273
|
-
{
|
|
274
|
-
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
275
|
-
label: "Close",
|
|
276
|
-
onClick: onClose,
|
|
277
|
-
size: "small"
|
|
278
|
-
}
|
|
279
|
-
)
|
|
280
|
+
/* @__PURE__ */ jsx2(Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Upload a file" }),
|
|
281
|
+
/* @__PURE__ */ jsx2(IconButton, { "aria-label": "Close", variant: "ghost", size: "xs", onPress: onClose, children: /* @__PURE__ */ jsx2(Close, {}) })
|
|
280
282
|
]
|
|
281
283
|
}
|
|
282
284
|
),
|
|
283
|
-
/* @__PURE__ */
|
|
284
|
-
/* @__PURE__ */ jsxs(
|
|
285
|
-
/* @__PURE__ */
|
|
286
|
-
/* @__PURE__ */
|
|
285
|
+
/* @__PURE__ */ jsx2("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ jsxs(Stack, { direction: "column", gap: "400", children: [
|
|
286
|
+
/* @__PURE__ */ jsxs(FormField.Root, { children: [
|
|
287
|
+
/* @__PURE__ */ jsx2(FormField.Label, { children: "Title" }),
|
|
288
|
+
/* @__PURE__ */ jsx2(FormField.Input, { children: /* @__PURE__ */ jsx2(
|
|
287
289
|
TextInput,
|
|
288
290
|
{
|
|
289
|
-
id: "upload-title",
|
|
290
291
|
value: title,
|
|
291
|
-
onChange: (
|
|
292
|
+
onChange: (value) => setTitle(value),
|
|
292
293
|
placeholder: "File title"
|
|
293
294
|
}
|
|
294
|
-
)
|
|
295
|
+
) })
|
|
295
296
|
] }),
|
|
296
|
-
/* @__PURE__ */ jsxs(
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
/* @__PURE__ */
|
|
297
|
+
/* @__PURE__ */ jsxs(FormField.Root, { children: [
|
|
298
|
+
/* @__PURE__ */ jsx2(FormField.Label, { children: "Description" }),
|
|
299
|
+
/* @__PURE__ */ jsx2(FormField.Input, { children: /* @__PURE__ */ jsx2(
|
|
299
300
|
TextInput,
|
|
300
301
|
{
|
|
301
|
-
id: "upload-description",
|
|
302
302
|
value: description,
|
|
303
|
-
onChange: (
|
|
303
|
+
onChange: (value) => setDescription(value),
|
|
304
304
|
placeholder: "Optional description"
|
|
305
305
|
}
|
|
306
|
-
)
|
|
306
|
+
) })
|
|
307
307
|
] }),
|
|
308
308
|
/* @__PURE__ */ jsxs(
|
|
309
309
|
"div",
|
|
@@ -335,8 +335,8 @@ var UploadModal = ({
|
|
|
335
335
|
(file.size / 1024).toFixed(0),
|
|
336
336
|
" KB"
|
|
337
337
|
] })
|
|
338
|
-
] }) : /* @__PURE__ */
|
|
339
|
-
/* @__PURE__ */
|
|
338
|
+
] }) : /* @__PURE__ */ jsx2("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
|
|
339
|
+
/* @__PURE__ */ jsx2(
|
|
340
340
|
"input",
|
|
341
341
|
{
|
|
342
342
|
ref: inputRef,
|
|
@@ -352,7 +352,7 @@ var UploadModal = ({
|
|
|
352
352
|
]
|
|
353
353
|
}
|
|
354
354
|
),
|
|
355
|
-
error && /* @__PURE__ */
|
|
355
|
+
error && /* @__PURE__ */ jsx2(Text, { color: "critical.11", children: error })
|
|
356
356
|
] }) }),
|
|
357
357
|
/* @__PURE__ */ jsxs(
|
|
358
358
|
"div",
|
|
@@ -366,15 +366,16 @@ var UploadModal = ({
|
|
|
366
366
|
gap: "12px"
|
|
367
367
|
},
|
|
368
368
|
children: [
|
|
369
|
-
/* @__PURE__ */
|
|
370
|
-
/* @__PURE__ */ jsxs(
|
|
371
|
-
/* @__PURE__ */
|
|
372
|
-
/* @__PURE__ */
|
|
373
|
-
|
|
369
|
+
/* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: file?.name ?? "No file selected" }),
|
|
370
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", children: [
|
|
371
|
+
/* @__PURE__ */ jsx2(Button, { variant: "outline", onPress: onClose, children: "Cancel" }),
|
|
372
|
+
/* @__PURE__ */ jsx2(
|
|
373
|
+
Button,
|
|
374
374
|
{
|
|
375
|
-
|
|
375
|
+
variant: "solid",
|
|
376
376
|
isDisabled: !file || uploading,
|
|
377
|
-
|
|
377
|
+
onPress: () => file && onUpload(file, title, description),
|
|
378
|
+
children: uploading ? "Uploading\u2026" : "Upload"
|
|
378
379
|
}
|
|
379
380
|
)
|
|
380
381
|
] })
|
|
@@ -401,7 +402,7 @@ var LibraryModal = ({
|
|
|
401
402
|
const handleConfirm = () => {
|
|
402
403
|
if (selected) onSelect(selected);
|
|
403
404
|
};
|
|
404
|
-
return /* @__PURE__ */
|
|
405
|
+
return /* @__PURE__ */ jsx2(
|
|
405
406
|
"div",
|
|
406
407
|
{
|
|
407
408
|
style: {
|
|
@@ -439,22 +440,14 @@ var LibraryModal = ({
|
|
|
439
440
|
borderBottom: "1px solid #e5e7eb"
|
|
440
441
|
},
|
|
441
442
|
children: [
|
|
442
|
-
/* @__PURE__ */
|
|
443
|
-
/* @__PURE__ */
|
|
444
|
-
SecondaryIconButton,
|
|
445
|
-
{
|
|
446
|
-
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
447
|
-
label: "Close",
|
|
448
|
-
onClick: onClose,
|
|
449
|
-
size: "small"
|
|
450
|
-
}
|
|
451
|
-
)
|
|
443
|
+
/* @__PURE__ */ jsx2(Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Select from Media Library" }),
|
|
444
|
+
/* @__PURE__ */ jsx2(IconButton, { "aria-label": "Close", variant: "ghost", size: "xs", onPress: onClose, children: /* @__PURE__ */ jsx2(Close, {}) })
|
|
452
445
|
]
|
|
453
446
|
}
|
|
454
447
|
),
|
|
455
448
|
/* @__PURE__ */ jsxs("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: [
|
|
456
|
-
loading ? /* @__PURE__ */
|
|
457
|
-
/* @__PURE__ */
|
|
449
|
+
loading ? /* @__PURE__ */ jsx2("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ jsx2(LoadingSpinner, {}) }) : files.length === 0 ? /* @__PURE__ */ jsx2(Text, { color: "neutral.11", children: "No files found." }) : /* @__PURE__ */ jsxs(Stack, { direction: "column", gap: "400", children: [
|
|
450
|
+
/* @__PURE__ */ jsx2(
|
|
458
451
|
"div",
|
|
459
452
|
{
|
|
460
453
|
style: {
|
|
@@ -478,14 +471,14 @@ var LibraryModal = ({
|
|
|
478
471
|
onClick: () => setSelected(file),
|
|
479
472
|
title: file.title ?? file.name,
|
|
480
473
|
children: [
|
|
481
|
-
file.isImage ? /* @__PURE__ */
|
|
474
|
+
file.isImage ? /* @__PURE__ */ jsx2(
|
|
482
475
|
"img",
|
|
483
476
|
{
|
|
484
477
|
src: file.url,
|
|
485
478
|
alt: file.name,
|
|
486
479
|
style: { width: "80px", height: "80px", objectFit: "cover", borderRadius: "4px", background: "#e5e7eb" }
|
|
487
480
|
}
|
|
488
|
-
) : /* @__PURE__ */
|
|
481
|
+
) : /* @__PURE__ */ jsx2(
|
|
489
482
|
"div",
|
|
490
483
|
{
|
|
491
484
|
style: {
|
|
@@ -501,7 +494,7 @@ var LibraryModal = ({
|
|
|
501
494
|
children: "\u{1F4C4}"
|
|
502
495
|
}
|
|
503
496
|
),
|
|
504
|
-
/* @__PURE__ */
|
|
497
|
+
/* @__PURE__ */ jsx2(
|
|
505
498
|
"div",
|
|
506
499
|
{
|
|
507
500
|
style: {
|
|
@@ -523,33 +516,35 @@ var LibraryModal = ({
|
|
|
523
516
|
))
|
|
524
517
|
}
|
|
525
518
|
),
|
|
526
|
-
pagination.totalPages > 1 && /* @__PURE__ */ jsxs(
|
|
527
|
-
/* @__PURE__ */
|
|
528
|
-
|
|
519
|
+
pagination.totalPages > 1 && /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", alignItems: "center", justifyContent: "center", children: [
|
|
520
|
+
/* @__PURE__ */ jsx2(
|
|
521
|
+
Button,
|
|
529
522
|
{
|
|
530
|
-
|
|
523
|
+
variant: "outline",
|
|
524
|
+
size: "sm",
|
|
531
525
|
isDisabled: pagination.currentPage <= 1,
|
|
532
|
-
|
|
533
|
-
|
|
526
|
+
onPress: onPrevPage,
|
|
527
|
+
children: "\u2190 Prev"
|
|
534
528
|
}
|
|
535
529
|
),
|
|
536
|
-
/* @__PURE__ */ jsxs(Text
|
|
530
|
+
/* @__PURE__ */ jsxs(Text, { fontSize: "sm", color: "neutral.11", children: [
|
|
537
531
|
pagination.currentPage,
|
|
538
532
|
" / ",
|
|
539
533
|
pagination.totalPages
|
|
540
534
|
] }),
|
|
541
|
-
/* @__PURE__ */
|
|
542
|
-
|
|
535
|
+
/* @__PURE__ */ jsx2(
|
|
536
|
+
Button,
|
|
543
537
|
{
|
|
544
|
-
|
|
538
|
+
variant: "outline",
|
|
539
|
+
size: "sm",
|
|
545
540
|
isDisabled: pagination.currentPage >= pagination.totalPages,
|
|
546
|
-
|
|
547
|
-
|
|
541
|
+
onPress: onNextPage,
|
|
542
|
+
children: "Next \u2192"
|
|
548
543
|
}
|
|
549
544
|
)
|
|
550
545
|
] })
|
|
551
546
|
] }),
|
|
552
|
-
error && /* @__PURE__ */
|
|
547
|
+
error && /* @__PURE__ */ jsx2(Text, { color: "critical.11", children: error })
|
|
553
548
|
] }),
|
|
554
549
|
/* @__PURE__ */ jsxs(
|
|
555
550
|
"div",
|
|
@@ -563,17 +558,10 @@ var LibraryModal = ({
|
|
|
563
558
|
gap: "12px"
|
|
564
559
|
},
|
|
565
560
|
children: [
|
|
566
|
-
/* @__PURE__ */
|
|
567
|
-
/* @__PURE__ */ jsxs(
|
|
568
|
-
/* @__PURE__ */
|
|
569
|
-
/* @__PURE__ */
|
|
570
|
-
PrimaryButton,
|
|
571
|
-
{
|
|
572
|
-
label: "Select",
|
|
573
|
-
isDisabled: !selected,
|
|
574
|
-
onClick: handleConfirm
|
|
575
|
-
}
|
|
576
|
-
)
|
|
561
|
+
/* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
|
|
562
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", children: [
|
|
563
|
+
/* @__PURE__ */ jsx2(Button, { variant: "outline", onPress: onClose, children: "Cancel" }),
|
|
564
|
+
/* @__PURE__ */ jsx2(Button, { variant: "solid", isDisabled: !selected, onPress: handleConfirm, children: "Select" })
|
|
577
565
|
] })
|
|
578
566
|
]
|
|
579
567
|
}
|
|
@@ -632,7 +620,7 @@ var ImagePickerField = ({
|
|
|
632
620
|
window.addEventListener("keydown", onKey);
|
|
633
621
|
return () => window.removeEventListener("keydown", onKey);
|
|
634
622
|
}, []);
|
|
635
|
-
return /* @__PURE__ */ jsxs(
|
|
623
|
+
return /* @__PURE__ */ jsx2(EnsureNimbusProvider, { children: /* @__PURE__ */ jsxs(Stack, { direction: "column", gap: "200", children: [
|
|
636
624
|
value ? /* @__PURE__ */ jsxs(
|
|
637
625
|
"div",
|
|
638
626
|
{
|
|
@@ -646,7 +634,7 @@ var ImagePickerField = ({
|
|
|
646
634
|
background: "#f9fafb"
|
|
647
635
|
},
|
|
648
636
|
children: [
|
|
649
|
-
/* @__PURE__ */
|
|
637
|
+
/* @__PURE__ */ jsx2(
|
|
650
638
|
"img",
|
|
651
639
|
{
|
|
652
640
|
src: value,
|
|
@@ -654,16 +642,16 @@ var ImagePickerField = ({
|
|
|
654
642
|
style: { width: "48px", height: "48px", objectFit: "cover", borderRadius: "4px", flexShrink: 0 }
|
|
655
643
|
}
|
|
656
644
|
),
|
|
657
|
-
/* @__PURE__ */
|
|
658
|
-
/* @__PURE__ */
|
|
645
|
+
/* @__PURE__ */ jsx2("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: value }) }),
|
|
646
|
+
/* @__PURE__ */ jsx2(Button, { variant: "ghost", colorPalette: "critical", size: "xs", onPress: () => onChange(""), children: "Remove" })
|
|
659
647
|
]
|
|
660
648
|
}
|
|
661
|
-
) : /* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */ jsxs(
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
649
|
+
) : /* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", children: "No image selected" }),
|
|
650
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", children: [
|
|
651
|
+
/* @__PURE__ */ jsx2(Button, { variant: "outline", onPress: () => setShowUpload(true), children: "Upload" }),
|
|
652
|
+
/* @__PURE__ */ jsx2(Button, { variant: "solid", onPress: openLibrary, children: "Media Library" })
|
|
665
653
|
] }),
|
|
666
|
-
showUpload && /* @__PURE__ */
|
|
654
|
+
showUpload && /* @__PURE__ */ jsx2(
|
|
667
655
|
UploadModal,
|
|
668
656
|
{
|
|
669
657
|
uploading,
|
|
@@ -673,7 +661,7 @@ var ImagePickerField = ({
|
|
|
673
661
|
onClose: () => setShowUpload(false)
|
|
674
662
|
}
|
|
675
663
|
),
|
|
676
|
-
showLibrary && /* @__PURE__ */
|
|
664
|
+
showLibrary && /* @__PURE__ */ jsx2(
|
|
677
665
|
LibraryModal,
|
|
678
666
|
{
|
|
679
667
|
files,
|
|
@@ -686,11 +674,11 @@ var ImagePickerField = ({
|
|
|
686
674
|
onClose: () => setShowLibrary(false)
|
|
687
675
|
}
|
|
688
676
|
)
|
|
689
|
-
] });
|
|
677
|
+
] }) });
|
|
690
678
|
};
|
|
691
679
|
|
|
692
680
|
// src/context/ImagePickerProvider.tsx
|
|
693
|
-
import { jsx as
|
|
681
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
694
682
|
var ImagePickerProvider = ({
|
|
695
683
|
children,
|
|
696
684
|
baseURL,
|
|
@@ -698,7 +686,7 @@ var ImagePickerProvider = ({
|
|
|
698
686
|
businessUnitKey,
|
|
699
687
|
jwtToken
|
|
700
688
|
}) => {
|
|
701
|
-
return /* @__PURE__ */
|
|
689
|
+
return /* @__PURE__ */ jsx3(
|
|
702
690
|
ImagePickerContext.Provider,
|
|
703
691
|
{
|
|
704
692
|
value: { baseURL, projectKey, businessUnitKey, jwtToken },
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ImagePickerField.tsx","../src/hooks/useMediaLibrary.ts","../src/api/media-library.api.ts","../src/context/ImagePickerContext.tsx","../src/context/ImagePickerProvider.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMediaLibrary } from './hooks/useMediaLibrary';\nimport type { MediaFile } from './types';\nimport PrimaryButton from '@commercetools-uikit/primary-button';\nimport SecondaryButton from '@commercetools-uikit/secondary-button';\nimport FlatButton from '@commercetools-uikit/flat-button';\nimport SecondaryIconButton from '@commercetools-uikit/secondary-icon-button';\nimport TextInput from '@commercetools-uikit/text-input';\nimport Label from '@commercetools-uikit/label';\nimport LoadingSpinner from '@commercetools-uikit/loading-spinner';\nimport Spacings from '@commercetools-uikit/spacings';\nimport Text from '@commercetools-uikit/text';\nimport { CloseIcon } from '@commercetools-uikit/icons';\n\n// ---------------------------------------------------------------------------\n// Upload modal\n// ---------------------------------------------------------------------------\n\ninterface UploadModalProps {\n uploading: boolean;\n error: string | null;\n imagesOnly: boolean;\n onUpload: (file: File, title: string, description: string) => void;\n onClose: () => void;\n}\n\nconst UploadModal: React.FC<UploadModalProps> = ({\n uploading,\n error,\n imagesOnly,\n onUpload,\n onClose,\n}) => {\n const [file, setFile] = useState<File | null>(null);\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFile = (f: File) => {\n setFile(f);\n if (!title) setTitle(f.name);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = e.dataTransfer.files[0];\n if (f) handleFile(f);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text.Subheadline as=\"h4\" isBold>Upload a file</Text.Subheadline>\n <SecondaryIconButton\n icon={<CloseIcon />}\n label=\"Close\"\n onClick={onClose}\n size=\"small\"\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n <Spacings.Stack scale=\"m\">\n <Spacings.Stack scale=\"xs\">\n <Label htmlFor=\"upload-title\">Title</Label>\n <TextInput\n id=\"upload-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"File title\"\n />\n </Spacings.Stack>\n <Spacings.Stack scale=\"xs\">\n <Label htmlFor=\"upload-description\">Description</Label>\n <TextInput\n id=\"upload-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n />\n </Spacings.Stack>\n <div\n style={{\n border: dragging ? '2px dashed #3b82f6' : '2px dashed #d1d5db',\n borderRadius: '6px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n color: dragging ? '#3b82f6' : '#6b7280',\n fontSize: '13px',\n transition: 'border-color .2s',\n }}\n onClick={() => inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n >\n {file ? (\n <>\n <div>π {file.name}</div>\n <div style={{ fontSize: '11px', marginTop: '4px', color: '#9ca3af' }}>\n {(file.size / 1024).toFixed(0)} KB\n </div>\n </>\n ) : (\n <div>π Click or drag & drop to select a file</div>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={imagesOnly ? 'image/*' : '*/*'}\n style={{ display: 'none' }}\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) handleFile(f);\n }}\n />\n </div>\n {error && <Text.Body tone=\"negative\">{error}</Text.Body>}\n </Spacings.Stack>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text.Detail tone=\"secondary\" truncate>\n {file?.name ?? 'No file selected'}\n </Text.Detail>\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Cancel\" onClick={onClose} />\n <PrimaryButton\n label={uploading ? 'Uploadingβ¦' : 'Upload'}\n isDisabled={!file || uploading}\n onClick={() => file && onUpload(file, title, description)}\n />\n </Spacings.Inline>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Library modal\n// ---------------------------------------------------------------------------\n\ninterface LibraryModalProps {\n files: MediaFile[];\n pagination: { currentPage: number; totalPages: number };\n loading: boolean;\n error: string | null;\n onNextPage: () => void;\n onPrevPage: () => void;\n onSelect: (file: MediaFile) => void;\n onClose: () => void;\n}\n\nconst LibraryModal: React.FC<LibraryModalProps> = ({\n files,\n pagination,\n loading,\n error,\n onNextPage,\n onPrevPage,\n onSelect,\n onClose,\n}) => {\n const [selected, setSelected] = useState<MediaFile | null>(null);\n\n const handleConfirm = () => {\n if (selected) onSelect(selected);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text.Subheadline as=\"h4\" isBold>Select from Media Library</Text.Subheadline>\n <SecondaryIconButton\n icon={<CloseIcon />}\n label=\"Close\"\n onClick={onClose}\n size=\"small\"\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n {loading ? (\n <div style={{ display: 'flex', justifyContent: 'center', padding: '32px' }}>\n <LoadingSpinner />\n </div>\n ) : files.length === 0 ? (\n <Text.Body tone=\"secondary\">No files found.</Text.Body>\n ) : (\n <Spacings.Stack scale=\"m\">\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))',\n gap: '12px',\n }}\n >\n {files.map((file) => (\n <div\n key={file.url}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n border: `2px solid ${selected?.url === file.url ? '#3b82f6' : 'transparent'}`,\n borderRadius: '6px',\n padding: '6px',\n background: selected?.url === file.url ? 'rgba(59,130,246,0.07)' : '#f9fafb',\n }}\n onClick={() => setSelected(file)}\n title={file.title ?? file.name}\n >\n {file.isImage ? (\n <img\n src={file.url}\n alt={file.name}\n style={{ width: '80px', height: '80px', objectFit: 'cover', borderRadius: '4px', background: '#e5e7eb' }}\n />\n ) : (\n <div\n style={{\n width: '80px',\n height: '80px',\n borderRadius: '4px',\n background: '#e5e7eb',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '28px',\n }}\n >\n π\n </div>\n )}\n <div\n style={{\n marginTop: '6px',\n fontSize: '11px',\n textAlign: 'center',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: '#374151',\n }}\n >\n {file.title ?? file.name}\n </div>\n </div>\n ))}\n </div>\n\n {pagination.totalPages > 1 && (\n <Spacings.Inline alignItems=\"center\" justifyContent=\"center\" scale=\"s\">\n <SecondaryButton\n label=\"β Prev\"\n isDisabled={pagination.currentPage <= 1}\n onClick={onPrevPage}\n size=\"small\"\n />\n <Text.Detail tone=\"secondary\">\n {pagination.currentPage} / {pagination.totalPages}\n </Text.Detail>\n <SecondaryButton\n label=\"Next β\"\n isDisabled={pagination.currentPage >= pagination.totalPages}\n onClick={onNextPage}\n size=\"small\"\n />\n </Spacings.Inline>\n )}\n </Spacings.Stack>\n )}\n {error && <Text.Body tone=\"negative\">{error}</Text.Body>}\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text.Detail tone=\"secondary\" truncate>\n {selected ? (selected.title ?? selected.name) : 'Nothing selected'}\n </Text.Detail>\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Cancel\" onClick={onClose} />\n <PrimaryButton\n label=\"Select\"\n isDisabled={!selected}\n onClick={handleConfirm}\n />\n </Spacings.Inline>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// ImagePickerField β standalone field component\n// ---------------------------------------------------------------------------\n\nexport interface ImagePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n /** Only show images (default: true) */\n imagesOnly?: boolean;\n}\n\nexport const ImagePickerField: React.FC<ImagePickerFieldProps> = ({\n value,\n onChange,\n imagesOnly = true,\n}) => {\n const {\n files,\n pagination,\n loading,\n uploading,\n error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n } = useMediaLibrary();\n\n const [showUpload, setShowUpload] = useState(false);\n const [showLibrary, setShowLibrary] = useState(false);\n\n const extensions = imagesOnly ? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'] : [];\n\n const openLibrary = useCallback(() => {\n void fetchMedia(extensions, 1, 20);\n setShowLibrary(true);\n }, [fetchMedia, extensions]);\n\n const handleUpload = useCallback(\n async (file: File, title: string, description: string) => {\n const mediaFile = await uploadFile(file, title, description);\n onChange(mediaFile.url);\n setShowUpload(false);\n },\n [uploadFile, onChange]\n );\n\n const handleSelect = useCallback(\n (file: MediaFile) => {\n onChange(file.url);\n setShowLibrary(false);\n },\n [onChange]\n );\n\n // Close modals on Escape\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setShowUpload(false);\n setShowLibrary(false);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return (\n <Spacings.Stack scale=\"s\">\n {value ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '8px',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n background: '#f9fafb',\n }}\n >\n <img\n src={value}\n alt=\"\"\n style={{ width: '48px', height: '48px', objectFit: 'cover', borderRadius: '4px', flexShrink: 0 }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <Text.Detail tone=\"secondary\" truncate>{value}</Text.Detail>\n </div>\n <FlatButton tone=\"critical\" label=\"Remove\" onClick={() => onChange('')} />\n </div>\n ) : (\n <Text.Detail tone=\"secondary\">No image selected</Text.Detail>\n )}\n\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Upload\" onClick={() => setShowUpload(true)} />\n <PrimaryButton label=\"Media Library\" onClick={openLibrary} />\n </Spacings.Inline>\n\n {showUpload && (\n <UploadModal\n uploading={uploading}\n error={error}\n imagesOnly={imagesOnly}\n onUpload={(file, title, desc) => void handleUpload(file, title, desc)}\n onClose={() => setShowUpload(false)}\n />\n )}\n\n {showLibrary && (\n <LibraryModal\n files={files}\n pagination={pagination}\n loading={loading}\n error={error}\n onNextPage={() => void loadNextPage(extensions)}\n onPrevPage={() => void loadPreviousPage(extensions)}\n onSelect={handleSelect}\n onClose={() => setShowLibrary(false)}\n />\n )}\n </Spacings.Stack>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type {\n MediaFile,\n MediaLibraryPagination,\n} from '../types';\nimport {\n fetchMediaLibraryApi,\n uploadMediaFileApi,\n} from '../api/media-library.api';\nimport { useImagePickerContext } from '../context/ImagePickerContext';\n\ninterface MediaLibraryState {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n}\n\nconst initialPagination: MediaLibraryPagination = {\n totalItems: 0,\n totalPages: 0,\n currentPage: 1,\n limit: 20,\n};\n\nexport interface UseMediaLibraryReturn {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n fetchMedia: (\n extensions?: string[],\n page?: number,\n limit?: number\n ) => Promise<void>;\n uploadFile: (\n file: File,\n title?: string,\n description?: string\n ) => Promise<MediaFile>;\n loadNextPage: (extensions?: string[]) => Promise<void>;\n loadPreviousPage: (extensions?: string[]) => Promise<void>;\n hasNextPage: () => boolean;\n hasPreviousPage: () => boolean;\n}\n\nexport const useMediaLibrary = (): UseMediaLibraryReturn => {\n const { baseURL, projectKey, businessUnitKey, jwtToken } =\n useImagePickerContext();\n\n const [state, setState] = useState<MediaLibraryState>({\n files: [],\n pagination: initialPagination,\n loading: false,\n uploading: false,\n error: null,\n });\n\n const fetchMedia = useCallback(\n async (\n extensions: string[] = [],\n page = 1,\n limit = 20\n ): Promise<void> => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const result = await fetchMediaLibraryApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n extensions,\n page,\n limit\n );\n setState((s) => ({\n ...s,\n files: result.files,\n pagination: result.pagination,\n loading: false,\n }));\n } catch (err) {\n setState((s) => ({\n ...s,\n loading: false,\n error: (err as Error).message,\n }));\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const uploadFile = useCallback(\n async (\n file: File,\n title?: string,\n description?: string\n ): Promise<MediaFile> => {\n if (!jwtToken) throw new Error('jwtToken is required to upload files');\n setState((s) => ({ ...s, uploading: true, error: null }));\n try {\n const result = await uploadMediaFileApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n file,\n title,\n description\n );\n const mediaFile: MediaFile = {\n url: result.url,\n name: file.name,\n title: title ?? file.name,\n description,\n isImage: file.type.startsWith('image/'),\n createdAt: new Date().toISOString(),\n size: file.size,\n };\n setState((s) => ({\n ...s,\n files: [mediaFile, ...s.files],\n pagination: {\n ...s.pagination,\n totalItems: s.pagination.totalItems + 1,\n },\n uploading: false,\n }));\n return mediaFile;\n } catch (err) {\n setState((s) => ({\n ...s,\n uploading: false,\n error: (err as Error).message,\n }));\n throw err;\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const loadNextPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const next = state.pagination.currentPage + 1;\n if (next <= state.pagination.totalPages) {\n await fetchMedia(extensions, next, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const loadPreviousPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const prev = state.pagination.currentPage - 1;\n if (prev >= 1) {\n await fetchMedia(extensions, prev, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const hasNextPage = useCallback(\n () => state.pagination.currentPage < state.pagination.totalPages,\n [state.pagination]\n );\n\n const hasPreviousPage = useCallback(\n () => state.pagination.currentPage > 1,\n [state.pagination]\n );\n\n return {\n files: state.files,\n pagination: state.pagination,\n loading: state.loading,\n uploading: state.uploading,\n error: state.error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n hasNextPage,\n hasPreviousPage,\n };\n};\n","import type { MediaLibraryResult } from '../types';\n\n/**\n * Fetch media library files for a business unit.\n * Maps to GET /service/:businessUnitKey/media-library\n */\nexport const fetchMediaLibraryApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken?: string,\n extensions: string[] = [],\n page = 1,\n limit = 20\n): Promise<MediaLibraryResult> => {\n const params = new URLSearchParams();\n if (extensions.length > 0) params.set('extensions', extensions.join(','));\n params.set('page', String(page));\n params.set('limit', String(limit));\n\n const headers: Record<string, string> = {\n 'x-project-key': projectKey,\n };\n if (jwtToken) headers['Authorization'] = `Bearer ${jwtToken}`;\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/media-library?${params}`,\n { headers }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<MediaLibraryResult>;\n};\n\n/**\n * Upload a file for a business unit.\n * Maps to POST /service/:businessUnitKey/upload-file\n */\nexport const uploadMediaFileApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken: string,\n file: File,\n title?: string,\n description?: string\n): Promise<{ url: string }> => {\n const formData = new FormData();\n formData.append('file', file);\n if (title) formData.append('title', title);\n if (description) formData.append('description', description);\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/upload-file`,\n {\n method: 'POST',\n headers: {\n 'x-project-key': projectKey,\n Authorization: `Bearer ${jwtToken}`,\n },\n body: formData,\n }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<{ url: string }>;\n};\n","import { createContext, useContext } from 'react';\n\nexport interface ImagePickerConfig {\n baseURL: string;\n projectKey: string;\n businessUnitKey: string;\n jwtToken?: string;\n}\n\nexport const ImagePickerContext = createContext<ImagePickerConfig | null>(null);\n\nexport const useImagePickerContext = (): ImagePickerConfig => {\n const ctx = useContext(ImagePickerContext);\n if (!ctx) {\n throw new Error(\n 'useImagePickerContext must be used inside <ImagePickerProvider>. ' +\n 'Wrap your component tree with <ImagePickerProvider>.'\n );\n }\n return ctx;\n};\n","import React, { type ReactNode } from 'react';\nimport { ImagePickerContext, type ImagePickerConfig } from './ImagePickerContext';\n\nexport interface ImagePickerProviderProps extends ImagePickerConfig {\n children: ReactNode;\n}\n\nexport const ImagePickerProvider: React.FC<ImagePickerProviderProps> = ({\n children,\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n}) => {\n return (\n <ImagePickerContext.Provider\n value={{ baseURL, projectKey, businessUnitKey, jwtToken }}\n >\n {children}\n </ImagePickerContext.Provider>\n );\n};\n"],"mappings":"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","names":["useCallback","useState","useState","useCallback","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/ImagePickerField.tsx","../src/hooks/useMediaLibrary.ts","../src/api/media-library.api.ts","../src/context/ImagePickerContext.tsx","../src/EnsureNimbusProvider.tsx","../src/context/ImagePickerProvider.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMediaLibrary } from './hooks/useMediaLibrary';\nimport type { MediaFile } from './types';\nimport {\n Button,\n FormField,\n IconButton,\n LoadingSpinner,\n Stack,\n Text,\n TextInput,\n} from '@commercetools/nimbus';\nimport { Close } from '@commercetools/nimbus-icons';\nimport { EnsureNimbusProvider } from './EnsureNimbusProvider';\n\n// ---------------------------------------------------------------------------\n// Upload modal\n// ---------------------------------------------------------------------------\n\ninterface UploadModalProps {\n uploading: boolean;\n error: string | null;\n imagesOnly: boolean;\n onUpload: (file: File, title: string, description: string) => void;\n onClose: () => void;\n}\n\nconst UploadModal: React.FC<UploadModalProps> = ({\n uploading,\n error,\n imagesOnly,\n onUpload,\n onClose,\n}) => {\n const [file, setFile] = useState<File | null>(null);\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFile = (f: File) => {\n setFile(f);\n if (!title) setTitle(f.name);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = e.dataTransfer.files[0];\n if (f) handleFile(f);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text as=\"h4\" fontSize=\"xl\" fontWeight=\"700\">Upload a file</Text>\n <IconButton aria-label=\"Close\" variant=\"ghost\" size=\"xs\" onPress={onClose}>\n <Close />\n </IconButton>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n <Stack direction=\"column\" gap=\"400\">\n <FormField.Root>\n <FormField.Label>Title</FormField.Label>\n <FormField.Input>\n <TextInput\n value={title}\n onChange={(value) => setTitle(value)}\n placeholder=\"File title\"\n />\n </FormField.Input>\n </FormField.Root>\n <FormField.Root>\n <FormField.Label>Description</FormField.Label>\n <FormField.Input>\n <TextInput\n value={description}\n onChange={(value) => setDescription(value)}\n placeholder=\"Optional description\"\n />\n </FormField.Input>\n </FormField.Root>\n <div\n style={{\n border: dragging ? '2px dashed #3b82f6' : '2px dashed #d1d5db',\n borderRadius: '6px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n color: dragging ? '#3b82f6' : '#6b7280',\n fontSize: '13px',\n transition: 'border-color .2s',\n }}\n onClick={() => inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n >\n {file ? (\n <>\n <div>π {file.name}</div>\n <div style={{ fontSize: '11px', marginTop: '4px', color: '#9ca3af' }}>\n {(file.size / 1024).toFixed(0)} KB\n </div>\n </>\n ) : (\n <div>π Click or drag & drop to select a file</div>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={imagesOnly ? 'image/*' : '*/*'}\n style={{ display: 'none' }}\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) handleFile(f);\n }}\n />\n </div>\n {error && <Text color=\"critical.11\">{error}</Text>}\n </Stack>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>\n {file?.name ?? 'No file selected'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={onClose}>Cancel</Button>\n <Button\n variant=\"solid\"\n isDisabled={!file || uploading}\n onPress={() => file && onUpload(file, title, description)}\n >\n {uploading ? 'Uploadingβ¦' : 'Upload'}\n </Button>\n </Stack>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Library modal\n// ---------------------------------------------------------------------------\n\ninterface LibraryModalProps {\n files: MediaFile[];\n pagination: { currentPage: number; totalPages: number };\n loading: boolean;\n error: string | null;\n onNextPage: () => void;\n onPrevPage: () => void;\n onSelect: (file: MediaFile) => void;\n onClose: () => void;\n}\n\nconst LibraryModal: React.FC<LibraryModalProps> = ({\n files,\n pagination,\n loading,\n error,\n onNextPage,\n onPrevPage,\n onSelect,\n onClose,\n}) => {\n const [selected, setSelected] = useState<MediaFile | null>(null);\n\n const handleConfirm = () => {\n if (selected) onSelect(selected);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text as=\"h4\" fontSize=\"xl\" fontWeight=\"700\">Select from Media Library</Text>\n <IconButton aria-label=\"Close\" variant=\"ghost\" size=\"xs\" onPress={onClose}>\n <Close />\n </IconButton>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n {loading ? (\n <div style={{ display: 'flex', justifyContent: 'center', padding: '32px' }}>\n <LoadingSpinner />\n </div>\n ) : files.length === 0 ? (\n <Text color=\"neutral.11\">No files found.</Text>\n ) : (\n <Stack direction=\"column\" gap=\"400\">\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))',\n gap: '12px',\n }}\n >\n {files.map((file) => (\n <div\n key={file.url}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n border: `2px solid ${selected?.url === file.url ? '#3b82f6' : 'transparent'}`,\n borderRadius: '6px',\n padding: '6px',\n background: selected?.url === file.url ? 'rgba(59,130,246,0.07)' : '#f9fafb',\n }}\n onClick={() => setSelected(file)}\n title={file.title ?? file.name}\n >\n {file.isImage ? (\n <img\n src={file.url}\n alt={file.name}\n style={{ width: '80px', height: '80px', objectFit: 'cover', borderRadius: '4px', background: '#e5e7eb' }}\n />\n ) : (\n <div\n style={{\n width: '80px',\n height: '80px',\n borderRadius: '4px',\n background: '#e5e7eb',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '28px',\n }}\n >\n π\n </div>\n )}\n <div\n style={{\n marginTop: '6px',\n fontSize: '11px',\n textAlign: 'center',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: '#374151',\n }}\n >\n {file.title ?? file.name}\n </div>\n </div>\n ))}\n </div>\n\n {pagination.totalPages > 1 && (\n <Stack direction=\"row\" gap=\"200\" alignItems=\"center\" justifyContent=\"center\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n isDisabled={pagination.currentPage <= 1}\n onPress={onPrevPage}\n >\n β Prev\n </Button>\n <Text fontSize=\"sm\" color=\"neutral.11\">\n {pagination.currentPage} / {pagination.totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"sm\"\n isDisabled={pagination.currentPage >= pagination.totalPages}\n onPress={onNextPage}\n >\n Next β\n </Button>\n </Stack>\n )}\n </Stack>\n )}\n {error && <Text color=\"critical.11\">{error}</Text>}\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>\n {selected ? (selected.title ?? selected.name) : 'Nothing selected'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={onClose}>Cancel</Button>\n <Button variant=\"solid\" isDisabled={!selected} onPress={handleConfirm}>\n Select\n </Button>\n </Stack>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// ImagePickerField β standalone field component\n// ---------------------------------------------------------------------------\n\nexport interface ImagePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n /** Only show images (default: true) */\n imagesOnly?: boolean;\n}\n\nexport const ImagePickerField: React.FC<ImagePickerFieldProps> = ({\n value,\n onChange,\n imagesOnly = true,\n}) => {\n const {\n files,\n pagination,\n loading,\n uploading,\n error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n } = useMediaLibrary();\n\n const [showUpload, setShowUpload] = useState(false);\n const [showLibrary, setShowLibrary] = useState(false);\n\n const extensions = imagesOnly ? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'] : [];\n\n const openLibrary = useCallback(() => {\n void fetchMedia(extensions, 1, 20);\n setShowLibrary(true);\n }, [fetchMedia, extensions]);\n\n const handleUpload = useCallback(\n async (file: File, title: string, description: string) => {\n const mediaFile = await uploadFile(file, title, description);\n onChange(mediaFile.url);\n setShowUpload(false);\n },\n [uploadFile, onChange]\n );\n\n const handleSelect = useCallback(\n (file: MediaFile) => {\n onChange(file.url);\n setShowLibrary(false);\n },\n [onChange]\n );\n\n // Close modals on Escape\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setShowUpload(false);\n setShowLibrary(false);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return (\n <EnsureNimbusProvider>\n <Stack direction=\"column\" gap=\"200\">\n {value ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '8px',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n background: '#f9fafb',\n }}\n >\n <img\n src={value}\n alt=\"\"\n style={{ width: '48px', height: '48px', objectFit: 'cover', borderRadius: '4px', flexShrink: 0 }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>{value}</Text>\n </div>\n <Button variant=\"ghost\" colorPalette=\"critical\" size=\"xs\" onPress={() => onChange('')}>\n Remove\n </Button>\n </div>\n ) : (\n <Text fontSize=\"sm\" color=\"neutral.11\">No image selected</Text>\n )}\n\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={() => setShowUpload(true)}>Upload</Button>\n <Button variant=\"solid\" onPress={openLibrary}>Media Library</Button>\n </Stack>\n\n {showUpload && (\n <UploadModal\n uploading={uploading}\n error={error}\n imagesOnly={imagesOnly}\n onUpload={(file, title, desc) => void handleUpload(file, title, desc)}\n onClose={() => setShowUpload(false)}\n />\n )}\n\n {showLibrary && (\n <LibraryModal\n files={files}\n pagination={pagination}\n loading={loading}\n error={error}\n onNextPage={() => void loadNextPage(extensions)}\n onPrevPage={() => void loadPreviousPage(extensions)}\n onSelect={handleSelect}\n onClose={() => setShowLibrary(false)}\n />\n )}\n </Stack>\n </EnsureNimbusProvider>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type {\n MediaFile,\n MediaLibraryPagination,\n} from '../types';\nimport {\n fetchMediaLibraryApi,\n uploadMediaFileApi,\n} from '../api/media-library.api';\nimport { useImagePickerContext } from '../context/ImagePickerContext';\n\ninterface MediaLibraryState {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n}\n\nconst initialPagination: MediaLibraryPagination = {\n totalItems: 0,\n totalPages: 0,\n currentPage: 1,\n limit: 20,\n};\n\nexport interface UseMediaLibraryReturn {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n fetchMedia: (\n extensions?: string[],\n page?: number,\n limit?: number\n ) => Promise<void>;\n uploadFile: (\n file: File,\n title?: string,\n description?: string\n ) => Promise<MediaFile>;\n loadNextPage: (extensions?: string[]) => Promise<void>;\n loadPreviousPage: (extensions?: string[]) => Promise<void>;\n hasNextPage: () => boolean;\n hasPreviousPage: () => boolean;\n}\n\nexport const useMediaLibrary = (): UseMediaLibraryReturn => {\n const { baseURL, projectKey, businessUnitKey, jwtToken } =\n useImagePickerContext();\n\n const [state, setState] = useState<MediaLibraryState>({\n files: [],\n pagination: initialPagination,\n loading: false,\n uploading: false,\n error: null,\n });\n\n const fetchMedia = useCallback(\n async (\n extensions: string[] = [],\n page = 1,\n limit = 20\n ): Promise<void> => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const result = await fetchMediaLibraryApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n extensions,\n page,\n limit\n );\n setState((s) => ({\n ...s,\n files: result.files,\n pagination: result.pagination,\n loading: false,\n }));\n } catch (err) {\n setState((s) => ({\n ...s,\n loading: false,\n error: (err as Error).message,\n }));\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const uploadFile = useCallback(\n async (\n file: File,\n title?: string,\n description?: string\n ): Promise<MediaFile> => {\n if (!jwtToken) throw new Error('jwtToken is required to upload files');\n setState((s) => ({ ...s, uploading: true, error: null }));\n try {\n const result = await uploadMediaFileApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n file,\n title,\n description\n );\n const mediaFile: MediaFile = {\n url: result.url,\n name: file.name,\n title: title ?? file.name,\n description,\n isImage: file.type.startsWith('image/'),\n createdAt: new Date().toISOString(),\n size: file.size,\n };\n setState((s) => ({\n ...s,\n files: [mediaFile, ...s.files],\n pagination: {\n ...s.pagination,\n totalItems: s.pagination.totalItems + 1,\n },\n uploading: false,\n }));\n return mediaFile;\n } catch (err) {\n setState((s) => ({\n ...s,\n uploading: false,\n error: (err as Error).message,\n }));\n throw err;\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const loadNextPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const next = state.pagination.currentPage + 1;\n if (next <= state.pagination.totalPages) {\n await fetchMedia(extensions, next, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const loadPreviousPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const prev = state.pagination.currentPage - 1;\n if (prev >= 1) {\n await fetchMedia(extensions, prev, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const hasNextPage = useCallback(\n () => state.pagination.currentPage < state.pagination.totalPages,\n [state.pagination]\n );\n\n const hasPreviousPage = useCallback(\n () => state.pagination.currentPage > 1,\n [state.pagination]\n );\n\n return {\n files: state.files,\n pagination: state.pagination,\n loading: state.loading,\n uploading: state.uploading,\n error: state.error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n hasNextPage,\n hasPreviousPage,\n };\n};\n","import type { MediaLibraryResult } from '../types';\n\n/**\n * Fetch media library files for a business unit.\n * Maps to GET /service/:businessUnitKey/media-library\n */\nexport const fetchMediaLibraryApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken?: string,\n extensions: string[] = [],\n page = 1,\n limit = 20\n): Promise<MediaLibraryResult> => {\n const params = new URLSearchParams();\n if (extensions.length > 0) params.set('extensions', extensions.join(','));\n params.set('page', String(page));\n params.set('limit', String(limit));\n\n const headers: Record<string, string> = {\n 'x-project-key': projectKey,\n };\n if (jwtToken) headers['Authorization'] = `Bearer ${jwtToken}`;\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/media-library?${params}`,\n { headers }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<MediaLibraryResult>;\n};\n\n/**\n * Upload a file for a business unit.\n * Maps to POST /service/:businessUnitKey/upload-file\n */\nexport const uploadMediaFileApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken: string,\n file: File,\n title?: string,\n description?: string\n): Promise<{ url: string }> => {\n const formData = new FormData();\n formData.append('file', file);\n if (title) formData.append('title', title);\n if (description) formData.append('description', description);\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/upload-file`,\n {\n method: 'POST',\n headers: {\n 'x-project-key': projectKey,\n Authorization: `Bearer ${jwtToken}`,\n },\n body: formData,\n }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<{ url: string }>;\n};\n","import { createContext, useContext } from 'react';\n\nexport interface ImagePickerConfig {\n baseURL: string;\n projectKey: string;\n businessUnitKey: string;\n jwtToken?: string;\n}\n\nexport const ImagePickerContext = createContext<ImagePickerConfig | null>(null);\n\nexport const useImagePickerContext = (): ImagePickerConfig => {\n const ctx = useContext(ImagePickerContext);\n if (!ctx) {\n throw new Error(\n 'useImagePickerContext must be used inside <ImagePickerProvider>. ' +\n 'Wrap your component tree with <ImagePickerProvider>.'\n );\n }\n return ctx;\n};\n","import React, { type PropsWithChildren } from 'react';\nimport { NimbusProvider } from '@commercetools/nimbus';\n\n/**\n * Ensures a Nimbus context (theme + Chakra + React Aria i18n) exists for the\n * Nimbus components rendered by this package.\n *\n * NimbusProvider is safe to nest: locale overrides the nearest ancestor, color\n * mode is global, and the Inter font links are deduplicated across instances.\n * That lets this standalone field work on its own while still composing cleanly\n * when a host (e.g. the Puck editor) already mounted a provider.\n */\nexport const EnsureNimbusProvider: React.FC<PropsWithChildren<{ locale?: string }>> = ({\n locale = 'en',\n children,\n}) => <NimbusProvider locale={locale}>{children}</NimbusProvider>;\n","import React, { type ReactNode } from 'react';\nimport { ImagePickerContext, type ImagePickerConfig } from './ImagePickerContext';\n\nexport interface ImagePickerProviderProps extends ImagePickerConfig {\n children: ReactNode;\n}\n\nexport const ImagePickerProvider: React.FC<ImagePickerProviderProps> = ({\n children,\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n}) => {\n return (\n <ImagePickerContext.Provider\n value={{ baseURL, projectKey, businessUnitKey, jwtToken }}\n >\n {children}\n </ImagePickerContext.Provider>\n );\n};\n"],"mappings":"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","names":["useCallback","useState","jsx","useState","useCallback","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-demo/puck-image-picker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Standalone ImagePickerField component with media library support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -25,30 +25,12 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@commercetools
|
|
29
|
-
"@commercetools-
|
|
30
|
-
"@commercetools-uikit/label": ">=20.0.0",
|
|
31
|
-
"@commercetools-uikit/loading-spinner": ">=20.0.0",
|
|
32
|
-
"@commercetools-uikit/primary-button": ">=20.0.0",
|
|
33
|
-
"@commercetools-uikit/secondary-button": ">=20.0.0",
|
|
34
|
-
"@commercetools-uikit/secondary-icon-button": ">=20.0.0",
|
|
35
|
-
"@commercetools-uikit/spacings": ">=20.0.0",
|
|
36
|
-
"@commercetools-uikit/text": ">=20.0.0",
|
|
37
|
-
"@commercetools-uikit/text-input": ">=20.0.0",
|
|
28
|
+
"@commercetools/nimbus": "^3.2.0",
|
|
29
|
+
"@commercetools/nimbus-icons": "^3.2.0",
|
|
38
30
|
"react": ">=19.0.0",
|
|
39
31
|
"react-dom": ">=19.0.0"
|
|
40
32
|
},
|
|
41
33
|
"devDependencies": {
|
|
42
|
-
"@commercetools-uikit/flat-button": "^20.5.0",
|
|
43
|
-
"@commercetools-uikit/icons": "^20.5.0",
|
|
44
|
-
"@commercetools-uikit/label": "^20.5.0",
|
|
45
|
-
"@commercetools-uikit/loading-spinner": "^20.5.0",
|
|
46
|
-
"@commercetools-uikit/primary-button": "^20.5.0",
|
|
47
|
-
"@commercetools-uikit/secondary-button": "^20.5.0",
|
|
48
|
-
"@commercetools-uikit/secondary-icon-button": "^20.5.0",
|
|
49
|
-
"@commercetools-uikit/spacings": "^20.5.0",
|
|
50
|
-
"@commercetools-uikit/text": "^20.5.0",
|
|
51
|
-
"@commercetools-uikit/text-input": "^20.5.0",
|
|
52
34
|
"@types/react": "^19",
|
|
53
35
|
"@types/react-dom": "^19",
|
|
54
36
|
"tsup": "^8.3.0",
|