@thorprovider/blocks 3.0.1 → 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.
- package/README.md +61 -21
- package/dist/blocks/designs/marketplace-product-card/block.d.ts +12 -0
- package/dist/blocks/designs/marketplace-product-card/block.d.ts.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/block.js +243 -0
- package/dist/blocks/designs/marketplace-product-card/block.js.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/block.mjs +233 -0
- package/dist/blocks/designs/marketplace-product-card/block.mjs.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/index.d.ts +3 -0
- package/dist/blocks/designs/marketplace-product-card/index.d.ts.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/index.js +36 -0
- package/dist/blocks/designs/marketplace-product-card/index.js.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/index.mjs +6 -0
- package/dist/blocks/designs/marketplace-product-card/index.mjs.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/normalize.d.ts +13 -0
- package/dist/blocks/designs/marketplace-product-card/normalize.d.ts.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/normalize.js +36 -0
- package/dist/blocks/designs/marketplace-product-card/normalize.js.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/normalize.mjs +12 -0
- package/dist/blocks/designs/marketplace-product-card/normalize.mjs.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/variants.d.ts +72 -0
- package/dist/blocks/designs/marketplace-product-card/variants.d.ts.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/variants.js +123 -0
- package/dist/blocks/designs/marketplace-product-card/variants.js.map +1 -0
- package/dist/blocks/designs/marketplace-product-card/variants.mjs +89 -0
- package/dist/blocks/designs/marketplace-product-card/variants.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkbox-check.js +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkbox-check.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkbox-check.mjs +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkbox-check.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.d.ts +11 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.js +46 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.mjs +22 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-equality.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.d.ts +28 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.js +278 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.mjs +260 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-address-fields.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.d.ts +12 -9
- package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.js +49 -71
- package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.mjs +50 -72
- package/dist/blocks/e-commerce/checkout-forms/checkout-contact-step.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.js +6 -3
- package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.mjs +6 -3
- package/dist/blocks/e-commerce/checkout-forms/checkout-country-field.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.d.ts +7 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.js +41 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.mjs +16 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-id-context.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.d.ts +24 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.js +75 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.mjs +58 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-location-select.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.d.ts +3 -2
- package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.js +9 -2
- package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.mjs +9 -2
- package/dist/blocks/e-commerce/checkout-forms/checkout-order-summary.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.d.ts +23 -8
- package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.js +136 -31
- package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.mjs +143 -32
- package/dist/blocks/e-commerce/checkout-forms/checkout-payment-step.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.d.ts +13 -7
- package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.js +179 -28
- package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.mjs +180 -29
- package/dist/blocks/e-commerce/checkout-forms/checkout-review-step.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.d.ts +20 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.js +199 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.mjs +175 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-saved-addresses.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.d.ts +14 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.js +136 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.mjs +109 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-section-nav.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.d.ts +32 -10
- package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.js +265 -147
- package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.mjs +272 -148
- package/dist/blocks/e-commerce/checkout-forms/checkout-shipping-step.mjs.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.d.ts +13 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.js +74 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.mjs +50 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-header.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.d.ts +7 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.d.ts.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.js +91 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.js.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.mjs +65 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout-step-summary.mjs.map +1 -0
- package/dist/blocks/e-commerce/checkout-forms/checkout.d.ts +174 -44
- package/dist/blocks/e-commerce/checkout-forms/checkout.d.ts.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout.js +532 -108
- package/dist/blocks/e-commerce/checkout-forms/checkout.js.map +1 -1
- package/dist/blocks/e-commerce/checkout-forms/checkout.mjs +542 -109
- package/dist/blocks/e-commerce/checkout-forms/checkout.mjs.map +1 -1
- package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.d.ts.map +1 -1
- package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.js +44 -20
- package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.js.map +1 -1
- package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.mjs +44 -20
- package/dist/blocks/e-commerce/navigation/storefront-navbar-cart-sheet.mjs.map +1 -1
- package/dist/blocks/e-commerce/navigation/storefront-navbar.d.ts.map +1 -1
- package/dist/blocks/e-commerce/navigation/storefront-navbar.js +21 -10
- package/dist/blocks/e-commerce/navigation/storefront-navbar.js.map +1 -1
- package/dist/blocks/e-commerce/navigation/storefront-navbar.mjs +21 -10
- package/dist/blocks/e-commerce/navigation/storefront-navbar.mjs.map +1 -1
- package/dist/blocks/e-commerce/product-list/product-card.d.ts.map +1 -1
- package/dist/blocks/e-commerce/product-list/product-card.js +36 -9
- package/dist/blocks/e-commerce/product-list/product-card.js.map +1 -1
- package/dist/blocks/e-commerce/product-list/product-card.mjs +36 -9
- package/dist/blocks/e-commerce/product-list/product-card.mjs.map +1 -1
- package/dist/blocks/e-commerce/product-list/product-showcase-1.d.ts.map +1 -1
- package/dist/blocks/e-commerce/product-list/product-showcase-1.js +7 -2
- package/dist/blocks/e-commerce/product-list/product-showcase-1.js.map +1 -1
- package/dist/blocks/e-commerce/product-list/product-showcase-1.mjs +7 -2
- package/dist/blocks/e-commerce/product-list/product-showcase-1.mjs.map +1 -1
- package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.d.ts.map +1 -1
- package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.js +5 -1
- package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.js.map +1 -1
- package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.mjs +5 -1
- package/dist/blocks/e-commerce/product-overview/product-quick-view-dialog.mjs.map +1 -1
- package/dist/blocks/e-commerce/storefront-hero/storefront-hero.d.ts.map +1 -1
- package/dist/blocks/e-commerce/storefront-hero/storefront-hero.js +71 -51
- package/dist/blocks/e-commerce/storefront-hero/storefront-hero.js.map +1 -1
- package/dist/blocks/e-commerce/storefront-hero/storefront-hero.mjs +71 -51
- package/dist/blocks/e-commerce/storefront-hero/storefront-hero.mjs.map +1 -1
- package/dist/blocks/marketing/banners/banner-1.d.ts.map +1 -1
- package/dist/blocks/marketing/banners/banner-1.js +15 -27
- package/dist/blocks/marketing/banners/banner-1.js.map +1 -1
- package/dist/blocks/marketing/banners/banner-1.mjs +16 -28
- package/dist/blocks/marketing/banners/banner-1.mjs.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -1
- package/dist/lib/contracts/marketplace-product-card.d.ts +324 -0
- package/dist/lib/contracts/marketplace-product-card.d.ts.map +1 -0
- package/dist/lib/contracts/marketplace-product-card.js +85 -0
- package/dist/lib/contracts/marketplace-product-card.js.map +1 -0
- package/dist/lib/contracts/marketplace-product-card.mjs +61 -0
- package/dist/lib/contracts/marketplace-product-card.mjs.map +1 -0
- package/dist/lib/contracts.d.ts +1861 -88
- package/dist/lib/contracts.d.ts.map +1 -1
- package/dist/lib/contracts.js +252 -25
- package/dist/lib/contracts.js.map +1 -1
- package/dist/lib/contracts.mjs +208 -5
- package/dist/lib/contracts.mjs.map +1 -1
- package/dist/lib/money-schema.d.ts +19 -0
- package/dist/lib/money-schema.d.ts.map +1 -0
- package/dist/lib/money-schema.js +33 -0
- package/dist/lib/money-schema.js.map +1 -0
- package/dist/lib/money-schema.mjs +9 -0
- package/dist/lib/money-schema.mjs.map +1 -0
- package/dist/lib/motion.d.ts +29 -0
- package/dist/lib/motion.d.ts.map +1 -0
- package/dist/lib/motion.js +65 -0
- package/dist/lib/motion.js.map +1 -0
- package/dist/lib/motion.mjs +41 -0
- package/dist/lib/motion.mjs.map +1 -0
- package/dist/ui/accordion.d.ts +3 -1
- package/dist/ui/accordion.d.ts.map +1 -1
- package/dist/ui/accordion.js +21 -5
- package/dist/ui/accordion.js.map +1 -1
- package/dist/ui/accordion.mjs +21 -5
- package/dist/ui/accordion.mjs.map +1 -1
- package/dist/ui/input-group.d.ts +1 -1
- package/package.json +19 -5
- 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":"AAiEO,SAAS,iBAAiB,SAAyB,WAA+B;AACvF,SAAO,OAAO,QAAQ,SAAS,EAAE;AAAA,IAC/B,CAAC,CAAC,UAAU,OAAO,MAAM,QAAQ,eAAe,QAAQ,MAAM;AAAA,EAChE;AACF;AAEO,SAAS,wBAAwB,SAA6B;AACnE,QAAM,UAAU,QAAQ,SAAS,KAAK,CAAC,cAAc,UAAU,SAAS,KAAK,QAAQ,SAAS,CAAC;AAC/F,SAAO,UAAU,EAAE,GAAG,QAAQ,eAAe,IAAI,CAAC;AACpD;AAEO,SAAS,YAAY,SAAkB,WAAkD;AAC9F,SAAO,QAAQ,SAAS,KAAK,CAAC,YAAY,iBAAiB,SAAS,SAAS,CAAC;AAChF;AAEO,SAAS,qBACd,SACA,WAC4B;AAC5B,SAAO,QAAQ,SAAS;AAAA,IACtB,CAAC,YAAY,QAAQ,aAAa,iBAAiB,SAAS,SAAS;AAAA,EACvE;AACF;AAEO,SAAS,gBACd,SACA,WACA,aACA,SACS;AACT,QAAM,SAAS,QAAQ,QAAQ,WAAW;AAC1C,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,SAAS,gBAAgB,QAAQ,QAAQ,SAAS;AAExD,SAAO,CAAC,QAAQ,SAAS,KAAK,CAAC,YAAY;AACzC,QAAI,CAAC,QAAQ,aAAa,QAAQ,eAAe,OAAO,EAAE,MAAM,QAAS,QAAO;AAChF,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,QAAQ,QACZ,MAAM,GAAG,WAAW,EACpB,MAAM,CAAC,YAAY,QAAQ,eAAe,QAAQ,EAAE,MAAM,UAAU,QAAQ,EAAE,CAAC;AAAA,EACpF,CAAC;AACH;AAEO,SAAS,YACd,SACA,WACA,aACA,SACW;AACX,QAAM,SAAS,QAAQ,QAAQ,WAAW;AAC1C,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,QAAQ;AAClD,MAAI,qBAAqB,SAAS,IAAI,EAAG,QAAO;AAEhD,QAAM,UAAU,QAAQ,QAAQ,MAAM,GAAG,cAAc,CAAC;AACxD,QAAM,UAAU,QAAQ,SAAS;AAAA,IAC/B,CAAC,YACC,QAAQ,aACR,QAAQ,MAAM,CAAC,UAAU,QAAQ,eAAe,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;AAAA,EAChF;AACA,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,YAAY,CAAC,YACjB,QAAQ,QAAQ;AAAA,IACd,CAAC,OAAO,UACN,SAAS,QAAQ,eAAe,MAAM,EAAE,MAAM,UAAU,MAAM,EAAE,IAAI,IAAI;AAAA,IAC1E;AAAA,EACF;AAEF,QAAM,OAAO,QAAQ;AAAA,IAAO,CAAC,SAAS,cACpC,UAAU,SAAS,IAAI,UAAU,OAAO,IAAI,YAAY;AAAA,EAC1D;AACA,SAAO,EAAE,GAAG,KAAK,eAAe;AAClC;AAEO,SAAS,iBAAiB,QAAuD;AACtF,aAAW,SAAS,QAAQ;AAC1B,QAAI,OAAO,UAAU,SAAU;AAC/B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAQ,SAAS,EAAG,QAAO;AAAA,EACjC;AACA,SAAO;AACT;AAEO,SAAS,oBACd,SACA,SACA,WAC0C;AAC1C,QAAM,cAAc,QAAQ,QAAQ,KAAK,CAAC,WAAW,OAAO,SAAS,OAAO;AAC5E,QAAM,aAAa,cACf,YAAY,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,UAAU,YAAY,EAAE,CAAC,IACzE;AAEJ,SAAO;AAAA,IACL,KAAK,cAAc,SAAS,OAAO,YAAY,OAAO,QAAQ,KAAK;AAAA,IACnE,KACE,cAAc,SAAS,UAAU,YAAY,UAAU,QAAQ,KAAK,KAAK,QAAQ;AAAA,EACrF;AACF;AAEO,SAAS,YAAY,QAAgB,QAAgB,UAA0B;AACpF,SAAO,IAAI,KAAK,aAAa,QAAQ,EAAE,OAAO,YAAY,SAAS,CAAC,EAAE,OAAO,MAAM;AACrF;AAEO,SAAS,gBAAgB,OAAe,gBAAwC;AACrF,MAAI,mBAAmB,UAAa,kBAAkB,MAAO,QAAO;AACpE,SAAO,KAAK,OAAO,IAAI,QAAQ,kBAAkB,GAAG;AACtD;AAEO,SAAS,eAAe,SAAiB,QAAwB;AACtE,SAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,IACnC,OAAO;AAAA,IACP,uBAAuB;AAAA,EACzB,CAAC,EAAE,OAAO,CAAC,UAAU,GAAG;AAC1B;","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,
|
|
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,
|
|
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
|