@thorprovider/blocks 3.0.2 → 4.0.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.
Files changed (192) hide show
  1. package/README.md +61 -21
  2. package/dist/blocks/designs/marketplace-product-card/block.d.ts +12 -0
  3. package/dist/blocks/designs/marketplace-product-card/block.d.ts.map +1 -0
  4. package/dist/blocks/designs/marketplace-product-card/block.js +243 -0
  5. package/dist/blocks/designs/marketplace-product-card/block.js.map +1 -0
  6. package/dist/blocks/designs/marketplace-product-card/block.mjs +233 -0
  7. package/dist/blocks/designs/marketplace-product-card/block.mjs.map +1 -0
  8. package/dist/blocks/designs/marketplace-product-card/index.d.ts +3 -0
  9. package/dist/blocks/designs/marketplace-product-card/index.d.ts.map +1 -0
  10. package/dist/blocks/designs/marketplace-product-card/index.js +36 -0
  11. package/dist/blocks/designs/marketplace-product-card/index.js.map +1 -0
  12. package/dist/blocks/designs/marketplace-product-card/index.mjs +6 -0
  13. package/dist/blocks/designs/marketplace-product-card/index.mjs.map +1 -0
  14. package/dist/blocks/designs/marketplace-product-card/normalize.d.ts +13 -0
  15. package/dist/blocks/designs/marketplace-product-card/normalize.d.ts.map +1 -0
  16. package/dist/blocks/designs/marketplace-product-card/normalize.js +36 -0
  17. package/dist/blocks/designs/marketplace-product-card/normalize.js.map +1 -0
  18. package/dist/blocks/designs/marketplace-product-card/normalize.mjs +12 -0
  19. package/dist/blocks/designs/marketplace-product-card/normalize.mjs.map +1 -0
  20. package/dist/blocks/designs/marketplace-product-card/variants.d.ts +72 -0
  21. package/dist/blocks/designs/marketplace-product-card/variants.d.ts.map +1 -0
  22. package/dist/blocks/designs/marketplace-product-card/variants.js +123 -0
  23. package/dist/blocks/designs/marketplace-product-card/variants.js.map +1 -0
  24. package/dist/blocks/designs/marketplace-product-card/variants.mjs +89 -0
  25. package/dist/blocks/designs/marketplace-product-card/variants.mjs.map +1 -0
  26. package/dist/blocks/e-commerce/checkout-forms/checkbox-check.js +1 -1
  27. package/dist/blocks/e-commerce/checkout-forms/checkbox-check.js.map +1 -1
  28. package/dist/blocks/e-commerce/checkout-forms/checkbox-check.mjs +1 -1
  29. package/dist/blocks/e-commerce/checkout-forms/checkbox-check.mjs.map +1 -1
  30. package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.d.ts +11 -0
  31. package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.d.ts.map +1 -0
  32. package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.js +46 -0
  33. package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.js.map +1 -0
  34. package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.mjs +22 -0
  35. package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.mjs.map +1 -0
  36. package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.d.ts +28 -0
  37. package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.d.ts.map +1 -0
  38. package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.js +278 -0
  39. package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.js.map +1 -0
  40. package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.mjs +260 -0
  41. package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.mjs.map +1 -0
  42. package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.d.ts +12 -9
  43. package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.d.ts.map +1 -1
  44. package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.js +49 -71
  45. package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.js.map +1 -1
  46. package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.mjs +50 -72
  47. package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.mjs.map +1 -1
  48. package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.d.ts.map +1 -1
  49. package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.js +6 -3
  50. package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.js.map +1 -1
  51. package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.mjs +6 -3
  52. package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.mjs.map +1 -1
  53. package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.d.ts +7 -0
  54. package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.d.ts.map +1 -0
  55. package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.js +41 -0
  56. package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.js.map +1 -0
  57. package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.mjs +16 -0
  58. package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.mjs.map +1 -0
  59. package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.d.ts +24 -0
  60. package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.d.ts.map +1 -0
  61. package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.js +75 -0
  62. package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.js.map +1 -0
  63. package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.mjs +58 -0
  64. package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.mjs.map +1 -0
  65. package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.d.ts +3 -2
  66. package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.d.ts.map +1 -1
  67. package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.js +9 -2
  68. package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.js.map +1 -1
  69. package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.mjs +9 -2
  70. package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.mjs.map +1 -1
  71. package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.d.ts +23 -8
  72. package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.d.ts.map +1 -1
  73. package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.js +136 -31
  74. package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.js.map +1 -1
  75. package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.mjs +143 -32
  76. package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.mjs.map +1 -1
  77. package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.d.ts +13 -7
  78. package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.d.ts.map +1 -1
  79. package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.js +179 -28
  80. package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.js.map +1 -1
  81. package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.mjs +180 -29
  82. package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.mjs.map +1 -1
  83. package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.d.ts +20 -0
  84. package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.d.ts.map +1 -0
  85. package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.js +199 -0
  86. package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.js.map +1 -0
  87. package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.mjs +175 -0
  88. package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.mjs.map +1 -0
  89. package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.d.ts +14 -0
  90. package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.d.ts.map +1 -0
  91. package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.js +136 -0
  92. package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.js.map +1 -0
  93. package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.mjs +109 -0
  94. package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.mjs.map +1 -0
  95. package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.d.ts +32 -10
  96. package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.d.ts.map +1 -1
  97. package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.js +265 -147
  98. package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.js.map +1 -1
  99. package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.mjs +272 -148
  100. package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.mjs.map +1 -1
  101. package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.d.ts +13 -0
  102. package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.d.ts.map +1 -0
  103. package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.js +74 -0
  104. package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.js.map +1 -0
  105. package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.mjs +50 -0
  106. package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.mjs.map +1 -0
  107. package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.d.ts +7 -0
  108. package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.d.ts.map +1 -0
  109. package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.js +91 -0
  110. package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.js.map +1 -0
  111. package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.mjs +65 -0
  112. package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.mjs.map +1 -0
  113. package/dist/blocks/e-commerce/checkout-forms/checkout.d.ts +174 -44
  114. package/dist/blocks/e-commerce/checkout-forms/checkout.d.ts.map +1 -1
  115. package/dist/blocks/e-commerce/checkout-forms/checkout.js +532 -108
  116. package/dist/blocks/e-commerce/checkout-forms/checkout.js.map +1 -1
  117. package/dist/blocks/e-commerce/checkout-forms/checkout.mjs +542 -109
  118. package/dist/blocks/e-commerce/checkout-forms/checkout.mjs.map +1 -1
  119. package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.d.ts.map +1 -1
  120. package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.js +44 -20
  121. package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.js.map +1 -1
  122. package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.mjs +44 -20
  123. package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.mjs.map +1 -1
  124. package/dist/blocks/e-commerce/navigation/storefront-navbar.d.ts.map +1 -1
  125. package/dist/blocks/e-commerce/navigation/storefront-navbar.js +21 -10
  126. package/dist/blocks/e-commerce/navigation/storefront-navbar.js.map +1 -1
  127. package/dist/blocks/e-commerce/navigation/storefront-navbar.mjs +21 -10
  128. package/dist/blocks/e-commerce/navigation/storefront-navbar.mjs.map +1 -1
  129. package/dist/blocks/e-commerce/product-list/product-card.d.ts.map +1 -1
  130. package/dist/blocks/e-commerce/product-list/product-card.js +36 -9
  131. package/dist/blocks/e-commerce/product-list/product-card.js.map +1 -1
  132. package/dist/blocks/e-commerce/product-list/product-card.mjs +36 -9
  133. package/dist/blocks/e-commerce/product-list/product-card.mjs.map +1 -1
  134. package/dist/blocks/e-commerce/product-list/product-showcase-1.d.ts.map +1 -1
  135. package/dist/blocks/e-commerce/product-list/product-showcase-1.js +7 -2
  136. package/dist/blocks/e-commerce/product-list/product-showcase-1.js.map +1 -1
  137. package/dist/blocks/e-commerce/product-list/product-showcase-1.mjs +7 -2
  138. package/dist/blocks/e-commerce/product-list/product-showcase-1.mjs.map +1 -1
  139. package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.d.ts.map +1 -1
  140. package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.js +5 -1
  141. package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.js.map +1 -1
  142. package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.mjs +5 -1
  143. package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.mjs.map +1 -1
  144. package/dist/blocks/e-commerce/storefront-hero/storefront-hero.d.ts.map +1 -1
  145. package/dist/blocks/e-commerce/storefront-hero/storefront-hero.js +71 -51
  146. package/dist/blocks/e-commerce/storefront-hero/storefront-hero.js.map +1 -1
  147. package/dist/blocks/e-commerce/storefront-hero/storefront-hero.mjs +71 -51
  148. package/dist/blocks/e-commerce/storefront-hero/storefront-hero.mjs.map +1 -1
  149. package/dist/blocks/marketing/banners/banner-1.d.ts.map +1 -1
  150. package/dist/blocks/marketing/banners/banner-1.js +15 -27
  151. package/dist/blocks/marketing/banners/banner-1.js.map +1 -1
  152. package/dist/blocks/marketing/banners/banner-1.mjs +16 -28
  153. package/dist/blocks/marketing/banners/banner-1.mjs.map +1 -1
  154. package/dist/index.d.ts +6 -3
  155. package/dist/index.d.ts.map +1 -1
  156. package/dist/index.js +5 -0
  157. package/dist/index.js.map +1 -1
  158. package/dist/index.mjs +4 -0
  159. package/dist/index.mjs.map +1 -1
  160. package/dist/lib/contracts/marketplace-product-card.d.ts +324 -0
  161. package/dist/lib/contracts/marketplace-product-card.d.ts.map +1 -0
  162. package/dist/lib/contracts/marketplace-product-card.js +85 -0
  163. package/dist/lib/contracts/marketplace-product-card.js.map +1 -0
  164. package/dist/lib/contracts/marketplace-product-card.mjs +61 -0
  165. package/dist/lib/contracts/marketplace-product-card.mjs.map +1 -0
  166. package/dist/lib/contracts.d.ts +1861 -88
  167. package/dist/lib/contracts.d.ts.map +1 -1
  168. package/dist/lib/contracts.js +252 -25
  169. package/dist/lib/contracts.js.map +1 -1
  170. package/dist/lib/contracts.mjs +208 -5
  171. package/dist/lib/contracts.mjs.map +1 -1
  172. package/dist/lib/money-schema.d.ts +19 -0
  173. package/dist/lib/money-schema.d.ts.map +1 -0
  174. package/dist/lib/money-schema.js +33 -0
  175. package/dist/lib/money-schema.js.map +1 -0
  176. package/dist/lib/money-schema.mjs +9 -0
  177. package/dist/lib/money-schema.mjs.map +1 -0
  178. package/dist/lib/motion.d.ts +29 -0
  179. package/dist/lib/motion.d.ts.map +1 -0
  180. package/dist/lib/motion.js +65 -0
  181. package/dist/lib/motion.js.map +1 -0
  182. package/dist/lib/motion.mjs +41 -0
  183. package/dist/lib/motion.mjs.map +1 -0
  184. package/dist/ui/accordion.d.ts +3 -1
  185. package/dist/ui/accordion.d.ts.map +1 -1
  186. package/dist/ui/accordion.js +21 -5
  187. package/dist/ui/accordion.js.map +1 -1
  188. package/dist/ui/accordion.mjs +21 -5
  189. package/dist/ui/accordion.mjs.map +1 -1
  190. package/dist/ui/input-group.d.ts +1 -1
  191. package/package.json +18 -3
  192. package/dist/.tsbuildinfo +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/designs/marketplace-product-card/variants.ts"],"sourcesContent":["export type StockTone = 'success' | 'attention' | 'destructive'\n\nexport type OptionValue = {\n id: string\n label: string\n image?: string\n imageAlt?: string\n}\n\nexport type ProductOption = {\n id: string\n name: string\n kind: 'image' | 'text'\n values: OptionValue[]\n}\n\nexport type ProductVariant = {\n id: string\n optionValueIds: Record<string, string>\n price: number\n compareAtPrice?: number\n image?: string\n imageAlt?: string\n available: boolean\n stockLabel: string\n stockTone: StockTone\n}\n\nexport type Product = {\n id: string\n brand: string\n title: string\n badge: string\n rating: number\n reviewCount: number\n ratingLabel: string\n soldLabel: string\n shippingLabel: string\n deliveryLabel: string\n currency: string\n locale: string\n image?: string\n options: ProductOption[]\n variants: ProductVariant[]\n}\n\nexport type CardLabels = {\n addToCart: string\n wishlistAdd: string\n wishlistRemove: string\n unavailableOption: string\n unavailablePrice: string\n outOfStock: string\n optionSeparator: string\n}\n\nexport type Glyphs = {\n fullStar: string\n emptyStar: string\n heart: string\n heartFilled: string\n}\n\nexport type Selection = Record<string, string>\n\nexport function matchesSelection(variant: ProductVariant, selection: Selection): boolean {\n return Object.entries(selection).every(\n ([optionId, valueId]) => variant.optionValueIds[optionId] === valueId,\n )\n}\n\nexport function firstAvailableSelection(product: Product): Selection {\n const variant = product.variants.find((candidate) => candidate.available) ?? product.variants[0]\n return variant ? { ...variant.optionValueIds } : {}\n}\n\nexport function findVariant(product: Product, selection: Selection): ProductVariant | undefined {\n return product.variants.find((variant) => matchesSelection(variant, selection))\n}\n\nexport function findAvailableVariant(\n product: Product,\n selection: Selection,\n): ProductVariant | undefined {\n return product.variants.find(\n (variant) => variant.available && matchesSelection(variant, selection),\n )\n}\n\nexport function isValueDisabled(\n product: Product,\n selection: Selection,\n optionIndex: number,\n valueId: string,\n): boolean {\n const option = product.options[optionIndex]\n if (!option) return true\n\n const isLast = optionIndex === product.options.length - 1\n\n return !product.variants.some((variant) => {\n if (!variant.available || variant.optionValueIds[option.id] !== valueId) return false\n if (!isLast) return true\n\n return product.options\n .slice(0, optionIndex)\n .every((earlier) => variant.optionValueIds[earlier.id] === selection[earlier.id])\n })\n}\n\nexport function selectValue(\n product: Product,\n selection: Selection,\n optionIndex: number,\n valueId: string,\n): Selection {\n const option = product.options[optionIndex]\n if (!option) return selection\n\n const next = { ...selection, [option.id]: valueId }\n if (findAvailableVariant(product, next)) return next\n\n const earlier = product.options.slice(0, optionIndex + 1)\n const matches = product.variants.filter(\n (variant) =>\n variant.available &&\n earlier.every((entry) => variant.optionValueIds[entry.id] === next[entry.id]),\n )\n if (matches.length === 0) return selection\n\n const preserved = (variant: ProductVariant) =>\n product.options.reduce(\n (count, entry) =>\n count + (variant.optionValueIds[entry.id] === selection[entry.id] ? 1 : 0),\n 0,\n )\n\n const best = matches.reduce((current, candidate) =>\n preserved(candidate) > preserved(current) ? candidate : current,\n )\n return { ...best.optionValueIds }\n}\n\nexport function firstNonEmpty(...values: Array<string | undefined>): string | undefined {\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (trimmed.length > 0) return trimmed\n }\n return undefined\n}\n\nexport function resolveVariantImage(\n product: Product,\n variant: ProductVariant | undefined,\n selection: Selection,\n): { src: string | undefined; alt: string } {\n const imageOption = product.options.find((option) => option.kind === 'image')\n const imageValue = imageOption\n ? imageOption.values.find((value) => value.id === selection[imageOption.id])\n : undefined\n\n return {\n src: firstNonEmpty(variant?.image, imageValue?.image, product.image),\n alt:\n firstNonEmpty(variant?.imageAlt, imageValue?.imageAlt, product.title) ?? product.title,\n }\n}\n\nexport function formatPrice(amount: number, locale: string, currency: string): string {\n return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount)\n}\n\nexport function discountPercent(price: number, compareAtPrice?: number): number | null {\n if (compareAtPrice === undefined || compareAtPrice <= price) return null\n return Math.round((1 - price / compareAtPrice) * 100)\n}\n\nexport function formatDiscount(percent: number, locale: string): string {\n return new Intl.NumberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: 0,\n }).format(-percent / 100)\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,89 @@
