@getmicdrop/svelte-components 5.3.10 → 5.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +4 -4
  2. package/dist/calendar/OrderSummary/OrderSummary.svelte +50 -10
  3. package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts +2 -0
  4. package/dist/calendar/OrderSummary/OrderSummary.svelte.d.ts.map +1 -1
  5. package/dist/primitives/Accordion/AccordionItem.svelte +1 -1
  6. package/dist/primitives/Button/Button.svelte +12 -3
  7. package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
  8. package/dist/primitives/Checkbox/Checkbox.svelte +8 -8
  9. package/dist/primitives/Icons/ImageOutline.svelte +19 -0
  10. package/dist/primitives/Icons/ImageOutline.svelte.d.ts +12 -0
  11. package/dist/primitives/Icons/ImageOutline.svelte.d.ts.map +1 -0
  12. package/dist/primitives/Icons/TrashBinOutline.svelte +19 -0
  13. package/dist/primitives/Icons/TrashBinOutline.svelte.d.ts +12 -0
  14. package/dist/primitives/Icons/TrashBinOutline.svelte.d.ts.map +1 -0
  15. package/dist/primitives/Icons/index.d.ts +2 -0
  16. package/dist/primitives/Icons/index.js +2 -0
  17. package/dist/primitives/Input/Input.svelte +3 -3
  18. package/dist/primitives/Input/Select.svelte +1 -1
  19. package/dist/primitives/Input/Textarea.svelte +1 -1
  20. package/dist/primitives/Radio/Radio.svelte +7 -7
  21. package/dist/recipes/ImageUploader/ImageUploader.svelte +59 -18
  22. package/dist/recipes/ImageUploader/ImageUploader.svelte.d.ts +2 -0
  23. package/dist/recipes/ImageUploader/ImageUploader.svelte.d.ts.map +1 -1
  24. package/dist/recipes/fields/FormField.svelte +2 -2
  25. package/dist/recipes/fields/TextareaField.svelte +1 -1
  26. package/dist/recipes/inputs/MultiSelect.svelte +1 -1
  27. package/dist/recipes/modals/ConfirmationModal.svelte +2 -1
  28. package/package.json +1 -1
@@ -322,7 +322,7 @@
322
322
  }
323
323
 
324
324
  triggerHaptic('medium');
325
- onmonthChange?.({ year: currentYear, month: currentMonth });
325
+ onMonthChange?.({ year: currentYear, month: currentMonth });
326
326
 
327
327
  const enterFrom = direction > 0 ? containerWidth : -containerWidth;
328
328
  calendarGridElement.style.transition = 'none';
@@ -615,7 +615,7 @@
615
615
 
616
616
  <!-- svelte-ignore a11y_no_static_element_interactions -->
617
617
  <div
618
- class="w-full max-w-full mx-auto overflow-hidden select-none"
618
+ class="w-full max-w-full mx-auto select-none"
619
619
  class:max-w-xs={variant === 'display'}
620
620
  ontouchstart={handleTouchStart}
621
621
  ontouchmove={handleTouchMove}
@@ -644,7 +644,7 @@
644
644
 
645
645
  <div class="flex items-center gap-2">
646
646
  <button
647
- class="p-3 -m-1.5 flex items-center justify-center border-0 rounded-full bg-transparent text-gray-500 dark:text-gray-400 cursor-pointer select-none transition-transform duration-100 ease-out hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
647
+ class="p-2 flex items-center justify-center border-0 rounded-lg bg-transparent text-gray-500 dark:text-gray-400 cursor-pointer select-none transition-all duration-100 ease-out hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
648
648
  class:scale-90={prevPressed}
649
649
  class:bg-gray-100={prevPressed}
650
650
  class:dark:bg-gray-700={prevPressed}
@@ -682,7 +682,7 @@
682
682
  {/if}
683
683
 
684
684
  <button
685
- class="p-3 -m-1.5 flex items-center justify-center border-0 rounded-full bg-transparent text-gray-500 dark:text-gray-400 cursor-pointer select-none transition-transform duration-100 ease-out hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2"
685
+ class="p-2 flex items-center justify-center border-0 rounded-lg bg-transparent text-gray-500 dark:text-gray-400 cursor-pointer select-none transition-all duration-100 ease-out hover:bg-gray-100 dark:hover:bg-gray-700 hover:text-gray-900 dark:hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2"
686
686
  class:scale-90={nextPressed}
687
687
  class:bg-gray-100={nextPressed}
688
688
  class:dark:bg-gray-700={nextPressed}
