@getmicdrop/svelte-components 5.16.2 → 5.17.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.
@@ -41,6 +41,22 @@
41
41
  type AspectRatio = '1:1' | '2:1' | '16:9' | '4:3' | 'free';
42
42
  type Size = 'sm' | 'md' | 'lg';
43
43
 
44
+ /**
45
+ * Default labels for user-visible strings in ImageUploader.
46
+ * Consumers can override via the `labels` prop.
47
+ */
48
+ const defaultLabels = {
49
+ uploadPhotoTitle: 'Upload photo',
50
+ mainBadge: 'Main',
51
+ replace: 'Replace',
52
+ delete: 'Delete',
53
+ removePhoto: 'Remove photo',
54
+ addPhotoAria: 'Add photo - drag and drop or click to upload',
55
+ fileTypes: 'JPG, PNG, WebP',
56
+ uploadedAlt: 'Uploaded',
57
+ closeModal: 'Close',
58
+ };
59
+
44
60
  interface Props {
45
61
  /** Single image or array of images (URLs) */
46
62
  images?: string | string[];
@@ -88,6 +104,8 @@
88
104
  disabled?: boolean;
89
105
  /** Custom class for wrapper */
90
106
  class?: string;
107
+ /** Override user-visible strings */
108
+ labels?: Partial<typeof defaultLabels>;
91
109
  }
92
110
 
93
111
  let {
@@ -113,8 +131,11 @@
113
131
  error = '',
114
132
  disabled = false,
115
133
  class: className = '',
134
+ labels: userLabels = {},
116
135
  }: Props = $props();
117
136
 
137
+ let labels = $derived({ ...defaultLabels, ...userLabels });
138
+
118
139
  // Normalize images to array
