@asteby/storefront-react 0.12.0 → 0.13.1

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.
@@ -1,103 +1,8 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, InputHTMLAttributes, SelectHTMLAttributes, RefObject } from 'react';
2
+ import { ReactNode } from 'react';
3
3
  import { Address, CartLine, CartCost, Money, ShippingRate, PickupOption } from '@asteby/storefront';
4
-
5
- type FieldMessages = {
6
- valueMissing: string;
7
- /** Required radio group (delivery, payment). */
8
- choiceMissing: string;
9
- email: string;
10
- tel: string;
11
- pattern: string;
12
- /** `{n}` = minimum length. */
13
- tooShort: string;
14
- /** A field the server rejected. */
15
- server: string;
16
- /** Error summary title, `{n}` = number of fields. */
17
- summaryOne: string;
18
- summaryMany: string;
19
- optional: string;
20
- };
21
- /** Messages for a locale (`es*` default, `en*`), with optional overrides. */
22
- declare function fieldMessages(locale?: string | null, overrides?: Partial<FieldMessages> | null): FieldMessages;
23
- /** Field name -> error text. */
24
- type FieldErrors = Record<string, string>;
25
- type ErrorSummaryItem = {
26
- name: string;
27
- id: string;
28
- label: string;
29
- message: string;
30
- };
31
- type Control = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
32
- /**
33
- * The error text for a control, from its validity. A control can bring its own text with `data-sf-error` (any
34
- * failure) or `title` (pattern mismatch, the HTML convention).
35
- */
36
- declare function validationMessage(el: Control, m?: FieldMessages): string | null;
37
- type UseFieldErrorsOptions = {
38
- locale?: string;
39
- messages?: Partial<FieldMessages>;
40
- /** Fields the server rejected (e.g. from the action), shown with `serverMessages[name]` or the generic text. */
41
- serverFields?: Iterable<string> | null;
42
- serverMessages?: Record<string, string> | null;
43
- };
44
- type FieldErrorsState = {
45
- errors: FieldErrors;
46
- /** Non-null after a submit with problems (or with server errors): render it in `<ErrorSummary>`. */
47
- summary: ErrorSummaryItem[] | null;
48
- /** Changes every time a new summary appears, so `<ErrorSummary>` focuses it again. */
49
- summaryKey: number;
50
- clear: () => void;
51
- };
52
- /**
53
- * Inline validation for the page `<form>`. Listens to the form (no wrapping component): leaving a field with a value
54
- * checks it; typing in a field with an error clears it when fixed; a submit or `reportValidity()` with problems
55
- * collects them (the browser's bubbles are replaced by the inline texts) for the summary.
56
- */
57
- declare function useFieldErrors(formRef: RefObject<HTMLFormElement | null>, options?: UseFieldErrorsOptions): FieldErrorsState;
58
- type ErrorSummaryProps = {
59
- items: readonly ErrorSummaryItem[] | null;
60
- /** Changes when a new summary must take focus (`useFieldErrors().summaryKey`). */
61
- focusKey?: number;
62
- locale?: string;
63
- messages?: Partial<FieldMessages>;
64
- title?: ReactNode;
65
- className?: string;
66
- classNames?: Partial<Record<'title' | 'list' | 'link', string>>;
67
- };
68
- /**
69
- * The list of problems after a submit, above the form: `role="alert"`, takes focus, one link per field (moves the
70
- * focus to it). Renders nothing without items.
71
- */
72
- declare function ErrorSummary({ items, focusKey, locale, messages, title, className, classNames: cx }: ErrorSummaryProps): react.JSX.Element | null;
73
- type CheckoutFieldClassNames = Partial<Record<'root' | 'label' | 'optional' | 'input' | 'hint' | 'error', string>>;
74
- type BaseFieldProps = {
75
- name: string;
76
- label: string;
77
- /** Field id. Default: the name. */
78
- id?: string;
79
- /** Error text (from `useFieldErrors().errors[name]` or the server). */
80
- error?: string | null;
81
- /** Help under the label ("we only use it for the delivery"). */
82
- hint?: ReactNode;
83
- /** Marks the label "(optional)" and drops `required`. */
84
- optional?: boolean;
85
- classNames?: CheckoutFieldClassNames;
86
- locale?: string;
87
- messages?: Partial<FieldMessages>;
88
- };
89
- type CheckoutFieldProps = BaseFieldProps & Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id'> & {
90
- as?: 'input';
91
- };
92
- type CheckoutSelectProps = BaseFieldProps & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'name' | 'id'> & {
93
- as: 'select';
94
- children: ReactNode;
95
- };
96
- /**
97
- * One labelled field: label (with "(optional)"), hint, the control and its error text, wired with `aria-describedby`
98
- * and `aria-invalid`. Required unless `optional`. `as="select"` renders a `<select>` with the given options.
99
- */
100
- declare function CheckoutField(props: CheckoutFieldProps | CheckoutSelectProps): react.JSX.Element;
4
+ import { F as FieldErrors, g as FieldMessages, a as CheckoutFieldClassNames } from './fields-vnMUi2HB.cjs';
5
+ export { C as CheckoutField, b as CheckoutFieldProps, c as CheckoutSelectProps, E as ErrorSummary, d as ErrorSummaryItem, e as ErrorSummaryProps, f as FieldErrorsState, U as UseFieldErrorsOptions, h as fieldMessages, u as useFieldErrors, v as validationMessage } from './fields-vnMUi2HB.cjs';
101
6
 
