@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 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 import_primary_button = __toESM(require("@commercetools-uikit/primary-button"));
233
- var import_secondary_button = __toESM(require("@commercetools-uikit/secondary-button"));
234
- var import_flat_button = __toESM(require("@commercetools-uikit/flat-button"));
235
- var import_secondary_icon_button = __toESM(require("@commercetools-uikit/secondary-icon-button"));
236
- var import_text_input = __toESM(require("@commercetools-uikit/text-input"));
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)(import_text.default.Subheadline, { as: "h4", isBold: true, children: "Upload a file" }),
304
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsx)("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Stack, { scale: "m", children: [
317
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Stack, { scale: "xs", children: [
318
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.default, { htmlFor: "upload-title", children: "Title" }),
319
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
320
- import_text_input.default,
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: (e) => setTitle(e.target.value),
307
+ onChange: (value) => setTitle(value),
325
308
  placeholder: "File title"
326
309
  }
327
- )
310
+ ) })
328
311
  ] }),
329
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Stack, { scale: "xs", children: [
330
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_label.default, { htmlFor: "upload-description", children: "Description" }),
331
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
332
- import_text_input.default,
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: (e) => setDescription(e.target.value),
318
+ onChange: (value) => setDescription(value),
337
319
  placeholder: "Optional description"
338
320
  }
339
- )
321
+ ) })
340
322
  ] }),
341
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
363
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
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, import_jsx_runtime.jsxs)("div", { style: { fontSize: "11px", marginTop: "4px", color: "#9ca3af" }, children: [
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, import_jsx_runtime.jsx)("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
372
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsx)(import_text.default.Body, { tone: "negative", children: error })
370
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { color: "critical.11", children: error })
389
371
  ] }) }),
390
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)(import_text.default.Detail, { tone: "secondary", truncate: true, children: file?.name ?? "No file selected" }),
403
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Inline, { scale: "s", children: [
404
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_secondary_button.default, { label: "Cancel", onClick: onClose }),
405
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
406
- import_primary_button.default,
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
- label: uploading ? "Uploading\u2026" : "Upload",
390
+ variant: "solid",
409
391
  isDisabled: !file || uploading,
410
- onClick: () => file && onUpload(file, title, description)
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)(import_text.default.Subheadline, { as: "h4", isBold: true, children: "Select from Media Library" }),
476
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsxs)("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: [
489
- loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_loading_spinner.default, {}) }) : files.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_text.default.Body, { tone: "secondary", children: "No files found." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Stack, { scale: "m", children: [
490
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsxs)(import_spacings.default.Inline, { alignItems: "center", justifyContent: "center", scale: "s", children: [
560
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
561
- import_secondary_button.default,
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
- label: "\u2190 Prev",
538
+ variant: "outline",
539
+ size: "sm",
564
540
  isDisabled: pagination.currentPage <= 1,
565
- onClick: onPrevPage,
566
- size: "small"
541
+ onPress: onPrevPage,
542
+ children: "\u2190 Prev"
567
543
  }
568
544
  ),
569
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_text.default.Detail, { tone: "secondary", children: [
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, import_jsx_runtime.jsx)(
575
- import_secondary_button.default,
550
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
551
+ import_nimbus2.Button,
576
552
  {
577
- label: "Next \u2192",
553
+ variant: "outline",
554
+ size: "sm",
578
555
  isDisabled: pagination.currentPage >= pagination.totalPages,
579
- onClick: onNextPage,
580
- size: "small"
556
+ onPress: onNextPage,
557
+ children: "Next \u2192"
581
558
  }
582
559
  )
583
560
  ] })
584
561
  ] }),
585
- error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_text.default.Body, { tone: "negative", children: error })
562
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_nimbus2.Text, { color: "critical.11", children: error })
586
563
  ] }),
587
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)(import_text.default.Detail, { tone: "secondary", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
600
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Inline, { scale: "s", children: [
601
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_secondary_button.default, { label: "Cancel", onClick: onClose }),
602
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsxs)(import_spacings.default.Stack, { scale: "s", children: [
669
- value ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsx)("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_text.default.Detail, { tone: "secondary", truncate: true, children: value }) }),
691
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_flat_button.default, { tone: "critical", label: "Remove", onClick: () => onChange("") })
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, import_jsx_runtime.jsx)(import_text.default.Detail, { tone: "secondary", children: "No image selected" }),
695
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_spacings.default.Inline, { scale: "s", children: [
696
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_secondary_button.default, { label: "Upload", onClick: () => setShowUpload(true) }),
697
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_primary_button.default, { label: "Media Library", onClick: openLibrary })
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, import_jsx_runtime.jsx)(
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, import_jsx_runtime.jsx)(
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 import_jsx_runtime2 = require("react/jsx-runtime");
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, import_jsx_runtime2.jsx)(
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 &amp; 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":["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 &amp; 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 PrimaryButton from "@commercetools-uikit/primary-button";
200
- import SecondaryButton from "@commercetools-uikit/secondary-button";
201
- import FlatButton from "@commercetools-uikit/flat-button";
202
- import SecondaryIconButton from "@commercetools-uikit/secondary-icon-button";
203
- import TextInput from "@commercetools-uikit/text-input";
204
- import Label from "@commercetools-uikit/label";
205
- import LoadingSpinner from "@commercetools-uikit/loading-spinner";
206
- import Spacings from "@commercetools-uikit/spacings";
207
- import Text from "@commercetools-uikit/text";
208
- import { CloseIcon } from "@commercetools-uikit/icons";
209
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
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__ */ jsx(
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__ */ jsx(Text.Subheadline, { as: "h4", isBold: true, children: "Upload a file" }),
271
- /* @__PURE__ */ jsx(
272
- SecondaryIconButton,
273
- {
274
- icon: /* @__PURE__ */ jsx(CloseIcon, {}),
275
- label: "Close",
276
- onClick: onClose,
277
- size: "small"
278
- }
279
- )
280
+ /* @__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__ */ jsx("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "m", children: [
284
- /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "xs", children: [
285
- /* @__PURE__ */ jsx(Label, { htmlFor: "upload-title", children: "Title" }),
286
- /* @__PURE__ */ jsx(
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: (e) => setTitle(e.target.value),
292
+ onChange: (value) => setTitle(value),
292
293
  placeholder: "File title"
293
294
  }
294
- )
295
+ ) })
295
296
  ] }),
