@thorprovider/blocks 4.0.0 → 4.1.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.
Files changed (55) hide show
  1. package/dist/blocks/designs/checkout-commerce-v1/block.d.ts +49 -0
  2. package/dist/blocks/designs/checkout-commerce-v1/block.d.ts.map +1 -0
  3. package/dist/blocks/designs/checkout-commerce-v1/block.js +2487 -0
  4. package/dist/blocks/designs/checkout-commerce-v1/block.js.map +1 -0
  5. package/dist/blocks/designs/checkout-commerce-v1/block.mjs +2467 -0
  6. package/dist/blocks/designs/checkout-commerce-v1/block.mjs.map +1 -0
  7. package/dist/blocks/designs/checkout-commerce-v1/data-context.d.ts +8 -0
  8. package/dist/blocks/designs/checkout-commerce-v1/data-context.d.ts.map +1 -0
  9. package/dist/blocks/designs/checkout-commerce-v1/data-context.js +44 -0
  10. package/dist/blocks/designs/checkout-commerce-v1/data-context.js.map +1 -0
  11. package/dist/blocks/designs/checkout-commerce-v1/data-context.mjs +19 -0
  12. package/dist/blocks/designs/checkout-commerce-v1/data-context.mjs.map +1 -0
  13. package/dist/blocks/designs/checkout-commerce-v1/index.d.ts +3 -0
  14. package/dist/blocks/designs/checkout-commerce-v1/index.d.ts.map +1 -0
  15. package/dist/blocks/designs/checkout-commerce-v1/index.js +36 -0
  16. package/dist/blocks/designs/checkout-commerce-v1/index.js.map +1 -0
  17. package/dist/blocks/designs/checkout-commerce-v1/index.mjs +6 -0
  18. package/dist/blocks/designs/checkout-commerce-v1/index.mjs.map +1 -0
  19. package/dist/blocks/e-commerce/account/account-frame.d.ts +38 -0
  20. package/dist/blocks/e-commerce/account/account-frame.d.ts.map +1 -0
  21. package/dist/blocks/e-commerce/account/account-frame.js +102 -0
  22. package/dist/blocks/e-commerce/account/account-frame.js.map +1 -0
  23. package/dist/blocks/e-commerce/account/account-frame.mjs +78 -0
  24. package/dist/blocks/e-commerce/account/account-frame.mjs.map +1 -0
  25. package/dist/blocks/e-commerce/account/address-book.d.ts +79 -0
  26. package/dist/blocks/e-commerce/account/address-book.d.ts.map +1 -0
  27. package/dist/blocks/e-commerce/account/address-book.js +250 -0
  28. package/dist/blocks/e-commerce/account/address-book.js.map +1 -0
  29. package/dist/blocks/e-commerce/account/address-book.mjs +225 -0
  30. package/dist/blocks/e-commerce/account/address-book.mjs.map +1 -0
  31. package/dist/blocks/e-commerce/account/profile-form.d.ts +35 -0
  32. package/dist/blocks/e-commerce/account/profile-form.d.ts.map +1 -0
  33. package/dist/blocks/e-commerce/account/profile-form.js +100 -0
  34. package/dist/blocks/e-commerce/account/profile-form.js.map +1 -0
  35. package/dist/blocks/e-commerce/account/profile-form.mjs +76 -0
  36. package/dist/blocks/e-commerce/account/profile-form.mjs.map +1 -0
  37. package/dist/index.d.ts +10 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +14 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/index.mjs +9 -0
  42. package/dist/index.mjs.map +1 -1
  43. package/dist/lib/contracts/checkout-commerce-v1.d.ts +2350 -0
  44. package/dist/lib/contracts/checkout-commerce-v1.d.ts.map +1 -0
  45. package/dist/lib/contracts/checkout-commerce-v1.js +417 -0
  46. package/dist/lib/contracts/checkout-commerce-v1.js.map +1 -0
  47. package/dist/lib/contracts/checkout-commerce-v1.mjs +392 -0
  48. package/dist/lib/contracts/checkout-commerce-v1.mjs.map +1 -0
  49. package/dist/lib/contracts.d.ts +515 -177
  50. package/dist/lib/contracts.d.ts.map +1 -1
  51. package/dist/lib/contracts.js +81 -1
  52. package/dist/lib/contracts.js.map +1 -1
  53. package/dist/lib/contracts.mjs +70 -0
  54. package/dist/lib/contracts.mjs.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/account/address-book.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { FormEvent } from 'react'\nimport { Badge } from '../../../ui/badge'\nimport { Button } from '../../../ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '../../../ui/card'\nimport { Field, FieldGroup, FieldLabel } from '../../../ui/field'\nimport { Input } from '../../../ui/input'\nimport { cn } from '../../../lib/utils'\n\n/** One address exactly as the host supplies it; the block formats no fields. */\nexport interface AccountAddress {\n id: string\n recipientName: string\n /** Address lines in display order (street, city, region, postal code, country). */\n lines: string[]\n isDefaultShipping?: boolean\n isDefaultBilling?: boolean\n}\n\nexport interface AddressBookLabels {\n title: string\n description: string\n emptyLabel: string\n addLabel: string\n editLabel: string\n deleteLabel: string\n confirmDeleteLabel: string\n cancelLabel: string\n defaultShippingLabel: string\n defaultBillingLabel: string\n setDefaultShippingLabel: string\n setDefaultBillingLabel: string\n}\n\nconst defaultLabels: AddressBookLabels = {\n title: 'Direcciones',\n description: 'Direcciones guardadas para tus pedidos.',\n emptyLabel: 'Aún no tienes direcciones guardadas.',\n addLabel: 'Añadir dirección',\n editLabel: 'Editar',\n deleteLabel: 'Eliminar',\n confirmDeleteLabel: '¿Eliminar esta dirección?',\n cancelLabel: 'Cancelar',\n defaultShippingLabel: 'Envío predeterminado',\n defaultBillingLabel: 'Facturación predeterminada',\n setDefaultShippingLabel: 'Usar para envío',\n setDefaultBillingLabel: 'Usar para facturación',\n}\n\nexport interface AddressBookProps {\n addresses: AccountAddress[]\n labels?: Partial<AddressBookLabels>\n onCreate?: () => void\n onEdit?: (id: string) => void\n onDelete?: (id: string) => void\n onSetDefaultShipping?: (id: string) => void\n onSetDefaultBilling?: (id: string) => void\n className?: string\n}\n\nfunction AddressEntry({\n address,\n copy,\n onEdit,\n onDelete,\n onSetDefaultShipping,\n onSetDefaultBilling,\n}: {\n address: AccountAddress\n copy: AddressBookLabels\n onEdit?: (id: string) => void\n onDelete?: (id: string) => void\n onSetDefaultShipping?: (id: string) => void\n onSetDefaultBilling?: (id: string) => void\n}) {\n const [confirming, setConfirming] = useState(false)\n const containerRef = useRef<HTMLLIElement | null>(null)\n\n return (\n <li\n ref={containerRef}\n tabIndex={-1}\n data-slot=\"address-book-entry\"\n className=\"focus-visible:ring-ring rounded-lg outline-none focus-visible:ring-2\"\n >\n <Card>\n <CardHeader className=\"flex flex-row items-start justify-between gap-4\">\n <div>\n <CardTitle className=\"text-base\">{address.recipientName}</CardTitle>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {address.isDefaultShipping ? (\n <Badge variant=\"secondary\">{copy.defaultShippingLabel}</Badge>\n ) : null}\n {address.isDefaultBilling ? (\n <Badge variant=\"outline\">{copy.defaultBillingLabel}</Badge>\n ) : null}\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <address className=\"text-muted-foreground text-sm not-italic\">\n {address.lines.map((line, index) => (\n <span key={`${address.id}:${index}`} className=\"block\">\n {line}\n </span>\n ))}\n </address>\n\n {confirming ? (\n <div className=\"mt-4 flex flex-wrap items-center gap-2\" role=\"group\" aria-label={copy.confirmDeleteLabel}>\n <span className=\"text-sm\">{copy.confirmDeleteLabel}</span>\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n onDelete?.(address.id)\n setConfirming(false)\n containerRef.current?.focus()\n }}\n >\n {copy.deleteLabel}\n </Button>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setConfirming(false)}>\n {copy.cancelLabel}\n </Button>\n </div>\n ) : (\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {onEdit ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => onEdit(address.id)}>\n {copy.editLabel}\n </Button>\n ) : null}\n {onDelete ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setConfirming(true)}>\n {copy.deleteLabel}\n </Button>\n ) : null}\n {onSetDefaultShipping && !address.isDefaultShipping ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onSetDefaultShipping(address.id)}\n >\n {copy.setDefaultShippingLabel}\n </Button>\n ) : null}\n {onSetDefaultBilling && !address.isDefaultBilling ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onSetDefaultBilling(address.id)}\n >\n {copy.setDefaultBillingLabel}\n </Button>\n ) : null}\n </div>\n )}\n </CardContent>\n </Card>\n </li>\n )\n}\n\n/**\n * The address book: renders the host's addresses verbatim, in the supplied\n * order, and reports every action. Deletion is a two-step inline confirmation\n * and the entry stays until the host supplies a refreshed list — the block never\n * removes it optimistically.\n */\nexport function AddressBook({\n addresses,\n labels,\n onCreate,\n onEdit,\n onDelete,\n onSetDefaultShipping,\n onSetDefaultBilling,\n className,\n}: AddressBookProps) {\n const copy = { ...defaultLabels, ...labels }\n return (\n <section className={cn('rounded-lg border p-6', className)}>\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <h2 className=\"text-lg font-semibold\">{copy.title}</h2>\n <p className=\"text-muted-foreground mt-1 text-sm\">{copy.description}</p>\n </div>\n {onCreate ? (\n <Button type=\"button\" onClick={onCreate}>\n {copy.addLabel}\n </Button>\n ) : null}\n </div>\n\n {addresses.length === 0 ? (\n <p className=\"text-muted-foreground mt-6 text-sm\" data-slot=\"address-book-empty\">\n {copy.emptyLabel}\n </p>\n ) : (\n <ul className=\"mt-6 grid list-none grid-cols-1 gap-4 p-0 md:grid-cols-2\">\n {addresses.map((address) => (\n <AddressEntry\n key={address.id}\n address={address}\n copy={copy}\n onEdit={onEdit}\n onDelete={onDelete}\n onSetDefaultShipping={onSetDefaultShipping}\n onSetDefaultBilling={onSetDefaultBilling}\n />\n ))}\n </ul>\n )}\n </section>\n )\n}\n\n/** One field of the address form, declared by the host. */\nexport interface AddressFormField {\n name: string\n label: string\n value?: string\n type?: 'text' | 'tel' | 'email' | 'select'\n required?: boolean\n autoComplete?: string\n /** Required for `select`; a select without options is not rendered. */\n options?: { value: string; label: string }[]\n}\n\nexport interface AddressFormLabels {\n title: string\n submit: string\n saving: string\n cancel: string\n requiredError: string\n}\n\nconst defaultFormLabels: AddressFormLabels = {\n title: 'Dirección',\n submit: 'Guardar dirección',\n saving: 'Guardando…',\n cancel: 'Cancelar',\n requiredError: 'Este campo es obligatorio.',\n}\n\nexport interface AddressFormProps {\n fields: AddressFormField[]\n labels?: Partial<AddressFormLabels>\n pending?: boolean\n error?: string | null\n /** Host-supplied field errors, keyed by field name. */\n fieldErrors?: Record<string, string>\n onSubmit: (values: Record<string, string>) => void\n onCancel?: () => void\n className?: string\n}\n\n/**\n * The address editor. It validates only the constraints the host declares (a\n * required field), never invents country or postal rules, and omits a select\n * the host supplied without options.\n */\nexport function AddressForm({\n fields,\n labels,\n pending = false,\n error,\n fieldErrors,\n onSubmit,\n onCancel,\n className,\n}: AddressFormProps) {\n const copy = { ...defaultFormLabels, ...labels }\n const visibleFields = fields.filter(\n (field) => field.type !== 'select' || (Array.isArray(field.options) && field.options.length > 0),\n )\n const signature = visibleFields.map((field) => `${field.name}:${field.value ?? ''}`).join('|')\n const [values, setValues] = useState<Record<string, string>>(() =>\n Object.fromEntries(visibleFields.map((field) => [field.name, field.value ?? ''])),\n )\n const [localErrors, setLocalErrors] = useState<Record<string, string>>({})\n\n // Re-seed when the host supplies new values (e.g. opening a different address).\n useEffect(() => {\n setValues(Object.fromEntries(visibleFields.map((field) => [field.name, field.value ?? ''])))\n setLocalErrors({})\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature])\n\n const submit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const nextErrors: Record<string, string> = {}\n for (const field of visibleFields) {\n if (field.required && (values[field.name] ?? '').trim() === '') {\n nextErrors[field.name] = copy.requiredError\n }\n }\n setLocalErrors(nextErrors)\n if (Object.keys(nextErrors).length > 0) return\n onSubmit(Object.fromEntries(visibleFields.map((field) => [field.name, values[field.name] ?? ''])))\n }\n\n return (\n <section className={cn('rounded-lg border p-6', className)}>\n <h2 className=\"text-lg font-semibold\">{copy.title}</h2>\n <form className=\"mt-6\" noValidate onSubmit={submit}>\n <fieldset disabled={pending} aria-busy={pending} className=\"contents\">\n <FieldGroup className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {visibleFields.map((field) => {\n const id = `address-${field.name}`\n const message = localErrors[field.name] ?? fieldErrors?.[field.name]\n return (\n <Field key={field.name}>\n <FieldLabel htmlFor={id}>{field.label}</FieldLabel>\n {field.type === 'select' ? (\n <select\n id={id}\n name={field.name}\n value={values[field.name] ?? ''}\n required={field.required}\n aria-invalid={message ? true : undefined}\n aria-describedby={message ? `${id}-error` : undefined}\n className=\"border-input bg-background h-9 w-full rounded-md border px-3 text-sm\"\n onChange={(event) =>\n setValues((current) => ({ ...current, [field.name]: event.target.value }))\n }\n >\n <option value=\"\">—</option>\n {(field.options ?? []).map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n ) : (\n <Input\n id={id}\n name={field.name}\n type={field.type ?? 'text'}\n value={values[field.name] ?? ''}\n required={field.required}\n autoComplete={field.autoComplete}\n aria-invalid={message ? true : undefined}\n aria-describedby={message ? `${id}-error` : undefined}\n onChange={(event) =>\n setValues((current) => ({ ...current, [field.name]: event.target.value }))\n }\n />\n )}\n {message ? (\n <p id={`${id}-error`} className=\"text-destructive text-sm\">\n {message}\n </p>\n ) : null}\n </Field>\n )\n })}\n </FieldGroup>\n </fieldset>\n\n {error ? (\n <p role=\"alert\" className=\"text-destructive mt-4 text-sm\">\n {error}\n </p>\n ) : null}\n\n <div className=\"mt-6 flex flex-wrap gap-2\">\n <Button type=\"submit\" disabled={pending}>\n {pending ? copy.saving : copy.submit}\n </Button>\n {onCancel ? (\n <Button type=\"button\" variant=\"outline\" disabled={pending} onClick={onCancel}>\n {copy.cancel}\n </Button>\n ) : null}\n </div>\n </form>\n </section>\n )\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,225 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { Badge } from "../../../ui/badge.mjs";
5
+ import { Button } from "../../../ui/button.mjs";
6
+ import { Card, CardContent, CardHeader, CardTitle } from "../../../ui/card.mjs";
7
+ import { Field, FieldGroup, FieldLabel } from "../../../ui/field.mjs";
8
+ import { Input } from "../../../ui/input.mjs";
9
+ import { cn } from "../../../lib/utils.mjs";
10
+ const defaultLabels = {
11
+ title: "Direcciones",
12
+ description: "Direcciones guardadas para tus pedidos.",
13
+ emptyLabel: "A\xFAn no tienes direcciones guardadas.",
14
+ addLabel: "A\xF1adir direcci\xF3n",
15
+ editLabel: "Editar",
16
+ deleteLabel: "Eliminar",
17
+ confirmDeleteLabel: "\xBFEliminar esta direcci\xF3n?",
18
+ cancelLabel: "Cancelar",
19
+ defaultShippingLabel: "Env\xEDo predeterminado",
20
+ defaultBillingLabel: "Facturaci\xF3n predeterminada",
21
+ setDefaultShippingLabel: "Usar para env\xEDo",
22
+ setDefaultBillingLabel: "Usar para facturaci\xF3n"
23
+ };
24
+ function AddressEntry({
25
+ address,
26
+ copy,
27
+ onEdit,
28
+ onDelete,
29
+ onSetDefaultShipping,
30
+ onSetDefaultBilling
31
+ }) {
32
+ const [confirming, setConfirming] = useState(false);
33
+ const containerRef = useRef(null);
34
+ return /* @__PURE__ */ jsx(
35
+ "li",
36
+ {
37
+ ref: containerRef,
38
+ tabIndex: -1,
39
+ "data-slot": "address-book-entry",
40
+ className: "focus-visible:ring-ring rounded-lg outline-none focus-visible:ring-2",
41
+ children: /* @__PURE__ */ jsxs(Card, { children: [
42
+ /* @__PURE__ */ jsx(CardHeader, { className: "flex flex-row items-start justify-between gap-4", children: /* @__PURE__ */ jsxs("div", { children: [
43
+ /* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: address.recipientName }),
44
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap gap-2", children: [
45
+ address.isDefaultShipping ? /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: copy.defaultShippingLabel }) : null,
46
+ address.isDefaultBilling ? /* @__PURE__ */ jsx(Badge, { variant: "outline", children: copy.defaultBillingLabel }) : null
47
+ ] })
48
+ ] }) }),
49
+ /* @__PURE__ */ jsxs(CardContent, { children: [
50
+ /* @__PURE__ */ jsx("address", { className: "text-muted-foreground text-sm not-italic", children: address.lines.map((line, index) => /* @__PURE__ */ jsx("span", { className: "block", children: line }, `${address.id}:${index}`)) }),
51
+ confirming ? /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-2", role: "group", "aria-label": copy.confirmDeleteLabel, children: [
52
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: copy.confirmDeleteLabel }),
53
+ /* @__PURE__ */ jsx(
54
+ Button,
55
+ {
56
+ type: "button",
57
+ variant: "destructive",
58
+ size: "sm",
59
+ onClick: () => {
60
+ onDelete?.(address.id);
61
+ setConfirming(false);
62
+ containerRef.current?.focus();
63
+ },
64
+ children: copy.deleteLabel
65
+ }
66
+ ),
67
+ /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setConfirming(false), children: copy.cancelLabel })
68
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-wrap gap-2", children: [
69
+ onEdit ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onEdit(address.id), children: copy.editLabel }) : null,
70
+ onDelete ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setConfirming(true), children: copy.deleteLabel }) : null,
71
+ onSetDefaultShipping && !address.isDefaultShipping ? /* @__PURE__ */ jsx(
72
+ Button,
73
+ {
74
+ type: "button",
75
+ variant: "ghost",
76
+ size: "sm",
77
+ onClick: () => onSetDefaultShipping(address.id),
78
+ children: copy.setDefaultShippingLabel
79
+ }
80
+ ) : null,
81
+ onSetDefaultBilling && !address.isDefaultBilling ? /* @__PURE__ */ jsx(
82
+ Button,
83
+ {
84
+ type: "button",
85
+ variant: "ghost",
86
+ size: "sm",
87
+ onClick: () => onSetDefaultBilling(address.id),
88
+ children: copy.setDefaultBillingLabel
89
+ }
90
+ ) : null
91
+ ] })
92
+ ] })
93
+ ] })
94
+ }
95
+ );
96
+ }
97
+ function AddressBook({
98
+ addresses,
99
+ labels,
100
+ onCreate,
101
+ onEdit,
102
+ onDelete,
103
+ onSetDefaultShipping,
104
+ onSetDefaultBilling,
105
+ className
106
+ }) {
107
+ const copy = { ...defaultLabels, ...labels };
108
+ return /* @__PURE__ */ jsxs("section", { className: cn("rounded-lg border p-6", className), children: [
109
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-4", children: [
110
+ /* @__PURE__ */ jsxs("div", { children: [
111
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: copy.title }),
112
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: copy.description })
113
+ ] }),
114
+ onCreate ? /* @__PURE__ */ jsx(Button, { type: "button", onClick: onCreate, children: copy.addLabel }) : null
115
+ ] }),
116
+ addresses.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-6 text-sm", "data-slot": "address-book-empty", children: copy.emptyLabel }) : /* @__PURE__ */ jsx("ul", { className: "mt-6 grid list-none grid-cols-1 gap-4 p-0 md:grid-cols-2", children: addresses.map((address) => /* @__PURE__ */ jsx(
117
+ AddressEntry,
118
+ {
119
+ address,
120
+ copy,
121
+ onEdit,
122
+ onDelete,
123
+ onSetDefaultShipping,
124
+ onSetDefaultBilling
125
+ },
126
+ address.id
127
+ )) })
128
+ ] });
129
+ }
130
+ const defaultFormLabels = {
131
+ title: "Direcci\xF3n",
132
+ submit: "Guardar direcci\xF3n",
133
+ saving: "Guardando\u2026",
134
+ cancel: "Cancelar",
135
+ requiredError: "Este campo es obligatorio."
136
+ };
137
+ function AddressForm({
138
+ fields,
139
+ labels,
140
+ pending = false,
141
+ error,
142
+ fieldErrors,
143
+ onSubmit,
144
+ onCancel,
145
+ className
146
+ }) {
147
+ const copy = { ...defaultFormLabels, ...labels };
148
+ const visibleFields = fields.filter(
149
+ (field) => field.type !== "select" || Array.isArray(field.options) && field.options.length > 0
150
+ );
151
+ const signature = visibleFields.map((field) => `${field.name}:${field.value ?? ""}`).join("|");
152
+ const [values, setValues] = useState(
153
+ () => Object.fromEntries(visibleFields.map((field) => [field.name, field.value ?? ""]))
154
+ );
155
+ const [localErrors, setLocalErrors] = useState({});
156
+ useEffect(() => {
157
+ setValues(Object.fromEntries(visibleFields.map((field) => [field.name, field.value ?? ""])));
158
+ setLocalErrors({});
159
+ }, [signature]);
160
+ const submit = (event) => {
161
+ event.preventDefault();
162
+ const nextErrors = {};
163
+ for (const field of visibleFields) {
164
+ if (field.required && (values[field.name] ?? "").trim() === "") {
165
+ nextErrors[field.name] = copy.requiredError;
166
+ }
167
+ }
168
+ setLocalErrors(nextErrors);
169
+ if (Object.keys(nextErrors).length > 0) return;
170
+ onSubmit(Object.fromEntries(visibleFields.map((field) => [field.name, values[field.name] ?? ""])));
171
+ };
172
+ return /* @__PURE__ */ jsxs("section", { className: cn("rounded-lg border p-6", className), children: [
173
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: copy.title }),
174
+ /* @__PURE__ */ jsxs("form", { className: "mt-6", noValidate: true, onSubmit: submit, children: [
175
+ /* @__PURE__ */ jsx("fieldset", { disabled: pending, "aria-busy": pending, className: "contents", children: /* @__PURE__ */ jsx(FieldGroup, { className: "grid grid-cols-1 gap-5 sm:grid-cols-2", children: visibleFields.map((field) => {
176
+ const id = `address-${field.name}`;
177
+ const message = localErrors[field.name] ?? fieldErrors?.[field.name];
178
+ return /* @__PURE__ */ jsxs(Field, { children: [
179
+ /* @__PURE__ */ jsx(FieldLabel, { htmlFor: id, children: field.label }),
180
+ field.type === "select" ? /* @__PURE__ */ jsxs(
181
+ "select",
182
+ {
183
+ id,
184
+ name: field.name,
185
+ value: values[field.name] ?? "",
186
+ required: field.required,
187
+ "aria-invalid": message ? true : void 0,
188
+ "aria-describedby": message ? `${id}-error` : void 0,
189
+ className: "border-input bg-background h-9 w-full rounded-md border px-3 text-sm",
190
+ onChange: (event) => setValues((current) => ({ ...current, [field.name]: event.target.value })),
191
+ children: [
192
+ /* @__PURE__ */ jsx("option", { value: "", children: "\u2014" }),
193
+ (field.options ?? []).map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
194
+ ]
195
+ }
196
+ ) : /* @__PURE__ */ jsx(
197
+ Input,
198
+ {
199
+ id,
200
+ name: field.name,
201
+ type: field.type ?? "text",
202
+ value: values[field.name] ?? "",
203
+ required: field.required,
204
+ autoComplete: field.autoComplete,
205
+ "aria-invalid": message ? true : void 0,
206
+ "aria-describedby": message ? `${id}-error` : void 0,
207
+ onChange: (event) => setValues((current) => ({ ...current, [field.name]: event.target.value }))
208
+ }
209
+ ),
210
+ message ? /* @__PURE__ */ jsx("p", { id: `${id}-error`, className: "text-destructive text-sm", children: message }) : null
211
+ ] }, field.name);
212
+ }) }) }),
213
+ error ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-destructive mt-4 text-sm", children: error }) : null,
214
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 flex flex-wrap gap-2", children: [
215
+ /* @__PURE__ */ jsx(Button, { type: "submit", disabled: pending, children: pending ? copy.saving : copy.submit }),
216
+ onCancel ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", disabled: pending, onClick: onCancel, children: copy.cancel }) : null
217
+ ] })
218
+ ] })
219
+ ] });
220
+ }
221
+ export {
222
+ AddressBook,
223
+ AddressForm
224
+ };
225
+ //# sourceMappingURL=address-book.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/account/address-book.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useRef, useState } from 'react'\nimport type { FormEvent } from 'react'\nimport { Badge } from '../../../ui/badge'\nimport { Button } from '../../../ui/button'\nimport { Card, CardContent, CardHeader, CardTitle } from '../../../ui/card'\nimport { Field, FieldGroup, FieldLabel } from '../../../ui/field'\nimport { Input } from '../../../ui/input'\nimport { cn } from '../../../lib/utils'\n\n/** One address exactly as the host supplies it; the block formats no fields. */\nexport interface AccountAddress {\n id: string\n recipientName: string\n /** Address lines in display order (street, city, region, postal code, country). */\n lines: string[]\n isDefaultShipping?: boolean\n isDefaultBilling?: boolean\n}\n\nexport interface AddressBookLabels {\n title: string\n description: string\n emptyLabel: string\n addLabel: string\n editLabel: string\n deleteLabel: string\n confirmDeleteLabel: string\n cancelLabel: string\n defaultShippingLabel: string\n defaultBillingLabel: string\n setDefaultShippingLabel: string\n setDefaultBillingLabel: string\n}\n\nconst defaultLabels: AddressBookLabels = {\n title: 'Direcciones',\n description: 'Direcciones guardadas para tus pedidos.',\n emptyLabel: 'Aún no tienes direcciones guardadas.',\n addLabel: 'Añadir dirección',\n editLabel: 'Editar',\n deleteLabel: 'Eliminar',\n confirmDeleteLabel: '¿Eliminar esta dirección?',\n cancelLabel: 'Cancelar',\n defaultShippingLabel: 'Envío predeterminado',\n defaultBillingLabel: 'Facturación predeterminada',\n setDefaultShippingLabel: 'Usar para envío',\n setDefaultBillingLabel: 'Usar para facturación',\n}\n\nexport interface AddressBookProps {\n addresses: AccountAddress[]\n labels?: Partial<AddressBookLabels>\n onCreate?: () => void\n onEdit?: (id: string) => void\n onDelete?: (id: string) => void\n onSetDefaultShipping?: (id: string) => void\n onSetDefaultBilling?: (id: string) => void\n className?: string\n}\n\nfunction AddressEntry({\n address,\n copy,\n onEdit,\n onDelete,\n onSetDefaultShipping,\n onSetDefaultBilling,\n}: {\n address: AccountAddress\n copy: AddressBookLabels\n onEdit?: (id: string) => void\n onDelete?: (id: string) => void\n onSetDefaultShipping?: (id: string) => void\n onSetDefaultBilling?: (id: string) => void\n}) {\n const [confirming, setConfirming] = useState(false)\n const containerRef = useRef<HTMLLIElement | null>(null)\n\n return (\n <li\n ref={containerRef}\n tabIndex={-1}\n data-slot=\"address-book-entry\"\n className=\"focus-visible:ring-ring rounded-lg outline-none focus-visible:ring-2\"\n >\n <Card>\n <CardHeader className=\"flex flex-row items-start justify-between gap-4\">\n <div>\n <CardTitle className=\"text-base\">{address.recipientName}</CardTitle>\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {address.isDefaultShipping ? (\n <Badge variant=\"secondary\">{copy.defaultShippingLabel}</Badge>\n ) : null}\n {address.isDefaultBilling ? (\n <Badge variant=\"outline\">{copy.defaultBillingLabel}</Badge>\n ) : null}\n </div>\n </div>\n </CardHeader>\n <CardContent>\n <address className=\"text-muted-foreground text-sm not-italic\">\n {address.lines.map((line, index) => (\n <span key={`${address.id}:${index}`} className=\"block\">\n {line}\n </span>\n ))}\n </address>\n\n {confirming ? (\n <div className=\"mt-4 flex flex-wrap items-center gap-2\" role=\"group\" aria-label={copy.confirmDeleteLabel}>\n <span className=\"text-sm\">{copy.confirmDeleteLabel}</span>\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => {\n onDelete?.(address.id)\n setConfirming(false)\n containerRef.current?.focus()\n }}\n >\n {copy.deleteLabel}\n </Button>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setConfirming(false)}>\n {copy.cancelLabel}\n </Button>\n </div>\n ) : (\n <div className=\"mt-4 flex flex-wrap gap-2\">\n {onEdit ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => onEdit(address.id)}>\n {copy.editLabel}\n </Button>\n ) : null}\n {onDelete ? (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => setConfirming(true)}>\n {copy.deleteLabel}\n </Button>\n ) : null}\n {onSetDefaultShipping && !address.isDefaultShipping ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onSetDefaultShipping(address.id)}\n >\n {copy.setDefaultShippingLabel}\n </Button>\n ) : null}\n {onSetDefaultBilling && !address.isDefaultBilling ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onSetDefaultBilling(address.id)}\n >\n {copy.setDefaultBillingLabel}\n </Button>\n ) : null}\n </div>\n )}\n </CardContent>\n </Card>\n </li>\n )\n}\n\n/**\n * The address book: renders the host's addresses verbatim, in the supplied\n * order, and reports every action. Deletion is a two-step inline confirmation\n * and the entry stays until the host supplies a refreshed list — the block never\n * removes it optimistically.\n */\nexport function AddressBook({\n addresses,\n labels,\n onCreate,\n onEdit,\n onDelete,\n onSetDefaultShipping,\n onSetDefaultBilling,\n className,\n}: AddressBookProps) {\n const copy = { ...defaultLabels, ...labels }\n return (\n <section className={cn('rounded-lg border p-6', className)}>\n <div className=\"flex flex-wrap items-start justify-between gap-4\">\n <div>\n <h2 className=\"text-lg font-semibold\">{copy.title}</h2>\n <p className=\"text-muted-foreground mt-1 text-sm\">{copy.description}</p>\n </div>\n {onCreate ? (\n <Button type=\"button\" onClick={onCreate}>\n {copy.addLabel}\n </Button>\n ) : null}\n </div>\n\n {addresses.length === 0 ? (\n <p className=\"text-muted-foreground mt-6 text-sm\" data-slot=\"address-book-empty\">\n {copy.emptyLabel}\n </p>\n ) : (\n <ul className=\"mt-6 grid list-none grid-cols-1 gap-4 p-0 md:grid-cols-2\">\n {addresses.map((address) => (\n <AddressEntry\n key={address.id}\n address={address}\n copy={copy}\n onEdit={onEdit}\n onDelete={onDelete}\n onSetDefaultShipping={onSetDefaultShipping}\n onSetDefaultBilling={onSetDefaultBilling}\n />\n ))}\n </ul>\n )}\n </section>\n )\n}\n\n/** One field of the address form, declared by the host. */\nexport interface AddressFormField {\n name: string\n label: string\n value?: string\n type?: 'text' | 'tel' | 'email' | 'select'\n required?: boolean\n autoComplete?: string\n /** Required for `select`; a select without options is not rendered. */\n options?: { value: string; label: string }[]\n}\n\nexport interface AddressFormLabels {\n title: string\n submit: string\n saving: string\n cancel: string\n requiredError: string\n}\n\nconst defaultFormLabels: AddressFormLabels = {\n title: 'Dirección',\n submit: 'Guardar dirección',\n saving: 'Guardando…',\n cancel: 'Cancelar',\n requiredError: 'Este campo es obligatorio.',\n}\n\nexport interface AddressFormProps {\n fields: AddressFormField[]\n labels?: Partial<AddressFormLabels>\n pending?: boolean\n error?: string | null\n /** Host-supplied field errors, keyed by field name. */\n fieldErrors?: Record<string, string>\n onSubmit: (values: Record<string, string>) => void\n onCancel?: () => void\n className?: string\n}\n\n/**\n * The address editor. It validates only the constraints the host declares (a\n * required field), never invents country or postal rules, and omits a select\n * the host supplied without options.\n */\nexport function AddressForm({\n fields,\n labels,\n pending = false,\n error,\n fieldErrors,\n onSubmit,\n onCancel,\n className,\n}: AddressFormProps) {\n const copy = { ...defaultFormLabels, ...labels }\n const visibleFields = fields.filter(\n (field) => field.type !== 'select' || (Array.isArray(field.options) && field.options.length > 0),\n )\n const signature = visibleFields.map((field) => `${field.name}:${field.value ?? ''}`).join('|')\n const [values, setValues] = useState<Record<string, string>>(() =>\n Object.fromEntries(visibleFields.map((field) => [field.name, field.value ?? ''])),\n )\n const [localErrors, setLocalErrors] = useState<Record<string, string>>({})\n\n // Re-seed when the host supplies new values (e.g. opening a different address).\n useEffect(() => {\n setValues(Object.fromEntries(visibleFields.map((field) => [field.name, field.value ?? ''])))\n setLocalErrors({})\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [signature])\n\n const submit = (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n const nextErrors: Record<string, string> = {}\n for (const field of visibleFields) {\n if (field.required && (values[field.name] ?? '').trim() === '') {\n nextErrors[field.name] = copy.requiredError\n }\n }\n setLocalErrors(nextErrors)\n if (Object.keys(nextErrors).length > 0) return\n onSubmit(Object.fromEntries(visibleFields.map((field) => [field.name, values[field.name] ?? ''])))\n }\n\n return (\n <section className={cn('rounded-lg border p-6', className)}>\n <h2 className=\"text-lg font-semibold\">{copy.title}</h2>\n <form className=\"mt-6\" noValidate onSubmit={submit}>\n <fieldset disabled={pending} aria-busy={pending} className=\"contents\">\n <FieldGroup className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {visibleFields.map((field) => {\n const id = `address-${field.name}`\n const message = localErrors[field.name] ?? fieldErrors?.[field.name]\n return (\n <Field key={field.name}>\n <FieldLabel htmlFor={id}>{field.label}</FieldLabel>\n {field.type === 'select' ? (\n <select\n id={id}\n name={field.name}\n value={values[field.name] ?? ''}\n required={field.required}\n aria-invalid={message ? true : undefined}\n aria-describedby={message ? `${id}-error` : undefined}\n className=\"border-input bg-background h-9 w-full rounded-md border px-3 text-sm\"\n onChange={(event) =>\n setValues((current) => ({ ...current, [field.name]: event.target.value }))\n }\n >\n <option value=\"\">—</option>\n {(field.options ?? []).map((option) => (\n <option key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n ) : (\n <Input\n id={id}\n name={field.name}\n type={field.type ?? 'text'}\n value={values[field.name] ?? ''}\n required={field.required}\n autoComplete={field.autoComplete}\n aria-invalid={message ? true : undefined}\n aria-describedby={message ? `${id}-error` : undefined}\n onChange={(event) =>\n setValues((current) => ({ ...current, [field.name]: event.target.value }))\n }\n />\n )}\n {message ? (\n <p id={`${id}-error`} className=\"text-destructive text-sm\">\n {message}\n </p>\n ) : null}\n </Field>\n )\n })}\n </FieldGroup>\n </fieldset>\n\n {error ? (\n <p role=\"alert\" className=\"text-destructive mt-4 text-sm\">\n {error}\n </p>\n ) : null}\n\n <div className=\"mt-6 flex flex-wrap gap-2\">\n <Button type=\"submit\" disabled={pending}>\n {pending ? copy.saving : copy.submit}\n </Button>\n {onCancel ? (\n <Button type=\"button\" variant=\"outline\" disabled={pending} onClick={onCancel}>\n {copy.cancel}\n </Button>\n ) : null}\n </div>\n </form>\n </section>\n )\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,35 @@
1
+ /** One editable (or read-only) profile field the host declares. */
2
+ export interface ProfileField {
3
+ name: string;
4
+ label: string;
5
+ value?: string;
6
+ type?: 'text' | 'tel' | 'email';
7
+ required?: boolean;
8
+ /** Rendered as read-only; a field the host omits is absent entirely. */
9
+ readOnly?: boolean;
10
+ autoComplete?: string;
11
+ }
12
+ export interface ProfileFormLabels {
13
+ title: string;
14
+ description: string;
15
+ submit: string;
16
+ saving: string;
17
+ }
18
+ export interface ProfileFormProps {
19
+ /** Exactly the fields the host declares, in order. */
20
+ fields: ProfileField[];
21
+ labels?: Partial<ProfileFormLabels>;
22
+ /** Host-owned mutation state; the form never claims success on its own. */
23
+ pending?: boolean;
24
+ error?: string | null;
25
+ onSubmit: (values: Record<string, string>) => void;
26
+ className?: string;
27
+ }
28
+ /**
29
+ * The profile editor. It renders only host-declared fields, keeps the entered
30
+ * values while a save is pending or fails, and reports the values to the host —
31
+ * it never calls a backend and never invents a field (an email change, for
32
+ * example, is absent when the host does not declare it).
33
+ */
34
+ export declare function ProfileForm({ fields, labels, pending, error, onSubmit, className, }: ProfileFormProps): import("react").JSX.Element;
35
+ //# sourceMappingURL=profile-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-form.d.ts","sourceRoot":"","sources":["../../../../src/blocks/e-commerce/account/profile-form.tsx"],"names":[],"mappings":"AAQA,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAA;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AASD,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACnC,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAA;IAClD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,MAAM,EACN,OAAe,EACf,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE,gBAAgB,+BAoElB"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var profile_form_exports = {};
21
+ __export(profile_form_exports, {
22
+ ProfileForm: () => ProfileForm
23
+ });
24
+ module.exports = __toCommonJS(profile_form_exports);
25
+ var import_jsx_runtime = require("react/jsx-runtime");
26
+ var import_react = require("react");
27
+ var import_button = require("../../../ui/button.js");
28
+ var import_field = require("../../../ui/field.js");
29
+ var import_input = require("../../../ui/input.js");
30
+ var import_utils = require("../../../lib/utils.js");
31
+ const defaultLabels = {
32
+ title: "Datos personales",
33
+ description: "Actualiza los datos de tu cuenta.",
34
+ submit: "Guardar cambios",
35
+ saving: "Guardando\u2026"
36
+ };
37
+ function ProfileForm({
38
+ fields,
39
+ labels,
40
+ pending = false,
41
+ error,
42
+ onSubmit,
43
+ className
44
+ }) {
45
+ const copy = { ...defaultLabels, ...labels };
46
+ const signature = fields.map((field) => `${field.name}:${field.value ?? ""}`).join("|");
47
+ const [values, setValues] = (0, import_react.useState)(
48
+ () => Object.fromEntries(fields.map((field) => [field.name, field.value ?? ""]))
49
+ );
50
+ (0, import_react.useEffect)(() => {
51
+ setValues(Object.fromEntries(fields.map((field) => [field.name, field.value ?? ""])));
52
+ }, [signature]);
53
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: (0, import_utils.cn)("rounded-lg border p-6", className), children: [
54
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-lg font-semibold", children: copy.title }),
55
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-muted-foreground mt-1 text-sm", children: copy.description }),
56
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
57
+ "form",
58
+ {
59
+ className: "mt-6",
60
+ noValidate: true,
61
+ onSubmit: (event) => {
62
+ event.preventDefault();
63
+ const submitted = Object.fromEntries(
64
+ fields.map((field) => [field.name, values[field.name] ?? ""])
65
+ );
66
+ onSubmit(submitted);
67
+ },
68
+ children: [
69
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("fieldset", { disabled: pending, "aria-busy": pending, className: "contents", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldGroup, { className: "grid grid-cols-1 gap-5 sm:grid-cols-2", children: fields.map((field) => {
70
+ const id = `profile-${field.name}`;
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_field.Field, { children: [
72
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_field.FieldLabel, { htmlFor: id, children: field.label }),
73
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
74
+ import_input.Input,
75
+ {
76
+ id,
77
+ name: field.name,
78
+ type: field.type ?? "text",
79
+ value: values[field.name] ?? "",
80
+ readOnly: field.readOnly,
81
+ required: field.required,
82
+ autoComplete: field.autoComplete,
83
+ "aria-readonly": field.readOnly || void 0,
84
+ onChange: (event) => setValues((current) => ({ ...current, [field.name]: event.target.value }))
85
+ }
86
+ )
87
+ ] }, field.name);
88
+ }) }) }),
89
+ error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { role: "alert", className: "text-destructive mt-4 text-sm", children: error }) : null,
90
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { type: "submit", className: "mt-6", disabled: pending, children: pending ? copy.saving : copy.submit })
91
+ ]
92
+ }
93
+ )
94
+ ] });
95
+ }
96
+ // Annotate the CommonJS export names for ESM import in node:
97
+ 0 && (module.exports = {
98
+ ProfileForm
99
+ });
100
+ //# sourceMappingURL=profile-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/account/profile-form.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport { Button } from '../../../ui/button'\nimport { Field, FieldGroup, FieldLabel } from '../../../ui/field'\nimport { Input } from '../../../ui/input'\nimport { cn } from '../../../lib/utils'\n\n/** One editable (or read-only) profile field the host declares. */\nexport interface ProfileField {\n name: string\n label: string\n value?: string\n type?: 'text' | 'tel' | 'email'\n required?: boolean\n /** Rendered as read-only; a field the host omits is absent entirely. */\n readOnly?: boolean\n autoComplete?: string\n}\n\nexport interface ProfileFormLabels {\n title: string\n description: string\n submit: string\n saving: string\n}\n\nconst defaultLabels: ProfileFormLabels = {\n title: 'Datos personales',\n description: 'Actualiza los datos de tu cuenta.',\n submit: 'Guardar cambios',\n saving: 'Guardando…',\n}\n\nexport interface ProfileFormProps {\n /** Exactly the fields the host declares, in order. */\n fields: ProfileField[]\n labels?: Partial<ProfileFormLabels>\n /** Host-owned mutation state; the form never claims success on its own. */\n pending?: boolean\n error?: string | null\n onSubmit: (values: Record<string, string>) => void\n className?: string\n}\n\n/**\n * The profile editor. It renders only host-declared fields, keeps the entered\n * values while a save is pending or fails, and reports the values to the host —\n * it never calls a backend and never invents a field (an email change, for\n * example, is absent when the host does not declare it).\n */\nexport function ProfileForm({\n fields,\n labels,\n pending = false,\n error,\n onSubmit,\n className,\n}: ProfileFormProps) {\n const copy = { ...defaultLabels, ...labels }\n const signature = fields.map((field) => `${field.name}:${field.value ?? ''}`).join('|')\n const [values, setValues] = useState<Record<string, string>>(() =>\n Object.fromEntries(fields.map((field) => [field.name, field.value ?? ''])),\n )\n\n // Re-seed when the host supplies new default values (for example after a\n // successful save). The signature covers field identity and values, so a\n // pending/error prop change never clears what the shopper typed.\n useEffect(() => {\n setValues(Object.fromEntries(fields.map((field) => [field.name, field.value ?? ''])))\n }, [signature])\n\n return (\n <section className={cn('rounded-lg border p-6', className)}>\n <h2 className=\"text-lg font-semibold\">{copy.title}</h2>\n <p className=\"text-muted-foreground mt-1 text-sm\">{copy.description}</p>\n\n <form\n className=\"mt-6\"\n noValidate\n onSubmit={(event) => {\n event.preventDefault()\n const submitted = Object.fromEntries(\n fields.map((field) => [field.name, values[field.name] ?? '']),\n )\n onSubmit(submitted)\n }}\n >\n <fieldset disabled={pending} aria-busy={pending} className=\"contents\">\n <FieldGroup className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {fields.map((field) => {\n const id = `profile-${field.name}`\n return (\n <Field key={field.name}>\n <FieldLabel htmlFor={id}>{field.label}</FieldLabel>\n <Input\n id={id}\n name={field.name}\n type={field.type ?? 'text'}\n value={values[field.name] ?? ''}\n readOnly={field.readOnly}\n required={field.required}\n autoComplete={field.autoComplete}\n aria-readonly={field.readOnly || undefined}\n onChange={(event) =>\n setValues((current) => ({ ...current, [field.name]: event.target.value }))\n }\n />\n </Field>\n )\n })}\n </FieldGroup>\n </fieldset>\n\n {error ? (\n <p role=\"alert\" className=\"text-destructive mt-4 text-sm\">\n {error}\n </p>\n ) : null}\n\n <Button type=\"submit\" className=\"mt-6\" disabled={pending}>\n {pending ? copy.saving : copy.submit}\n </Button>\n </form>\n </section>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA0EM;AAxEN,mBAAoC;AACpC,oBAAuB;AACvB,mBAA8C;AAC9C,mBAAsB;AACtB,mBAAmB;AAqBnB,MAAM,gBAAmC;AAAA,EACvC,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,QAAQ;AACV;AAmBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,OAAO,EAAE,GAAG,eAAe,GAAG,OAAO;AAC3C,QAAM,YAAY,OAAO,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,IAAI,MAAM,SAAS,EAAE,EAAE,EAAE,KAAK,GAAG;AACtF,QAAM,CAAC,QAAQ,SAAS,QAAI;AAAA,IAAiC,MAC3D,OAAO,YAAY,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;AAAA,EAC3E;AAKA,8BAAU,MAAM;AACd,cAAU,OAAO,YAAY,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC,CAAC;AAAA,EACtF,GAAG,CAAC,SAAS,CAAC;AAEd,SACE,6CAAC,aAAQ,eAAW,iBAAG,yBAAyB,SAAS,GACvD;AAAA,gDAAC,QAAG,WAAU,yBAAyB,eAAK,OAAM;AAAA,IAClD,4CAAC,OAAE,WAAU,sCAAsC,eAAK,aAAY;AAAA,IAEpE;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,YAAU;AAAA,QACV,UAAU,CAAC,UAAU;AACnB,gBAAM,eAAe;AACrB,gBAAM,YAAY,OAAO;AAAA,YACvB,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,OAAO,MAAM,IAAI,KAAK,EAAE,CAAC;AAAA,UAC9D;AACA,mBAAS,SAAS;AAAA,QACpB;AAAA,QAEA;AAAA,sDAAC,cAAS,UAAU,SAAS,aAAW,SAAS,WAAU,YACzD,sDAAC,2BAAW,WAAU,yCACnB,iBAAO,IAAI,CAAC,UAAU;AACrB,kBAAM,KAAK,WAAW,MAAM,IAAI;AAChC,mBACE,6CAAC,sBACC;AAAA,0DAAC,2BAAW,SAAS,IAAK,gBAAM,OAAM;AAAA,cACtC;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA,MAAM,MAAM;AAAA,kBACZ,MAAM,MAAM,QAAQ;AAAA,kBACpB,OAAO,OAAO,MAAM,IAAI,KAAK;AAAA,kBAC7B,UAAU,MAAM;AAAA,kBAChB,UAAU,MAAM;AAAA,kBAChB,cAAc,MAAM;AAAA,kBACpB,iBAAe,MAAM,YAAY;AAAA,kBACjC,UAAU,CAAC,UACT,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,MAAM,OAAO,MAAM,EAAE;AAAA;AAAA,cAE7E;AAAA,iBAdU,MAAM,IAelB;AAAA,UAEJ,CAAC,GACH,GACF;AAAA,UAEC,QACC,4CAAC,OAAE,MAAK,SAAQ,WAAU,iCACvB,iBACH,IACE;AAAA,UAEJ,4CAAC,wBAAO,MAAK,UAAS,WAAU,QAAO,UAAU,SAC9C,oBAAU,KAAK,SAAS,KAAK,QAChC;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,76 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { Button } from "../../../ui/button.mjs";
5
+ import { Field, FieldGroup, FieldLabel } from "../../../ui/field.mjs";
6
+ import { Input } from "../../../ui/input.mjs";
7
+ import { cn } from "../../../lib/utils.mjs";
8
+ const defaultLabels = {
9
+ title: "Datos personales",
10
+ description: "Actualiza los datos de tu cuenta.",
11
+ submit: "Guardar cambios",
12
+ saving: "Guardando\u2026"
13
+ };
14
+ function ProfileForm({
15
+ fields,
16
+ labels,
17
+ pending = false,
18
+ error,
19
+ onSubmit,
20
+ className
21
+ }) {
22
+ const copy = { ...defaultLabels, ...labels };
23
+ const signature = fields.map((field) => `${field.name}:${field.value ?? ""}`).join("|");
24
+ const [values, setValues] = useState(
25
+ () => Object.fromEntries(fields.map((field) => [field.name, field.value ?? ""]))
26
+ );
27
+ useEffect(() => {
28
+ setValues(Object.fromEntries(fields.map((field) => [field.name, field.value ?? ""])));
29
+ }, [signature]);
30
+ return /* @__PURE__ */ jsxs("section", { className: cn("rounded-lg border p-6", className), children: [
31
+ /* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: copy.title }),
32
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: copy.description }),
33
+ /* @__PURE__ */ jsxs(
34
+ "form",
35
+ {
36
+ className: "mt-6",
37
+ noValidate: true,
38
+ onSubmit: (event) => {
39
+ event.preventDefault();
40
+ const submitted = Object.fromEntries(
41
+ fields.map((field) => [field.name, values[field.name] ?? ""])
42
+ );
43
+ onSubmit(submitted);
44
+ },
45
+ children: [
46
+ /* @__PURE__ */ jsx("fieldset", { disabled: pending, "aria-busy": pending, className: "contents", children: /* @__PURE__ */ jsx(FieldGroup, { className: "grid grid-cols-1 gap-5 sm:grid-cols-2", children: fields.map((field) => {
47
+ const id = `profile-${field.name}`;
48
+ return /* @__PURE__ */ jsxs(Field, { children: [
49
+ /* @__PURE__ */ jsx(FieldLabel, { htmlFor: id, children: field.label }),
50
+ /* @__PURE__ */ jsx(
51
+ Input,
52
+ {
53
+ id,
54
+ name: field.name,
55
+ type: field.type ?? "text",
56
+ value: values[field.name] ?? "",
57
+ readOnly: field.readOnly,
58
+ required: field.required,
59
+ autoComplete: field.autoComplete,
60
+ "aria-readonly": field.readOnly || void 0,
61
+ onChange: (event) => setValues((current) => ({ ...current, [field.name]: event.target.value }))
62
+ }
63
+ )
64
+ ] }, field.name);
65
+ }) }) }),
66
+ error ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-destructive mt-4 text-sm", children: error }) : null,
67
+ /* @__PURE__ */ jsx(Button, { type: "submit", className: "mt-6", disabled: pending, children: pending ? copy.saving : copy.submit })
68
+ ]
69
+ }
70
+ )
71
+ ] });
72
+ }
73
+ export {
74
+ ProfileForm
75
+ };
76
+ //# sourceMappingURL=profile-form.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/e-commerce/account/profile-form.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, useState } from 'react'\nimport { Button } from '../../../ui/button'\nimport { Field, FieldGroup, FieldLabel } from '../../../ui/field'\nimport { Input } from '../../../ui/input'\nimport { cn } from '../../../lib/utils'\n\n/** One editable (or read-only) profile field the host declares. */\nexport interface ProfileField {\n name: string\n label: string\n value?: string\n type?: 'text' | 'tel' | 'email'\n required?: boolean\n /** Rendered as read-only; a field the host omits is absent entirely. */\n readOnly?: boolean\n autoComplete?: string\n}\n\nexport interface ProfileFormLabels {\n title: string\n description: string\n submit: string\n saving: string\n}\n\nconst defaultLabels: ProfileFormLabels = {\n title: 'Datos personales',\n description: 'Actualiza los datos de tu cuenta.',\n submit: 'Guardar cambios',\n saving: 'Guardando…',\n}\n\nexport interface ProfileFormProps {\n /** Exactly the fields the host declares, in order. */\n fields: ProfileField[]\n labels?: Partial<ProfileFormLabels>\n /** Host-owned mutation state; the form never claims success on its own. */\n pending?: boolean\n error?: string | null\n onSubmit: (values: Record<string, string>) => void\n className?: string\n}\n\n/**\n * The profile editor. It renders only host-declared fields, keeps the entered\n * values while a save is pending or fails, and reports the values to the host —\n * it never calls a backend and never invents a field (an email change, for\n * example, is absent when the host does not declare it).\n */\nexport function ProfileForm({\n fields,\n labels,\n pending = false,\n error,\n onSubmit,\n className,\n}: ProfileFormProps) {\n const copy = { ...defaultLabels, ...labels }\n const signature = fields.map((field) => `${field.name}:${field.value ?? ''}`).join('|')\n const [values, setValues] = useState<Record<string, string>>(() =>\n Object.fromEntries(fields.map((field) => [field.name, field.value ?? ''])),\n )\n\n // Re-seed when the host supplies new default values (for example after a\n // successful save). The signature covers field identity and values, so a\n // pending/error prop change never clears what the shopper typed.\n useEffect(() => {\n setValues(Object.fromEntries(fields.map((field) => [field.name, field.value ?? ''])))\n }, [signature])\n\n return (\n <section className={cn('rounded-lg border p-6', className)}>\n <h2 className=\"text-lg font-semibold\">{copy.title}</h2>\n <p className=\"text-muted-foreground mt-1 text-sm\">{copy.description}</p>\n\n <form\n className=\"mt-6\"\n noValidate\n onSubmit={(event) => {\n event.preventDefault()\n const submitted = Object.fromEntries(\n fields.map((field) => [field.name, values[field.name] ?? '']),\n )\n onSubmit(submitted)\n }}\n >\n <fieldset disabled={pending} aria-busy={pending} className=\"contents\">\n <FieldGroup className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n {fields.map((field) => {\n const id = `profile-${field.name}`\n return (\n <Field key={field.name}>\n <FieldLabel htmlFor={id}>{field.label}</FieldLabel>\n <Input\n id={id}\n name={field.name}\n type={field.type ?? 'text'}\n value={values[field.name] ?? ''}\n readOnly={field.readOnly}\n required={field.required}\n autoComplete={field.autoComplete}\n aria-readonly={field.readOnly || undefined}\n onChange={(event) =>\n setValues((current) => ({ ...current, [field.name]: event.target.value }))\n }\n />\n </Field>\n )\n })}\n </FieldGroup>\n </fieldset>\n\n {error ? (\n <p role=\"alert\" className=\"text-destructive mt-4 text-sm\">\n {error}\n </p>\n ) : null}\n\n <Button type=\"submit\" className=\"mt-6\" disabled={pending}>\n {pending ? copy.saving : copy.submit}\n </Button>\n </form>\n </section>\n )\n}\n"],"mappings":";AA0EM,cAmBU,YAnBV;AAxEN,SAAS,WAAW,gBAAgB;AACpC,SAAS,cAAc;AACvB,SAAS,OAAO,YAAY,kBAAkB;AAC9C,SAAS,aAAa;AACtB,SAAS,UAAU;AAqBnB,MAAM,gBAAmC;AAAA,EACvC,OAAO;AAAA,EACP,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,QAAQ;AACV;AAmBO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,OAAO,EAAE,GAAG,eAAe,GAAG,OAAO;AAC3C,QAAM,YAAY,OAAO,IAAI,CAAC,UAAU,GAAG,MAAM,IAAI,IAAI,MAAM,SAAS,EAAE,EAAE,EAAE,KAAK,GAAG;AACtF,QAAM,CAAC,QAAQ,SAAS,IAAI;AAAA,IAAiC,MAC3D,OAAO,YAAY,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC;AAAA,EAC3E;AAKA,YAAU,MAAM;AACd,cAAU,OAAO,YAAY,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,MAAM,SAAS,EAAE,CAAC,CAAC,CAAC;AAAA,EACtF,GAAG,CAAC,SAAS,CAAC;AAEd,SACE,qBAAC,aAAQ,WAAW,GAAG,yBAAyB,SAAS,GACvD;AAAA,wBAAC,QAAG,WAAU,yBAAyB,eAAK,OAAM;AAAA,IAClD,oBAAC,OAAE,WAAU,sCAAsC,eAAK,aAAY;AAAA,IAEpE;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,YAAU;AAAA,QACV,UAAU,CAAC,UAAU;AACnB,gBAAM,eAAe;AACrB,gBAAM,YAAY,OAAO;AAAA,YACvB,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,OAAO,MAAM,IAAI,KAAK,EAAE,CAAC;AAAA,UAC9D;AACA,mBAAS,SAAS;AAAA,QACpB;AAAA,QAEA;AAAA,8BAAC,cAAS,UAAU,SAAS,aAAW,SAAS,WAAU,YACzD,8BAAC,cAAW,WAAU,yCACnB,iBAAO,IAAI,CAAC,UAAU;AACrB,kBAAM,KAAK,WAAW,MAAM,IAAI;AAChC,mBACE,qBAAC,SACC;AAAA,kCAAC,cAAW,SAAS,IAAK,gBAAM,OAAM;AAAA,cACtC;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA,MAAM,MAAM;AAAA,kBACZ,MAAM,MAAM,QAAQ;AAAA,kBACpB,OAAO,OAAO,MAAM,IAAI,KAAK;AAAA,kBAC7B,UAAU,MAAM;AAAA,kBAChB,UAAU,MAAM;AAAA,kBAChB,cAAc,MAAM;AAAA,kBACpB,iBAAe,MAAM,YAAY;AAAA,kBACjC,UAAU,CAAC,UACT,UAAU,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC,MAAM,IAAI,GAAG,MAAM,OAAO,MAAM,EAAE;AAAA;AAAA,cAE7E;AAAA,iBAdU,MAAM,IAelB;AAAA,UAEJ,CAAC,GACH,GACF;AAAA,UAEC,QACC,oBAAC,OAAE,MAAK,SAAQ,WAAU,iCACvB,iBACH,IACE;AAAA,UAEJ,oBAAC,UAAO,MAAK,UAAS,WAAU,QAAO,UAAU,SAC9C,oBAAU,KAAK,SAAS,KAAK,QAChC;AAAA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;","names":[]}
package/dist/index.d.ts CHANGED
@@ -80,6 +80,12 @@ export { OrderHistory } from './blocks/e-commerce/order-history/order-history';
80
80
  export { OrderLine } from './blocks/e-commerce/order-history/order-line';