102
7
  type AddressFieldKey = 'zip' | 'province' | 'city' | 'neighborhood' | 'address1' | 'address2' | 'reference';
103
8
  type ContactFieldKey = 'email' | 'phone' | 'first_name' | 'last_name';
@@ -305,7 +210,7 @@ type Brand = {
305
210
  /** Short wordmark drawn in the badge (`\n` = two lines). Default: `name`. */
306
211
  mark?: string;
307
212
  /** Special drawings instead of a wordmark. */
308
- shape?: 'mastercard';
213
+ shape?: 'mastercard' | 'transfer';
309
214
  };
310
215
  /** `"FedEx México"`, `"fedex_mx"` and `"FEDEX"` all become `fedex`. Lowercase ASCII letters and digits only. */
311
216
  declare function brandKey(raw: string | null | undefined): string;
@@ -528,4 +433,4 @@ declare function dedupeRates<R extends ShippingRate>(rates: readonly R[]): R[];
528
433
  */
529
434
  declare function recommendRates<R extends ShippingRate>(input: readonly R[], options?: RecommendRatesOptions): RecommendedRates<R>;
530
435
 
531
- export { type AddressFieldKey, AddressFields, type AddressFieldsMessages, type AddressFieldsProps, type Brand, type BrandKind, BrandMark, type BrandMarkProps, type BrandMarkSource, CheckoutField, type CheckoutFieldClassNames, type CheckoutFieldProps, type CheckoutSelectProps, type ContactFieldKey, ContactFields, type ContactFieldsProps, type DeliveryMessages, DeliveryOptions, type DeliveryOptionsClassNames, type DeliveryOptionsProps, ErrorSummary, type ErrorSummaryItem, type ErrorSummaryProps, type FieldErrors, type FieldErrorsState, type FieldLayoutClassNames, type FieldMessages, OrderSummary, type OrderSummaryClassNames, OrderSummaryDisclosure, type OrderSummaryDisclosureProps, type OrderSummaryMessages, type OrderSummaryProps, type PostalCodeInfo, type QuoteNote, type RateBadge, type RateGroup, type RateTag, type RecommendRatesOptions, type RecommendedRate, type RecommendedRates, type UseFieldErrorsOptions, addressFieldsMessages, brandKey, brandLogo, brandName, dedupeRates, deliveryMessages, fieldMessages, findBrand, isQuoteChange, listBrands, matchRate, orderSummaryMessages, quoteDeadline, quoteNote, rateBadges, rateCarrier, rateEta, rateService, recommendRates, useFieldErrors, validationMessage };
436
+ export { type AddressFieldKey, AddressFields, type AddressFieldsMessages, type AddressFieldsProps, type Brand, type BrandKind, BrandMark, type BrandMarkProps, type BrandMarkSource, CheckoutFieldClassNames, type ContactFieldKey, ContactFields, type ContactFieldsProps, type DeliveryMessages, DeliveryOptions, type DeliveryOptionsClassNames, type DeliveryOptionsProps, FieldErrors, type FieldLayoutClassNames, FieldMessages, OrderSummary, type OrderSummaryClassNames, OrderSummaryDisclosure, type OrderSummaryDisclosureProps, type OrderSummaryMessages, type OrderSummaryProps, type PostalCodeInfo, type QuoteNote, type RateBadge, type RateGroup, type RateTag, type RecommendRatesOptions, type RecommendedRate, type RecommendedRates, addressFieldsMessages, brandKey, brandLogo, brandName, dedupeRates, deliveryMessages, findBrand, isQuoteChange, listBrands, matchRate, orderSummaryMessages, quoteDeadline, quoteNote, rateBadges, rateCarrier, rateEta, rateService, recommendRates };
@@ -1,103 +1,8 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, InputHTMLAttributes, SelectHTMLAttributes, RefObject } from 'react';
2
+ import { ReactNode } from 'react';
3
3
  import { Address, CartLine, CartCost, Money, ShippingRate, PickupOption } from '@asteby/storefront';