1
+ function matchesSelection(variant, selection) {
2
+ return Object.entries(selection).every(
3
+ ([optionId, valueId]) => variant.optionValueIds[optionId] === valueId
4
+ );
5
+ }
6
+ function firstAvailableSelection(product) {
7
+ const variant = product.variants.find((candidate) => candidate.available) ?? product.variants[0];
8
+ return variant ? { ...variant.optionValueIds } : {};
9
+ }
10
+ function findVariant(product, selection) {
11
+ return product.variants.find((variant) => matchesSelection(variant, selection));
12
+ }
13
+ function findAvailableVariant(product, selection) {
14
+ return product.variants.find(
15
+ (variant) => variant.available && matchesSelection(variant, selection)
16
+ );
17
+ }
18
+ function isValueDisabled(product, selection, optionIndex, valueId) {
19
+ const option = product.options[optionIndex];
20
+ if (!option) return true;
21
+ const isLast = optionIndex === product.options.length - 1;
22
+ return !product.variants.some((variant) => {
23
+ if (!variant.available || variant.optionValueIds[option.id] !== valueId) return false;
24
+ if (!isLast) return true;
25
+ return product.options.slice(0, optionIndex).every((earlier) => variant.optionValueIds[earlier.id] === selection[earlier.id]);
26
+ });
27
+ }
28
+ function selectValue(product, selection, optionIndex, valueId) {
29
+ const option = product.options[optionIndex];
30
+ if (!option) return selection;
31
+ const next = { ...selection, [option.id]: valueId };
32
+ if (findAvailableVariant(product, next)) return next;
33
+ const earlier = product.options.slice(0, optionIndex + 1);
34
+ const matches = product.variants.filter(
35
+ (variant) => variant.available && earlier.every((entry) => variant.optionValueIds[entry.id] === next[entry.id])
36
+ );
37
+ if (matches.length === 0) return selection;
38
+ const preserved = (variant) => product.options.reduce(
39
+ (count, entry) => count + (variant.optionValueIds[entry.id] === selection[entry.id] ? 1 : 0),
40
+ 0
41
+ );
42
+ const best = matches.reduce(
43
+ (current, candidate) => preserved(candidate) > preserved(current) ? candidate : current
44
+ );
45
+ return { ...best.optionValueIds };
46
+ }
47
+ function firstNonEmpty(...values) {
48
+ for (const value of values) {
49
+ if (typeof value !== "string") continue;
50
+ const trimmed = value.trim();
51
+ if (trimmed.length > 0) return trimmed;
52
+ }
53
+ return void 0;
54
+ }
55
+ function resolveVariantImage(product, variant, selection) {
56
+ const imageOption = product.options.find((option) => option.kind === "image");
57
+ const imageValue = imageOption ? imageOption.values.find((value) => value.id === selection[imageOption.id]) : void 0;
58
+ return {
59
+ src: firstNonEmpty(variant?.image, imageValue?.image, product.image),
60
+ alt: firstNonEmpty(variant?.imageAlt, imageValue?.imageAlt, product.title) ?? product.title
61
+ };
62
+ }
63
+ function formatPrice(amount, locale, currency) {
64
+ return new Intl.NumberFormat(locale, { style: "currency", currency }).format(amount);
65
+ }
66
+ function discountPercent(price, compareAtPrice) {
67
+ if (compareAtPrice === void 0 || compareAtPrice <= price) return null;
68
+ return Math.round((1 - price / compareAtPrice) * 100);
69
+ }
70
+ function formatDiscount(percent, locale) {
71
+ return new Intl.NumberFormat(locale, {
72
+ style: "percent",
73
+ maximumFractionDigits: 0
74
+ }).format(-percent / 100);
75
+ }
76
+ export {
77
+ discountPercent,
78
+ findAvailableVariant,
79
+ findVariant,
80
+ firstAvailableSelection,
81
+ firstNonEmpty,
82
+ formatDiscount,
83
+ formatPrice,
84
+ isValueDisabled,
85
+ matchesSelection,
86
+ resolveVariantImage,
87
+ selectValue
88
+ };
89
+ //# sourceMappingURL=variants.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/designs/marketplace-product-card/variants.ts"],"sourcesContent":["export type StockTone = 'success' | 'attention' | 'destructive'\n\nexport type OptionValue = {\n id: string\n label: string\n image?: string\n imageAlt?: string\n}\n\nexport type ProductOption = {\n id: string\n name: string\n kind: 'image' | 'text'\n values: OptionValue[]\n}\n\nexport type ProductVariant = {\n id: string\n optionValueIds: Record<string, string>\n price: number\n compareAtPrice?: number\n image?: string\n imageAlt?: string\n available: boolean\n stockLabel: string\n stockTone: StockTone\n}\n\nexport type Product = {\n id: string\n brand: string\n title: string\n badge: string\n rating: number\n reviewCount: number\n ratingLabel: string\n soldLabel: string\n shippingLabel: string\n deliveryLabel: string\n currency: string\n locale: string\n image?: string\n options: ProductOption[]\n variants: ProductVariant[]\n}\n\nexport type CardLabels = {\n addToCart: string\n wishlistAdd: string\n wishlistRemove: string\n unavailableOption: string\n unavailablePrice: string\n outOfStock: string\n optionSeparator: string\n}\n\nexport type Glyphs = {\n fullStar: string\n emptyStar: string\n heart: string\n heartFilled: string\n}\n\nexport type Selection = Record<string, string>\n\nexport function matchesSelection(variant: ProductVariant, selection: Selection): boolean {\n return Object.entries(selection).every(\n ([optionId, valueId]) => variant.optionValueIds[optionId] === valueId,\n )\n}\n\nexport function firstAvailableSelection(product: Product): Selection {\n const variant = product.variants.find((candidate) => candidate.available) ?? product.variants[0]\n return variant ? { ...variant.optionValueIds } : {}\n}\n\nexport function findVariant(product: Product, selection: Selection): ProductVariant | undefined {\n return product.variants.find((variant) => matchesSelection(variant, selection))\n}\n\nexport function findAvailableVariant(\n product: Product,\n selection: Selection,\n): ProductVariant | undefined {\n return product.variants.find(\n (variant) => variant.available && matchesSelection(variant, selection),\n )\n}\n\nexport function isValueDisabled(\n product: Product,\n selection: Selection,\n optionIndex: number,\n valueId: string,\n): boolean {\n const option = product.options[optionIndex]\n if (!option) return true\n\n const isLast = optionIndex === product.options.length - 1\n\n return !product.variants.some((variant) => {\n if (!variant.available || variant.optionValueIds[option.id] !== valueId) return false\n if (!isLast) return true\n\n return product.options\n .slice(0, optionIndex)\n .every((earlier) => variant.optionValueIds[earlier.id] === selection[earlier.id])\n })\n}\n\nexport function selectValue(\n product: Product,\n selection: Selection,\n optionIndex: number,\n valueId: string,\n): Selection {\n const option = product.options[optionIndex]\n if (!option) return selection\n\n const next = { ...selection, [option.id]: valueId }\n if (findAvailableVariant(product, next)) return next\n\n const earlier = product.options.slice(0, optionIndex + 1)\n const matches = product.variants.filter(\n (variant) =>\n variant.available &&\n earlier.every((entry) => variant.optionValueIds[entry.id] === next[entry.id]),\n )\n if (matches.length === 0) return selection\n\n const preserved = (variant: ProductVariant) =>\n product.options.reduce(\n (count, entry) =>\n count + (variant.optionValueIds[entry.id] === selection[entry.id] ? 1 : 0),\n 0,\n )\n\n const best = matches.reduce((current, candidate) =>\n preserved(candidate) > preserved(current) ? candidate : current,\n )\n return { ...best.optionValueIds }\n}\n\nexport function firstNonEmpty(...values: Array<string | undefined>): string | undefined {\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (trimmed.length > 0) return trimmed\n }\n return undefined\n}\n\nexport function resolveVariantImage(\n product: Product,\n variant: ProductVariant | undefined,\n selection: Selection,\n): { src: string | undefined; alt: string } {\n const imageOption = product.options.find((option) => option.kind === 'image')\n const imageValue = imageOption\n ? imageOption.values.find((value) => value.id === selection[imageOption.id])\n : undefined\n\n return {\n src: firstNonEmpty(variant?.image, imageValue?.image, product.image),\n alt:\n firstNonEmpty(variant?.imageAlt, imageValue?.imageAlt, product.title) ?? product.title,\n }\n}\n\nexport function formatPrice(amount: number, locale: string, currency: string): string {\n return new Intl.NumberFormat(locale, { style: 'currency', currency }).format(amount)\n}\n\nexport function discountPercent(price: number, compareAtPrice?: number): number | null {\n if (compareAtPrice === undefined || compareAtPrice <= price) return null\n return Math.round((1 - price / compareAtPrice) * 100)\n}\n\nexport function formatDiscount(percent: number, locale: string): string {\n return new Intl.NumberFormat(locale, {\n style: 'percent',\n maximumFractionDigits: 0,\n }).format(-percent / 100)\n}\n"],"mappings":"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","names":[]}
@@ -36,7 +36,7 @@ function CheckboxCheck({ className, indeterminate, ...props }) {
36
36
  const [length, setLength] = (0, import_react.useState)(15);
37
37
  (0, import_react.useLayoutEffect)(() => {
38
38
  const path = pathRef.current;
39
- if (path) {
39
+ if (path && typeof path.getTotalLength === "function") {
40
40
  setLength(Math.ceil(path.getTotalLength()));
41
41
  }
42
42
  }, []);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkbox-check.tsx"],"sourcesContent":["'use client'\n\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox'\n\nimport { cn } from '../../../lib/utils'\n\nconst BOX_MS = 150\nconst DRAW_MS = 350\nconst UNCHECK_MS = 150\nconst EASE = 'cubic-bezier(0.22, 1, 0.36, 1)'\n\nexport function CheckboxCheck({ className, indeterminate, ...props }: CheckboxPrimitive.Root.Props) {\n const pathRef = useRef<SVGPathElement>(null)\n const [length, setLength] = useState(15)\n\n useLayoutEffect(() => {\n const path = pathRef.current\n if (path) {\n setLength(Math.ceil(path.getTotalLength()))\n }\n }, [])\n\n const mark = indeterminate ? 'M2.12 5.08H8.47' : 'M1.69 5.08L3.81 7.2L8.47 2.54'\n\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary',\n 'motion-reduce:transition-none',\n className\n )}\n style={{ transition: `background-color ${BOX_MS}ms ${EASE}, border-color ${BOX_MS}ms ${EASE}` }}\n indeterminate={indeterminate}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n keepMounted\n data-slot=\"checkbox-indicator\"\n className={cn(\n 'grid size-3.5 place-content-center text-current',\n '[&_path]:[transition:stroke-dashoffset_var(--check-uncheck)_var(--check-ease)]',\n '[&_path]:[stroke-dashoffset:var(--check-len)]',\n 'data-checked:[&_path]:[stroke-dashoffset:0]',\n 'data-checked:[&_path]:[transition-duration:var(--check-draw)]',\n 'motion-reduce:[&_path]:transition-none'\n )}\n style={\n {\n '--check-len': length,\n '--check-draw': `${DRAW_MS}ms`,\n '--check-uncheck': `${UNCHECK_MS}ms`,\n '--check-ease': EASE,\n } as React.CSSProperties\n }\n >\n <svg viewBox=\"0 0 10.1668 10.1668\" fill=\"none\" aria-hidden className=\"size-full overflow-visible\">\n <path\n ref={pathRef}\n d={mark}\n stroke=\"currentColor\"\n strokeWidth={0.9}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ strokeDasharray: length }}\n />\n </svg>\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport default CheckboxCheck"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0DU;AAxDV,mBAAkD;AAClD,sBAA8C;AAE9C,mBAAmB;AAEnB,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,aAAa;AACnB,MAAM,OAAO;AAEN,SAAS,cAAc,EAAE,WAAW,eAAe,GAAG,MAAM,GAAiC;AAClG,QAAM,cAAU,qBAAuB,IAAI;AAC3C,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,EAAE;AAEvC,oCAAgB,MAAM;AACpB,UAAM,OAAO,QAAQ;AACrB,QAAI,MAAM;AACR,gBAAU,KAAK,KAAK,KAAK,eAAe,CAAC,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,gBAAgB,oBAAoB;AAEjD,SACE;AAAA,IAAC,gBAAAA,SAAkB;AAAA,IAAlB;AAAA,MACC,aAAU;AAAA,MACV,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,YAAY,oBAAoB,MAAM,MAAM,IAAI,kBAAkB,MAAM,MAAM,IAAI,GAAG;AAAA,MAC9F;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,QAAC,gBAAAA,SAAkB;AAAA,QAAlB;AAAA,UACC,aAAW;AAAA,UACX,aAAU;AAAA,UACV,eAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,OACE;AAAA,YACE,eAAe;AAAA,YACf,gBAAgB,GAAG,OAAO;AAAA,YAC1B,mBAAmB,GAAG,UAAU;AAAA,YAChC,gBAAgB;AAAA,UAClB;AAAA,UAGF,sDAAC,SAAI,SAAQ,uBAAsB,MAAK,QAAO,eAAW,MAAC,WAAU,8BACnE;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,GAAG;AAAA,cACH,QAAO;AAAA,cACP,aAAa;AAAA,cACb,eAAc;AAAA,cACd,gBAAe;AAAA,cACf,OAAO,EAAE,iBAAiB,OAAO;AAAA;AAAA,UACnC,GACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,yBAAQ;","names":["CheckboxPrimitive"]}
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkbox-check.tsx"],"sourcesContent":["'use client'\n\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox'\n\nimport { cn } from '../../../lib/utils'\n\nconst BOX_MS = 150\nconst DRAW_MS = 350\nconst UNCHECK_MS = 150\nconst EASE = 'cubic-bezier(0.22, 1, 0.36, 1)'\n\nexport function CheckboxCheck({ className, indeterminate, ...props }: CheckboxPrimitive.Root.Props) {\n const pathRef = useRef<SVGPathElement>(null)\n const [length, setLength] = useState(15)\n\n useLayoutEffect(() => {\n const path = pathRef.current\n if (path && typeof path.getTotalLength === 'function') {\n setLength(Math.ceil(path.getTotalLength()))\n }\n }, [])\n\n const mark = indeterminate ? 'M2.12 5.08H8.47' : 'M1.69 5.08L3.81 7.2L8.47 2.54'\n\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary',\n 'motion-reduce:transition-none',\n className\n )}\n style={{ transition: `background-color ${BOX_MS}ms ${EASE}, border-color ${BOX_MS}ms ${EASE}` }}\n indeterminate={indeterminate}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n keepMounted\n data-slot=\"checkbox-indicator\"\n className={cn(\n 'grid size-3.5 place-content-center text-current',\n '[&_path]:[transition:stroke-dashoffset_var(--check-uncheck)_var(--check-ease)]',\n '[&_path]:[stroke-dashoffset:var(--check-len)]',\n 'data-checked:[&_path]:[stroke-dashoffset:0]',\n 'data-checked:[&_path]:[transition-duration:var(--check-draw)]',\n 'motion-reduce:[&_path]:transition-none'\n )}\n style={\n {\n '--check-len': length,\n '--check-draw': `${DRAW_MS}ms`,\n '--check-uncheck': `${UNCHECK_MS}ms`,\n '--check-ease': EASE,\n } as React.CSSProperties\n }\n >\n <svg viewBox=\"0 0 10.1668 10.1668\" fill=\"none\" aria-hidden className=\"size-full overflow-visible\">\n <path\n ref={pathRef}\n d={mark}\n stroke=\"currentColor\"\n strokeWidth={0.9}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ strokeDasharray: length }}\n />\n </svg>\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport default CheckboxCheck"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0DU;AAxDV,mBAAkD;AAClD,sBAA8C;AAE9C,mBAAmB;AAEnB,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,aAAa;AACnB,MAAM,OAAO;AAEN,SAAS,cAAc,EAAE,WAAW,eAAe,GAAG,MAAM,GAAiC;AAClG,QAAM,cAAU,qBAAuB,IAAI;AAC3C,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,EAAE;AAEvC,oCAAgB,MAAM;AACpB,UAAM,OAAO,QAAQ;AACrB,QAAI,QAAQ,OAAO,KAAK,mBAAmB,YAAY;AACrD,gBAAU,KAAK,KAAK,KAAK,eAAe,CAAC,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,gBAAgB,oBAAoB;AAEjD,SACE;AAAA,IAAC,gBAAAA,SAAkB;AAAA,IAAlB;AAAA,MACC,aAAU;AAAA,MACV,eAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,YAAY,oBAAoB,MAAM,MAAM,IAAI,kBAAkB,MAAM,MAAM,IAAI,GAAG;AAAA,MAC9F;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,QAAC,gBAAAA,SAAkB;AAAA,QAAlB;AAAA,UACC,aAAW;AAAA,UACX,aAAU;AAAA,UACV,eAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,OACE;AAAA,YACE,eAAe;AAAA,YACf,gBAAgB,GAAG,OAAO;AAAA,YAC1B,mBAAmB,GAAG,UAAU;AAAA,YAChC,gBAAgB;AAAA,UAClB;AAAA,UAGF,sDAAC,SAAI,SAAQ,uBAAsB,MAAK,QAAO,eAAW,MAAC,WAAU,8BACnE;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,GAAG;AAAA,cACH,QAAO;AAAA,cACP,aAAa;AAAA,cACb,eAAc;AAAA,cACd,gBAAe;AAAA,cACf,OAAO,EAAE,iBAAiB,OAAO;AAAA;AAAA,UACnC,GACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,yBAAQ;","names":["CheckboxPrimitive"]}
@@ -12,7 +12,7 @@ function CheckboxCheck({ className, indeterminate, ...props }) {
12
12
  const [length, setLength] = useState(15);
13
13
  useLayoutEffect(() => {
14
14
  const path = pathRef.current;
15
- if (path) {
15
+ if (path && typeof path.getTotalLength === "function") {
16
16
  setLength(Math.ceil(path.getTotalLength()));
17
17
  }
18
18
  }, []);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkbox-check.tsx"],"sourcesContent":["'use client'\n\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox'\n\nimport { cn } from '../../../lib/utils'\n\nconst BOX_MS = 150\nconst DRAW_MS = 350\nconst UNCHECK_MS = 150\nconst EASE = 'cubic-bezier(0.22, 1, 0.36, 1)'\n\nexport function CheckboxCheck({ className, indeterminate, ...props }: CheckboxPrimitive.Root.Props) {\n const pathRef = useRef<SVGPathElement>(null)\n const [length, setLength] = useState(15)\n\n useLayoutEffect(() => {\n const path = pathRef.current\n if (path) {\n setLength(Math.ceil(path.getTotalLength()))\n }\n }, [])\n\n const mark = indeterminate ? 'M2.12 5.08H8.47' : 'M1.69 5.08L3.81 7.2L8.47 2.54'\n\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary',\n 'motion-reduce:transition-none',\n className\n )}\n style={{ transition: `background-color ${BOX_MS}ms ${EASE}, border-color ${BOX_MS}ms ${EASE}` }}\n indeterminate={indeterminate}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n keepMounted\n data-slot=\"checkbox-indicator\"\n className={cn(\n 'grid size-3.5 place-content-center text-current',\n '[&_path]:[transition:stroke-dashoffset_var(--check-uncheck)_var(--check-ease)]',\n '[&_path]:[stroke-dashoffset:var(--check-len)]',\n 'data-checked:[&_path]:[stroke-dashoffset:0]',\n 'data-checked:[&_path]:[transition-duration:var(--check-draw)]',\n 'motion-reduce:[&_path]:transition-none'\n )}\n style={\n {\n '--check-len': length,\n '--check-draw': `${DRAW_MS}ms`,\n '--check-uncheck': `${UNCHECK_MS}ms`,\n '--check-ease': EASE,\n } as React.CSSProperties\n }\n >\n <svg viewBox=\"0 0 10.1668 10.1668\" fill=\"none\" aria-hidden className=\"size-full overflow-visible\">\n <path\n ref={pathRef}\n d={mark}\n stroke=\"currentColor\"\n strokeWidth={0.9}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ strokeDasharray: length }}\n />\n </svg>\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport default CheckboxCheck"],"mappings":";AA0DU;AAxDV,SAAS,iBAAiB,QAAQ,gBAAgB;AAClD,SAAS,YAAY,yBAAyB;AAE9C,SAAS,UAAU;AAEnB,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,aAAa;AACnB,MAAM,OAAO;AAEN,SAAS,cAAc,EAAE,WAAW,eAAe,GAAG,MAAM,GAAiC;AAClG,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AAEvC,kBAAgB,MAAM;AACpB,UAAM,OAAO,QAAQ;AACrB,QAAI,MAAM;AACR,gBAAU,KAAK,KAAK,KAAK,eAAe,CAAC,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,gBAAgB,oBAAoB;AAEjD,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,YAAY,oBAAoB,MAAM,MAAM,IAAI,kBAAkB,MAAM,MAAM,IAAI,GAAG;AAAA,MAC9F;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,QAAC,kBAAkB;AAAA,QAAlB;AAAA,UACC,aAAW;AAAA,UACX,aAAU;AAAA,UACV,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,OACE;AAAA,YACE,eAAe;AAAA,YACf,gBAAgB,GAAG,OAAO;AAAA,YAC1B,mBAAmB,GAAG,UAAU;AAAA,YAChC,gBAAgB;AAAA,UAClB;AAAA,UAGF,8BAAC,SAAI,SAAQ,uBAAsB,MAAK,QAAO,eAAW,MAAC,WAAU,8BACnE;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,GAAG;AAAA,cACH,QAAO;AAAA,cACP,aAAa;AAAA,cACb,eAAc;AAAA,cACd,gBAAe;AAAA,cACf,OAAO,EAAE,iBAAiB,OAAO;AAAA;AAAA,UACnC,GACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,yBAAQ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkbox-check.tsx"],"sourcesContent":["'use client'\n\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox'\n\nimport { cn } from '../../../lib/utils'\n\nconst BOX_MS = 150\nconst DRAW_MS = 350\nconst UNCHECK_MS = 150\nconst EASE = 'cubic-bezier(0.22, 1, 0.36, 1)'\n\nexport function CheckboxCheck({ className, indeterminate, ...props }: CheckboxPrimitive.Root.Props) {\n const pathRef = useRef<SVGPathElement>(null)\n const [length, setLength] = useState(15)\n\n useLayoutEffect(() => {\n const path = pathRef.current\n if (path && typeof path.getTotalLength === 'function') {\n setLength(Math.ceil(path.getTotalLength()))\n }\n }, [])\n\n const mark = indeterminate ? 'M2.12 5.08H8.47' : 'M1.69 5.08L3.81 7.2L8.47 2.54'\n\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary',\n 'motion-reduce:transition-none',\n className\n )}\n style={{ transition: `background-color ${BOX_MS}ms ${EASE}, border-color ${BOX_MS}ms ${EASE}` }}\n indeterminate={indeterminate}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n keepMounted\n data-slot=\"checkbox-indicator\"\n className={cn(\n 'grid size-3.5 place-content-center text-current',\n '[&_path]:[transition:stroke-dashoffset_var(--check-uncheck)_var(--check-ease)]',\n '[&_path]:[stroke-dashoffset:var(--check-len)]',\n 'data-checked:[&_path]:[stroke-dashoffset:0]',\n 'data-checked:[&_path]:[transition-duration:var(--check-draw)]',\n 'motion-reduce:[&_path]:transition-none'\n )}\n style={\n {\n '--check-len': length,\n '--check-draw': `${DRAW_MS}ms`,\n '--check-uncheck': `${UNCHECK_MS}ms`,\n '--check-ease': EASE,\n } as React.CSSProperties\n }\n >\n <svg viewBox=\"0 0 10.1668 10.1668\" fill=\"none\" aria-hidden className=\"size-full overflow-visible\">\n <path\n ref={pathRef}\n d={mark}\n stroke=\"currentColor\"\n strokeWidth={0.9}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{ strokeDasharray: length }}\n />\n </svg>\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport default CheckboxCheck"],"mappings":";AA0DU;AAxDV,SAAS,iBAAiB,QAAQ,gBAAgB;AAClD,SAAS,YAAY,yBAAyB;AAE9C,SAAS,UAAU;AAEnB,MAAM,SAAS;AACf,MAAM,UAAU;AAChB,MAAM,aAAa;AACnB,MAAM,OAAO;AAEN,SAAS,cAAc,EAAE,WAAW,eAAe,GAAG,MAAM,GAAiC;AAClG,QAAM,UAAU,OAAuB,IAAI;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AAEvC,kBAAgB,MAAM;AACpB,UAAM,OAAO,QAAQ;AACrB,QAAI,QAAQ,OAAO,KAAK,mBAAmB,YAAY;AACrD,gBAAU,KAAK,KAAK,KAAK,eAAe,CAAC,CAAC;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,gBAAgB,oBAAoB;AAEjD,SACE;AAAA,IAAC,kBAAkB;AAAA,IAAlB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,OAAO,EAAE,YAAY,oBAAoB,MAAM,MAAM,IAAI,kBAAkB,MAAM,MAAM,IAAI,GAAG;AAAA,MAC9F;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,QAAC,kBAAkB;AAAA,QAAlB;AAAA,UACC,aAAW;AAAA,UACX,aAAU;AAAA,UACV,WAAW;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,UACA,OACE;AAAA,YACE,eAAe;AAAA,YACf,gBAAgB,GAAG,OAAO;AAAA,YAC1B,mBAAmB,GAAG,UAAU;AAAA,YAChC,gBAAgB;AAAA,UAClB;AAAA,UAGF,8BAAC,SAAI,SAAQ,uBAAsB,MAAK,QAAO,eAAW,MAAC,WAAU,8BACnE;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,GAAG;AAAA,cACH,QAAO;AAAA,cACP,aAAa;AAAA,cACb,eAAc;AAAA,cACd,gBAAe;AAAA,cACf,OAAO,EAAE,iBAAiB,OAAO;AAAA;AAAA,UACnC,GACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,yBAAQ;","names":[]}