296
- /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "xs", children: [
297
- /* @__PURE__ */ jsx(Label, { htmlFor: "upload-description", children: "Description" }),
298
- /* @__PURE__ */ jsx(
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: (e) => setDescription(e.target.value),
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__ */ jsx("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
339
- /* @__PURE__ */ jsx(
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__ */ jsx(Text.Body, { tone: "negative", children: error })
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__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: file?.name ?? "No file selected" }),
370
- /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
371
- /* @__PURE__ */ jsx(SecondaryButton, { label: "Cancel", onClick: onClose }),
372
- /* @__PURE__ */ jsx(
373
- PrimaryButton,
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
- label: uploading ? "Uploading\u2026" : "Upload",
375
+ variant: "solid",
376
376
  isDisabled: !file || uploading,
377
- onClick: () => file && onUpload(file, title, description)
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__ */ jsx(
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__ */ jsx(Text.Subheadline, { as: "h4", isBold: true, children: "Select from Media Library" }),
443
- /* @__PURE__ */ jsx(
444
- SecondaryIconButton,
445
- {
446
- icon: /* @__PURE__ */ jsx(CloseIcon, {}),
447
- label: "Close",
448
- onClick: onClose,
449
- size: "small"
450
- }
451
- )
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__ */ jsx("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }) : files.length === 0 ? /* @__PURE__ */ jsx(Text.Body, { tone: "secondary", children: "No files found." }) : /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "m", children: [
457
- /* @__PURE__ */ jsx(
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__ */ jsx(
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__ */ jsx(
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__ */ jsx(
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(Spacings.Inline, { alignItems: "center", justifyContent: "center", scale: "s", children: [
527
- /* @__PURE__ */ jsx(
528
- SecondaryButton,
519
+ pagination.totalPages > 1 && /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", alignItems: "center", justifyContent: "center", children: [
520
+ /* @__PURE__ */ jsx2(
521
+ Button,
529
522
  {
530
- label: "\u2190 Prev",
523
+ variant: "outline",
524
+ size: "sm",
531
525
  isDisabled: pagination.currentPage <= 1,
532
- onClick: onPrevPage,
533
- size: "small"
526
+ onPress: onPrevPage,
527
+ children: "\u2190 Prev"
534
528
  }
535
529
  ),
536
- /* @__PURE__ */ jsxs(Text.Detail, { tone: "secondary", children: [
530
+ /* @__PURE__ */ jsxs(Text, { fontSize: "sm", color: "neutral.11", children: [
537
531
  pagination.currentPage,
538
532
  " / ",
539
533
  pagination.totalPages
540
534
  ] }),
541
- /* @__PURE__ */ jsx(
542
- SecondaryButton,
535
+ /* @__PURE__ */ jsx2(
536
+ Button,
543
537
  {
544
- label: "Next \u2192",
538
+ variant: "outline",
539
+ size: "sm",
545
540
  isDisabled: pagination.currentPage >= pagination.totalPages,
546
- onClick: onNextPage,
547
- size: "small"
541
+ onPress: onNextPage,
542
+ children: "Next \u2192"
548
543
  }
549
544
  )
550
545
  ] })
551
546
  ] }),
552
- error && /* @__PURE__ */ jsx(Text.Body, { tone: "negative", children: error })
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__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
567
- /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
568
- /* @__PURE__ */ jsx(SecondaryButton, { label: "Cancel", onClick: onClose }),
569
- /* @__PURE__ */ jsx(
570
- PrimaryButton,
571
- {
572
- label: "Select",
573
- isDisabled: !selected,
574
- onClick: handleConfirm
575
- }
576
- )
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(Spacings.Stack, { scale: "s", children: [
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__ */ jsx(
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__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: value }) }),
658
- /* @__PURE__ */ jsx(FlatButton, { tone: "critical", label: "Remove", onClick: () => onChange("") })
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__ */ jsx(Text.Detail, { tone: "secondary", children: "No image selected" }),
662
- /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
663
- /* @__PURE__ */ jsx(SecondaryButton, { label: "Upload", onClick: () => setShowUpload(true) }),
664
- /* @__PURE__ */ jsx(PrimaryButton, { label: "Media Library", onClick: openLibrary })
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__ */ jsx(
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__ */ jsx(
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 jsx2 } from "react/jsx-runtime";
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__ */ jsx2(
689
+ return /* @__PURE__ */ jsx3(
702
690
  ImagePickerContext.Provider,
703
691
  {
704
692
  value: { baseURL, projectKey, businessUnitKey, jwtToken },
@@ -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 &amp; 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 &amp; 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.4.1",
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-uikit/flat-button": ">=20.0.0",
29
- "@commercetools-uikit/icons": ">=20.0.0",
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",