4
-
5
- type FieldMessages = {
6
- valueMissing: string;
7
- /** Required radio group (delivery, payment). */
8
- choiceMissing: string;
9
- email: string;
10
- tel: string;
11
- pattern: string;
12
- /** `{n}` = minimum length. */
13
- tooShort: string;
14
- /** A field the server rejected. */
15
- server: string;
16
- /** Error summary title, `{n}` = number of fields. */
17
- summaryOne: string;
18
- summaryMany: string;
19
- optional: string;
20
- };
21
- /** Messages for a locale (`es*` default, `en*`), with optional overrides. */
22
- declare function fieldMessages(locale?: string | null, overrides?: Partial<FieldMessages> | null): FieldMessages;
23
- /** Field name -> error text. */
24
- type FieldErrors = Record<string, string>;
25
- type ErrorSummaryItem = {
26
- name: string;
27
- id: string;
28
- label: string;
29
- message: string;
30
- };
31
- type Control = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
32
- /**
33
- * The error text for a control, from its validity. A control can bring its own text with `data-sf-error` (any
34
- * failure) or `title` (pattern mismatch, the HTML convention).
35
- */
36
- declare function validationMessage(el: Control, m?: FieldMessages): string | null;
37
- type UseFieldErrorsOptions = {
38
- locale?: string;
39
- messages?: Partial<FieldMessages>;
40
- /** Fields the server rejected (e.g. from the action), shown with `serverMessages[name]` or the generic text. */
41
- serverFields?: Iterable<string> | null;
42
- serverMessages?: Record<string, string> | null;
43
- };
44
- type FieldErrorsState = {
45
- errors: FieldErrors;
46
- /** Non-null after a submit with problems (or with server errors): render it in `<ErrorSummary>`. */
47
- summary: ErrorSummaryItem[] | null;
48
- /** Changes every time a new summary appears, so `<ErrorSummary>` focuses it again. */
49
- summaryKey: number;
50
- clear: () => void;
51
- };
52
- /**
53
- * Inline validation for the page `<form>`. Listens to the form (no wrapping component): leaving a field with a value
54
- * checks it; typing in a field with an error clears it when fixed; a submit or `reportValidity()` with problems
55
- * collects them (the browser's bubbles are replaced by the inline texts) for the summary.
56
- */
57
- declare function useFieldErrors(formRef: RefObject<HTMLFormElement | null>, options?: UseFieldErrorsOptions): FieldErrorsState;
58
- type ErrorSummaryProps = {
59
- items: readonly ErrorSummaryItem[] | null;
60
- /** Changes when a new summary must take focus (`useFieldErrors().summaryKey`). */
61
- focusKey?: number;
62
- locale?: string;
63
- messages?: Partial<FieldMessages>;
64
- title?: ReactNode;
65
- className?: string;
66
- classNames?: Partial<Record<'title' | 'list' | 'link', string>>;
67
- };
68
- /**
69
- * The list of problems after a submit, above the form: `role="alert"`, takes focus, one link per field (moves the
70
- * focus to it). Renders nothing without items.
71
- */
72
- declare function ErrorSummary({ items, focusKey, locale, messages, title, className, classNames: cx }: ErrorSummaryProps): react.JSX.Element | null;
73
- type CheckoutFieldClassNames = Partial<Record<'root' | 'label' | 'optional' | 'input' | 'hint' | 'error', string>>;
74
- type BaseFieldProps = {
75
- name: string;
76
- label: string;
77
- /** Field id. Default: the name. */
78
- id?: string;
79
- /** Error text (from `useFieldErrors().errors[name]` or the server). */
80
- error?: string | null;
81
- /** Help under the label ("we only use it for the delivery"). */
82
- hint?: ReactNode;
83
- /** Marks the label "(optional)" and drops `required`. */
84
- optional?: boolean;
85
- classNames?: CheckoutFieldClassNames;
86
- locale?: string;
87
- messages?: Partial<FieldMessages>;
88
- };
89
- type CheckoutFieldProps = BaseFieldProps & Omit<InputHTMLAttributes<HTMLInputElement>, 'name' | 'id'> & {
90
- as?: 'input';
91
- };
92
- type CheckoutSelectProps = BaseFieldProps & Omit<SelectHTMLAttributes<HTMLSelectElement>, 'name' | 'id'> & {
93
- as: 'select';
94
- children: ReactNode;
95
- };
96
- /**
97
- * One labelled field: label (with "(optional)"), hint, the control and its error text, wired with `aria-describedby`
98
- * and `aria-invalid`. Required unless `optional`. `as="select"` renders a `<select>` with the given options.
99
- */
100
- declare function CheckoutField(props: CheckoutFieldProps | CheckoutSelectProps): react.JSX.Element;
4
+ import { F as FieldErrors, g as FieldMessages, a as CheckoutFieldClassNames } from './fields-vnMUi2HB.js';
5
+ export { C as CheckoutField, b as CheckoutFieldProps, c as CheckoutSelectProps, E as ErrorSummary, d as ErrorSummaryItem, e as ErrorSummaryProps, f as FieldErrorsState, U as UseFieldErrorsOptions, h as fieldMessages, u as useFieldErrors, v as validationMessage } from './fields-vnMUi2HB.js';
101
6
 