@@ -0,0 +1,11 @@
1
+ import type { CheckoutAddressValues } from '@thorprovider/types';
2
+ /**
3
+ * Compare two controlled addresses for the saved-address affordances.
4
+ *
5
+ * The host may serialise an absent optional field as `undefined` or as an
6
+ * empty string; both mean "not supplied" and must compare equal. Whitespace is
7
+ * ignored so a value that only gained surrounding spaces is still the same
8
+ * address. Every address key participates.
9
+ */
10
+ export declare function addressesEqual(a: CheckoutAddressValues, b: CheckoutAddressValues): boolean;
11
+ //# sourceMappingURL=checkout-address-equality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-address-equality.d.ts","sourceRoot":"","sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-address-equality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAmBhE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,qBAAqB,EACxB,CAAC,EAAE,qBAAqB,GACvB,OAAO,CAET"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var checkout_address_equality_exports = {};
20
+ __export(checkout_address_equality_exports, {
21
+ addressesEqual: () => addressesEqual
22
+ });
23
+ module.exports = __toCommonJS(checkout_address_equality_exports);
24
+ const ADDRESS_KEYS = [
25
+ "firstName",
26
+ "lastName",
27
+ "address1",
28
+ "address2",
29
+ "company",
30
+ "city",
31
+ "province",
32
+ "postalCode",
33
+ "countryCode",
34
+ "phone"
35
+ ];
36
+ function normalize(value) {
37
+ return (value ?? "").trim();
38
+ }
39
+ function addressesEqual(a, b) {
40
+ return ADDRESS_KEYS.every((key) => normalize(a[key]) === normalize(b[key]));
41
+ }
42
+ // Annotate the CommonJS export names for ESM import in node:
43
+ 0 && (module.exports = {
44
+ addressesEqual
45
+ });
46
+ //# sourceMappingURL=checkout-address-equality.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-address-equality.ts"],"sourcesContent":["import type { CheckoutAddressValues } from '@thorprovider/types'\n\nconst ADDRESS_KEYS: Array<keyof CheckoutAddressValues> = [\n 'firstName',\n 'lastName',\n 'address1',\n 'address2',\n 'company',\n 'city',\n 'province',\n 'postalCode',\n 'countryCode',\n 'phone',\n]\n\nfunction normalize(value: string | undefined): string {\n return (value ?? '').trim()\n}\n\n/**\n * Compare two controlled addresses for the saved-address affordances.\n *\n * The host may serialise an absent optional field as `undefined` or as an\n * empty string; both mean \"not supplied\" and must compare equal. Whitespace is\n * ignored so a value that only gained surrounding spaces is still the same\n * address. Every address key participates.\n */\nexport function addressesEqual(\n a: CheckoutAddressValues,\n b: CheckoutAddressValues,\n): boolean {\n return ADDRESS_KEYS.every((key) => normalize(a[key]) === normalize(b[key]))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,MAAM,eAAmD;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,UAAU,OAAmC;AACpD,UAAQ,SAAS,IAAI,KAAK;AAC5B;AAUO,SAAS,eACd,GACA,GACS;AACT,SAAO,aAAa,MAAM,CAAC,QAAQ,UAAU,EAAE,GAAG,CAAC,MAAM,UAAU,EAAE,GAAG,CAAC,CAAC;AAC5E;","names":[]}
@@ -0,0 +1,22 @@
1
+ const ADDRESS_KEYS = [
2
+ "firstName",
3
+ "lastName",
4
+ "address1",
5
+ "address2",
6
+ "company",
7
+ "city",
8
+ "province",
9
+ "postalCode",
10
+ "countryCode",
11
+ "phone"
12
+ ];
13
+ function normalize(value) {
14
+ return (value ?? "").trim();
15
+ }
16
+ function addressesEqual(a, b) {
17
+ return ADDRESS_KEYS.every((key) => normalize(a[key]) === normalize(b[key]));
18
+ }
19
+ export {
20
+ addressesEqual
21
+ };
22
+ //# sourceMappingURL=checkout-address-equality.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-address-equality.ts"],"sourcesContent":["import type { CheckoutAddressValues } from '@thorprovider/types'\n\nconst ADDRESS_KEYS: Array<keyof CheckoutAddressValues> = [\n 'firstName',\n 'lastName',\n 'address1',\n 'address2',\n 'company',\n 'city',\n 'province',\n 'postalCode',\n 'countryCode',\n 'phone',\n]\n\nfunction normalize(value: string | undefined): string {\n return (value ?? '').trim()\n}\n\n/**\n * Compare two controlled addresses for the saved-address affordances.\n *\n * The host may serialise an absent optional field as `undefined` or as an\n * empty string; both mean \"not supplied\" and must compare equal. Whitespace is\n * ignored so a value that only gained surrounding spaces is still the same\n * address. Every address key participates.\n */\nexport function addressesEqual(\n a: CheckoutAddressValues,\n b: CheckoutAddressValues,\n): boolean {\n return ADDRESS_KEYS.every((key) => normalize(a[key]) === normalize(b[key]))\n}\n"],"mappings":"AAEA,MAAM,eAAmD;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,UAAU,OAAmC;AACpD,UAAQ,SAAS,IAAI,KAAK;AAC5B;AAUO,SAAS,eACd,GACA,GACS;AACT,SAAO,aAAa,MAAM,CAAC,QAAQ,UAAU,EAAE,GAAG,CAAC,MAAM,UAAU,EAAE,GAAG,CAAC,CAAC;AAC5E;","names":[]}
@@ -0,0 +1,28 @@
1
+ import type { CheckoutAddressLevel, CheckoutAddressValues, CheckoutLocationOptions } from '@thorprovider/types';
2
+ import type { CheckoutFieldError } from './checkout-form-types';
3
+ import type { CheckoutAddressChangeHandler, CheckoutLabels } from './checkout';
4
+ type AddressErrors = Partial<Record<keyof CheckoutAddressValues, CheckoutFieldError[]>>;
5
+ type AddressDescriptions = Partial<Record<keyof CheckoutAddressValues, string>>;
6
+ export interface CheckoutAddressFieldsProps {
7
+ prefix: 'shipping' | 'billing';
8
+ values: CheckoutAddressValues;
9
+ onChange: CheckoutAddressChangeHandler;
10
+ locations?: CheckoutLocationOptions;
11
+ onRetryLocation?: (level: CheckoutAddressLevel) => void;
12
+ labels: CheckoutLabels;
13
+ errors?: AddressErrors;
14
+ descriptions?: AddressDescriptions;
15
+ /** Rendered only for the shipping variant; billing keeps its own section heading. */
16
+ heading?: string;
17
+ description?: string;
18
+ requiredPhone?: boolean;
19
+ }
20
+ /**
21
+ * The shared address form. The recipient fields come first, then the delivery
22
+ * address in a fixed order: line 1 (required), line 2 (optional), country,
23
+ * state/province, city, postal code. Billing reuses the same fields without the
24
+ * recipient legend.
25
+ */
26
+ export declare function CheckoutAddressFields({ prefix, values, onChange, locations, onRetryLocation, labels, errors, descriptions, heading, description, requiredPhone, }: CheckoutAddressFieldsProps): import("react").JSX.Element;
27
+ export {};
28
+ //# sourceMappingURL=checkout-address-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkout-address-fields.d.ts","sourceRoot":"","sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-address-fields.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,KAAK,EACV,4BAA4B,EAE5B,cAAc,EACf,MAAM,YAAY,CAAA;AAEnB,KAAK,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,qBAAqB,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAA;AACvF,KAAK,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAA;AAE/E,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAA;IAC9B,MAAM,EAAE,qBAAqB,CAAA;IAC7B,QAAQ,EAAE,4BAA4B,CAAA;IACtC,SAAS,CAAC,EAAE,uBAAuB,CAAA;IACnC,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACvD,MAAM,EAAE,cAAc,CAAA;IACtB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,MAAM,EACN,QAAQ,EACR,SAAS,EACT,eAAe,EACf,MAAM,EACN,MAAM,EACN,YAAY,EACZ,OAAO,EACP,WAAW,EACX,aAAqB,GACtB,EAAE,0BAA0B,+BA+L5B"}
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var checkout_address_fields_exports = {};
21
+ __export(checkout_address_fields_exports, {
22
+ CheckoutAddressFields: () => CheckoutAddressFields
23
+ });
24
+ module.exports = __toCommonJS(checkout_address_fields_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_field = require("../../../ui/field.js");
27
+ var import_input = require("../../../ui/input.js");
28
+ var import_checkout_field_feedback = require("./checkout-field-feedback.js");
29
+ var import_checkout_location_select = require("./checkout-location-select.js");
30
+ var import_checkout_id_context = require("./checkout-id-context.js");
31
+ function CheckoutAddressFields({
32
+ prefix,
33
+ values,
34
+ onChange,
35
+ locations,
36
+ onRetryLocation,
37
+ labels,
38
+ errors,
39
+ descriptions,
40
+ heading,
41
+ description,
42
+ requiredPhone = false
43
+ }) {
44
+ const checkoutId = (0, import_checkout_id_context.useCheckoutIds)();
45
+ const id = (field) => checkoutId(`checkout-${prefix}-${field}`);
46
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.FieldGroup, { className: "grid grid-cols-1 gap-6", children: [
47
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.FieldSet, { children: [
48
+ heading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLegend, { children: heading }) : null,
49
+ description ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-muted-foreground -mt-3 text-sm", children: description }) : null,
50
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
51
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.firstName?.length, children: [
52
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id("first-name"), children: labels.firstNameLabel }),
53
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
54
+ import_input.Input,
55
+ {
56
+ id: id("first-name"),
57
+ autoComplete: "given-name",
58
+ "aria-required": "true",
59
+ value: values.firstName,
60
+ onChange: (e) => onChange("firstName", e.target.value),
61
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("first-name"), errors?.firstName)
62
+ }
63
+ ),
64
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
65
+ import_checkout_field_feedback.CheckoutFieldFeedback,
66
+ {
67
+ id: id("first-name"),
68
+ errors: errors?.firstName,
69
+ description: descriptions?.firstName
70
+ }
71
+ )
72
+ ] }),
73
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.lastName?.length, children: [
74
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id("last-name"), children: labels.lastNameLabel }),
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
76
+ import_input.Input,
77
+ {
78
+ id: id("last-name"),
79
+ autoComplete: "family-name",
80
+ "aria-required": "true",
81
+ value: values.lastName,
82
+ onChange: (e) => onChange("lastName", e.target.value),
83
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("last-name"), errors?.lastName)
84
+ }
85
+ ),
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
87
+ import_checkout_field_feedback.CheckoutFieldFeedback,
88
+ {
89
+ id: id("last-name"),
90
+ errors: errors?.lastName,
91
+ description: descriptions?.lastName
92
+ }
93
+ )
94
+ ] })
95
+ ] }),
96
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.company?.length, children: [
97
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id("company"), children: labels.companyLabel }),
98
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
99
+ import_input.Input,
100
+ {
101
+ id: id("company"),
102
+ autoComplete: "organization",
103
+ value: values.company ?? "",
104
+ onChange: (e) => onChange("company", e.target.value),
105
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("company"), errors?.company)
106
+ }
107
+ ),
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
109
+ import_checkout_field_feedback.CheckoutFieldFeedback,
110
+ {
111
+ id: id("company"),
112
+ errors: errors?.company,
113
+ description: descriptions?.company
114
+ }
115
+ )
116
+ ] }),
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.phone?.length, children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.FieldLabel, { htmlFor: id("phone"), children: [
119
+ labels.phoneLabel,
120
+ !requiredPhone ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-muted-foreground", children: [
121
+ " (",
122
+ labels.optionalIndicatorLabel,
123
+ ")"
124
+ ] }) : null
125
+ ] }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
127
+ import_input.Input,
128
+ {
129
+ id: id("phone"),
130
+ type: "tel",
131
+ inputMode: "tel",
132
+ autoComplete: "tel",
133
+ "aria-required": requiredPhone || void 0,
134
+ value: values.phone ?? "",
135
+ onChange: (e) => onChange("phone", e.target.value),
136
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("phone"), errors?.phone)
137
+ }
138
+ ),
139
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
140
+ import_checkout_field_feedback.CheckoutFieldFeedback,
141
+ {
142
+ id: id("phone"),
143
+ errors: errors?.phone,
144
+ description: descriptions?.phone
145
+ }
146
+ )
147
+ ] })
148
+ ] }),
149
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.FieldSet, { children: [
150
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLegend, { children: labels.addressHeading }),
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.address1?.length, children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id("address"), children: labels.addressLabel }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
154
+ import_input.Input,
155
+ {
156
+ id: id("address"),
157
+ "data-checkout-field": `${prefix}.address1`,
158
+ autoComplete: "address-line1",
159
+ "aria-required": "true",
160
+ value: values.address1,
161
+ onChange: (e) => onChange("address1", e.target.value),
162
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("address"), errors?.address1)
163
+ }
164
+ ),
165
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
166
+ import_checkout_field_feedback.CheckoutFieldFeedback,
167
+ {
168
+ id: id("address"),
169
+ errors: errors?.address1,
170
+ description: descriptions?.address1
171
+ }
172
+ )
173
+ ] }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.address2?.length, children: [
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id("address2"), children: labels.address2Label }),
176
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
177
+ import_input.Input,
178
+ {
179
+ id: id("address2"),
180
+ autoComplete: "address-line2",
181
+ value: values.address2 ?? "",
182
+ onChange: (e) => onChange("address2", e.target.value),
183
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("address2"), errors?.address2)
184
+ }
185
+ ),
186
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
187
+ import_checkout_field_feedback.CheckoutFieldFeedback,
188
+ {
189
+ id: id("address2"),
190
+ errors: errors?.address2,
191
+ description: descriptions?.address2
192
+ }
193
+ )
194
+ ] }),
195
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
196
+ import_checkout_location_select.CheckoutLocationSelect,
197
+ {
198
+ id: id("country"),
199
+ label: labels.countryLabel,
200
+ placeholder: labels.countryPlaceholder,
201
+ value: values.countryCode,
202
+ options: locations?.countries ?? [],
203
+ state: locations?.countriesState,
204
+ error: locations?.countriesError,
205
+ onChange: (value) => onChange("countryCode", value),
206
+ onRetry: onRetryLocation ? () => onRetryLocation("countries") : void 0,
207
+ labels,
208
+ errors: errors?.countryCode,
209
+ description: descriptions?.countryCode
210
+ }
211
+ ),
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
213
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
214
+ import_checkout_location_select.CheckoutLocationSelect,
215
+ {
216
+ id: id("province"),
217
+ label: labels.stateLabel,
218
+ placeholder: labels.provincePlaceholder,
219
+ value: values.province ?? "",
220
+ options: values.countryCode ? locations?.provinces ?? [] : [],
221
+ state: values.countryCode ? locations?.provincesState : void 0,
222
+ error: values.countryCode ? locations?.provincesError : void 0,
223
+ disabled: !values.countryCode,
224
+ onChange: (value) => onChange("province", value),
225
+ onRetry: onRetryLocation ? () => onRetryLocation("provinces") : void 0,
226
+ labels,
227
+ errors: errors?.province,
228
+ description: descriptions?.province
229
+ }
230
+ ),
231
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
232
+ import_checkout_location_select.CheckoutLocationSelect,
233
+ {
234
+ id: id("city"),
235
+ label: labels.cityLabel,
236
+ placeholder: labels.cityPlaceholder,
237
+ value: values.city,
238
+ options: values.province ? locations?.cities ?? [] : [],
239
+ state: values.province ? locations?.citiesState : void 0,
240
+ error: values.province ? locations?.citiesError : void 0,
241
+ disabled: !values.province,
242
+ onChange: (value) => onChange("city", value),
243
+ onRetry: onRetryLocation ? () => onRetryLocation("cities") : void 0,
244
+ labels,
245
+ errors: errors?.city,
246
+ description: descriptions?.city
247
+ }
248
+ )
249
+ ] }),
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { "data-invalid": !!errors?.postalCode?.length, children: [
251
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id("zip"), children: labels.zipCodeLabel }),
252
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
253
+ import_input.Input,
254
+ {
255
+ id: id("zip"),
256
+ autoComplete: "postal-code",
257
+ value: values.postalCode ?? "",
258
+ onChange: (e) => onChange("postalCode", e.target.value),
259
+ ...(0, import_checkout_field_feedback.checkoutFieldAria)(id("zip"), errors?.postalCode)
260
+ }
261
+ ),
262
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
263
+ import_checkout_field_feedback.CheckoutFieldFeedback,
264
+ {
265
+ id: id("zip"),
266
+ errors: errors?.postalCode,
267
+ description: descriptions?.postalCode
268
+ }
269
+ )
270
+ ] })
271
+ ] })
272
+ ] });
273
+ }
274
+ // Annotate the CommonJS export names for ESM import in node:
275
+ 0 && (module.exports = {
276
+ CheckoutAddressFields
277
+ });
278
+ //# sourceMappingURL=checkout-address-fields.js.map