@asteby/storefront-react 0.21.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/checkout.cjs +74 -6
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +9 -2
- package/dist/checkout.d.ts +9 -2
- package/dist/checkout.js +74 -6
- package/dist/checkout.js.map +1 -1
- package/package.json +2 -2
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"). */
|
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"). */
|
package/dist/checkout.js
CHANGED
|
@@ -28,7 +28,9 @@ var ES = {
|
|
|
28
28
|
referenceHint: "Entre qu\xE9 calles, color de la fachada\u2026",
|
|
29
29
|
emailHint: "Te enviamos aqu\xED la confirmaci\xF3n y el seguimiento.",
|
|
30
30
|
phoneHint: "Solo para la paqueter\xEDa, por si necesita contactarte.",
|
|
31
|
-
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"
|
|
32
34
|
};
|
|
33
35
|
var EN = {
|
|
34
36
|
email: "Email",
|
|
@@ -48,7 +50,9 @@ var EN = {
|
|
|
48
50
|
referenceHint: "Cross streets, building color\u2026",
|
|
49
51
|
emailHint: "We send the confirmation and tracking here.",
|
|
50
52
|
phoneHint: "Only for the carrier, in case they need to reach you.",
|
|
51
|
-
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"
|
|
52
56
|
};
|
|
53
57
|
function addressFieldsMessages(locale, overrides) {
|
|
54
58
|
const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN : ES;
|
|
@@ -74,8 +78,10 @@ function lockField(el) {
|
|
|
74
78
|
if (el instanceof HTMLSelectElement) {
|
|
75
79
|
const name = el.getAttribute("name");
|
|
76
80
|
if (name) {
|
|
81
|
+
el.dataset.sfName = name;
|
|
77
82
|
const hidden = document.createElement("input");
|
|
78
83
|
hidden.type = "hidden";
|
|
84
|
+
hidden.dataset.sfLockMirror = "1";
|
|
79
85
|
hidden.name = name;
|
|
80
86
|
hidden.value = el.value;
|
|
81
87
|
el.insertAdjacentElement("afterend", hidden);
|
|
@@ -86,12 +92,27 @@ function lockField(el) {
|
|
|
86
92
|
el.readOnly = true;
|
|
87
93
|
}
|
|
88
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
|
+
}
|
|
89
110
|
var ADDRESS_FILL_EVENT_FLAG = "sfSynthetic";
|
|
90
111
|
function isAddressFillEvent(event) {
|
|
91
112
|
return event[ADDRESS_FILL_EVENT_FLAG] === true;
|
|
92
113
|
}
|
|
93
114
|
function AddressFields(props) {
|
|
94
|
-
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;
|
|
95
116
|
const showNeighborhood = props.neighborhood ?? true;
|
|
96
117
|
const showReference = props.reference ?? true;
|
|
97
118
|
const m = addressFieldsMessages(locale, messages);
|
|
@@ -100,6 +121,7 @@ function AddressFields(props) {
|
|
|
100
121
|
const listId = useId();
|
|
101
122
|
const [colonias, setColonias] = useState([]);
|
|
102
123
|
const [filled, setFilled] = useState(false);
|
|
124
|
+
const [provinceLocked, setProvinceLocked] = useState(false);
|
|
103
125
|
const [coloniaSelect, setColoniaSelect] = useState(false);
|
|
104
126
|
const coloniaSelectRef = useRef(false);
|
|
105
127
|
const coloniaCarry = useRef(null);
|
|
@@ -130,6 +152,31 @@ function AddressFields(props) {
|
|
|
130
152
|
form.removeEventListener("change", mark, true);
|
|
131
153
|
};
|
|
132
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
|
+
};
|
|
133
180
|
const runLookup = (zip) => {
|
|
134
181
|
const lookup = lookupRef.current;
|
|
135
182
|
if (!lookup || !zip || zip === lastZip.current) return;
|
|
@@ -153,7 +200,11 @@ function AddressFields(props) {
|
|
|
153
200
|
const event = new Event("input", { bubbles: true });
|
|
154
201
|
Object.defineProperty(event, ADDRESS_FILL_EVENT_FLAG, { value: true });
|
|
155
202
|
el2.dispatchEvent(event);
|
|
156
|
-
if (lock)
|
|
203
|
+
if (lock) {
|
|
204
|
+
lockField(el2);
|
|
205
|
+
el2.title = m.provinceLocked;
|
|
206
|
+
setProvinceLocked(true);
|
|
207
|
+
}
|
|
157
208
|
return true;
|
|
158
209
|
};
|
|
159
210
|
const a = fill2(n("province"), info.province, lockProvinceOnFill);
|
|
@@ -201,6 +252,22 @@ function AddressFields(props) {
|
|
|
201
252
|
const zip = defaults?.zip;
|
|
202
253
|
if (zip) runLookup(zip);
|
|
203
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;
|
|
204
271
|
const numericZip = postalCode?.inputMode === "numeric";
|
|
205
272
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
206
273
|
/* @__PURE__ */ jsx("div", { ref: zipRef, className: join(cx.half), "data-sf-zip": true, children: /* @__PURE__ */ jsx(
|
|
@@ -220,15 +287,16 @@ function AddressFields(props) {
|
|
|
220
287
|
classNames: { ...cx, root: cx.root },
|
|
221
288
|
onInput: (e) => {
|
|
222
289
|
const v = e.currentTarget.value.trim();
|
|
290
|
+
if (v !== lastZip.current && hasLock(zipRef.current)) releaseLookup();
|
|
223
291
|
if (postalCode?.maxLength && v.length === postalCode.maxLength) runLookup(v);
|
|
224
292
|
},
|
|
225
293
|
onBlur: (e) => runLookup(e.currentTarget.value.trim())
|
|
226
294
|
}
|
|
227
295
|
) }),
|
|
228
|
-
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: [
|
|
229
297
|
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: m.provincePlaceholder }),
|
|
230
298
|
provinces.map((p) => /* @__PURE__ */ jsx("option", { value: p.name, children: p.name }, p.code ?? p.name))
|
|
231
|
-
] }) : /* @__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 }),
|
|
232
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") }),
|
|
233
301
|
showNeighborhood && coloniaSelect ? /* @__PURE__ */ jsxs(
|
|
234
302
|
CheckoutField,
|