102
7
  type AddressFieldKey = 'zip' | 'province' | 'city' | 'neighborhood' | 'address1' | 'address2' | 'reference';
103
8
  type ContactFieldKey = 'email' | 'phone' | 'first_name' | 'last_name';
@@ -305,7 +210,7 @@ type Brand = {
305
210
  /** Short wordmark drawn in the badge (`\n` = two lines). Default: `name`. */
306
211
  mark?: string;
307
212
  /** Special drawings instead of a wordmark. */
308
- shape?: 'mastercard';
213
+ shape?: 'mastercard' | 'transfer';
309
214
  };
310
215
  /** `"FedEx México"`, `"fedex_mx"` and `"FEDEX"` all become `fedex`. Lowercase ASCII letters and digits only. */
311
216
  declare function brandKey(raw: string | null | undefined): string;
@@ -528,4 +433,4 @@ declare function dedupeRates<R extends ShippingRate>(rates: readonly R[]): R[];
528
433
  */
529
434
  declare function recommendRates<R extends ShippingRate>(input: readonly R[], options?: RecommendRatesOptions): RecommendedRates<R>;
530
435
 
531
- export { type AddressFieldKey, AddressFields, type AddressFieldsMessages, type AddressFieldsProps, type Brand, type BrandKind, BrandMark, type BrandMarkProps, type BrandMarkSource, CheckoutField, type CheckoutFieldClassNames, type CheckoutFieldProps, type CheckoutSelectProps, type ContactFieldKey, ContactFields, type ContactFieldsProps, type DeliveryMessages, DeliveryOptions, type DeliveryOptionsClassNames, type DeliveryOptionsProps, ErrorSummary, type ErrorSummaryItem, type ErrorSummaryProps, type FieldErrors, type FieldErrorsState, type FieldLayoutClassNames, type FieldMessages, OrderSummary, type OrderSummaryClassNames, OrderSummaryDisclosure, type OrderSummaryDisclosureProps, type OrderSummaryMessages, type OrderSummaryProps, type PostalCodeInfo, type QuoteNote, type RateBadge, type RateGroup, type RateTag, type RecommendRatesOptions, type RecommendedRate, type RecommendedRates, type UseFieldErrorsOptions, addressFieldsMessages, brandKey, brandLogo, brandName, dedupeRates, deliveryMessages, fieldMessages, findBrand, isQuoteChange, listBrands, matchRate, orderSummaryMessages, quoteDeadline, quoteNote, rateBadges, rateCarrier, rateEta, rateService, recommendRates, useFieldErrors, validationMessage };
436
+ export { type AddressFieldKey, AddressFields, type AddressFieldsMessages, type AddressFieldsProps, type Brand, type BrandKind, BrandMark, type BrandMarkProps, type BrandMarkSource, CheckoutFieldClassNames, type ContactFieldKey, ContactFields, type ContactFieldsProps, type DeliveryMessages, DeliveryOptions, type DeliveryOptionsClassNames, type DeliveryOptionsProps, FieldErrors, type FieldLayoutClassNames, FieldMessages, OrderSummary, type OrderSummaryClassNames, OrderSummaryDisclosure, type OrderSummaryDisclosureProps, type OrderSummaryMessages, type OrderSummaryProps, type PostalCodeInfo, type QuoteNote, type RateBadge, type RateGroup, type RateTag, type RecommendRatesOptions, type RecommendedRate, type RecommendedRates, addressFieldsMessages, brandKey, brandLogo, brandName, dedupeRates, deliveryMessages, findBrand, isQuoteChange, listBrands, matchRate, orderSummaryMessages, quoteDeadline, quoteNote, rateBadges, rateCarrier, rateEta, rateService, recommendRates };
package/dist/checkout.js CHANGED
@@ -1,230 +1,14 @@
1
- import { brandName, BrandMark, brandKey } from './chunk-ODIQR6TG.js';
2
- export { BrandMark, brandKey, brandLogo, brandName, findBrand, listBrands } from './chunk-ODIQR6TG.js';
1
+ import { brandName, BrandMark, brandKey } from './chunk-JNUJGPJC.js';
2
+ export { BrandMark, brandKey, brandLogo, brandName, findBrand, listBrands } from './chunk-JNUJGPJC.js';
3
3
  import { useResolvedLocale } from './chunk-T52H5HL3.js';