81
81
  export type { OrderHistoryLabels, OrderHistoryOrder, OrderHistoryPresentation, OrderHistoryProps, OrderHistoryStatus, OrderHistoryStatusTone, } from './blocks/e-commerce/order-history/order-history';
82
82
  export type { OrderLineData, OrderLineProps } from './blocks/e-commerce/order-history/order-line';
83
+ export { AccountFrame } from './blocks/e-commerce/account/account-frame';
84
+ export type { AccountFrameLabels, AccountFramePresentation, AccountFrameProps, AccountModule, } from './blocks/e-commerce/account/account-frame';
85
+ export { ProfileForm } from './blocks/e-commerce/account/profile-form';
86
+ export type { ProfileField, ProfileFormLabels, ProfileFormProps, } from './blocks/e-commerce/account/profile-form';
87
+ export { AddressBook, AddressForm } from './blocks/e-commerce/account/address-book';
88
+ export type { AccountAddress, AddressBookLabels, AddressBookProps, AddressFormField, AddressFormLabels, AddressFormProps, } from './blocks/e-commerce/account/address-book';
83
89
  export { default as StorefrontHero } from './blocks/e-commerce/storefront-hero/storefront-hero';
84
90
  export type { FeaturedProduct, HeroImage, HeroDepartment, HeroFeaturedDeal, HeroStoreLocator, HeroDeal, HeroCategory, StorefrontHeroPresentation, StorefrontHeroProps, } from './blocks/e-commerce/storefront-hero/storefront-hero';