@@ -8,6 +8,7 @@
8
8
  let {
9
9
  loading = false,
10
10
  quantities = {},
11
+ donationAmounts = {}, // Map of ticketId -> donation amount string
11
12
  eventTickets = [],
12
13
  checkoutTicket = null,
13
14
  isAgreed = true,
@@ -27,6 +28,24 @@
27
28
  onPriceUpdate,
28
29
  } = $props();
29
30
 
31
+ // Helper to get effective price for a ticket (handles donation tickets)
32
+ function getEffectivePrice(ticket) {
33
+ // Donation ticket (type 2): use user-entered donation amount
34
+ if (isDonationTicket(ticket)) {
35
+ const donationAmount = donationAmounts[ticket.ID];
36
+ return parseFloat(donationAmount) || 0;
37
+ }
38
+ // Regular ticket: use ticket price
39
+ return parseFloat(ticket.price) || 0;
40
+ }
41
+
42
+ // Check if ticket is a donation ticket
43
+ // Handle both 'type' and 'ticketType' fields, and coerce to number for comparison
44
+ function isDonationTicket(ticket) {
45
+ const ticketType = ticket.type ?? ticket.ticketType ?? 0;
46
+ return Number(ticketType) === 2;
47
+ }
48
+
30
49
  let showOrderSummaryOnMobile = $state(false);
31
50
 