4
4
  import './chunk-DQBL2DFJ.js';
5
- import { useRef, useState, useEffect, useId, useMemo, useSyncExternalStore } from 'react';
6
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
+ import { CheckoutField } from './chunk-DFGLCIEG.js';
6
+ export { CheckoutField, ErrorSummary, fieldMessages, useFieldErrors, validationMessage } from './chunk-DFGLCIEG.js';
7
+ import { useId, useState, useRef, useEffect, useMemo, useSyncExternalStore } from 'react';
8
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
7
9
  import { formatMoney } from '@asteby/storefront';
8
10
 
9
11
  var ES = {
10
- valueMissing: "Completa este campo.",
11
- choiceMissing: "Elige una opci\xF3n.",
12
- email: "Escribe un correo v\xE1lido, por ejemplo nombre@correo.com.",
13
- tel: "Escribe un tel\xE9fono v\xE1lido.",
14
- pattern: "Revisa el formato.",
15
- tooShort: "Escribe al menos {n} caracteres.",
16
- server: "Revisa este campo.",
17
- summaryOne: "Revisa 1 campo para continuar",
18
- summaryMany: "Revisa {n} campos para continuar",
19
- optional: "(opcional)"
20
- };
21
- var EN = {
22
- valueMissing: "Fill in this field.",
23
- choiceMissing: "Choose an option.",
24
- email: "Enter a valid email, like name@example.com.",
25
- tel: "Enter a valid phone number.",
26
- pattern: "Check the format.",
27
- tooShort: "Enter at least {n} characters.",
28
- server: "Check this field.",
29
- summaryOne: "Check 1 field to continue",
30
- summaryMany: "Check {n} fields to continue",
31
- optional: "(optional)"
32
- };
33
- function fieldMessages(locale, overrides) {
34
- const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN : ES;
35
- return overrides ? { ...base, ...overrides } : base;
36
- }
37
- var isControl = (el) => !!el && typeof el.tagName === "string" && ["INPUT", "SELECT", "TEXTAREA"].includes(el.tagName) && !!el.name;
38
- function validationMessage(el, m = ES) {
39
- const v = el.validity;
40
- if (!v || v.valid) return null;
41
- const own = el.getAttribute("data-sf-error");
42
- if (own) return own;
43
- if (v.valueMissing) return el instanceof HTMLInputElement && (el.type === "radio" || el.type === "checkbox") ? m.choiceMissing : m.valueMissing;
44
- if (v.typeMismatch && el instanceof HTMLInputElement) return el.type === "email" ? m.email : el.type === "tel" ? m.tel : m.pattern;
45
- if (v.patternMismatch) return el.getAttribute("title") || (el instanceof HTMLInputElement && el.type === "tel" ? m.tel : m.pattern);
46
- if (v.tooShort && el instanceof HTMLInputElement) return m.tooShort.replace("{n}", String(el.minLength));
47
- return el.validationMessage || m.pattern;
48
- }
49
- function labelOf(el) {
50
- if (el instanceof HTMLInputElement && el.type === "radio") {
51
- const legend = el.closest("fieldset")?.querySelector("legend");
52
- if (legend?.textContent) return legend.textContent.trim();
53
- }
54
- const text = el.labels?.[0]?.getAttribute("data-sf-label") ?? el.labels?.[0]?.textContent ?? el.getAttribute("aria-label") ?? el.name;
55
- return text.trim();
56
- }
57
- function useFieldErrors(formRef, options = {}) {
58
- const m = fieldMessages(options.locale, options.messages);
59
- const live = useRef(m);
60
- live.current = m;
61
- const server = [...options.serverFields ?? []];
62
- const serverKey = server.join("|");
63
- const [errors, setErrors] = useState(() => Object.fromEntries(server.map((n) => [n, options.serverMessages?.[n] ?? m.server])));
64
- const [summary, setSummary] = useState(null);
65
- const [summaryKey, setSummaryKey] = useState(0);
66
- useEffect(() => {
67
- if (!server.length) return;
68
- const form = formRef.current;
69
- const items = [];
70
- const next = {};
71
- for (const name of server) {
72
- const msg = options.serverMessages?.[name] ?? live.current.server;
73
- next[name] = msg;
74
- const el = form?.elements.namedItem(name);
75
- const ctl = el && "length" in el && !(el instanceof HTMLSelectElement) ? el[0] : el;
76
- if (ctl) items.push({ name, id: ctl.id || name, label: labelOf(ctl), message: msg });
77
- }
78
- setErrors((e) => ({ ...e, ...next }));
79
- if (items.length) {
80
- setSummary(items);
81
- setSummaryKey((k) => k + 1);
82
- }
83
- }, [serverKey]);
84
- useEffect(() => {
85
- const form = formRef.current;
86
- if (!form) return;
87
- let batch = null;
88
- const set = (name, msg) => setErrors((e) => {
89
- if (msg === null) {
90
- if (!(name in e)) return e;
91
- const { [name]: _gone, ...rest } = e;
92
- return rest;
93
- }
94
- return e[name] === msg ? e : { ...e, [name]: msg };
95
- });
96
- const onBlur = (ev) => {
97
- const el = ev.target;
98
- if (!isControl(el) || el instanceof HTMLInputElement && (el.type === "radio" || el.type === "checkbox" || el.type === "hidden")) return;
99
- if (!el.value) return;
100
- set(el.name, validationMessage(el, live.current));
101
- };
102
- const onInput = (ev) => {
103
- const el = ev.target;
104
- if (!isControl(el)) return;
105
- setErrors((e) => {
106
- if (!(el.name in e)) return e;
107
- const msg = el.validity.valid ? null : validationMessage(el, live.current);
108
- if (msg !== null) return e;
109
- const { [el.name]: _gone, ...rest } = e;
110
- return rest;
111
- });
112
- };
113
- const onInvalid = (ev) => {
114
- const el = ev.target;
115
- if (!isControl(el)) return;
116
- ev.preventDefault();
117
- if (!batch) {
118
- batch = [];
119
- queueMicrotask(() => {
120
- const list = batch ?? [];
121
- batch = null;
122
- const seen = /* @__PURE__ */ new Set();
123
- const items = [];
124
- const next = {};
125
- for (const c of list) {
126
- if (seen.has(c.name)) continue;
127
- seen.add(c.name);
128
- const msg = validationMessage(c, live.current) ?? live.current.valueMissing;
129
- next[c.name] = msg;
130
- items.push({ name: c.name, id: c.id || c.name, label: labelOf(c), message: msg });
131
- }
132
- setErrors((e) => ({ ...e, ...next }));
133
- setSummary(items);
134
- setSummaryKey((k) => k + 1);
135
- });
136
- }
137
- batch.push(el);
138
- };
139
- form.addEventListener("focusout", onBlur);
140
- form.addEventListener("input", onInput);
141
- form.addEventListener("change", onInput);
142
- form.addEventListener("invalid", onInvalid, true);
143
- return () => {
144
- form.removeEventListener("focusout", onBlur);
145
- form.removeEventListener("input", onInput);
146
- form.removeEventListener("change", onInput);
147
- form.removeEventListener("invalid", onInvalid, true);
148
- };
149
- }, [formRef]);
150
- const shown = summary ? summary.filter((s) => s.name in errors).map((s) => ({ ...s, message: errors[s.name] })) : null;
151
- return {
152
- errors,
153
- summary: shown && shown.length ? shown : null,
154
- summaryKey,
155
- clear: () => {
156
- setErrors({});
157
- setSummary(null);
158
- }
159
- };
160
- }
161
- function ErrorSummary({ items, focusKey, locale, messages, title, className, classNames: cx = {} }) {
162
- const ref = useRef(null);
163
- const m = fieldMessages(locale, messages);
164
- const has = !!items && items.length > 0;
165
- useEffect(() => {
166
- if (has) ref.current?.focus();
167
- }, [focusKey]);
168
- if (!has) return null;
169
- const n = items.length;
170
- return /* @__PURE__ */ jsxs("div", { ref, role: "alert", tabIndex: -1, className, "data-sf-error-summary": true, "aria-labelledby": "sf-error-summary-title", children: [
171
- /* @__PURE__ */ jsx("p", { id: "sf-error-summary-title", className: cx.title, "data-sf-error-summary-title": true, children: title ?? (n === 1 ? m.summaryOne : m.summaryMany.replace("{n}", String(n))) }),
172
- /* @__PURE__ */ jsx("ul", { className: cx.list, children: items.map((it) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
173
- "a",
174
- {
175
- href: `#${it.id}`,
176
- className: cx.link,
177
- onClick: (e) => {
178
- const el = document.getElementById(it.id);
179
- if (!el) return;
180
- e.preventDefault();
181
- el.focus();
182
- el.scrollIntoView?.({ block: "center" });
183
- },
184
- children: [
185
- it.label,
186
- ": ",
187
- it.message
188
- ]
189
- }
190
- ) }, it.name)) })
191
- ] });
192
- }
193
- function CheckoutField(props) {
194
- const { name, label, id = name, error, hint, optional = false, classNames: cx = {}, locale, messages, ...rest } = props;
195
- const m = fieldMessages(locale, messages);
196
- const hintId = hint ? `${id}-hint` : void 0;
197
- const errorId = `${id}-error`;
198
- const describedBy = [hintId, error ? errorId : void 0].filter(Boolean).join(" ") || void 0;
199
- const common = {
200
- id,
201
- name,
202
- required: !optional,
203
- "aria-invalid": error ? true : void 0,
204
- "aria-describedby": describedBy,
205
- className: cx.input,
206
- "data-sf-field-control": ""
207
- };
208
- return /* @__PURE__ */ jsxs("div", { className: cx.root, "data-sf-field": true, "data-invalid": error ? "" : void 0, children: [
209
- /* @__PURE__ */ jsxs("label", { htmlFor: id, className: cx.label, "data-sf-label": label, children: [
210
- label,
211
- optional ? /* @__PURE__ */ jsxs("span", { className: cx.optional, "data-sf-field-optional": true, children: [
212
- " ",
213
- m.optional
214
- ] }) : null
215
- ] }),
216
- hint ? /* @__PURE__ */ jsx("p", { id: hintId, className: cx.hint, "data-sf-field-hint": true, children: hint }) : null,
217
- rest.as === "select" ? (() => {
218
- const { as: _as, children, ...select } = rest;
219
- return /* @__PURE__ */ jsx("select", { ...select, ...common, children });
220
- })() : (() => {
221
- const { as: _as, ...input } = rest;
222
- return /* @__PURE__ */ jsx("input", { ...input, ...common });
223
- })(),
224
- error ? /* @__PURE__ */ jsx("p", { id: errorId, className: cx.error, "data-sf-field-error": true, children: error }) : null
225
- ] });
226
- }
227
- var ES2 = {
228
12
  email: "Correo",
229
13
  phone: "Tel\xE9fono",
230
14
  first_name: "Nombre",
@@ -243,7 +27,7 @@ var ES2 = {
243
27
  phoneHint: "Solo para la paqueter\xEDa, por si necesita contactarte.",
244
28
  lookupFilled: "Completamos estado y ciudad con tu c\xF3digo postal."
245
29
  };
246
- var EN2 = {
30
+ var EN = {
247
31
  email: "Email",
248
32
  phone: "Phone",
249
33
  first_name: "First name",
@@ -263,7 +47,7 @@ var EN2 = {
263
47
  lookupFilled: "We filled in state and city from your postal code."
264
48
  };
265
49
  function addressFieldsMessages(locale, overrides) {
266
- const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN2 : ES2;
50
+ const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN : ES;
267
51
  return overrides ? { ...base, ...overrides } : base;
268
52
  }
269
53
  var join = (...c) => c.filter(Boolean).join(" ") || void 0;
@@ -377,7 +161,7 @@ function AddressFields(props) {
377
161
  children
378
162
  ] });
379
163
  }