85
91
  export { default as AppShell1 } from './blocks/application/app-shells/app-shell-1';
@@ -96,8 +102,11 @@ export { PRODUCT_IMAGE_FALLBACK } from './lib/contracts';
96
102
  export { isCompleteFiniteDecimal, isAvailableMoney, formatMoney, } from './lib/money';
97
103
  export { resolveAbsoluteQuantity } from './lib/cart';
98
104
  export { moneySchema, cartTotalsSchema, productDetailProductSchema, productDetailVariantSchema, productOverviewPropsSchema, storefrontHeroPropsSchema, storefrontHeroProductSchema, buttonPropsSchema, storeContainer1PropsSchema, productCardPropsSchema, productGridPropsSchema, productPresentationSchema, productShowcase1PropsSchema, shoppingCartPropsSchema, shoppingCartItemSchema, shoppingCartSuggestionSchema, navbarPresentationSchema, navbarItemSchema, navbarGroupSchema, navbarLinkSchema, navbarFeaturedSchema, navbarPropsSchema, storefrontNavbarPropsSchema, paymentMethodSchema, checkoutPropsSchema, cardProductSchema, cartItemSchema, promotionSchema, storeCategorySchema, utilityLinkSchema, navCartItemSchema, storeUserSchema, accountMenuItemSchema, featurePropsSchema, featureCardsSpecSchema, featureSplitSpecSchema, productCategoryItemSchema, productCategoryPropsSchema, orderHistoryPresentationSchema, orderHistoryStatusSchema, orderLineDataSchema, orderHistoryOrderSchema, orderHistoryPropsSchema, orderLinePropsSchema, } from './lib/contracts';