119
140
  let imageArray = $derived(
120
141
  Array.isArray(images)
@@ -235,7 +256,7 @@
235
256
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
236
257
  </svg>
237
258
  <span class="text-sm font-medium text-gray-600 dark:text-gray-300">${emptyLabel}</span>
238
- <span class="text-[11px] text-gray-400 dark:text-gray-500 mt-2 block">JPG, PNG, WebP</span>
259
+ <span class="text-[11px] text-gray-400 dark:text-gray-500 mt-2 block">${labels.fileTypes}</span>
239
260
  ${constraintsText ? `<span class="text-[10px] text-gray-400/50 dark:text-gray-500/50 mt-1 block">${constraintsText}</span>` : ''}
240
261
  </div>
241
262
  `,
@@ -592,7 +613,7 @@
592
613
  <div class="relative {shapeAspects[shape]} bg-gray-100 dark:bg-gray-800 rounded-xl overflow-hidden group">
593
614
  <img
594
615
  src={imageArray[0]}
595
- alt="Uploaded"
616
+ alt={labels.uploadedAlt}
596
617
  class="w-full h-full object-contain"
597
618
  />
598
619
  {#if !disabled}
@@ -603,7 +624,7 @@
603
624
  onclick={() => singleModeFileInput?.click()}
604
625
  >
605
626
  <ImageOutline class="w-4 h-4 mr-1.5" />
606
- Replace
627
+ {labels.replace}
607
628
  </Button>
608
629
  <Button
609
630
  variant="red"
@@ -611,7 +632,7 @@
611
632
  onclick={() => handleRemoveImage(0)}
612
633
  >
613
634
  <TrashBinOutline class="w-4 h-4 mr-1.5" />
614
- Delete
635
+ {labels.delete}
615
636
  </Button>
616
637
  </div>
617
638
  <!-- Hidden file input for replace -->
@@ -620,6 +641,7 @@
620
641
  type="file"
621
642
  accept={acceptedTypes.join(',')}
622
643
  class="hidden"
644
+ data-testid="image-upload-input"
623
645
  onchange={handleSingleModeFileSelect}
624
646
  />
625
647
  {/if}
@@ -683,13 +705,13 @@
683
705
  >
684
706
  <img
685
707
  src={slot.image}
686
- alt="Uploaded"
708
+ alt={labels.uploadedAlt}
687
709
  class="w-full h-full object-contain pointer-events-none"
688
710
  draggable="false"
689
711
  />
690
712
  {#if showMainBadge && index === 0}
691
713
  <div class="absolute bottom-1 left-1 z-10 pointer-events-none">
692
- <Badge variant="info" size={currentSizeConfig.badgeSize}>Main</Badge>
714
+ <Badge variant="info" size={currentSizeConfig.badgeSize}>{labels.mainBadge}</Badge>
693
715
  </div>
694
716
  {/if}
695
717
  {#if !disabled}
@@ -697,7 +719,7 @@
697
719
  type="button"
698
720
  class="remove-btn absolute top-1 right-1 {currentSizeConfig.removeSize} bg-white/90 dark:bg-gray-900/90 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity hover:bg-white dark:hover:bg-gray-900"
699
721
  onclick={(e) => { e.stopPropagation(); handleRemoveImage(index); }}
700
- aria-label="Remove photo"
722
+ aria-label={labels.removePhoto}
701
723
  >
702
724
  <CloseOutline class="w-3 h-3 text-gray-700 dark:text-gray-300" />
703
725
  </button>
@@ -719,7 +741,7 @@
719
741
  ondragover={(e) => { e.preventDefault(); e.stopPropagation(); isDropzoneDragOver = true; }}
720
742
  ondragleave={(e) => { e.preventDefault(); e.stopPropagation(); isDropzoneDragOver = false; }}
721
743
  ondrop={(e) => handleDropzoneDrop(e, index)}
722
- aria-label="Add photo - drag and drop or click to upload"
744
+ aria-label={labels.addPhotoAria}
723
745
  >
724
746
  <PlusOutline class={currentSizeConfig.iconClass + ' text-gray-400 dark:text-gray-500'} />
725
747
  </div>
@@ -755,12 +777,12 @@
755
777
  onclick={(e) => e.stopPropagation()}
756
778
  >
757
779
  <div class="flex items-center justify-between p-4 border-b border-gray-200 dark:border-gray-700">
758
- <h3 class={typography.h3}>Upload photo</h3>
780
+ <h3 class={typography.h3}>{labels.uploadPhotoTitle}</h3>
759
781
  <button
760
782
  type="button"
761
783
  class="p-1.5 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors"
762
784
  onclick={() => (showFilePondModal = false)}
763
- aria-label="Close"
785
+ aria-label={labels.closeModal}
764
786
  >
765
787
  <CloseOutline class="w-5 h-5" />
766
788
  </button>
@@ -783,13 +805,14 @@
783
805
  >
784
806
  <PlusOutline class="w-8 h-8 mb-2 text-gray-400" />
785
807
  <span class={typography.smMuted}>{emptyLabel}</span>
786
- <span class={`${typography.xsMuted} mt-1`}>JPG, PNG, WebP</span>
808
+ <span class={`${typography.xsMuted} mt-1`}>{labels.fileTypes}</span>
787
809
  </div>
788
810
  <input
789
811
  bind:this={modalFileInput}
790
812
  type="file"
791
813
  accept={acceptedTypes.join(',')}
792
814
  class="hidden"
815
+ data-testid="image-upload-modal-input"
793
816
  onchange={handleModalFileSelect}
794
817
  />
795
818
  </div>
@@ -1,9 +1,6 @@
1
1
  import 'filepond/dist/filepond.min.css';
2
2
  import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
3
- type Shape = 'square' | 'wide';
4
- type AspectRatio = '1:1' | '2:1' | '16:9' | '4:3' | 'free';
5
- type Size = 'sm' | 'md' | 'lg';
6
- interface Props {
3
+ declare const ImageUploader: import("svelte").Component<{
7
4
  /** Single image or array of images (URLs) */
8
5
  images?: string | string[];
9
6
  /** Maximum number of images (only for multi mode) */
@@ -11,13 +8,13 @@ interface Props {
11
8
  /** Enable cropping step */
12
9
  enableCrop?: boolean;
13
10
  /** Crop aspect ratio */
14
- cropAspectRatio?: AspectRatio;
11
+ cropAspectRatio?: "1:1" | "2:1" | "16:9" | "4:3" | "free";
15
12
  /** Enable drag-to-reorder (only for multi mode) */
16
13
  enableReorder?: boolean;
17
14
  /** Dropzone shape - affects aspect ratio and styling */
18
- shape?: Shape;
15
+ shape?: "wide" | "square";
19
16
  /** Size of image slots: sm (~64px), md (~96px), lg (~200px+) */
20
- size?: Size;
17
+ size?: "sm" | "md" | "lg";
21
18
  /** Show "Main" badge on first image (multi mode) */
22
19
  showMainBadge?: boolean;
23
20
  /** Maximum file size (e.g., "10MB") */
@@ -55,8 +52,19 @@ interface Props {
55
52
  disabled?: boolean;
56
53
  /** Custom class for wrapper */
57
54
  class?: string;
58
- }
59
- declare const ImageUploader: import("svelte").Component<Props, {}, "images">;
55
+ /** Override user-visible strings */
56
+ labels?: Partial<{
57
+ uploadPhotoTitle: string;
58
+ mainBadge: string;
59
+ replace: string;
60
+ delete: string;
61
+ removePhoto: string;
62
+ addPhotoAria: string;
63
+ fileTypes: string;
64
+ uploadedAlt: string;
65
+ closeModal: string;
66
+ }>;
67
+ }, {}, "images">;
60
68
  type ImageUploader = ReturnType<typeof ImageUploader>;
61
69
  export default ImageUploader;
62
70
  //# sourceMappingURL=ImageUploader.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageUploader.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/ImageUploader/ImageUploader.svelte.ts"],"names":[],"mappings":"AAoBA,OAAO,gCAAgC,CAAC;AACxC,OAAO,sEAAsE,CAAC;AAY5E,KAAK,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC/B,KAAK,WAAW,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAC3D,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/B,UAAU,KAAK;IACb,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wBAAwB;IACxB,eAAe,CAAC,EAAE,WAAW,CAAC;IAC9B,mDAAmD;IACnD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wDAAwD;IACxD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,gEAAgE;IAChE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,oDAAoD;IACpD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;sEAEkE;IAClE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChE,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACvC,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAChE,4EAA4E;IAC5E,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9C,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACtC,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkpBH,QAAA,MAAM,aAAa,iDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ImageUploader.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/recipes/ImageUploader/ImageUploader.svelte.ts"],"names":[],"mappings":"AAoBA,OAAO,gCAAgC,CAAC;AACxC,OAAO,sEAAsE,CAAC;AAkuB9E,QAAA,MAAM,aAAa;IAtqBf,6CAA6C;aACpC,MAAM,GAAG,MAAM,EAAE;IAC1B,qDAAqD;gBACzC,MAAM;IAClB,2BAA2B;iBACd,OAAO;IACpB,wBAAwB;;IAExB,mDAAmD;oBACnC,OAAO;IACvB,wDAAwD;;IAExD,gEAAgE;;IAEhE,oDAAoD;oBACpC,OAAO;IACvB,uCAAuC;kBACzB,MAAM;IACpB,0BAA0B;oBACV,MAAM,EAAE;IACxB,6BAA6B;iBAChB,MAAM;IACnB,wEAAwE;sBACtD,MAAM;IACxB,uCAAuC;iBAC1B,MAAM;IACnB;;sEAEkE;eACvD,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI;IAC/D,qCAAqC;eAC1B,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;IAClC,8DAA8D;gBAClD,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI;IACtC,oFAAoF;uBACjE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI;IAC/D,4EAA4E;gBAChE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI;IAC7C,2DAA2D;eAChD,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI;IACrC,wBAAwB;YAChB,MAAM;IACd,qBAAqB;eACV,OAAO;IAClB,+BAA+B;YACvB,MAAM;IACd,oCAAoC;aAC3B,OAAO;;;;;;;;;;MAAsB;gBAunBiB,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}