platform-types 1.10.772 → 1.10.774
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/storefrontDesign.js +17 -0
- package/dist/cjs/storefrontDesignRegistry.js +9 -0
- package/dist/cjs/storefrontTheme.js +19 -4
- package/dist/cjs/storefrontWebLiteralKeys.js +15 -0
- package/dist/storefrontDesign.d.ts +75 -3
- package/dist/storefrontDesign.js +17 -0
- package/dist/storefrontDesignRegistry.d.ts +150 -0
- package/dist/storefrontDesignRegistry.js +9 -0
- package/dist/storefrontTheme.d.ts +18 -1
- package/dist/storefrontTheme.js +19 -4
- package/dist/storefrontWebLiteralKeys.js +15 -0
- package/package.json +1 -1
|
@@ -35,6 +35,10 @@ exports.STOREFRONT_DESIGN_LIMITS = {
|
|
|
35
35
|
footerLinks: 8,
|
|
36
36
|
faqs: 20,
|
|
37
37
|
benefits: 8,
|
|
38
|
+
/** Logos in one `logoWall` section; a 25th is `INVALID` at `content.items`. */
|
|
39
|
+
logoWallItems: 24,
|
|
40
|
+
/** Photos in one `gallery` section; a 25th is `INVALID` at `content.items`. */
|
|
41
|
+
galleryItems: 24,
|
|
38
42
|
historyEntries: 20,
|
|
39
43
|
selectedSourceIds: 50,
|
|
40
44
|
/** A `visibility` rule's `priceLists`: the store's own cap on price lists. */
|
|
@@ -43,6 +47,8 @@ exports.STOREFRONT_DESIGN_LIMITS = {
|
|
|
43
47
|
heading: 120,
|
|
44
48
|
label: 80,
|
|
45
49
|
body: 4000,
|
|
50
|
+
/** The announcement bar's `subtitle`; its `text` is bounded by `heading`. */
|
|
51
|
+
announcementSubtitle: 240,
|
|
46
52
|
slug: 80,
|
|
47
53
|
seoTitle: 120,
|
|
48
54
|
seoDescription: 320,
|
|
@@ -83,6 +89,8 @@ exports.STOREFRONT_SECTION_TYPES = [
|
|
|
83
89
|
'benefits',
|
|
84
90
|
'contact',
|
|
85
91
|
'paymentDelivery',
|
|
92
|
+
'logoWall',
|
|
93
|
+
'gallery',
|
|
86
94
|
];
|
|
87
95
|
/**
|
|
88
96
|
* The section types a page may repeat, each up to `STOREFRONT_DESIGN_LIMITS.repeatableSectionsPerType`
|
|
@@ -329,6 +337,7 @@ function parseStorefrontPreviewDocument(input) {
|
|
|
329
337
|
const parsedPages = pages.map(previewPage);
|
|
330
338
|
if (!sections || parsedPages.some((page) => page === undefined))
|
|
331
339
|
return undefined;
|
|
340
|
+
const announcement = previewAnnouncement(input.announcement);
|
|
332
341
|
return {
|
|
333
342
|
schemaVersion: 1,
|
|
334
343
|
templateId: 'standard',
|
|
@@ -341,8 +350,16 @@ function parseStorefrontPreviewDocument(input) {
|
|
|
341
350
|
pages: parsedPages,
|
|
342
351
|
navigation,
|
|
343
352
|
footer,
|
|
353
|
+
...(announcement ? { announcement } : {}),
|
|
344
354
|
};
|
|
345
355
|
}
|
|
356
|
+
/** The bar on the transport: an object kept as sent minus a malformed rule; anything else left off. */
|
|
357
|
+
function previewAnnouncement(input) {
|
|
358
|
+
if (!previewRecord(input))
|
|
359
|
+
return undefined;
|
|
360
|
+
const { visibility, ...rest } = input;
|
|
361
|
+
return { ...rest, ...previewVisibility(visibility) };
|
|
362
|
+
}
|
|
346
363
|
/** The codes a preview frame may report in an `error` message; the parser accepts exactly these. */
|
|
347
364
|
exports.STOREFRONT_PREVIEW_PROTOCOL_ERRORS = [
|
|
348
365
|
'STOREFRONT_PREVIEW_EXPIRED',
|
|
@@ -50,6 +50,15 @@ exports.STOREFRONT_DESIGN_SETTINGS = {
|
|
|
50
50
|
textSize: choice('textSize', ['compact', 'standard', 'large'], 'standard', 'Tamaño de texto', 'Escala de texto de la tienda.'),
|
|
51
51
|
cardImageRatio: choice('cardImageRatio', ['square', 'portrait'], 'square', 'Proporción de imágenes', 'Proporción de las imágenes en las tarjetas de productos.'),
|
|
52
52
|
cardDensity: choice('cardDensity', ['compact', 'spacious'], 'spacious', 'Espaciado de tarjetas', 'Espaciado entre los elementos de las tarjetas.'),
|
|
53
|
+
/*
|
|
54
|
+
* The three shape settings take values no other setting uses (`compact`, `standard`, `square`,
|
|
55
|
+
* `large`, `spacious` are taken): the editor labels an option by its value alone. Each default
|
|
56
|
+
* reproduces the tokens every shop rendered before they existed, so a publication that lacks
|
|
57
|
+
* them resolves exactly as before and `STOREFRONT_DEFAULTS_VERSION` does not move.
|
|
58
|
+
*/
|
|
59
|
+
cornerRadius: choice('cornerRadius', ['none', 'soft', 'round'], 'soft', 'Bordes', 'Elegí cuánto se redondean las tarjetas, los botones y los campos.'),
|
|
60
|
+
buttonStyle: choice('buttonStyle', ['filled', 'outlined', 'pill'], 'filled', 'Estilo de botones', 'Elegí si los botones van rellenos, con contorno o con forma de píldora.'),
|
|
61
|
+
layoutDensity: choice('layoutDensity', ['comfortable', 'dense'], 'comfortable', 'Densidad', 'Elegí cuánto espacio dejás entre los elementos de toda la tienda.'),
|
|
53
62
|
showBrand: toggle('showBrand', false, 'Mostrar marca', 'Mostrar la marca en las tarjetas de productos.'),
|
|
54
63
|
showSku: toggle('showSku', false, 'Mostrar SKU', 'Mostrar el código SKU en las tarjetas de productos.'),
|
|
55
64
|
};
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.resolveStorefrontTheme = exports.resolveStorefrontEffectiveSettings = exports.storefrontGlobalSettingsLayer = exports.storefrontContrastRatio = void 0;
|
|
4
4
|
const storefrontDesignRegistry_ts_1 = require("./storefrontDesignRegistry.js");
|
|
5
|
+
const CORNER_RADIUS = { none: 0, soft: 4, round: 12 };
|
|
6
|
+
const LAYOUT_SPACING = { comfortable: 8, dense: 6 };
|
|
7
|
+
const PILL_RADIUS = 999;
|
|
8
|
+
const buttonTokens = (style, borderRadius) => style === 'pill' ? { variant: 'filled', borderRadius: PILL_RADIUS } : { variant: style, borderRadius };
|
|
9
|
+
/*
|
|
10
|
+
* An outlined button draws with the `button` colour as its border and the `link` colour as its
|
|
11
|
+
* text, so a design that chose `outlined` caused any adjustment to either: both are reported.
|
|
12
|
+
*/
|
|
13
|
+
const OUTLINED_ROLES = new Set(['button', 'link']);
|
|
5
14
|
/*
|
|
6
15
|
* The one binding of a warning role and of a surface to the setting it reads: `surfaceTokens`
|
|
7
16
|
* and `makeMode` read the colours THROUGH these maps, and the `warnings` filter judges by them,
|
|
@@ -113,7 +122,8 @@ exports.resolveStorefrontEffectiveSettings = resolveStorefrontEffectiveSettings;
|
|
|
113
122
|
* already-effective settings as `overrides` rebuilds the same tokens.
|
|
114
123
|
*
|
|
115
124
|
* `warnings` names only adjustments the design itself caused: the adjusted colour, or the
|
|
116
|
-
* background of the surface it sits on, is set in `overrides
|
|
125
|
+
* background of the surface it sits on, is set in `overrides`, or (for the `button` and `link`
|
|
126
|
+
* roles) `overrides` chose an `outlined` `buttonStyle`, which draws the button with both. No single colour reads at 4.5:1 on
|
|
117
127
|
* both a white page and its dark-mode counterpart, so a platform or GLOBAL default is always
|
|
118
128
|
* adjusted somewhere, and a shop that chose nothing has nothing to act on. Pass the design's own
|
|
119
129
|
* settings, not effective ones, or every default reads as chosen.
|
|
@@ -127,6 +137,8 @@ const resolveStorefrontTheme = (overrides = {}, globalsRow) => {
|
|
|
127
137
|
return { page: surface('page'), header: surface('header'), footer: surface('footer') };
|
|
128
138
|
};
|
|
129
139
|
const scale = { compact: 0.875, standard: 1, large: 1.125 }[settings.textSize];
|
|
140
|
+
const borderRadius = CORNER_RADIUS[settings.cornerRadius];
|
|
141
|
+
const outlinedChosen = overrides.buttonStyle !== undefined && settings.buttonStyle === 'outlined';
|
|
130
142
|
return {
|
|
131
143
|
requested: settings,
|
|
132
144
|
light: makeMode('light'),
|
|
@@ -144,9 +156,12 @@ const resolveStorefrontTheme = (overrides = {}, globalsRow) => {
|
|
|
144
156
|
h5: 24 * scale,
|
|
145
157
|
h6: 20 * scale,
|
|
146
158
|
},
|
|
147
|
-
shape: { borderRadius
|
|
148
|
-
spacing:
|
|
149
|
-
|
|
159
|
+
shape: { borderRadius },
|
|
160
|
+
spacing: LAYOUT_SPACING[settings.layoutDensity],
|
|
161
|
+
buttons: buttonTokens(settings.buttonStyle, borderRadius),
|
|
162
|
+
warnings: warnings.filter(({ role, surface }) => overrides[WARNING_SETTING[role]] !== undefined ||
|
|
163
|
+
overrides[SURFACE_SETTING[surface]] !== undefined ||
|
|
164
|
+
(outlinedChosen && OUTLINED_ROLES.has(role))),
|
|
150
165
|
};
|
|
151
166
|
};
|
|
152
167
|
exports.resolveStorefrontTheme = resolveStorefrontTheme;
|
|
@@ -411,8 +411,10 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
|
|
|
411
411
|
'CHECKOUT_MIN_BUY_ALERT',
|
|
412
412
|
'CHECKOUT_MIN_BUY_ERROR',
|
|
413
413
|
'CHECKOUT_MIN_BUY_REFUSED',
|
|
414
|
+
'CHECKOUT_NO_DELIVERY_METHODS_FOR_ACCOUNT',
|
|
414
415
|
'CHECKOUT_NO_INVOICE',
|
|
415
416
|
'CHECKOUT_NO_INVOICE_OPTION',
|
|
417
|
+
'CHECKOUT_NO_PAYMENT_METHODS_FOR_ACCOUNT',
|
|
416
418
|
'CHECKOUT_ORDER_CREATED',
|
|
417
419
|
'CHECKOUT_ORDER_CREATION_ERROR',
|
|
418
420
|
'CHECKOUT_ORDER_IN_PROGRESS',
|
|
@@ -929,6 +931,18 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
|
|
|
929
931
|
'ORDER_COLUMN_SKU',
|
|
930
932
|
'ORDER_COLUMN_TOTAL',
|
|
931
933
|
'ORDER_COMMENTS_TOOLTIP',
|
|
934
|
+
'ORDER_DELIVERY_CONTACT_PHONE',
|
|
935
|
+
'ORDER_DELIVERY_CONTACT_WHATSAPP',
|
|
936
|
+
'ORDER_DELIVERY_ETA',
|
|
937
|
+
'ORDER_DELIVERY_FAILED_NEXT_STEP',
|
|
938
|
+
'ORDER_DELIVERY_METHOD_FALLBACK',
|
|
939
|
+
'ORDER_DELIVERY_NEXT_DATE',
|
|
940
|
+
'ORDER_DELIVERY_STATUS_ASSIGNED',
|
|
941
|
+
'ORDER_DELIVERY_STATUS_DELIVERED',
|
|
942
|
+
'ORDER_DELIVERY_STATUS_FAILED',
|
|
943
|
+
'ORDER_DELIVERY_STATUS_IN_TRANSIT',
|
|
944
|
+
'ORDER_DELIVERY_STATUS_PICKED_UP',
|
|
945
|
+
'ORDER_DELIVERY_UPDATED',
|
|
932
946
|
'ORDER_DISABLED_ALERT',
|
|
933
947
|
'ORDER_DISCOUNT_LABEL',
|
|
934
948
|
'ORDER_ERROR',
|
|
@@ -939,6 +953,7 @@ exports.STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
|
|
|
939
953
|
'ORDER_NAV_PREV',
|
|
940
954
|
'ORDER_PAYMENT_CHARGED_BACK',
|
|
941
955
|
'ORDER_PAYMENT_EXPIRED',
|
|
956
|
+
'ORDER_PAYMENT_METHOD_FALLBACK',
|
|
942
957
|
'ORDER_PAYMENT_NOT_STARTED',
|
|
943
958
|
'ORDER_PAYMENT_PAID',
|
|
944
959
|
'ORDER_PAYMENT_PAY',
|
|
@@ -29,6 +29,10 @@ export declare const STOREFRONT_DESIGN_LIMITS: {
|
|
|
29
29
|
readonly footerLinks: 8;
|
|
30
30
|
readonly faqs: 20;
|
|
31
31
|
readonly benefits: 8;
|
|
32
|
+
/** Logos in one `logoWall` section; a 25th is `INVALID` at `content.items`. */
|
|
33
|
+
readonly logoWallItems: 24;
|
|
34
|
+
/** Photos in one `gallery` section; a 25th is `INVALID` at `content.items`. */
|
|
35
|
+
readonly galleryItems: 24;
|
|
32
36
|
readonly historyEntries: 20;
|
|
33
37
|
readonly selectedSourceIds: 50;
|
|
34
38
|
/** A `visibility` rule's `priceLists`: the store's own cap on price lists. */
|
|
@@ -37,6 +41,8 @@ export declare const STOREFRONT_DESIGN_LIMITS: {
|
|
|
37
41
|
readonly heading: 120;
|
|
38
42
|
readonly label: 80;
|
|
39
43
|
readonly body: 4000;
|
|
44
|
+
/** The announcement bar's `subtitle`; its `text` is bounded by `heading`. */
|
|
45
|
+
readonly announcementSubtitle: 240;
|
|
40
46
|
readonly slug: 80;
|
|
41
47
|
readonly seoTitle: 120;
|
|
42
48
|
readonly seoDescription: 320;
|
|
@@ -65,7 +71,7 @@ export declare const STOREFRONT_DESIGN_LIMITS: {
|
|
|
65
71
|
*/
|
|
66
72
|
export declare const STOREFRONT_PAGE_SLUG_RE: RegExp;
|
|
67
73
|
export declare const isStorefrontPageSlug: (value: unknown) => value is string;
|
|
68
|
-
export declare const STOREFRONT_SECTION_TYPES: readonly ["banner", "imageText", "products", "categories", "brands", "text", "faq", "benefits", "contact", "paymentDelivery"];
|
|
74
|
+
export declare const STOREFRONT_SECTION_TYPES: readonly ["banner", "imageText", "products", "categories", "brands", "text", "faq", "benefits", "contact", "paymentDelivery", "logoWall", "gallery"];
|
|
69
75
|
/**
|
|
70
76
|
* The section types a page may repeat, each up to `STOREFRONT_DESIGN_LIMITS.repeatableSectionsPerType`
|
|
71
77
|
* times (disabled sections count), so a Home can show offers and new arrivals together. Every other
|
|
@@ -209,6 +215,36 @@ declare global {
|
|
|
209
215
|
showPayments?: boolean;
|
|
210
216
|
showDelivery?: boolean;
|
|
211
217
|
};
|
|
218
|
+
/**
|
|
219
|
+
* Merchant logos (clients, distributed brands, certifications) that are not catalogue brands.
|
|
220
|
+
* A logo is never decorative: `image.decorative` is `false`, and `name` (up to `label`) is
|
|
221
|
+
* its alt text, required to publish. Every projection (the publication, web `GET /store`,
|
|
222
|
+
* the preview read) writes `name` into `image.alt` when the editor left `alt` blank; an
|
|
223
|
+
* explicit `alt` wins, and the draft keeps `alt` as authored. Its optional link names a target, so a target that
|
|
224
|
+
* vanishes drops only the link, never the logo. Once per page.
|
|
225
|
+
*/
|
|
226
|
+
logoWall: {
|
|
227
|
+
heading?: string;
|
|
228
|
+
body?: string;
|
|
229
|
+
items?: {
|
|
230
|
+
image: StorefrontDesignImagePlacement & {
|
|
231
|
+
decorative: false;
|
|
232
|
+
};
|
|
233
|
+
name: string;
|
|
234
|
+
action?: StorefrontDesignAction & {
|
|
235
|
+
target: StorefrontDesignLinkTarget;
|
|
236
|
+
};
|
|
237
|
+
}[];
|
|
238
|
+
};
|
|
239
|
+
/** Photos, each with `alt` unless decorative and an optional `caption` (up to `heading`). Once per page. */
|
|
240
|
+
gallery: {
|
|
241
|
+
heading?: string;
|
|
242
|
+
body?: string;
|
|
243
|
+
items?: {
|
|
244
|
+
image: StorefrontDesignImagePlacement;
|
|
245
|
+
caption?: string;
|
|
246
|
+
}[];
|
|
247
|
+
};
|
|
212
248
|
}
|
|
213
249
|
type StorefrontDesignAudience = (typeof STOREFRONT_DESIGN_AUDIENCES)[number];
|
|
214
250
|
/**
|
|
@@ -224,6 +260,36 @@ declare global {
|
|
|
224
260
|
audiences: StorefrontDesignAudience[];
|
|
225
261
|
priceLists?: number[];
|
|
226
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* The one announcement bar a design carries above every page, never a second. `text` and
|
|
265
|
+
* `subtitle` are plain text (no control characters; renderers escape markup); `text` is required
|
|
266
|
+
* to publish while `enabled`. `action` always names a target, so a target that vanishes drops
|
|
267
|
+
* only the link. `backgroundColor` is a 6-digit hex colour.
|
|
268
|
+
*
|
|
269
|
+
* `id` is minted by the server from `text`, `subtitle` and `action`: whatever a client sends is
|
|
270
|
+
* replaced (an editor adding a bar may send `''`), so it changes whenever the message or its
|
|
271
|
+
* link does and never when only the rule, colour or dismiss behaviour does. A storefront keys a
|
|
272
|
+
* remembered dismissal by it, so a dismiss of an old message never hides a new one. Every
|
|
273
|
+
* document the server answers carries it.
|
|
274
|
+
*
|
|
275
|
+
* Every projection drops a disabled bar, as it drops a disabled section. Web `GET /store` also
|
|
276
|
+
* drops one whose `visibility` the caller does not match; the private preview carries the rule
|
|
277
|
+
* as authored.
|
|
278
|
+
*/
|
|
279
|
+
interface StorefrontDesignAnnouncement {
|
|
280
|
+
id: string;
|
|
281
|
+
enabled: boolean;
|
|
282
|
+
text?: string;
|
|
283
|
+
subtitle?: string;
|
|
284
|
+
action?: StorefrontDesignAction & {
|
|
285
|
+
target: StorefrontDesignLinkTarget;
|
|
286
|
+
};
|
|
287
|
+
dismissable: boolean;
|
|
288
|
+
/** Whether a dismissal outlives the browser session; meaningful only with `dismissable`. */
|
|
289
|
+
persistDismiss: boolean;
|
|
290
|
+
backgroundColor?: string;
|
|
291
|
+
visibility?: StorefrontDesignVisibility;
|
|
292
|
+
}
|
|
227
293
|
type StorefrontDesignSection = {
|
|
228
294
|
[K in StorefrontDesignSectionType]: {
|
|
229
295
|
id: string;
|
|
@@ -331,7 +397,8 @@ declare global {
|
|
|
331
397
|
* Private preview envelopes instead supply `/preview/read?operation=asset&assetId=...`; the
|
|
332
398
|
* preview transport adds a variant query and its in-memory grant, then renders returned bytes.
|
|
333
399
|
*
|
|
334
|
-
* An item that can carry `visibility` (section, page, navigation entry, footer link
|
|
400
|
+
* An item that can carry `visibility` (section, page, navigation entry, footer link, the
|
|
401
|
+
* announcement bar) may also
|
|
335
402
|
* carry `audienceScoped: true`: web `GET /store` sets it on an item it returned because the
|
|
336
403
|
* caller matched that item's rule, and strips every `visibility`. The preview never sets it.
|
|
337
404
|
*/
|
|
@@ -378,6 +445,8 @@ declare global {
|
|
|
378
445
|
contact: StorefrontDesignContact;
|
|
379
446
|
seo: StorefrontDesignSeo;
|
|
380
447
|
literalOverrides: Record<string, string>;
|
|
448
|
+
/** Absent on every document written before the bar existed, and whenever none is authored. */
|
|
449
|
+
announcement?: StorefrontDesignAnnouncement;
|
|
381
450
|
}
|
|
382
451
|
/**
|
|
383
452
|
* `TOO_LARGE` at path `''` means the whole stored draft would exceed its row budget, not one field.
|
|
@@ -535,7 +604,8 @@ declare global {
|
|
|
535
604
|
/**
|
|
536
605
|
* Only adjustments the design itself caused: the adjusted colour, or the background of the
|
|
537
606
|
* surface it sits on, is set by the design. So a default primary or accent colour IS listed
|
|
538
|
-
* when the design sets that surface's background
|
|
607
|
+
* when the design sets that surface's background, and a default primary's `button` and
|
|
608
|
+
* `link` adjustments are listed when the design chooses an `outlined` `buttonStyle`.
|
|
539
609
|
*/
|
|
540
610
|
changeSummary: {
|
|
541
611
|
contrastAdjustments: StorefrontThemeWarning[];
|
|
@@ -731,6 +801,8 @@ declare global {
|
|
|
731
801
|
contact: Record<string, unknown>;
|
|
732
802
|
seo: object;
|
|
733
803
|
literalOverrides: Record<string, unknown>;
|
|
804
|
+
/** Carried as sent when it is an object, its `visibility` kept only when well-formed; never applied. */
|
|
805
|
+
announcement?: object;
|
|
734
806
|
}
|
|
735
807
|
type StorefrontPreviewProtocolError = (typeof STOREFRONT_PREVIEW_PROTOCOL_ERRORS)[number];
|
|
736
808
|
type StorefrontPreviewViewport = 'desktop' | 'mobile';
|
package/dist/storefrontDesign.js
CHANGED
|
@@ -28,6 +28,10 @@ export const STOREFRONT_DESIGN_LIMITS = {
|
|
|
28
28
|
footerLinks: 8,
|
|
29
29
|
faqs: 20,
|
|
30
30
|
benefits: 8,
|
|
31
|
+
/** Logos in one `logoWall` section; a 25th is `INVALID` at `content.items`. */
|
|
32
|
+
logoWallItems: 24,
|
|
33
|
+
/** Photos in one `gallery` section; a 25th is `INVALID` at `content.items`. */
|
|
34
|
+
galleryItems: 24,
|
|
31
35
|
historyEntries: 20,
|
|
32
36
|
selectedSourceIds: 50,
|
|
33
37
|
/** A `visibility` rule's `priceLists`: the store's own cap on price lists. */
|
|
@@ -36,6 +40,8 @@ export const STOREFRONT_DESIGN_LIMITS = {
|
|
|
36
40
|
heading: 120,
|
|
37
41
|
label: 80,
|
|
38
42
|
body: 4000,
|
|
43
|
+
/** The announcement bar's `subtitle`; its `text` is bounded by `heading`. */
|
|
44
|
+
announcementSubtitle: 240,
|
|
39
45
|
slug: 80,
|
|
40
46
|
seoTitle: 120,
|
|
41
47
|
seoDescription: 320,
|
|
@@ -75,6 +81,8 @@ export const STOREFRONT_SECTION_TYPES = [
|
|
|
75
81
|
'benefits',
|
|
76
82
|
'contact',
|
|
77
83
|
'paymentDelivery',
|
|
84
|
+
'logoWall',
|
|
85
|
+
'gallery',
|
|
78
86
|
];
|
|
79
87
|
/**
|
|
80
88
|
* The section types a page may repeat, each up to `STOREFRONT_DESIGN_LIMITS.repeatableSectionsPerType`
|
|
@@ -321,6 +329,7 @@ export function parseStorefrontPreviewDocument(input) {
|
|
|
321
329
|
const parsedPages = pages.map(previewPage);
|
|
322
330
|
if (!sections || parsedPages.some((page) => page === undefined))
|
|
323
331
|
return undefined;
|
|
332
|
+
const announcement = previewAnnouncement(input.announcement);
|
|
324
333
|
return {
|
|
325
334
|
schemaVersion: 1,
|
|
326
335
|
templateId: 'standard',
|
|
@@ -333,8 +342,16 @@ export function parseStorefrontPreviewDocument(input) {
|
|
|
333
342
|
pages: parsedPages,
|
|
334
343
|
navigation,
|
|
335
344
|
footer,
|
|
345
|
+
...(announcement ? { announcement } : {}),
|
|
336
346
|
};
|
|
337
347
|
}
|
|
348
|
+
/** The bar on the transport: an object kept as sent minus a malformed rule; anything else left off. */
|
|
349
|
+
function previewAnnouncement(input) {
|
|
350
|
+
if (!previewRecord(input))
|
|
351
|
+
return undefined;
|
|
352
|
+
const { visibility, ...rest } = input;
|
|
353
|
+
return { ...rest, ...previewVisibility(visibility) };
|
|
354
|
+
}
|
|
338
355
|
/** The codes a preview frame may report in an `error` message; the parser accepts exactly these. */
|
|
339
356
|
export const STOREFRONT_PREVIEW_PROTOCOL_ERRORS = [
|
|
340
357
|
'STOREFRONT_PREVIEW_EXPIRED',
|
|
@@ -293,6 +293,81 @@ export declare const STOREFRONT_DESIGN_SETTINGS: {
|
|
|
293
293
|
};
|
|
294
294
|
readonly ownership: "storefront-design";
|
|
295
295
|
};
|
|
296
|
+
readonly cornerRadius: {
|
|
297
|
+
readonly key: "cornerRadius";
|
|
298
|
+
readonly defaultValue: "none" | "soft" | "round";
|
|
299
|
+
readonly valueType: "string";
|
|
300
|
+
readonly allowedValues: readonly ["none", "soft", "round"];
|
|
301
|
+
readonly valueSchema: {
|
|
302
|
+
readonly type: "string";
|
|
303
|
+
readonly enum: readonly ["none", "soft", "round"];
|
|
304
|
+
};
|
|
305
|
+
readonly description: string;
|
|
306
|
+
readonly literal: {
|
|
307
|
+
readonly kind: "text";
|
|
308
|
+
readonly label: string;
|
|
309
|
+
readonly help: string;
|
|
310
|
+
};
|
|
311
|
+
readonly scope: "storefront";
|
|
312
|
+
readonly allowedLayers: readonly ["GLOBAL", "WEB", "WEB#store"];
|
|
313
|
+
readonly audience: "public";
|
|
314
|
+
readonly lifecycle: "release-owned";
|
|
315
|
+
readonly storage: {
|
|
316
|
+
readonly policy: "GLOBALS";
|
|
317
|
+
readonly override: "design.settings";
|
|
318
|
+
};
|
|
319
|
+
readonly ownership: "storefront-design";
|
|
320
|
+
};
|
|
321
|
+
readonly buttonStyle: {
|
|
322
|
+
readonly key: "buttonStyle";
|
|
323
|
+
readonly defaultValue: "filled" | "outlined" | "pill";
|
|
324
|
+
readonly valueType: "string";
|
|
325
|
+
readonly allowedValues: readonly ["filled", "outlined", "pill"];
|
|
326
|
+
readonly valueSchema: {
|
|
327
|
+
readonly type: "string";
|
|
328
|
+
readonly enum: readonly ["filled", "outlined", "pill"];
|
|
329
|
+
};
|
|
330
|
+
readonly description: string;
|
|
331
|
+
readonly literal: {
|
|
332
|
+
readonly kind: "text";
|
|
333
|
+
readonly label: string;
|
|
334
|
+
readonly help: string;
|
|
335
|
+
};
|
|
336
|
+
readonly scope: "storefront";
|
|
337
|
+
readonly allowedLayers: readonly ["GLOBAL", "WEB", "WEB#store"];
|
|
338
|
+
readonly audience: "public";
|
|
339
|
+
readonly lifecycle: "release-owned";
|
|
340
|
+
readonly storage: {
|
|
341
|
+
readonly policy: "GLOBALS";
|
|
342
|
+
readonly override: "design.settings";
|
|
343
|
+
};
|
|
344
|
+
readonly ownership: "storefront-design";
|
|
345
|
+
};
|
|
346
|
+
readonly layoutDensity: {
|
|
347
|
+
readonly key: "layoutDensity";
|
|
348
|
+
readonly defaultValue: "comfortable" | "dense";
|
|
349
|
+
readonly valueType: "string";
|
|
350
|
+
readonly allowedValues: readonly ["comfortable", "dense"];
|
|
351
|
+
readonly valueSchema: {
|
|
352
|
+
readonly type: "string";
|
|
353
|
+
readonly enum: readonly ["comfortable", "dense"];
|
|
354
|
+
};
|
|
355
|
+
readonly description: string;
|
|
356
|
+
readonly literal: {
|
|
357
|
+
readonly kind: "text";
|
|
358
|
+
readonly label: string;
|
|
359
|
+
readonly help: string;
|
|
360
|
+
};
|
|
361
|
+
readonly scope: "storefront";
|
|
362
|
+
readonly allowedLayers: readonly ["GLOBAL", "WEB", "WEB#store"];
|
|
363
|
+
readonly audience: "public";
|
|
364
|
+
readonly lifecycle: "release-owned";
|
|
365
|
+
readonly storage: {
|
|
366
|
+
readonly policy: "GLOBALS";
|
|
367
|
+
readonly override: "design.settings";
|
|
368
|
+
};
|
|
369
|
+
readonly ownership: "storefront-design";
|
|
370
|
+
};
|
|
296
371
|
readonly showBrand: {
|
|
297
372
|
readonly key: "showBrand";
|
|
298
373
|
readonly defaultValue: boolean;
|
|
@@ -626,6 +701,81 @@ export declare const STOREFRONT_DESIGN_REGISTRY: {
|
|
|
626
701
|
};
|
|
627
702
|
readonly ownership: "storefront-design";
|
|
628
703
|
};
|
|
704
|
+
readonly cornerRadius: {
|
|
705
|
+
readonly key: "cornerRadius";
|
|
706
|
+
readonly defaultValue: "none" | "soft" | "round";
|
|
707
|
+
readonly valueType: "string";
|
|
708
|
+
readonly allowedValues: readonly ["none", "soft", "round"];
|
|
709
|
+
readonly valueSchema: {
|
|
710
|
+
readonly type: "string";
|
|
711
|
+
readonly enum: readonly ["none", "soft", "round"];
|
|
712
|
+
};
|
|
713
|
+
readonly description: string;
|
|
714
|
+
readonly literal: {
|
|
715
|
+
readonly kind: "text";
|
|
716
|
+
readonly label: string;
|
|
717
|
+
readonly help: string;
|
|
718
|
+
};
|
|
719
|
+
readonly scope: "storefront";
|
|
720
|
+
readonly allowedLayers: readonly ["GLOBAL", "WEB", "WEB#store"];
|
|
721
|
+
readonly audience: "public";
|
|
722
|
+
readonly lifecycle: "release-owned";
|
|
723
|
+
readonly storage: {
|
|
724
|
+
readonly policy: "GLOBALS";
|
|
725
|
+
readonly override: "design.settings";
|
|
726
|
+
};
|
|
727
|
+
readonly ownership: "storefront-design";
|
|
728
|
+
};
|
|
729
|
+
readonly buttonStyle: {
|
|
730
|
+
readonly key: "buttonStyle";
|
|
731
|
+
readonly defaultValue: "filled" | "outlined" | "pill";
|
|
732
|
+
readonly valueType: "string";
|
|
733
|
+
readonly allowedValues: readonly ["filled", "outlined", "pill"];
|
|
734
|
+
readonly valueSchema: {
|
|
735
|
+
readonly type: "string";
|
|
736
|
+
readonly enum: readonly ["filled", "outlined", "pill"];
|
|
737
|
+
};
|
|
738
|
+
readonly description: string;
|
|
739
|
+
readonly literal: {
|
|
740
|
+
readonly kind: "text";
|
|
741
|
+
readonly label: string;
|
|
742
|
+
readonly help: string;
|
|
743
|
+
};
|
|
744
|
+
readonly scope: "storefront";
|
|
745
|
+
readonly allowedLayers: readonly ["GLOBAL", "WEB", "WEB#store"];
|
|
746
|
+
readonly audience: "public";
|
|
747
|
+
readonly lifecycle: "release-owned";
|
|
748
|
+
readonly storage: {
|
|
749
|
+
readonly policy: "GLOBALS";
|
|
750
|
+
readonly override: "design.settings";
|
|
751
|
+
};
|
|
752
|
+
readonly ownership: "storefront-design";
|
|
753
|
+
};
|
|
754
|
+
readonly layoutDensity: {
|
|
755
|
+
readonly key: "layoutDensity";
|
|
756
|
+
readonly defaultValue: "comfortable" | "dense";
|
|
757
|
+
readonly valueType: "string";
|
|
758
|
+
readonly allowedValues: readonly ["comfortable", "dense"];
|
|
759
|
+
readonly valueSchema: {
|
|
760
|
+
readonly type: "string";
|
|
761
|
+
readonly enum: readonly ["comfortable", "dense"];
|
|
762
|
+
};
|
|
763
|
+
readonly description: string;
|
|
764
|
+
readonly literal: {
|
|
765
|
+
readonly kind: "text";
|
|
766
|
+
readonly label: string;
|
|
767
|
+
readonly help: string;
|
|
768
|
+
};
|
|
769
|
+
readonly scope: "storefront";
|
|
770
|
+
readonly allowedLayers: readonly ["GLOBAL", "WEB", "WEB#store"];
|
|
771
|
+
readonly audience: "public";
|
|
772
|
+
readonly lifecycle: "release-owned";
|
|
773
|
+
readonly storage: {
|
|
774
|
+
readonly policy: "GLOBALS";
|
|
775
|
+
readonly override: "design.settings";
|
|
776
|
+
};
|
|
777
|
+
readonly ownership: "storefront-design";
|
|
778
|
+
};
|
|
629
779
|
readonly showBrand: {
|
|
630
780
|
readonly key: "showBrand";
|
|
631
781
|
readonly defaultValue: boolean;
|
|
@@ -47,6 +47,15 @@ export const STOREFRONT_DESIGN_SETTINGS = {
|
|
|
47
47
|
textSize: choice('textSize', ['compact', 'standard', 'large'], 'standard', 'Tamaño de texto', 'Escala de texto de la tienda.'),
|
|
48
48
|
cardImageRatio: choice('cardImageRatio', ['square', 'portrait'], 'square', 'Proporción de imágenes', 'Proporción de las imágenes en las tarjetas de productos.'),
|
|
49
49
|
cardDensity: choice('cardDensity', ['compact', 'spacious'], 'spacious', 'Espaciado de tarjetas', 'Espaciado entre los elementos de las tarjetas.'),
|
|
50
|
+
/*
|
|
51
|
+
* The three shape settings take values no other setting uses (`compact`, `standard`, `square`,
|
|
52
|
+
* `large`, `spacious` are taken): the editor labels an option by its value alone. Each default
|
|
53
|
+
* reproduces the tokens every shop rendered before they existed, so a publication that lacks
|
|
54
|
+
* them resolves exactly as before and `STOREFRONT_DEFAULTS_VERSION` does not move.
|
|
55
|
+
*/
|
|
56
|
+
cornerRadius: choice('cornerRadius', ['none', 'soft', 'round'], 'soft', 'Bordes', 'Elegí cuánto se redondean las tarjetas, los botones y los campos.'),
|
|
57
|
+
buttonStyle: choice('buttonStyle', ['filled', 'outlined', 'pill'], 'filled', 'Estilo de botones', 'Elegí si los botones van rellenos, con contorno o con forma de píldora.'),
|
|
58
|
+
layoutDensity: choice('layoutDensity', ['comfortable', 'dense'], 'comfortable', 'Densidad', 'Elegí cuánto espacio dejás entre los elementos de toda la tienda.'),
|
|
50
59
|
showBrand: toggle('showBrand', false, 'Mostrar marca', 'Mostrar la marca en las tarjetas de productos.'),
|
|
51
60
|
showSku: toggle('showSku', false, 'Mostrar SKU', 'Mostrar el código SKU en las tarjetas de productos.'),
|
|
52
61
|
};
|
|
@@ -43,10 +43,26 @@ export interface StorefrontResolvedTheme {
|
|
|
43
43
|
h5: number;
|
|
44
44
|
h6: number;
|
|
45
45
|
};
|
|
46
|
+
/** `cornerRadius`: `none` 0, `soft` 4, `round` 12 px. Cards, buttons and fields share it. */
|
|
46
47
|
shape: {
|
|
47
48
|
borderRadius: number;
|
|
48
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* The MUI spacing unit, from `layoutDensity`: `comfortable` 8, `dense` 6. It scales every
|
|
52
|
+
* spacing call in the shop (header and sidebar included), so it overlaps `cardDensity`, which
|
|
53
|
+
* only spaces the product card's own contents.
|
|
54
|
+
*/
|
|
49
55
|
spacing: number;
|
|
56
|
+
/**
|
|
57
|
+
* How buttons are drawn, from `buttonStyle`. `filled` and `outlined` take the shape radius;
|
|
58
|
+
* `pill` is `filled` with a 999 px radius. An `outlined` button has no token of its own: its
|
|
59
|
+
* border is the surface's `button.background` (at least 3:1 against the surface) and its text
|
|
60
|
+
* the surface's `link` (at least 4.5:1).
|
|
61
|
+
*/
|
|
62
|
+
buttons: {
|
|
63
|
+
variant: 'filled' | 'outlined';
|
|
64
|
+
borderRadius: number;
|
|
65
|
+
};
|
|
50
66
|
warnings: StorefrontThemeWarning[];
|
|
51
67
|
}
|
|
52
68
|
export declare const storefrontContrastRatio: (foreground: string, background: string) => number;
|
|
@@ -74,7 +90,8 @@ export declare const resolveStorefrontEffectiveSettings: (overrides?: Partial<St
|
|
|
74
90
|
* already-effective settings as `overrides` rebuilds the same tokens.
|
|
75
91
|
*
|
|
76
92
|
* `warnings` names only adjustments the design itself caused: the adjusted colour, or the
|
|
77
|
-
* background of the surface it sits on, is set in `overrides
|
|
93
|
+
* background of the surface it sits on, is set in `overrides`, or (for the `button` and `link`
|
|
94
|
+
* roles) `overrides` chose an `outlined` `buttonStyle`, which draws the button with both. No single colour reads at 4.5:1 on
|
|
78
95
|
* both a white page and its dark-mode counterpart, so a platform or GLOBAL default is always
|
|
79
96
|
* adjusted somewhere, and a shop that chose nothing has nothing to act on. Pass the design's own
|
|
80
97
|
* settings, not effective ones, or every default reads as chosen.
|
package/dist/storefrontTheme.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { resolveStorefrontDesignSettings, validateStorefrontDesignSetting, } from "./storefrontDesignRegistry.js";
|
|
2
|
+
const CORNER_RADIUS = { none: 0, soft: 4, round: 12 };
|
|
3
|
+
const LAYOUT_SPACING = { comfortable: 8, dense: 6 };
|
|
4
|
+
const PILL_RADIUS = 999;
|
|
5
|
+
const buttonTokens = (style, borderRadius) => style === 'pill' ? { variant: 'filled', borderRadius: PILL_RADIUS } : { variant: style, borderRadius };
|
|
6
|
+
/*
|
|
7
|
+
* An outlined button draws with the `button` colour as its border and the `link` colour as its
|
|
8
|
+
* text, so a design that chose `outlined` caused any adjustment to either: both are reported.
|
|
9
|
+
*/
|
|
10
|
+
const OUTLINED_ROLES = new Set(['button', 'link']);
|
|
2
11
|
/*
|
|
3
12
|
* The one binding of a warning role and of a surface to the setting it reads: `surfaceTokens`
|
|
4
13
|
* and `makeMode` read the colours THROUGH these maps, and the `warnings` filter judges by them,
|
|
@@ -107,7 +116,8 @@ export const resolveStorefrontEffectiveSettings = (overrides = {}, globalsRow) =
|
|
|
107
116
|
* already-effective settings as `overrides` rebuilds the same tokens.
|
|
108
117
|
*
|
|
109
118
|
* `warnings` names only adjustments the design itself caused: the adjusted colour, or the
|
|
110
|
-
* background of the surface it sits on, is set in `overrides
|
|
119
|
+
* background of the surface it sits on, is set in `overrides`, or (for the `button` and `link`
|
|
120
|
+
* roles) `overrides` chose an `outlined` `buttonStyle`, which draws the button with both. No single colour reads at 4.5:1 on
|
|
111
121
|
* both a white page and its dark-mode counterpart, so a platform or GLOBAL default is always
|
|
112
122
|
* adjusted somewhere, and a shop that chose nothing has nothing to act on. Pass the design's own
|
|
113
123
|
* settings, not effective ones, or every default reads as chosen.
|
|
@@ -121,6 +131,8 @@ export const resolveStorefrontTheme = (overrides = {}, globalsRow) => {
|
|
|
121
131
|
return { page: surface('page'), header: surface('header'), footer: surface('footer') };
|
|
122
132
|
};
|
|
123
133
|
const scale = { compact: 0.875, standard: 1, large: 1.125 }[settings.textSize];
|
|
134
|
+
const borderRadius = CORNER_RADIUS[settings.cornerRadius];
|
|
135
|
+
const outlinedChosen = overrides.buttonStyle !== undefined && settings.buttonStyle === 'outlined';
|
|
124
136
|
return {
|
|
125
137
|
requested: settings,
|
|
126
138
|
light: makeMode('light'),
|
|
@@ -138,8 +150,11 @@ export const resolveStorefrontTheme = (overrides = {}, globalsRow) => {
|
|
|
138
150
|
h5: 24 * scale,
|
|
139
151
|
h6: 20 * scale,
|
|
140
152
|
},
|
|
141
|
-
shape: { borderRadius
|
|
142
|
-
spacing:
|
|
143
|
-
|
|
153
|
+
shape: { borderRadius },
|
|
154
|
+
spacing: LAYOUT_SPACING[settings.layoutDensity],
|
|
155
|
+
buttons: buttonTokens(settings.buttonStyle, borderRadius),
|
|
156
|
+
warnings: warnings.filter(({ role, surface }) => overrides[WARNING_SETTING[role]] !== undefined ||
|
|
157
|
+
overrides[SURFACE_SETTING[surface]] !== undefined ||
|
|
158
|
+
(outlinedChosen && OUTLINED_ROLES.has(role))),
|
|
144
159
|
};
|
|
145
160
|
};
|
|
@@ -408,8 +408,10 @@ export const STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
|
|
|
408
408
|
'CHECKOUT_MIN_BUY_ALERT',
|
|
409
409
|
'CHECKOUT_MIN_BUY_ERROR',
|
|
410
410
|
'CHECKOUT_MIN_BUY_REFUSED',
|
|
411
|
+
'CHECKOUT_NO_DELIVERY_METHODS_FOR_ACCOUNT',
|
|
411
412
|
'CHECKOUT_NO_INVOICE',
|
|
412
413
|
'CHECKOUT_NO_INVOICE_OPTION',
|
|
414
|
+
'CHECKOUT_NO_PAYMENT_METHODS_FOR_ACCOUNT',
|
|
413
415
|
'CHECKOUT_ORDER_CREATED',
|
|
414
416
|
'CHECKOUT_ORDER_CREATION_ERROR',
|
|
415
417
|
'CHECKOUT_ORDER_IN_PROGRESS',
|
|
@@ -926,6 +928,18 @@ export const STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
|
|
|
926
928
|
'ORDER_COLUMN_SKU',
|
|
927
929
|
'ORDER_COLUMN_TOTAL',
|
|
928
930
|
'ORDER_COMMENTS_TOOLTIP',
|
|
931
|
+
'ORDER_DELIVERY_CONTACT_PHONE',
|
|
932
|
+
'ORDER_DELIVERY_CONTACT_WHATSAPP',
|
|
933
|
+
'ORDER_DELIVERY_ETA',
|
|
934
|
+
'ORDER_DELIVERY_FAILED_NEXT_STEP',
|
|
935
|
+
'ORDER_DELIVERY_METHOD_FALLBACK',
|
|
936
|
+
'ORDER_DELIVERY_NEXT_DATE',
|
|
937
|
+
'ORDER_DELIVERY_STATUS_ASSIGNED',
|
|
938
|
+
'ORDER_DELIVERY_STATUS_DELIVERED',
|
|
939
|
+
'ORDER_DELIVERY_STATUS_FAILED',
|
|
940
|
+
'ORDER_DELIVERY_STATUS_IN_TRANSIT',
|
|
941
|
+
'ORDER_DELIVERY_STATUS_PICKED_UP',
|
|
942
|
+
'ORDER_DELIVERY_UPDATED',
|
|
929
943
|
'ORDER_DISABLED_ALERT',
|
|
930
944
|
'ORDER_DISCOUNT_LABEL',
|
|
931
945
|
'ORDER_ERROR',
|
|
@@ -936,6 +950,7 @@ export const STOREFRONT_WEB_LITERAL_KEYS = Object.freeze([
|
|
|
936
950
|
'ORDER_NAV_PREV',
|
|
937
951
|
'ORDER_PAYMENT_CHARGED_BACK',
|
|
938
952
|
'ORDER_PAYMENT_EXPIRED',
|
|
953
|
+
'ORDER_PAYMENT_METHOD_FALLBACK',
|
|
939
954
|
'ORDER_PAYMENT_NOT_STARTED',
|
|
940
955
|
'ORDER_PAYMENT_PAID',
|
|
941
956
|
'ORDER_PAYMENT_PAY',
|