99
- export type { ProductDetailProductSpec, ProductDetailVariantSpec, StorefrontHeroProduct, StorefrontHeroSpecProps, CartTotals, ButtonSpecProps, StoreContainer1SpecProps, ProductCardSpecProps, ProductGridSpecProps, ProductPresentation, ProductShowcase1SpecProps, ShoppingCartItem, ShoppingCartSuggestion, ShoppingCartSpecProps, NavbarPresentationSpec, NavbarItemSpec, NavbarGroupSpec, NavbarLinkSpec, NavbarFeaturedSpec, NavbarSpecProps, StorefrontNavbarSpecProps, CardProduct, CartItem, Promotion, StoreCategory, UtilityLink, NavCartItem, StoreUser, AccountMenuItem, FeatureSpecProps, FeatureCardsSpecProps, FeatureSplitSpecProps, ProductCategoryItem, ProductCategorySpecProps, CategoryCardSpecProps, CategoryGridSpecProps, OrderHistoryPresentationSpec, OrderHistoryStatusSpec, OrderLineDataSpec, OrderHistoryOrderSpec, OrderHistorySpecProps, OrderLineSpecProps, } from './lib/contracts';
105
+ export type { ProductDetailProductSpec, ProductDetailVariantSpec, StorefrontHeroProduct, StorefrontHeroSpecProps, CartTotals, ButtonSpecProps, StoreContainer1SpecProps, ProductCardSpecProps, ProductGridSpecProps, ProductPresentation, ProductShowcase1SpecProps, ShoppingCartItem, ShoppingCartSuggestion, ShoppingCartSpecProps, NavbarPresentationSpec, NavbarItemSpec, NavbarGroupSpec, NavbarLinkSpec, NavbarFeaturedSpec, NavbarSpecProps, StorefrontNavbarSpecProps, CardProduct, CartItem, Promotion, StoreCategory, UtilityLink, NavCartItem, StoreUser, AccountMenuItem, FeatureSpecProps, FeatureCardsSpecProps, FeatureSplitSpecProps, ProductCategoryItem, ProductCategorySpecProps, CategoryCardSpecProps, CategoryGridSpecProps, OrderHistoryPresentationSpec, OrderHistoryStatusSpec, OrderLineDataSpec, OrderHistoryOrderSpec, OrderHistorySpecProps, OrderLineSpecProps, AccountFramePresentationSpec, AccountFrameSpecProps, AccountModuleSpec, ProfileFieldSpec, ProfileFormSpecProps, AccountAddressSpec, AddressBookSpecProps, AddressFormFieldSpec, AddressFormSpecProps, } from './lib/contracts';
100
106
  export { default as MarketplaceProductCard } from './blocks/designs/marketplace-product-card/index';
101
107
  export type { MarketplaceProductCardProps } from './blocks/designs/marketplace-product-card/index';
102
108
  export type { MarketplaceProductCardData } from './lib/contracts/marketplace-product-card';
109
+ export { default as CheckoutCommerceV1 } from './blocks/designs/checkout-commerce-v1/index';
110
+ export type { CheckoutCommerceV1Props } from './blocks/designs/checkout-commerce-v1/index';
111
+ export type { CheckoutCommerceV1Item, CheckoutCommerceV1Data } from './lib/contracts/checkout-commerce-v1';
103
112
  //# sourceMappingURL=index.d.ts.map