@asteby/storefront-react 0.20.0 → 0.22.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/dist/account.cjs +272 -2
- package/dist/account.cjs.map +1 -1
- package/dist/account.css +159 -0
- package/dist/account.d.cts +35 -3
- package/dist/account.d.ts +35 -3
- package/dist/account.js +70 -1
- package/dist/account.js.map +1 -1
- package/dist/cart.cjs +125 -2
- package/dist/cart.cjs.map +1 -1
- package/dist/cart.css +145 -2
- package/dist/cart.js +4 -2
- package/dist/cart.js.map +1 -1
- package/dist/checkout.cjs +203 -7
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.css +142 -0
- package/dist/checkout.d.cts +12 -3
- package/dist/checkout.d.ts +12 -3
- package/dist/checkout.js +82 -7
- package/dist/checkout.js.map +1 -1
- package/dist/chunk-VHEY5AU3.js +152 -0
- package/dist/chunk-VHEY5AU3.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/product-preview-DRtLWGLS.d.cts +85 -0
- package/dist/product-preview-DaICr4f2.d.ts +85 -0
- package/dist/ui.cjs +202 -0
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.css +142 -0
- package/dist/ui.d.cts +3 -0
- package/dist/ui.d.ts +3 -0
- package/dist/ui.js +3 -1
- package/dist/ui.js.map +1 -1
- package/package.json +2 -2
package/dist/checkout.css
CHANGED
|
@@ -328,3 +328,145 @@
|
|
|
328
328
|
zoom: 0.78;
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
|
+
|
|
332
|
+
/*
|
|
333
|
+
* <ProductThumb>, <ProductPreview>, <ProductThumbStack>: la foto del producto y la línea de producto de la tienda.
|
|
334
|
+
* CSS plano sobre los tokens de la tienda (--foreground, --background, --border, --muted-foreground, --radius); en tema
|
|
335
|
+
* oscuro la superficie y el brillo salen de color-mix, sin colores escritos aquí. Va incluido en cart.css, checkout.css,
|
|
336
|
+
* account.css y ui.css (misma regla, un solo origen: src/ui/product-preview.css).
|
|
337
|
+
*/
|
|
338
|
+
[data-sf-thumb] {
|
|
339
|
+
--_surface: color-mix(in srgb, var(--foreground, #111) 5%, var(--background, #fff));
|
|
340
|
+
position: relative;
|
|
341
|
+
display: inline-block;
|
|
342
|
+
flex: none;
|
|
343
|
+
box-sizing: border-box;
|
|
344
|
+
width: var(--sf-preview-size, 3.5rem);
|
|
345
|
+
aspect-ratio: var(--sf-preview-ratio, 1 / 1);
|
|
346
|
+
overflow: hidden;
|
|
347
|
+
border-radius: calc(var(--radius, 0.5rem) * 1.25);
|
|
348
|
+
background: var(--_surface);
|
|
349
|
+
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--foreground, #111) 9%, transparent);
|
|
350
|
+
vertical-align: middle;
|
|
351
|
+
}
|
|
352
|
+
:root[data-theme="dark"] [data-sf-thumb] { --_surface: color-mix(in srgb, var(--foreground, #fff) 9%, var(--background, #111)); }
|
|
353
|
+
[data-sf-thumb] > img {
|
|
354
|
+
display: block;
|
|
355
|
+
width: 100%;
|
|
356
|
+
height: 100%;
|
|
357
|
+
box-sizing: border-box;
|
|
358
|
+
object-fit: contain;
|
|
359
|
+
padding: 6%;
|
|
360
|
+
transition: transform 220ms cubic-bezier(0.2, 0.7, 0.2, 1), opacity 180ms;
|
|
361
|
+
}
|
|
362
|
+
[data-sf-thumb][data-fit="cover"] > img { object-fit: cover; padding: 0; }
|
|
363
|
+
/* Fotos sobre fondo blanco: se funden con la superficie en tema claro (no hay caja blanca dentro del marco). */
|
|
364
|
+
[data-sf-thumb][data-fit="contain"] > img { mix-blend-mode: multiply; }
|
|
365
|
+
:root[data-theme="dark"] [data-sf-thumb] > img { mix-blend-mode: normal; }
|
|
366
|
+
[data-sf-thumb][data-state="loading"]::before {
|
|
367
|
+
content: "";
|
|
368
|
+
position: absolute;
|
|
369
|
+
inset: 0;
|
|
370
|
+
background: linear-gradient(100deg, transparent 20%, color-mix(in srgb, var(--foreground, #111) 8%, transparent) 50%, transparent 80%);
|
|
371
|
+
background-size: 200% 100%;
|
|
372
|
+
animation: sf-thumb-shimmer 1.4s linear infinite;
|
|
373
|
+
pointer-events: none;
|
|
374
|
+
}
|
|
375
|
+
@keyframes sf-thumb-shimmer { from { background-position: 150% 0; } to { background-position: -50% 0; } }
|
|
376
|
+
[data-sf-thumb][data-zoom]:hover > img { transform: scale(1.07); }
|
|
377
|
+
@media (prefers-reduced-motion: reduce) {
|
|
378
|
+
[data-sf-thumb][data-state="loading"]::before { animation: none; }
|
|
379
|
+
[data-sf-thumb] > img { transition: none; }
|
|
380
|
+
[data-sf-thumb][data-zoom]:hover > img { transform: none; }
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
[data-sf-thumb-fallback] {
|
|
384
|
+
position: absolute;
|
|
385
|
+
inset: 0;
|
|
386
|
+
display: grid;
|
|
387
|
+
place-items: center;
|
|
388
|
+
color: color-mix(in srgb, var(--foreground, #111) 42%, transparent);
|
|
389
|
+
background: linear-gradient(145deg, color-mix(in srgb, var(--foreground, #111) 3%, transparent), color-mix(in srgb, var(--foreground, #111) 9%, transparent));
|
|
390
|
+
}
|
|
391
|
+
[data-sf-thumb-initial] {
|
|
392
|
+
font-size: calc(var(--sf-preview-size, 3.5rem) * 0.36);
|
|
393
|
+
font-weight: 600;
|
|
394
|
+
letter-spacing: 0.02em;
|
|
395
|
+
line-height: 1;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
[data-sf-thumb-qty] {
|
|
399
|
+
position: absolute;
|
|
400
|
+
top: 0.2rem;
|
|
401
|
+
right: 0.2rem;
|
|
402
|
+
min-width: 1.25rem;
|
|
403
|
+
height: 1.25rem;
|
|
404
|
+
padding: 0 0.3rem;
|
|
405
|
+
box-sizing: border-box;
|
|
406
|
+
display: inline-grid;
|
|
407
|
+
place-items: center;
|
|
408
|
+
border-radius: 999px;
|
|
409
|
+
font-size: 0.7rem;
|
|
410
|
+
font-weight: 700;
|
|
411
|
+
font-variant-numeric: tabular-nums;
|
|
412
|
+
background: var(--sf-summary-qty-bg, color-mix(in srgb, var(--foreground, #111) 78%, transparent));
|
|
413
|
+
color: var(--sf-summary-qty-fg, var(--background, #fff));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/* Línea de producto: foto | texto | importe. */
|
|
417
|
+
[data-sf-preview] {
|
|
418
|
+
display: flex;
|
|
419
|
+
align-items: center;
|
|
420
|
+
gap: 0.875rem;
|
|
421
|
+
min-width: 0;
|
|
422
|
+
}
|
|
423
|
+
[data-sf-preview][data-missing] [data-sf-preview-name] { font-style: italic; color: var(--muted-foreground, color-mix(in srgb, currentColor 60%, transparent)); }
|
|
424
|
+
[data-sf-preview-media] { flex: none; display: inline-flex; }
|
|
425
|
+
[data-sf-preview-body] { display: grid; flex: 1 1 auto; gap: 0.125rem; min-width: 0; }
|
|
426
|
+
[data-sf-preview-name] {
|
|
427
|
+
display: -webkit-box;
|
|
428
|
+
-webkit-line-clamp: 2;
|
|
429
|
+
-webkit-box-orient: vertical;
|
|
430
|
+
overflow: hidden;
|
|
431
|
+
overflow-wrap: anywhere;
|
|
432
|
+
font-size: 0.9375rem;
|
|
433
|
+
font-weight: 600;
|
|
434
|
+
line-height: 1.3;
|
|
435
|
+
}
|
|
436
|
+
[data-sf-preview-name] a { color: inherit; text-decoration: none; }
|
|
437
|
+
[data-sf-preview-name] a:hover { text-decoration: underline; }
|
|
438
|
+
[data-sf-preview-variant],
|
|
439
|
+
[data-sf-preview-sku],
|
|
440
|
+
[data-sf-preview-meta] {
|
|
441
|
+
font-size: 0.8125rem;
|
|
442
|
+
line-height: 1.35;
|
|
443
|
+
color: var(--muted-foreground, color-mix(in srgb, currentColor 66%, transparent));
|
|
444
|
+
}
|
|
445
|
+
[data-sf-preview-sku] { font-variant-numeric: tabular-nums; letter-spacing: 0.01em; }
|
|
446
|
+
[data-sf-preview-total] {
|
|
447
|
+
flex: none;
|
|
448
|
+
align-self: flex-start;
|
|
449
|
+
font-size: 0.9375rem;
|
|
450
|
+
font-weight: 700;
|
|
451
|
+
font-variant-numeric: tabular-nums;
|
|
452
|
+
text-align: right;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/* Fotos apiladas (tarjeta de pedido). */
|
|
456
|
+
[data-sf-thumb-stack] { display: inline-flex; align-items: center; }
|
|
457
|
+
[data-sf-thumb-stack] > * { box-shadow: 0 0 0 2px var(--card, var(--background, #fff)), inset 0 0 0 1px color-mix(in srgb, var(--foreground, #111) 9%, transparent); }
|
|
458
|
+
[data-sf-thumb-stack] > * + * { margin-inline-start: -0.625rem; }
|
|
459
|
+
[data-sf-thumb-more] {
|
|
460
|
+
display: inline-grid;
|
|
461
|
+
place-items: center;
|
|
462
|
+
flex: none;
|
|
463
|
+
box-sizing: border-box;
|
|
464
|
+
width: var(--sf-preview-size, 2.75rem);
|
|
465
|
+
aspect-ratio: 1 / 1;
|
|
466
|
+
border-radius: calc(var(--radius, 0.5rem) * 1.25);
|
|
467
|
+
font-size: 0.8125rem;
|
|
468
|
+
font-weight: 600;
|
|
469
|
+
font-variant-numeric: tabular-nums;
|
|
470
|
+
color: var(--muted-foreground, color-mix(in srgb, currentColor 66%, transparent));
|
|
471
|
+
background: color-mix(in srgb, var(--foreground, #111) 7%, var(--background, #fff));
|
|
472
|
+
}
|
package/dist/checkout.d.cts
CHANGED
|
@@ -14,6 +14,10 @@ type AddressFieldsMessages = Record<AddressFieldKey | ContactFieldKey, string> &
|
|
|
14
14
|
emailHint: string;
|
|
15
15
|
phoneHint: string;
|
|
16
16
|
lookupFilled: string;
|
|
17
|
+
/** Tooltip and note of a state the postal code defined (locked). */
|
|
18
|
+
provinceLocked: string;
|
|
19
|
+
/** Discreet action that releases the locked state so the buyer can fix the postal code. */
|
|
20
|
+
changePostalCode: string;
|
|
17
21
|
};
|
|
18
22
|
declare function addressFieldsMessages(locale?: string | null, overrides?: Partial<AddressFieldsMessages> | null): AddressFieldsMessages;
|
|
19
23
|
type FieldLayoutClassNames = CheckoutFieldClassNames & {
|
|
@@ -88,8 +92,11 @@ type AddressFieldsProps = Common & {
|
|
|
88
92
|
/**
|
|
89
93
|
* Once `lookupPostalCode` fills the state field (never over what the buyer already typed), lock it: a plain
|
|
90
94
|
* `<input>` turns read-only; a `<select>` (from `provinces`) turns disabled with a hidden field that keeps
|
|
91
|
-
* submitting its value. The
|
|
92
|
-
*
|
|
95
|
+
* submitting its value. The state is the postal code's: the field shows a lock, the tooltip `provinceLocked` and a
|
|
96
|
+
* discreet `changePostalCode` action; editing the postal code releases the lock and clears what the lookup filled
|
|
97
|
+
* (also when the new code resolves nothing), so a stale state is never left behind. Default TRUE (the server
|
|
98
|
+
* validates the pair again; set `false` to keep the filled state as editable as any field). Marked with
|
|
99
|
+
* `data-sf-locked="1"` for the shop's own styling.
|
|
93
100
|
*/
|
|
94
101
|
lockProvinceOnFill?: boolean;
|
|
95
102
|
/** Rendered after the fields (e.g. "save this address"). */
|
|
@@ -131,8 +138,10 @@ type OrderSummaryProps = {
|
|
|
131
138
|
cost: CartCost;
|
|
132
139
|
/** The delivery is being saved and the cart re-read: shipping and total say so (`aria-busy`). */
|
|
133
140
|
updating?: boolean;
|
|
134
|
-
/** Picture of a line (e.g. `<ProductImage>`), 48-64 px. The quantity badge sits on it. */
|
|
141
|
+
/** Picture of a line (e.g. `<ProductImage>`), 48-64 px. The quantity badge sits on it. Default: `<ProductThumb>` of the line's image (fallback initial when it has none). */
|
|
135
142
|
renderLineMedia?: (line: CartLine) => ReactNode;
|
|
143
|
+
/** Show the default picture of each line. Default true; `false` gives the text-only "2 × Name" list. */
|
|
144
|
+
media?: boolean;
|
|
136
145
|
renderAmount?: (amount: Money) => ReactNode;
|
|
137
146
|
/** Heading. `false` hides it (the disclosure already names the block). */
|
|
138
147
|
title?: ReactNode | false;
|
package/dist/checkout.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ type AddressFieldsMessages = Record<AddressFieldKey | ContactFieldKey, string> &
|
|
|
14
14
|
emailHint: string;
|
|
15
15
|
phoneHint: string;
|
|
16
16
|
lookupFilled: string;
|
|
17
|
+
/** Tooltip and note of a state the postal code defined (locked). */
|
|
18
|
+
provinceLocked: string;
|
|
19
|
+
/** Discreet action that releases the locked state so the buyer can fix the postal code. */
|
|
20
|
+
changePostalCode: string;
|
|
17
21
|
};
|
|
18
22
|
declare function addressFieldsMessages(locale?: string | null, overrides?: Partial<AddressFieldsMessages> | null): AddressFieldsMessages;
|
|
19
23
|
type FieldLayoutClassNames = CheckoutFieldClassNames & {
|
|
@@ -88,8 +92,11 @@ type AddressFieldsProps = Common & {
|
|
|
88
92
|
/**
|
|
89
93
|
* Once `lookupPostalCode` fills the state field (never over what the buyer already typed), lock it: a plain
|
|
90
94
|
* `<input>` turns read-only; a `<select>` (from `provinces`) turns disabled with a hidden field that keeps
|
|
91
|
-
* submitting its value. The
|
|
92
|
-
*
|
|
95
|
+
* submitting its value. The state is the postal code's: the field shows a lock, the tooltip `provinceLocked` and a
|
|
96
|
+
* discreet `changePostalCode` action; editing the postal code releases the lock and clears what the lookup filled
|
|
97
|
+
* (also when the new code resolves nothing), so a stale state is never left behind. Default TRUE (the server
|
|
98
|
+
* validates the pair again; set `false` to keep the filled state as editable as any field). Marked with
|
|
99
|
+
* `data-sf-locked="1"` for the shop's own styling.
|
|
93
100
|
*/
|
|
94
101
|
lockProvinceOnFill?: boolean;
|
|
95
102
|
/** Rendered after the fields (e.g. "save this address"). */
|
|
@@ -131,8 +138,10 @@ type OrderSummaryProps = {
|
|
|
131
138
|
cost: CartCost;
|
|
132
139
|
/** The delivery is being saved and the cart re-read: shipping and total say so (`aria-busy`). */
|
|
133
140
|
updating?: boolean;
|
|
134
|
-
/** Picture of a line (e.g. `<ProductImage>`), 48-64 px. The quantity badge sits on it. */
|
|
141
|
+
/** Picture of a line (e.g. `<ProductImage>`), 48-64 px. The quantity badge sits on it. Default: `<ProductThumb>` of the line's image (fallback initial when it has none). */
|
|
135
142
|
renderLineMedia?: (line: CartLine) => ReactNode;
|
|
143
|
+
/** Show the default picture of each line. Default true; `false` gives the text-only "2 × Name" list. */
|
|
144
|
+
media?: boolean;
|
|
136
145
|
renderAmount?: (amount: Money) => ReactNode;
|
|
137
146
|
/** Heading. `false` hides it (the disclosure already names the block). */
|
|
138
147
|
title?: ReactNode | false;
|
package/dist/checkout.js
CHANGED
|
@@ -2,6 +2,8 @@ import { brandName, BrandMark, brandKey } from './chunk-JNUJGPJC.js';
|
|
|
2
2
|
export { BrandMark, brandKey, brandLogo, brandName, findBrand, listBrands } from './chunk-JNUJGPJC.js';
|
|
3
3
|
import { CheckoutField } from './chunk-DFGLCIEG.js';
|
|
4
4
|
export { CheckoutField, ErrorSummary, fieldMessages, useFieldErrors, validationMessage } from './chunk-DFGLCIEG.js';
|
|
5
|
+
import { ProductThumb } from './chunk-VHEY5AU3.js';
|
|
6
|
+
import './chunk-6CVKW7F3.js';
|
|
5
7
|
import { useResolvedLocale } from './chunk-T52H5HL3.js';
|
|
6
8
|
import './chunk-DQBL2DFJ.js';
|
|
7
9
|
import { useId, useState, useRef, useEffect, useMemo, useSyncExternalStore } from 'react';
|
|
@@ -26,7 +28,9 @@ var ES = {
|
|
|
26
28
|
referenceHint: "Entre qu\xE9 calles, color de la fachada\u2026",
|
|
27
29
|
emailHint: "Te enviamos aqu\xED la confirmaci\xF3n y el seguimiento.",
|
|
28
30
|
phoneHint: "Solo para la paqueter\xEDa, por si necesita contactarte.",
|
|
29
|
-
lookupFilled: "Completamos estado y ciudad con tu c\xF3digo postal."
|
|
31
|
+
lookupFilled: "Completamos estado y ciudad con tu c\xF3digo postal.",
|
|
32
|
+
provinceLocked: "Definido por tu c\xF3digo postal",
|
|
33
|
+
changePostalCode: "Cambiar c\xF3digo postal"
|
|
30
34
|
};
|
|
31
35
|
var EN = {
|
|
32
36
|
email: "Email",
|
|
@@ -46,7 +50,9 @@ var EN = {
|
|
|
46
50
|
referenceHint: "Cross streets, building color\u2026",
|
|
47
51
|
emailHint: "We send the confirmation and tracking here.",
|
|
48
52
|
phoneHint: "Only for the carrier, in case they need to reach you.",
|
|
49
|
-
lookupFilled: "We filled in state and city from your postal code."
|
|
53
|
+
lookupFilled: "We filled in state and city from your postal code.",
|
|
54
|
+
provinceLocked: "Set by your postal code",
|
|
55
|
+
changePostalCode: "Change postal code"
|
|
50
56
|
};
|
|
51
57
|
function addressFieldsMessages(locale, overrides) {
|
|
52
58
|
const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN : ES;
|
|
@@ -72,8 +78,10 @@ function lockField(el) {
|
|
|
72
78
|
if (el instanceof HTMLSelectElement) {
|
|
73
79
|
const name = el.getAttribute("name");
|
|
74
80
|
if (name) {
|
|
81
|
+
el.dataset.sfName = name;
|
|
75
82
|
const hidden = document.createElement("input");
|
|
76
83
|
hidden.type = "hidden";
|
|
84
|
+
hidden.dataset.sfLockMirror = "1";
|
|
77
85
|
hidden.name = name;
|
|
78
86
|
hidden.value = el.value;
|
|
79
87
|
el.insertAdjacentElement("afterend", hidden);
|
|
@@ -84,12 +92,27 @@ function lockField(el) {
|
|
|
84
92
|
el.readOnly = true;
|
|
85
93
|
}
|
|
86
94
|
}
|
|
95
|
+
function unlockField(el) {
|
|
96
|
+
if (el.dataset.sfLocked !== "1") return;
|
|
97
|
+
delete el.dataset.sfLocked;
|
|
98
|
+
el.removeAttribute("aria-readonly");
|
|
99
|
+
el.removeAttribute("title");
|
|
100
|
+
if (el instanceof HTMLSelectElement) {
|
|
101
|
+
const mirror = el.nextElementSibling;
|
|
102
|
+
if (mirror instanceof HTMLInputElement && mirror.dataset.sfLockMirror === "1") mirror.remove();
|
|
103
|
+
if (el.dataset.sfName) el.setAttribute("name", el.dataset.sfName);
|
|
104
|
+
delete el.dataset.sfName;
|
|
105
|
+
el.disabled = false;
|
|
106
|
+
} else {
|
|
107
|
+
el.readOnly = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
87
110
|
var ADDRESS_FILL_EVENT_FLAG = "sfSynthetic";
|
|
88
111
|
function isAddressFillEvent(event) {
|
|
89
112
|
return event[ADDRESS_FILL_EVENT_FLAG] === true;
|
|
90
113
|
}
|
|
91
114
|
function AddressFields(props) {
|
|
92
|
-
const { defaults, names = {}, errors = {}, countryCode, provinces, postalCode, lookupPostalCode, lockProvinceOnFill, locale, messages, fieldMessages: fm, classNames: cx = {}, children } = props;
|
|
115
|
+
const { defaults, names = {}, errors = {}, countryCode, provinces, postalCode, lookupPostalCode, lockProvinceOnFill = true, locale, messages, fieldMessages: fm, classNames: cx = {}, children } = props;
|
|
93
116
|
const showNeighborhood = props.neighborhood ?? true;
|
|
94
117
|
const showReference = props.reference ?? true;
|
|
95
118
|
const m = addressFieldsMessages(locale, messages);
|
|
@@ -98,6 +121,7 @@ function AddressFields(props) {
|
|
|
98
121
|
const listId = useId();
|
|
99
122
|
const [colonias, setColonias] = useState([]);
|
|
100
123
|
const [filled, setFilled] = useState(false);
|
|
124
|
+
const [provinceLocked, setProvinceLocked] = useState(false);
|
|
101
125
|
const [coloniaSelect, setColoniaSelect] = useState(false);
|
|
102
126
|
const coloniaSelectRef = useRef(false);
|
|
103
127
|
const coloniaCarry = useRef(null);
|
|
@@ -128,6 +152,31 @@ function AddressFields(props) {
|
|
|
128
152
|
form.removeEventListener("change", mark, true);
|
|
129
153
|
};
|
|
130
154
|
}, []);
|
|
155
|
+
const releaseLookup = () => {
|
|
156
|
+
const form = zipRef.current?.closest("form");
|
|
157
|
+
if (!form) return;
|
|
158
|
+
const locked = form.querySelector('[data-sf-locked="1"]');
|
|
159
|
+
const touched = [];
|
|
160
|
+
if (locked) {
|
|
161
|
+
unlockField(locked);
|
|
162
|
+
touched.push(locked);
|
|
163
|
+
}
|
|
164
|
+
for (const key of ["province", "city", "neighborhood"]) {
|
|
165
|
+
const el = form.elements.namedItem(n(key));
|
|
166
|
+
if (el && !("length" in el && !(el instanceof HTMLSelectElement)) && !touched.includes(el)) touched.push(el);
|
|
167
|
+
}
|
|
168
|
+
for (const el of touched) {
|
|
169
|
+
if (el.dataset.sfAutofilled !== "1") continue;
|
|
170
|
+
el.value = "";
|
|
171
|
+
delete el.dataset.sfAutofilled;
|
|
172
|
+
const event = new Event("input", { bubbles: true });
|
|
173
|
+
Object.defineProperty(event, ADDRESS_FILL_EVENT_FLAG, { value: true });
|
|
174
|
+
el.dispatchEvent(event);
|
|
175
|
+
}
|
|
176
|
+
lastZip.current = null;
|
|
177
|
+
setProvinceLocked(false);
|
|
178
|
+
setFilled(false);
|
|
179
|
+
};
|
|
131
180
|
const runLookup = (zip) => {
|
|
132
181
|
const lookup = lookupRef.current;
|
|
133
182
|
if (!lookup || !zip || zip === lastZip.current) return;
|
|
@@ -151,7 +200,11 @@ function AddressFields(props) {
|
|
|
151
200
|
const event = new Event("input", { bubbles: true });
|
|
152
201
|
Object.defineProperty(event, ADDRESS_FILL_EVENT_FLAG, { value: true });
|
|
153
202
|
el2.dispatchEvent(event);
|
|
154
|
-
if (lock)
|
|
203
|
+
if (lock) {
|
|
204
|
+
lockField(el2);
|
|
205
|
+
el2.title = m.provinceLocked;
|
|
206
|
+
setProvinceLocked(true);
|
|
207
|
+
}
|
|
155
208
|
return true;
|
|
156
209
|
};
|
|
157
210
|
const a = fill2(n("province"), info.province, lockProvinceOnFill);
|
|
@@ -199,6 +252,22 @@ function AddressFields(props) {
|
|
|
199
252
|
const zip = defaults?.zip;
|
|
200
253
|
if (zip) runLookup(zip);
|
|
201
254
|
}, []);
|
|
255
|
+
const hasLock = (root) => !!root?.closest("form")?.querySelector('[data-sf-locked="1"]');
|
|
256
|
+
const changeZip = () => {
|
|
257
|
+
releaseLookup();
|
|
258
|
+
const zipEl = zipRef.current?.querySelector("input");
|
|
259
|
+
zipEl?.focus();
|
|
260
|
+
zipEl?.select();
|
|
261
|
+
};
|
|
262
|
+
const provinceHint = provinceLocked ? /* @__PURE__ */ jsxs("span", { "data-sf-province-locked": "", title: m.provinceLocked, children: [
|
|
263
|
+
/* @__PURE__ */ jsxs("svg", { "aria-hidden": "true", width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { display: "inline-block", verticalAlign: "-1px", marginRight: 4 }, children: [
|
|
264
|
+
/* @__PURE__ */ jsx("rect", { x: "4", y: "11", width: "16", height: "10", rx: "2" }),
|
|
265
|
+
/* @__PURE__ */ jsx("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" })
|
|
266
|
+
] }),
|
|
267
|
+
m.provinceLocked,
|
|
268
|
+
" \xB7 ",
|
|
269
|
+
/* @__PURE__ */ jsx("button", { type: "button", "data-sf-change-zip": "", onClick: changeZip, style: { background: "none", border: 0, padding: 0, font: "inherit", color: "inherit", textDecoration: "underline", cursor: "pointer" }, children: m.changePostalCode })
|
|
270
|
+
] }) : void 0;
|
|
202
271
|
const numericZip = postalCode?.inputMode === "numeric";
|
|
203
272
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
204
273
|
/* @__PURE__ */ jsx("div", { ref: zipRef, className: join(cx.half), "data-sf-zip": true, children: /* @__PURE__ */ jsx(
|
|
@@ -218,15 +287,16 @@ function AddressFields(props) {
|
|
|
218
287
|
classNames: { ...cx, root: cx.root },
|
|
219
288
|
onInput: (e) => {
|
|
220
289
|
const v = e.currentTarget.value.trim();
|
|
290
|
+
if (v !== lastZip.current && hasLock(zipRef.current)) releaseLookup();
|
|
221
291
|
if (postalCode?.maxLength && v.length === postalCode.maxLength) runLookup(v);
|
|
222
292
|
},
|
|
223
293
|
onBlur: (e) => runLookup(e.currentTarget.value.trim())
|
|
224
294
|
}
|
|
225
295
|
) }),
|
|
226
|
-
provinces && provinces.length ? /* @__PURE__ */ jsxs(CheckoutField, { ...common, as: "select", name: n("province"), label: m.province, autoComplete: "address-level1", defaultValue: defaults?.province ?? "", error: errors[n("province")] ?? null, classNames: field(cx, "half"), children: [
|
|
296
|
+
provinces && provinces.length ? /* @__PURE__ */ jsxs(CheckoutField, { ...common, as: "select", name: n("province"), label: m.province, autoComplete: "address-level1", defaultValue: defaults?.province ?? "", error: errors[n("province")] ?? null, classNames: field(cx, "half"), hint: provinceHint, children: [
|
|
227
297
|
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: m.provincePlaceholder }),
|
|
228
298
|
provinces.map((p) => /* @__PURE__ */ jsx("option", { value: p.name, children: p.name }, p.code ?? p.name))
|
|
229
|
-
] }) : /* @__PURE__ */ jsx(CheckoutField, { ...common, name: n("province"), label: m.province, autoComplete: "address-level1", defaultValue: defaults?.province ?? "", error: errors[n("province")] ?? null, classNames: field(cx, "half") }),
|
|
299
|
+
] }) : /* @__PURE__ */ jsx(CheckoutField, { ...common, name: n("province"), label: m.province, autoComplete: "address-level1", defaultValue: defaults?.province ?? "", error: errors[n("province")] ?? null, classNames: field(cx, "half"), hint: provinceHint }),
|
|
230
300
|
/* @__PURE__ */ jsx(CheckoutField, { ...common, name: n("city"), label: m.city, autoComplete: "address-level2", defaultValue: defaults?.city ?? "", error: errors[n("city")] ?? null, classNames: field(cx, "half") }),
|
|
231
301
|
showNeighborhood && coloniaSelect ? /* @__PURE__ */ jsxs(
|
|
232
302
|
CheckoutField,
|
|
@@ -302,13 +372,18 @@ function orderSummaryMessages(locale, overrides) {
|
|
|
302
372
|
const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN2 : ES2;
|
|
303
373
|
return overrides ? { ...base, ...overrides } : base;
|
|
304
374
|
}
|
|
375
|
+
function defaultLineMedia(l) {
|
|
376
|
+
const img = l.merchandise.image ?? l.merchandise.product.featured_image ?? null;
|
|
377
|
+
return /* @__PURE__ */ jsx(ProductThumb, { image: img, name: l.merchandise.product.title, size: 56, decorative: true, zoom: false });
|
|
378
|
+
}
|
|
305
379
|
var isZero = (m) => !!m && Number(m.amount) === 0;
|
|
306
380
|
var positive = (m) => !!m && Number(m.amount) > 0;
|
|
307
381
|
function OrderSummary(props) {
|
|
308
|
-
const { lines, cost, updating = false,
|
|
382
|
+
const { lines, cost, updating = false, media = true, renderAmount, title, headingLevel = 2, classNames: cx = {}, children } = props;
|
|
309
383
|
const locale = useResolvedLocale(props.locale);
|
|
310
384
|
const m = orderSummaryMessages(locale, props.messages);
|
|
311
385
|
const money = (v) => renderAmount ? renderAmount(v) : formatMoney(v, locale);
|
|
386
|
+
const renderLineMedia = props.renderLineMedia ?? (media ? defaultLineMedia : void 0);
|
|
312
387
|
const H = headingLevel === 3 ? "h3" : "h2";
|
|
313
388
|
const discounts = cost.discounts?.filter((d) => positive(d.amount)) ?? [];
|
|
314
389
|
return /* @__PURE__ */ jsxs("div", { className: cx.root, "data-sf-summary": true, children: [
|