@asteby/storefront-react 0.25.0 → 0.26.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 +35 -2
- package/dist/account-server.cjs +128 -19
- package/dist/account-server.cjs.map +1 -1
- package/dist/account-server.d.cts +67 -4
- package/dist/account-server.d.ts +67 -4
- package/dist/account-server.js +125 -20
- package/dist/account-server.js.map +1 -1
- package/dist/account.cjs +252 -7
- package/dist/account.cjs.map +1 -1
- package/dist/account.css +91 -0
- package/dist/account.d.cts +130 -6
- package/dist/account.d.ts +130 -6
- package/dist/account.js +247 -8
- package/dist/account.js.map +1 -1
- package/dist/checkout.cjs +162 -8
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +104 -4
- package/dist/checkout.d.ts +104 -4
- package/dist/checkout.js +158 -10
- package/dist/checkout.js.map +1 -1
- package/dist/chunk-Z4C4LKXF.js +25 -0
- package/dist/chunk-Z4C4LKXF.js.map +1 -0
- package/dist/fit-key-B9sYQVwG.d.cts +49 -0
- package/dist/fit-key-B9sYQVwG.d.ts +49 -0
- package/dist/fitment.cjs +54 -9
- package/dist/fitment.cjs.map +1 -1
- package/dist/fitment.d.cts +20 -2
- package/dist/fitment.d.ts +20 -2
- package/dist/fitment.js +54 -10
- package/dist/fitment.js.map +1 -1
- package/dist/settings-types-jxFQFFqP.d.cts +77 -0
- package/dist/settings-types-jxFQFFqP.d.ts +77 -0
- package/dist/subjects-server.cjs +248 -0
- package/dist/subjects-server.cjs.map +1 -0
- package/dist/subjects-server.d.cts +130 -0
- package/dist/subjects-server.d.ts +130 -0
- package/dist/subjects-server.js +217 -0
- package/dist/subjects-server.js.map +1 -0
- package/dist/subjects.cjs +501 -0
- package/dist/subjects.cjs.map +1 -0
- package/dist/subjects.css +166 -0
- package/dist/subjects.d.cts +178 -0
- package/dist/subjects.d.ts +178 -0
- package/dist/subjects.js +465 -0
- package/dist/subjects.js.map +1 -0
- package/package.json +23 -2
- package/dist/types-D7pVK0GK.d.cts +0 -39
- package/dist/types-D7pVK0GK.d.ts +0 -39
package/dist/checkout.cjs
CHANGED
|
@@ -1180,7 +1180,10 @@ var ES4 = {
|
|
|
1180
1180
|
moreOptions: "Ver m\xE1s opciones ({n})",
|
|
1181
1181
|
otherCarriers: "Otras opciones",
|
|
1182
1182
|
error: "No pudimos consultar las opciones de env\xEDo en este momento.",
|
|
1183
|
-
retry: "Intentar de nuevo"
|
|
1183
|
+
retry: "Intentar de nuevo",
|
|
1184
|
+
freeShipping: "Env\xEDo gratis",
|
|
1185
|
+
freeShippingNote: "Tu pedido ya incluye el env\xEDo: no tienes que elegir paqueter\xEDa.",
|
|
1186
|
+
ratesReady: "Opciones de env\xEDo listas ({n})."
|
|
1184
1187
|
};
|
|
1185
1188
|
var EN4 = {
|
|
1186
1189
|
etaOne: "Arrives in 1 business day",
|
|
@@ -1203,7 +1206,10 @@ var EN4 = {
|
|
|
1203
1206
|
moreOptions: "Show more options ({n})",
|
|
1204
1207
|
otherCarriers: "Other options",
|
|
1205
1208
|
error: "We couldn't get delivery options right now.",
|
|
1206
|
-
retry: "Try again"
|
|
1209
|
+
retry: "Try again",
|
|
1210
|
+
freeShipping: "Free shipping",
|
|
1211
|
+
freeShippingNote: "Shipping is included in your order: there is no carrier to choose.",
|
|
1212
|
+
ratesReady: "Delivery options ready ({n})."
|
|
1207
1213
|
};
|
|
1208
1214
|
function deliveryMessages(locale, overrides) {
|
|
1209
1215
|
const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN4 : ES4;
|
|
@@ -1296,13 +1302,13 @@ function isQuoteChange(err) {
|
|
|
1296
1302
|
}
|
|
1297
1303
|
function matchRate(previous, rates) {
|
|
1298
1304
|
if (!previous) return null;
|
|
1299
|
-
const
|
|
1300
|
-
const sameCarrier = (r) =>
|
|
1305
|
+
const norm3 = (s) => (s ?? "").trim().toLowerCase();
|
|
1306
|
+
const sameCarrier = (r) => norm3(r.carrier) === norm3(previous.carrier);
|
|
1301
1307
|
if (previous.service_code) {
|
|
1302
|
-
const hit = rates.find((r) => sameCarrier(r) &&
|
|
1308
|
+
const hit = rates.find((r) => sameCarrier(r) && norm3(r.service_code) === norm3(previous.service_code));
|
|
1303
1309
|
if (hit) return hit;
|
|
1304
1310
|
}
|
|
1305
|
-
return rates.find((r) => sameCarrier(r) &&
|
|
1311
|
+
return rates.find((r) => sameCarrier(r) && norm3(r.title) === norm3(previous.title)) ?? null;
|
|
1306
1312
|
}
|
|
1307
1313
|
var SR_ONLY = { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)", whiteSpace: "nowrap" };
|
|
1308
1314
|
var useHydrated = () => react.useSyncExternalStore(
|
|
@@ -1339,7 +1345,8 @@ function DeliveryOptions(props) {
|
|
|
1339
1345
|
children,
|
|
1340
1346
|
layout = "list",
|
|
1341
1347
|
error,
|
|
1342
|
-
onRetry
|
|
1348
|
+
onRetry,
|
|
1349
|
+
free = false
|
|
1343
1350
|
} = props;
|
|
1344
1351
|
const locale = useResolvedLocale(props.locale);
|
|
1345
1352
|
const m = react.useMemo(() => deliveryMessages(locale, props.messages), [locale, props.messages]);
|
|
@@ -1407,17 +1414,24 @@ function DeliveryOptions(props) {
|
|
|
1407
1414
|
] }, rate.id);
|
|
1408
1415
|
};
|
|
1409
1416
|
const errorText = error ? typeof error === "string" ? error : m.error : null;
|
|
1417
|
+
const freeRate = free && !loading && pickup.length === 0 ? rates.find((r) => !r.pickup) ?? null : null;
|
|
1410
1418
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.root, "data-sf-delivery": true, "data-layout": layout, "aria-busy": loading || void 0, children: [
|
|
1411
1419
|
partial && !errorText ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: cx.partial, "data-sf-delivery-partial": true, children: m.partial }) : null,
|
|
1412
1420
|
requoted ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: cx.partial, "data-sf-delivery-requoted": true, children: m.requoted }) : null,
|
|
1413
1421
|
loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: SR_ONLY, role: "status", "data-sf-delivery-loading": true, children: m.loading }) : null,
|
|
1422
|
+
props.announceReady && !loading && rates.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: SR_ONLY, role: "status", "data-sf-delivery-ready": true, children: freeRate ? m.freeShipping : m.ratesReady.replace("{n}", String(rates.length)) }) : null,
|
|
1414
1423
|
errorText && rates.length === 0 && !loading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: cx.error, "data-sf-delivery-error": true, children: [
|
|
1415
1424
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: errorText }),
|
|
1416
1425
|
onRetry ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cx.retry, onClick: onRetry, "data-sf-delivery-retry": true, children: m.retry }) : null
|
|
1417
1426
|
] }) : null,
|
|
1427
|
+
freeRate ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.freeBanner, role: props.announceReady ? void 0 : "status", "data-sf-delivery-free-banner": true, children: [
|
|
1428
|
+
/* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: rateValue(freeRate), ...testId ? { "data-testid": testId } : {} }),
|
|
1429
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.free, "data-sf-delivery-free-title": true, children: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: m.freeShipping }) }),
|
|
1430
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.note, children: m.freeShippingNote })
|
|
1431
|
+
] }) : null,
|
|
1418
1432
|
children,
|
|
1419
1433
|
loading && rates.length === 0 ? [0, 1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx.skeleton, "data-sf-delivery-skeleton": true, "aria-hidden": "true" }, i)) : null,
|
|
1420
|
-
flat ? flat.map(({ rate, tags }) => rateRow(rate, { tags: showBadges ? tags : [] })) : plan ? plan.recommended.map(({ rate, tags }) => rateRow(rate, { tags: showBadges ? tags : [] })) : rates.map((rate) => rateRow(rate, { tags: badges.get(rate.id) ?? [] })),
|
|
1434
|
+
freeRate ? null : flat ? flat.map(({ rate, tags }) => rateRow(rate, { tags: showBadges ? tags : [] })) : plan ? plan.recommended.map(({ rate, tags }) => rateRow(rate, { tags: showBadges ? tags : [] })) : rates.map((rate) => rateRow(rate, { tags: badges.get(rate.id) ?? [] })),
|
|
1421
1435
|
plan && plan.moreCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("details", { className: cx.more, "data-sf-delivery-more": true, ...inMore ? { open: true } : {}, children: [
|
|
1422
1436
|
/* @__PURE__ */ jsxRuntime.jsx("summary", { className: cx.moreSummary, "data-sf-delivery-more-summary": true, children: m.moreOptions.replace("{n}", String(plan.moreCount)) }),
|
|
1423
1437
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-sf-delivery-groups": true, children: plan.more.map((g) => {
|
|
@@ -1444,21 +1458,158 @@ function DeliveryOptions(props) {
|
|
|
1444
1458
|
deadline ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.note, "data-sf-delivery-note": true, "data-soon": shownNote?.soon || void 0, "aria-live": "polite", children: shownNote?.text ?? "" }) : null
|
|
1445
1459
|
] });
|
|
1446
1460
|
}
|
|
1461
|
+
var DEFAULT_QUOTE_NAMES = {
|
|
1462
|
+
country_code: "country_code",
|
|
1463
|
+
zip: "zip",
|
|
1464
|
+
province: "province",
|
|
1465
|
+
city: "city",
|
|
1466
|
+
neighborhood: "neighborhood",
|
|
1467
|
+
address1: "address1"
|
|
1468
|
+
};
|
|
1469
|
+
var DEFAULT_REQUIRED = ["zip", "province", "city", "neighborhood", "address1"];
|
|
1470
|
+
var QUOTE_KEYS = ["country_code", "zip", "province", "city"];
|
|
1471
|
+
var norm2 = (v) => v.normalize("NFD").replace(/[̀-ͯ]/g, "").trim().toLowerCase();
|
|
1472
|
+
function quoteFingerprint(a) {
|
|
1473
|
+
return QUOTE_KEYS.map((k) => norm2(a[k] ?? "")).join("|");
|
|
1474
|
+
}
|
|
1475
|
+
function defaultRate(delivery) {
|
|
1476
|
+
let best = null;
|
|
1477
|
+
for (const r of delivery.rates) {
|
|
1478
|
+
if (r.pickup) continue;
|
|
1479
|
+
if (!best || Number(r.cost.amount) < Number(best.cost.amount)) best = r;
|
|
1480
|
+
}
|
|
1481
|
+
return best;
|
|
1482
|
+
}
|
|
1483
|
+
function readQuoteAddress(form, opts = {}) {
|
|
1484
|
+
if (!form) return null;
|
|
1485
|
+
const names = { ...DEFAULT_QUOTE_NAMES, ...opts.names };
|
|
1486
|
+
const data = new FormData(form);
|
|
1487
|
+
const get = (name) => String(data.get(name) ?? "").trim();
|
|
1488
|
+
const address = {
|
|
1489
|
+
country_code: get(names.country_code) || opts.defaultCountry || "MX",
|
|
1490
|
+
zip: get(names.zip),
|
|
1491
|
+
province: get(names.province),
|
|
1492
|
+
city: get(names.city),
|
|
1493
|
+
neighborhood: get(names.neighborhood),
|
|
1494
|
+
address1: get(names.address1)
|
|
1495
|
+
};
|
|
1496
|
+
const valid = opts.validPostalCode ?? ((z) => /^\d{5}$/.test(z));
|
|
1497
|
+
if (!valid(address.zip)) return null;
|
|
1498
|
+
for (const k of opts.required ?? DEFAULT_REQUIRED) if (!address[k]) return null;
|
|
1499
|
+
return address;
|
|
1500
|
+
}
|
|
1501
|
+
function useAutoQuote(options) {
|
|
1502
|
+
const { formRef, debounceMs = 600, enabled = true } = options;
|
|
1503
|
+
const [status, setStatus] = react.useState("idle");
|
|
1504
|
+
const [delivery, setDelivery] = react.useState(null);
|
|
1505
|
+
const [quotedFor, setQuotedFor] = react.useState(null);
|
|
1506
|
+
const opts = react.useRef(options);
|
|
1507
|
+
opts.current = options;
|
|
1508
|
+
const timer = react.useRef(null);
|
|
1509
|
+
const inflight = react.useRef(null);
|
|
1510
|
+
const quotedFp = react.useRef(null);
|
|
1511
|
+
const pendingFp = react.useRef(null);
|
|
1512
|
+
const run = react.useCallback((address, fp) => {
|
|
1513
|
+
inflight.current?.abort();
|
|
1514
|
+
const ctl = new AbortController();
|
|
1515
|
+
inflight.current = ctl;
|
|
1516
|
+
pendingFp.current = fp;
|
|
1517
|
+
setStatus("loading");
|
|
1518
|
+
opts.current.quote(address, ctl.signal).then((d) => {
|
|
1519
|
+
if (ctl.signal.aborted) return;
|
|
1520
|
+
quotedFp.current = fp;
|
|
1521
|
+
pendingFp.current = null;
|
|
1522
|
+
setDelivery(d);
|
|
1523
|
+
setQuotedFor(address);
|
|
1524
|
+
setStatus("ready");
|
|
1525
|
+
opts.current.onQuoted?.(d);
|
|
1526
|
+
}).catch(() => {
|
|
1527
|
+
if (ctl.signal.aborted) return;
|
|
1528
|
+
pendingFp.current = null;
|
|
1529
|
+
quotedFp.current = null;
|
|
1530
|
+
setStatus("error");
|
|
1531
|
+
});
|
|
1532
|
+
}, []);
|
|
1533
|
+
const evaluate = react.useCallback(
|
|
1534
|
+
(force) => {
|
|
1535
|
+
const address = readQuoteAddress(formRef.current, opts.current);
|
|
1536
|
+
if (!address) {
|
|
1537
|
+
if (timer.current) clearTimeout(timer.current);
|
|
1538
|
+
timer.current = null;
|
|
1539
|
+
inflight.current?.abort();
|
|
1540
|
+
pendingFp.current = null;
|
|
1541
|
+
setStatus("idle");
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
const fp = quoteFingerprint(address);
|
|
1545
|
+
if (!force && (fp === quotedFp.current || fp === pendingFp.current)) {
|
|
1546
|
+
if (timer.current) clearTimeout(timer.current);
|
|
1547
|
+
timer.current = null;
|
|
1548
|
+
if (fp === quotedFp.current) setStatus("ready");
|
|
1549
|
+
return;
|
|
1550
|
+
}
|
|
1551
|
+
if (timer.current) clearTimeout(timer.current);
|
|
1552
|
+
if (force) {
|
|
1553
|
+
timer.current = null;
|
|
1554
|
+
run(address, fp);
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
setStatus("waiting");
|
|
1558
|
+
timer.current = setTimeout(() => {
|
|
1559
|
+
timer.current = null;
|
|
1560
|
+
const latest = readQuoteAddress(formRef.current, opts.current);
|
|
1561
|
+
if (latest) run(latest, quoteFingerprint(latest));
|
|
1562
|
+
}, debounceMs);
|
|
1563
|
+
},
|
|
1564
|
+
[debounceMs, formRef, run]
|
|
1565
|
+
);
|
|
1566
|
+
react.useEffect(() => {
|
|
1567
|
+
const form = formRef.current;
|
|
1568
|
+
if (!enabled || !form) return;
|
|
1569
|
+
const onChange = () => evaluate(false);
|
|
1570
|
+
form.addEventListener("input", onChange);
|
|
1571
|
+
form.addEventListener("change", onChange);
|
|
1572
|
+
const first = setTimeout(onChange, 0);
|
|
1573
|
+
return () => {
|
|
1574
|
+
clearTimeout(first);
|
|
1575
|
+
form.removeEventListener("input", onChange);
|
|
1576
|
+
form.removeEventListener("change", onChange);
|
|
1577
|
+
if (timer.current) clearTimeout(timer.current);
|
|
1578
|
+
inflight.current?.abort();
|
|
1579
|
+
};
|
|
1580
|
+
}, [enabled, evaluate, formRef]);
|
|
1581
|
+
const retry = react.useCallback(() => evaluate(true), [evaluate]);
|
|
1582
|
+
const defaultValue = react.useMemo(() => {
|
|
1583
|
+
if (!delivery) return null;
|
|
1584
|
+
const saved = opts.current.savedValue;
|
|
1585
|
+
if (saved?.startsWith("rate:")) {
|
|
1586
|
+
const hit = delivery.rates.find((r) => `rate:${r.id}` === saved);
|
|
1587
|
+
if (hit) return `rate:${hit.id}`;
|
|
1588
|
+
}
|
|
1589
|
+
const pick = (opts.current.pickDefault ?? defaultRate)(delivery);
|
|
1590
|
+
return pick ? `rate:${pick.id}` : null;
|
|
1591
|
+
}, [delivery, options.savedValue]);
|
|
1592
|
+
const announce = status === "loading" || status === "waiting" ? "searching" : status === "error" ? "error" : status === "ready" ? delivery?.free ? "free" : "ready" : null;
|
|
1593
|
+
return { status, delivery, defaultValue, quotedFor, retry, announce };
|
|
1594
|
+
}
|
|
1447
1595
|
|
|
1448
1596
|
exports.ADDRESS_FILL_EVENT_FLAG = ADDRESS_FILL_EVENT_FLAG;
|
|
1449
1597
|
exports.AddressFields = AddressFields;
|
|
1450
1598
|
exports.BrandMark = BrandMark;
|
|
1451
1599
|
exports.CheckoutField = CheckoutField;
|
|
1452
1600
|
exports.ContactFields = ContactFields;
|
|
1601
|
+
exports.DEFAULT_QUOTE_NAMES = DEFAULT_QUOTE_NAMES;
|
|
1453
1602
|
exports.DeliveryOptions = DeliveryOptions;
|
|
1454
1603
|
exports.ErrorSummary = ErrorSummary;
|
|
1455
1604
|
exports.OrderSummary = OrderSummary;
|
|
1456
1605
|
exports.OrderSummaryDisclosure = OrderSummaryDisclosure;
|
|
1606
|
+
exports.QUOTE_KEYS = QUOTE_KEYS;
|
|
1457
1607
|
exports.addressFieldsMessages = addressFieldsMessages;
|
|
1458
1608
|
exports.brandKey = brandKey;
|
|
1459
1609
|
exports.brandLogo = brandLogo;
|
|
1460
1610
|
exports.brandName = brandName;
|
|
1461
1611
|
exports.dedupeRates = dedupeRates;
|
|
1612
|
+
exports.defaultRate = defaultRate;
|
|
1462
1613
|
exports.deliveryMessages = deliveryMessages;
|
|
1463
1614
|
exports.fieldMessages = fieldMessages;
|
|
1464
1615
|
exports.findBrand = findBrand;
|
|
@@ -1469,12 +1620,15 @@ exports.listBrands = listBrands;
|
|
|
1469
1620
|
exports.matchRate = matchRate;
|
|
1470
1621
|
exports.orderSummaryMessages = orderSummaryMessages;
|
|
1471
1622
|
exports.quoteDeadline = quoteDeadline;
|
|
1623
|
+
exports.quoteFingerprint = quoteFingerprint;
|
|
1472
1624
|
exports.quoteNote = quoteNote;
|
|
1473
1625
|
exports.rateBadges = rateBadges;
|
|
1474
1626
|
exports.rateCarrier = rateCarrier;
|
|
1475
1627
|
exports.rateEta = rateEta;
|
|
1476
1628
|
exports.rateService = rateService;
|
|
1629
|
+
exports.readQuoteAddress = readQuoteAddress;
|
|
1477
1630
|
exports.recommendRates = recommendRates;
|
|
1631
|
+
exports.useAutoQuote = useAutoQuote;
|
|
1478
1632
|
exports.useFieldErrors = useFieldErrors;
|
|
1479
1633
|
exports.validationMessage = validationMessage;
|
|
1480
1634
|
//# sourceMappingURL=checkout.cjs.map
|