32
51
  function feeFor(price) {
@@ -76,12 +95,20 @@
76
95
  let subtotalWithoutDiscount = $derived(Object.keys(quantities).reduce((acc, key) => {
77
96
  const ticket = eventTickets.find(t => t.ID == key);
78
97
  if (!ticket) return acc;
79
- return acc + quantities[key] * ticket.price;
98
+ // For donation tickets, use the donation amount; otherwise use ticket price
99
+ const effectivePrice = getEffectivePrice(ticket);
100
+ return acc + quantities[key] * effectivePrice;
80
101
  }, 0));
81
102
 
82
103
  let subtotal = $derived(Object.keys(quantities).reduce((acc, key) => {
83
104
  const ticket = eventTickets.find(t => t.ID == key);
84
105
  if (!ticket) return acc;
106
+ // For donation tickets, use the donation amount (no discounts apply)
107
+ if (isDonationTicket(ticket)) {
108
+ const effectivePrice = getEffectivePrice(ticket);
109
+ return acc + quantities[key] * effectivePrice;
110
+ }
111
+ // For regular tickets, apply discounts as usual
85
112
  const discountedPrice = getDiscountedPrice(ticket);
86
113
  const priceToUse = discountedPrice !== null ? parseFloat(discountedPrice) : ticket.price;
87
114
  return acc + quantities[key] * priceToUse;
@@ -91,7 +118,8 @@
91
118
 
92
119
  let fees = $derived(Object.keys(quantities).reduce((acc, key) => {
93
120
  const ticket = eventTickets.find(t => t.ID == key);
94
- if (!ticket || ticket.price == 0) return acc;
121
+ // Skip fees for: no ticket, free tickets, and donation tickets (type 2)
122
+ if (!ticket || ticket.price == 0 || isDonationTicket(ticket)) return acc;
95
123
  const discountedPrice = getDiscountedPrice(ticket);
96
124
  const priceToUse = discountedPrice !== null ? parseFloat(discountedPrice) : ticket.price;
97
125
  return acc + quantities[key] * feeFor(priceToUse);
@@ -126,21 +154,27 @@
126
154
  {#if quantities[key] > 0}
127
155
  {#each eventTickets as ticket}
128
156
  {#if ticket.ID == key}
157
+ {@const effectivePrice = getEffectivePrice(ticket)}
158
+ {@const isDonation = isDonationTicket(ticket)}
129
159
  <div class="flex justify-between py-3 border-b border-gray-200/50 dark:border-gray-600/50">
130
160
  <div>
131
161
  <p class="{typography.label}">{ticket.name}</p>
132
162
  <p class="{typography.smMuted}">
133
- {#if ticket.price === 0}
163
+ {#if ticket.price === 0 && !isDonation}
134
164
  Free x {quantities[key]}
165
+ {:else if isDonation}
166
+ ${effectivePrice.toFixed(2)} x {quantities[key]}
135
167
  {:else}
136
168
  ${ticket.price.toFixed(2)} x {quantities[key]}
137
169
  {/if}
138
170
  </p>
139
171
  </div>
140
172
  <div class="{typography.label}">
141
- {ticket.price === 0
142
- ? 'Free'
143
- : `$${(ticket.price * quantities[key]).toFixed(2)}`}
173
+ {#if ticket.price === 0 && !isDonation}
174
+ Free
175
+ {:else}
176
+ ${(effectivePrice * quantities[key]).toFixed(2)}
177
+ {/if}
144
178
  </div>
145
179
  </div>
146
180
  {/if}
@@ -236,21 +270,27 @@
236
270
  {#if quantities[key] > 0}
237
271
  {#each eventTickets as ticket}
238
272
  {#if ticket.ID == key}
273
+ {@const effectivePrice = getEffectivePrice(ticket)}
274
+ {@const isDonation = isDonationTicket(ticket)}
239
275
  <div class="flex justify-between py-4 border-b border-gray-200 dark:border-gray-600">
240
276
  <div>
241
277
  <p class="{typography.h5}">{ticket.name}</p>
242
278
  <p class="{typography.smMuted}">
243
- {#if ticket.price === 0}
279
+ {#if ticket.price === 0 && !isDonation}
244
280
  Free x {quantities[key]}
281
+ {:else if isDonation}
282
+ ${effectivePrice.toFixed(2)} x {quantities[key]}
245
283
  {:else}
246
284
  ${ticket.price.toFixed(2)} x {quantities[key]}
247
285
  {/if}
248
286
  </p>
249
287
  </div>
250
288
  <div class="{typography.h5}">
251
- {ticket.price === 0
252
- ? 'Free'
253
- : `$${(ticket.price * quantities[key]).toFixed(2)}`}
289
+ {#if ticket.price === 0 && !isDonation}
290
+ Free
291
+ {:else}
292
+ ${(effectivePrice * quantities[key]).toFixed(2)}
293
+ {/if}
254
294
  </div>
255
295
  </div>
256
296
  {/if}
@@ -6,6 +6,7 @@ type OrderSummary = {
6
6
  declare const OrderSummary: import("svelte").Component<{
7
7
  loading?: boolean;
8
8
  quantities?: Record<string, any>;
9
+ donationAmounts?: Record<string, any>;
9
10
  eventTickets?: any[];
10
11
  checkoutTicket?: any;
11
12
  isAgreed?: boolean;
@@ -21,6 +22,7 @@ declare const OrderSummary: import("svelte").Component<{
21
22
  type $$ComponentProps = {
22
23
  loading?: boolean;
23
24
  quantities?: Record<string, any>;
25
+ donationAmounts?: Record<string, any>;
24
26
  eventTickets?: any[];
25
27
  checkoutTicket?: any;
26
28
  isAgreed?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"OrderSummary.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/OrderSummary/OrderSummary.svelte.js"],"names":[],"mappings":";;;;;AAoTA;cApS+B,OAAO;iBAAe,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBAAiB,GAAG,EAAE;qBAAmB,GAAG;eAAa,OAAO;cAAY,MAAM;mBAAiB,OAAO;oBAAkB,MAAM;uBAAqB,GAAG;sBAAoB,GAAG;eAAa,GAAG;yBAAuB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBAAiB,GAAG;WAoS5Q;wBApSxC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC;IAAC,eAAe,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,GAAG,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,aAAa,EAAE,GAAG,CAAA;CAAE"}
1
+ {"version":3,"file":"OrderSummary.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/calendar/OrderSummary/OrderSummary.svelte.js"],"names":[],"mappings":";;;;;AAoVA;cApU+B,OAAO;iBAAe,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;sBAAoB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBAAiB,GAAG,EAAE;qBAAmB,GAAG;eAAa,OAAO;cAAY,MAAM;mBAAiB,OAAO;oBAAkB,MAAM;uBAAqB,GAAG;sBAAoB,GAAG;eAAa,GAAG;yBAAuB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;mBAAiB,GAAG;WAoUnT;wBApUxC;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,cAAc,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,GAAG,CAAC;IAAC,eAAe,CAAC,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,EAAE,GAAG,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,aAAa,EAAE,GAAG,CAAA;CAAE"}
@@ -61,7 +61,7 @@
61
61
  typography.smMuted,
62
62
  "bg-gray-100 dark:bg-gray-800",
63
63
  "hover:bg-gray-200 dark:hover:bg-gray-700",
64
- "focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800",
64
+ "focus:outline-none",
65
65
  "gap-3",
66
66
  isOpen ? "bg-gray-100 dark:bg-gray-800" : "",
67
67
  ].join(" "));
@@ -130,9 +130,9 @@
130
130
  // Avatar/image trigger - no background, opacity hover
131
131
  avatar: "bg-transparent border-transparent hover:opacity-80",
132
132
  // Menu items - full width, left-aligned, for dropdowns/sheets and sidebar nav
133
- "menu-item": "w-full text-left text-gray-900 bg-transparent border-transparent hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600",
133
+ "menu-item": "w-full text-left whitespace-nowrap text-gray-900 bg-transparent border-transparent hover:bg-gray-100 dark:text-white dark:hover:bg-gray-600",
134
134
  // Danger menu item - red text version
135
- "menu-item-danger": "w-full text-left text-red-600 bg-transparent border-transparent hover:bg-red-50 dark:text-red-500 dark:hover:bg-gray-600",
135
+ "menu-item-danger": "w-full text-left whitespace-nowrap text-red-600 bg-transparent border-transparent hover:bg-red-50 dark:text-red-500 dark:hover:bg-gray-600",
136
136
  // Selectable card - bordered card-like button for list selections
137
137
  card: "w-full text-left text-gray-900 bg-white border border-gray-300 hover:bg-gray-50 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700",
138
138
  // Search result item - blue hover for search dropdowns
@@ -155,6 +155,8 @@
155
155
 
156
156
  // Disabled classes
157
157
  const disabledClasses = "bg-gray-200 border-gray-200 text-gray-400 cursor-not-allowed dark:bg-gray-700 dark:border-gray-700 dark:text-gray-500";
158
+ // Disabled classes for transparent variants (link, ghost) - no background
159
+ const disabledTransparentClasses = "text-gray-400 cursor-not-allowed dark:text-gray-500";
158
160
 
159
161
  let sizeClass = $derived((() => {
160
162
  if (resolvedVariant === "icon") return iconSizes[size] || iconSizes.sm;
@@ -169,9 +171,16 @@
169
171
  return sizeClasses[size] || sizeClasses.md;
170
172
  })());
171
173
 
174
+ // Variants that should stay transparent when disabled
175
+ const transparentVariants = ["link", "ghost", "ghost-red", "icon"];
176
+
172
177
  let variantClass = $derived((() => {
173
178
  if (success) return variantClasses.success;
174
- if (disabled && !loading && !success) return disabledClasses;
179
+ if (disabled && !loading && !success) {
180
+ return transparentVariants.includes(resolvedVariant)
181
+ ? disabledTransparentClasses
182
+ : disabledClasses;
183
+ }
175
184
  if (active && activeClasses[resolvedVariant]) {
176
185
  // When active, use ONLY active classes (they include all necessary styling)
177
186
  return activeClasses[resolvedVariant];
@@ -1 +1 @@
1
- {"version":3,"file":"Button.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Button/Button.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAyQA;;cAfc,MAAM;WACT,MAAM;eACF,OAAO;cACR,OAAO;cACP,OAAO;kBACH,MAAM;aACX,OAAO;WACT,MAAM,GAAG,IAAI;WACb,QAAQ,GAAG,QAAQ,GAAG,OAAO;eACzB,GAAG;eACH,GAAG;YACN,MAAM;cACJ,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI;WAGgB"}
1
+ {"version":3,"file":"Button.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Button/Button.svelte.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAkRA;;cAfc,MAAM;WACT,MAAM;eACF,OAAO;cACR,OAAO;cACP,OAAO;kBACH,MAAM;aACX,OAAO;WACT,MAAM,GAAG,IAAI;WACb,QAAQ,GAAG,QAAQ,GAAG,OAAO;eACzB,GAAG;eACH,GAAG;YACN,MAAM;cACJ,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI;WAGgB"}
@@ -42,12 +42,12 @@
42
42
  }
43
43
 
44
44
  const colorClasses = {
45
- blue: "text-blue-600 focus:ring-blue-500 dark:focus:ring-blue-600",
46
- red: "text-red-600 focus:ring-red-500 dark:focus:ring-red-600",
47
- green: "text-green-600 focus:ring-green-500 dark:focus:ring-green-600",
48
- purple: "text-purple-600 focus:ring-purple-500 dark:focus:ring-purple-600",
49
- orange: "text-orange-500 focus:ring-orange-500 dark:focus:ring-orange-600",
50
- yellow: "text-yellow-400 focus:ring-yellow-500 dark:focus:ring-yellow-600"
45
+ blue: "text-blue-600",
46
+ red: "text-red-600",
47
+ green: "text-green-600",
48
+ purple: "text-purple-600",
49
+ orange: "text-orange-500",
50
+ yellow: "text-yellow-400"
51
51
  };
52
52
 
53
53
  let colorClass = $derived(colorClasses[color] || colorClasses.blue);
@@ -55,8 +55,8 @@
55
55
  let inputClasses = $derived([
56
56
  "w-4 h-4 rounded",
57
57
  "bg-gray-100 border-gray-300",
58
- "dark:bg-gray-700 dark:border-gray-600 dark:ring-offset-gray-800",
59
- "focus:ring-2",
58
+ "dark:bg-gray-700 dark:border-gray-600",
59
+ "focus:outline-none",
60
60
  colorClass,
61
61
  disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
62
62
  ].join(" "));
@@ -0,0 +1,19 @@
1
+ <script>
2
+ let { class: className = 'w-5 h-5', ...restProps } = $props();
3
+ </script>
4
+
5
+ <svg
6
+ class={className}
7
+ fill="none"
8
+ stroke="currentColor"
9
+ viewBox="0 0 24 24"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ {...restProps}
12
+ >
13
+ <path
14
+ stroke-linecap="round"
15
+ stroke-linejoin="round"
16
+ stroke-width="2"
17
+ d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
18
+ />
19
+ </svg>
@@ -0,0 +1,12 @@
1
+ export default ImageOutline;
2
+ type ImageOutline = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const ImageOutline: import("svelte").Component<{
7
+ class?: string;
8
+ } & Record<string, any>, {}, "">;
9
+ type $$ComponentProps = {
10
+ class?: string;
11
+ } & Record<string, any>;
12
+ //# sourceMappingURL=ImageOutline.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageOutline.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/ImageOutline.svelte.js"],"names":[],"mappings":";;;;;AAaA;YAT6B,MAAM;iCASwB;wBATxC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
@@ -0,0 +1,19 @@
1
+ <script>
2
+ let { class: className = 'w-5 h-5', ...restProps } = $props();
3
+ </script>
4
+
5
+ <svg
6
+ class={className}
7
+ fill="none"
8
+ stroke="currentColor"
9
+ viewBox="0 0 24 24"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ {...restProps}
12
+ >
13
+ <path
14
+ stroke-linecap="round"
15
+ stroke-linejoin="round"
16
+ stroke-width="2"
17
+ d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
18
+ />
19
+ </svg>
@@ -0,0 +1,12 @@
1
+ export default TrashBinOutline;
2
+ type TrashBinOutline = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const TrashBinOutline: import("svelte").Component<{
7
+ class?: string;
8
+ } & Record<string, any>, {}, "">;
9
+ type $$ComponentProps = {
10
+ class?: string;
11
+ } & Record<string, any>;
12
+ //# sourceMappingURL=TrashBinOutline.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrashBinOutline.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/primitives/Icons/TrashBinOutline.svelte.js"],"names":[],"mappings":";;;;;AAaA;YAT6B,MAAM;iCAS2B;wBAT3C;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
@@ -16,6 +16,8 @@ export { default as PlusOutline } from "./PlusOutline.svelte";
16
16
  export { default as ExclamationTriangleOutline } from "./ExclamationTriangleOutline.svelte";
17
17
  export { default as DotsHorizontalOutline } from "./DotsHorizontalOutline.svelte";
18
18
  export { default as FileCopyOutline } from "./FileCopyOutline.svelte";
19
+ export { default as ImageOutline } from "./ImageOutline.svelte";
20
+ export { default as TrashBinOutline } from "./TrashBinOutline.svelte";
19
21
  export { default as CheckCircleSolid } from "./CheckCircleSolid.svelte";
20
22
  export { default as HomeSolid } from "./HomeSolid.svelte";
21
23
  export { default as LogoInstagram } from "./LogoInstagram.svelte";
@@ -17,6 +17,8 @@ export { default as PlusOutline } from './PlusOutline.svelte';
17
17
  export { default as ExclamationTriangleOutline } from './ExclamationTriangleOutline.svelte';
18
18
  export { default as DotsHorizontalOutline } from './DotsHorizontalOutline.svelte';
19
19
  export { default as FileCopyOutline } from './FileCopyOutline.svelte';
20
+ export { default as ImageOutline } from './ImageOutline.svelte';
21
+ export { default as TrashBinOutline } from './TrashBinOutline.svelte';
20
22
 
21
23
  // Solid icons (fill-based)
22
24
  export { default as CheckCircleSolid } from './CheckCircleSolid.svelte';
@@ -309,7 +309,7 @@
309
309
  onfocus={handleFocus}
310
310
  {maxlength}
311
311
  {minlength}
312
- class="{typography.sm} w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 resize-y {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {getContentFloatClass()} {getTextareaSizeClass()} {shouldAnimate ? 'focus:scale-[1.01]' : ''}"
312
+ class="{typography.sm} w-full px-3 py-2 bg-gray-50 dark:bg-gray-800 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 resize-y {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {getContentFloatClass()} {getTextareaSizeClass()} {shouldAnimate ? 'focus:scale-[1.01]' : ''}"
313
313
  required={false}
314
314
  {disabled}
315
315
  {readonly}
@@ -317,7 +317,7 @@
317
317
  aria-required={required}
318
318
  ></textarea>
319
319
  {:else if type === "password" && showPasswordToggle}
320
- <div class="flex items-center w-full bg-gray-50 dark:bg-gray-700 border rounded-lg transition-all outline-none focus-within:ring-4 focus-within:ring-blue-300 dark:focus-within:ring-blue-800 {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus-within:border-blue-500'} {shouldAnimate ? 'focus-within:scale-[1.01]' : ''}">
320
+ <div class="flex items-center w-full bg-gray-50 dark:bg-gray-800 border rounded-lg transition-all outline-none focus-within:ring-4 focus-within:ring-blue-300 dark:focus-within:ring-blue-800 {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus-within:border-blue-500'} {shouldAnimate ? 'focus-within:scale-[1.01]' : ''}">
321
321
  <input
322
322
  bind:this={inputElement}
323
323
  {id}
@@ -375,7 +375,7 @@
375
375
  onkeydown={handleSearchKeyDown}
376
376
  {maxlength}
377
377
  {minlength}
378
- class="{typography.body} w-full {sizeClass} bg-gray-50 dark:bg-gray-700 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {icon || (showClearButton && inputValue) ? 'pr-10' : ''} {leftIcon ? 'pl-10' : ''} {getContentFloatClass()} {shouldAnimate ? 'focus:scale-[1.01]' : ''} {disabled ? 'opacity-50 cursor-not-allowed' : ''}"
378
+ class="{typography.body} w-full {sizeClass} bg-gray-50 dark:bg-gray-800 border rounded-lg font-medium placeholder-gray-500 dark:placeholder-gray-400 transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {hasError ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {icon || (showClearButton && inputValue) ? 'pr-10' : ''} {leftIcon ? 'pl-10' : ''} {getContentFloatClass()} {shouldAnimate ? 'focus:scale-[1.01]' : ''} {disabled ? 'opacity-50 cursor-not-allowed' : ''}"
379
379
  required={false}
380
380
  {disabled}
381
381
  {readonly}
@@ -163,7 +163,7 @@
163
163
  bind:this={triggerElement}
164
164
  {id}
165
165
  {name}
166
- class="flex items-center justify-between w-full {sizeClass} bg-gray-50 dark:bg-gray-700 border rounded-lg cursor-pointer transition-colors text-left focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {error ? 'border-red-500 dark:border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {!selectedItem ? `${typography.textMuted}` : `${typography.body}`}"
166
+ class="flex items-center justify-between w-full {sizeClass} bg-gray-50 dark:bg-gray-800 border rounded-lg cursor-pointer transition-colors text-left focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 {error ? 'border-red-500 dark:border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {!selectedItem ? `${typography.textMuted}` : `${typography.body}`}"
167
167
  {disabled}
168
168
  aria-haspopup="listbox"
169
169
  aria-expanded={isOpen}
@@ -59,7 +59,7 @@
59
59
  {readonly}
60
60
  {maxlength}
61
61
  {minlength}
62
- class="{typography.sm} w-full p-2.5 bg-gray-50 dark:bg-gray-700 leading-normal border rounded-lg resize-y transition-colors focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 placeholder-gray-500 dark:placeholder-gray-400 {error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {className}"
62
+ class="{typography.sm} w-full p-2.5 bg-gray-50 dark:bg-gray-800 leading-normal border rounded-lg resize-y transition-colors focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800 placeholder-gray-500 dark:placeholder-gray-400 {error ? 'border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 focus:border-blue-500'} {disabled ? 'opacity-50 cursor-not-allowed' : ''} {className}"
63
63
  bind:value
64
64
  oninput={handleInput}
65
65
  onchange={handleChange}
@@ -35,12 +35,12 @@
35
35
  }
36
36
 
37
37
  const colorClasses = {
38
- blue: 'text-blue-600 focus:ring-blue-500 dark:focus:ring-blue-600',
39
- red: 'text-red-600 focus:ring-red-500 dark:focus:ring-red-600',
40
- green: 'text-green-600 focus:ring-green-500 dark:focus:ring-green-600',
41
- purple: 'text-purple-600 focus:ring-purple-500 dark:focus:ring-purple-600',
42
- orange: 'text-orange-500 focus:ring-orange-500 dark:focus:ring-orange-600',
43
- yellow: 'text-yellow-400 focus:ring-yellow-500 dark:focus:ring-yellow-600'
38
+ blue: 'text-blue-600',
39
+ red: 'text-red-600',
40
+ green: 'text-green-600',
41
+ purple: 'text-purple-600',
42
+ orange: 'text-orange-500',
43
+ yellow: 'text-yellow-400'
44
44
  };
45
45
 
46
46
  let colorClass = $derived(colorClasses[color] || colorClasses.blue);
@@ -57,7 +57,7 @@
57
57
  {disabled}
58
58
  checked={isChecked}
59
59
  onchange={handleChange}
60
- class="w-4 h-4 bg-gray-100 border-gray-300 focus:ring-2 dark:ring-offset-gray-800 dark:bg-gray-700 dark:border-gray-600 {colorClass}"
60
+ class="w-4 h-4 bg-gray-100 border-gray-300 focus:outline-none dark:bg-gray-700 dark:border-gray-600 {colorClass}"
61
61
  />
62
62
  {#if children}
63
63
  <span class="text-sm font-medium text-gray-900 dark:text-gray-300">
@@ -23,7 +23,8 @@
23
23
  import Sortable from 'sortablejs';
24
24
  import CropImage from '../CropImage/CropImage.svelte';
25
25
  import Badge from '../../primitives/Badges/Badge.svelte';
26
- import { CloseOutline, PlusOutline } from '../../primitives/Icons';
26
+ import Button from '../../primitives/Button/Button.svelte';
27
+ import { CloseOutline, ImageOutline, PlusOutline, TrashBinOutline } from '../../primitives/Icons';
27
28
  import { typography } from '../../tokens/typography';
28
29
 
29
30
  // Register FilePond plugins once
@@ -62,6 +63,8 @@
62
63
  acceptedTypes?: string[];
63
64
  /** Label shown when empty */
64
65
  emptyLabel?: string;
66
+ /** Constraints text shown inside dropzone (e.g., "Max 10MB, 2160px") */
67
+ constraintsText?: string;
65
68
  /** Helper text shown below dropzone */
66
69
  helperText?: string;
67
70
  /** Callback when image is uploaded - receives File, optionally returns URL
@@ -98,6 +101,7 @@
98
101
  maxFileSize = '20MB',
99
102
  acceptedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/heic', 'image/heif'],
100
103
  emptyLabel = 'Drag & drop or click to upload',
104
+ constraintsText = '',
101
105
  helperText = '',
102
106
  onUpload,
103
107
  onRemove,
@@ -147,6 +151,9 @@
147
151
  let isModalDragOver = $state(false);
148
152
  let modalFileInput: HTMLInputElement;
149
153
 
154
+ // Single-mode file input for replace functionality
155
+ let singleModeFileInput: HTMLInputElement;
156
+
150
157
  // Prevent browser from opening dragged files in new tab
151
158
  // This MUST be at document level to intercept before browser default behavior
152
159
  $effect(() => {
@@ -223,11 +230,12 @@
223
230
  dropOnElement: true,
224
231
  labelIdle: `
225
232
  <div class="filepond-custom-label">
226
- <svg class="w-8 h-8 mb-2 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
233
+ <svg class="w-8 h-8 mb-5 text-gray-400 dark:text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
227
234
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
228
235
  </svg>
229
- <span class="text-sm text-gray-500 dark:text-gray-400">${emptyLabel}</span>
230
- <span class="text-xs text-gray-400 dark:text-gray-500 mt-1">JPG, PNG, WebP</span>
236
+ <span class="text-sm font-medium text-gray-600 dark:text-gray-300">${emptyLabel}</span>
237
+ <span class="text-[11px] text-gray-400 dark:text-gray-500 mt-2 block">JPG, PNG, WebP</span>
238
+ ${constraintsText ? `<span class="text-[10px] text-gray-400/50 dark:text-gray-500/50 mt-1 block">${constraintsText}</span>` : ''}
231
239
  </div>
232
240
  `,
233
241
  credits: false,
@@ -460,6 +468,26 @@
460
468
  input.value = '';
461
469
  }
462
470
 
471
+ // Handle single-mode file input selection (for replace)
472
+ function handleSingleModeFileSelect(e: Event) {
473
+ const input = e.target as HTMLInputElement;
474
+ const file = input?.files?.[0];
475
+ if (!file) return;
476
+
477
+ targetSlotIndex = 0; // Replace the existing image
478
+
479
+ if (enableCrop) {
480
+ const objectUrl = URL.createObjectURL(file);
481
+ imageForCrop = objectUrl;
482
+ showCropModal = true;
483
+ } else {
484
+ handleUpload(file);
485
+ }
486
+
487
+ // Clear input for next selection
488
+ input.value = '';
489
+ }
490
+
463
491
  // Initialize sortable for multi-image grid
464
492
  function initSortable() {
465
493
  if (!browser || !gridContainer || !enableReorder || !isMultiMode) return;
@@ -543,6 +571,7 @@
543
571
  });
544
572
  </script>
545
573
 
574
+
546
575
  <!-- Single Image Mode -->
547
576
  {#if !isMultiMode}
548
577
  <div class="image-uploader-single {className}">
@@ -555,24 +584,32 @@
555
584
  class="w-full h-full object-cover"
556
585
  />
557
586
  {#if !disabled}
558
- <div class="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-2">
559
- <button
560
- type="button"
561
- class="p-2 bg-white/90 rounded-full hover:bg-white transition-colors"
562
- onclick={() => openUploadModal(0)}
563
- aria-label="Replace image"
587
+ <div class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center gap-3">
588
+ <Button
589
+ variant="default"
590
+ size="sm"
591
+ onclick={() => singleModeFileInput?.click()}
564
592
  >
565
- <PlusOutline class="w-5 h-5 text-gray-700" />
566
- </button>
567
- <button
568
- type="button"
569
- class="p-2 bg-red-500/90 rounded-full hover:bg-red-500 transition-colors"
593
+ <ImageOutline class="w-4 h-4 mr-1.5" />
594
+ Replace
595
+ </Button>
596
+ <Button
597
+ variant="red"
598
+ size="sm"
570
599
  onclick={() => handleRemoveImage(0)}
571
- aria-label="Remove image"
572
600
  >
573
- <CloseOutline class="w-5 h-5 text-white" />
574
- </button>
601
+ <TrashBinOutline class="w-4 h-4 mr-1.5" />
602
+ Delete
603
+ </Button>
575
604
  </div>
605
+ <!-- Hidden file input for replace -->
606
+ <input
607
+ bind:this={singleModeFileInput}
608
+ type="file"
609
+ accept={acceptedTypes.join(',')}
610
+ class="hidden"
611
+ onchange={handleSingleModeFileSelect}
612
+ />
576
613
  {/if}
577
614
  </div>
578
615
  {:else}
@@ -779,6 +816,10 @@
779
816
  justify-content: center;
780
817
  }
781
818
 
819
+ /* Note: FilePond dark mode is handled via runtime JS injection
820
+ because Svelte's scoped :global() can't reliably override
821
+ FilePond's CSS that loads from node_modules */
822
+
782
823
  :global(.filepond-wrapper .filepond--drop-label label) {
783
824
  display: flex;
784
825
  flex-direction: column;
@@ -26,6 +26,8 @@ interface Props {
26
26
  acceptedTypes?: string[];
27
27
  /** Label shown when empty */
28
28
  emptyLabel?: string;
29
+ /** Constraints text shown inside dropzone (e.g., "Max 10MB, 2160px") */
30
+ constraintsText?: string;
29
31
  /** Helper text shown below dropzone */
30
32
  helperText?: string;
31
33
  /** Callback when image is uploaded - receives File, optionally returns URL
@@ -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;AAU5E,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,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;AAumBH,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;AAW5E,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;AAsoBH,QAAA,MAAM,aAAa,iDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -48,9 +48,9 @@
48
48
 
49
49
  {#if !error}
50
50
  {#if hintContent}
51
- <p class={typography.smMuted}>{@render hintContent()}</p>
51
+ <p class={typography.xsMuted}>{@render hintContent()}</p>
52
52
  {:else if hint}
53
- <p class={typography.smMuted}>{hint}</p>
53
+ <p class={typography.xsMuted}>{hint}</p>
54
54
  {/if}
55
55
  {/if}
56
56
 
@@ -96,6 +96,6 @@
96
96
  />
97
97
 
98
98
  {#if hint && !error}
99
- <p class={`${typography.smMuted} mt-1`}>{hint}</p>
99
+ <p class={`${typography.xsMuted} mt-1`}>{hint}</p>
100
100
  {/if}
101
101
  </div>
@@ -152,7 +152,7 @@
152
152
  bind:this={triggerElement}
153
153
  {id}
154
154
  {name}
155
- class="flex items-center justify-between gap-2 w-full {sizeClass} bg-gray-50 dark:bg-gray-700 border rounded-lg cursor-pointer text-left transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800
155
+ class="flex items-center justify-between gap-2 w-full {sizeClass} bg-gray-50 dark:bg-gray-800 border rounded-lg cursor-pointer text-left transition-all focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800
156
156
  {error ? 'border-red-500 dark:border-red-500' : 'border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-500 focus:border-blue-500 dark:focus:border-blue-500'}
157
157
  {disabled ? 'opacity-50 cursor-not-allowed' : ''}"
158
158
  {disabled}
@@ -136,7 +136,8 @@
136
136
  <div class="flex gap-3">
137
137
  {#each resolvedActions as action}
138
138
  <Button
139
- size="full"
139
+ size="md"
140
+ class="flex-1"
140
141
  variant={getVariant(action)}
141
142
  {...cleanActionProps(action)}
142
143
  disabled={disabled || action.disabled}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getmicdrop/svelte-components",
3
- "version": "5.3.10",
3
+ "version": "5.3.12",
4
4
  "description": "Shared component library for Micdrop applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",