@asteby/storefront-react 0.8.0 → 0.10.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.
@@ -0,0 +1,440 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var storefront = require('@asteby/storefront');
6
+
7
+ // src/checkout/brands.ts
8
+ var B = (key, name, kind, bg, fg, mark, shape) => ({
9
+ key,
10
+ name,
11
+ kind,
12
+ bg,
13
+ fg,
14
+ ...mark ? { mark } : {},
15
+ ...shape ? { shape } : {}
16
+ });
17
+ var LIST = [
18
+ // Parcel carriers (Mexico and global).
19
+ B("fedex", "FedEx", "carrier", "#4D148C", "#FFFFFF"),
20
+ B("dhl", "DHL", "carrier", "#FFCC00", "#B00410"),
21
+ B("estafeta", "Estafeta", "carrier", "#C8102E", "#FFFFFF"),
22
+ B("paquetexpress", "Paquetexpress", "carrier", "#0B4EA2", "#FFFFFF", "Paquet\nexpress"),
23
+ B("ups", "UPS", "carrier", "#351C15", "#FFB500"),
24
+ B("redpack", "Redpack", "carrier", "#C8102E", "#FFFFFF"),
25
+ B("99minutos", "99 Minutos", "carrier", "#00704A", "#FFFFFF", "99"),
26
+ B("jtexpress", "J&T Express", "carrier", "#C8102E", "#FFFFFF", "J&T"),
27
+ B("sendex", "Sendex", "carrier", "#003A70", "#FFFFFF"),
28
+ B("ampm", "AMPM", "carrier", "#1D1D1B", "#FFFFFF"),
29
+ B("tresguerras", "Tresguerras", "carrier", "#005BAC", "#FFFFFF", "3G"),
30
+ B("quiken", "Quiken", "carrier", "#1D1D1B", "#FFFFFF"),
31
+ B("imile", "iMile", "carrier", "#0057B8", "#FFFFFF"),
32
+ B("carssa", "Carssa", "carrier", "#00529B", "#FFFFFF"),
33
+ B("correosdemexico", "Correos de M\xE9xico", "carrier", "#7A1E3A", "#FFFFFF", "Correos\nM\xE9xico"),
34
+ B("usps", "USPS", "carrier", "#333366", "#FFFFFF"),
35
+ B("canadapost", "Canada Post", "carrier", "#DA291C", "#FFFFFF", "CPC"),
36
+ // Card networks.
37
+ B("visa", "Visa", "card", "#1A1F71", "#FFFFFF", "VISA"),
38
+ B("mastercard", "Mastercard", "card", "#FFFFFF", "#1D1D1B", "MC", "mastercard"),
39
+ B("amex", "American Express", "card", "#1F72CD", "#FFFFFF", "AMEX"),
40
+ B("carnet", "Carnet", "card", "#003B71", "#FFFFFF"),
41
+ // Wallets and payment providers.
42
+ B("mercadopago", "Mercado Pago", "wallet", "#00B1EA", "#0B1F4E", "mercado\npago"),
43
+ B("paypal", "PayPal", "wallet", "#003087", "#FFFFFF"),
44
+ B("clip", "Clip", "wallet", "#FC4C02", "#1D1D1B"),
45
+ B("applepay", "Apple Pay", "wallet", "#000000", "#FFFFFF", "Pay"),
46
+ B("googlepay", "Google Pay", "wallet", "#FFFFFF", "#3C4043", "G Pay"),
47
+ // Cash points and transfers (Mexico).
48
+ B("oxxo", "OXXO", "cash", "#E21E26", "#FFE600"),
49
+ B("spei", "SPEI", "bank", "#14365F", "#FFFFFF"),
50
+ B("stp", "STP", "bank", "#14365F", "#FFFFFF", "SPEI"),
51
+ B("7eleven", "7-Eleven", "cash", "#00704A", "#FFFFFF", "7-11"),
52
+ B("circlek", "Circle K", "cash", "#DA291C", "#FFFFFF", "K"),
53
+ B("soriana", "Soriana", "cash", "#C8102E", "#FFFFFF"),
54
+ B("extra", "Extra", "cash", "#E35205", "#FFFFFF"),
55
+ B("kiosko", "Kiosko", "cash", "#C8102E", "#FFFFFF"),
56
+ B("calimax", "Calimax", "cash", "#D52B1E", "#FFFFFF"),
57
+ B("farmaciasyza", "Farmacias Yza", "cash", "#0A5A9C", "#FFFFFF", "Yza"),
58
+ B("chedraui", "Chedraui", "cash", "#0047BB", "#FFFFFF"),
59
+ B("casaley", "Casa Ley", "cash", "#C8102E", "#FFFFFF", "Ley"),
60
+ B("telecomm", "Telecomm", "cash", "#6F1D46", "#FFFFFF"),
61
+ B("walmart", "Walmart", "cash", "#0071CE", "#FFFFFF"),
62
+ B("santander", "Santander", "bank", "#C00000", "#FFFFFF"),
63
+ B("bbva", "BBVA", "bank", "#004481", "#FFFFFF"),
64
+ B("citibanamex", "Citibanamex", "bank", "#004B8D", "#FFFFFF", "Citi"),
65
+ B("banorte", "Banorte", "bank", "#C8102E", "#FFFFFF")
66
+ ];
67
+ var ALIASES = {
68
+ fedexmx: "fedex",
69
+ fedexexpress: "fedex",
70
+ dhlexpress: "dhl",
71
+ dhlmx: "dhl",
72
+ paquetexpres: "paquetexpress",
73
+ paqueteexpress: "paquetexpress",
74
+ jt: "jtexpress",
75
+ jandtexpress: "jtexpress",
76
+ noventaynueveminutos: "99minutos",
77
+ correos: "correosdemexico",
78
+ sepomex: "correosdemexico",
79
+ master: "mastercard",
80
+ americanexpress: "amex",
81
+ mercadopagomx: "mercadopago",
82
+ mp: "mercadopago",
83
+ clabe: "spei",
84
+ banktransfer: "spei",
85
+ seveneleven: "7eleven",
86
+ "711": "7eleven",
87
+ circulok: "circlek",
88
+ yza: "farmaciasyza",
89
+ bancomer: "bbva",
90
+ banamex: "citibanamex",
91
+ ley: "casaley"
92
+ };
93
+ var BY_KEY = new Map(LIST.map((b) => [b.key, b]));
94
+ function brandKey(raw) {
95
+ const flat = (raw ?? "").normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/&/g, "and").replace(/[^a-z0-9]/g, "");
96
+ const noCountry = flat.endsWith("mexico") && flat !== "correosdemexico" ? flat.slice(0, -6) : flat;
97
+ return ALIASES[noCountry] ?? (BY_KEY.has(noCountry) ? noCountry : ALIASES[flat] ?? flat);
98
+ }
99
+ function findBrand(raw) {
100
+ return BY_KEY.get(brandKey(raw)) ?? null;
101
+ }
102
+ function brandName(raw) {
103
+ const brand = findBrand(raw);
104
+ if (brand) return brand.name;
105
+ const text = (raw ?? "").trim();
106
+ if (!text) return null;
107
+ if (text !== text.toLowerCase() && text !== text.toUpperCase()) return text;
108
+ return text.toLowerCase().split(/[\s_-]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
109
+ }
110
+ function listBrands(kind) {
111
+ return kind ? LIST.filter((b) => b.kind === kind) : [...LIST];
112
+ }
113
+ function safeLogo(url) {
114
+ if (!url) return null;
115
+ try {
116
+ return new URL(url).protocol === "https:" ? url : null;
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+ function monogram(raw) {
122
+ const words = (brandName(raw) ?? raw).split(/\s+/).filter(Boolean);
123
+ const letters = words.length > 1 ? words.slice(0, 2).map((w) => w[0]) : [(words[0] ?? "?").slice(0, 2)];
124
+ return letters.join("").toUpperCase();
125
+ }
126
+ function BrandMark({ brand, logoUrl, size = 24, title, className }) {
127
+ const height = size;
128
+ const width = Math.round(size * 1.5);
129
+ const a11y = title ? { role: "img", "aria-label": title } : { "aria-hidden": true };
130
+ const logo = safeLogo(logoUrl);
131
+ const found = findBrand(brand);
132
+ const key = found?.key ?? "generic";
133
+ const style = { width, height, flex: "none" };
134
+ if (logo) {
135
+ return /* @__PURE__ */ jsxRuntime.jsx(
136
+ "img",
137
+ {
138
+ src: logo,
139
+ alt: title ?? "",
140
+ width,
141
+ height,
142
+ loading: "lazy",
143
+ decoding: "async",
144
+ className,
145
+ style: { ...style, objectFit: "contain" },
146
+ "data-sf-brand-mark": key,
147
+ ...title ? {} : { "aria-hidden": true }
148
+ }
149
+ );
150
+ }
151
+ const ring = "var(--sf-brand-mark-ring, rgb(127 127 127 / 0.35))";
152
+ if (found?.shape === "mastercard") {
153
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 48 32", width, height, className, style, "data-sf-brand-mark": key, focusable: "false", ...a11y, children: [
154
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "0.5", width: "47", height: "31", rx: "5", fill: found.bg, stroke: ring }),
155
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "19", cy: "16", r: "9", fill: "#EB001B" }),
156
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "29", cy: "16", r: "9", fill: "#F79E1B" }),
157
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M24 8.52a9 9 0 0 1 0 14.96a9 9 0 0 1 0-14.96z", fill: "#FF5F00" })
158
+ ] });
159
+ }
160
+ const text = found ? found.mark ?? found.name : monogram(brand ?? "");
161
+ const bg = found?.bg ?? "var(--sf-brand-mark-bg, #E7E9EE)";
162
+ const fg = found?.fg ?? "var(--sf-brand-mark-fg, #2B2F38)";
163
+ const lines = text.split("\n");
164
+ const longest = Math.max(...lines.map((l) => l.length));
165
+ const fontSize = lines.length > 1 ? longest <= 5 ? 11 : 9.5 : longest <= 2 ? 15 : longest <= 4 ? 12 : 10;
166
+ const fit = (l) => l.length > 5 ? { textLength: 40, lengthAdjust: "spacingAndGlyphs" } : {};
167
+ const italic = found?.key === "visa" || found?.key === "fedex" ? "italic" : void 0;
168
+ const common = {
169
+ textAnchor: "middle",
170
+ fill: fg,
171
+ fontFamily: "system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif",
172
+ fontWeight: 800,
173
+ fontSize,
174
+ fontStyle: italic
175
+ };
176
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 48 32", width, height, className, style, "data-sf-brand-mark": key, focusable: "false", ...a11y, children: [
177
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "0.5", width: "47", height: "31", rx: "5", fill: bg, stroke: ring }),
178
+ lines.length > 1 ? lines.slice(0, 2).map((l, i) => /* @__PURE__ */ jsxRuntime.jsx("text", { x: "24", y: i === 0 ? 15 : 25.5, ...common, ...fit(l), children: l }, i)) : /* @__PURE__ */ jsxRuntime.jsx("text", { x: "24", y: "16", dominantBaseline: "central", letterSpacing: longest <= 4 ? 0.3 : 0, ...common, ...fit(text), children: text })
179
+ ] });
180
+ }
181
+ var StorefrontContext = react.createContext(null);
182
+ function useOptionalStorefront() {
183
+ return react.useContext(StorefrontContext);
184
+ }
185
+
186
+ // src/locale.ts
187
+ function useResolvedLocale(locale) {
188
+ const sf = useOptionalStorefront();
189
+ return locale ?? sf?.locale ?? "es-MX";
190
+ }
191
+
192
+ // src/checkout/delivery.ts
193
+ var ES = {
194
+ etaOne: "Llega en 1 d\xEDa h\xE1bil",
195
+ etaMany: "Llega en {n} d\xEDas h\xE1biles",
196
+ etaRange: "Llega en {min} a {max} d\xEDas h\xE1biles",
197
+ etaUpTo: "Llega en m\xE1ximo {max} d\xEDas h\xE1biles",
198
+ etaFrom: "Llega en {min} d\xEDas h\xE1biles o m\xE1s",
199
+ cheapest: "M\xE1s econ\xF3mico",
200
+ fastest: "M\xE1s r\xE1pido",
201
+ free: "Gratis",
202
+ pickupTitle: "Recoger en {name}",
203
+ quoteToday: "Precios de env\xEDo vigentes hasta las {time}.",
204
+ quoteTomorrow: "Precios de env\xEDo vigentes hasta ma\xF1ana a las {time}.",
205
+ quoteLater: "Precios de env\xEDo vigentes hasta el {date}.",
206
+ quoteSoon: "Los precios de env\xEDo vencen pronto ({time}).",
207
+ partial: "No pudimos consultar todas las paqueter\xEDas. Estas son las opciones disponibles ahora.",
208
+ loading: "Buscando opciones de env\xEDo\u2026",
209
+ requoted: "Las tarifas de env\xEDo cambiaron y ya est\xE1n actualizadas. Revisa tu env\xEDo antes de pagar."
210
+ };
211
+ var EN = {
212
+ etaOne: "Arrives in 1 business day",
213
+ etaMany: "Arrives in {n} business days",
214
+ etaRange: "Arrives in {min} to {max} business days",
215
+ etaUpTo: "Arrives in up to {max} business days",
216
+ etaFrom: "Arrives in {min}+ business days",
217
+ cheapest: "Cheapest",
218
+ fastest: "Fastest",
219
+ free: "Free",
220
+ pickupTitle: "Pick up at {name}",
221
+ quoteToday: "Shipping prices valid until {time}.",
222
+ quoteTomorrow: "Shipping prices valid until tomorrow at {time}.",
223
+ quoteLater: "Shipping prices valid until {date}.",
224
+ quoteSoon: "Shipping prices expire soon ({time}).",
225
+ partial: "We couldn't reach every carrier. These are the options available now.",
226
+ loading: "Looking for delivery options\u2026",
227
+ requoted: "Shipping rates changed and are now up to date. Check your delivery before paying."
228
+ };
229
+ function deliveryMessages(locale, overrides) {
230
+ const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN : ES;
231
+ return overrides ? { ...base, ...overrides } : base;
232
+ }
233
+ var fill = (tpl, vars) => tpl.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? "")).replace(/\.\.$/, ".");
234
+ function rateCarrier(rate) {
235
+ return brandName(rate.carrier);
236
+ }
237
+ function rateService(rate) {
238
+ const title = rate.title.trim();
239
+ const carrier = rateCarrier(rate);
240
+ if (!carrier) return title;
241
+ for (const prefix of [carrier, rate.carrier ?? ""]) {
242
+ if (!prefix) continue;
243
+ if (title.toLowerCase().startsWith(prefix.toLowerCase())) {
244
+ const rest = title.slice(prefix.length).replace(/^[\s·:|-]+/, "");
245
+ if (rest) return rest;
246
+ }
247
+ }
248
+ return title;
249
+ }
250
+ function rateEta(rate, messages = ES) {
251
+ const { eta_days_min: min, eta_days_max: max } = rate;
252
+ if (typeof min === "number" && typeof max === "number") {
253
+ if (min === max) return min === 1 ? messages.etaOne : fill(messages.etaMany, { n: min });
254
+ return fill(messages.etaRange, { min, max });
255
+ }
256
+ if (typeof max === "number") return max === 1 ? messages.etaOne : fill(messages.etaUpTo, { max });
257
+ if (typeof min === "number") return min === 1 ? messages.etaOne : fill(messages.etaFrom, { min });
258
+ return rate.eta ?? null;
259
+ }
260
+ var costOf = (r) => {
261
+ const n = Number(r.cost.amount);
262
+ return Number.isFinite(n) ? n : null;
263
+ };
264
+ var daysOf = (r) => r.eta_days_max ?? r.eta_days_min ?? null;
265
+ function rateBadges(rates) {
266
+ const out = /* @__PURE__ */ new Map();
267
+ if (rates.length < 2) return out;
268
+ const add = (id, b) => out.set(id, [...out.get(id) ?? [], b]);
269
+ const unique = (values) => {
270
+ const known = values.filter((v) => v[1] !== null);
271
+ if (known.length < 2) return null;
272
+ const min = Math.min(...known.map((v) => v[1]));
273
+ const winners = known.filter((v) => v[1] === min);
274
+ return winners.length === 1 ? winners[0][0] : null;
275
+ };
276
+ const currencies = new Set(rates.map((r) => r.cost.currency_code));
277
+ if (currencies.size === 1) {
278
+ const id = unique(rates.map((r) => [r.id, costOf(r)]));
279
+ if (id) add(id, "cheapest");
280
+ }
281
+ const fast = unique(rates.map((r) => [r.id, daysOf(r)]));
282
+ if (fast) add(fast, "fastest");
283
+ return out;
284
+ }
285
+ function quoteDeadline(rates) {
286
+ let best = null;
287
+ for (const r of rates) {
288
+ if (!r.expires_at) continue;
289
+ const d = new Date(r.expires_at);
290
+ if (Number.isNaN(d.getTime())) continue;
291
+ if (!best || d < best) best = d;
292
+ }
293
+ return best;
294
+ }
295
+ function quoteNote(deadline, opts = {}) {
296
+ if (!deadline) return null;
297
+ const now = opts.now ?? /* @__PURE__ */ new Date();
298
+ const left = deadline.getTime() - now.getTime();
299
+ if (left <= 0) return null;
300
+ const m = opts.messages ?? ES;
301
+ const locale = opts.locale ?? "es-MX";
302
+ const tz = opts.timeZone ? { timeZone: opts.timeZone } : {};
303
+ const time = new Intl.DateTimeFormat(locale, { hour: "numeric", minute: "2-digit", ...tz }).format(deadline);
304
+ if (left <= (opts.soonMinutes ?? 15) * 6e4) return { text: fill(m.quoteSoon, { time }), soon: true };
305
+ const day = (d) => new Intl.DateTimeFormat("en-CA", { year: "numeric", month: "2-digit", day: "2-digit", ...tz }).format(d);
306
+ if (day(deadline) === day(now)) return { text: fill(m.quoteToday, { time }), soon: false };
307
+ if (day(deadline) === day(new Date(now.getTime() + 864e5))) return { text: fill(m.quoteTomorrow, { time }), soon: false };
308
+ const date = new Intl.DateTimeFormat(locale, { day: "numeric", month: "short", hour: "numeric", minute: "2-digit", ...tz }).format(deadline);
309
+ return { text: fill(m.quoteLater, { date }), soon: false };
310
+ }
311
+ var QUOTE_CODES = /* @__PURE__ */ new Set(["quote_expired", "rate_expired", "rate_changed", "rate_unavailable", "rate_not_found", "stale_rate", "invalid_rate"]);
312
+ function isQuoteChange(err) {
313
+ if (!err) return false;
314
+ if (err.code && QUOTE_CODES.has(err.code)) return true;
315
+ if (err.status === 409) return true;
316
+ return err.status === 422 && (err.field === "rate_id" || err.field === "delivery" || err.field === "delivery.rate_id" || !err.field);
317
+ }
318
+ function matchRate(previous, rates) {
319
+ if (!previous) return null;
320
+ const norm = (s) => (s ?? "").trim().toLowerCase();
321
+ const sameCarrier = (r) => norm(r.carrier) === norm(previous.carrier);
322
+ if (previous.service_code) {
323
+ const hit = rates.find((r) => sameCarrier(r) && norm(r.service_code) === norm(previous.service_code));
324
+ if (hit) return hit;
325
+ }
326
+ return rates.find((r) => sameCarrier(r) && norm(r.title) === norm(previous.title)) ?? null;
327
+ }
328
+ var SR_ONLY = { position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)", whiteSpace: "nowrap" };
329
+ var useHydrated = () => react.useSyncExternalStore(
330
+ () => () => {
331
+ },
332
+ () => true,
333
+ () => false
334
+ );
335
+ function PickupGlyph({ size = 24 }) {
336
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 48 32", width: Math.round(size * 1.5), height: size, "aria-hidden": "true", focusable: "false", style: { flex: "none" }, "data-sf-brand-mark": "pickup", children: [
337
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "0.5", width: "47", height: "31", rx: "5", fill: "var(--sf-brand-mark-bg, #E7E9EE)", stroke: "var(--sf-brand-mark-ring, rgb(127 127 127 / 0.35))" }),
338
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M15 13.5 17 9h14l2 4.5M15 13.5h18M15 13.5V23h18v-9.5M21 23v-5h6v5", fill: "none", stroke: "var(--sf-brand-mark-fg, #2B2F38)", strokeWidth: "1.8", strokeLinejoin: "round" })
339
+ ] });
340
+ }
341
+ function DeliveryOptions(props) {
342
+ const {
343
+ rates,
344
+ pickup = [],
345
+ name = "delivery_choice",
346
+ rateValue = (r) => `rate:${r.id}`,
347
+ pickupValue = (b) => `pickup:${b.branch_id}`,
348
+ value,
349
+ onValueChange,
350
+ partial = false,
351
+ requoted = false,
352
+ loading = false,
353
+ timeZone,
354
+ marks = true,
355
+ badges: showBadges = true,
356
+ required = true,
357
+ renderAmount,
358
+ classNames: cx = {},
359
+ testId,
360
+ children
361
+ } = props;
362
+ const locale = useResolvedLocale(props.locale);
363
+ const m = react.useMemo(() => deliveryMessages(locale, props.messages), [locale, props.messages]);
364
+ const hydrated = useHydrated();
365
+ const badges = react.useMemo(() => showBadges ? rateBadges(rates) : /* @__PURE__ */ new Map(), [rates, showBadges]);
366
+ const firstValue = rates[0] ? rateValue(rates[0]) : null;
367
+ const defaultValue = props.defaultValue === void 0 ? firstValue : props.defaultValue;
368
+ const amount = (money) => Number(money.amount) === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.free, "data-sf-delivery-free": true, children: m.free }) : renderAmount ? renderAmount(money) : storefront.formatMoney(money, locale);
369
+ const mode = props.quoteNote ?? "always";
370
+ const deadline = mode === "never" ? null : quoteDeadline(rates);
371
+ const note = hydrated && deadline ? quoteNote(deadline, { locale, messages: m, ...timeZone ? { timeZone } : {} }) : null;
372
+ const shownNote = note && (mode === "always" || note.soon) ? note : null;
373
+ const radio = (v) => /* @__PURE__ */ jsxRuntime.jsx(
374
+ "input",
375
+ {
376
+ type: "radio",
377
+ name,
378
+ value: v,
379
+ required,
380
+ className: cx.radio,
381
+ ...value !== void 0 ? { checked: value === v, onChange: () => onValueChange?.(v) } : { defaultChecked: v === defaultValue, ...onValueChange ? { onChange: () => onValueChange(v) } : {} },
382
+ ...testId ? { "data-testid": testId } : {}
383
+ }
384
+ );
385
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.root, "data-sf-delivery": true, "aria-busy": loading || void 0, children: [
386
+ partial ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: cx.partial, "data-sf-delivery-partial": true, children: m.partial }) : null,
387
+ requoted ? /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: cx.partial, "data-sf-delivery-requoted": true, children: m.requoted }) : null,
388
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: SR_ONLY, role: "status", "data-sf-delivery-loading": true, children: m.loading }) : null,
389
+ children,
390
+ 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,
391
+ rates.map((rate) => {
392
+ const carrier = rateCarrier(rate);
393
+ const service = rateService(rate);
394
+ const eta = rateEta(rate, m);
395
+ const own = badges.get(rate.id) ?? [];
396
+ return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cx.option, "data-sf-delivery-option": true, "data-loading": loading || void 0, children: [
397
+ radio(rateValue(rate)),
398
+ marks ? /* @__PURE__ */ jsxRuntime.jsx(BrandMark, { brand: rate.carrier ?? rate.provider ?? rate.title, size: 28, ...cx.mark ? { className: cx.mark } : {} }) : null,
399
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cx.body, "data-sf-delivery-body": true, children: [
400
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.title, "data-sf-delivery-title": true, children: carrier ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
401
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.carrier, "data-sf-delivery-carrier": true, children: carrier }),
402
+ " ",
403
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.service, "data-sf-delivery-service": true, children: service })
404
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.carrier, "data-sf-delivery-carrier": true, children: service }) }),
405
+ eta ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.eta, "data-sf-delivery-eta": true, children: eta }) : null,
406
+ own.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.badges, "data-sf-delivery-badges": true, children: own.map((b) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.badge, "data-sf-delivery-badge": b, children: b === "cheapest" ? m.cheapest : m.fastest }, b)) }) : null
407
+ ] }),
408
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.price, "data-sf-delivery-price": true, children: amount(rate.cost) })
409
+ ] }, rate.id);
410
+ }),
411
+ pickup.map((b) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cx.option, "data-sf-delivery-option": true, "data-sf-delivery-pickup": true, children: [
412
+ radio(pickupValue(b)),
413
+ marks ? /* @__PURE__ */ jsxRuntime.jsx(PickupGlyph, { size: 28 }) : null,
414
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cx.body, "data-sf-delivery-body": true, children: [
415
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.title, "data-sf-delivery-title": true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.carrier, "data-sf-delivery-carrier": true, children: m.pickupTitle.replace("{name}", b.name) }) }),
416
+ b.address || b.city ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.eta, "data-sf-delivery-eta": true, children: [b.address, b.city].filter(Boolean).join(", ") }) : null
417
+ ] }),
418
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.price, "data-sf-delivery-price": true, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx.free, "data-sf-delivery-free": true, children: m.free }) })
419
+ ] }, b.branch_id)),
420
+ 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
421
+ ] });
422
+ }
423
+
424
+ exports.BrandMark = BrandMark;
425
+ exports.DeliveryOptions = DeliveryOptions;
426
+ exports.brandKey = brandKey;
427
+ exports.brandName = brandName;
428
+ exports.deliveryMessages = deliveryMessages;
429
+ exports.findBrand = findBrand;
430
+ exports.isQuoteChange = isQuoteChange;
431
+ exports.listBrands = listBrands;
432
+ exports.matchRate = matchRate;
433
+ exports.quoteDeadline = quoteDeadline;
434
+ exports.quoteNote = quoteNote;
435
+ exports.rateBadges = rateBadges;
436
+ exports.rateCarrier = rateCarrier;
437
+ exports.rateEta = rateEta;
438
+ exports.rateService = rateService;
439
+ //# sourceMappingURL=checkout.cjs.map
440
+ //# sourceMappingURL=checkout.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/checkout/brands.ts","../src/checkout/brand-mark.tsx","../src/context.tsx","../src/locale.ts","../src/checkout/delivery.ts","../src/checkout/delivery-options.tsx"],"names":["jsx","jsxs","createContext","useContext","useSyncExternalStore","useMemo","formatMoney","Fragment"],"mappings":"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","file":"checkout.cjs","sourcesContent":["/**\n * Shared catalog of the brands a checkout names: parcel carriers, card networks, wallets and cash payment points.\n *\n * Keys are the stable identifiers the providers already send (`ShippingRate.carrier` of Skydropx / Envía, the\n * `PaymentPoint.payment_point` or `id` of the payment addon, a `PaymentMethod.key`). Nothing here decides what a shop\n * offers: the server lists the rates and methods; this only gives each one its commercial name and a mark.\n *\n * Marks are typographic badges drawn by `<BrandMark>` (brand color + short wordmark): no third-party logo files are\n * bundled, so there is no licensing question and no extra request. A provider that holds a licensed logo sends it as\n * `logo_url` and it wins over the badge. Colors are close approximations of each brand's public color.\n */\n\nexport type BrandKind = 'carrier' | 'card' | 'wallet' | 'cash' | 'bank'\n\nexport type Brand = {\n key: string\n /** Commercial name, as the brand writes it. */\n name: string\n kind: BrandKind\n /** Badge background. */\n bg: string\n /** Badge text color (AA on `bg`). */\n fg: string\n /** Short wordmark drawn in the badge (`\\n` = two lines). Default: `name`. */\n mark?: string\n /** Special drawings instead of a wordmark. */\n shape?: 'mastercard'\n}\n\nconst B = (key: string, name: string, kind: BrandKind, bg: string, fg: string, mark?: string, shape?: Brand['shape']): Brand => ({\n key,\n name,\n kind,\n bg,\n fg,\n ...(mark ? { mark } : {}),\n ...(shape ? { shape } : {}),\n})\n\nconst LIST: Brand[] = [\n // Parcel carriers (Mexico and global).\n B('fedex', 'FedEx', 'carrier', '#4D148C', '#FFFFFF'),\n B('dhl', 'DHL', 'carrier', '#FFCC00', '#B00410'),\n B('estafeta', 'Estafeta', 'carrier', '#C8102E', '#FFFFFF'),\n B('paquetexpress', 'Paquetexpress', 'carrier', '#0B4EA2', '#FFFFFF', 'Paquet\\nexpress'),\n B('ups', 'UPS', 'carrier', '#351C15', '#FFB500'),\n B('redpack', 'Redpack', 'carrier', '#C8102E', '#FFFFFF'),\n B('99minutos', '99 Minutos', 'carrier', '#00704A', '#FFFFFF', '99'),\n B('jtexpress', 'J&T Express', 'carrier', '#C8102E', '#FFFFFF', 'J&T'),\n B('sendex', 'Sendex', 'carrier', '#003A70', '#FFFFFF'),\n B('ampm', 'AMPM', 'carrier', '#1D1D1B', '#FFFFFF'),\n B('tresguerras', 'Tresguerras', 'carrier', '#005BAC', '#FFFFFF', '3G'),\n B('quiken', 'Quiken', 'carrier', '#1D1D1B', '#FFFFFF'),\n B('imile', 'iMile', 'carrier', '#0057B8', '#FFFFFF'),\n B('carssa', 'Carssa', 'carrier', '#00529B', '#FFFFFF'),\n B('correosdemexico', 'Correos de México', 'carrier', '#7A1E3A', '#FFFFFF', 'Correos\\nMéxico'),\n B('usps', 'USPS', 'carrier', '#333366', '#FFFFFF'),\n B('canadapost', 'Canada Post', 'carrier', '#DA291C', '#FFFFFF', 'CPC'),\n // Card networks.\n B('visa', 'Visa', 'card', '#1A1F71', '#FFFFFF', 'VISA'),\n B('mastercard', 'Mastercard', 'card', '#FFFFFF', '#1D1D1B', 'MC', 'mastercard'),\n B('amex', 'American Express', 'card', '#1F72CD', '#FFFFFF', 'AMEX'),\n B('carnet', 'Carnet', 'card', '#003B71', '#FFFFFF'),\n // Wallets and payment providers.\n B('mercadopago', 'Mercado Pago', 'wallet', '#00B1EA', '#0B1F4E', 'mercado\\npago'),\n B('paypal', 'PayPal', 'wallet', '#003087', '#FFFFFF'),\n B('clip', 'Clip', 'wallet', '#FC4C02', '#1D1D1B'),\n B('applepay', 'Apple Pay', 'wallet', '#000000', '#FFFFFF', 'Pay'),\n B('googlepay', 'Google Pay', 'wallet', '#FFFFFF', '#3C4043', 'G Pay'),\n // Cash points and transfers (Mexico).\n B('oxxo', 'OXXO', 'cash', '#E21E26', '#FFE600'),\n B('spei', 'SPEI', 'bank', '#14365F', '#FFFFFF'),\n B('stp', 'STP', 'bank', '#14365F', '#FFFFFF', 'SPEI'),\n B('7eleven', '7-Eleven', 'cash', '#00704A', '#FFFFFF', '7-11'),\n B('circlek', 'Circle K', 'cash', '#DA291C', '#FFFFFF', 'K'),\n B('soriana', 'Soriana', 'cash', '#C8102E', '#FFFFFF'),\n B('extra', 'Extra', 'cash', '#E35205', '#FFFFFF'),\n B('kiosko', 'Kiosko', 'cash', '#C8102E', '#FFFFFF'),\n B('calimax', 'Calimax', 'cash', '#D52B1E', '#FFFFFF'),\n B('farmaciasyza', 'Farmacias Yza', 'cash', '#0A5A9C', '#FFFFFF', 'Yza'),\n B('chedraui', 'Chedraui', 'cash', '#0047BB', '#FFFFFF'),\n B('casaley', 'Casa Ley', 'cash', '#C8102E', '#FFFFFF', 'Ley'),\n B('telecomm', 'Telecomm', 'cash', '#6F1D46', '#FFFFFF'),\n B('walmart', 'Walmart', 'cash', '#0071CE', '#FFFFFF'),\n B('santander', 'Santander', 'bank', '#C00000', '#FFFFFF'),\n B('bbva', 'BBVA', 'bank', '#004481', '#FFFFFF'),\n B('citibanamex', 'Citibanamex', 'bank', '#004B8D', '#FFFFFF', 'Citi'),\n B('banorte', 'Banorte', 'bank', '#C8102E', '#FFFFFF'),\n]\n\n/** Alternative spellings that providers send for the same brand (already normalized by `brandKey`). */\nconst ALIASES: Record<string, string> = {\n fedexmx: 'fedex',\n fedexexpress: 'fedex',\n dhlexpress: 'dhl',\n dhlmx: 'dhl',\n paquetexpres: 'paquetexpress',\n paqueteexpress: 'paquetexpress',\n jt: 'jtexpress',\n jandtexpress: 'jtexpress',\n noventaynueveminutos: '99minutos',\n correos: 'correosdemexico',\n sepomex: 'correosdemexico',\n master: 'mastercard',\n americanexpress: 'amex',\n mercadopagomx: 'mercadopago',\n mp: 'mercadopago',\n clabe: 'spei',\n banktransfer: 'spei',\n seveneleven: '7eleven',\n '711': '7eleven',\n circulok: 'circlek',\n yza: 'farmaciasyza',\n bancomer: 'bbva',\n banamex: 'citibanamex',\n ley: 'casaley',\n}\n\nconst BY_KEY = new Map(LIST.map((b) => [b.key, b]))\n\n/** `\"FedEx México\"`, `\"fedex_mx\"` and `\"FEDEX\"` all become `fedex`. Lowercase ASCII letters and digits only. */\nexport function brandKey(raw: string | null | undefined): string {\n const flat = (raw ?? '')\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/&/g, 'and')\n .replace(/[^a-z0-9]/g, '')\n const noCountry = flat.endsWith('mexico') && flat !== 'correosdemexico' ? flat.slice(0, -6) : flat\n return ALIASES[noCountry] ?? (BY_KEY.has(noCountry) ? noCountry : ALIASES[flat] ?? flat)\n}\n\n/** Catalog entry for a provider identifier, or `null` when the brand is not in the catalog. */\nexport function findBrand(raw: string | null | undefined): Brand | null {\n return BY_KEY.get(brandKey(raw)) ?? null\n}\n\n/**\n * Commercial name for a provider identifier: the catalog's (`fedex` → \"FedEx\") or, for an unknown one, the identifier\n * in title case (`\"envios_rapidos\"` → \"Envios Rapidos\"). `null` for an empty input.\n */\nexport function brandName(raw: string | null | undefined): string | null {\n const brand = findBrand(raw)\n if (brand) return brand.name\n const text = (raw ?? '').trim()\n if (!text) return null\n // Already cased by the provider (\"Envía Plus\"): keep it.\n if (text !== text.toLowerCase() && text !== text.toUpperCase()) return text\n return text\n .toLowerCase()\n .split(/[\\s_-]+/)\n .filter(Boolean)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ')\n}\n\n/** Every brand of the catalog (for docs, previews and tests). */\nexport function listBrands(kind?: BrandKind): Brand[] {\n return kind ? LIST.filter((b) => b.kind === kind) : [...LIST]\n}\n","import type { CSSProperties } from 'react'\nimport { brandName, findBrand } from './brands.js'\n\nexport type BrandMarkProps = {\n /** Provider identifier (`fedex`, `oxxo`, `mercadopago`, `7eleven`…). Unknown keys get a neutral monogram. */\n brand: string | null | undefined\n /** Licensed logo sent by the provider (`PaymentPoint.logo_url`…). Only `https:`; it wins over the badge. */\n logoUrl?: string | null\n /** Height in px. The badge is 3:2 (width = 1.5 × height). Default 24. */\n size?: number\n /**\n * Accessible name. Omit it when the brand name is already written next to the mark (the usual case): the mark is then\n * decorative (`aria-hidden`).\n */\n title?: string\n className?: string\n}\n\nfunction safeLogo(url: string | null | undefined): string | null {\n if (!url) return null\n try {\n return new URL(url).protocol === 'https:' ? url : null\n } catch {\n return null\n }\n}\n\n/** Letters of a monogram for a brand outside the catalog: \"envios rapidos\" → \"ER\". */\nfunction monogram(raw: string): string {\n const words = (brandName(raw) ?? raw).split(/\\s+/).filter(Boolean)\n const letters = words.length > 1 ? words.slice(0, 2).map((w) => w[0]) : [(words[0] ?? '?').slice(0, 2)]\n return letters.join('').toUpperCase()\n}\n\n/**\n * The mark of a carrier, card network, wallet or cash point: an inline SVG badge in the brand color with its short\n * wordmark (no network request, same size on the server and in the browser, so no layout shift). With `logoUrl` it\n * draws the provider's licensed logo instead, lazily, with fixed dimensions.\n *\n * The badge carries its own background, so it keeps its contrast on light and dark themes; a hairline\n * (`--sf-brand-mark-ring`) separates it from the page.\n */\nexport function BrandMark({ brand, logoUrl, size = 24, title, className }: BrandMarkProps) {\n const height = size\n const width = Math.round(size * 1.5)\n const a11y = title ? { role: 'img' as const, 'aria-label': title } : { 'aria-hidden': true as const }\n const logo = safeLogo(logoUrl)\n const found = findBrand(brand)\n const key = found?.key ?? 'generic'\n const style: CSSProperties = { width, height, flex: 'none' }\n if (logo) {\n return (\n <img\n src={logo}\n alt={title ?? ''}\n width={width}\n height={height}\n loading=\"lazy\"\n decoding=\"async\"\n className={className}\n style={{ ...style, objectFit: 'contain' }}\n data-sf-brand-mark={key}\n {...(title ? {} : { 'aria-hidden': true })}\n />\n )\n }\n const ring = 'var(--sf-brand-mark-ring, rgb(127 127 127 / 0.35))'\n if (found?.shape === 'mastercard') {\n return (\n <svg viewBox=\"0 0 48 32\" width={width} height={height} className={className} style={style} data-sf-brand-mark={key} focusable=\"false\" {...a11y}>\n <rect x=\"0.5\" y=\"0.5\" width=\"47\" height=\"31\" rx=\"5\" fill={found.bg} stroke={ring} />\n <circle cx=\"19\" cy=\"16\" r=\"9\" fill=\"#EB001B\" />\n <circle cx=\"29\" cy=\"16\" r=\"9\" fill=\"#F79E1B\" />\n <path d=\"M24 8.52a9 9 0 0 1 0 14.96a9 9 0 0 1 0-14.96z\" fill=\"#FF5F00\" />\n </svg>\n )\n }\n const text = found ? (found.mark ?? found.name) : monogram(brand ?? '')\n const bg = found?.bg ?? 'var(--sf-brand-mark-bg, #E7E9EE)'\n const fg = found?.fg ?? 'var(--sf-brand-mark-fg, #2B2F38)'\n const lines = text.split('\\n')\n const longest = Math.max(...lines.map((l) => l.length))\n // Short marks grow; long ones are squeezed into the badge (textLength) so every badge has the same box.\n const fontSize = lines.length > 1 ? (longest <= 5 ? 11 : 9.5) : longest <= 2 ? 15 : longest <= 4 ? 12 : 10\n const fit = (l: string) => (l.length > 5 ? { textLength: 40, lengthAdjust: 'spacingAndGlyphs' as const } : {})\n const italic = found?.key === 'visa' || found?.key === 'fedex' ? 'italic' : undefined\n const common = {\n textAnchor: 'middle' as const,\n fill: fg,\n fontFamily: \"system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif\",\n fontWeight: 800,\n fontSize,\n fontStyle: italic,\n }\n return (\n <svg viewBox=\"0 0 48 32\" width={width} height={height} className={className} style={style} data-sf-brand-mark={key} focusable=\"false\" {...a11y}>\n <rect x=\"0.5\" y=\"0.5\" width=\"47\" height=\"31\" rx=\"5\" fill={bg} stroke={ring} />\n {lines.length > 1 ? (\n lines.slice(0, 2).map((l, i) => (\n <text key={i} x=\"24\" y={i === 0 ? 15 : 25.5} {...common} {...fit(l)}>\n {l}\n </text>\n ))\n ) : (\n <text x=\"24\" y=\"16\" dominantBaseline=\"central\" letterSpacing={longest <= 4 ? 0.3 : 0} {...common} {...fit(text)}>\n {text}\n </text>\n )}\n </svg>\n )\n}\n","import { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport { createStorefrontClient, type Shop, type StorefrontClient, type StorefrontClientOptions } from '@asteby/storefront'\n\nexport type StorefrontContextValue = {\n /** Client for browser-side calls (use a public `pk_` token). */\n client: StorefrontClient | null\n shop: Shop | null\n /** BCP 47 locale used for formatting (defaults to `shop.locale`, then `es-MX`). */\n locale: string\n /** ISO 4217 currency (defaults to `shop.currency_code`, then `MXN`). */\n currency: string\n}\n\nconst StorefrontContext = createContext<StorefrontContextValue | null>(null)\n\nexport type StorefrontProviderProps = {\n /** A ready client. Takes precedence over `config`. */\n client?: StorefrontClient\n /** Options to create the browser client (use a `pk_` token). */\n config?: StorefrontClientOptions\n /** Shop info loaded on the server (root loader). */\n shop?: Shop | null\n locale?: string\n currency?: string\n children?: ReactNode\n}\n\n/**\n * Makes the storefront client, shop, locale and currency available to the\n * tree. SSR-safe: creating the client does not touch `window`.\n */\nexport function StorefrontProvider({ client, config, shop = null, locale, currency, children }: StorefrontProviderProps) {\n const configKey = config ? `${config.baseUrl}|${config.token}|${config.locale ?? ''}|${config.customerToken ?? ''}` : ''\n const resolvedClient = useMemo(\n () => client ?? (config ? createStorefrontClient(config) : null),\n [client, configKey],\n )\n const value = useMemo<StorefrontContextValue>(\n () => ({\n client: resolvedClient,\n shop,\n locale: locale ?? config?.locale ?? shop?.locale ?? 'es-MX',\n currency: currency ?? shop?.currency_code ?? 'MXN',\n }),\n [resolvedClient, shop, locale, currency, config?.locale],\n )\n return <StorefrontContext.Provider value={value}>{children}</StorefrontContext.Provider>\n}\n\n/** Storefront context. Throws outside `<StorefrontProvider>`. */\nexport function useStorefront(): StorefrontContextValue {\n const ctx = useContext(StorefrontContext)\n if (!ctx) throw new Error('useStorefront must be used inside <StorefrontProvider>')\n return ctx\n}\n\n/** Storefront context or `null` outside a provider (for components that work standalone). */\nexport function useOptionalStorefront(): StorefrontContextValue | null {\n return useContext(StorefrontContext)\n}\n\n/** The client from context; throws when the provider has none. */\nexport function useStorefrontClient(): StorefrontClient {\n const { client } = useStorefront()\n if (!client) throw new Error('<StorefrontProvider> needs a `client` or `config` for browser-side calls')\n return client\n}\n","import { useOptionalStorefront } from './context.js'\n\n/** Locale of a component: its own prop, else the `StorefrontProvider`'s, else `es-MX`. */\nexport function useResolvedLocale(locale?: string | null): string {\n const sf = useOptionalStorefront()\n return locale ?? sf?.locale ?? 'es-MX'\n}\n","/**\n * Pure helpers for the \"Delivery\" step: how to name a carrier rate, its arrival time, which rate is the cheapest or the\n * fastest, and one human note for the quote deadline. No amounts are computed: `cost` is shown as the server sends it;\n * comparing two costs to flag the cheapest is the only arithmetic.\n */\nimport type { ShippingRate } from '@asteby/storefront'\nimport { brandName } from './brands.js'\n\nexport type DeliveryMessages = {\n /** `{n}` = business days. */\n etaOne: string\n etaMany: string\n /** `{min}` / `{max}` = business days. */\n etaRange: string\n etaUpTo: string\n etaFrom: string\n cheapest: string\n fastest: string\n free: string\n pickupTitle: string\n /** Quote deadline, `{time}` = local time. */\n quoteToday: string\n quoteTomorrow: string\n /** `{date}` = short date + time. */\n quoteLater: string\n quoteSoon: string\n partial: string\n loading: string\n /** The quote expired or changed and the rates were reloaded. */\n requoted: string\n}\n\nconst ES: DeliveryMessages = {\n etaOne: 'Llega en 1 día hábil',\n etaMany: 'Llega en {n} días hábiles',\n etaRange: 'Llega en {min} a {max} días hábiles',\n etaUpTo: 'Llega en máximo {max} días hábiles',\n etaFrom: 'Llega en {min} días hábiles o más',\n cheapest: 'Más económico',\n fastest: 'Más rápido',\n free: 'Gratis',\n pickupTitle: 'Recoger en {name}',\n quoteToday: 'Precios de envío vigentes hasta las {time}.',\n quoteTomorrow: 'Precios de envío vigentes hasta mañana a las {time}.',\n quoteLater: 'Precios de envío vigentes hasta el {date}.',\n quoteSoon: 'Los precios de envío vencen pronto ({time}).',\n partial: 'No pudimos consultar todas las paqueterías. Estas son las opciones disponibles ahora.',\n loading: 'Buscando opciones de envío…',\n requoted: 'Las tarifas de envío cambiaron y ya están actualizadas. Revisa tu envío antes de pagar.',\n}\n\nconst EN: DeliveryMessages = {\n etaOne: 'Arrives in 1 business day',\n etaMany: 'Arrives in {n} business days',\n etaRange: 'Arrives in {min} to {max} business days',\n etaUpTo: 'Arrives in up to {max} business days',\n etaFrom: 'Arrives in {min}+ business days',\n cheapest: 'Cheapest',\n fastest: 'Fastest',\n free: 'Free',\n pickupTitle: 'Pick up at {name}',\n quoteToday: 'Shipping prices valid until {time}.',\n quoteTomorrow: 'Shipping prices valid until tomorrow at {time}.',\n quoteLater: 'Shipping prices valid until {date}.',\n quoteSoon: 'Shipping prices expire soon ({time}).',\n partial: \"We couldn't reach every carrier. These are the options available now.\",\n loading: 'Looking for delivery options…',\n requoted: 'Shipping rates changed and are now up to date. Check your delivery before paying.',\n}\n\n/** Messages for a locale (`es*` default, `en*`), with optional overrides. */\nexport function deliveryMessages(locale?: string | null, overrides?: Partial<DeliveryMessages> | null): DeliveryMessages {\n const base = (locale ?? 'es-MX').toLowerCase().startsWith('en') ? EN : ES\n return overrides ? { ...base, ...overrides } : base\n}\n\n// A value that already ends in a period (\"9:39 p.m.\") does not get a second one from the template.\nconst fill = (tpl: string, vars: Record<string, string | number>) => tpl.replace(/\\{(\\w+)\\}/g, (_, k: string) => String(vars[k] ?? '')).replace(/\\.\\.$/, '.')\n\n/** Commercial carrier name of a rate (`fedex` → \"FedEx\"); `null` without carrier. */\nexport function rateCarrier(rate: Pick<ShippingRate, 'carrier'>): string | null {\n return brandName(rate.carrier)\n}\n\n/**\n * Service name without the carrier repeated: \"FedEx Express Saver\" with carrier `fedex` → \"Express Saver\". Falls back\n * to the title when stripping would leave nothing.\n */\nexport function rateService(rate: Pick<ShippingRate, 'title' | 'carrier'>): string {\n const title = rate.title.trim()\n const carrier = rateCarrier(rate)\n if (!carrier) return title\n for (const prefix of [carrier, rate.carrier ?? '']) {\n if (!prefix) continue\n if (title.toLowerCase().startsWith(prefix.toLowerCase())) {\n const rest = title.slice(prefix.length).replace(/^[\\s·:|-]+/, '')\n if (rest) return rest\n }\n }\n return title\n}\n\n/** Arrival time of a rate: business days from the provider, else the server `eta` text as is. */\nexport function rateEta(\n rate: Pick<ShippingRate, 'eta' | 'eta_days_min' | 'eta_days_max'>,\n messages: DeliveryMessages = ES,\n): string | null {\n const { eta_days_min: min, eta_days_max: max } = rate\n if (typeof min === 'number' && typeof max === 'number') {\n if (min === max) return min === 1 ? messages.etaOne : fill(messages.etaMany, { n: min })\n return fill(messages.etaRange, { min, max })\n }\n if (typeof max === 'number') return max === 1 ? messages.etaOne : fill(messages.etaUpTo, { max })\n if (typeof min === 'number') return min === 1 ? messages.etaOne : fill(messages.etaFrom, { min })\n return rate.eta ?? null\n}\n\nexport type RateBadge = 'cheapest' | 'fastest'\n\nconst costOf = (r: ShippingRate) => {\n const n = Number(r.cost.amount)\n return Number.isFinite(n) ? n : null\n}\nconst daysOf = (r: ShippingRate) => r.eta_days_max ?? r.eta_days_min ?? null\n\n/**\n * Badges per rate id. Only with two or more rates, only when one rate is strictly the cheapest (same currency) or\n * strictly the fastest: a tie gets no badge, so the badge always tells the buyer something.\n */\nexport function rateBadges(rates: readonly ShippingRate[]): Map<string, RateBadge[]> {\n const out = new Map<string, RateBadge[]>()\n if (rates.length < 2) return out\n const add = (id: string, b: RateBadge) => out.set(id, [...(out.get(id) ?? []), b])\n const unique = (values: Array<[string, number | null]>) => {\n const known = values.filter((v): v is [string, number] => v[1] !== null)\n if (known.length < 2) return null\n const min = Math.min(...known.map((v) => v[1]))\n const winners = known.filter((v) => v[1] === min)\n return winners.length === 1 ? winners[0]![0] : null\n }\n const currencies = new Set(rates.map((r) => r.cost.currency_code))\n if (currencies.size === 1) {\n const id = unique(rates.map((r) => [r.id, costOf(r)]))\n if (id) add(id, 'cheapest')\n }\n const fast = unique(rates.map((r) => [r.id, daysOf(r)]))\n if (fast) add(fast, 'fastest')\n return out\n}\n\n/** Earliest `expires_at` of the rates (the deadline of the whole list), or `null`. */\nexport function quoteDeadline(rates: readonly Pick<ShippingRate, 'expires_at'>[]): Date | null {\n let best: Date | null = null\n for (const r of rates) {\n if (!r.expires_at) continue\n const d = new Date(r.expires_at)\n if (Number.isNaN(d.getTime())) continue\n if (!best || d < best) best = d\n }\n return best\n}\n\nexport type QuoteNote = { text: string; soon: boolean }\n\n/**\n * One human note for the quote deadline, in the buyer's time zone (or `timeZone`): \"valid until 9:39 p.m.\", \"until\n * tomorrow at…\", \"until Oct 24, …\", or \"expire soon\" within `soonMinutes` (default 15). `null` when already past.\n */\nexport function quoteNote(\n deadline: Date | null,\n opts: { locale?: string; now?: Date; timeZone?: string; soonMinutes?: number; messages?: DeliveryMessages } = {},\n): QuoteNote | null {\n if (!deadline) return null\n const now = opts.now ?? new Date()\n const left = deadline.getTime() - now.getTime()\n if (left <= 0) return null\n const m = opts.messages ?? ES\n const locale = opts.locale ?? 'es-MX'\n const tz = opts.timeZone ? { timeZone: opts.timeZone } : {}\n const time = new Intl.DateTimeFormat(locale, { hour: 'numeric', minute: '2-digit', ...tz }).format(deadline)\n if (left <= (opts.soonMinutes ?? 15) * 60_000) return { text: fill(m.quoteSoon, { time }), soon: true }\n const day = (d: Date) => new Intl.DateTimeFormat('en-CA', { year: 'numeric', month: '2-digit', day: '2-digit', ...tz }).format(d)\n if (day(deadline) === day(now)) return { text: fill(m.quoteToday, { time }), soon: false }\n if (day(deadline) === day(new Date(now.getTime() + 86_400_000))) return { text: fill(m.quoteTomorrow, { time }), soon: false }\n const date = new Intl.DateTimeFormat(locale, { day: 'numeric', month: 'short', hour: 'numeric', minute: '2-digit', ...tz }).format(deadline)\n return { text: fill(m.quoteLater, { date }), soon: false }\n}\n\n/** Error codes a server uses (or will use) when the chosen rate is no longer quotable. */\nconst QUOTE_CODES = new Set(['quote_expired', 'rate_expired', 'rate_changed', 'rate_unavailable', 'rate_not_found', 'stale_rate', 'invalid_rate'])\n\n/**\n * `true` when saving a shipping rate failed because the quote expired or the rates changed, so the shop should reload\n * the rates (and keep the address) instead of showing a generic failure. Recognizes the explicit codes\n * (`quote_expired`, `rate_expired`…, any status), a `409`, and the generic `422` on the rate field that older servers\n * answer when the provider re-quoted with new ids. 5xx and other 4xx stay real failures.\n */\nexport function isQuoteChange(err: { status?: number; code?: string | null; field?: string | null } | null | undefined): boolean {\n if (!err) return false\n if (err.code && QUOTE_CODES.has(err.code)) return true\n if (err.status === 409) return true\n return err.status === 422 && (err.field === 'rate_id' || err.field === 'delivery' || err.field === 'delivery.rate_id' || !err.field)\n}\n\n/**\n * The rate of a fresh quote that matches the one the buyer had chosen (same carrier and service), so a re-quote keeps\n * the choice even though the provider issued new ids. `null` when that service is no longer offered.\n */\nexport function matchRate<R extends Pick<ShippingRate, 'id' | 'carrier' | 'service_code' | 'title'>>(previous: Pick<ShippingRate, 'carrier' | 'service_code' | 'title'> | null | undefined, rates: readonly R[]): R | null {\n if (!previous) return null\n const norm = (s: string | null | undefined) => (s ?? '').trim().toLowerCase()\n const sameCarrier = (r: R) => norm(r.carrier) === norm(previous.carrier)\n if (previous.service_code) {\n const hit = rates.find((r) => sameCarrier(r) && norm(r.service_code) === norm(previous.service_code))\n if (hit) return hit\n }\n return rates.find((r) => sameCarrier(r) && norm(r.title) === norm(previous.title)) ?? null\n}\n","import { useMemo, useSyncExternalStore, type CSSProperties, type ReactNode } from 'react'\nimport { formatMoney, type Money, type PickupOption, type ShippingRate } from '@asteby/storefront'\nimport { useResolvedLocale } from '../locale.js'\nimport { BrandMark } from './brand-mark.js'\nimport {\n deliveryMessages,\n quoteDeadline,\n quoteNote,\n rateBadges,\n rateCarrier,\n rateEta,\n rateService,\n type DeliveryMessages,\n type RateBadge,\n} from './delivery.js'\n\nexport type DeliveryOptionsClassNames = Partial<\n Record<\n | 'root'\n | 'option'\n | 'radio'\n | 'mark'\n | 'body'\n | 'title'\n | 'carrier'\n | 'service'\n | 'eta'\n | 'badges'\n | 'badge'\n | 'price'\n | 'free'\n | 'note'\n | 'partial'\n | 'skeleton',\n string\n >\n>\n\nexport type DeliveryOptionsProps = {\n rates: readonly ShippingRate[]\n pickup?: readonly PickupOption[]\n /** Radio group name. Default `delivery_choice`. */\n name?: string\n /** Form value of a rate. Default `rate:<id>`. */\n rateValue?: (rate: ShippingRate) => string\n /** Form value of a pickup branch. Default `pickup:<branch_id>`. */\n pickupValue?: (branch: PickupOption) => string\n /** Uncontrolled preselection. Default: the first rate. `null`: nothing preselected. */\n defaultValue?: string | null\n /** Controlled value (use with `onValueChange`). */\n value?: string\n onValueChange?: (value: string) => void\n /** Some provider did not answer (`DeliveryOptions.partial`): one neutral note above the list. */\n partial?: boolean\n /** The previous quote expired or changed and these rates are fresh: one status note above the list. */\n requoted?: boolean\n /** Rates are being quoted again: skeleton rows (no rates yet) or the current rows dimmed, `aria-busy`. */\n loading?: boolean\n /** Quote deadline note: `always` (default), only when it is `soon`, or `never`. */\n quoteNote?: 'always' | 'soon' | 'never'\n /** Time zone of the note. Default: the buyer's browser. */\n timeZone?: string\n /** Show the carrier marks. Default true. */\n marks?: boolean\n /** Cheapest / fastest badges. Default true. */\n badges?: boolean\n required?: boolean\n locale?: string\n messages?: Partial<DeliveryMessages>\n renderAmount?: (amount: Money) => ReactNode\n classNames?: DeliveryOptionsClassNames\n /** `data-testid` of every radio. */\n testId?: string\n /** Rows the shop renders before the rates (e.g. \"home delivery, rates after the address\"). */\n children?: ReactNode\n}\n\nconst SR_ONLY: CSSProperties = { position: 'absolute', width: 1, height: 1, overflow: 'hidden', clip: 'rect(0 0 0 0)', whiteSpace: 'nowrap' }\n\nconst useHydrated = () =>\n useSyncExternalStore(\n () => () => {},\n () => true,\n () => false,\n )\n\nfunction PickupGlyph({ size = 24 }: { size?: number }) {\n return (\n <svg viewBox=\"0 0 48 32\" width={Math.round(size * 1.5)} height={size} aria-hidden=\"true\" focusable=\"false\" style={{ flex: 'none' }} data-sf-brand-mark=\"pickup\">\n <rect x=\"0.5\" y=\"0.5\" width=\"47\" height=\"31\" rx=\"5\" fill=\"var(--sf-brand-mark-bg, #E7E9EE)\" stroke=\"var(--sf-brand-mark-ring, rgb(127 127 127 / 0.35))\" />\n <path d=\"M15 13.5 17 9h14l2 4.5M15 13.5h18M15 13.5V23h18v-9.5M21 23v-5h6v5\" fill=\"none\" stroke=\"var(--sf-brand-mark-fg, #2B2F38)\" strokeWidth=\"1.8\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\n/**\n * The rates and pickup branches of \"Delivery\" as native radios: carrier mark and commercial name, readable service,\n * arrival time, cheapest / fastest badges, price as the server sends it, and ONE note for the quote deadline in the\n * buyer's time zone. Works without JavaScript (plain radios in the page form); the note appears after hydration in a\n * reserved line, so it never shifts the layout.\n *\n * Wrap it in the shop's own `<fieldset><legend>`. Style it with `classNames` and/or the default sheet\n * `@asteby/storefront-react/checkout.css`.\n */\nexport function DeliveryOptions(props: DeliveryOptionsProps) {\n const {\n rates,\n pickup = [],\n name = 'delivery_choice',\n rateValue = (r) => `rate:${r.id}`,\n pickupValue = (b) => `pickup:${b.branch_id}`,\n value,\n onValueChange,\n partial = false,\n requoted = false,\n loading = false,\n timeZone,\n marks = true,\n badges: showBadges = true,\n required = true,\n renderAmount,\n classNames: cx = {},\n testId,\n children,\n } = props\n const locale = useResolvedLocale(props.locale)\n const m = useMemo(() => deliveryMessages(locale, props.messages), [locale, props.messages])\n const hydrated = useHydrated()\n const badges = useMemo(() => (showBadges ? rateBadges(rates) : new Map<string, RateBadge[]>()), [rates, showBadges])\n const firstValue = rates[0] ? rateValue(rates[0]) : null\n const defaultValue = props.defaultValue === undefined ? firstValue : props.defaultValue\n const amount = (money: Money) => (Number(money.amount) === 0 ? <span className={cx.free} data-sf-delivery-free>{m.free}</span> : renderAmount ? renderAmount(money) : formatMoney(money, locale))\n const mode = props.quoteNote ?? 'always'\n const deadline = mode === 'never' ? null : quoteDeadline(rates)\n const note = hydrated && deadline ? quoteNote(deadline, { locale, messages: m, ...(timeZone ? { timeZone } : {}) }) : null\n const shownNote = note && (mode === 'always' || note.soon) ? note : null\n\n const radio = (v: string) => (\n <input\n type=\"radio\"\n name={name}\n value={v}\n required={required}\n className={cx.radio}\n {...(value !== undefined ? { checked: value === v, onChange: () => onValueChange?.(v) } : { defaultChecked: v === defaultValue, ...(onValueChange ? { onChange: () => onValueChange(v) } : {}) })}\n {...(testId ? { 'data-testid': testId } : {})}\n />\n )\n\n return (\n <div className={cx.root} data-sf-delivery aria-busy={loading || undefined}>\n {partial ? (\n <p role=\"status\" className={cx.partial} data-sf-delivery-partial>\n {m.partial}\n </p>\n ) : null}\n {requoted ? (\n <p role=\"status\" className={cx.partial} data-sf-delivery-requoted>\n {m.requoted}\n </p>\n ) : null}\n {loading ? (\n <span style={SR_ONLY} role=\"status\" data-sf-delivery-loading>\n {m.loading}\n </span>\n ) : null}\n {children}\n {loading && rates.length === 0\n ? [0, 1, 2].map((i) => <div key={i} className={cx.skeleton} data-sf-delivery-skeleton aria-hidden=\"true\" />)\n : null}\n {rates.map((rate) => {\n const carrier = rateCarrier(rate)\n const service = rateService(rate)\n const eta = rateEta(rate, m)\n const own = badges.get(rate.id) ?? []\n return (\n <label key={rate.id} className={cx.option} data-sf-delivery-option data-loading={loading || undefined}>\n {radio(rateValue(rate))}\n {marks ? <BrandMark brand={rate.carrier ?? rate.provider ?? rate.title} size={28} {...(cx.mark ? { className: cx.mark } : {})} /> : null}\n <span className={cx.body} data-sf-delivery-body>\n <span className={cx.title} data-sf-delivery-title>\n {carrier ? (\n <>\n <span className={cx.carrier} data-sf-delivery-carrier>\n {carrier}\n </span>{' '}\n <span className={cx.service} data-sf-delivery-service>\n {service}\n </span>\n </>\n ) : (\n <span className={cx.carrier} data-sf-delivery-carrier>\n {service}\n </span>\n )}\n </span>\n {eta ? (\n <span className={cx.eta} data-sf-delivery-eta>\n {eta}\n </span>\n ) : null}\n {own.length ? (\n <span className={cx.badges} data-sf-delivery-badges>\n {own.map((b) => (\n <span key={b} className={cx.badge} data-sf-delivery-badge={b}>\n {b === 'cheapest' ? m.cheapest : m.fastest}\n </span>\n ))}\n </span>\n ) : null}\n </span>\n <span className={cx.price} data-sf-delivery-price>\n {amount(rate.cost)}\n </span>\n </label>\n )\n })}\n {pickup.map((b) => (\n <label key={b.branch_id} className={cx.option} data-sf-delivery-option data-sf-delivery-pickup>\n {radio(pickupValue(b))}\n {marks ? <PickupGlyph size={28} /> : null}\n <span className={cx.body} data-sf-delivery-body>\n <span className={cx.title} data-sf-delivery-title>\n <span className={cx.carrier} data-sf-delivery-carrier>\n {m.pickupTitle.replace('{name}', b.name)}\n </span>\n </span>\n {b.address || b.city ? (\n <span className={cx.eta} data-sf-delivery-eta>\n {[b.address, b.city].filter(Boolean).join(', ')}\n </span>\n ) : null}\n </span>\n <span className={cx.price} data-sf-delivery-price>\n <span className={cx.free} data-sf-delivery-free>\n {m.free}\n </span>\n </span>\n </label>\n ))}\n {deadline ? (\n <p className={cx.note} data-sf-delivery-note data-soon={shownNote?.soon || undefined} aria-live=\"polite\">\n {shownNote?.text ?? ''}\n </p>\n ) : null}\n </div>\n )\n}\n"]}