380
- var ES3 = {
164
+ var ES2 = {
381
165
  title: "Tu pedido",
382
166
  subtotal: "Subtotal",
383
167
  discount: "Descuento",
@@ -392,7 +176,7 @@ var ES3 = {
392
176
  show: "Ver resumen del pedido",
393
177
  hide: "Ocultar resumen del pedido"
394
178
  };
395
- var EN3 = {
179
+ var EN2 = {
396
180
  title: "Your order",
397
181
  subtotal: "Subtotal",
398
182
  discount: "Discount",
@@ -408,7 +192,7 @@ var EN3 = {
408
192
  hide: "Hide order summary"
409
193
  };
410
194
  function orderSummaryMessages(locale, overrides) {
411
- const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN3 : ES3;
195
+ const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN2 : ES2;
412
196
  return overrides ? { ...base, ...overrides } : base;
413
197
  }
414
198
  var isZero = (m) => !!m && Number(m.amount) === 0;
@@ -565,7 +349,7 @@ function recommendRates(input, options = {}) {
565
349
  }
566
350
 
567
351
  // src/checkout/delivery.ts
568
- var ES4 = {
352
+ var ES3 = {
569
353
  etaOne: "Llega en 1 d\xEDa h\xE1bil",
570
354
  etaMany: "Llega en {n} d\xEDas h\xE1biles",
571
355
  etaRange: "Llega en {min} a {max} d\xEDas h\xE1biles",
@@ -588,7 +372,7 @@ var ES4 = {
588
372
  error: "No pudimos consultar las opciones de env\xEDo en este momento.",
589
373
  retry: "Intentar de nuevo"
590
374
  };
591
- var EN4 = {
375
+ var EN3 = {
592
376
  etaOne: "Arrives in 1 business day",
593
377
  etaMany: "Arrives in {n} business days",
594
378
  etaRange: "Arrives in {min} to {max} business days",
@@ -612,7 +396,7 @@ var EN4 = {
612
396
  retry: "Try again"
613
397
  };
614
398
  function deliveryMessages(locale, overrides) {
615
- const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN4 : ES4;
399
+ const base = (locale ?? "es-MX").toLowerCase().startsWith("en") ? EN3 : ES3;
616
400
  return overrides ? { ...base, ...overrides } : base;
617
401
  }
618
402
  var fill = (tpl, vars) => tpl.replace(/\{(\w+)\}/g, (_, k) => String(vars[k] ?? "")).replace(/\.\.$/, ".");
@@ -632,7 +416,7 @@ function rateService(rate) {
632
416
  }
633
417
  return title;
634
418
  }
635
- function rateEta(rate, messages = ES4) {
419
+ function rateEta(rate, messages = ES3) {
636
420
  const { eta_days_min: min, eta_days_max: max } = rate;
637
421
  if (typeof min === "number" && typeof max === "number") {
638
422
  if (min === max) return min === 1 ? messages.etaOne : fill(messages.etaMany, { n: min });
@@ -682,7 +466,7 @@ function quoteNote(deadline, opts = {}) {
682
466
  const now = opts.now ?? /* @__PURE__ */ new Date();
683
467
  const left = deadline.getTime() - now.getTime();
684
468
  if (left <= 0) return null;
685
- const m = opts.messages ?? ES4;
469
+ const m = opts.messages ?? ES3;
686
470
  const locale = opts.locale ?? "es-MX";
687
471
  const tz = opts.timeZone ? { timeZone: opts.timeZone } : {};
688
472
  const time = new Intl.DateTimeFormat(locale, { hour: "numeric", minute: "2-digit", ...tz }).format(deadline);
@@ -845,6 +629,6 @@ function DeliveryOptions(props) {
845
629
  ] });
846
630
  }
847
631
 
848
- export { AddressFields, CheckoutField, ContactFields, DeliveryOptions, ErrorSummary, OrderSummary, OrderSummaryDisclosure, addressFieldsMessages, dedupeRates, deliveryMessages, fieldMessages, isQuoteChange, matchRate, orderSummaryMessages, quoteDeadline, quoteNote, rateBadges, rateCarrier, rateEta, rateService, recommendRates, useFieldErrors, validationMessage };
632
+ export { AddressFields, ContactFields, DeliveryOptions, OrderSummary, OrderSummaryDisclosure, addressFieldsMessages, dedupeRates, deliveryMessages, isQuoteChange, matchRate, orderSummaryMessages, quoteDeadline, quoteNote, rateBadges, rateCarrier, rateEta, rateService, recommendRates };
849
633
  //# sourceMappingURL=checkout.js.map
850
634
  //# sourceMappingURL=checkout.js.map