@thorprovider/blocks 3.0.2 → 4.1.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/checkout-commerce-v1/block.d.ts +49 -0
- package/dist/blocks/designs/checkout-commerce-v1/block.d.ts.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/block.js +2487 -0
- package/dist/blocks/designs/checkout-commerce-v1/block.js.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/block.mjs +2467 -0
- package/dist/blocks/designs/checkout-commerce-v1/block.mjs.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/data-context.d.ts +8 -0
- package/dist/blocks/designs/checkout-commerce-v1/data-context.d.ts.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/data-context.js +44 -0
- package/dist/blocks/designs/checkout-commerce-v1/data-context.js.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/data-context.mjs +19 -0
- package/dist/blocks/designs/checkout-commerce-v1/data-context.mjs.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/index.d.ts +3 -0
- package/dist/blocks/designs/checkout-commerce-v1/index.d.ts.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/index.js +36 -0
- package/dist/blocks/designs/checkout-commerce-v1/index.js.map +1 -0
- package/dist/blocks/designs/checkout-commerce-v1/index.mjs +6 -0
- package/dist/blocks/designs/checkout-commerce-v1/index.mjs.map +1 -0
- 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/account/account-frame.d.ts +38 -0
- package/dist/blocks/e-commerce/account/account-frame.d.ts.map +1 -0
- package/dist/blocks/e-commerce/account/account-frame.js +102 -0
- package/dist/blocks/e-commerce/account/account-frame.js.map +1 -0
- package/dist/blocks/e-commerce/account/account-frame.mjs +78 -0
- package/dist/blocks/e-commerce/account/account-frame.mjs.map +1 -0
- package/dist/blocks/e-commerce/account/address-book.d.ts +79 -0
- package/dist/blocks/e-commerce/account/address-book.d.ts.map +1 -0
- package/dist/blocks/e-commerce/account/address-book.js +250 -0
- package/dist/blocks/e-commerce/account/address-book.js.map +1 -0
- package/dist/blocks/e-commerce/account/address-book.mjs +225 -0
- package/dist/blocks/e-commerce/account/address-book.mjs.map +1 -0
- package/dist/blocks/e-commerce/account/profile-form.d.ts +35 -0
- package/dist/blocks/e-commerce/account/profile-form.d.ts.map +1 -0
- package/dist/blocks/e-commerce/account/profile-form.js +100 -0
- package/dist/blocks/e-commerce/account/profile-form.js.map +1 -0
- package/dist/blocks/e-commerce/account/profile-form.mjs +76 -0
- package/dist/blocks/e-commerce/account/profile-form.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 +16 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -1
- package/dist/lib/contracts/checkout-commerce-v1.d.ts +2350 -0
- package/dist/lib/contracts/checkout-commerce-v1.d.ts.map +1 -0
- package/dist/lib/contracts/checkout-commerce-v1.js +417 -0
- package/dist/lib/contracts/checkout-commerce-v1.js.map +1 -0
- package/dist/lib/contracts/checkout-commerce-v1.mjs +392 -0
- package/dist/lib/contracts/checkout-commerce-v1.mjs.map +1 -0
- 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 +2289 -178
- package/dist/lib/contracts.d.ts.map +1 -1
- package/dist/lib/contracts.js +332 -25
- package/dist/lib/contracts.js.map +1 -1
- package/dist/lib/contracts.mjs +278 -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 +18 -3
- package/dist/.tsbuildinfo +0 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { Badge } from "../../../ui/badge.mjs";
|
|
5
|
+
import { Button } from "../../../ui/button.mjs";
|
|
6
|
+
import { FieldLegend, FieldSet } from "../../../ui/field.mjs";
|
|
7
|
+
import { RadioGroup, RadioGroupItem } from "../../../ui/radio-group.mjs";
|
|
8
|
+
import { useCheckoutIds } from "./checkout-id-context.mjs";
|
|
9
|
+
function recipientName(address) {
|
|
10
|
+
return [address.firstName, address.lastName].filter(Boolean).join(" ");
|
|
11
|
+
}
|
|
12
|
+
function addressLocality(address) {
|
|
13
|
+
return [address.city, address.province, address.postalCode].filter(Boolean).join(", ");
|
|
14
|
+
}
|
|
15
|
+
function focusEntry(id) {
|
|
16
|
+
document.getElementById(id)?.focus();
|
|
17
|
+
}
|
|
18
|
+
function CheckoutSavedAddresses({
|
|
19
|
+
savedAddresses,
|
|
20
|
+
selectedId,
|
|
21
|
+
state,
|
|
22
|
+
labels,
|
|
23
|
+
countryLabel,
|
|
24
|
+
onSelect,
|
|
25
|
+
onDelete
|
|
26
|
+
}) {
|
|
27
|
+
const checkoutId = useCheckoutIds();
|
|
28
|
+
const [confirmingId, setConfirmingId] = useState(null);
|
|
29
|
+
const pendingDelete = useRef(null);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const pending = pendingDelete.current;
|
|
32
|
+
if (!pending) return;
|
|
33
|
+
const stillPresent = savedAddresses.some((entry) => entry.id === pending.deletedId);
|
|
34
|
+
if (stillPresent) {
|
|
35
|
+
if (state?.error?.id === pending.deletedId) {
|
|
36
|
+
focusEntry(checkoutId(`checkout-saved-address-${pending.deletedId}`));
|
|
37
|
+
pendingDelete.current = null;
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (pending.nextId) {
|
|
42
|
+
focusEntry(checkoutId(`checkout-saved-address-${pending.nextId}`));
|
|
43
|
+
} else {
|
|
44
|
+
document.getElementById(checkoutId("checkout-add-address"))?.focus();
|
|
45
|
+
}
|
|
46
|
+
pendingDelete.current = null;
|
|
47
|
+
}, [checkoutId, savedAddresses, state?.error?.id]);
|
|
48
|
+
if (savedAddresses.length === 0) return null;
|
|
49
|
+
const confirmDelete = (id) => {
|
|
50
|
+
const index = savedAddresses.findIndex((entry) => entry.id === id);
|
|
51
|
+
const next = savedAddresses[index + 1] ?? savedAddresses[index - 1];
|
|
52
|
+
pendingDelete.current = { deletedId: id, nextId: next?.id };
|
|
53
|
+
setConfirmingId(null);
|
|
54
|
+
onDelete?.(id);
|
|
55
|
+
};
|
|
56
|
+
return /* @__PURE__ */ jsxs(FieldSet, { "aria-labelledby": checkoutId("checkout-saved-addresses-heading"), children: [
|
|
57
|
+
/* @__PURE__ */ jsx(FieldLegend, { id: checkoutId("checkout-saved-addresses-heading"), children: labels.savedAddressesLabel }),
|
|
58
|
+
/* @__PURE__ */ jsx(
|
|
59
|
+
RadioGroup,
|
|
60
|
+
{
|
|
61
|
+
value: selectedId ?? "",
|
|
62
|
+
onValueChange: (value) => value && onSelect(String(value)),
|
|
63
|
+
className: "grid grid-cols-1 gap-3",
|
|
64
|
+
children: savedAddresses.map((saved) => {
|
|
65
|
+
const inputId = checkoutId(`checkout-saved-address-${saved.id}`);
|
|
66
|
+
const pending = state?.pendingId === saved.id;
|
|
67
|
+
const error = state?.error?.id === saved.id ? state.error : void 0;
|
|
68
|
+
const confirming = confirmingId === saved.id;
|
|
69
|
+
const name = recipientName(saved.address);
|
|
70
|
+
const locality = addressLocality(saved.address);
|
|
71
|
+
const title = saved.label?.trim() || name || saved.address.address1 || labels.savedAddressesLabel;
|
|
72
|
+
return /* @__PURE__ */ jsxs(
|
|
73
|
+
"div",
|
|
74
|
+
{
|
|
75
|
+
className: "flex flex-col gap-2",
|
|
76
|
+
"data-checkout-saved-address": saved.id,
|
|
77
|
+
"aria-busy": pending || void 0,
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-lg border p-4 sm:flex-row sm:items-start sm:justify-between", children: [
|
|
80
|
+
/* @__PURE__ */ jsxs(
|
|
81
|
+
"label",
|
|
82
|
+
{
|
|
83
|
+
htmlFor: inputId,
|
|
84
|
+
className: "flex min-w-0 flex-1 flex-col gap-0.5 text-left text-sm font-medium",
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ jsxs("span", { className: "flex flex-wrap items-center gap-2", children: [
|
|
87
|
+
title,
|
|
88
|
+
saved.label && name ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs font-normal", children: name }) : null,
|
|
89
|
+
saved.isDefaultShipping ? /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: labels.defaultAddressLabel }) : null
|
|
90
|
+
] }),
|
|
91
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm font-normal", children: saved.address.address1 }),
|
|
92
|
+
saved.address.address2 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm font-normal", children: saved.address.address2 }) : null,
|
|
93
|
+
locality ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm font-normal", children: locality }) : null,
|
|
94
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm font-normal", children: countryLabel(saved.address.countryCode) })
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
),
|
|
98
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 sm:shrink-0", children: [
|
|
99
|
+
selectedId !== saved.id ? /* @__PURE__ */ jsx(
|
|
100
|
+
Button,
|
|
101
|
+
{
|
|
102
|
+
type: "button",
|
|
103
|
+
variant: "outline",
|
|
104
|
+
size: "sm",
|
|
105
|
+
disabled: pending,
|
|
106
|
+
"aria-label": `${labels.useAddressLabel}: ${title}`,
|
|
107
|
+
onClick: () => onSelect(saved.id),
|
|
108
|
+
children: labels.useAddressLabel
|
|
109
|
+
}
|
|
110
|
+
) : null,
|
|
111
|
+
onDelete ? /* @__PURE__ */ jsx(
|
|
112
|
+
Button,
|
|
113
|
+
{
|
|
114
|
+
type: "button",
|
|
115
|
+
variant: "ghost",
|
|
116
|
+
size: "sm",
|
|
117
|
+
disabled: pending,
|
|
118
|
+
"aria-label": `${labels.deleteAddressLabel}: ${title}`,
|
|
119
|
+
onClick: () => setConfirmingId(saved.id),
|
|
120
|
+
children: pending ? labels.deletingAddressLabel : labels.deleteAddressLabel
|
|
121
|
+
}
|
|
122
|
+
) : null,
|
|
123
|
+
/* @__PURE__ */ jsx(RadioGroupItem, { value: saved.id, id: inputId, disabled: pending })
|
|
124
|
+
] })
|
|
125
|
+
] }),
|
|
126
|
+
confirming ? /* @__PURE__ */ jsxs(
|
|
127
|
+
"div",
|
|
128
|
+
{
|
|
129
|
+
className: "flex flex-col gap-2 rounded-md border border-destructive/40 p-3",
|
|
130
|
+
role: "group",
|
|
131
|
+
"aria-label": labels.deleteAddressConfirmLabel,
|
|
132
|
+
children: [
|
|
133
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: labels.deleteAddressConfirmLabel }),
|
|
134
|
+
/* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: labels.deleteAddressHintLabel }),
|
|
135
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
136
|
+
/* @__PURE__ */ jsx(
|
|
137
|
+
Button,
|
|
138
|
+
{
|
|
139
|
+
type: "button",
|
|
140
|
+
variant: "destructive",
|
|
141
|
+
size: "sm",
|
|
142
|
+
disabled: pending,
|
|
143
|
+
onClick: () => confirmDelete(saved.id),
|
|
144
|
+
children: pending ? labels.deletingAddressLabel : labels.deleteAddressLabel
|
|
145
|
+
}
|
|
146
|
+
),
|
|
147
|
+
/* @__PURE__ */ jsx(
|
|
148
|
+
Button,
|
|
149
|
+
{
|
|
150
|
+
type: "button",
|
|
151
|
+
variant: "outline",
|
|
152
|
+
size: "sm",
|
|
153
|
+
disabled: pending,
|
|
154
|
+
onClick: () => setConfirmingId(null),
|
|
155
|
+
children: labels.cancelAddressLabel
|
|
156
|
+
}
|
|
157
|
+
)
|
|
158
|
+
] })
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
) : null,
|
|
162
|
+
error ? /* @__PURE__ */ jsx("p", { className: "text-destructive text-sm", role: "alert", children: error.message || labels.addressDeleteErrorLabel }) : null
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
saved.id
|
|
166
|
+
);
|
|
167
|
+
})
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
] });
|
|
171
|
+
}
|
|
172
|
+
export {
|
|
173
|
+
CheckoutSavedAddresses
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=checkout-saved-addresses.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-saved-addresses.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport { Badge } from '../../../ui/badge'\nimport { Button } from '../../../ui/button'\nimport { FieldLegend, FieldSet } from '../../../ui/field'\nimport { RadioGroup, RadioGroupItem } from '../../../ui/radio-group'\nimport { useCheckoutIds } from './checkout-id-context'\nimport type { CheckoutAddressValues, CheckoutSavedAddress } from '@thorprovider/types'\nimport type { CheckoutLabels, CheckoutSavedAddressState } from './checkout'\n\nexport interface CheckoutSavedAddressesProps {\n savedAddresses: CheckoutSavedAddress[]\n selectedId?: string\n state?: CheckoutSavedAddressState\n labels: CheckoutLabels\n countryLabel: (countryCode: string) => string\n onSelect: (id: string) => void\n onDelete?: (id: string) => void\n}\n\nfunction recipientName(address: CheckoutAddressValues): string {\n return [address.firstName, address.lastName].filter(Boolean).join(' ')\n}\n\nfunction addressLocality(address: CheckoutAddressValues): string {\n return [address.city, address.province, address.postalCode].filter(Boolean).join(', ')\n}\n\nfunction focusEntry(id: string): void {\n document.getElementById(id)?.focus()\n}\n\n/**\n * The saved-address book as selectable cards. The radio and the two actions are\n * siblings: the label contains only the address summary, so activating Use or\n * Delete never selects the address as a side effect. Delete is a two-step\n * inline confirmation; the host owns the mutation and the refreshed list, so\n * the card is never removed optimistically.\n */\nexport function CheckoutSavedAddresses({\n savedAddresses,\n selectedId,\n state,\n labels,\n countryLabel,\n onSelect,\n onDelete,\n}: CheckoutSavedAddressesProps) {\n const checkoutId = useCheckoutIds()\n const [confirmingId, setConfirmingId] = useState<string | null>(null)\n const pendingDelete = useRef<{ deletedId: string; nextId?: string } | null>(null)\n\n useEffect(() => {\n const pending = pendingDelete.current\n if (!pending) return\n\n const stillPresent = savedAddresses.some((entry) => entry.id === pending.deletedId)\n if (stillPresent) {\n if (state?.error?.id === pending.deletedId) {\n focusEntry(checkoutId(`checkout-saved-address-${pending.deletedId}`))\n pendingDelete.current = null\n }\n return\n }\n\n if (pending.nextId) {\n focusEntry(checkoutId(`checkout-saved-address-${pending.nextId}`))\n } else {\n document.getElementById(checkoutId('checkout-add-address'))?.focus()\n }\n pendingDelete.current = null\n }, [checkoutId, savedAddresses, state?.error?.id])\n\n if (savedAddresses.length === 0) return null\n\n const confirmDelete = (id: string) => {\n const index = savedAddresses.findIndex((entry) => entry.id === id)\n const next = savedAddresses[index + 1] ?? savedAddresses[index - 1]\n pendingDelete.current = { deletedId: id, nextId: next?.id }\n setConfirmingId(null)\n onDelete?.(id)\n }\n\n return (\n <FieldSet aria-labelledby={checkoutId('checkout-saved-addresses-heading')}>\n <FieldLegend id={checkoutId('checkout-saved-addresses-heading')}>\n {labels.savedAddressesLabel}\n </FieldLegend>\n <RadioGroup\n value={selectedId ?? ''}\n onValueChange={(value) => value && onSelect(String(value))}\n className=\"grid grid-cols-1 gap-3\"\n >\n {savedAddresses.map((saved) => {\n const inputId = checkoutId(`checkout-saved-address-${saved.id}`)\n const pending = state?.pendingId === saved.id\n const error = state?.error?.id === saved.id ? state.error : undefined\n const confirming = confirmingId === saved.id\n const name = recipientName(saved.address)\n const locality = addressLocality(saved.address)\n const title =\n saved.label?.trim() || name || saved.address.address1 || labels.savedAddressesLabel\n\n return (\n <div\n key={saved.id}\n className=\"flex flex-col gap-2\"\n data-checkout-saved-address={saved.id}\n aria-busy={pending || undefined}\n >\n <div className=\"flex flex-col gap-3 rounded-lg border p-4 sm:flex-row sm:items-start sm:justify-between\">\n <label\n htmlFor={inputId}\n className=\"flex min-w-0 flex-1 flex-col gap-0.5 text-left text-sm font-medium\"\n >\n <span className=\"flex flex-wrap items-center gap-2\">\n {title}\n {saved.label && name ? (\n <span className=\"text-muted-foreground text-xs font-normal\">{name}</span>\n ) : null}\n {saved.isDefaultShipping ? (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {labels.defaultAddressLabel}\n </Badge>\n ) : null}\n </span>\n <span className=\"text-muted-foreground text-sm font-normal\">\n {saved.address.address1}\n </span>\n {saved.address.address2 ? (\n <span className=\"text-muted-foreground text-sm font-normal\">\n {saved.address.address2}\n </span>\n ) : null}\n {locality ? (\n <span className=\"text-muted-foreground text-sm font-normal\">{locality}</span>\n ) : null}\n <span className=\"text-muted-foreground text-sm font-normal\">\n {countryLabel(saved.address.countryCode)}\n </span>\n </label>\n\n <div className=\"flex flex-wrap items-center gap-2 sm:shrink-0\">\n {selectedId !== saved.id ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={pending}\n aria-label={`${labels.useAddressLabel}: ${title}`}\n onClick={() => onSelect(saved.id)}\n >\n {labels.useAddressLabel}\n </Button>\n ) : null}\n {onDelete ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={pending}\n aria-label={`${labels.deleteAddressLabel}: ${title}`}\n onClick={() => setConfirmingId(saved.id)}\n >\n {pending ? labels.deletingAddressLabel : labels.deleteAddressLabel}\n </Button>\n ) : null}\n <RadioGroupItem value={saved.id} id={inputId} disabled={pending} />\n </div>\n </div>\n\n {confirming ? (\n <div\n className=\"flex flex-col gap-2 rounded-md border border-destructive/40 p-3\"\n role=\"group\"\n aria-label={labels.deleteAddressConfirmLabel}\n >\n <p className=\"text-sm font-medium\">{labels.deleteAddressConfirmLabel}</p>\n <p className=\"text-muted-foreground text-xs\">{labels.deleteAddressHintLabel}</p>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n disabled={pending}\n onClick={() => confirmDelete(saved.id)}\n >\n {pending ? labels.deletingAddressLabel : labels.deleteAddressLabel}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={pending}\n onClick={() => setConfirmingId(null)}\n >\n {labels.cancelAddressLabel}\n </Button>\n </div>\n </div>\n ) : null}\n\n {error ? (\n <p className=\"text-destructive text-sm\" role=\"alert\">\n {error.message || labels.addressDeleteErrorLabel}\n </p>\n ) : null}\n </div>\n )\n })}\n </RadioGroup>\n </FieldSet>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CheckoutStepId } from './checkout';
|
|
2
|
+
export interface CheckoutSectionNavProps {
|
|
3
|
+
steps: Array<{
|
|
4
|
+
id: CheckoutStepId;
|
|
5
|
+
label: string;
|
|
6
|
+
}>;
|
|
7
|
+
ariaLabel: string;
|
|
8
|
+
instanceId: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function checkoutSectionId(instanceId: string, step: CheckoutStepId): string;
|
|
11
|
+
export declare function checkoutSectionHeadingId(instanceId: string, step: CheckoutStepId): string;
|
|
12
|
+
export declare function useActiveCheckoutSection(stepIds: CheckoutStepId[], instanceId: string): CheckoutStepId;
|
|
13
|
+
export declare function CheckoutSectionNav({ steps, ariaLabel, instanceId }: CheckoutSectionNavProps): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=checkout-section-nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkout-section-nav.d.ts","sourceRoot":"","sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-section-nav.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAEhD,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAElF;AAED,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAEzF;AAkBD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EAAE,EACzB,UAAU,EAAE,MAAM,GACjB,cAAc,CA4ChB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,uBAAuB,+BA0D3F"}
|
|
@@ -0,0 +1,136 @@
|
|
|
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_section_nav_exports = {};
|
|
21
|
+
__export(checkout_section_nav_exports, {
|
|
22
|
+
CheckoutSectionNav: () => CheckoutSectionNav,
|
|
23
|
+
checkoutSectionHeadingId: () => checkoutSectionHeadingId,
|
|
24
|
+
checkoutSectionId: () => checkoutSectionId,
|
|
25
|
+
useActiveCheckoutSection: () => useActiveCheckoutSection
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(checkout_section_nav_exports);
|
|
28
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
|
+
var import_react = require("react");
|
|
30
|
+
var import_react2 = require("motion/react");
|
|
31
|
+
var import_utils = require("../../../lib/utils.js");
|
|
32
|
+
var import_motion = require("../../../lib/motion.js");
|
|
33
|
+
function checkoutSectionId(instanceId, step) {
|
|
34
|
+
return `${instanceId}-step-${step}`;
|
|
35
|
+
}
|
|
36
|
+
function checkoutSectionHeadingId(instanceId, step) {
|
|
37
|
+
return `${instanceId}-heading-${step}`;
|
|
38
|
+
}
|
|
39
|
+
function fallbackStep(steps, sections) {
|
|
40
|
+
const line = window.innerHeight * 0.25;
|
|
41
|
+
let current;
|
|
42
|
+
sections.forEach((section, index) => {
|
|
43
|
+
if (section && section.getBoundingClientRect().top <= line) {
|
|
44
|
+
current = steps[index];
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return current ?? steps[0];
|
|
48
|
+
}
|
|
49
|
+
function useActiveCheckoutSection(stepIds, instanceId) {
|
|
50
|
+
const stepKey = stepIds.join("|");
|
|
51
|
+
const [activeStep, setActiveStep] = (0, import_react.useState)(stepIds[0] ?? "contact");
|
|
52
|
+
(0, import_react.useEffect)(() => {
|
|
53
|
+
if (typeof window === "undefined" || typeof IntersectionObserver === "undefined") return;
|
|
54
|
+
const ids = stepKey.split("|");
|
|
55
|
+
const sections = ids.map(
|
|
56
|
+
(step) => document.getElementById(checkoutSectionId(instanceId, step))
|
|
57
|
+
);
|
|
58
|
+
const observer = new IntersectionObserver(
|
|
59
|
+
(entries) => {
|
|
60
|
+
const intersecting = entries.filter((entry) => entry.isIntersecting);
|
|
61
|
+
if (intersecting.length > 0) {
|
|
62
|
+
const line = window.innerHeight * 0.25;
|
|
63
|
+
const activeEntry = intersecting.reduce(
|
|
64
|
+
(closest, entry) => Math.abs(entry.boundingClientRect.top - line) < Math.abs(closest.boundingClientRect.top - line) ? entry : closest
|
|
65
|
+
);
|
|
66
|
+
const step = activeEntry.target.dataset.checkoutStep;
|
|
67
|
+
if (step && ids.includes(step)) setActiveStep(step);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const fallback = fallbackStep(ids, sections);
|
|
71
|
+
if (fallback) setActiveStep(fallback);
|
|
72
|
+
},
|
|
73
|
+
{ rootMargin: "-20% 0px -70% 0px", threshold: 0 }
|
|
74
|
+
);
|
|
75
|
+
sections.forEach((section) => {
|
|
76
|
+
if (section) observer.observe(section);
|
|
77
|
+
});
|
|
78
|
+
return () => observer.disconnect();
|
|
79
|
+
}, [instanceId, stepKey]);
|
|
80
|
+
return activeStep;
|
|
81
|
+
}
|
|
82
|
+
function CheckoutSectionNav({ steps, ariaLabel, instanceId }) {
|
|
83
|
+
const activeStep = useActiveCheckoutSection(
|
|
84
|
+
steps.map((step) => step.id),
|
|
85
|
+
instanceId
|
|
86
|
+
);
|
|
87
|
+
const reduceMotion = (0, import_react2.useReducedMotion)();
|
|
88
|
+
const navigateToStep = (event, step) => {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
const heading = document.getElementById(checkoutSectionHeadingId(instanceId, step));
|
|
91
|
+
if (!heading) return;
|
|
92
|
+
const prefersReducedMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? Boolean(reduceMotion);
|
|
93
|
+
heading.scrollIntoView?.({ behavior: prefersReducedMotion ? "auto" : "smooth", block: "start" });
|
|
94
|
+
heading.focus({ preventScroll: true });
|
|
95
|
+
};
|
|
96
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { "aria-label": ariaLabel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "flex flex-wrap items-center gap-x-6 gap-y-1 border-b", children: steps.map((step, index) => {
|
|
97
|
+
const isCurrent = step.id === activeStep;
|
|
98
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
99
|
+
"a",
|
|
100
|
+
{
|
|
101
|
+
"data-checkout-step-nav": step.id,
|
|
102
|
+
href: `#${checkoutSectionId(instanceId, step.id)}`,
|
|
103
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
104
|
+
onClick: (event) => navigateToStep(event, step.id),
|
|
105
|
+
className: (0, import_utils.cn)(
|
|
106
|
+
"relative flex items-center gap-2 py-3 text-sm transition-colors",
|
|
107
|
+
isCurrent ? "font-medium text-foreground" : "text-muted-foreground"
|
|
108
|
+
),
|
|
109
|
+
children: [
|
|
110
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", className: "text-xs tabular-nums", children: String(index + 1).padStart(2, "0") }),
|
|
111
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: step.label }),
|
|
112
|
+
isCurrent ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
113
|
+
import_react2.motion.span,
|
|
114
|
+
{
|
|
115
|
+
"aria-hidden": "true",
|
|
116
|
+
layoutId: reduceMotion ? void 0 : "checkout-section-indicator",
|
|
117
|
+
transition: {
|
|
118
|
+
duration: import_motion.MOTION.durationSeconds.state,
|
|
119
|
+
ease: import_motion.MOTION.easing.standard
|
|
120
|
+
},
|
|
121
|
+
className: "bg-primary absolute inset-x-0 -bottom-px h-0.5"
|
|
122
|
+
}
|
|
123
|
+
) : null
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
) }, step.id);
|
|
127
|
+
}) }) });
|
|
128
|
+
}
|
|
129
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
130
|
+
0 && (module.exports = {
|
|
131
|
+
CheckoutSectionNav,
|
|
132
|
+
checkoutSectionHeadingId,
|
|
133
|
+
checkoutSectionId,
|
|
134
|
+
useActiveCheckoutSection
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=checkout-section-nav.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-section-nav.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport { motion, useReducedMotion } from 'motion/react'\nimport { cn } from '../../../lib/utils'\nimport { MOTION } from '../../../lib/motion'\nimport type { CheckoutStepId } from './checkout'\n\nexport interface CheckoutSectionNavProps {\n steps: Array<{ id: CheckoutStepId; label: string }>\n ariaLabel: string\n instanceId: string\n}\n\nexport function checkoutSectionId(instanceId: string, step: CheckoutStepId): string {\n return `${instanceId}-step-${step}`\n}\n\nexport function checkoutSectionHeadingId(instanceId: string, step: CheckoutStepId): string {\n return `${instanceId}-heading-${step}`\n}\n\nfunction fallbackStep(\n steps: CheckoutStepId[],\n sections: Array<HTMLElement | null>,\n): CheckoutStepId | undefined {\n const line = window.innerHeight * 0.25\n let current: CheckoutStepId | undefined\n\n sections.forEach((section, index) => {\n if (section && section.getBoundingClientRect().top <= line) {\n current = steps[index]\n }\n })\n\n return current ?? steps[0]\n}\n\nexport function useActiveCheckoutSection(\n stepIds: CheckoutStepId[],\n instanceId: string,\n): CheckoutStepId {\n const stepKey = stepIds.join('|')\n const [activeStep, setActiveStep] = useState<CheckoutStepId>(stepIds[0] ?? 'contact')\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof IntersectionObserver === 'undefined') return\n\n const ids = stepKey.split('|') as CheckoutStepId[]\n const sections = ids.map(\n (step) => document.getElementById(checkoutSectionId(instanceId, step)),\n )\n const observer = new IntersectionObserver(\n (entries) => {\n const intersecting = entries.filter((entry) => entry.isIntersecting)\n\n if (intersecting.length > 0) {\n const line = window.innerHeight * 0.25\n const activeEntry = intersecting.reduce((closest, entry) =>\n Math.abs(entry.boundingClientRect.top - line) <\n Math.abs(closest.boundingClientRect.top - line)\n ? entry\n : closest,\n )\n const step = (activeEntry.target as HTMLElement).dataset.checkoutStep as\n | CheckoutStepId\n | undefined\n if (step && ids.includes(step)) setActiveStep(step)\n return\n }\n\n const fallback = fallbackStep(ids, sections)\n if (fallback) setActiveStep(fallback)\n },\n { rootMargin: '-20% 0px -70% 0px', threshold: 0 },\n )\n\n sections.forEach((section) => {\n if (section) observer.observe(section)\n })\n\n return () => observer.disconnect()\n }, [instanceId, stepKey])\n\n return activeStep\n}\n\nexport function CheckoutSectionNav({ steps, ariaLabel, instanceId }: CheckoutSectionNavProps) {\n const activeStep = useActiveCheckoutSection(\n steps.map((step) => step.id),\n instanceId,\n )\n const reduceMotion = useReducedMotion()\n\n const navigateToStep = (event: React.MouseEvent<HTMLAnchorElement>, step: CheckoutStepId) => {\n event.preventDefault()\n const heading = document.getElementById(checkoutSectionHeadingId(instanceId, step))\n if (!heading) return\n\n const prefersReducedMotion =\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? Boolean(reduceMotion)\n heading.scrollIntoView?.({ behavior: prefersReducedMotion ? 'auto' : 'smooth', block: 'start' })\n heading.focus({ preventScroll: true })\n }\n\n return (\n <nav aria-label={ariaLabel}>\n <ol className=\"flex flex-wrap items-center gap-x-6 gap-y-1 border-b\">\n {steps.map((step, index) => {\n const isCurrent = step.id === activeStep\n\n return (\n <li key={step.id}>\n <a\n data-checkout-step-nav={step.id}\n href={`#${checkoutSectionId(instanceId, step.id)}`}\n aria-current={isCurrent ? 'step' : undefined}\n onClick={(event) => navigateToStep(event, step.id)}\n className={cn(\n 'relative flex items-center gap-2 py-3 text-sm transition-colors',\n isCurrent ? 'font-medium text-foreground' : 'text-muted-foreground',\n )}\n >\n <span aria-hidden=\"true\" className=\"text-xs tabular-nums\">\n {String(index + 1).padStart(2, '0')}\n </span>\n <span>{step.label}</span>\n {isCurrent ? (\n <motion.span\n aria-hidden=\"true\"\n layoutId={reduceMotion ? undefined : 'checkout-section-indicator'}\n transition={{\n duration: MOTION.durationSeconds.state,\n ease: MOTION.easing.standard,\n }}\n className=\"bg-primary absolute inset-x-0 -bottom-px h-0.5\"\n />\n ) : null}\n </a>\n </li>\n )\n })}\n </ol>\n </nav>\n )\n}\n"],"mappings":"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","names":["import_react"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { motion, useReducedMotion } from "motion/react";
|
|
5
|
+
import { cn } from "../../../lib/utils.mjs";
|
|
6
|
+
import { MOTION } from "../../../lib/motion.mjs";
|
|
7
|
+
function checkoutSectionId(instanceId, step) {
|
|
8
|
+
return `${instanceId}-step-${step}`;
|
|
9
|
+
}
|
|
10
|
+
function checkoutSectionHeadingId(instanceId, step) {
|
|
11
|
+
return `${instanceId}-heading-${step}`;
|
|
12
|
+
}
|
|
13
|
+
function fallbackStep(steps, sections) {
|
|
14
|
+
const line = window.innerHeight * 0.25;
|
|
15
|
+
let current;
|
|
16
|
+
sections.forEach((section, index) => {
|
|
17
|
+
if (section && section.getBoundingClientRect().top <= line) {
|
|
18
|
+
current = steps[index];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return current ?? steps[0];
|
|
22
|
+
}
|
|
23
|
+
function useActiveCheckoutSection(stepIds, instanceId) {
|
|
24
|
+
const stepKey = stepIds.join("|");
|
|
25
|
+
const [activeStep, setActiveStep] = useState(stepIds[0] ?? "contact");
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (typeof window === "undefined" || typeof IntersectionObserver === "undefined") return;
|
|
28
|
+
const ids = stepKey.split("|");
|
|
29
|
+
const sections = ids.map(
|
|
30
|
+
(step) => document.getElementById(checkoutSectionId(instanceId, step))
|
|
31
|
+
);
|
|
32
|
+
const observer = new IntersectionObserver(
|
|
33
|
+
(entries) => {
|
|
34
|
+
const intersecting = entries.filter((entry) => entry.isIntersecting);
|
|
35
|
+
if (intersecting.length > 0) {
|
|
36
|
+
const line = window.innerHeight * 0.25;
|
|
37
|
+
const activeEntry = intersecting.reduce(
|
|
38
|
+
(closest, entry) => Math.abs(entry.boundingClientRect.top - line) < Math.abs(closest.boundingClientRect.top - line) ? entry : closest
|
|
39
|
+
);
|
|
40
|
+
const step = activeEntry.target.dataset.checkoutStep;
|
|
41
|
+
if (step && ids.includes(step)) setActiveStep(step);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const fallback = fallbackStep(ids, sections);
|
|
45
|
+
if (fallback) setActiveStep(fallback);
|
|
46
|
+
},
|
|
47
|
+
{ rootMargin: "-20% 0px -70% 0px", threshold: 0 }
|
|
48
|
+
);
|
|
49
|
+
sections.forEach((section) => {
|
|
50
|
+
if (section) observer.observe(section);
|
|
51
|
+
});
|
|
52
|
+
return () => observer.disconnect();
|
|
53
|
+
}, [instanceId, stepKey]);
|
|
54
|
+
return activeStep;
|
|
55
|
+
}
|
|
56
|
+
function CheckoutSectionNav({ steps, ariaLabel, instanceId }) {
|
|
57
|
+
const activeStep = useActiveCheckoutSection(
|
|
58
|
+
steps.map((step) => step.id),
|
|
59
|
+
instanceId
|
|
60
|
+
);
|
|
61
|
+
const reduceMotion = useReducedMotion();
|
|
62
|
+
const navigateToStep = (event, step) => {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
const heading = document.getElementById(checkoutSectionHeadingId(instanceId, step));
|
|
65
|
+
if (!heading) return;
|
|
66
|
+
const prefersReducedMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? Boolean(reduceMotion);
|
|
67
|
+
heading.scrollIntoView?.({ behavior: prefersReducedMotion ? "auto" : "smooth", block: "start" });
|
|
68
|
+
heading.focus({ preventScroll: true });
|
|
69
|
+
};
|
|
70
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": ariaLabel, children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap items-center gap-x-6 gap-y-1 border-b", children: steps.map((step, index) => {
|
|
71
|
+
const isCurrent = step.id === activeStep;
|
|
72
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
73
|
+
"a",
|
|
74
|
+
{
|
|
75
|
+
"data-checkout-step-nav": step.id,
|
|
76
|
+
href: `#${checkoutSectionId(instanceId, step.id)}`,
|
|
77
|
+
"aria-current": isCurrent ? "step" : void 0,
|
|
78
|
+
onClick: (event) => navigateToStep(event, step.id),
|
|
79
|
+
className: cn(
|
|
80
|
+
"relative flex items-center gap-2 py-3 text-sm transition-colors",
|
|
81
|
+
isCurrent ? "font-medium text-foreground" : "text-muted-foreground"
|
|
82
|
+
),
|
|
83
|
+
children: [
|
|
84
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "text-xs tabular-nums", children: String(index + 1).padStart(2, "0") }),
|
|
85
|
+
/* @__PURE__ */ jsx("span", { children: step.label }),
|
|
86
|
+
isCurrent ? /* @__PURE__ */ jsx(
|
|
87
|
+
motion.span,
|
|
88
|
+
{
|
|
89
|
+
"aria-hidden": "true",
|
|
90
|
+
layoutId: reduceMotion ? void 0 : "checkout-section-indicator",
|
|
91
|
+
transition: {
|
|
92
|
+
duration: MOTION.durationSeconds.state,
|
|
93
|
+
ease: MOTION.easing.standard
|
|
94
|
+
},
|
|
95
|
+
className: "bg-primary absolute inset-x-0 -bottom-px h-0.5"
|
|
96
|
+
}
|
|
97
|
+
) : null
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
) }, step.id);
|
|
101
|
+
}) }) });
|
|
102
|
+
}
|
|
103
|
+
export {
|
|
104
|
+
CheckoutSectionNav,
|
|
105
|
+
checkoutSectionHeadingId,
|
|
106
|
+
checkoutSectionId,
|
|
107
|
+
useActiveCheckoutSection
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=checkout-section-nav.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-section-nav.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport { motion, useReducedMotion } from 'motion/react'\nimport { cn } from '../../../lib/utils'\nimport { MOTION } from '../../../lib/motion'\nimport type { CheckoutStepId } from './checkout'\n\nexport interface CheckoutSectionNavProps {\n steps: Array<{ id: CheckoutStepId; label: string }>\n ariaLabel: string\n instanceId: string\n}\n\nexport function checkoutSectionId(instanceId: string, step: CheckoutStepId): string {\n return `${instanceId}-step-${step}`\n}\n\nexport function checkoutSectionHeadingId(instanceId: string, step: CheckoutStepId): string {\n return `${instanceId}-heading-${step}`\n}\n\nfunction fallbackStep(\n steps: CheckoutStepId[],\n sections: Array<HTMLElement | null>,\n): CheckoutStepId | undefined {\n const line = window.innerHeight * 0.25\n let current: CheckoutStepId | undefined\n\n sections.forEach((section, index) => {\n if (section && section.getBoundingClientRect().top <= line) {\n current = steps[index]\n }\n })\n\n return current ?? steps[0]\n}\n\nexport function useActiveCheckoutSection(\n stepIds: CheckoutStepId[],\n instanceId: string,\n): CheckoutStepId {\n const stepKey = stepIds.join('|')\n const [activeStep, setActiveStep] = useState<CheckoutStepId>(stepIds[0] ?? 'contact')\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof IntersectionObserver === 'undefined') return\n\n const ids = stepKey.split('|') as CheckoutStepId[]\n const sections = ids.map(\n (step) => document.getElementById(checkoutSectionId(instanceId, step)),\n )\n const observer = new IntersectionObserver(\n (entries) => {\n const intersecting = entries.filter((entry) => entry.isIntersecting)\n\n if (intersecting.length > 0) {\n const line = window.innerHeight * 0.25\n const activeEntry = intersecting.reduce((closest, entry) =>\n Math.abs(entry.boundingClientRect.top - line) <\n Math.abs(closest.boundingClientRect.top - line)\n ? entry\n : closest,\n )\n const step = (activeEntry.target as HTMLElement).dataset.checkoutStep as\n | CheckoutStepId\n | undefined\n if (step && ids.includes(step)) setActiveStep(step)\n return\n }\n\n const fallback = fallbackStep(ids, sections)\n if (fallback) setActiveStep(fallback)\n },\n { rootMargin: '-20% 0px -70% 0px', threshold: 0 },\n )\n\n sections.forEach((section) => {\n if (section) observer.observe(section)\n })\n\n return () => observer.disconnect()\n }, [instanceId, stepKey])\n\n return activeStep\n}\n\nexport function CheckoutSectionNav({ steps, ariaLabel, instanceId }: CheckoutSectionNavProps) {\n const activeStep = useActiveCheckoutSection(\n steps.map((step) => step.id),\n instanceId,\n )\n const reduceMotion = useReducedMotion()\n\n const navigateToStep = (event: React.MouseEvent<HTMLAnchorElement>, step: CheckoutStepId) => {\n event.preventDefault()\n const heading = document.getElementById(checkoutSectionHeadingId(instanceId, step))\n if (!heading) return\n\n const prefersReducedMotion =\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? Boolean(reduceMotion)\n heading.scrollIntoView?.({ behavior: prefersReducedMotion ? 'auto' : 'smooth', block: 'start' })\n heading.focus({ preventScroll: true })\n }\n\n return (\n <nav aria-label={ariaLabel}>\n <ol className=\"flex flex-wrap items-center gap-x-6 gap-y-1 border-b\">\n {steps.map((step, index) => {\n const isCurrent = step.id === activeStep\n\n return (\n <li key={step.id}>\n <a\n data-checkout-step-nav={step.id}\n href={`#${checkoutSectionId(instanceId, step.id)}`}\n aria-current={isCurrent ? 'step' : undefined}\n onClick={(event) => navigateToStep(event, step.id)}\n className={cn(\n 'relative flex items-center gap-2 py-3 text-sm transition-colors',\n isCurrent ? 'font-medium text-foreground' : 'text-muted-foreground',\n )}\n >\n <span aria-hidden=\"true\" className=\"text-xs tabular-nums\">\n {String(index + 1).padStart(2, '0')}\n </span>\n <span>{step.label}</span>\n {isCurrent ? (\n <motion.span\n aria-hidden=\"true\"\n layoutId={reduceMotion ? undefined : 'checkout-section-indicator'}\n transition={{\n duration: MOTION.durationSeconds.state,\n ease: MOTION.easing.standard,\n }}\n className=\"bg-primary absolute inset-x-0 -bottom-px h-0.5\"\n />\n ) : null}\n </a>\n </li>\n )\n })}\n </ol>\n </nav>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,17 +1,39 @@
|
|
|
1
|
-
import type { Money } from '@thorprovider/types';
|
|
2
|
-
import type {
|
|
1
|
+
import type { CheckoutAddressLevel, CheckoutAddressValues, CheckoutLocationOptions, CheckoutSavedAddress, CheckoutShippingGroup, Money } from '@thorprovider/types';
|
|
2
|
+
import type { CheckoutAddressChangeHandler, CheckoutFieldDescriptions, CheckoutFieldErrors, CheckoutLabels, CheckoutSavedAddressState } from './checkout';
|
|
3
3
|
export interface CheckoutShippingStepProps {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
shippingAddress: CheckoutAddressValues;
|
|
5
|
+
billingAddress?: CheckoutAddressValues;
|
|
6
|
+
sameAsShipping: boolean;
|
|
7
|
+
onShippingAddressChange: CheckoutAddressChangeHandler;
|
|
8
|
+
onBillingAddressChange?: CheckoutAddressChangeHandler;
|
|
9
|
+
onSameAsShippingChange: (same: boolean) => void;
|
|
10
|
+
shippingLocations?: CheckoutLocationOptions;
|
|
11
|
+
billingLocations?: CheckoutLocationOptions;
|
|
12
|
+
onRetryLocations?: (kind: 'shipping' | 'billing', level: CheckoutAddressLevel) => void;
|
|
13
|
+
savedAddresses?: CheckoutSavedAddress[];
|
|
14
|
+
onSelectSavedAddress?: (id: string) => void;
|
|
15
|
+
onCreateSavedAddress?: (address: CheckoutAddressValues) => void;
|
|
16
|
+
onUpdateSavedAddress?: (id: string, address: CheckoutAddressValues) => void;
|
|
17
|
+
onDeleteSavedAddress?: (id: string) => void;
|
|
18
|
+
onStartNewAddress?: () => void;
|
|
19
|
+
onCancelNewAddress?: () => void;
|
|
20
|
+
savedAddressState?: CheckoutSavedAddressState;
|
|
21
|
+
shippingGroups?: CheckoutShippingGroup[];
|
|
22
|
+
shippingState?: 'idle' | 'pending' | 'error' | 'unavailable';
|
|
23
|
+
onSelectShippingOption?: (groupId: string, optionId: string) => void;
|
|
24
|
+
onRetryShipping?: () => void;
|
|
6
25
|
labels: CheckoutLabels;
|
|
7
|
-
countries?: CheckoutCountryOption[];
|
|
8
|
-
shippingOptions?: CheckoutShippingOption[];
|
|
9
|
-
selectedShippingOptionId?: string;
|
|
10
|
-
onSelectShippingOption?: (id: string) => void;
|
|
11
26
|
/** Override money formatting (locale, currency). Defaults to `Money.currencyCode`. */
|
|
12
27
|
formatMoney?: (money: Money) => string;
|
|
13
|
-
fieldErrors?:
|
|
28
|
+
fieldErrors?: CheckoutFieldErrors;
|
|
14
29
|
fieldDescriptions?: CheckoutFieldDescriptions;
|
|
30
|
+
requireShippingPhone?: boolean;
|
|
15
31
|
}
|
|
16
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Shipping and billing addresses, the saved-address book, and the contextual
|
|
34
|
+
* save/update/create actions. The block is controlled: it reports intentions
|
|
35
|
+
* and renders the host's refreshed list and mutation state; it never mutates
|
|
36
|
+
* the address book itself.
|
|
37
|
+
*/
|
|
38
|
+
export declare function CheckoutShippingStep({ shippingAddress, billingAddress, sameAsShipping, onShippingAddressChange, onBillingAddressChange, onSameAsShippingChange, shippingLocations, billingLocations, onRetryLocations, savedAddresses, onSelectSavedAddress, onCreateSavedAddress, onUpdateSavedAddress, onDeleteSavedAddress, onStartNewAddress, onCancelNewAddress, savedAddressState, shippingGroups, shippingState, onSelectShippingOption, onRetryShipping, labels, formatMoney: formatMoneyProp, fieldErrors, fieldDescriptions, requireShippingPhone, }: CheckoutShippingStepProps): import("react").JSX.Element;
|
|
17
39
|
//# sourceMappingURL=checkout-shipping-step.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout-shipping-step.d.ts","sourceRoot":"","sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-shipping-step.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkout-shipping-step.d.ts","sourceRoot":"","sources":["../../../../src/blocks/e-commerce/checkout-forms/checkout-shipping-step.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,EACN,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EACV,4BAA4B,EAC5B,yBAAyB,EACzB,mBAAmB,EACnB,cAAc,EACd,yBAAyB,EAC1B,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,yBAAyB;IACxC,eAAe,EAAE,qBAAqB,CAAA;IACtC,cAAc,CAAC,EAAE,qBAAqB,CAAA;IACtC,cAAc,EAAE,OAAO,CAAA;IACvB,uBAAuB,EAAE,4BAA4B,CAAA;IACrD,sBAAsB,CAAC,EAAE,4BAA4B,CAAA;IACrD,sBAAsB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAC/C,iBAAiB,CAAC,EAAE,uBAAuB,CAAA;IAC3C,gBAAgB,CAAC,EAAE,uBAAuB,CAAA;IAC1C,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,EAAE,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACtF,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAA;IACvC,oBAAoB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAC/D,oBAAoB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAC3E,oBAAoB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC/B,iBAAiB,CAAC,EAAE,yBAAyB,CAAA;IAC7C,cAAc,CAAC,EAAE,qBAAqB,EAAE,CAAA;IACxC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAA;IAC5D,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACpE,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;IAC5B,MAAM,EAAE,cAAc,CAAA;IACtB,sFAAsF;IACtF,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAA;IACtC,WAAW,CAAC,EAAE,mBAAmB,CAAA;IACjC,iBAAiB,CAAC,EAAE,yBAAyB,CAAA;IAC7C,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,eAAe,EACf,cAAc,EACd,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,aAAsB,EACtB,sBAAsB,EACtB,eAAe,EACf,MAAM,EACN,WAAW,EAAE,eAAe,EAC5B,WAAW,EACX,iBAAiB,EACjB,oBAA4B,GAC7B,EAAE,yBAAyB,+BA2N3B"}
|