riverbankcms 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acceptance/matrix.mjs +3 -3
- package/dist/cli/index.mjs +1676 -1215
- package/dist/cli/init-docs/content/cli-reference.md +2 -0
- package/dist/cli/init-docs/content/content-management.md +3 -1
- package/dist/{eventUpsertInputSchema-BE3nSNsn.mjs → eventUpsertInputSchema-yErCHdr6.mjs} +2 -2
- package/dist/load-config-BToL9PfS.mjs +4 -0
- package/dist/{load-config-De0cFlPg.mjs → load-config-Bzc6Qo24.mjs} +2 -2
- package/dist/{local-sync-EcUwLrRx.mjs → local-sync-3ZG1khGb.mjs} +12 -3
- package/dist/{plan-DtQEnwCM.mjs → plan-C1Frmu6F.mjs} +1 -1
- package/dist/scaffold/index.mjs +2 -2
- package/dist/{sdk-event-upsert-Bf6wAl4s.mjs → sdk-event-upsert-DhdlT2ko.mjs} +2258 -1848
- package/dist/{src-B8fOSKJ6.mjs → src-DIAVNRwo.mjs} +195 -1
- package/dist/testing.mjs +3 -3
- package/package.json +1 -1
- package/dist/load-config-Ca13nCpT.mjs +0 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { A as parseFooterCompositionV1, Ht as
|
|
2
|
+
import { A as parseFooterCompositionV1, Ht as err, M as isCanonicalRichTextDoc, P as isPresent, Ut as ok, Z as parseBookingTimeZone, b as stableJsonStringify, k as footerNavigationLayouts, l as EVENT_PRESET_VALUES, n as NAVIGATION_LOCATIONS, q as parseUtcIsoDateTimeString, s as resolveSiteVerticalBookingConfig, u as ORDINARY_EVENT_PRESET_VALUES, ut as assertNever } from "./src-DIAVNRwo.mjs";
|
|
3
3
|
import "node:module";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
@@ -61,41 +61,6 @@ function siteCommandResourceResult(ref, resourceId, effect) {
|
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
//#endregion
|
|
65
|
-
//#region ../site-commands/src/capabilityGaps.ts
|
|
66
|
-
const staticExecutionGapCodes = [
|
|
67
|
-
"event_occurrence_required",
|
|
68
|
-
"event_occurrence_invalid",
|
|
69
|
-
"event_occurrence_venue_mapping_unsupported",
|
|
70
|
-
"event_booking_offer_invalid",
|
|
71
|
-
"event_ticket_single_occurrence_scope_unsupported",
|
|
72
|
-
"event_manual_payment_unsupported",
|
|
73
|
-
"event_external_payment_unsupported",
|
|
74
|
-
"event_waitlist_requires_waitlist_adapter",
|
|
75
|
-
"event_media_content_requires_media_adapter",
|
|
76
|
-
"event_linked_content_requires_content_adapter",
|
|
77
|
-
"event_delivery_mode_requires_booking_surface_adapter",
|
|
78
|
-
"event_whole_series_page_fields_unsupported",
|
|
79
|
-
"event_whole_series_passes_unsupported",
|
|
80
|
-
"event_whole_series_pricing_unsupported",
|
|
81
|
-
"event_whole_series_schedule_update_unsupported",
|
|
82
|
-
"event_whole_series_staff_update_unsupported"
|
|
83
|
-
];
|
|
84
|
-
const plannerCapabilityGapCodes = ["command_metadata_support_gap"];
|
|
85
|
-
const adapterCapabilityGapCodes = [
|
|
86
|
-
"demo_recipe_adapter_missing",
|
|
87
|
-
"media_manifest_storage_resolution_missing",
|
|
88
|
-
"navigation_content_entry_refs_unsupported",
|
|
89
|
-
"staff_site_user_requires_dashboard_user",
|
|
90
|
-
"team_member_profile_requires_dashboard_user",
|
|
91
|
-
"generated_navigation_command_unsupported"
|
|
92
|
-
];
|
|
93
|
-
const siteCommandCapabilityGapCodes = [
|
|
94
|
-
...staticExecutionGapCodes,
|
|
95
|
-
...plannerCapabilityGapCodes,
|
|
96
|
-
...adapterCapabilityGapCodes
|
|
97
|
-
];
|
|
98
|
-
|
|
99
64
|
//#endregion
|
|
100
65
|
//#region ../site-commands/src/refs.ts
|
|
101
66
|
const resourceKinds = [
|
|
@@ -123,6 +88,7 @@ const resourceKinds = [
|
|
|
123
88
|
"pass-redemption",
|
|
124
89
|
"order",
|
|
125
90
|
"appointment-service",
|
|
91
|
+
"appointment-service-category",
|
|
126
92
|
"appointment-resource",
|
|
127
93
|
"availability"
|
|
128
94
|
];
|
|
@@ -167,6 +133,9 @@ function createVenueRef(parts) {
|
|
|
167
133
|
function createEventCategoryRef(parts) {
|
|
168
134
|
return `event-category:${joinRefSlugParts(parts)}`;
|
|
169
135
|
}
|
|
136
|
+
function createAppointmentServiceCategoryRef(parts) {
|
|
137
|
+
return `appointment-service-category:${joinRefSlugParts(parts)}`;
|
|
138
|
+
}
|
|
170
139
|
function createEventSeriesRef(parts) {
|
|
171
140
|
return `event:${joinRefSlugParts(parts)}`;
|
|
172
141
|
}
|
|
@@ -245,6 +214,118 @@ function isValidIanaTimezone(value) {
|
|
|
245
214
|
}
|
|
246
215
|
}
|
|
247
216
|
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region ../site-commands/src/appointmentServiceCategoryCommands.ts
|
|
219
|
+
const appointmentServiceCategoryRefSchema = resourceRefSchema("appointment-service-category");
|
|
220
|
+
/**
|
|
221
|
+
* Creates or updates one appointment-service category (issue 1403).
|
|
222
|
+
*
|
|
223
|
+
* The category's `identifier` is its stable key: it never changes after the
|
|
224
|
+
* category is created, so a rename in the dashboard doesn't break a rerun.
|
|
225
|
+
* When a command leaves it out, the identifier is the ref's slug, which keeps
|
|
226
|
+
* reruns of the same command pointed at the same category.
|
|
227
|
+
*
|
|
228
|
+
* `description` and `sortOrder` describe the wanted state. An omitted
|
|
229
|
+
* description means no description. An omitted `sortOrder` puts a new
|
|
230
|
+
* category last and leaves an existing one where it is.
|
|
231
|
+
*/
|
|
232
|
+
const upsertAppointmentServiceCategoryCommandSchema = z.object({
|
|
233
|
+
type: z.literal("upsertAppointmentServiceCategory"),
|
|
234
|
+
ref: appointmentServiceCategoryRefSchema,
|
|
235
|
+
input: z.object({
|
|
236
|
+
identifier: recipeIdentifierSchema.optional(),
|
|
237
|
+
name: z.string().trim().min(1),
|
|
238
|
+
description: z.string().trim().nullable().optional(),
|
|
239
|
+
sortOrder: nonNegativeIntegerSchema.optional()
|
|
240
|
+
}).strict()
|
|
241
|
+
}).strict();
|
|
242
|
+
/**
|
|
243
|
+
* The three ways a service can be placed among the categories. Each variant
|
|
244
|
+
* forbids the other key, so a command naming both a `categoryRef` and a
|
|
245
|
+
* `categoryIdentifier` can't be represented.
|
|
246
|
+
*/
|
|
247
|
+
const noAppointmentServiceCategoryFields = {
|
|
248
|
+
categoryRef: z.undefined().optional(),
|
|
249
|
+
categoryIdentifier: z.undefined().optional()
|
|
250
|
+
};
|
|
251
|
+
const appointmentServiceCategoryRefFields = {
|
|
252
|
+
categoryRef: appointmentServiceCategoryRefSchema,
|
|
253
|
+
categoryIdentifier: z.undefined().optional()
|
|
254
|
+
};
|
|
255
|
+
const appointmentServiceCategoryIdentifierFields = {
|
|
256
|
+
categoryRef: z.undefined().optional(),
|
|
257
|
+
categoryIdentifier: recipeIdentifierSchema
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Rejects a command that names both category keys with one clear message,
|
|
261
|
+
* before the union reports that no variant matched.
|
|
262
|
+
*/
|
|
263
|
+
function rejectBothAppointmentServiceCategoryKeys(value, ctx) {
|
|
264
|
+
if (typeof value !== "object" || value === null || !("categoryRef" in value) || !("categoryIdentifier" in value) || value.categoryRef === undefined || value.categoryIdentifier === undefined) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
ctx.addIssue({
|
|
268
|
+
code: "custom",
|
|
269
|
+
path: ["categoryIdentifier"],
|
|
270
|
+
message: "Use categoryRef for a category upserted in this batch, or categoryIdentifier for one that already exists, not both."
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/** Where an `upsertAppointmentService` command puts the service. */
|
|
274
|
+
function appointmentServiceCategoryPlacement(input) {
|
|
275
|
+
if (input.categoryRef !== undefined) {
|
|
276
|
+
return {
|
|
277
|
+
kind: "batch_ref",
|
|
278
|
+
categoryRef: input.categoryRef
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
if (input.categoryIdentifier !== undefined) {
|
|
282
|
+
return {
|
|
283
|
+
kind: "identifier",
|
|
284
|
+
identifier: input.categoryIdentifier
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return { kind: "uncategorized" };
|
|
288
|
+
}
|
|
289
|
+
/** The stable key an `upsertAppointmentServiceCategory` command writes to. */
|
|
290
|
+
function appointmentServiceCategoryIdentifierForCommand(command) {
|
|
291
|
+
return command.input.identifier ?? refSlug(command.ref);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region ../site-commands/src/capabilityGaps.ts
|
|
296
|
+
const staticExecutionGapCodes = [
|
|
297
|
+
"event_occurrence_required",
|
|
298
|
+
"event_occurrence_invalid",
|
|
299
|
+
"event_occurrence_venue_mapping_unsupported",
|
|
300
|
+
"event_booking_offer_invalid",
|
|
301
|
+
"event_ticket_single_occurrence_scope_unsupported",
|
|
302
|
+
"event_manual_payment_unsupported",
|
|
303
|
+
"event_external_payment_unsupported",
|
|
304
|
+
"event_waitlist_requires_waitlist_adapter",
|
|
305
|
+
"event_media_content_requires_media_adapter",
|
|
306
|
+
"event_linked_content_requires_content_adapter",
|
|
307
|
+
"event_delivery_mode_requires_booking_surface_adapter",
|
|
308
|
+
"event_whole_series_page_fields_unsupported",
|
|
309
|
+
"event_whole_series_passes_unsupported",
|
|
310
|
+
"event_whole_series_pricing_unsupported",
|
|
311
|
+
"event_whole_series_schedule_update_unsupported",
|
|
312
|
+
"event_whole_series_staff_update_unsupported"
|
|
313
|
+
];
|
|
314
|
+
const plannerCapabilityGapCodes = ["command_metadata_support_gap"];
|
|
315
|
+
const adapterCapabilityGapCodes = [
|
|
316
|
+
"demo_recipe_adapter_missing",
|
|
317
|
+
"media_manifest_storage_resolution_missing",
|
|
318
|
+
"navigation_content_entry_refs_unsupported",
|
|
319
|
+
"staff_site_user_requires_dashboard_user",
|
|
320
|
+
"team_member_profile_requires_dashboard_user",
|
|
321
|
+
"generated_navigation_command_unsupported"
|
|
322
|
+
];
|
|
323
|
+
const siteCommandCapabilityGapCodes = [
|
|
324
|
+
...staticExecutionGapCodes,
|
|
325
|
+
...plannerCapabilityGapCodes,
|
|
326
|
+
...adapterCapabilityGapCodes
|
|
327
|
+
];
|
|
328
|
+
|
|
248
329
|
//#endregion
|
|
249
330
|
//#region ../site-commands/src/bookingCommandValues.ts
|
|
250
331
|
const bookingPassProductUseCases = ["event_pass", "appointment_package"];
|
|
@@ -2449,8 +2530,8 @@ const BACKGROUND_ROLE_NAMES = new Set([
|
|
|
2449
2530
|
"muted",
|
|
2450
2531
|
"neutral"
|
|
2451
2532
|
]);
|
|
2452
|
-
function onColorTokenName(backgroundToken) {
|
|
2453
|
-
return `on${backgroundToken.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
|
|
2533
|
+
function onColorTokenName(backgroundToken$1) {
|
|
2534
|
+
return `on${backgroundToken$1.split("-").filter((part) => part.length > 0).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("")}`;
|
|
2454
2535
|
}
|
|
2455
2536
|
function isOnColorBackgroundCandidateToken(token) {
|
|
2456
2537
|
const role = token.match(/^(.*?)(?:-\d{2,3})?$/)?.[1] ?? token;
|
|
@@ -2584,8 +2665,8 @@ function resolveDeterministicForeground(backgroundReference, candidates, palette
|
|
|
2584
2665
|
if (!backgroundHex) {
|
|
2585
2666
|
return resolveTrustedTreatmentForeground(candidates, palette);
|
|
2586
2667
|
}
|
|
2587
|
-
const backgroundToken = paletteToken(backgroundReference);
|
|
2588
|
-
const derivedOnToken = backgroundToken ? onColorTokenName(backgroundToken) : null;
|
|
2668
|
+
const backgroundToken$1 = paletteToken(backgroundReference);
|
|
2669
|
+
const derivedOnToken = backgroundToken$1 ? onColorTokenName(backgroundToken$1) : null;
|
|
2589
2670
|
const text = firstSafeToken([
|
|
2590
2671
|
candidates.text,
|
|
2591
2672
|
derivedOnToken,
|
|
@@ -2658,6 +2739,37 @@ function normalizedReference(value) {
|
|
|
2658
2739
|
return normalized.length > 0 ? normalized : null;
|
|
2659
2740
|
}
|
|
2660
2741
|
|
|
2742
|
+
//#endregion
|
|
2743
|
+
//#region ../theme-core/src/surfaces/logoVariant.ts
|
|
2744
|
+
/** Concrete hex behind a plain, opaque palette token, or null otherwise. */
|
|
2745
|
+
function opaquePaletteHexForToken(expandedPalette, token) {
|
|
2746
|
+
if (!token) return null;
|
|
2747
|
+
const parts = parseColorTokenParts(token);
|
|
2748
|
+
if (parts.kind !== "token" || parts.opacityPercent !== null) return null;
|
|
2749
|
+
return expandedPalette[parts.token] ?? null;
|
|
2750
|
+
}
|
|
2751
|
+
/**
|
|
2752
|
+
* Tone of the surface a foreground token was resolved for.
|
|
2753
|
+
*
|
|
2754
|
+
* A token with opacity has no known underlay to composite against, and a raw
|
|
2755
|
+
* or unrecognised token has no palette hex, so both are `unknown` rather than
|
|
2756
|
+
* a guess.
|
|
2757
|
+
*/
|
|
2758
|
+
function surfaceToneFromForegroundToken(expandedPalette, foregroundToken) {
|
|
2759
|
+
const hex = opaquePaletteHexForToken(expandedPalette, foregroundToken);
|
|
2760
|
+
if (!hex) return "unknown";
|
|
2761
|
+
return featuresFromHex(hex).Y >= .5 ? "dark" : "light";
|
|
2762
|
+
}
|
|
2763
|
+
/**
|
|
2764
|
+
* The logo to draw on a surface of the given tone. A missing variant falls
|
|
2765
|
+
* back to the other one, and an unknown tone uses the light-backgrounds logo,
|
|
2766
|
+
* which is what every site rendered before variants existed.
|
|
2767
|
+
*/
|
|
2768
|
+
function selectLogoVariant(tone, variants) {
|
|
2769
|
+
const { forLightBackgrounds, forDarkBackgrounds } = variants;
|
|
2770
|
+
return tone === "dark" ? forDarkBackgrounds ?? forLightBackgrounds : forLightBackgrounds ?? forDarkBackgrounds;
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2661
2773
|
//#endregion
|
|
2662
2774
|
//#region ../theme-core/src/utils/colorStyles.ts
|
|
2663
2775
|
const COLOR_VAR_PREFIX = "--tb-";
|
|
@@ -2733,18 +2845,30 @@ function backgroundColorStyle(token) {
|
|
|
2733
2845
|
return { backgroundColor: rgbColorValue(token) };
|
|
2734
2846
|
}
|
|
2735
2847
|
/**
|
|
2736
|
-
*
|
|
2848
|
+
* Converts a text color token to a CSS color value that follows the enclosing
|
|
2849
|
+
* surface. The semantic text tokens (`text`, `heading`, `mutedText`) resolve
|
|
2850
|
+
* to the surface foreground variables, so text adapts when a section's
|
|
2851
|
+
* background changes; any other token is a fixed theme color.
|
|
2737
2852
|
*
|
|
2738
2853
|
* @param token - Theme color token
|
|
2739
|
-
* @returns
|
|
2854
|
+
* @returns CSS color value
|
|
2740
2855
|
*/
|
|
2741
|
-
function
|
|
2856
|
+
function textColorValue(token) {
|
|
2742
2857
|
const parsed = parseToken(token);
|
|
2743
2858
|
const surfaceRole = parsed.raw ? null : surfaceRoleForTextToken(parsed.token);
|
|
2744
|
-
if (surfaceRole) {
|
|
2745
|
-
return
|
|
2859
|
+
if (!surfaceRole) {
|
|
2860
|
+
return rgbColorValue(token);
|
|
2746
2861
|
}
|
|
2747
|
-
return
|
|
2862
|
+
return parsed.opacityPercent === undefined ? surfaceForegroundValue(surfaceRole) : surfaceForegroundValueWithOpacity(surfaceRole, parsed.opacityPercent);
|
|
2863
|
+
}
|
|
2864
|
+
/**
|
|
2865
|
+
* Creates a text color style object from a theme token.
|
|
2866
|
+
*
|
|
2867
|
+
* @param token - Theme color token
|
|
2868
|
+
* @returns CSSProperties with color
|
|
2869
|
+
*/
|
|
2870
|
+
function textColorStyle(token) {
|
|
2871
|
+
return { color: textColorValue(token) };
|
|
2748
2872
|
}
|
|
2749
2873
|
/**
|
|
2750
2874
|
* Creates a border color style object from a theme token.
|
|
@@ -4573,16 +4697,18 @@ const themeV2RuntimeStyleFieldNames = [
|
|
|
4573
4697
|
"_frameStyles",
|
|
4574
4698
|
"_sectionStyles",
|
|
4575
4699
|
"_containerStyles",
|
|
4576
|
-
"_cardStyles"
|
|
4577
|
-
"_transitionStyles",
|
|
4578
|
-
"styleGroup"
|
|
4700
|
+
"_cardStyles"
|
|
4579
4701
|
];
|
|
4580
4702
|
const themeV2BlockSpecificRawStyleFieldNames = [
|
|
4581
4703
|
"_contentCardStyles",
|
|
4582
4704
|
"_heroLayoutStyles",
|
|
4583
4705
|
"_textCardStyles"
|
|
4584
4706
|
];
|
|
4585
|
-
const themeV2NormalEditorRawStyleFieldNames = [
|
|
4707
|
+
const themeV2NormalEditorRawStyleFieldNames = [
|
|
4708
|
+
...themeV2RuntimeStyleFieldNames,
|
|
4709
|
+
...themeV2BlockSpecificRawStyleFieldNames,
|
|
4710
|
+
"styleGroup"
|
|
4711
|
+
];
|
|
4586
4712
|
const themeV2NormalEditorRawStyleFieldNameSet = new Set(themeV2NormalEditorRawStyleFieldNames);
|
|
4587
4713
|
const themeV2CompilerOwnedFieldNames = [...themeV2RuntimeStyleFieldNames, ...themeV2BlockSpecificRawStyleFieldNames];
|
|
4588
4714
|
const pageDesignEditorBackgroundOverrideOwner = "page-design-editor";
|
|
@@ -4594,6 +4720,21 @@ function isThemeV2NormalEditorRawStylePath(fieldPath) {
|
|
|
4594
4720
|
const rootField = fieldPath.split(".")[0] ?? "";
|
|
4595
4721
|
return isThemeV2NormalEditorRawStyleFieldName(rootField);
|
|
4596
4722
|
}
|
|
4723
|
+
const staleTransitionStyleGroupPrefix = "site-style-transition-";
|
|
4724
|
+
/**
|
|
4725
|
+
* A `styleGroup` in the retired `site-style-transition-*` namespace is residue
|
|
4726
|
+
* from the old per-block transition path (issue 1422). Any other value is
|
|
4727
|
+
* authored and must survive.
|
|
4728
|
+
*/
|
|
4729
|
+
function isStaleTransitionStyleGroup(value) {
|
|
4730
|
+
return typeof value === "string" && value.startsWith(staleTransitionStyleGroupPrefix);
|
|
4731
|
+
}
|
|
4732
|
+
/** Drops a stale transition `styleGroup`, leaving authored values untouched. */
|
|
4733
|
+
function stripStaleTransitionStyleGroup(content) {
|
|
4734
|
+
if (!isStaleTransitionStyleGroup(content.styleGroup)) return { ...content };
|
|
4735
|
+
const { styleGroup: _stale, ...rest } = content;
|
|
4736
|
+
return rest;
|
|
4737
|
+
}
|
|
4597
4738
|
|
|
4598
4739
|
//#endregion
|
|
4599
4740
|
//#region ../theme-core/src/utils/tokenOrColor.ts
|
|
@@ -6657,10 +6798,10 @@ function resolveFocusIndicator(colour) {
|
|
|
6657
6798
|
};
|
|
6658
6799
|
}
|
|
6659
6800
|
}
|
|
6660
|
-
function resolveSolid(input, backgroundToken) {
|
|
6661
|
-
const backgroundHex = paletteHex(input, backgroundToken);
|
|
6801
|
+
function resolveSolid(input, backgroundToken$1) {
|
|
6802
|
+
const backgroundHex = paletteHex(input, backgroundToken$1);
|
|
6662
6803
|
if (!backgroundHex.ok) return backgroundHex;
|
|
6663
|
-
const foregroundToken = unsafeAsOpaqueButtonColourToken(onColorTokenName(backgroundToken));
|
|
6804
|
+
const foregroundToken = unsafeAsOpaqueButtonColourToken(onColorTokenName(backgroundToken$1));
|
|
6664
6805
|
const foregroundHex = input.palette[foregroundToken];
|
|
6665
6806
|
if (typeof foregroundHex !== "string") {
|
|
6666
6807
|
return {
|
|
@@ -6669,14 +6810,14 @@ function resolveSolid(input, backgroundToken) {
|
|
|
6669
6810
|
tag: "missing_on_colour",
|
|
6670
6811
|
variantId: input.variantId,
|
|
6671
6812
|
state: input.state,
|
|
6672
|
-
backgroundToken,
|
|
6813
|
+
backgroundToken: backgroundToken$1,
|
|
6673
6814
|
foregroundToken
|
|
6674
6815
|
}
|
|
6675
6816
|
};
|
|
6676
6817
|
}
|
|
6677
6818
|
const contrast = validateButtonTextContrast({
|
|
6678
6819
|
...input,
|
|
6679
|
-
background: backgroundToken,
|
|
6820
|
+
background: backgroundToken$1,
|
|
6680
6821
|
backgroundHex: backgroundHex.hex,
|
|
6681
6822
|
foreground: foregroundToken,
|
|
6682
6823
|
foregroundHex
|
|
@@ -6694,9 +6835,9 @@ function resolveSolid(input, backgroundToken) {
|
|
|
6694
6835
|
ok: true,
|
|
6695
6836
|
colour: {
|
|
6696
6837
|
kind: "solid",
|
|
6697
|
-
backgroundToken,
|
|
6838
|
+
backgroundToken: backgroundToken$1,
|
|
6698
6839
|
foregroundToken,
|
|
6699
|
-
backgroundCss: tokenCss(backgroundToken),
|
|
6840
|
+
backgroundCss: tokenCss(backgroundToken$1),
|
|
6700
6841
|
foregroundCss: tokenCss(foregroundToken)
|
|
6701
6842
|
}
|
|
6702
6843
|
};
|
|
@@ -6930,7 +7071,7 @@ function parseThemeForPersistence(value) {
|
|
|
6930
7071
|
* overriding the twelve styles that deliberately declare none. Whether a button
|
|
6931
7072
|
* carries a trailing affordance is the style's decision; the only caller that
|
|
6932
7073
|
* legitimately opts out is the authored-button renderer, which reaches it
|
|
6933
|
-
* through `
|
|
7074
|
+
* through `themeButtonExtraClassesWithTrailingIcon`.
|
|
6934
7075
|
*/
|
|
6935
7076
|
const AFFORDANCE_SUPPRESS_CLASS = "rb-affordance-off";
|
|
6936
7077
|
|
|
@@ -6970,19 +7111,10 @@ function themeButtonSelector(variant, size) {
|
|
|
6970
7111
|
}
|
|
6971
7112
|
return `${baseSelector}.${themeButtonSizeClassName(size)}`;
|
|
6972
7113
|
}
|
|
6973
|
-
function themeButtonClassName(spec) {
|
|
6974
|
-
const classes = [
|
|
6975
|
-
...themeButtonVariantClassNames(spec.variant),
|
|
6976
|
-
themeButtonSizeClassName(spec.size),
|
|
6977
|
-
spec.extraClassName
|
|
6978
|
-
];
|
|
6979
|
-
return classes.filter(Boolean).join(" ");
|
|
6980
|
-
}
|
|
6981
7114
|
/**
|
|
6982
|
-
*
|
|
7115
|
+
* Extra classes for an authored button that renders its own trailing icon.
|
|
6983
7116
|
*
|
|
6984
|
-
*
|
|
6985
|
-
* there is exactly one caller and it should stay visible in a diff. The name
|
|
7117
|
+
* This intent-named function has exactly one caller. The name
|
|
6986
7118
|
* states what the caller knows to be true of its own markup — that it renders a
|
|
6987
7119
|
* trailing icon — rather than what the theme does about it. The consequence is
|
|
6988
7120
|
* the theme's to decide and to change; a caller naming the consequence would be
|
|
@@ -6993,11 +7125,8 @@ function themeButtonClassName(spec) {
|
|
|
6993
7125
|
* affordance is declared by the button style, and a block overriding that is the
|
|
6994
7126
|
* defect this replaced.
|
|
6995
7127
|
*/
|
|
6996
|
-
function
|
|
6997
|
-
return
|
|
6998
|
-
...spec,
|
|
6999
|
-
extraClassName: [spec.extraClassName, AFFORDANCE_SUPPRESS_CLASS].filter(Boolean).join(" ")
|
|
7000
|
-
});
|
|
7128
|
+
function themeButtonExtraClassesWithTrailingIcon() {
|
|
7129
|
+
return AFFORDANCE_SUPPRESS_CLASS;
|
|
7001
7130
|
}
|
|
7002
7131
|
|
|
7003
7132
|
//#endregion
|
|
@@ -13407,11 +13536,11 @@ const TEXT_CONTRAST_THRESHOLD = 3;
|
|
|
13407
13536
|
* @param palette - Palette with color tokens (either ExpandedPalette or simple Record<string, string>)
|
|
13408
13537
|
* @returns Array of text color token names that meet contrast threshold (3:1)
|
|
13409
13538
|
*/
|
|
13410
|
-
function getLegibleTextColors(backgroundToken, palette) {
|
|
13411
|
-
if (!backgroundToken) {
|
|
13539
|
+
function getLegibleTextColors(backgroundToken$1, palette) {
|
|
13540
|
+
if (!backgroundToken$1) {
|
|
13412
13541
|
return getAllColorTokens(palette);
|
|
13413
13542
|
}
|
|
13414
|
-
const bgHex = palette[backgroundToken];
|
|
13543
|
+
const bgHex = palette[backgroundToken$1];
|
|
13415
13544
|
if (!bgHex || typeof bgHex !== "string") {
|
|
13416
13545
|
return getAllColorTokens(palette);
|
|
13417
13546
|
}
|
|
@@ -15300,12 +15429,12 @@ function resolveAccessibleSurface(input) {
|
|
|
15300
15429
|
const rejectedCandidates = [];
|
|
15301
15430
|
const recipe = surfaceRecipes[input.surface];
|
|
15302
15431
|
const threshold = contrastThresholdByPolicy[input.policy ?? "body-aa"];
|
|
15303
|
-
for (const backgroundToken of recipe.backgroundCandidates) {
|
|
15304
|
-
const backgroundHex = readPaletteHex(input.palette, backgroundToken);
|
|
15432
|
+
for (const backgroundToken$1 of recipe.backgroundCandidates) {
|
|
15433
|
+
const backgroundHex = readPaletteHex(input.palette, backgroundToken$1);
|
|
15305
15434
|
if (!backgroundHex) {
|
|
15306
15435
|
rejectedCandidates.push({
|
|
15307
15436
|
kind: "background-candidate",
|
|
15308
|
-
token: backgroundToken,
|
|
15437
|
+
token: backgroundToken$1,
|
|
15309
15438
|
reason: "missing-token"
|
|
15310
15439
|
});
|
|
15311
15440
|
continue;
|
|
@@ -15313,7 +15442,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15313
15442
|
const heading = resolveRequiredForeground({
|
|
15314
15443
|
role: "heading",
|
|
15315
15444
|
candidates: recipe.headingCandidates,
|
|
15316
|
-
backgroundToken,
|
|
15445
|
+
backgroundToken: backgroundToken$1,
|
|
15317
15446
|
backgroundHex,
|
|
15318
15447
|
palette: input.palette,
|
|
15319
15448
|
threshold,
|
|
@@ -15322,7 +15451,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15322
15451
|
const text = resolveRequiredForeground({
|
|
15323
15452
|
role: "text",
|
|
15324
15453
|
candidates: recipe.textCandidates,
|
|
15325
|
-
backgroundToken,
|
|
15454
|
+
backgroundToken: backgroundToken$1,
|
|
15326
15455
|
backgroundHex,
|
|
15327
15456
|
palette: input.palette,
|
|
15328
15457
|
threshold,
|
|
@@ -15331,7 +15460,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15331
15460
|
const link = resolveRequiredForeground({
|
|
15332
15461
|
role: "link",
|
|
15333
15462
|
candidates: recipe.linkCandidates,
|
|
15334
|
-
backgroundToken,
|
|
15463
|
+
backgroundToken: backgroundToken$1,
|
|
15335
15464
|
backgroundHex,
|
|
15336
15465
|
palette: input.palette,
|
|
15337
15466
|
threshold,
|
|
@@ -15340,7 +15469,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15340
15469
|
if (!heading || !text || !link) continue;
|
|
15341
15470
|
const supporting = resolveSupportingForeground({
|
|
15342
15471
|
candidates: recipe.supportingCandidates,
|
|
15343
|
-
backgroundToken,
|
|
15472
|
+
backgroundToken: backgroundToken$1,
|
|
15344
15473
|
backgroundHex,
|
|
15345
15474
|
text,
|
|
15346
15475
|
palette: input.palette,
|
|
@@ -15351,7 +15480,7 @@ function resolveAccessibleSurface(input) {
|
|
|
15351
15480
|
kind: "resolved-accessible-surface",
|
|
15352
15481
|
surface: input.surface,
|
|
15353
15482
|
background: {
|
|
15354
|
-
token: asAccessibleSurfaceToken(backgroundToken),
|
|
15483
|
+
token: asAccessibleSurfaceToken(backgroundToken$1),
|
|
15355
15484
|
hex: backgroundHex,
|
|
15356
15485
|
inherited: recipe.inheritedBackground
|
|
15357
15486
|
},
|
|
@@ -15450,23 +15579,23 @@ function resolveSafeToken(input) {
|
|
|
15450
15579
|
}
|
|
15451
15580
|
return null;
|
|
15452
15581
|
}
|
|
15453
|
-
function expandForegroundCandidates(candidates, backgroundToken) {
|
|
15582
|
+
function expandForegroundCandidates(candidates, backgroundToken$1) {
|
|
15454
15583
|
const seen = new Set();
|
|
15455
15584
|
const expanded = [];
|
|
15456
15585
|
for (const candidate$1 of candidates) {
|
|
15457
|
-
const token = expandForegroundCandidate(candidate$1, backgroundToken);
|
|
15586
|
+
const token = expandForegroundCandidate(candidate$1, backgroundToken$1);
|
|
15458
15587
|
if (seen.has(token)) continue;
|
|
15459
15588
|
seen.add(token);
|
|
15460
15589
|
expanded.push(token);
|
|
15461
15590
|
}
|
|
15462
15591
|
return expanded;
|
|
15463
15592
|
}
|
|
15464
|
-
function expandForegroundCandidate(candidate$1, backgroundToken) {
|
|
15593
|
+
function expandForegroundCandidate(candidate$1, backgroundToken$1) {
|
|
15465
15594
|
if (typeof candidate$1 === "string") {
|
|
15466
15595
|
return candidate$1;
|
|
15467
15596
|
}
|
|
15468
15597
|
switch (candidate$1.kind) {
|
|
15469
|
-
case "on-background": return onColorTokenName(backgroundToken);
|
|
15598
|
+
case "on-background": return onColorTokenName(backgroundToken$1);
|
|
15470
15599
|
}
|
|
15471
15600
|
}
|
|
15472
15601
|
function readPaletteHex(palette, token) {
|
|
@@ -15600,7 +15729,6 @@ function blockDesignPlanFromAppearancePreset(preset, input) {
|
|
|
15600
15729
|
return {
|
|
15601
15730
|
...planInput,
|
|
15602
15731
|
appearancePresetId: asAppearancePresetId(preset.id),
|
|
15603
|
-
transitionAfter: "none",
|
|
15604
15732
|
emphasis: "medium",
|
|
15605
15733
|
...resolveBlockAppearancePresetDesign(preset, layoutProfile ?? null)
|
|
15606
15734
|
};
|
|
@@ -16475,235 +16603,339 @@ function cardRoleFromLegacyVocabulary(value) {
|
|
|
16475
16603
|
const cardRoleWithLegacyAliasSchema = z.preprocess((value) => cardRoleFromLegacyVocabulary(value) ?? value, cardRoleSchema);
|
|
16476
16604
|
|
|
16477
16605
|
//#endregion
|
|
16478
|
-
//#region ../theme-core/src/site-styles/
|
|
16479
|
-
|
|
16480
|
-
|
|
16481
|
-
|
|
16482
|
-
|
|
16483
|
-
|
|
16484
|
-
|
|
16485
|
-
|
|
16486
|
-
|
|
16487
|
-
|
|
16488
|
-
|
|
16489
|
-
|
|
16490
|
-
|
|
16606
|
+
//#region ../theme-core/src/site-styles/runtimeBackgroundResolution.ts
|
|
16607
|
+
function parseCanonicalRuntimeBackground(content) {
|
|
16608
|
+
const sectionStyles = readRecord(content._sectionStyles);
|
|
16609
|
+
const background = readRecord(sectionStyles?.background);
|
|
16610
|
+
if (!background) return { kind: "none" };
|
|
16611
|
+
const parsed = boxBackgroundSchema.safeParse(background);
|
|
16612
|
+
if (!parsed.success) return { kind: "none" };
|
|
16613
|
+
return parsed.data.contentOwner === pageDesignEditorBackgroundOverrideOwner ? {
|
|
16614
|
+
kind: "page-design-override",
|
|
16615
|
+
background: parsed.data
|
|
16616
|
+
} : {
|
|
16617
|
+
kind: "block-authored",
|
|
16618
|
+
background: parsed.data
|
|
16491
16619
|
};
|
|
16492
16620
|
}
|
|
16493
|
-
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
}
|
|
16500
|
-
function isRatioExceeded(actualCount, totalItems, allowedRatio) {
|
|
16501
|
-
return actualCount > maxCompositionItemsWithinRatio(totalItems, allowedRatio);
|
|
16502
|
-
}
|
|
16503
|
-
function issueWhenRatioExceeded(input) {
|
|
16504
|
-
const actualRatio = ratio(input.blockIds.length, input.totalBlocks);
|
|
16505
|
-
if (!isRatioExceeded(input.blockIds.length, input.totalBlocks, input.allowedRatio)) {
|
|
16506
|
-
return null;
|
|
16621
|
+
function resolveSectionBackground(source, lookDefault) {
|
|
16622
|
+
if (source.kind === "page-design-override") {
|
|
16623
|
+
return {
|
|
16624
|
+
kind: "page-design-override",
|
|
16625
|
+
background: source.background
|
|
16626
|
+
};
|
|
16507
16627
|
}
|
|
16508
|
-
|
|
16509
|
-
kind
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16628
|
+
if (lookDefault) {
|
|
16629
|
+
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
16630
|
+
return {
|
|
16631
|
+
kind: "block-authored",
|
|
16632
|
+
background: mergeLookForegroundWithAuthoredMedia(lookDefault, source.background)
|
|
16633
|
+
};
|
|
16634
|
+
}
|
|
16635
|
+
return {
|
|
16636
|
+
kind: "look-default",
|
|
16637
|
+
background: lookDefault
|
|
16638
|
+
};
|
|
16639
|
+
}
|
|
16640
|
+
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
16641
|
+
return {
|
|
16642
|
+
kind: "block-authored",
|
|
16643
|
+
background: source.background
|
|
16644
|
+
};
|
|
16645
|
+
}
|
|
16646
|
+
return source.kind === "block-authored" ? {
|
|
16647
|
+
kind: "block-authored",
|
|
16648
|
+
background: source.background
|
|
16649
|
+
} : { kind: "none" };
|
|
16516
16650
|
}
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
return block.appliedContentFrame.kind !== "plain" || block.appliedCardRole != null && block.appliedCardRole !== "none";
|
|
16651
|
+
function resolveSectionForeground(background, palette) {
|
|
16652
|
+
return resolveSurfaceForeground(background.kind === "none" ? null : background.background, palette, {}, { compositeBase: "background" });
|
|
16520
16653
|
}
|
|
16521
|
-
/**
|
|
16522
|
-
|
|
16523
|
-
|
|
16654
|
+
/**
|
|
16655
|
+
* Read foreground authority from post-compiler block content. The preview
|
|
16656
|
+
* compiler has already materialized any Look-owned background into
|
|
16657
|
+
* `_sectionStyles`; raw authored content must be composed with its Look through
|
|
16658
|
+
* `resolveSectionBackground` instead.
|
|
16659
|
+
*/
|
|
16660
|
+
function resolveCompiledSectionForegroundFromContent(content, palette) {
|
|
16661
|
+
if (!content) return resolveSurfaceForeground(null, palette);
|
|
16662
|
+
return resolveSectionForeground(resolveSectionBackground(parseCanonicalRuntimeBackground(content), null), palette);
|
|
16524
16663
|
}
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16664
|
+
function mergeLookForegroundWithAuthoredMedia(lookDefault, authored) {
|
|
16665
|
+
const merged = boxBackgroundSchema.safeParse({
|
|
16666
|
+
...lookDefault,
|
|
16667
|
+
type: authored.type,
|
|
16668
|
+
image: authored.image,
|
|
16669
|
+
objectFit: authored.objectFit,
|
|
16670
|
+
scale: authored.scale,
|
|
16671
|
+
position: authored.position
|
|
16672
|
+
});
|
|
16673
|
+
return merged.success ? merged.data : authored;
|
|
16528
16674
|
}
|
|
16529
|
-
function
|
|
16530
|
-
|
|
16531
|
-
const totalBlocks = resolved.blocks.length;
|
|
16532
|
-
const knownBlockIds = new Set(resolved.blocks.map((block) => block.blockId));
|
|
16533
|
-
const blockContexts = input.blockContexts ?? [];
|
|
16534
|
-
const unknownContextBlockIds = blockContexts.filter((context) => !knownBlockIds.has(context.blockId)).map((context) => context.blockId);
|
|
16535
|
-
const knownBlockContexts = blockContexts.filter((context) => knownBlockIds.has(context.blockId));
|
|
16536
|
-
const contextsByBlockId = new Map(knownBlockContexts.map((context) => [context.blockId, context]));
|
|
16537
|
-
const issues = [];
|
|
16538
|
-
if (unknownContextBlockIds.length > 0) {
|
|
16539
|
-
issues.push({
|
|
16540
|
-
kind: "unknown-composition-context-block",
|
|
16541
|
-
blockIds: unknownContextBlockIds,
|
|
16542
|
-
...issueMetadata(policy, [])
|
|
16543
|
-
});
|
|
16544
|
-
}
|
|
16545
|
-
const accentBlockIds = resolved.blocks.filter((block) => block.appliedSectionSurface === "accent-band" || block.appliedSectionSurface === "brand-depth-band").map((block) => block.blockId);
|
|
16546
|
-
const accentIssue = issueWhenRatioExceeded({
|
|
16547
|
-
kind: "accent-density-exceeded",
|
|
16548
|
-
policy,
|
|
16549
|
-
budget: budget.accentDensity,
|
|
16550
|
-
blockIds: accentBlockIds,
|
|
16551
|
-
totalBlocks,
|
|
16552
|
-
allowedRatio: compositionDensityRatioLimits[budget.accentDensity]
|
|
16553
|
-
});
|
|
16554
|
-
if (accentIssue) {
|
|
16555
|
-
issues.push(accentIssue);
|
|
16556
|
-
}
|
|
16557
|
-
const panelBlockIds = resolved.blocks.filter(hasPanelFrameOrCardSurface).map((block) => block.blockId);
|
|
16558
|
-
const panelIssue = issueWhenRatioExceeded({
|
|
16559
|
-
kind: "panel-density-exceeded",
|
|
16560
|
-
policy,
|
|
16561
|
-
budget: budget.panelDensity,
|
|
16562
|
-
blockIds: panelBlockIds,
|
|
16563
|
-
totalBlocks,
|
|
16564
|
-
allowedRatio: compositionDensityRatioLimits[budget.panelDensity]
|
|
16565
|
-
});
|
|
16566
|
-
if (panelIssue) {
|
|
16567
|
-
issues.push(panelIssue);
|
|
16568
|
-
}
|
|
16569
|
-
const transitionBlockIds = resolved.blocks.filter((block) => block.appliedTransitionAfter !== "none").map((block) => block.blockId);
|
|
16570
|
-
const transitionIssue = issueWhenRatioExceeded({
|
|
16571
|
-
kind: "transition-mix-exceeded",
|
|
16572
|
-
policy,
|
|
16573
|
-
budget: budget.transitionMix,
|
|
16574
|
-
blockIds: transitionBlockIds,
|
|
16575
|
-
totalBlocks,
|
|
16576
|
-
allowedRatio: compositionTransitionMixRatioLimits[budget.transitionMix]
|
|
16577
|
-
});
|
|
16578
|
-
if (transitionIssue) {
|
|
16579
|
-
issues.push(transitionIssue);
|
|
16580
|
-
}
|
|
16581
|
-
const ctaContexts = knownBlockContexts.filter((context) => (context.primaryCtaCount ?? 0) > 0);
|
|
16582
|
-
const actualPrimaryCtaCount = ctaContexts.reduce((sum, context) => sum + (context.primaryCtaCount ?? 0), 0);
|
|
16583
|
-
if (actualPrimaryCtaCount > budget.primaryCtaLimit) {
|
|
16584
|
-
issues.push({
|
|
16585
|
-
kind: "primary-cta-limit-exceeded",
|
|
16586
|
-
actualCount: actualPrimaryCtaCount,
|
|
16587
|
-
allowedCount: budget.primaryCtaLimit,
|
|
16588
|
-
blockIds: ctaContexts.map((context) => context.blockId),
|
|
16589
|
-
...issueMetadata(policy, ["reduce-primary-ctas"])
|
|
16590
|
-
});
|
|
16591
|
-
}
|
|
16592
|
-
const mediaBlockIds = resolved.blocks.filter((block) => hasMediaAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
16593
|
-
const mediaIssue = issueWhenRatioExceeded({
|
|
16594
|
-
kind: "media-density-exceeded",
|
|
16595
|
-
policy,
|
|
16596
|
-
budget: budget.mediaDensity,
|
|
16597
|
-
blockIds: mediaBlockIds,
|
|
16598
|
-
totalBlocks,
|
|
16599
|
-
allowedRatio: compositionDensityRatioLimits[budget.mediaDensity]
|
|
16600
|
-
});
|
|
16601
|
-
if (mediaIssue) {
|
|
16602
|
-
issues.push(mediaIssue);
|
|
16603
|
-
}
|
|
16604
|
-
const decorativeBlockIds = resolved.blocks.filter((block) => hasDecorativeAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
16605
|
-
const decorativeIssue = issueWhenRatioExceeded({
|
|
16606
|
-
kind: "decorative-repetition-exceeded",
|
|
16607
|
-
policy,
|
|
16608
|
-
budget: budget.decorativeRepetition,
|
|
16609
|
-
blockIds: decorativeBlockIds,
|
|
16610
|
-
totalBlocks,
|
|
16611
|
-
allowedRatio: compositionDensityRatioLimits[budget.decorativeRepetition]
|
|
16612
|
-
});
|
|
16613
|
-
if (decorativeIssue) {
|
|
16614
|
-
issues.push(decorativeIssue);
|
|
16615
|
-
}
|
|
16616
|
-
return issues;
|
|
16675
|
+
function readRecord(value) {
|
|
16676
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
16617
16677
|
}
|
|
16618
16678
|
|
|
16619
16679
|
//#endregion
|
|
16620
|
-
//#region ../theme-core/src/site-styles/
|
|
16621
|
-
const defaultHeaderBrandPreferences = {
|
|
16622
|
-
brandDisplay: "auto",
|
|
16623
|
-
logoSize: "auto"
|
|
16624
|
-
};
|
|
16625
|
-
function headerBrandPreferencesFromTheme(theme) {
|
|
16626
|
-
return {
|
|
16627
|
-
brandDisplay: theme?.header.logo?.brandDisplay ?? defaultHeaderBrandPreferences.brandDisplay,
|
|
16628
|
-
logoSize: theme?.header.logo?.size ?? defaultHeaderBrandPreferences.logoSize
|
|
16629
|
-
};
|
|
16630
|
-
}
|
|
16631
|
-
function replaceSiteStyleCompilationPlan(input) {
|
|
16632
|
-
return {
|
|
16633
|
-
kind: "replace-site-style",
|
|
16634
|
-
buttons: {
|
|
16635
|
-
kind: "recompile",
|
|
16636
|
-
selection: input.buttonStyleSelection ?? null,
|
|
16637
|
-
reason: "site-style-replacement"
|
|
16638
|
-
},
|
|
16639
|
-
header: {
|
|
16640
|
-
kind: "recompile",
|
|
16641
|
-
selection: input.headerSelection,
|
|
16642
|
-
brandPresentation: input.headerLogo === undefined ? { kind: "use-compiled-defaults" } : {
|
|
16643
|
-
kind: "apply-logo-context",
|
|
16644
|
-
logo: input.headerLogo
|
|
16645
|
-
}
|
|
16646
|
-
},
|
|
16647
|
-
footerLookId: input.footerLookId ?? null
|
|
16648
|
-
};
|
|
16649
|
-
}
|
|
16680
|
+
//#region ../theme-core/src/site-styles/transitionCatalogue.ts
|
|
16650
16681
|
/**
|
|
16651
|
-
*
|
|
16652
|
-
*
|
|
16653
|
-
* Moved here from preview-next in #1318 Phase 4a so the header preference
|
|
16654
|
-
* pipeline can be composed once, in theme-core, rather than half in the client.
|
|
16682
|
+
* Family order for pickers. Entries below are listed family by family in this
|
|
16683
|
+
* same order, so the flat option list and the grouped families agree.
|
|
16655
16684
|
*/
|
|
16656
|
-
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
|
|
16685
|
+
const transitionCatalogueFamilies = [
|
|
16686
|
+
{
|
|
16687
|
+
id: "gradient",
|
|
16688
|
+
label: "Gradient"
|
|
16689
|
+
},
|
|
16690
|
+
{
|
|
16691
|
+
id: "wave",
|
|
16692
|
+
label: "Wave"
|
|
16693
|
+
},
|
|
16694
|
+
{
|
|
16695
|
+
id: "angle",
|
|
16696
|
+
label: "Angle"
|
|
16660
16697
|
}
|
|
16661
|
-
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
16670
|
-
|
|
16671
|
-
|
|
16698
|
+
];
|
|
16699
|
+
const mediumHeight = "6rem + 2px";
|
|
16700
|
+
const compactHeight = "4.5rem + 2px";
|
|
16701
|
+
const largeHeight = "7rem + 2px";
|
|
16702
|
+
/**
|
|
16703
|
+
* The single source of transition vocabulary. Order is significant: it is the
|
|
16704
|
+
* order of `boundaryOptions` (after `none`) and of each family's variants,
|
|
16705
|
+
* which persisted pins, page-flow presets and the editor picker all rely on.
|
|
16706
|
+
*
|
|
16707
|
+
* Shapes match what `generateLayoutCss` draws today. Structured
|
|
16708
|
+
* amplitude/frequency treatments (issue 826) extend this list later.
|
|
16709
|
+
*/
|
|
16710
|
+
const transitionCatalogueEntries = defineExactCatalog()([
|
|
16711
|
+
{
|
|
16712
|
+
intent: "soft-fade-short",
|
|
16713
|
+
optionId: asBoundaryOptionId("break:soft"),
|
|
16714
|
+
family: "gradient",
|
|
16715
|
+
variantId: "soft",
|
|
16716
|
+
label: "Soft",
|
|
16717
|
+
variantLabel: "Soft",
|
|
16718
|
+
treatment: {
|
|
16719
|
+
kind: "soft-fade",
|
|
16720
|
+
height: "medium",
|
|
16721
|
+
curve: "soft"
|
|
16722
|
+
},
|
|
16723
|
+
size: "medium",
|
|
16724
|
+
heightExpression: mediumHeight,
|
|
16725
|
+
shape: { kind: "fade" }
|
|
16726
|
+
},
|
|
16727
|
+
{
|
|
16728
|
+
intent: "soft-fade-long",
|
|
16729
|
+
optionId: asBoundaryOptionId("break:spacious"),
|
|
16730
|
+
family: "gradient",
|
|
16731
|
+
variantId: "spacious",
|
|
16732
|
+
label: "Spacious",
|
|
16733
|
+
variantLabel: "Spacious",
|
|
16734
|
+
treatment: {
|
|
16735
|
+
kind: "soft-fade",
|
|
16736
|
+
height: "large",
|
|
16737
|
+
curve: "spacious"
|
|
16738
|
+
},
|
|
16739
|
+
size: "spacious",
|
|
16740
|
+
heightExpression: "10rem",
|
|
16741
|
+
shape: { kind: "fade" }
|
|
16742
|
+
},
|
|
16743
|
+
{
|
|
16744
|
+
intent: "soft-fade-expansive",
|
|
16745
|
+
optionId: asBoundaryOptionId("break:expansive"),
|
|
16746
|
+
family: "gradient",
|
|
16747
|
+
variantId: "expansive",
|
|
16748
|
+
label: "Expansive",
|
|
16749
|
+
variantLabel: "Expansive",
|
|
16750
|
+
treatment: {
|
|
16751
|
+
kind: "soft-fade",
|
|
16752
|
+
height: "expansive",
|
|
16753
|
+
curve: "expansive"
|
|
16754
|
+
},
|
|
16755
|
+
size: "expansive",
|
|
16756
|
+
heightExpression: "14rem",
|
|
16757
|
+
shape: { kind: "fade" }
|
|
16758
|
+
},
|
|
16759
|
+
{
|
|
16760
|
+
intent: "wave-edge-balanced",
|
|
16761
|
+
optionId: asBoundaryOptionId("break:wave-balanced"),
|
|
16762
|
+
family: "wave",
|
|
16763
|
+
variantId: "balanced",
|
|
16764
|
+
label: "Balanced wave",
|
|
16765
|
+
variantLabel: "Balanced",
|
|
16766
|
+
treatment: {
|
|
16767
|
+
kind: "wave-edge",
|
|
16768
|
+
height: "medium",
|
|
16769
|
+
amplitude: "balanced",
|
|
16770
|
+
rhythm: "double",
|
|
16771
|
+
symmetry: "symmetrical"
|
|
16772
|
+
},
|
|
16773
|
+
size: "medium",
|
|
16774
|
+
heightExpression: mediumHeight,
|
|
16775
|
+
shape: {
|
|
16776
|
+
kind: "wave",
|
|
16777
|
+
mask: "balanced"
|
|
16778
|
+
}
|
|
16779
|
+
},
|
|
16780
|
+
{
|
|
16781
|
+
intent: "wave-edge",
|
|
16782
|
+
optionId: asBoundaryOptionId("break:wave"),
|
|
16783
|
+
family: "wave",
|
|
16784
|
+
variantId: "classic",
|
|
16785
|
+
label: "Classic wave",
|
|
16786
|
+
variantLabel: "Classic",
|
|
16787
|
+
treatment: {
|
|
16788
|
+
kind: "wave-edge",
|
|
16789
|
+
height: "medium",
|
|
16790
|
+
amplitude: "balanced",
|
|
16791
|
+
rhythm: "double",
|
|
16792
|
+
symmetry: "asymmetrical"
|
|
16793
|
+
},
|
|
16794
|
+
size: "medium",
|
|
16795
|
+
heightExpression: mediumHeight,
|
|
16796
|
+
shape: {
|
|
16797
|
+
kind: "wave",
|
|
16798
|
+
mask: "classic"
|
|
16799
|
+
}
|
|
16800
|
+
},
|
|
16801
|
+
{
|
|
16802
|
+
intent: "wave-edge-gentle",
|
|
16803
|
+
optionId: asBoundaryOptionId("break:wave-gentle"),
|
|
16804
|
+
family: "wave",
|
|
16805
|
+
variantId: "gentle",
|
|
16806
|
+
label: "Gentle wave",
|
|
16807
|
+
variantLabel: "Gentle",
|
|
16808
|
+
treatment: {
|
|
16809
|
+
kind: "wave-edge",
|
|
16810
|
+
height: "compact",
|
|
16811
|
+
amplitude: "subtle",
|
|
16812
|
+
rhythm: "single",
|
|
16813
|
+
symmetry: "symmetrical"
|
|
16814
|
+
},
|
|
16815
|
+
size: "compact",
|
|
16816
|
+
heightExpression: compactHeight,
|
|
16817
|
+
shape: {
|
|
16818
|
+
kind: "wave",
|
|
16819
|
+
mask: "gentle"
|
|
16820
|
+
}
|
|
16821
|
+
},
|
|
16822
|
+
{
|
|
16823
|
+
intent: "wave-edge-bold",
|
|
16824
|
+
optionId: asBoundaryOptionId("break:wave-bold"),
|
|
16825
|
+
family: "wave",
|
|
16826
|
+
variantId: "bold",
|
|
16827
|
+
label: "Bold wave",
|
|
16828
|
+
variantLabel: "Bold",
|
|
16829
|
+
treatment: {
|
|
16830
|
+
kind: "wave-edge",
|
|
16831
|
+
height: "large",
|
|
16832
|
+
amplitude: "bold",
|
|
16833
|
+
rhythm: "double",
|
|
16834
|
+
symmetry: "symmetrical"
|
|
16835
|
+
},
|
|
16836
|
+
size: "large",
|
|
16837
|
+
heightExpression: largeHeight,
|
|
16838
|
+
shape: {
|
|
16839
|
+
kind: "wave",
|
|
16840
|
+
mask: "bold"
|
|
16841
|
+
}
|
|
16842
|
+
},
|
|
16843
|
+
{
|
|
16844
|
+
intent: "wave-edge-drift",
|
|
16845
|
+
optionId: asBoundaryOptionId("break:wave-drift"),
|
|
16846
|
+
family: "wave",
|
|
16847
|
+
variantId: "drift",
|
|
16848
|
+
label: "Drift wave",
|
|
16849
|
+
variantLabel: "Drift",
|
|
16850
|
+
treatment: {
|
|
16851
|
+
kind: "wave-edge",
|
|
16852
|
+
height: "medium",
|
|
16853
|
+
amplitude: "balanced",
|
|
16854
|
+
rhythm: "double",
|
|
16855
|
+
symmetry: "drift"
|
|
16856
|
+
},
|
|
16857
|
+
size: "medium",
|
|
16858
|
+
heightExpression: mediumHeight,
|
|
16859
|
+
shape: {
|
|
16860
|
+
kind: "wave",
|
|
16861
|
+
mask: "drift"
|
|
16862
|
+
}
|
|
16863
|
+
},
|
|
16864
|
+
{
|
|
16865
|
+
intent: "angle-edge-subtle",
|
|
16866
|
+
optionId: asBoundaryOptionId("break:angle-subtle"),
|
|
16867
|
+
family: "angle",
|
|
16868
|
+
variantId: "subtle",
|
|
16869
|
+
label: "Subtle angle",
|
|
16870
|
+
variantLabel: "Subtle",
|
|
16871
|
+
treatment: {
|
|
16872
|
+
kind: "angle-edge",
|
|
16873
|
+
height: "compact",
|
|
16874
|
+
slope: "subtle",
|
|
16875
|
+
direction: "forward"
|
|
16876
|
+
},
|
|
16877
|
+
size: "compact",
|
|
16878
|
+
heightExpression: compactHeight,
|
|
16879
|
+
shape: {
|
|
16880
|
+
kind: "angle",
|
|
16881
|
+
polygon: {
|
|
16882
|
+
startTopPercent: 34,
|
|
16883
|
+
endTopPercent: 18
|
|
16672
16884
|
}
|
|
16673
16885
|
}
|
|
16674
|
-
}
|
|
16675
|
-
|
|
16676
|
-
|
|
16677
|
-
|
|
16678
|
-
|
|
16679
|
-
|
|
16680
|
-
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16684
|
-
|
|
16685
|
-
|
|
16686
|
-
|
|
16687
|
-
|
|
16688
|
-
|
|
16886
|
+
},
|
|
16887
|
+
{
|
|
16888
|
+
intent: "angle-edge",
|
|
16889
|
+
optionId: asBoundaryOptionId("break:angle-balanced"),
|
|
16890
|
+
family: "angle",
|
|
16891
|
+
variantId: "balanced",
|
|
16892
|
+
label: "Balanced angle",
|
|
16893
|
+
variantLabel: "Balanced",
|
|
16894
|
+
treatment: {
|
|
16895
|
+
kind: "angle-edge",
|
|
16896
|
+
height: "medium",
|
|
16897
|
+
slope: "balanced",
|
|
16898
|
+
direction: "forward"
|
|
16899
|
+
},
|
|
16900
|
+
size: "medium",
|
|
16901
|
+
heightExpression: mediumHeight,
|
|
16902
|
+
shape: {
|
|
16903
|
+
kind: "angle",
|
|
16904
|
+
polygon: {
|
|
16905
|
+
startTopPercent: 42,
|
|
16906
|
+
endTopPercent: 8
|
|
16689
16907
|
}
|
|
16690
|
-
}
|
|
16691
|
-
}
|
|
16692
|
-
|
|
16693
|
-
|
|
16694
|
-
|
|
16695
|
-
|
|
16696
|
-
|
|
16697
|
-
|
|
16698
|
-
|
|
16699
|
-
|
|
16908
|
+
}
|
|
16909
|
+
},
|
|
16910
|
+
{
|
|
16911
|
+
intent: "angle-edge-steep",
|
|
16912
|
+
optionId: asBoundaryOptionId("break:angle-steep"),
|
|
16913
|
+
family: "angle",
|
|
16914
|
+
variantId: "steep",
|
|
16915
|
+
label: "Steep angle",
|
|
16916
|
+
variantLabel: "Steep",
|
|
16917
|
+
treatment: {
|
|
16918
|
+
kind: "angle-edge",
|
|
16919
|
+
height: "large",
|
|
16920
|
+
slope: "steep",
|
|
16921
|
+
direction: "forward"
|
|
16922
|
+
},
|
|
16923
|
+
size: "large",
|
|
16924
|
+
heightExpression: largeHeight,
|
|
16925
|
+
shape: {
|
|
16926
|
+
kind: "angle",
|
|
16927
|
+
polygon: {
|
|
16928
|
+
startTopPercent: 54,
|
|
16929
|
+
endTopPercent: 0
|
|
16700
16930
|
}
|
|
16701
|
-
}
|
|
16931
|
+
}
|
|
16702
16932
|
}
|
|
16703
|
-
|
|
16704
|
-
|
|
16705
|
-
|
|
16706
|
-
|
|
16933
|
+
]);
|
|
16934
|
+
const transitionCatalogueCoversEveryIntentOnce = true;
|
|
16935
|
+
void transitionCatalogueCoversEveryIntentOnce;
|
|
16936
|
+
/** CSS `clip-path` value for an angle shape, as `generateLayoutCss` draws it. */
|
|
16937
|
+
function anglePolygonCss(polygon) {
|
|
16938
|
+
return `polygon(0 ${polygon.startTopPercent}%, 100% ${polygon.endTopPercent}%, 100% 100%, 0 100%)`;
|
|
16707
16939
|
}
|
|
16708
16940
|
|
|
16709
16941
|
//#endregion
|
|
@@ -16716,22 +16948,27 @@ function boundaryRuntimeMetrics(family, size, heightExpression) {
|
|
|
16716
16948
|
reserveCss: `calc((${heightExpression}) / 2)`
|
|
16717
16949
|
};
|
|
16718
16950
|
}
|
|
16719
|
-
const
|
|
16720
|
-
|
|
16721
|
-
|
|
16722
|
-
|
|
16723
|
-
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
16727
|
-
|
|
16728
|
-
|
|
16729
|
-
|
|
16730
|
-
|
|
16731
|
-
|
|
16732
|
-
|
|
16733
|
-
|
|
16734
|
-
|
|
16951
|
+
const catalogueEntryByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, entry]));
|
|
16952
|
+
const metricsByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, boundaryRuntimeMetrics(entry.family, entry.size, entry.heightExpression)]));
|
|
16953
|
+
/**
|
|
16954
|
+
* The catalogue's compile-time coverage check guarantees an entry per
|
|
16955
|
+
* decorative intent, so a miss here is a broken invariant, not bad input.
|
|
16956
|
+
*/
|
|
16957
|
+
function requireCatalogueValue(values, intent) {
|
|
16958
|
+
const value = values.get(intent);
|
|
16959
|
+
if (value === undefined) {
|
|
16960
|
+
throw new Error(`Transition catalogue has no entry for ${intent}`);
|
|
16961
|
+
}
|
|
16962
|
+
return value;
|
|
16963
|
+
}
|
|
16964
|
+
function transitionCatalogueEntryForIntent(intent) {
|
|
16965
|
+
return requireCatalogueValue(catalogueEntryByIntent, intent);
|
|
16966
|
+
}
|
|
16967
|
+
function isDecorativeTransitionIntent(transition) {
|
|
16968
|
+
return transition !== "none";
|
|
16969
|
+
}
|
|
16970
|
+
function boundaryRuntimeMetricsForDecorativeTransition(transition) {
|
|
16971
|
+
return requireCatalogueValue(metricsByIntent, transition);
|
|
16735
16972
|
}
|
|
16736
16973
|
const noneBoundaryOption = {
|
|
16737
16974
|
id: asBoundaryOptionId("break:none"),
|
|
@@ -16739,264 +16976,63 @@ const noneBoundaryOption = {
|
|
|
16739
16976
|
transitionAfter: "none",
|
|
16740
16977
|
treatment: { kind: "none" }
|
|
16741
16978
|
};
|
|
16742
|
-
const
|
|
16743
|
-
id:
|
|
16744
|
-
label:
|
|
16745
|
-
transitionAfter:
|
|
16746
|
-
treatment:
|
|
16747
|
-
|
|
16748
|
-
|
|
16749
|
-
|
|
16750
|
-
|
|
16751
|
-
|
|
16752
|
-
const spaciousBoundaryOption =
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
16756
|
-
|
|
16757
|
-
|
|
16758
|
-
|
|
16759
|
-
|
|
16760
|
-
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
treatment: {
|
|
16767
|
-
kind: "soft-fade",
|
|
16768
|
-
height: "expansive",
|
|
16769
|
-
curve: "expansive"
|
|
16770
|
-
}
|
|
16771
|
-
};
|
|
16772
|
-
const waveBoundaryOption = {
|
|
16773
|
-
id: asBoundaryOptionId("break:wave"),
|
|
16774
|
-
label: "Classic wave",
|
|
16775
|
-
transitionAfter: "wave-edge",
|
|
16776
|
-
treatment: {
|
|
16777
|
-
kind: "wave-edge",
|
|
16778
|
-
height: "medium",
|
|
16779
|
-
amplitude: "balanced",
|
|
16780
|
-
rhythm: "double",
|
|
16781
|
-
symmetry: "asymmetrical"
|
|
16782
|
-
}
|
|
16783
|
-
};
|
|
16784
|
-
const balancedWaveBoundaryOption = {
|
|
16785
|
-
id: asBoundaryOptionId("break:wave-balanced"),
|
|
16786
|
-
label: "Balanced wave",
|
|
16787
|
-
transitionAfter: "wave-edge-balanced",
|
|
16788
|
-
treatment: {
|
|
16789
|
-
kind: "wave-edge",
|
|
16790
|
-
height: "medium",
|
|
16791
|
-
amplitude: "balanced",
|
|
16792
|
-
rhythm: "double",
|
|
16793
|
-
symmetry: "symmetrical"
|
|
16794
|
-
}
|
|
16795
|
-
};
|
|
16796
|
-
const gentleWaveBoundaryOption = {
|
|
16797
|
-
id: asBoundaryOptionId("break:wave-gentle"),
|
|
16798
|
-
label: "Gentle wave",
|
|
16799
|
-
transitionAfter: "wave-edge-gentle",
|
|
16800
|
-
treatment: {
|
|
16801
|
-
kind: "wave-edge",
|
|
16802
|
-
height: "compact",
|
|
16803
|
-
amplitude: "subtle",
|
|
16804
|
-
rhythm: "single",
|
|
16805
|
-
symmetry: "symmetrical"
|
|
16806
|
-
}
|
|
16807
|
-
};
|
|
16808
|
-
const boldWaveBoundaryOption = {
|
|
16809
|
-
id: asBoundaryOptionId("break:wave-bold"),
|
|
16810
|
-
label: "Bold wave",
|
|
16811
|
-
transitionAfter: "wave-edge-bold",
|
|
16812
|
-
treatment: {
|
|
16813
|
-
kind: "wave-edge",
|
|
16814
|
-
height: "large",
|
|
16815
|
-
amplitude: "bold",
|
|
16816
|
-
rhythm: "double",
|
|
16817
|
-
symmetry: "symmetrical"
|
|
16818
|
-
}
|
|
16819
|
-
};
|
|
16820
|
-
const driftWaveBoundaryOption = {
|
|
16821
|
-
id: asBoundaryOptionId("break:wave-drift"),
|
|
16822
|
-
label: "Drift wave",
|
|
16823
|
-
transitionAfter: "wave-edge-drift",
|
|
16824
|
-
treatment: {
|
|
16825
|
-
kind: "wave-edge",
|
|
16826
|
-
height: "medium",
|
|
16827
|
-
amplitude: "balanced",
|
|
16828
|
-
rhythm: "double",
|
|
16829
|
-
symmetry: "drift"
|
|
16830
|
-
}
|
|
16831
|
-
};
|
|
16832
|
-
const subtleAngleBoundaryOption = {
|
|
16833
|
-
id: asBoundaryOptionId("break:angle-subtle"),
|
|
16834
|
-
label: "Subtle angle",
|
|
16835
|
-
transitionAfter: "angle-edge-subtle",
|
|
16836
|
-
treatment: {
|
|
16837
|
-
kind: "angle-edge",
|
|
16838
|
-
height: "compact",
|
|
16839
|
-
slope: "subtle",
|
|
16840
|
-
direction: "forward"
|
|
16841
|
-
}
|
|
16842
|
-
};
|
|
16843
|
-
const balancedAngleBoundaryOption = {
|
|
16844
|
-
id: asBoundaryOptionId("break:angle-balanced"),
|
|
16845
|
-
label: "Balanced angle",
|
|
16846
|
-
transitionAfter: "angle-edge",
|
|
16847
|
-
treatment: {
|
|
16848
|
-
kind: "angle-edge",
|
|
16849
|
-
height: "medium",
|
|
16850
|
-
slope: "balanced",
|
|
16851
|
-
direction: "forward"
|
|
16852
|
-
}
|
|
16853
|
-
};
|
|
16854
|
-
const steepAngleBoundaryOption = {
|
|
16855
|
-
id: asBoundaryOptionId("break:angle-steep"),
|
|
16856
|
-
label: "Steep angle",
|
|
16857
|
-
transitionAfter: "angle-edge-steep",
|
|
16858
|
-
treatment: {
|
|
16859
|
-
kind: "angle-edge",
|
|
16860
|
-
height: "large",
|
|
16861
|
-
slope: "steep",
|
|
16862
|
-
direction: "forward"
|
|
16863
|
-
}
|
|
16864
|
-
};
|
|
16979
|
+
const boundaryOptionByIntent = new Map(transitionCatalogueEntries.map((entry) => [entry.intent, {
|
|
16980
|
+
id: entry.optionId,
|
|
16981
|
+
label: entry.label,
|
|
16982
|
+
transitionAfter: entry.intent,
|
|
16983
|
+
treatment: entry.treatment
|
|
16984
|
+
}]));
|
|
16985
|
+
function boundaryOptionForTransitionIntent(intent) {
|
|
16986
|
+
return requireCatalogueValue(boundaryOptionByIntent, intent);
|
|
16987
|
+
}
|
|
16988
|
+
const softBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-short");
|
|
16989
|
+
const spaciousBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-long");
|
|
16990
|
+
const expansiveBoundaryOption = boundaryOptionForTransitionIntent("soft-fade-expansive");
|
|
16991
|
+
const waveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge");
|
|
16992
|
+
const balancedWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-balanced");
|
|
16993
|
+
const gentleWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-gentle");
|
|
16994
|
+
const boldWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-bold");
|
|
16995
|
+
const driftWaveBoundaryOption = boundaryOptionForTransitionIntent("wave-edge-drift");
|
|
16996
|
+
const subtleAngleBoundaryOption = boundaryOptionForTransitionIntent("angle-edge-subtle");
|
|
16997
|
+
const balancedAngleBoundaryOption = boundaryOptionForTransitionIntent("angle-edge");
|
|
16998
|
+
const steepAngleBoundaryOption = boundaryOptionForTransitionIntent("angle-edge-steep");
|
|
16999
|
+
/**
|
|
17000
|
+
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
17001
|
+
*/
|
|
17002
|
+
const boundaryOptions = [noneBoundaryOption, ...transitionCatalogueEntries.map((entry) => boundaryOptionForTransitionIntent(entry.intent))];
|
|
16865
17003
|
const noneTransitionVariant = {
|
|
16866
17004
|
familyId: "none",
|
|
16867
17005
|
variantId: "none",
|
|
16868
17006
|
label: "None",
|
|
16869
17007
|
boundaryOption: noneBoundaryOption
|
|
16870
17008
|
};
|
|
16871
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
|
|
16876
|
-
|
|
16877
|
-
|
|
16878
|
-
|
|
16879
|
-
|
|
16880
|
-
|
|
16881
|
-
|
|
16882
|
-
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
16889
|
-
const
|
|
16890
|
-
|
|
16891
|
-
|
|
16892
|
-
label: "Balanced",
|
|
16893
|
-
boundaryOption: balancedWaveBoundaryOption
|
|
16894
|
-
};
|
|
16895
|
-
const classicWaveTransitionVariant = {
|
|
16896
|
-
familyId: "wave",
|
|
16897
|
-
variantId: "classic",
|
|
16898
|
-
label: "Classic",
|
|
16899
|
-
boundaryOption: waveBoundaryOption
|
|
16900
|
-
};
|
|
16901
|
-
const gentleWaveTransitionVariant = {
|
|
16902
|
-
familyId: "wave",
|
|
16903
|
-
variantId: "gentle",
|
|
16904
|
-
label: "Gentle",
|
|
16905
|
-
boundaryOption: gentleWaveBoundaryOption
|
|
16906
|
-
};
|
|
16907
|
-
const boldWaveTransitionVariant = {
|
|
16908
|
-
familyId: "wave",
|
|
16909
|
-
variantId: "bold",
|
|
16910
|
-
label: "Bold",
|
|
16911
|
-
boundaryOption: boldWaveBoundaryOption
|
|
16912
|
-
};
|
|
16913
|
-
const driftWaveTransitionVariant = {
|
|
16914
|
-
familyId: "wave",
|
|
16915
|
-
variantId: "drift",
|
|
16916
|
-
label: "Drift",
|
|
16917
|
-
boundaryOption: driftWaveBoundaryOption
|
|
16918
|
-
};
|
|
16919
|
-
const subtleAngleTransitionVariant = {
|
|
16920
|
-
familyId: "angle",
|
|
16921
|
-
variantId: "subtle",
|
|
16922
|
-
label: "Subtle",
|
|
16923
|
-
boundaryOption: subtleAngleBoundaryOption
|
|
16924
|
-
};
|
|
16925
|
-
const balancedAngleTransitionVariant = {
|
|
16926
|
-
familyId: "angle",
|
|
16927
|
-
variantId: "balanced",
|
|
16928
|
-
label: "Balanced",
|
|
16929
|
-
boundaryOption: balancedAngleBoundaryOption
|
|
16930
|
-
};
|
|
16931
|
-
const steepAngleTransitionVariant = {
|
|
16932
|
-
familyId: "angle",
|
|
16933
|
-
variantId: "steep",
|
|
16934
|
-
label: "Steep",
|
|
16935
|
-
boundaryOption: steepAngleBoundaryOption
|
|
16936
|
-
};
|
|
16937
|
-
const sectionTransitionFamilies = [
|
|
16938
|
-
{
|
|
16939
|
-
id: "none",
|
|
16940
|
-
label: "None",
|
|
16941
|
-
variants: [noneTransitionVariant]
|
|
16942
|
-
},
|
|
16943
|
-
{
|
|
16944
|
-
id: "gradient",
|
|
16945
|
-
label: "Gradient",
|
|
16946
|
-
variants: [
|
|
16947
|
-
softGradientTransitionVariant,
|
|
16948
|
-
spaciousGradientTransitionVariant,
|
|
16949
|
-
expansiveGradientTransitionVariant
|
|
16950
|
-
]
|
|
16951
|
-
},
|
|
16952
|
-
{
|
|
16953
|
-
id: "wave",
|
|
16954
|
-
label: "Wave",
|
|
16955
|
-
variants: [
|
|
16956
|
-
balancedWaveTransitionVariant,
|
|
16957
|
-
classicWaveTransitionVariant,
|
|
16958
|
-
gentleWaveTransitionVariant,
|
|
16959
|
-
boldWaveTransitionVariant,
|
|
16960
|
-
driftWaveTransitionVariant
|
|
16961
|
-
]
|
|
16962
|
-
},
|
|
16963
|
-
{
|
|
16964
|
-
id: "angle",
|
|
16965
|
-
label: "Angle",
|
|
16966
|
-
variants: [
|
|
16967
|
-
subtleAngleTransitionVariant,
|
|
16968
|
-
balancedAngleTransitionVariant,
|
|
16969
|
-
steepAngleTransitionVariant
|
|
16970
|
-
]
|
|
16971
|
-
}
|
|
16972
|
-
];
|
|
16973
|
-
/**
|
|
16974
|
-
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
16975
|
-
*/
|
|
16976
|
-
const boundaryOptions = [
|
|
16977
|
-
noneBoundaryOption,
|
|
16978
|
-
softBoundaryOption,
|
|
16979
|
-
spaciousBoundaryOption,
|
|
16980
|
-
expansiveBoundaryOption,
|
|
16981
|
-
balancedWaveBoundaryOption,
|
|
16982
|
-
waveBoundaryOption,
|
|
16983
|
-
gentleWaveBoundaryOption,
|
|
16984
|
-
boldWaveBoundaryOption,
|
|
16985
|
-
driftWaveBoundaryOption,
|
|
16986
|
-
subtleAngleBoundaryOption,
|
|
16987
|
-
balancedAngleBoundaryOption,
|
|
16988
|
-
steepAngleBoundaryOption
|
|
16989
|
-
];
|
|
17009
|
+
function transitionVariantForEntry(entry) {
|
|
17010
|
+
return {
|
|
17011
|
+
familyId: entry.family,
|
|
17012
|
+
variantId: entry.variantId,
|
|
17013
|
+
label: entry.variantLabel,
|
|
17014
|
+
boundaryOption: boundaryOptionForTransitionIntent(entry.intent)
|
|
17015
|
+
};
|
|
17016
|
+
}
|
|
17017
|
+
const sectionTransitionFamilies = [{
|
|
17018
|
+
id: "none",
|
|
17019
|
+
label: "None",
|
|
17020
|
+
variants: [noneTransitionVariant]
|
|
17021
|
+
}, ...transitionCatalogueFamilies.map((family) => ({
|
|
17022
|
+
id: family.id,
|
|
17023
|
+
label: family.label,
|
|
17024
|
+
variants: requireNonEmptyReadonlyArray(transitionCatalogueEntries.filter((entry) => entry.family === family.id).map(transitionVariantForEntry), `Transition family ${family.id} has no catalogue entries.`)
|
|
17025
|
+
}))];
|
|
17026
|
+
const boundaryOptionById = new Map(boundaryOptions.map((option) => [option.id, option]));
|
|
17027
|
+
const boundaryOptionByTreatmentKey = new Map(boundaryOptions.map((option) => [stableTreatmentKey(option.treatment), option]));
|
|
17028
|
+
const transitionVariantByBoundaryOptionId = new Map(sectionTransitionFamilies.flatMap((family) => family.variants.map((variant) => [variant.boundaryOption.id, variant])));
|
|
17029
|
+
const transitionFamilyById = new Map(sectionTransitionFamilies.map((family) => [family.id, family]));
|
|
16990
17030
|
function sectionTransitionVariantForBoundaryOptionId(boundaryOptionId) {
|
|
16991
17031
|
if (!boundaryOptionId) return null;
|
|
16992
|
-
|
|
16993
|
-
const variant = family.variants.find((candidate$1) => candidate$1.boundaryOption.id === boundaryOptionId);
|
|
16994
|
-
if (variant) return variant;
|
|
16995
|
-
}
|
|
16996
|
-
return null;
|
|
17032
|
+
return transitionVariantByBoundaryOptionId.get(boundaryOptionId) ?? null;
|
|
16997
17033
|
}
|
|
16998
17034
|
function boundaryTreatmentForBoundaryOptionId(boundaryOptionId) {
|
|
16999
|
-
return
|
|
17035
|
+
return boundaryOptionById.get(boundaryOptionId)?.treatment ?? {
|
|
17000
17036
|
kind: "legacy-unsupported",
|
|
17001
17037
|
boundaryOptionId
|
|
17002
17038
|
};
|
|
@@ -17005,11 +17041,19 @@ function boundaryOptionForTreatment(treatment) {
|
|
|
17005
17041
|
if (treatment.kind === "legacy-unsupported") {
|
|
17006
17042
|
return null;
|
|
17007
17043
|
}
|
|
17008
|
-
return
|
|
17044
|
+
return boundaryOptionByTreatmentKey.get(stableTreatmentKey(treatment)) ?? null;
|
|
17009
17045
|
}
|
|
17010
17046
|
function boundaryOptionIdForTreatment(treatment) {
|
|
17011
17047
|
return boundaryOptionForTreatment(treatment)?.id ?? (treatment.kind === "legacy-unsupported" ? treatment.boundaryOptionId : null);
|
|
17012
17048
|
}
|
|
17049
|
+
/**
|
|
17050
|
+
* Supported decorative intent for a structured treatment, or null for `none`,
|
|
17051
|
+
* legacy-unsupported pins and structured treatments the catalogue lacks.
|
|
17052
|
+
*/
|
|
17053
|
+
function transitionIntentForTreatment(treatment) {
|
|
17054
|
+
const transition = boundaryOptionForTreatment(treatment)?.transitionAfter;
|
|
17055
|
+
return transition && isDecorativeTransitionIntent(transition) ? transition : null;
|
|
17056
|
+
}
|
|
17013
17057
|
function sectionBoundaryTreatmentsEqual(left, right) {
|
|
17014
17058
|
return stableTreatmentKey(left) === stableTreatmentKey(right);
|
|
17015
17059
|
}
|
|
@@ -17036,10 +17080,10 @@ function stableTreatmentKey(treatment) {
|
|
|
17036
17080
|
function sectionTransitionFamilyForBoundaryOptionId(boundaryOptionId) {
|
|
17037
17081
|
const variant = sectionTransitionVariantForBoundaryOptionId(boundaryOptionId);
|
|
17038
17082
|
if (!variant) return null;
|
|
17039
|
-
return
|
|
17083
|
+
return transitionFamilyById.get(variant.familyId) ?? null;
|
|
17040
17084
|
}
|
|
17041
17085
|
function defaultSectionTransitionVariantForFamily(familyId) {
|
|
17042
|
-
const family =
|
|
17086
|
+
const family = transitionFamilyById.get(familyId);
|
|
17043
17087
|
if (!family) {
|
|
17044
17088
|
throw new Error(`Unknown section transition family: ${familyId}`);
|
|
17045
17089
|
}
|
|
@@ -17047,409 +17091,807 @@ function defaultSectionTransitionVariantForFamily(familyId) {
|
|
|
17047
17091
|
}
|
|
17048
17092
|
|
|
17049
17093
|
//#endregion
|
|
17050
|
-
//#region ../theme-core/src/site-styles/
|
|
17051
|
-
const
|
|
17052
|
-
|
|
17053
|
-
|
|
17094
|
+
//#region ../theme-core/src/site-styles/sectionBoundaryComposition.ts
|
|
17095
|
+
const backgroundToken = requireThemeColorToken$1("background");
|
|
17096
|
+
/**
|
|
17097
|
+
* Classifies a section from its final render content. `_sectionStyles`
|
|
17098
|
+
* already holds the effective background (Look default, page-design override
|
|
17099
|
+
* and block-authored media merged by `resolveSectionBackground`), so this only
|
|
17100
|
+
* reads it and never re-decides precedence. A missing or unparseable
|
|
17101
|
+
* background is the page background, as it is for the renderer.
|
|
17102
|
+
*/
|
|
17103
|
+
function boundaryEndpointForSectionContent(content) {
|
|
17104
|
+
const background = parseCanonicalRuntimeBackground(content);
|
|
17105
|
+
if (background.kind === "none") {
|
|
17106
|
+
return {
|
|
17107
|
+
kind: "paint",
|
|
17108
|
+
token: backgroundToken
|
|
17109
|
+
};
|
|
17110
|
+
}
|
|
17111
|
+
const effective = background.background;
|
|
17112
|
+
switch (effective.type) {
|
|
17113
|
+
case "color": {
|
|
17114
|
+
if (effective.color === null || effective.color === undefined) {
|
|
17115
|
+
return {
|
|
17116
|
+
kind: "paint",
|
|
17117
|
+
token: backgroundToken
|
|
17118
|
+
};
|
|
17119
|
+
}
|
|
17120
|
+
const token = parseThemeColorToken(effective.color);
|
|
17121
|
+
return token ? {
|
|
17122
|
+
kind: "paint",
|
|
17123
|
+
token
|
|
17124
|
+
} : {
|
|
17125
|
+
kind: "unpainted",
|
|
17126
|
+
reason: "literal-color"
|
|
17127
|
+
};
|
|
17128
|
+
}
|
|
17129
|
+
case "gradient": return {
|
|
17130
|
+
kind: "unpainted",
|
|
17131
|
+
reason: "gradient"
|
|
17132
|
+
};
|
|
17133
|
+
case "image":
|
|
17134
|
+
case "video": return {
|
|
17135
|
+
kind: "unpainted",
|
|
17136
|
+
reason: "media"
|
|
17137
|
+
};
|
|
17138
|
+
default: return assertNever$1(effective, "Unhandled section background type");
|
|
17139
|
+
}
|
|
17140
|
+
}
|
|
17054
17141
|
/**
|
|
17055
|
-
*
|
|
17056
|
-
*
|
|
17142
|
+
* Reads both facts from final render content in one place. `_frameStyles` is
|
|
17143
|
+
* the compiled frame; content without one (no page design, an SDK block)
|
|
17144
|
+
* draws a plain frame.
|
|
17057
17145
|
*/
|
|
17058
|
-
function
|
|
17059
|
-
return
|
|
17060
|
-
|
|
17061
|
-
|
|
17146
|
+
function sectionFactsForContent(content) {
|
|
17147
|
+
return {
|
|
17148
|
+
endpoint: boundaryEndpointForSectionContent(content),
|
|
17149
|
+
frame: frameKindForContent(content)
|
|
17062
17150
|
};
|
|
17063
17151
|
}
|
|
17064
|
-
|
|
17065
|
-
|
|
17066
|
-
|
|
17067
|
-
|
|
17068
|
-
|
|
17069
|
-
kind: z.literal("user-pinned"),
|
|
17070
|
-
value: z.string().min(1).transform(asBoundaryOptionId)
|
|
17071
|
-
}).strict();
|
|
17072
|
-
const pageDesignBoundaryTreatmentSchema = z.discriminatedUnion("kind", [
|
|
17073
|
-
z.object({ kind: z.literal("none") }).strict(),
|
|
17074
|
-
z.object({
|
|
17075
|
-
kind: z.literal("soft-fade"),
|
|
17076
|
-
height: z.enum([
|
|
17077
|
-
"compact",
|
|
17078
|
-
"medium",
|
|
17079
|
-
"large",
|
|
17080
|
-
"expansive"
|
|
17081
|
-
]),
|
|
17082
|
-
curve: z.enum([
|
|
17083
|
-
"soft",
|
|
17084
|
-
"spacious",
|
|
17085
|
-
"expansive"
|
|
17086
|
-
])
|
|
17087
|
-
}).strict(),
|
|
17088
|
-
z.object({
|
|
17089
|
-
kind: z.literal("wave-edge"),
|
|
17090
|
-
height: z.enum([
|
|
17091
|
-
"compact",
|
|
17092
|
-
"medium",
|
|
17093
|
-
"large"
|
|
17094
|
-
]),
|
|
17095
|
-
amplitude: z.enum([
|
|
17096
|
-
"subtle",
|
|
17097
|
-
"balanced",
|
|
17098
|
-
"bold"
|
|
17099
|
-
]),
|
|
17100
|
-
rhythm: z.enum(["single", "double"]),
|
|
17101
|
-
symmetry: z.enum([
|
|
17102
|
-
"symmetrical",
|
|
17103
|
-
"asymmetrical",
|
|
17104
|
-
"drift"
|
|
17105
|
-
])
|
|
17106
|
-
}).strict(),
|
|
17107
|
-
z.object({
|
|
17108
|
-
kind: z.literal("angle-edge"),
|
|
17109
|
-
height: z.enum([
|
|
17110
|
-
"compact",
|
|
17111
|
-
"medium",
|
|
17112
|
-
"large"
|
|
17113
|
-
]),
|
|
17114
|
-
slope: z.enum([
|
|
17115
|
-
"subtle",
|
|
17116
|
-
"balanced",
|
|
17117
|
-
"steep"
|
|
17118
|
-
]),
|
|
17119
|
-
direction: z.enum(["forward", "reverse"])
|
|
17120
|
-
}).strict(),
|
|
17121
|
-
z.object({
|
|
17122
|
-
kind: z.literal("legacy-unsupported"),
|
|
17123
|
-
boundaryOptionId: z.string().min(1).transform(asBoundaryOptionId)
|
|
17124
|
-
}).strict()
|
|
17125
|
-
]);
|
|
17126
|
-
const pageDesignUserPinnedBoundaryTreatmentChoiceSchema = z.object({
|
|
17127
|
-
kind: z.literal("user-pinned"),
|
|
17128
|
-
value: pageDesignBoundaryTreatmentSchema
|
|
17129
|
-
}).strict();
|
|
17130
|
-
const pageDesignBlockLookPinSchema = z.object({
|
|
17131
|
-
blockId: z.string().min(1).transform(asDesignBlockId),
|
|
17132
|
-
blockKind: z.string().min(1),
|
|
17133
|
-
choice: pageDesignUserPinnedAppearanceChoiceSchema
|
|
17134
|
-
}).strict();
|
|
17135
|
-
const pageDesignBoundaryPinSchema = z.object({
|
|
17136
|
-
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17137
|
-
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17138
|
-
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17139
|
-
choice: pageDesignUserPinnedBoundaryTreatmentChoiceSchema
|
|
17140
|
-
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17141
|
-
const legacyPageDesignBoundaryPinSchema = z.object({
|
|
17142
|
-
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17143
|
-
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17144
|
-
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17145
|
-
choice: pageDesignUserPinnedBoundaryChoiceSchema
|
|
17146
|
-
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17152
|
+
function frameKindForContent(content) {
|
|
17153
|
+
const frameStyles = content._frameStyles;
|
|
17154
|
+
const kind = typeof frameStyles === "object" && frameStyles !== null && "kind" in frameStyles ? frameStyles.kind : null;
|
|
17155
|
+
return kind === "panel" || kind === "flush-panel" ? kind : "plain";
|
|
17156
|
+
}
|
|
17147
17157
|
/**
|
|
17148
|
-
*
|
|
17149
|
-
*
|
|
17150
|
-
*
|
|
17158
|
+
* The frame rule: a flush panel owns the edge it runs to, so no break is
|
|
17159
|
+
* drawn next to one. The single home for this rule; the generated
|
|
17160
|
+
* pipeline's budget and the site-style lab ask it with their plan frames.
|
|
17151
17161
|
*/
|
|
17152
|
-
|
|
17153
|
-
|
|
17154
|
-
|
|
17155
|
-
|
|
17156
|
-
|
|
17157
|
-
|
|
17158
|
-
|
|
17159
|
-
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
}
|
|
17166
|
-
function parsePageDesignIntent(value, options = {}) {
|
|
17167
|
-
if (isLegacyPageDesignIntentCandidate(value)) {
|
|
17168
|
-
const legacyParsed = parseSchemaVersionedJson({
|
|
17169
|
-
value,
|
|
17170
|
-
schema: pageDesignIntentV1Schema,
|
|
17171
|
-
expectedSchemaVersion: legacyPageDesignIntentSchemaVersion,
|
|
17172
|
-
unsupportedSchemaVersionMessage: options.unsupportedSchemaVersionMessage ?? "Unsupported Theme V2 page design intent schemaVersion.",
|
|
17173
|
-
invalidShapeMessage: options.invalidShapeMessage ?? "Invalid Theme V2 page design intent shape."
|
|
17174
|
-
});
|
|
17175
|
-
switch (legacyParsed.kind) {
|
|
17176
|
-
case "absent": return legacyParsed;
|
|
17177
|
-
case "parsed": return {
|
|
17178
|
-
kind: "parsed",
|
|
17179
|
-
intent: normalizeLegacyPageDesignIntent(legacyParsed.value)
|
|
17180
|
-
};
|
|
17181
|
-
case "invalid": return legacyParsed;
|
|
17182
|
-
default: return assertNever$1(legacyParsed, "Unhandled legacy page design intent JSON parse result");
|
|
17183
|
-
}
|
|
17162
|
+
function frameNotShownReason(previous, next) {
|
|
17163
|
+
return previous === "flush-panel" || next === "flush-panel" ? "flush-panel" : null;
|
|
17164
|
+
}
|
|
17165
|
+
/**
|
|
17166
|
+
* Decides whether and how a join draws. The frame rule wins before paint is
|
|
17167
|
+
* considered; two unpainted sides show nothing.
|
|
17168
|
+
*/
|
|
17169
|
+
function composeBoundary(previous, next) {
|
|
17170
|
+
const frameReason = frameNotShownReason(previous.frame, next.frame);
|
|
17171
|
+
if (frameReason) {
|
|
17172
|
+
return {
|
|
17173
|
+
kind: "not-shown",
|
|
17174
|
+
reason: frameReason
|
|
17175
|
+
};
|
|
17184
17176
|
}
|
|
17185
|
-
const
|
|
17186
|
-
|
|
17187
|
-
|
|
17188
|
-
|
|
17189
|
-
|
|
17190
|
-
|
|
17191
|
-
|
|
17192
|
-
|
|
17193
|
-
|
|
17194
|
-
|
|
17195
|
-
|
|
17196
|
-
|
|
17177
|
+
const from = previous.endpoint;
|
|
17178
|
+
const to = next.endpoint;
|
|
17179
|
+
if (from.kind === "paint") {
|
|
17180
|
+
return {
|
|
17181
|
+
kind: "shown",
|
|
17182
|
+
composition: to.kind === "paint" ? {
|
|
17183
|
+
kind: "paint-to-paint",
|
|
17184
|
+
from: from.token,
|
|
17185
|
+
to: to.token
|
|
17186
|
+
} : {
|
|
17187
|
+
kind: "paint-to-unpainted",
|
|
17188
|
+
from: from.token
|
|
17189
|
+
}
|
|
17197
17190
|
};
|
|
17198
|
-
case "invalid": return parsed;
|
|
17199
|
-
default: return assertNever$1(parsed, "Unhandled page design intent JSON parse result");
|
|
17200
17191
|
}
|
|
17192
|
+
return to.kind === "paint" ? {
|
|
17193
|
+
kind: "shown",
|
|
17194
|
+
composition: {
|
|
17195
|
+
kind: "unpainted-to-paint",
|
|
17196
|
+
to: to.token
|
|
17197
|
+
}
|
|
17198
|
+
} : {
|
|
17199
|
+
kind: "not-shown",
|
|
17200
|
+
reason: "both-unpainted"
|
|
17201
|
+
};
|
|
17201
17202
|
}
|
|
17202
|
-
|
|
17203
|
-
|
|
17203
|
+
/**
|
|
17204
|
+
* Placement, reserves and paint for a shown boundary, derived from the
|
|
17205
|
+
* composition and the catalogue's metrics for the treatment.
|
|
17206
|
+
*/
|
|
17207
|
+
function boundaryLayout(intent, composition) {
|
|
17208
|
+
const metrics = boundaryRuntimeMetricsForDecorativeTransition(intent);
|
|
17209
|
+
switch (composition.kind) {
|
|
17210
|
+
case "paint-to-paint": return {
|
|
17211
|
+
placement: "centred",
|
|
17212
|
+
reserves: {
|
|
17213
|
+
before: metrics.reserveCss,
|
|
17214
|
+
after: metrics.reserveCss
|
|
17215
|
+
},
|
|
17216
|
+
paint: {
|
|
17217
|
+
band: composition.from,
|
|
17218
|
+
shape: composition.to
|
|
17219
|
+
}
|
|
17220
|
+
};
|
|
17221
|
+
case "unpainted-to-paint": return {
|
|
17222
|
+
placement: "previous",
|
|
17223
|
+
reserves: {
|
|
17224
|
+
before: metrics.heightCss,
|
|
17225
|
+
after: null
|
|
17226
|
+
},
|
|
17227
|
+
paint: {
|
|
17228
|
+
band: null,
|
|
17229
|
+
shape: composition.to
|
|
17230
|
+
}
|
|
17231
|
+
};
|
|
17232
|
+
case "paint-to-unpainted": return {
|
|
17233
|
+
placement: "next",
|
|
17234
|
+
reserves: {
|
|
17235
|
+
before: null,
|
|
17236
|
+
after: metrics.heightCss
|
|
17237
|
+
},
|
|
17238
|
+
paint: {
|
|
17239
|
+
band: null,
|
|
17240
|
+
shape: composition.from
|
|
17241
|
+
}
|
|
17242
|
+
};
|
|
17243
|
+
default: return assertNever$1(composition, "Unhandled boundary composition");
|
|
17244
|
+
}
|
|
17204
17245
|
}
|
|
17205
|
-
function
|
|
17246
|
+
function requireThemeColorToken$1(value) {
|
|
17247
|
+
const token = parseThemeColorToken(value);
|
|
17248
|
+
if (!token) {
|
|
17249
|
+
throw new Error(`Expected a theme color token. Received: ${value}`);
|
|
17250
|
+
}
|
|
17251
|
+
return token;
|
|
17252
|
+
}
|
|
17253
|
+
|
|
17254
|
+
//#endregion
|
|
17255
|
+
//#region ../theme-core/src/site-styles/compositionBudget.ts
|
|
17256
|
+
const repairActionsByRatioIssueKind = {
|
|
17257
|
+
"accent-density-exceeded": ["reduce-accent-density"],
|
|
17258
|
+
"panel-density-exceeded": ["reduce-panel-density"],
|
|
17259
|
+
"transition-mix-exceeded": ["reduce-transition-mix"],
|
|
17260
|
+
"media-density-exceeded": ["reduce-media-density"],
|
|
17261
|
+
"decorative-repetition-exceeded": ["reduce-decorative-repetition"]
|
|
17262
|
+
};
|
|
17263
|
+
function issueMetadata(policy, allowedRepairActions) {
|
|
17206
17264
|
return {
|
|
17207
|
-
|
|
17208
|
-
|
|
17209
|
-
|
|
17210
|
-
blockLookPins: intent.blockLookPins,
|
|
17211
|
-
boundaryPins: intent.boundaryPins.map((pin) => ({
|
|
17212
|
-
boundaryId: pin.boundaryId,
|
|
17213
|
-
previousBlockId: pin.previousBlockId,
|
|
17214
|
-
nextBlockId: pin.nextBlockId,
|
|
17215
|
-
choice: userPinnedDesignChoice(boundaryTreatmentForBoundaryOptionId(pin.choice.value))
|
|
17216
|
-
}))
|
|
17265
|
+
policy,
|
|
17266
|
+
severity: designIssueSeverityForPolicy(policy),
|
|
17267
|
+
allowedRepairActions
|
|
17217
17268
|
};
|
|
17218
17269
|
}
|
|
17219
|
-
|
|
17220
|
-
|
|
17270
|
+
/** Returns the fraction of page blocks selected by a budget check. */
|
|
17271
|
+
function ratio(count, total) {
|
|
17272
|
+
return total === 0 ? 0 : count / total;
|
|
17221
17273
|
}
|
|
17222
|
-
function
|
|
17274
|
+
function maxCompositionItemsWithinRatio(totalItems, allowedRatio) {
|
|
17275
|
+
return Math.floor((allowedRatio + Number.EPSILON) * totalItems);
|
|
17276
|
+
}
|
|
17277
|
+
function isRatioExceeded(actualCount, totalItems, allowedRatio) {
|
|
17278
|
+
return actualCount > maxCompositionItemsWithinRatio(totalItems, allowedRatio);
|
|
17279
|
+
}
|
|
17280
|
+
function issueWhenRatioExceeded(input) {
|
|
17281
|
+
const actualRatio = ratio(input.blockIds.length, input.totalBlocks);
|
|
17282
|
+
if (!isRatioExceeded(input.blockIds.length, input.totalBlocks, input.allowedRatio)) {
|
|
17283
|
+
return null;
|
|
17284
|
+
}
|
|
17223
17285
|
return {
|
|
17224
|
-
kind:
|
|
17225
|
-
|
|
17286
|
+
kind: input.kind,
|
|
17287
|
+
budget: input.budget,
|
|
17288
|
+
actualRatio,
|
|
17289
|
+
allowedRatio: input.allowedRatio,
|
|
17290
|
+
blockIds: input.blockIds,
|
|
17291
|
+
...issueMetadata(input.policy, repairActionsByRatioIssueKind[input.kind])
|
|
17226
17292
|
};
|
|
17227
17293
|
}
|
|
17228
|
-
|
|
17229
|
-
|
|
17294
|
+
/** Checks whether block framing or a card surface contributes panel mass. */
|
|
17295
|
+
function hasPanelFrameOrCardSurface(block) {
|
|
17296
|
+
return block.appliedContentFrame.kind !== "plain" || block.appliedCardRole != null && block.appliedCardRole !== "none";
|
|
17230
17297
|
}
|
|
17231
|
-
|
|
17232
|
-
|
|
17298
|
+
/** Checks explicit decorative annotations; transitions are budgeted separately. */
|
|
17299
|
+
function hasDecorativeAnnotation(context) {
|
|
17300
|
+
return context?.decorativeIntent === "supporting" || context?.decorativeIntent === "feature";
|
|
17233
17301
|
}
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
previousBlockId,
|
|
17238
|
-
nextBlockId,
|
|
17239
|
-
choice
|
|
17240
|
-
};
|
|
17302
|
+
/** Checks whether a block annotation says media contributes visual weight. */
|
|
17303
|
+
function hasMediaAnnotation(context) {
|
|
17304
|
+
return context?.mediaIntent === "supporting" || context?.mediaIntent === "dominant";
|
|
17241
17305
|
}
|
|
17242
|
-
function
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17246
|
-
|
|
17247
|
-
|
|
17248
|
-
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
|
|
17252
|
-
|
|
17306
|
+
function validateCompositionBudget(input) {
|
|
17307
|
+
const { budget, policy, resolved } = input;
|
|
17308
|
+
const totalBlocks = resolved.blocks.length;
|
|
17309
|
+
const knownBlockIds = new Set(resolved.blocks.map((block) => block.blockId));
|
|
17310
|
+
const blockContexts = input.blockContexts ?? [];
|
|
17311
|
+
const unknownContextBlockIds = blockContexts.filter((context) => !knownBlockIds.has(context.blockId)).map((context) => context.blockId);
|
|
17312
|
+
const knownBlockContexts = blockContexts.filter((context) => knownBlockIds.has(context.blockId));
|
|
17313
|
+
const contextsByBlockId = new Map(knownBlockContexts.map((context) => [context.blockId, context]));
|
|
17314
|
+
const issues = [];
|
|
17315
|
+
if (unknownContextBlockIds.length > 0) {
|
|
17316
|
+
issues.push({
|
|
17317
|
+
kind: "unknown-composition-context-block",
|
|
17318
|
+
blockIds: unknownContextBlockIds,
|
|
17319
|
+
...issueMetadata(policy, [])
|
|
17320
|
+
});
|
|
17253
17321
|
}
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
|
|
17258
|
-
|
|
17259
|
-
|
|
17260
|
-
|
|
17261
|
-
|
|
17262
|
-
|
|
17263
|
-
|
|
17322
|
+
const accentBlockIds = resolved.blocks.filter((block) => block.appliedSectionSurface === "accent-band" || block.appliedSectionSurface === "brand-depth-band").map((block) => block.blockId);
|
|
17323
|
+
const accentIssue = issueWhenRatioExceeded({
|
|
17324
|
+
kind: "accent-density-exceeded",
|
|
17325
|
+
policy,
|
|
17326
|
+
budget: budget.accentDensity,
|
|
17327
|
+
blockIds: accentBlockIds,
|
|
17328
|
+
totalBlocks,
|
|
17329
|
+
allowedRatio: compositionDensityRatioLimits[budget.accentDensity]
|
|
17330
|
+
});
|
|
17331
|
+
if (accentIssue) {
|
|
17332
|
+
issues.push(accentIssue);
|
|
17264
17333
|
}
|
|
17265
|
-
|
|
17266
|
-
|
|
17267
|
-
|
|
17268
|
-
|
|
17269
|
-
|
|
17270
|
-
|
|
17271
|
-
|
|
17272
|
-
|
|
17273
|
-
const blockLookPins = intent.blockLookPins.flatMap((pin) => {
|
|
17274
|
-
const target = targetBySourceId.get(pin.blockId);
|
|
17275
|
-
return target ? [{
|
|
17276
|
-
blockId: target.blockId,
|
|
17277
|
-
blockKind: target.blockKind,
|
|
17278
|
-
choice: pin.choice
|
|
17279
|
-
}] : [];
|
|
17334
|
+
const panelBlockIds = resolved.blocks.filter(hasPanelFrameOrCardSurface).map((block) => block.blockId);
|
|
17335
|
+
const panelIssue = issueWhenRatioExceeded({
|
|
17336
|
+
kind: "panel-density-exceeded",
|
|
17337
|
+
policy,
|
|
17338
|
+
budget: budget.panelDensity,
|
|
17339
|
+
blockIds: panelBlockIds,
|
|
17340
|
+
totalBlocks,
|
|
17341
|
+
allowedRatio: compositionDensityRatioLimits[budget.panelDensity]
|
|
17280
17342
|
});
|
|
17281
|
-
|
|
17282
|
-
|
|
17283
|
-
|
|
17284
|
-
|
|
17285
|
-
|
|
17286
|
-
|
|
17287
|
-
|
|
17288
|
-
|
|
17289
|
-
|
|
17290
|
-
|
|
17343
|
+
if (panelIssue) {
|
|
17344
|
+
issues.push(panelIssue);
|
|
17345
|
+
}
|
|
17346
|
+
const frameByBlockId = new Map(input.resolved.blocks.map((block) => [block.blockId, block.appliedContentFrame.kind]));
|
|
17347
|
+
const transitionBlockIds = input.joins.filter((join) => {
|
|
17348
|
+
const previous = frameByBlockId.get(join.previousBlockId);
|
|
17349
|
+
const next = frameByBlockId.get(join.nextBlockId);
|
|
17350
|
+
return previous !== undefined && next !== undefined && frameNotShownReason(previous, next) === null;
|
|
17351
|
+
}).map((join) => join.previousBlockId);
|
|
17352
|
+
const transitionIssue = issueWhenRatioExceeded({
|
|
17353
|
+
kind: "transition-mix-exceeded",
|
|
17354
|
+
policy,
|
|
17355
|
+
budget: budget.transitionMix,
|
|
17356
|
+
blockIds: transitionBlockIds,
|
|
17357
|
+
totalBlocks,
|
|
17358
|
+
allowedRatio: compositionTransitionMixRatioLimits[budget.transitionMix]
|
|
17359
|
+
});
|
|
17360
|
+
if (transitionIssue) {
|
|
17361
|
+
issues.push(transitionIssue);
|
|
17362
|
+
}
|
|
17363
|
+
const ctaContexts = knownBlockContexts.filter((context) => (context.primaryCtaCount ?? 0) > 0);
|
|
17364
|
+
const actualPrimaryCtaCount = ctaContexts.reduce((sum, context) => sum + (context.primaryCtaCount ?? 0), 0);
|
|
17365
|
+
if (actualPrimaryCtaCount > budget.primaryCtaLimit) {
|
|
17366
|
+
issues.push({
|
|
17367
|
+
kind: "primary-cta-limit-exceeded",
|
|
17368
|
+
actualCount: actualPrimaryCtaCount,
|
|
17369
|
+
allowedCount: budget.primaryCtaLimit,
|
|
17370
|
+
blockIds: ctaContexts.map((context) => context.blockId),
|
|
17371
|
+
...issueMetadata(policy, ["reduce-primary-ctas"])
|
|
17372
|
+
});
|
|
17373
|
+
}
|
|
17374
|
+
const mediaBlockIds = resolved.blocks.filter((block) => hasMediaAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
17375
|
+
const mediaIssue = issueWhenRatioExceeded({
|
|
17376
|
+
kind: "media-density-exceeded",
|
|
17377
|
+
policy,
|
|
17378
|
+
budget: budget.mediaDensity,
|
|
17379
|
+
blockIds: mediaBlockIds,
|
|
17380
|
+
totalBlocks,
|
|
17381
|
+
allowedRatio: compositionDensityRatioLimits[budget.mediaDensity]
|
|
17382
|
+
});
|
|
17383
|
+
if (mediaIssue) {
|
|
17384
|
+
issues.push(mediaIssue);
|
|
17385
|
+
}
|
|
17386
|
+
const decorativeBlockIds = resolved.blocks.filter((block) => hasDecorativeAnnotation(contextsByBlockId.get(block.blockId))).map((block) => block.blockId);
|
|
17387
|
+
const decorativeIssue = issueWhenRatioExceeded({
|
|
17388
|
+
kind: "decorative-repetition-exceeded",
|
|
17389
|
+
policy,
|
|
17390
|
+
budget: budget.decorativeRepetition,
|
|
17391
|
+
blockIds: decorativeBlockIds,
|
|
17392
|
+
totalBlocks,
|
|
17393
|
+
allowedRatio: compositionDensityRatioLimits[budget.decorativeRepetition]
|
|
17291
17394
|
});
|
|
17395
|
+
if (decorativeIssue) {
|
|
17396
|
+
issues.push(decorativeIssue);
|
|
17397
|
+
}
|
|
17398
|
+
return issues;
|
|
17399
|
+
}
|
|
17400
|
+
|
|
17401
|
+
//#endregion
|
|
17402
|
+
//#region ../theme-core/src/site-styles/compilationPlan.ts
|
|
17403
|
+
const defaultHeaderBrandPreferences = {
|
|
17404
|
+
brandDisplay: "auto",
|
|
17405
|
+
logoSize: "auto"
|
|
17406
|
+
};
|
|
17407
|
+
function headerBrandPreferencesFromTheme(theme) {
|
|
17292
17408
|
return {
|
|
17293
|
-
|
|
17294
|
-
|
|
17295
|
-
|
|
17296
|
-
|
|
17409
|
+
brandDisplay: theme?.header.logo?.brandDisplay ?? defaultHeaderBrandPreferences.brandDisplay,
|
|
17410
|
+
logoSize: theme?.header.logo?.size ?? defaultHeaderBrandPreferences.logoSize
|
|
17411
|
+
};
|
|
17412
|
+
}
|
|
17413
|
+
function replaceSiteStyleCompilationPlan(input) {
|
|
17414
|
+
return {
|
|
17415
|
+
kind: "replace-site-style",
|
|
17416
|
+
buttons: {
|
|
17417
|
+
kind: "recompile",
|
|
17418
|
+
selection: input.buttonStyleSelection ?? null,
|
|
17419
|
+
reason: "site-style-replacement"
|
|
17297
17420
|
},
|
|
17298
|
-
|
|
17421
|
+
header: {
|
|
17422
|
+
kind: "recompile",
|
|
17423
|
+
selection: input.headerSelection,
|
|
17424
|
+
brandPresentation: input.headerLogo === undefined ? { kind: "use-compiled-defaults" } : {
|
|
17425
|
+
kind: "apply-logo-context",
|
|
17426
|
+
logo: input.headerLogo
|
|
17427
|
+
}
|
|
17428
|
+
},
|
|
17429
|
+
footerLookId: input.footerLookId ?? null
|
|
17299
17430
|
};
|
|
17300
17431
|
}
|
|
17301
|
-
|
|
17302
|
-
|
|
17303
|
-
|
|
17304
|
-
|
|
17305
|
-
|
|
17306
|
-
|
|
17307
|
-
|
|
17432
|
+
/**
|
|
17433
|
+
* Writes the brand display / logo size preference onto the header's logo style.
|
|
17434
|
+
*
|
|
17435
|
+
* Moved here from preview-next in #1318 Phase 4a so the header preference
|
|
17436
|
+
* pipeline can be composed once, in theme-core, rather than half in the client.
|
|
17437
|
+
*/
|
|
17438
|
+
function withHeaderBrandThemePreferences(theme, preferences) {
|
|
17439
|
+
const currentLogo = theme.header.logo;
|
|
17440
|
+
if (!currentLogo && preferences.brandDisplay === defaultHeaderBrandPreferences.brandDisplay && preferences.logoSize === defaultHeaderBrandPreferences.logoSize) {
|
|
17441
|
+
return theme;
|
|
17308
17442
|
}
|
|
17309
17443
|
return {
|
|
17310
|
-
...
|
|
17311
|
-
|
|
17312
|
-
|
|
17313
|
-
|
|
17314
|
-
|
|
17315
|
-
|
|
17444
|
+
...theme,
|
|
17445
|
+
header: {
|
|
17446
|
+
...theme.header,
|
|
17447
|
+
logo: {
|
|
17448
|
+
fontFamily: currentLogo?.fontFamily ?? "heading",
|
|
17449
|
+
letterSpacing: currentLogo?.letterSpacing ?? "normal",
|
|
17450
|
+
gradient: currentLogo?.gradient ?? false,
|
|
17451
|
+
...currentLogo ?? {},
|
|
17452
|
+
brandDisplay: preferences.brandDisplay,
|
|
17453
|
+
size: preferences.logoSize
|
|
17454
|
+
}
|
|
17455
|
+
}
|
|
17316
17456
|
};
|
|
17317
17457
|
}
|
|
17318
|
-
|
|
17319
|
-
|
|
17320
|
-
|
|
17458
|
+
|
|
17459
|
+
//#endregion
|
|
17460
|
+
//#region ../theme-core/src/site-styles/schemaVersionedJson.ts
|
|
17461
|
+
function parseSchemaVersionedJson(input) {
|
|
17462
|
+
if (input.value == null) {
|
|
17463
|
+
return { kind: "absent" };
|
|
17464
|
+
}
|
|
17465
|
+
if (typeof input.value === "object" && input.value !== null && "schemaVersion" in input.value && input.value.schemaVersion !== input.expectedSchemaVersion) {
|
|
17321
17466
|
return {
|
|
17322
|
-
|
|
17323
|
-
|
|
17467
|
+
kind: "invalid",
|
|
17468
|
+
issue: {
|
|
17469
|
+
kind: "unsupported-schema-version",
|
|
17470
|
+
message: input.unsupportedSchemaVersionMessage
|
|
17471
|
+
}
|
|
17472
|
+
};
|
|
17473
|
+
}
|
|
17474
|
+
const parsed = input.schema.safeParse(input.value);
|
|
17475
|
+
if (!parsed.success) {
|
|
17476
|
+
const firstIssue = parsed.error.issues[0];
|
|
17477
|
+
return {
|
|
17478
|
+
kind: "invalid",
|
|
17479
|
+
issue: {
|
|
17480
|
+
kind: "invalid-json-shape",
|
|
17481
|
+
message: firstIssue?.message ?? input.invalidShapeMessage
|
|
17482
|
+
}
|
|
17324
17483
|
};
|
|
17325
17484
|
}
|
|
17326
17485
|
return {
|
|
17327
|
-
|
|
17328
|
-
|
|
17329
|
-
};
|
|
17330
|
-
}
|
|
17331
|
-
function removeBlockFromPageDesignIntent(intent, blockId) {
|
|
17332
|
-
const removedLookIssues = intent.blockLookPins.flatMap((pin) => pin.blockId === blockId ? [{
|
|
17333
|
-
kind: "removed-look-pin-for-deleted-block",
|
|
17334
|
-
blockId,
|
|
17335
|
-
presetId: pin.choice.value,
|
|
17336
|
-
feedback: "debug"
|
|
17337
|
-
}] : []);
|
|
17338
|
-
const removedBoundaryIssues = intent.boundaryPins.flatMap((pin) => pin.previousBlockId === blockId || pin.nextBlockId === blockId ? [{
|
|
17339
|
-
kind: "removed-boundary-pin-for-broken-adjacency",
|
|
17340
|
-
boundaryId: pin.boundaryId,
|
|
17341
|
-
previousBlockId: pin.previousBlockId,
|
|
17342
|
-
nextBlockId: pin.nextBlockId,
|
|
17343
|
-
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17344
|
-
feedback: "debug"
|
|
17345
|
-
}] : []);
|
|
17346
|
-
return {
|
|
17347
|
-
intent: {
|
|
17348
|
-
...intent,
|
|
17349
|
-
blockLookPins: intent.blockLookPins.filter((pin) => pin.blockId !== blockId),
|
|
17350
|
-
boundaryPins: intent.boundaryPins.filter((pin) => pin.previousBlockId !== blockId && pin.nextBlockId !== blockId)
|
|
17351
|
-
},
|
|
17352
|
-
issues: [...removedLookIssues, ...removedBoundaryIssues]
|
|
17353
|
-
};
|
|
17354
|
-
}
|
|
17355
|
-
function pruneBoundaryPinsForOrder(intent, orderedBlockIds) {
|
|
17356
|
-
const adjacentPairs = adjacentPairKeySet(orderedBlockIds);
|
|
17357
|
-
const removedBoundaryIssues = intent.boundaryPins.flatMap((pin) => adjacentPairs.has(boundaryKey(pin.previousBlockId, pin.nextBlockId)) ? [] : [{
|
|
17358
|
-
kind: "removed-boundary-pin-for-broken-adjacency",
|
|
17359
|
-
boundaryId: pin.boundaryId,
|
|
17360
|
-
previousBlockId: pin.previousBlockId,
|
|
17361
|
-
nextBlockId: pin.nextBlockId,
|
|
17362
|
-
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17363
|
-
feedback: "debug"
|
|
17364
|
-
}]);
|
|
17365
|
-
return {
|
|
17366
|
-
intent: {
|
|
17367
|
-
...intent,
|
|
17368
|
-
boundaryPins: intent.boundaryPins.filter((pin) => adjacentPairs.has(boundaryKey(pin.previousBlockId, pin.nextBlockId)))
|
|
17369
|
-
},
|
|
17370
|
-
issues: removedBoundaryIssues
|
|
17486
|
+
kind: "parsed",
|
|
17487
|
+
value: parsed.data
|
|
17371
17488
|
};
|
|
17372
17489
|
}
|
|
17490
|
+
|
|
17491
|
+
//#endregion
|
|
17492
|
+
//#region ../theme-core/src/site-styles/pageDesignIntent.ts
|
|
17493
|
+
const pageDesignIntentSchemaVersion = 2;
|
|
17494
|
+
const legacyPageDesignIntentSchemaVersion = 1;
|
|
17495
|
+
const unknownBoundaryOptionId = asBoundaryOptionId("break:unknown");
|
|
17373
17496
|
/**
|
|
17374
|
-
*
|
|
17375
|
-
*
|
|
17376
|
-
* the resolver must render a safe auto fallback while the user-facing issue is open.
|
|
17497
|
+
* Site style is site-owned authority. Page design snapshots retain pins and
|
|
17498
|
+
* flow choices, but must not keep resolving against a superseded site style.
|
|
17377
17499
|
*/
|
|
17378
|
-
function
|
|
17379
|
-
|
|
17380
|
-
...
|
|
17381
|
-
|
|
17382
|
-
} : pin);
|
|
17383
|
-
const changed = intent.blockLookPins.find((pin) => pin.blockId === event.blockId);
|
|
17384
|
-
const incompatiblePinnedLook = changed && !event.compatiblePinnedLookPresetIds.includes(changed.choice.value) ? changed : null;
|
|
17385
|
-
return {
|
|
17386
|
-
intent: {
|
|
17387
|
-
...intent,
|
|
17388
|
-
blockLookPins
|
|
17389
|
-
},
|
|
17390
|
-
issues: incompatiblePinnedLook ? [{
|
|
17391
|
-
kind: "pinned-look-incompatible-with-block-kind",
|
|
17392
|
-
blockId: event.blockId,
|
|
17393
|
-
presetId: incompatiblePinnedLook.choice.value,
|
|
17394
|
-
previousBlockKind: incompatiblePinnedLook.blockKind,
|
|
17395
|
-
nextBlockKind: event.nextBlockKind,
|
|
17396
|
-
feedback: "user-facing"
|
|
17397
|
-
}] : []
|
|
17500
|
+
function rebasePageDesignIntentToSiteStyle(intent, siteStyleId) {
|
|
17501
|
+
return intent.siteStyleId === siteStyleId ? intent : {
|
|
17502
|
+
...intent,
|
|
17503
|
+
siteStyleId
|
|
17398
17504
|
};
|
|
17399
17505
|
}
|
|
17400
|
-
|
|
17401
|
-
|
|
17402
|
-
|
|
17403
|
-
}
|
|
17506
|
+
const pageDesignUserPinnedAppearanceChoiceSchema = z.object({
|
|
17507
|
+
kind: z.literal("user-pinned"),
|
|
17508
|
+
value: z.string().min(1).transform(asAppearancePresetId)
|
|
17509
|
+
}).strict();
|
|
17510
|
+
const pageDesignUserPinnedBoundaryChoiceSchema = z.object({
|
|
17511
|
+
kind: z.literal("user-pinned"),
|
|
17512
|
+
value: z.string().min(1).transform(asBoundaryOptionId)
|
|
17513
|
+
}).strict();
|
|
17514
|
+
const pageDesignBoundaryTreatmentSchema = z.discriminatedUnion("kind", [
|
|
17515
|
+
z.object({ kind: z.literal("none") }).strict(),
|
|
17516
|
+
z.object({
|
|
17517
|
+
kind: z.literal("soft-fade"),
|
|
17518
|
+
height: z.enum([
|
|
17519
|
+
"compact",
|
|
17520
|
+
"medium",
|
|
17521
|
+
"large",
|
|
17522
|
+
"expansive"
|
|
17523
|
+
]),
|
|
17524
|
+
curve: z.enum([
|
|
17525
|
+
"soft",
|
|
17526
|
+
"spacious",
|
|
17527
|
+
"expansive"
|
|
17528
|
+
])
|
|
17529
|
+
}).strict(),
|
|
17530
|
+
z.object({
|
|
17531
|
+
kind: z.literal("wave-edge"),
|
|
17532
|
+
height: z.enum([
|
|
17533
|
+
"compact",
|
|
17534
|
+
"medium",
|
|
17535
|
+
"large"
|
|
17536
|
+
]),
|
|
17537
|
+
amplitude: z.enum([
|
|
17538
|
+
"subtle",
|
|
17539
|
+
"balanced",
|
|
17540
|
+
"bold"
|
|
17541
|
+
]),
|
|
17542
|
+
rhythm: z.enum(["single", "double"]),
|
|
17543
|
+
symmetry: z.enum([
|
|
17544
|
+
"symmetrical",
|
|
17545
|
+
"asymmetrical",
|
|
17546
|
+
"drift"
|
|
17547
|
+
])
|
|
17548
|
+
}).strict(),
|
|
17549
|
+
z.object({
|
|
17550
|
+
kind: z.literal("angle-edge"),
|
|
17551
|
+
height: z.enum([
|
|
17552
|
+
"compact",
|
|
17553
|
+
"medium",
|
|
17554
|
+
"large"
|
|
17555
|
+
]),
|
|
17556
|
+
slope: z.enum([
|
|
17557
|
+
"subtle",
|
|
17558
|
+
"balanced",
|
|
17559
|
+
"steep"
|
|
17560
|
+
]),
|
|
17561
|
+
direction: z.enum(["forward", "reverse"])
|
|
17562
|
+
}).strict(),
|
|
17563
|
+
z.object({
|
|
17564
|
+
kind: z.literal("legacy-unsupported"),
|
|
17565
|
+
boundaryOptionId: z.string().min(1).transform(asBoundaryOptionId)
|
|
17566
|
+
}).strict()
|
|
17567
|
+
]);
|
|
17568
|
+
const pageDesignUserPinnedBoundaryTreatmentChoiceSchema = z.object({
|
|
17569
|
+
kind: z.literal("user-pinned"),
|
|
17570
|
+
value: pageDesignBoundaryTreatmentSchema
|
|
17571
|
+
}).strict();
|
|
17572
|
+
const pageDesignBlockLookPinSchema = z.object({
|
|
17573
|
+
blockId: z.string().min(1).transform(asDesignBlockId),
|
|
17574
|
+
blockKind: z.string().min(1),
|
|
17575
|
+
choice: pageDesignUserPinnedAppearanceChoiceSchema
|
|
17576
|
+
}).strict();
|
|
17577
|
+
const pageDesignBoundaryPinSchema = z.object({
|
|
17578
|
+
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17579
|
+
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17580
|
+
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17581
|
+
choice: pageDesignUserPinnedBoundaryTreatmentChoiceSchema
|
|
17582
|
+
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17583
|
+
const legacyPageDesignBoundaryPinSchema = z.object({
|
|
17584
|
+
boundaryId: z.string().min(1).transform(asDesignBoundaryId),
|
|
17585
|
+
previousBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17586
|
+
nextBlockId: z.string().min(1).transform(asDesignBlockId),
|
|
17587
|
+
choice: pageDesignUserPinnedBoundaryChoiceSchema
|
|
17588
|
+
}).strict().superRefine(validateBoundaryPinIdMatchesBlocks);
|
|
17404
17589
|
/**
|
|
17405
|
-
*
|
|
17406
|
-
*
|
|
17590
|
+
* Persisted editor intent stores only user-pinned block Looks and boundary choices.
|
|
17591
|
+
* Missing pins mean `auto`; block-kind/preset compatibility is enforced by resolution,
|
|
17592
|
+
* not by this JSON parse boundary.
|
|
17407
17593
|
*/
|
|
17408
|
-
|
|
17409
|
-
|
|
17410
|
-
|
|
17411
|
-
|
|
17412
|
-
|
|
17413
|
-
|
|
17414
|
-
|
|
17594
|
+
const pageDesignIntentV1Schema = z.object({
|
|
17595
|
+
schemaVersion: z.literal(legacyPageDesignIntentSchemaVersion),
|
|
17596
|
+
siteStyleId: z.string().min(1).transform(asSiteStyleId),
|
|
17597
|
+
pageFlowPresetId: z.string().min(1).transform(asPageFlowPresetId),
|
|
17598
|
+
blockLookPins: z.array(pageDesignBlockLookPinSchema),
|
|
17599
|
+
boundaryPins: z.array(legacyPageDesignBoundaryPinSchema)
|
|
17600
|
+
}).strict().superRefine(validateUniquePageDesignPins);
|
|
17601
|
+
const pageDesignIntentV2Schema = z.object({
|
|
17602
|
+
schemaVersion: z.literal(pageDesignIntentSchemaVersion),
|
|
17603
|
+
siteStyleId: z.string().min(1).transform(asSiteStyleId),
|
|
17604
|
+
pageFlowPresetId: z.string().min(1).transform(asPageFlowPresetId),
|
|
17605
|
+
blockLookPins: z.array(pageDesignBlockLookPinSchema),
|
|
17606
|
+
boundaryPins: z.array(pageDesignBoundaryPinSchema)
|
|
17607
|
+
}).strict().superRefine(validateUniquePageDesignPins);
|
|
17608
|
+
function parsePageDesignIntent(value, options = {}) {
|
|
17609
|
+
if (isLegacyPageDesignIntentCandidate(value)) {
|
|
17610
|
+
const legacyParsed = parseSchemaVersionedJson({
|
|
17611
|
+
value,
|
|
17612
|
+
schema: pageDesignIntentV1Schema,
|
|
17613
|
+
expectedSchemaVersion: legacyPageDesignIntentSchemaVersion,
|
|
17614
|
+
unsupportedSchemaVersionMessage: options.unsupportedSchemaVersionMessage ?? "Unsupported Theme V2 page design intent schemaVersion.",
|
|
17615
|
+
invalidShapeMessage: options.invalidShapeMessage ?? "Invalid Theme V2 page design intent shape."
|
|
17616
|
+
});
|
|
17617
|
+
switch (legacyParsed.kind) {
|
|
17618
|
+
case "absent": return legacyParsed;
|
|
17619
|
+
case "parsed": return {
|
|
17620
|
+
kind: "parsed",
|
|
17621
|
+
intent: normalizeLegacyPageDesignIntent(legacyParsed.value)
|
|
17622
|
+
};
|
|
17623
|
+
case "invalid": return legacyParsed;
|
|
17624
|
+
default: return assertNever$1(legacyParsed, "Unhandled legacy page design intent JSON parse result");
|
|
17625
|
+
}
|
|
17415
17626
|
}
|
|
17416
|
-
|
|
17417
|
-
|
|
17418
|
-
|
|
17419
|
-
|
|
17420
|
-
|
|
17421
|
-
|
|
17422
|
-
|
|
17423
|
-
|
|
17424
|
-
|
|
17627
|
+
const parsed = parseSchemaVersionedJson({
|
|
17628
|
+
value,
|
|
17629
|
+
schema: pageDesignIntentV2Schema,
|
|
17630
|
+
expectedSchemaVersion: pageDesignIntentSchemaVersion,
|
|
17631
|
+
unsupportedSchemaVersionMessage: options.unsupportedSchemaVersionMessage ?? "Unsupported Theme V2 page design intent schemaVersion.",
|
|
17632
|
+
invalidShapeMessage: options.invalidShapeMessage ?? "Invalid Theme V2 page design intent shape."
|
|
17633
|
+
});
|
|
17634
|
+
switch (parsed.kind) {
|
|
17635
|
+
case "absent": return parsed;
|
|
17636
|
+
case "parsed": return {
|
|
17637
|
+
kind: "parsed",
|
|
17638
|
+
intent: parsed.value
|
|
17425
17639
|
};
|
|
17640
|
+
case "invalid": return parsed;
|
|
17641
|
+
default: return assertNever$1(parsed, "Unhandled page design intent JSON parse result");
|
|
17426
17642
|
}
|
|
17643
|
+
}
|
|
17644
|
+
function isLegacyPageDesignIntentCandidate(value) {
|
|
17645
|
+
return typeof value === "object" && value !== null && "schemaVersion" in value && value.schemaVersion === legacyPageDesignIntentSchemaVersion;
|
|
17646
|
+
}
|
|
17647
|
+
function normalizeLegacyPageDesignIntent(intent) {
|
|
17427
17648
|
return {
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
|
|
17433
|
-
|
|
17434
|
-
|
|
17435
|
-
|
|
17436
|
-
|
|
17649
|
+
schemaVersion: pageDesignIntentSchemaVersion,
|
|
17650
|
+
siteStyleId: intent.siteStyleId,
|
|
17651
|
+
pageFlowPresetId: intent.pageFlowPresetId,
|
|
17652
|
+
blockLookPins: intent.blockLookPins,
|
|
17653
|
+
boundaryPins: intent.boundaryPins.map((pin) => ({
|
|
17654
|
+
boundaryId: pin.boundaryId,
|
|
17655
|
+
previousBlockId: pin.previousBlockId,
|
|
17656
|
+
nextBlockId: pin.nextBlockId,
|
|
17657
|
+
choice: userPinnedDesignChoice(boundaryTreatmentForBoundaryOptionId(pin.choice.value))
|
|
17658
|
+
}))
|
|
17437
17659
|
};
|
|
17438
17660
|
}
|
|
17439
|
-
function
|
|
17440
|
-
|
|
17441
|
-
const [first, ...rest] = orderedBlockIds;
|
|
17442
|
-
if (!first) {
|
|
17443
|
-
return pairs;
|
|
17444
|
-
}
|
|
17445
|
-
let previousBlockId = first;
|
|
17446
|
-
for (const nextBlockId of rest) {
|
|
17447
|
-
pairs.add(boundaryKey(previousBlockId, nextBlockId));
|
|
17448
|
-
previousBlockId = nextBlockId;
|
|
17449
|
-
}
|
|
17450
|
-
return pairs;
|
|
17661
|
+
function autoDesignChoice() {
|
|
17662
|
+
return { kind: "auto" };
|
|
17451
17663
|
}
|
|
17452
|
-
function
|
|
17664
|
+
function userPinnedDesignChoice(value) {
|
|
17665
|
+
return {
|
|
17666
|
+
kind: "user-pinned",
|
|
17667
|
+
value
|
|
17668
|
+
};
|
|
17669
|
+
}
|
|
17670
|
+
function resolvePageDesignBlockLookChoice(intent, blockId) {
|
|
17671
|
+
return intent.blockLookPins.find((pin) => pin.blockId === blockId)?.choice ?? autoDesignChoice();
|
|
17672
|
+
}
|
|
17673
|
+
function resolvePageDesignBoundaryChoice(intent, previousBlockId, nextBlockId) {
|
|
17674
|
+
return intent.boundaryPins.find((pin) => pin.previousBlockId === previousBlockId && pin.nextBlockId === nextBlockId)?.choice ?? autoDesignChoice();
|
|
17675
|
+
}
|
|
17676
|
+
function buildBoundaryPin(previousBlockId, nextBlockId, choice) {
|
|
17677
|
+
return {
|
|
17678
|
+
boundaryId: makeBoundaryId(previousBlockId, nextBlockId),
|
|
17679
|
+
previousBlockId,
|
|
17680
|
+
nextBlockId,
|
|
17681
|
+
choice
|
|
17682
|
+
};
|
|
17683
|
+
}
|
|
17684
|
+
function reducePageDesignIntentForStructureEvent(intent, event) {
|
|
17685
|
+
switch (event.kind) {
|
|
17686
|
+
case "block-added": return {
|
|
17687
|
+
intent,
|
|
17688
|
+
issues: []
|
|
17689
|
+
};
|
|
17690
|
+
case "block-removed": return removeBlockFromPageDesignIntent(intent, event.blockId);
|
|
17691
|
+
case "blocks-reordered": return pruneBoundaryPinsForOrder(intent, event.orderedBlockIds);
|
|
17692
|
+
case "block-kind-changed": return changeBlockKindInPageDesignIntent(intent, event);
|
|
17693
|
+
case "block-duplicated": return duplicateBlockInPageDesignIntent(intent, event);
|
|
17694
|
+
default: return assertNever$1(event, "Unhandled page design structure event");
|
|
17695
|
+
}
|
|
17696
|
+
}
|
|
17697
|
+
function reducePageDesignIntentForUserAction(intent, action) {
|
|
17698
|
+
switch (action.kind) {
|
|
17699
|
+
case "set-page-flow": return {
|
|
17700
|
+
...intent,
|
|
17701
|
+
pageFlowPresetId: action.pageFlowPresetId
|
|
17702
|
+
};
|
|
17703
|
+
case "set-block-look": return setBlockLookChoice(intent, action.block, action.choice);
|
|
17704
|
+
case "set-boundary": return setBoundaryChoice(intent, action.previousBlockId, action.nextBlockId, action.choice);
|
|
17705
|
+
default: return assertNever$1(action, "Unhandled page design user action");
|
|
17706
|
+
}
|
|
17707
|
+
}
|
|
17708
|
+
function remapPageDesignIntentForDuplicate(intent, input) {
|
|
17709
|
+
const targetBySourceId = new Map(input.blockMappings.map((mapping) => [mapping.sourceBlockId, {
|
|
17710
|
+
blockId: mapping.targetBlockId,
|
|
17711
|
+
blockKind: mapping.targetBlockKind
|
|
17712
|
+
}]));
|
|
17713
|
+
const targetBlockOrder = input.blockMappings.map((mapping) => mapping.targetBlockId);
|
|
17714
|
+
const adjacentTargetPairs = adjacentPairKeySet(targetBlockOrder);
|
|
17715
|
+
const blockLookPins = intent.blockLookPins.flatMap((pin) => {
|
|
17716
|
+
const target = targetBySourceId.get(pin.blockId);
|
|
17717
|
+
return target ? [{
|
|
17718
|
+
blockId: target.blockId,
|
|
17719
|
+
blockKind: target.blockKind,
|
|
17720
|
+
choice: pin.choice
|
|
17721
|
+
}] : [];
|
|
17722
|
+
});
|
|
17723
|
+
const boundaryPins = intent.boundaryPins.flatMap((pin) => {
|
|
17724
|
+
const targetPrevious = targetBySourceId.get(pin.previousBlockId);
|
|
17725
|
+
const targetNext = targetBySourceId.get(pin.nextBlockId);
|
|
17726
|
+
if (!targetPrevious || !targetNext) {
|
|
17727
|
+
return [];
|
|
17728
|
+
}
|
|
17729
|
+
if (!adjacentTargetPairs.has(makeBoundaryId(targetPrevious.blockId, targetNext.blockId))) {
|
|
17730
|
+
return [];
|
|
17731
|
+
}
|
|
17732
|
+
return [buildBoundaryPin(targetPrevious.blockId, targetNext.blockId, pin.choice)];
|
|
17733
|
+
});
|
|
17734
|
+
return {
|
|
17735
|
+
intent: {
|
|
17736
|
+
...intent,
|
|
17737
|
+
blockLookPins,
|
|
17738
|
+
boundaryPins
|
|
17739
|
+
},
|
|
17740
|
+
issues: []
|
|
17741
|
+
};
|
|
17742
|
+
}
|
|
17743
|
+
function setBlockLookChoice(intent, block, choice) {
|
|
17744
|
+
const withoutBlock = intent.blockLookPins.filter((pin) => pin.blockId !== block.blockId);
|
|
17745
|
+
if (choice.kind === "auto") {
|
|
17746
|
+
return {
|
|
17747
|
+
...intent,
|
|
17748
|
+
blockLookPins: withoutBlock
|
|
17749
|
+
};
|
|
17750
|
+
}
|
|
17751
|
+
return {
|
|
17752
|
+
...intent,
|
|
17753
|
+
blockLookPins: [...withoutBlock, {
|
|
17754
|
+
blockId: block.blockId,
|
|
17755
|
+
blockKind: block.blockKind,
|
|
17756
|
+
choice
|
|
17757
|
+
}]
|
|
17758
|
+
};
|
|
17759
|
+
}
|
|
17760
|
+
function setBoundaryChoice(intent, previousBlockId, nextBlockId, choice) {
|
|
17761
|
+
const withoutBoundary = intent.boundaryPins.filter((pin) => pin.previousBlockId !== previousBlockId || pin.nextBlockId !== nextBlockId);
|
|
17762
|
+
if (choice.kind === "auto") {
|
|
17763
|
+
return {
|
|
17764
|
+
...intent,
|
|
17765
|
+
boundaryPins: withoutBoundary
|
|
17766
|
+
};
|
|
17767
|
+
}
|
|
17768
|
+
return {
|
|
17769
|
+
...intent,
|
|
17770
|
+
boundaryPins: [...withoutBoundary, buildBoundaryPin(previousBlockId, nextBlockId, choice)]
|
|
17771
|
+
};
|
|
17772
|
+
}
|
|
17773
|
+
function removeBlockFromPageDesignIntent(intent, blockId) {
|
|
17774
|
+
const removedLookIssues = intent.blockLookPins.flatMap((pin) => pin.blockId === blockId ? [{
|
|
17775
|
+
kind: "removed-look-pin-for-deleted-block",
|
|
17776
|
+
blockId,
|
|
17777
|
+
presetId: pin.choice.value,
|
|
17778
|
+
feedback: "debug"
|
|
17779
|
+
}] : []);
|
|
17780
|
+
const removedBoundaryIssues = intent.boundaryPins.flatMap((pin) => pin.previousBlockId === blockId || pin.nextBlockId === blockId ? [{
|
|
17781
|
+
kind: "removed-boundary-pin-for-broken-adjacency",
|
|
17782
|
+
boundaryId: pin.boundaryId,
|
|
17783
|
+
previousBlockId: pin.previousBlockId,
|
|
17784
|
+
nextBlockId: pin.nextBlockId,
|
|
17785
|
+
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17786
|
+
feedback: "debug"
|
|
17787
|
+
}] : []);
|
|
17788
|
+
return {
|
|
17789
|
+
intent: {
|
|
17790
|
+
...intent,
|
|
17791
|
+
blockLookPins: intent.blockLookPins.filter((pin) => pin.blockId !== blockId),
|
|
17792
|
+
boundaryPins: intent.boundaryPins.filter((pin) => pin.previousBlockId !== blockId && pin.nextBlockId !== blockId)
|
|
17793
|
+
},
|
|
17794
|
+
issues: [...removedLookIssues, ...removedBoundaryIssues]
|
|
17795
|
+
};
|
|
17796
|
+
}
|
|
17797
|
+
function pruneBoundaryPinsForOrder(intent, orderedBlockIds) {
|
|
17798
|
+
const adjacentPairs = adjacentPairKeySet(orderedBlockIds);
|
|
17799
|
+
const removedBoundaryIssues = intent.boundaryPins.flatMap((pin) => adjacentPairs.has(makeBoundaryId(pin.previousBlockId, pin.nextBlockId)) ? [] : [{
|
|
17800
|
+
kind: "removed-boundary-pin-for-broken-adjacency",
|
|
17801
|
+
boundaryId: pin.boundaryId,
|
|
17802
|
+
previousBlockId: pin.previousBlockId,
|
|
17803
|
+
nextBlockId: pin.nextBlockId,
|
|
17804
|
+
presetId: boundaryIssuePresetId(pin.choice.value),
|
|
17805
|
+
feedback: "debug"
|
|
17806
|
+
}]);
|
|
17807
|
+
return {
|
|
17808
|
+
intent: {
|
|
17809
|
+
...intent,
|
|
17810
|
+
boundaryPins: intent.boundaryPins.filter((pin) => adjacentPairs.has(makeBoundaryId(pin.previousBlockId, pin.nextBlockId)))
|
|
17811
|
+
},
|
|
17812
|
+
issues: removedBoundaryIssues
|
|
17813
|
+
};
|
|
17814
|
+
}
|
|
17815
|
+
/**
|
|
17816
|
+
* A block-kind change updates the pin's current block kind so future resolution sees
|
|
17817
|
+
* the current tree. If the pinned Look is incompatible, the pin remains stored and
|
|
17818
|
+
* the resolver must render a safe auto fallback while the user-facing issue is open.
|
|
17819
|
+
*/
|
|
17820
|
+
function changeBlockKindInPageDesignIntent(intent, event) {
|
|
17821
|
+
const blockLookPins = intent.blockLookPins.map((pin) => pin.blockId === event.blockId ? {
|
|
17822
|
+
...pin,
|
|
17823
|
+
blockKind: event.nextBlockKind
|
|
17824
|
+
} : pin);
|
|
17825
|
+
const changed = intent.blockLookPins.find((pin) => pin.blockId === event.blockId);
|
|
17826
|
+
const incompatiblePinnedLook = changed && !event.compatiblePinnedLookPresetIds.includes(changed.choice.value) ? changed : null;
|
|
17827
|
+
return {
|
|
17828
|
+
intent: {
|
|
17829
|
+
...intent,
|
|
17830
|
+
blockLookPins
|
|
17831
|
+
},
|
|
17832
|
+
issues: incompatiblePinnedLook ? [{
|
|
17833
|
+
kind: "pinned-look-incompatible-with-block-kind",
|
|
17834
|
+
blockId: event.blockId,
|
|
17835
|
+
presetId: incompatiblePinnedLook.choice.value,
|
|
17836
|
+
previousBlockKind: incompatiblePinnedLook.blockKind,
|
|
17837
|
+
nextBlockKind: event.nextBlockKind,
|
|
17838
|
+
feedback: "user-facing"
|
|
17839
|
+
}] : []
|
|
17840
|
+
};
|
|
17841
|
+
}
|
|
17842
|
+
function boundaryIssuePresetId(treatment) {
|
|
17843
|
+
if (typeof treatment === "string") return treatment;
|
|
17844
|
+
return boundaryOptionIdForTreatment(treatment) ?? unknownBoundaryOptionId;
|
|
17845
|
+
}
|
|
17846
|
+
/**
|
|
17847
|
+
* Ordinary block duplication does not copy boundary pins. Boundary pins represent
|
|
17848
|
+
* exact adjacent pairs, so duplicated blocks start with automatic surrounding breaks.
|
|
17849
|
+
*/
|
|
17850
|
+
function duplicateBlockInPageDesignIntent(intent, event) {
|
|
17851
|
+
const sourcePin = intent.blockLookPins.find((pin) => pin.blockId === event.sourceBlockId);
|
|
17852
|
+
if (!event.copyPinnedLook) {
|
|
17853
|
+
return {
|
|
17854
|
+
intent,
|
|
17855
|
+
issues: []
|
|
17856
|
+
};
|
|
17857
|
+
}
|
|
17858
|
+
if (!sourcePin) {
|
|
17859
|
+
return {
|
|
17860
|
+
intent,
|
|
17861
|
+
issues: [{
|
|
17862
|
+
kind: "missing-look-pin-to-copy-on-duplicate",
|
|
17863
|
+
sourceBlockId: event.sourceBlockId,
|
|
17864
|
+
duplicatedBlockId: event.block.blockId,
|
|
17865
|
+
feedback: "debug"
|
|
17866
|
+
}]
|
|
17867
|
+
};
|
|
17868
|
+
}
|
|
17869
|
+
return {
|
|
17870
|
+
intent: {
|
|
17871
|
+
...intent,
|
|
17872
|
+
blockLookPins: [...intent.blockLookPins, {
|
|
17873
|
+
blockId: event.block.blockId,
|
|
17874
|
+
blockKind: event.block.blockKind,
|
|
17875
|
+
choice: sourcePin.choice
|
|
17876
|
+
}]
|
|
17877
|
+
},
|
|
17878
|
+
issues: []
|
|
17879
|
+
};
|
|
17880
|
+
}
|
|
17881
|
+
function adjacentPairKeySet(orderedBlockIds) {
|
|
17882
|
+
const pairs = new Set();
|
|
17883
|
+
const [first, ...rest] = orderedBlockIds;
|
|
17884
|
+
if (!first) {
|
|
17885
|
+
return pairs;
|
|
17886
|
+
}
|
|
17887
|
+
let previousBlockId = first;
|
|
17888
|
+
for (const nextBlockId of rest) {
|
|
17889
|
+
pairs.add(makeBoundaryId(previousBlockId, nextBlockId));
|
|
17890
|
+
previousBlockId = nextBlockId;
|
|
17891
|
+
}
|
|
17892
|
+
return pairs;
|
|
17893
|
+
}
|
|
17894
|
+
function addDuplicateStringIssues(ctx, input) {
|
|
17453
17895
|
const seen = new Set();
|
|
17454
17896
|
const duplicates = new Set();
|
|
17455
17897
|
for (const value of input.values) {
|
|
@@ -17483,14 +17925,11 @@ function validateUniquePageDesignPins(intent, ctx) {
|
|
|
17483
17925
|
label: "block Look pin"
|
|
17484
17926
|
});
|
|
17485
17927
|
addDuplicateStringIssues(ctx, {
|
|
17486
|
-
values: intent.boundaryPins.map((pin) =>
|
|
17928
|
+
values: intent.boundaryPins.map((pin) => makeBoundaryId(pin.previousBlockId, pin.nextBlockId)),
|
|
17487
17929
|
path: ["boundaryPins"],
|
|
17488
17930
|
label: "boundary pin"
|
|
17489
17931
|
});
|
|
17490
17932
|
}
|
|
17491
|
-
function boundaryKey(previousBlockId, nextBlockId) {
|
|
17492
|
-
return makeBoundaryId(previousBlockId, nextBlockId);
|
|
17493
|
-
}
|
|
17494
17933
|
|
|
17495
17934
|
//#endregion
|
|
17496
17935
|
//#region ../theme-core/src/site-styles/contentTemplateDesignIntent.ts
|
|
@@ -20855,7 +21294,7 @@ function underlineNavLinkStyle(colorToken, underlineColorToken, typography = "pl
|
|
|
20855
21294
|
}] }
|
|
20856
21295
|
}, typography);
|
|
20857
21296
|
}
|
|
20858
|
-
function pillNavLinkStyle(colorToken, backgroundToken = "primary", opacity = 10, typography = "plain") {
|
|
21297
|
+
function pillNavLinkStyle(colorToken, backgroundToken$1 = "primary", opacity = 10, typography = "plain") {
|
|
20859
21298
|
return applyNavTypography({
|
|
20860
21299
|
name: "Pill",
|
|
20861
21300
|
typography: "body",
|
|
@@ -20869,14 +21308,14 @@ function pillNavLinkStyle(colorToken, backgroundToken = "primary", opacity = 10,
|
|
|
20869
21308
|
hover: [{
|
|
20870
21309
|
effectId: "background-on-hover-alpha",
|
|
20871
21310
|
options: {
|
|
20872
|
-
colorToken: backgroundToken,
|
|
21311
|
+
colorToken: backgroundToken$1,
|
|
20873
21312
|
opacity
|
|
20874
21313
|
}
|
|
20875
21314
|
}],
|
|
20876
21315
|
active: [{
|
|
20877
21316
|
effectId: "background-on-hover-alpha",
|
|
20878
21317
|
options: {
|
|
20879
|
-
colorToken: backgroundToken,
|
|
21318
|
+
colorToken: backgroundToken$1,
|
|
20880
21319
|
opacity: opacity + 5
|
|
20881
21320
|
}
|
|
20882
21321
|
}]
|
|
@@ -21930,151 +22369,650 @@ function classifyRuntimeStyleFields(input) {
|
|
|
21930
22369
|
fields: []
|
|
21931
22370
|
};
|
|
21932
22371
|
}
|
|
21933
|
-
if (!input.authority) {
|
|
21934
|
-
return {
|
|
21935
|
-
kind: "unsupported-manual-review",
|
|
21936
|
-
fields
|
|
21937
|
-
};
|
|
22372
|
+
if (!input.authority) {
|
|
22373
|
+
return {
|
|
22374
|
+
kind: "unsupported-manual-review",
|
|
22375
|
+
fields
|
|
22376
|
+
};
|
|
22377
|
+
}
|
|
22378
|
+
switch (input.authority.kind) {
|
|
22379
|
+
case "theme-v2": return {
|
|
22380
|
+
kind: "interpretable-override",
|
|
22381
|
+
fields,
|
|
22382
|
+
authority: input.authority
|
|
22383
|
+
};
|
|
22384
|
+
case "advanced-detached": return {
|
|
22385
|
+
kind: "advanced-detached",
|
|
22386
|
+
fields,
|
|
22387
|
+
authority: input.authority
|
|
22388
|
+
};
|
|
22389
|
+
case "legacy-raw": return {
|
|
22390
|
+
kind: "unsupported-manual-review",
|
|
22391
|
+
fields,
|
|
22392
|
+
authority: input.authority
|
|
22393
|
+
};
|
|
22394
|
+
default: return assertNever$1(input.authority);
|
|
22395
|
+
}
|
|
22396
|
+
}
|
|
22397
|
+
function canWriteThemeV2RuntimeFields(authority) {
|
|
22398
|
+
return authority?.kind === "theme-v2";
|
|
22399
|
+
}
|
|
22400
|
+
function blockReasonForAuthority(authority) {
|
|
22401
|
+
if (!authority) {
|
|
22402
|
+
return "missing-theme-v2-authority";
|
|
22403
|
+
}
|
|
22404
|
+
switch (authority?.kind) {
|
|
22405
|
+
case "advanced-detached": return "advanced-detached";
|
|
22406
|
+
case "legacy-raw": return "legacy-raw";
|
|
22407
|
+
default: return assertNever$1(authority);
|
|
22408
|
+
}
|
|
22409
|
+
}
|
|
22410
|
+
/**
|
|
22411
|
+
* Replace every compiler-owned field on a block's content with a fresh compiled
|
|
22412
|
+
* set — the one primitive both writers of compiled output share.
|
|
22413
|
+
*
|
|
22414
|
+
* Replacement rather than merge is the whole point: a field the new
|
|
22415
|
+
* compilation does not produce must *go*, or a recompile onto a Look that asks
|
|
22416
|
+
* for no card leaves the old `_cardStyles` sitting there claiming a surface
|
|
22417
|
+
* nobody asked for. Every writer that discovers compiler ownership for itself
|
|
22418
|
+
* eventually forgets one of these names, so nobody does.
|
|
22419
|
+
*
|
|
22420
|
+
* Pure, and deliberately free of authority checks — those belong to the
|
|
22421
|
+
* persistence wrapper, not to the shape of the content.
|
|
22422
|
+
*/
|
|
22423
|
+
function withCompiledRuntimeStyleFields(input) {
|
|
22424
|
+
const authored = Object.fromEntries(Object.entries(stripStaleTransitionStyleGroup(input.content)).filter(([fieldName]) => !themeV2CompilerOwnedFieldNames.includes(fieldName)));
|
|
22425
|
+
return {
|
|
22426
|
+
...authored,
|
|
22427
|
+
...input.fields
|
|
22428
|
+
};
|
|
22429
|
+
}
|
|
22430
|
+
/**
|
|
22431
|
+
* Persisted Theme V2 output is compile-at-write: once a block has Theme V2
|
|
22432
|
+
* authority, compiler-owned runtime fields are replaced in the same content
|
|
22433
|
+
* version. Preview-only compile-at-read callers should use compileBlockRuntimeFields
|
|
22434
|
+
* and avoid persisting these fields.
|
|
22435
|
+
*/
|
|
22436
|
+
function replaceCompiledRuntimeStyleFields(input) {
|
|
22437
|
+
if (!canWriteThemeV2RuntimeFields(input.authority)) {
|
|
22438
|
+
return {
|
|
22439
|
+
kind: "blocked",
|
|
22440
|
+
reason: blockReasonForAuthority(input.authority),
|
|
22441
|
+
content: input.content
|
|
22442
|
+
};
|
|
22443
|
+
}
|
|
22444
|
+
return {
|
|
22445
|
+
kind: "applied",
|
|
22446
|
+
content: withCompiledRuntimeStyleFields(input)
|
|
22447
|
+
};
|
|
22448
|
+
}
|
|
22449
|
+
function uniqueBlockIds(values) {
|
|
22450
|
+
return [...new Set(values)];
|
|
22451
|
+
}
|
|
22452
|
+
function collectPageStyleAuthorityBuckets(styleAuthorities) {
|
|
22453
|
+
const themeV2BlockIds = [];
|
|
22454
|
+
const legacyRawBlockIds = [];
|
|
22455
|
+
const advancedDetachedBlockIds = [];
|
|
22456
|
+
for (const entry of styleAuthorities) {
|
|
22457
|
+
switch (entry.authority.kind) {
|
|
22458
|
+
case "theme-v2":
|
|
22459
|
+
themeV2BlockIds.push(entry.blockId);
|
|
22460
|
+
break;
|
|
22461
|
+
case "legacy-raw":
|
|
22462
|
+
legacyRawBlockIds.push(entry.blockId);
|
|
22463
|
+
break;
|
|
22464
|
+
case "advanced-detached":
|
|
22465
|
+
advancedDetachedBlockIds.push(entry.blockId);
|
|
22466
|
+
break;
|
|
22467
|
+
default: assertNever$1(entry.authority);
|
|
22468
|
+
}
|
|
22469
|
+
}
|
|
22470
|
+
return {
|
|
22471
|
+
themeV2BlockIds: uniqueBlockIds(themeV2BlockIds),
|
|
22472
|
+
legacyRawBlockIds: uniqueBlockIds(legacyRawBlockIds),
|
|
22473
|
+
advancedDetachedBlockIds: uniqueBlockIds(advancedDetachedBlockIds)
|
|
22474
|
+
};
|
|
22475
|
+
}
|
|
22476
|
+
function summarizePageStyleAuthorities(state) {
|
|
22477
|
+
const { themeV2BlockIds, legacyRawBlockIds, advancedDetachedBlockIds } = collectPageStyleAuthorityBuckets(state.styleAuthorities);
|
|
22478
|
+
if (themeV2BlockIds.length === 0 && legacyRawBlockIds.length === 0 && advancedDetachedBlockIds.length === 0) {
|
|
22479
|
+
return {
|
|
22480
|
+
kind: "no-runtime-authority",
|
|
22481
|
+
themeV2BlockIds: [],
|
|
22482
|
+
legacyRawBlockIds: [],
|
|
22483
|
+
advancedDetachedBlockIds: []
|
|
22484
|
+
};
|
|
22485
|
+
}
|
|
22486
|
+
if (legacyRawBlockIds.length > 0) {
|
|
22487
|
+
return {
|
|
22488
|
+
kind: "manual-review-required",
|
|
22489
|
+
themeV2BlockIds,
|
|
22490
|
+
legacyRawBlockIds,
|
|
22491
|
+
advancedDetachedBlockIds
|
|
22492
|
+
};
|
|
22493
|
+
}
|
|
22494
|
+
if (themeV2BlockIds.length === 0) {
|
|
22495
|
+
return {
|
|
22496
|
+
kind: "advanced-detached-only",
|
|
22497
|
+
themeV2BlockIds: [],
|
|
22498
|
+
legacyRawBlockIds: [],
|
|
22499
|
+
advancedDetachedBlockIds
|
|
22500
|
+
};
|
|
22501
|
+
}
|
|
22502
|
+
if (advancedDetachedBlockIds.length > 0) {
|
|
22503
|
+
return {
|
|
22504
|
+
kind: "mixed-authority",
|
|
22505
|
+
themeV2BlockIds,
|
|
22506
|
+
legacyRawBlockIds: [],
|
|
22507
|
+
advancedDetachedBlockIds
|
|
22508
|
+
};
|
|
22509
|
+
}
|
|
22510
|
+
return {
|
|
22511
|
+
kind: "theme-v2-only",
|
|
22512
|
+
themeV2BlockIds,
|
|
22513
|
+
legacyRawBlockIds: [],
|
|
22514
|
+
advancedDetachedBlockIds: []
|
|
22515
|
+
};
|
|
22516
|
+
}
|
|
22517
|
+
|
|
22518
|
+
//#endregion
|
|
22519
|
+
//#region ../theme-core/src/site-styles/pageFlowPresets.ts
|
|
22520
|
+
/**
|
|
22521
|
+
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
22522
|
+
*/
|
|
22523
|
+
const pageFlowPresets = [
|
|
22524
|
+
{
|
|
22525
|
+
id: asPageFlowPresetId("flow:quiet"),
|
|
22526
|
+
label: "Quiet",
|
|
22527
|
+
boundaryStrategy: "quiet",
|
|
22528
|
+
defaultBoundaryOptionId: noneBoundaryOption.id
|
|
22529
|
+
},
|
|
22530
|
+
{
|
|
22531
|
+
id: asPageFlowPresetId("flow:balanced"),
|
|
22532
|
+
label: "Balanced",
|
|
22533
|
+
boundaryStrategy: "balanced",
|
|
22534
|
+
defaultBoundaryOptionId: softBoundaryOption.id
|
|
22535
|
+
},
|
|
22536
|
+
{
|
|
22537
|
+
id: asPageFlowPresetId("flow:expressive"),
|
|
22538
|
+
label: "Expressive",
|
|
22539
|
+
boundaryStrategy: "expressive",
|
|
22540
|
+
defaultBoundaryOptionId: spaciousBoundaryOption.id
|
|
22541
|
+
}
|
|
22542
|
+
];
|
|
22543
|
+
/**
|
|
22544
|
+
* The break a join gets when nothing more specific applies. An unknown preset
|
|
22545
|
+
* id (a stale or policy-owned one) falls back to the first boundary option,
|
|
22546
|
+
* and `preset` is null so callers can tell the two apart.
|
|
22547
|
+
*/
|
|
22548
|
+
function pageFlowDefaultBoundary(pageFlowPresetId) {
|
|
22549
|
+
const preset = pageFlowPresets.find((candidate$1) => candidate$1.id === pageFlowPresetId) ?? null;
|
|
22550
|
+
return {
|
|
22551
|
+
preset,
|
|
22552
|
+
boundaryOptionId: preset?.defaultBoundaryOptionId ?? boundaryOptions[0].id
|
|
22553
|
+
};
|
|
22554
|
+
}
|
|
22555
|
+
|
|
22556
|
+
//#endregion
|
|
22557
|
+
//#region ../theme-core/src/site-styles/lookResolution.ts
|
|
22558
|
+
function blockAppearancePresetSupportsBlockKind(preset, blockKind) {
|
|
22559
|
+
return preset.blockKinds.some((candidate$1) => candidate$1 === blockKind);
|
|
22560
|
+
}
|
|
22561
|
+
function preferredAppearanceTargetForBlockKind(blockKind) {
|
|
22562
|
+
switch (blockKind) {
|
|
22563
|
+
case "block.event-calendar":
|
|
22564
|
+
case "block.event-listing": return "events";
|
|
22565
|
+
default: return null;
|
|
22566
|
+
}
|
|
22567
|
+
}
|
|
22568
|
+
function sortCompatibleBlockAppearancePresets(blockKind, options) {
|
|
22569
|
+
const preferredTarget = preferredAppearanceTargetForBlockKind(blockKind);
|
|
22570
|
+
if (!preferredTarget) {
|
|
22571
|
+
return options;
|
|
22572
|
+
}
|
|
22573
|
+
return [...options].sort((left, right) => {
|
|
22574
|
+
const leftPreset = appearancePresets.find((preset) => preset.id === left.id);
|
|
22575
|
+
const rightPreset = appearancePresets.find((preset) => preset.id === right.id);
|
|
22576
|
+
const leftPreferred = leftPreset?.target === preferredTarget;
|
|
22577
|
+
const rightPreferred = rightPreset?.target === preferredTarget;
|
|
22578
|
+
if (leftPreferred === rightPreferred) {
|
|
22579
|
+
return 0;
|
|
22580
|
+
}
|
|
22581
|
+
return leftPreferred ? -1 : 1;
|
|
22582
|
+
});
|
|
22583
|
+
}
|
|
22584
|
+
function blockAppearancePresetSupportsLayoutProfile(preset, profile, input = {}) {
|
|
22585
|
+
const constraints = preset.constraints;
|
|
22586
|
+
if (!constraints || !constraints.layoutFamilies && !constraints.layoutVariantKeys) {
|
|
22587
|
+
return true;
|
|
22588
|
+
}
|
|
22589
|
+
if (!profile) {
|
|
22590
|
+
return input.allowLayoutConstrainedPresetWithoutProfile ?? true;
|
|
22591
|
+
}
|
|
22592
|
+
return layoutProfileSupportsConstraints(profile, constraints);
|
|
22593
|
+
}
|
|
22594
|
+
function resolveBlockAppearancePreset(preset, layoutProfile = null) {
|
|
22595
|
+
return {
|
|
22596
|
+
id: asAppearancePresetId(preset.id),
|
|
22597
|
+
label: preset.label,
|
|
22598
|
+
design: resolveBlockAppearancePresetDesign(preset, layoutProfile)
|
|
22599
|
+
};
|
|
22600
|
+
}
|
|
22601
|
+
function getCompatibleBlockAppearancePresets(input) {
|
|
22602
|
+
const options = appearancePresets.flatMap((preset) => {
|
|
22603
|
+
if (!blockAppearancePresetSupportsBlockKind(preset, input.blockKind) || !blockAppearancePresetSupportsLayoutProfile(preset, input.layoutProfile ?? null, { allowLayoutConstrainedPresetWithoutProfile: input.allowLayoutConstrainedPresetWithoutProfile })) {
|
|
22604
|
+
return [];
|
|
22605
|
+
}
|
|
22606
|
+
return [resolveBlockAppearancePreset(preset, input.layoutProfile ?? null)];
|
|
22607
|
+
});
|
|
22608
|
+
const sortedOptions = sortCompatibleBlockAppearancePresets(input.blockKind, options);
|
|
22609
|
+
const recommendedIds = input.siteStyle?.recommendedAppearancePresetIds ?? [];
|
|
22610
|
+
if (recommendedIds.length === 0) {
|
|
22611
|
+
return sortedOptions;
|
|
22612
|
+
}
|
|
22613
|
+
const recommended = recommendedIds.flatMap((presetId) => sortedOptions.find((option) => option.id === presetId) ?? []);
|
|
22614
|
+
const alreadyIncludedIds = new Set(recommended.map((option) => option.id));
|
|
22615
|
+
return [...recommended, ...sortedOptions.filter((option) => !alreadyIncludedIds.has(option.id))];
|
|
22616
|
+
}
|
|
22617
|
+
|
|
22618
|
+
//#endregion
|
|
22619
|
+
//#region ../theme-core/src/site-styles/siteStyleBlockPolicies.ts
|
|
22620
|
+
const defaultPolicyPageFlowPresetId = asPageFlowPresetId("generated-default");
|
|
22621
|
+
const southWestTwerkSchoolSiteStyleId = asSiteStyleId("site-style:south-west-twerk-school");
|
|
22622
|
+
const heroBrandScrimFixedFrameLookId = asAppearancePresetId("hero-brand-scrim-fixed-frame");
|
|
22623
|
+
const classicHeroLayoutVariantKey = asLayoutVariantKey("classic");
|
|
22624
|
+
const microHeroLayoutVariantKey = asLayoutVariantKey("micro");
|
|
22625
|
+
const waveBoundaryOptionId = asBoundaryOptionId("break:wave");
|
|
22626
|
+
const registeredSiteStyleBlockPolicies = [{
|
|
22627
|
+
siteStyleId: southWestTwerkSchoolSiteStyleId,
|
|
22628
|
+
kind: "locked-look-and-layouts",
|
|
22629
|
+
blockKind: "block.hero",
|
|
22630
|
+
lookId: heroBrandScrimFixedFrameLookId,
|
|
22631
|
+
allowedLayoutVariantKeys: [classicHeroLayoutVariantKey, microHeroLayoutVariantKey],
|
|
22632
|
+
defaultLayoutVariantKey: classicHeroLayoutVariantKey,
|
|
22633
|
+
defaultBoundaryAfter: {
|
|
22634
|
+
optionId: waveBoundaryOptionId,
|
|
22635
|
+
mode: "default-only"
|
|
22636
|
+
},
|
|
22637
|
+
customize: {
|
|
22638
|
+
hideDisallowedLooks: true,
|
|
22639
|
+
hideDisallowedLayouts: true
|
|
22640
|
+
}
|
|
22641
|
+
}];
|
|
22642
|
+
function siteStyleBlockPolicies() {
|
|
22643
|
+
return registeredSiteStyleBlockPolicies;
|
|
22644
|
+
}
|
|
22645
|
+
function buildInitialPolicyPageDesignIntent(siteStyleId) {
|
|
22646
|
+
return {
|
|
22647
|
+
schemaVersion: pageDesignIntentSchemaVersion,
|
|
22648
|
+
siteStyleId,
|
|
22649
|
+
pageFlowPresetId: defaultPolicyPageFlowPresetId,
|
|
22650
|
+
blockLookPins: [],
|
|
22651
|
+
boundaryPins: []
|
|
22652
|
+
};
|
|
22653
|
+
}
|
|
22654
|
+
function deriveSiteStyleBlockPolicy(input) {
|
|
22655
|
+
return registeredSiteStyleBlockPolicies.find((policy) => policy.siteStyleId === input.siteStyleId && policy.blockKind === input.blockKind) ?? { kind: "open" };
|
|
22656
|
+
}
|
|
22657
|
+
function isLayoutVariantAllowedByPolicy(policy, layoutVariantKey) {
|
|
22658
|
+
switch (policy.kind) {
|
|
22659
|
+
case "open": return true;
|
|
22660
|
+
case "locked-look-and-layouts": return policy.allowedLayoutVariantKeys.includes(layoutVariantKey);
|
|
22661
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21938
22662
|
}
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
21942
|
-
|
|
21943
|
-
|
|
21944
|
-
|
|
21945
|
-
case "advanced-detached": return {
|
|
21946
|
-
kind: "advanced-detached",
|
|
21947
|
-
fields,
|
|
21948
|
-
authority: input.authority
|
|
21949
|
-
};
|
|
21950
|
-
case "legacy-raw": return {
|
|
21951
|
-
kind: "unsupported-manual-review",
|
|
21952
|
-
fields,
|
|
21953
|
-
authority: input.authority
|
|
21954
|
-
};
|
|
21955
|
-
default: return assertNever$1(input.authority);
|
|
22663
|
+
}
|
|
22664
|
+
function normalizeLayoutVariantForPolicy(policy, layoutVariantKey) {
|
|
22665
|
+
switch (policy.kind) {
|
|
22666
|
+
case "open": return layoutVariantKey ?? null;
|
|
22667
|
+
case "locked-look-and-layouts": return layoutVariantKey && isLayoutVariantAllowedByPolicy(policy, layoutVariantKey) ? layoutVariantKey : policy.defaultLayoutVariantKey;
|
|
22668
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21956
22669
|
}
|
|
21957
22670
|
}
|
|
21958
|
-
function
|
|
21959
|
-
|
|
22671
|
+
function filterLayoutProfilesForPolicy(policy, layoutProfiles) {
|
|
22672
|
+
switch (policy.kind) {
|
|
22673
|
+
case "open": return layoutProfiles;
|
|
22674
|
+
case "locked-look-and-layouts": return layoutProfiles.filter((profile) => isLayoutVariantAllowedByPolicy(policy, profile.variantKey));
|
|
22675
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22676
|
+
}
|
|
21960
22677
|
}
|
|
21961
|
-
function
|
|
21962
|
-
|
|
21963
|
-
|
|
22678
|
+
function isLookAllowedByPolicy(policy, lookId) {
|
|
22679
|
+
switch (policy.kind) {
|
|
22680
|
+
case "open": return true;
|
|
22681
|
+
case "locked-look-and-layouts": return lookId === policy.lookId;
|
|
22682
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21964
22683
|
}
|
|
21965
|
-
|
|
21966
|
-
|
|
21967
|
-
|
|
21968
|
-
|
|
22684
|
+
}
|
|
22685
|
+
function filterLookIdsForPolicy(policy, looks) {
|
|
22686
|
+
switch (policy.kind) {
|
|
22687
|
+
case "open": return looks;
|
|
22688
|
+
case "locked-look-and-layouts": return looks.filter((look) => look.id === policy.lookId);
|
|
22689
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
21969
22690
|
}
|
|
21970
22691
|
}
|
|
21971
|
-
|
|
21972
|
-
* Replace every compiler-owned field on a block's content with a fresh compiled
|
|
21973
|
-
* set — the one primitive both writers of compiled output share.
|
|
21974
|
-
*
|
|
21975
|
-
* Replacement rather than merge is the whole point: a field the new
|
|
21976
|
-
* compilation does not produce must *go*, or a recompile onto a Look that asks
|
|
21977
|
-
* for no card leaves the old `_cardStyles` sitting there claiming a surface
|
|
21978
|
-
* nobody asked for. Every writer that discovers compiler ownership for itself
|
|
21979
|
-
* eventually forgets one of these names, so nobody does.
|
|
21980
|
-
*
|
|
21981
|
-
* Pure, and deliberately free of authority checks — those belong to the
|
|
21982
|
-
* persistence wrapper, not to the shape of the content.
|
|
21983
|
-
*/
|
|
21984
|
-
function withCompiledRuntimeStyleFields(input) {
|
|
21985
|
-
const authored = Object.fromEntries(Object.entries(input.content).filter(([fieldName]) => !themeV2CompilerOwnedFieldNames.includes(fieldName)));
|
|
22692
|
+
function requiredLookChoice(lookId) {
|
|
21986
22693
|
return {
|
|
21987
|
-
|
|
21988
|
-
|
|
22694
|
+
kind: "user-pinned",
|
|
22695
|
+
value: lookId
|
|
21989
22696
|
};
|
|
21990
22697
|
}
|
|
21991
22698
|
/**
|
|
21992
|
-
*
|
|
21993
|
-
*
|
|
21994
|
-
*
|
|
21995
|
-
*
|
|
22699
|
+
* Writes the look pins a locked-look site style requires.
|
|
22700
|
+
*
|
|
22701
|
+
* Boundary pins are never written: a site style's default break after a block
|
|
22702
|
+
* is resolved at read time by `resolveJoinTreatment`, so it shows as a default
|
|
22703
|
+
* and follows later changes to the style (issue 1422). Pins already stored,
|
|
22704
|
+
* including ones an earlier version wrote on the style's behalf, are left as
|
|
22705
|
+
* they are.
|
|
21996
22706
|
*/
|
|
21997
|
-
function
|
|
21998
|
-
|
|
21999
|
-
|
|
22000
|
-
|
|
22001
|
-
|
|
22002
|
-
|
|
22003
|
-
|
|
22707
|
+
function applySiteStyleBlockPoliciesToPageDesignIntent(intent, blocks) {
|
|
22708
|
+
const policyLookPins = blocks.flatMap((block) => {
|
|
22709
|
+
const policy = deriveSiteStyleBlockPolicy({
|
|
22710
|
+
siteStyleId: intent.siteStyleId,
|
|
22711
|
+
blockKind: block.blockKind
|
|
22712
|
+
});
|
|
22713
|
+
switch (policy.kind) {
|
|
22714
|
+
case "open": return [];
|
|
22715
|
+
case "locked-look-and-layouts": return [{
|
|
22716
|
+
blockId: block.blockId,
|
|
22717
|
+
blockKind: block.blockKind,
|
|
22718
|
+
choice: requiredLookChoice(policy.lookId)
|
|
22719
|
+
}];
|
|
22720
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22721
|
+
}
|
|
22722
|
+
});
|
|
22723
|
+
if (policyLookPins.length === 0) {
|
|
22724
|
+
return intent;
|
|
22004
22725
|
}
|
|
22726
|
+
const policyPinBlockIds = new Set(policyLookPins.map((pin) => pin.blockId));
|
|
22005
22727
|
return {
|
|
22006
|
-
|
|
22007
|
-
|
|
22728
|
+
...intent,
|
|
22729
|
+
blockLookPins: [...intent.blockLookPins.filter((pin) => !policyPinBlockIds.has(pin.blockId)), ...policyLookPins]
|
|
22008
22730
|
};
|
|
22009
22731
|
}
|
|
22010
|
-
function
|
|
22011
|
-
|
|
22732
|
+
function planBlockContentVariantPolicyUpdate(input) {
|
|
22733
|
+
switch (input.policy.kind) {
|
|
22734
|
+
case "open": return { kind: "unchanged" };
|
|
22735
|
+
case "locked-look-and-layouts": {
|
|
22736
|
+
const currentVariant = typeof input.content.variant === "string" ? asLayoutVariantKey(input.content.variant) : null;
|
|
22737
|
+
return currentVariant && isLayoutVariantAllowedByPolicy(input.policy, currentVariant) ? { kind: "unchanged" } : {
|
|
22738
|
+
kind: "set-variant",
|
|
22739
|
+
variantKey: input.policy.defaultLayoutVariantKey
|
|
22740
|
+
};
|
|
22741
|
+
}
|
|
22742
|
+
default: return assertNever$1(input.policy, "Unhandled site style block policy");
|
|
22743
|
+
}
|
|
22012
22744
|
}
|
|
22013
|
-
function
|
|
22014
|
-
const
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
|
|
22021
|
-
|
|
22022
|
-
|
|
22023
|
-
|
|
22024
|
-
|
|
22025
|
-
|
|
22026
|
-
|
|
22027
|
-
|
|
22028
|
-
|
|
22745
|
+
function applyBlockContentVariantPolicy(input) {
|
|
22746
|
+
const plan = planBlockContentVariantPolicyUpdate(input);
|
|
22747
|
+
switch (plan.kind) {
|
|
22748
|
+
case "unchanged": return input.content;
|
|
22749
|
+
case "set-variant": return {
|
|
22750
|
+
...input.content,
|
|
22751
|
+
variant: plan.variantKey
|
|
22752
|
+
};
|
|
22753
|
+
default: return assertNever$1(plan, "Unhandled block content variant policy plan");
|
|
22754
|
+
}
|
|
22755
|
+
}
|
|
22756
|
+
function auditPageDesignIntentPolicy(input) {
|
|
22757
|
+
return input.blocks.flatMap((block) => {
|
|
22758
|
+
const policy = deriveSiteStyleBlockPolicy({
|
|
22759
|
+
siteStyleId: input.intent.siteStyleId,
|
|
22760
|
+
blockKind: block.blockKind
|
|
22761
|
+
});
|
|
22762
|
+
switch (policy.kind) {
|
|
22763
|
+
case "open": return [];
|
|
22764
|
+
case "locked-look-and-layouts": {
|
|
22765
|
+
const choice = resolvePageDesignBlockLookChoice(input.intent, block.blockId);
|
|
22766
|
+
const lookIssue = choice.kind === "auto" ? {
|
|
22767
|
+
kind: "missing-required-look-pin",
|
|
22768
|
+
blockId: block.blockId,
|
|
22769
|
+
blockKind: block.blockKind,
|
|
22770
|
+
requiredLookId: policy.lookId
|
|
22771
|
+
} : choice.value === policy.lookId ? null : {
|
|
22772
|
+
kind: "unsupported-look-pin",
|
|
22773
|
+
blockId: block.blockId,
|
|
22774
|
+
blockKind: block.blockKind,
|
|
22775
|
+
actualLookId: choice.value,
|
|
22776
|
+
requiredLookId: policy.lookId
|
|
22777
|
+
};
|
|
22778
|
+
const layoutIssue = block.currentLayoutVariantKey && !isLayoutVariantAllowedByPolicy(policy, block.currentLayoutVariantKey) ? {
|
|
22779
|
+
kind: "unsupported-layout-variant",
|
|
22780
|
+
blockId: block.blockId,
|
|
22781
|
+
blockKind: block.blockKind,
|
|
22782
|
+
actualLayoutVariantKey: block.currentLayoutVariantKey,
|
|
22783
|
+
defaultLayoutVariantKey: policy.defaultLayoutVariantKey
|
|
22784
|
+
} : null;
|
|
22785
|
+
const issues = [];
|
|
22786
|
+
if (lookIssue) {
|
|
22787
|
+
issues.push(lookIssue);
|
|
22788
|
+
}
|
|
22789
|
+
if (layoutIssue) {
|
|
22790
|
+
issues.push(layoutIssue);
|
|
22791
|
+
}
|
|
22792
|
+
return issues;
|
|
22793
|
+
}
|
|
22794
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22795
|
+
}
|
|
22796
|
+
});
|
|
22797
|
+
}
|
|
22798
|
+
function auditPageDesignAuthorityPolicy(input) {
|
|
22799
|
+
if (input.intent) {
|
|
22800
|
+
return auditPageDesignIntentPolicy({
|
|
22801
|
+
intent: input.intent,
|
|
22802
|
+
blocks: input.blocks
|
|
22803
|
+
});
|
|
22804
|
+
}
|
|
22805
|
+
const policyBlockCount = input.blocks.filter((block) => deriveSiteStyleBlockPolicy({
|
|
22806
|
+
siteStyleId: input.siteStyleId,
|
|
22807
|
+
blockKind: block.blockKind
|
|
22808
|
+
}).kind !== "open").length;
|
|
22809
|
+
return policyBlockCount === 0 ? [] : [{
|
|
22810
|
+
kind: "missing-page-design-authority",
|
|
22811
|
+
siteStyleId: input.siteStyleId,
|
|
22812
|
+
policyBlockCount
|
|
22813
|
+
}];
|
|
22814
|
+
}
|
|
22815
|
+
function assertRegisteredSiteStyleBlockPoliciesAreValid() {
|
|
22816
|
+
registeredSiteStyleBlockPolicies.forEach((policy) => {
|
|
22817
|
+
if (!policy.allowedLayoutVariantKeys.includes(policy.defaultLayoutVariantKey)) {
|
|
22818
|
+
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} has a default layout outside its allowed layouts.`);
|
|
22819
|
+
}
|
|
22820
|
+
const preset = appearancePresets.find((candidate$1) => candidate$1.id === policy.lookId && blockAppearancePresetSupportsBlockKind(candidate$1, policy.blockKind));
|
|
22821
|
+
if (!preset) {
|
|
22822
|
+
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} references an unavailable Look ${policy.lookId}.`);
|
|
22029
22823
|
}
|
|
22824
|
+
});
|
|
22825
|
+
}
|
|
22826
|
+
function autoChoiceAllowedByPolicy(policy) {
|
|
22827
|
+
switch (policy.kind) {
|
|
22828
|
+
case "open": return autoDesignChoice();
|
|
22829
|
+
case "locked-look-and-layouts": return requiredLookChoice(policy.lookId);
|
|
22830
|
+
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
22030
22831
|
}
|
|
22832
|
+
}
|
|
22833
|
+
|
|
22834
|
+
//#endregion
|
|
22835
|
+
//#region ../theme-core/src/site-styles/joinTreatment.ts
|
|
22836
|
+
/** Narrows any join (a resolved intent included) to its public, intent-only form. */
|
|
22837
|
+
function toPageRuntimeJoin(join) {
|
|
22031
22838
|
return {
|
|
22032
|
-
|
|
22033
|
-
|
|
22034
|
-
|
|
22839
|
+
previousBlockId: join.previousBlockId,
|
|
22840
|
+
nextBlockId: join.nextBlockId,
|
|
22841
|
+
treatment: join.treatment
|
|
22035
22842
|
};
|
|
22036
22843
|
}
|
|
22037
|
-
|
|
22038
|
-
|
|
22039
|
-
|
|
22844
|
+
/**
|
|
22845
|
+
* The single rule set for which treatment a join gets. Candidates arrive in
|
|
22846
|
+
* priority order; the first supported one wins.
|
|
22847
|
+
*
|
|
22848
|
+
* - `none` ends the search and yields no join.
|
|
22849
|
+
* - An unsupported candidate (a legacy option id, or a structured treatment the
|
|
22850
|
+
* catalogue lacks) falls through to the next one. When it was the user's
|
|
22851
|
+
* pin, the pin is reported unsupported and the existing
|
|
22852
|
+
* `pinned-boundary-option-unavailable` issue is raised.
|
|
22853
|
+
*/
|
|
22854
|
+
function resolveJoinTreatment(input) {
|
|
22855
|
+
const boundaryId = makeBoundaryId(input.previousBlockId, input.nextBlockId);
|
|
22856
|
+
const selection = selectCandidate(input.candidates);
|
|
22857
|
+
const selectedOutcome = selection.kind === "selected" ? selection.outcome : { kind: "none" };
|
|
22858
|
+
const pin = pinStatus(input.candidates, selectedOutcome);
|
|
22859
|
+
const issues = pin.kind === "unsupported" ? [{
|
|
22860
|
+
kind: "pinned-boundary-option-unavailable",
|
|
22861
|
+
boundaryId,
|
|
22862
|
+
presetId: pin.optionId,
|
|
22863
|
+
feedback: "user-facing"
|
|
22864
|
+
}] : [];
|
|
22865
|
+
if (selection.kind === "exhausted") {
|
|
22040
22866
|
return {
|
|
22041
|
-
|
|
22042
|
-
|
|
22043
|
-
|
|
22044
|
-
|
|
22867
|
+
join: null,
|
|
22868
|
+
selectedSource: null,
|
|
22869
|
+
pin,
|
|
22870
|
+
issues
|
|
22045
22871
|
};
|
|
22046
22872
|
}
|
|
22047
|
-
if (
|
|
22873
|
+
if (selection.outcome.kind === "none") {
|
|
22048
22874
|
return {
|
|
22049
|
-
|
|
22050
|
-
|
|
22051
|
-
|
|
22052
|
-
|
|
22875
|
+
join: null,
|
|
22876
|
+
selectedSource: selection.candidate.source,
|
|
22877
|
+
pin,
|
|
22878
|
+
issues
|
|
22053
22879
|
};
|
|
22054
22880
|
}
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
|
|
22058
|
-
|
|
22059
|
-
|
|
22060
|
-
|
|
22061
|
-
|
|
22881
|
+
return {
|
|
22882
|
+
selectedSource: selection.candidate.source,
|
|
22883
|
+
join: {
|
|
22884
|
+
boundaryId,
|
|
22885
|
+
previousBlockId: input.previousBlockId,
|
|
22886
|
+
nextBlockId: input.nextBlockId,
|
|
22887
|
+
treatment: selection.outcome.treatment,
|
|
22888
|
+
source: selection.candidate.source
|
|
22889
|
+
},
|
|
22890
|
+
pin,
|
|
22891
|
+
issues
|
|
22892
|
+
};
|
|
22893
|
+
}
|
|
22894
|
+
function pinStatus(candidates, selectedOutcome) {
|
|
22895
|
+
const pinned = candidates.find((candidate$1) => candidate$1.source.kind === "user-pinned");
|
|
22896
|
+
if (!pinned) return { kind: "none" };
|
|
22897
|
+
const outcome = candidateOutcome(pinned.treatment);
|
|
22898
|
+
return outcome.kind === "unsupported" ? {
|
|
22899
|
+
kind: "unsupported",
|
|
22900
|
+
optionId: outcome.boundaryOptionId ?? fallbackOptionId(selectedOutcome)
|
|
22901
|
+
} : { kind: "supported" };
|
|
22902
|
+
}
|
|
22903
|
+
function selectCandidate(candidates) {
|
|
22904
|
+
for (const candidate$1 of candidates) {
|
|
22905
|
+
const outcome = candidateOutcome(candidate$1.treatment);
|
|
22906
|
+
switch (outcome.kind) {
|
|
22907
|
+
case "decorative":
|
|
22908
|
+
case "none": return {
|
|
22909
|
+
kind: "selected",
|
|
22910
|
+
candidate: candidate$1,
|
|
22911
|
+
outcome
|
|
22912
|
+
};
|
|
22913
|
+
case "unsupported": continue;
|
|
22914
|
+
default: return assertNever$1(outcome, "Unhandled join candidate outcome");
|
|
22915
|
+
}
|
|
22062
22916
|
}
|
|
22063
|
-
|
|
22064
|
-
|
|
22065
|
-
|
|
22066
|
-
|
|
22067
|
-
|
|
22068
|
-
|
|
22069
|
-
|
|
22917
|
+
return { kind: "exhausted" };
|
|
22918
|
+
}
|
|
22919
|
+
function candidateOutcome(treatment) {
|
|
22920
|
+
if (treatment.kind === "none") return { kind: "none" };
|
|
22921
|
+
const intent = transitionIntentForTreatment(treatment);
|
|
22922
|
+
return intent ? {
|
|
22923
|
+
kind: "decorative",
|
|
22924
|
+
treatment: intent
|
|
22925
|
+
} : {
|
|
22926
|
+
kind: "unsupported",
|
|
22927
|
+
boundaryOptionId: boundaryOptionIdForTreatment(treatment)
|
|
22928
|
+
};
|
|
22929
|
+
}
|
|
22930
|
+
/**
|
|
22931
|
+
* Matches the editor's existing issue payload: the pin's own option id when
|
|
22932
|
+
* it has one, otherwise the option the join fell back to.
|
|
22933
|
+
*/
|
|
22934
|
+
function fallbackOptionId(outcome) {
|
|
22935
|
+
switch (outcome.kind) {
|
|
22936
|
+
case "decorative": return boundaryOptionForTransitionIntent(outcome.treatment).id;
|
|
22937
|
+
case "none": return noneBoundaryOption.id;
|
|
22938
|
+
default: return assertNever$1(outcome, "Unhandled join fallback outcome");
|
|
22070
22939
|
}
|
|
22940
|
+
}
|
|
22941
|
+
/**
|
|
22942
|
+
* The page-design defaults for a join, in priority order: the site style's
|
|
22943
|
+
* default break after the previous block, then the page-flow default, which
|
|
22944
|
+
* is always last.
|
|
22945
|
+
*/
|
|
22946
|
+
function pageDesignDefaultJoinCandidates(input) {
|
|
22947
|
+
const policy = deriveSiteStyleBlockPolicy({
|
|
22948
|
+
siteStyleId: input.siteStyleId,
|
|
22949
|
+
blockKind: input.previousBlockKind
|
|
22950
|
+
});
|
|
22951
|
+
const siteStyleDefault = policy.kind === "locked-look-and-layouts" && policy.defaultBoundaryAfter ? [{
|
|
22952
|
+
source: {
|
|
22953
|
+
kind: "site-style-default",
|
|
22954
|
+
siteStyleId: input.siteStyleId
|
|
22955
|
+
},
|
|
22956
|
+
treatment: boundaryTreatmentForBoundaryOptionId(policy.defaultBoundaryAfter.optionId)
|
|
22957
|
+
}] : [];
|
|
22958
|
+
return [...siteStyleDefault, pageFlowDefaultJoinCandidate(input.pageFlowPresetId)];
|
|
22959
|
+
}
|
|
22960
|
+
/** The last-resort page-design default, also the source of a fully unsupported join. */
|
|
22961
|
+
function pageFlowDefaultJoinCandidate(pageFlowPresetId) {
|
|
22962
|
+
const pageFlow = pageFlowDefaultBoundary(pageFlowPresetId);
|
|
22071
22963
|
return {
|
|
22072
|
-
|
|
22073
|
-
|
|
22074
|
-
|
|
22075
|
-
|
|
22964
|
+
source: {
|
|
22965
|
+
kind: "page-flow-default",
|
|
22966
|
+
pageFlowPresetId: pageFlow.preset?.id ?? null
|
|
22967
|
+
},
|
|
22968
|
+
treatment: boundaryTreatmentForBoundaryOptionId(pageFlow.boundaryOptionId)
|
|
22076
22969
|
};
|
|
22077
22970
|
}
|
|
22971
|
+
/**
|
|
22972
|
+
* Page-design source adapter. Priority: the user's pin, then the defaults.
|
|
22973
|
+
* The pin is offered even when unsupported so the rule function can report it.
|
|
22974
|
+
*/
|
|
22975
|
+
function joinCandidatesFromPageDesign(intent, siteStyleId, previous, next) {
|
|
22976
|
+
const choice = resolvePageDesignBoundaryChoice(intent, previous.blockId, next.blockId);
|
|
22977
|
+
return [...choice.kind === "user-pinned" ? [{
|
|
22978
|
+
source: { kind: "user-pinned" },
|
|
22979
|
+
treatment: choice.value
|
|
22980
|
+
}] : [], ...pageDesignDefaultJoinCandidates({
|
|
22981
|
+
siteStyleId,
|
|
22982
|
+
pageFlowPresetId: intent.pageFlowPresetId,
|
|
22983
|
+
previousBlockKind: previous.blockKind
|
|
22984
|
+
})];
|
|
22985
|
+
}
|
|
22986
|
+
/**
|
|
22987
|
+
* Generated-design source adapter. Mirrors today's materialisation: the
|
|
22988
|
+
* boundary intent's explicit choice, then the block design's explicit choice,
|
|
22989
|
+
* then the automatic default of no break.
|
|
22990
|
+
*/
|
|
22991
|
+
function joinCandidatesFromGeneratedIntent(block) {
|
|
22992
|
+
return [
|
|
22993
|
+
...explicitGeneratedCandidate(block.boundaryIntent.transitionAfter, "boundary-intent"),
|
|
22994
|
+
...explicitGeneratedCandidate(block.design.transitionAfter, "block-design"),
|
|
22995
|
+
{
|
|
22996
|
+
source: {
|
|
22997
|
+
kind: "generated",
|
|
22998
|
+
origin: "automatic"
|
|
22999
|
+
},
|
|
23000
|
+
treatment: { kind: "none" }
|
|
23001
|
+
}
|
|
23002
|
+
];
|
|
23003
|
+
}
|
|
23004
|
+
function explicitGeneratedCandidate(choice, origin) {
|
|
23005
|
+
return choice.kind === "explicit" ? [{
|
|
23006
|
+
source: {
|
|
23007
|
+
kind: "generated",
|
|
23008
|
+
origin
|
|
23009
|
+
},
|
|
23010
|
+
treatment: treatmentForTransitionIntent(choice.value)
|
|
23011
|
+
}] : [];
|
|
23012
|
+
}
|
|
23013
|
+
function treatmentForTransitionIntent(transition) {
|
|
23014
|
+
return transition === "none" ? { kind: "none" } : transitionCatalogueEntryForIntent(transition).treatment;
|
|
23015
|
+
}
|
|
22078
23016
|
|
|
22079
23017
|
//#endregion
|
|
22080
23018
|
//#region ../theme-core/src/site-styles/imageSurfaceBackground.ts
|
|
@@ -22188,13 +23126,15 @@ const compiledRuntimeStyleFieldNames = [
|
|
|
22188
23126
|
"_contentCardStyles",
|
|
22189
23127
|
"_heroLayoutStyles",
|
|
22190
23128
|
"_cardStyles",
|
|
22191
|
-
"_transitionStyles",
|
|
22192
23129
|
"blockLook",
|
|
22193
|
-
"blockComposition"
|
|
22194
|
-
"styleGroup"
|
|
23130
|
+
"blockComposition"
|
|
22195
23131
|
];
|
|
23132
|
+
/**
|
|
23133
|
+
* Removes every compiler-owned field, plus a stale transition `styleGroup`.
|
|
23134
|
+
* An authored `styleGroup` is content and survives.
|
|
23135
|
+
*/
|
|
22196
23136
|
function stripCompiledRuntimeStyleFields(content) {
|
|
22197
|
-
return Object.fromEntries(Object.entries(content).filter(([fieldName]) => !compiledRuntimeStyleFieldNames.includes(fieldName)));
|
|
23137
|
+
return Object.fromEntries(Object.entries(stripStaleTransitionStyleGroup(content)).filter(([fieldName]) => !compiledRuntimeStyleFieldNames.includes(fieldName)));
|
|
22198
23138
|
}
|
|
22199
23139
|
function surfaceResolutionContextFromPalette(palette) {
|
|
22200
23140
|
return {
|
|
@@ -22213,7 +23153,7 @@ function defineComponentRuntimeRules(rules) {
|
|
|
22213
23153
|
}
|
|
22214
23154
|
/**
|
|
22215
23155
|
* Default design rules translate semantic page-level choices into the current
|
|
22216
|
-
* runtime's section background
|
|
23156
|
+
* runtime's section background vocabulary.
|
|
22217
23157
|
*/
|
|
22218
23158
|
const defaultDesignRuntimeRules = defineDesignRuntimeRules({
|
|
22219
23159
|
sectionSurfaces: {
|
|
@@ -22248,8 +23188,7 @@ const defaultDesignRuntimeRules = defineDesignRuntimeRules({
|
|
|
22248
23188
|
color: "surface",
|
|
22249
23189
|
opacity: .88
|
|
22250
23190
|
}
|
|
22251
|
-
}
|
|
22252
|
-
transitionClassName: (transition, fromSurface, toSurface) => transition === "none" ? null : `site-style-transition-${transition}-from-${fromSurface}-to-${toSurface}`
|
|
23191
|
+
}
|
|
22253
23192
|
});
|
|
22254
23193
|
/**
|
|
22255
23194
|
* Default component rules translate frame and item-surface semantics into the
|
|
@@ -22475,26 +23414,6 @@ function compileCardStyles(input) {
|
|
|
22475
23414
|
if (!role) return undefined;
|
|
22476
23415
|
return cardStylesOverrideSchema.parse({ role });
|
|
22477
23416
|
}
|
|
22478
|
-
function sectionAdjacencyForBlock(input) {
|
|
22479
|
-
if (input.sectionAdjacency) {
|
|
22480
|
-
return input.sectionAdjacency;
|
|
22481
|
-
}
|
|
22482
|
-
if (input.nextSectionSurface) {
|
|
22483
|
-
return {
|
|
22484
|
-
kind: "next-section",
|
|
22485
|
-
surface: input.nextSectionSurface
|
|
22486
|
-
};
|
|
22487
|
-
}
|
|
22488
|
-
return { kind: "page-end" };
|
|
22489
|
-
}
|
|
22490
|
-
function transitionTargetSurfaceForAdjacency(adjacency) {
|
|
22491
|
-
switch (adjacency.kind) {
|
|
22492
|
-
case "next-section":
|
|
22493
|
-
case "terminal-surface": return adjacency.surface;
|
|
22494
|
-
case "page-end": return null;
|
|
22495
|
-
default: return assertNever$1(adjacency);
|
|
22496
|
-
}
|
|
22497
|
-
}
|
|
22498
23417
|
function resolveEyebrowTreatmentForRuntime(block, rules) {
|
|
22499
23418
|
return block.eyebrowTreatment ?? rules.defaultEyebrowTreatment ?? block.appliedEyebrowTreatment;
|
|
22500
23419
|
}
|
|
@@ -22512,19 +23431,6 @@ function compileBlockRuntimeFields(input) {
|
|
|
22512
23431
|
});
|
|
22513
23432
|
const shouldSuppressContainerFrame = shouldMoveFrameToHeroContentCard(input.block);
|
|
22514
23433
|
const cardStyles = compileCardStyles({ cardRole: input.block.appliedCardRole });
|
|
22515
|
-
const transitionTargetSurface = transitionTargetSurfaceForAdjacency(sectionAdjacencyForBlock(input));
|
|
22516
|
-
const transitionClassName = transitionTargetSurface ? designRules.transitionClassName(input.block.appliedTransitionAfter, visualSectionSurface, transitionTargetSurface) : null;
|
|
22517
|
-
const transitionRuntime = transitionTargetSurface && transitionClassName ? compileTransitionRuntime({
|
|
22518
|
-
treatment: input.block.appliedTransitionAfter,
|
|
22519
|
-
from: {
|
|
22520
|
-
kind: "surface",
|
|
22521
|
-
surface: visualSectionSurface
|
|
22522
|
-
},
|
|
22523
|
-
to: {
|
|
22524
|
-
kind: "surface",
|
|
22525
|
-
surface: transitionTargetSurface
|
|
22526
|
-
}
|
|
22527
|
-
}) : null;
|
|
22528
23434
|
return {
|
|
22529
23435
|
blockId: input.block.blockId,
|
|
22530
23436
|
visualSectionSurface,
|
|
@@ -22549,72 +23455,10 @@ function compileBlockRuntimeFields(input) {
|
|
|
22549
23455
|
...cardStyles ? { _cardStyles: cardStyles } : {},
|
|
22550
23456
|
...heroRuntimeFields,
|
|
22551
23457
|
...input.block.appearancePresetId ? { blockLook: input.block.appearancePresetId } : {},
|
|
22552
|
-
...input.block.appliedComposition ? { blockComposition: input.block.appliedComposition } : {}
|
|
22553
|
-
...transitionRuntime ? { _transitionStyles: transitionRuntime } : {},
|
|
22554
|
-
...transitionClassName ? { styleGroup: transitionClassName } : {}
|
|
22555
|
-
}
|
|
22556
|
-
};
|
|
22557
|
-
}
|
|
22558
|
-
function compileTransitionRuntime(input) {
|
|
22559
|
-
return {
|
|
22560
|
-
treatment: input.treatment,
|
|
22561
|
-
from: input.from,
|
|
22562
|
-
to: input.to,
|
|
22563
|
-
cssVars: {
|
|
22564
|
-
from: input.from.kind === "surface" && input.from.surface === "hero-image" ? "transparent" : transitionEndpointCssValue(input.from),
|
|
22565
|
-
to: transitionEndpointCssValue(input.to)
|
|
22566
|
-
}
|
|
22567
|
-
};
|
|
22568
|
-
}
|
|
22569
|
-
function compileBoundaryRuntime(input) {
|
|
22570
|
-
const rules = input.rules ?? defaultDesignRuntimeRules;
|
|
22571
|
-
const styleGroup = rules.transitionClassName(input.treatment, input.fromSurface, input.toSurface);
|
|
22572
|
-
if (!styleGroup) return null;
|
|
22573
|
-
const metrics = boundaryRuntimeMetricsForTransition(input.treatment);
|
|
22574
|
-
if (!metrics) return null;
|
|
22575
|
-
const transition = compileTransitionRuntime({
|
|
22576
|
-
treatment: input.treatment,
|
|
22577
|
-
from: {
|
|
22578
|
-
kind: "surface",
|
|
22579
|
-
surface: input.fromSurface
|
|
22580
|
-
},
|
|
22581
|
-
to: {
|
|
22582
|
-
kind: "surface",
|
|
22583
|
-
surface: input.toSurface
|
|
23458
|
+
...input.block.appliedComposition ? { blockComposition: input.block.appliedComposition } : {}
|
|
22584
23459
|
}
|
|
22585
|
-
});
|
|
22586
|
-
return {
|
|
22587
|
-
boundaryId: input.boundaryId,
|
|
22588
|
-
previousBlockId: input.previousBlockId,
|
|
22589
|
-
nextBlockId: input.nextBlockId,
|
|
22590
|
-
treatment: transition.treatment,
|
|
22591
|
-
metrics,
|
|
22592
|
-
from: transition.from,
|
|
22593
|
-
to: transition.to,
|
|
22594
|
-
cssVars: transition.cssVars,
|
|
22595
|
-
styleGroup
|
|
22596
23460
|
};
|
|
22597
23461
|
}
|
|
22598
|
-
function transitionEndpointCssValue(endpoint) {
|
|
22599
|
-
switch (endpoint.kind) {
|
|
22600
|
-
case "color-token": return themeColorTokenCssValue(endpoint.token);
|
|
22601
|
-
case "surface": return themeColorTokenCssValue(tokenForTransitionSurface(endpoint.surface));
|
|
22602
|
-
default: return assertNever$1(endpoint);
|
|
22603
|
-
}
|
|
22604
|
-
}
|
|
22605
|
-
function tokenForTransitionSurface(surface$1) {
|
|
22606
|
-
switch (surface$1) {
|
|
22607
|
-
case "base":
|
|
22608
|
-
case "hero-image": return "background";
|
|
22609
|
-
case "muted-band": return "muted";
|
|
22610
|
-
case "accent-band": return "accent";
|
|
22611
|
-
case "brand-depth-band": return "primary-800";
|
|
22612
|
-
default: return assertNever$1(surface$1);
|
|
22613
|
-
}
|
|
22614
|
-
}
|
|
22615
|
-
function themeColorTokenCssValue(token) {
|
|
22616
|
-
return `rgb(var(--tb-${token}))`;
|
|
22617
|
-
}
|
|
22618
23462
|
/**
|
|
22619
23463
|
* Compiles block runtime fields and writes them into content only when Theme V2
|
|
22620
23464
|
* owns that block's runtime-style fields.
|
|
@@ -22627,58 +23471,30 @@ function compileBlockRuntimeFieldsIntoContent(input) {
|
|
|
22627
23471
|
authority: input.authority
|
|
22628
23472
|
});
|
|
22629
23473
|
}
|
|
22630
|
-
/**
|
|
23474
|
+
/**
|
|
23475
|
+
* Compiles a resolved page plan into legacy runtime fields for each resolved
|
|
23476
|
+
* block, plus the public runtime joins between them.
|
|
23477
|
+
*
|
|
23478
|
+
* Joins come from `resolveJoinTreatment`; plans no longer carry a treatment.
|
|
23479
|
+
* Only joins whose two blocks were compiled are kept, and they leave as intent
|
|
23480
|
+
* only: the blocks renderer composes each one from final content after
|
|
23481
|
+
* omission, including whether it draws at all (issue 1422).
|
|
23482
|
+
*/
|
|
22631
23483
|
function compilePageRuntimeFields(input) {
|
|
22632
|
-
const
|
|
22633
|
-
|
|
22634
|
-
|
|
22635
|
-
|
|
22636
|
-
|
|
22637
|
-
|
|
22638
|
-
|
|
22639
|
-
|
|
22640
|
-
|
|
22641
|
-
componentRules: input.componentRules,
|
|
22642
|
-
sectionSpacing: input.sectionSpacing,
|
|
22643
|
-
sectionAdjacency: nextSurface ? {
|
|
22644
|
-
kind: "next-section",
|
|
22645
|
-
surface: nextSurface
|
|
22646
|
-
} : terminalSectionAdjacency
|
|
22647
|
-
});
|
|
22648
|
-
return {
|
|
22649
|
-
...compiled,
|
|
22650
|
-
fields: stripPageLevelTransitionFields(compiled.fields)
|
|
22651
|
-
};
|
|
22652
|
-
});
|
|
22653
|
-
const boundaries = input.resolved.blocks.flatMap((block, index) => {
|
|
22654
|
-
const nextBlock = input.resolved.blocks[index + 1];
|
|
22655
|
-
const fromSurface = visualSurfaces[index];
|
|
22656
|
-
const toSurface = visualSurfaces[index + 1];
|
|
22657
|
-
if (!nextBlock || !fromSurface || !toSurface) {
|
|
22658
|
-
return [];
|
|
22659
|
-
}
|
|
22660
|
-
const boundary = compileBoundaryRuntime({
|
|
22661
|
-
boundaryId: `boundary:${block.blockId}:${nextBlock.blockId}`,
|
|
22662
|
-
previousBlockId: block.blockId,
|
|
22663
|
-
nextBlockId: nextBlock.blockId,
|
|
22664
|
-
treatment: block.appliedTransitionAfter,
|
|
22665
|
-
fromSurface,
|
|
22666
|
-
toSurface,
|
|
22667
|
-
rules: designRules
|
|
22668
|
-
});
|
|
22669
|
-
return boundary ? [boundary] : [];
|
|
22670
|
-
});
|
|
23484
|
+
const blocks = input.resolved.blocks.map((block) => compileBlockRuntimeFields({
|
|
23485
|
+
block,
|
|
23486
|
+
surfaceResolutionContext: input.surfaceResolutionContext,
|
|
23487
|
+
designRules: input.designRules,
|
|
23488
|
+
componentRules: input.componentRules,
|
|
23489
|
+
sectionSpacing: input.sectionSpacing
|
|
23490
|
+
}));
|
|
23491
|
+
const compiledIds = new Set(blocks.map((block) => block.blockId));
|
|
23492
|
+
const joins = input.joins.filter((join) => compiledIds.has(join.previousBlockId) && compiledIds.has(join.nextBlockId)).map(toPageRuntimeJoin);
|
|
22671
23493
|
return {
|
|
22672
23494
|
blocks,
|
|
22673
|
-
|
|
23495
|
+
joins
|
|
22674
23496
|
};
|
|
22675
23497
|
}
|
|
22676
|
-
function stripPageLevelTransitionFields(fields) {
|
|
22677
|
-
const { _transitionStyles, styleGroup, ...rest } = fields;
|
|
22678
|
-
void _transitionStyles;
|
|
22679
|
-
void styleGroup;
|
|
22680
|
-
return rest;
|
|
22681
|
-
}
|
|
22682
23498
|
const paletteByRecipe = {
|
|
22683
23499
|
"brand-led": [
|
|
22684
23500
|
{
|
|
@@ -24738,371 +25554,173 @@ const curatedSiteStylesById = new Map(curatedSiteStyles.map((style) => [style.id
|
|
|
24738
25554
|
* only to the compiler.
|
|
24739
25555
|
*/
|
|
24740
25556
|
function headerStyleRecipeForTheme(theme, styleId) {
|
|
24741
|
-
const siteStyle = theme?.siteStyleId ? getCuratedSiteStyle(theme.siteStyleId) : null;
|
|
24742
|
-
return resolveHeaderStyleRecipe(siteStyle, styleId);
|
|
24743
|
-
}
|
|
24744
|
-
function getCuratedSiteStyle(id) {
|
|
24745
|
-
return curatedSiteStylesById.get(id) ?? null;
|
|
24746
|
-
}
|
|
24747
|
-
function designRuntimeRulesForSiteStyle(siteStyle) {
|
|
24748
|
-
return siteStyle?.designRuntimeRules ?? defaultDesignRuntimeRules;
|
|
24749
|
-
}
|
|
24750
|
-
function designRuntimeRulesForTheme(theme) {
|
|
24751
|
-
const siteStyleId = theme?.siteStyleId;
|
|
24752
|
-
if (!siteStyleId) return defaultDesignRuntimeRules;
|
|
24753
|
-
return designRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24754
|
-
}
|
|
24755
|
-
function componentRuntimeRulesForSiteStyle(siteStyle) {
|
|
24756
|
-
return siteStyle?.componentRuntimeRules ?? defaultComponentRuntimeRules;
|
|
24757
|
-
}
|
|
24758
|
-
function componentRuntimeRulesForTheme(theme) {
|
|
24759
|
-
const siteStyleId = theme?.siteStyleId;
|
|
24760
|
-
if (!siteStyleId) return defaultComponentRuntimeRules;
|
|
24761
|
-
return componentRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24762
|
-
}
|
|
24763
|
-
function defaultBlockVariantForSiteStyle(siteStyle, blockKind) {
|
|
24764
|
-
return siteStyle.defaultBlockVariants?.[blockKind] ?? null;
|
|
24765
|
-
}
|
|
24766
|
-
|
|
24767
|
-
//#endregion
|
|
24768
|
-
//#region ../theme-core/src/site-styles/pageDesignEditorCapabilities.ts
|
|
24769
|
-
function cardRoleCapabilityOf(capability) {
|
|
24770
|
-
return capability?.kind === "designed" ? capability.cardRoles : "unsupported";
|
|
24771
|
-
}
|
|
24772
|
-
function backgroundSupportForCapability(capability) {
|
|
24773
|
-
if (capability === null) {
|
|
24774
|
-
return {
|
|
24775
|
-
kind: "unsupported",
|
|
24776
|
-
reason: "missing-design-capability"
|
|
24777
|
-
};
|
|
24778
|
-
}
|
|
24779
|
-
if (capability.kind === "not-designed") {
|
|
24780
|
-
return {
|
|
24781
|
-
kind: "unsupported",
|
|
24782
|
-
reason: capability.reason
|
|
24783
|
-
};
|
|
24784
|
-
}
|
|
24785
|
-
return capability.sectionSurfaces === "supported" ? {
|
|
24786
|
-
kind: "supported",
|
|
24787
|
-
richBackgrounds: capability.richBackgrounds ?? "unsupported"
|
|
24788
|
-
} : {
|
|
24789
|
-
kind: "unsupported",
|
|
24790
|
-
reason: "section-surfaces-unsupported"
|
|
24791
|
-
};
|
|
24792
|
-
}
|
|
24793
|
-
/**
|
|
24794
|
-
* The capability-derived half of a block's editor read model, in one call so
|
|
24795
|
-
* the read-model builder does not grow a projection per axis.
|
|
24796
|
-
*/
|
|
24797
|
-
function capabilitySupportFor(capability) {
|
|
24798
|
-
return {
|
|
24799
|
-
backgroundSupport: backgroundSupportForCapability(capability),
|
|
24800
|
-
cardRoles: cardRoleCapabilityOf(capability)
|
|
24801
|
-
};
|
|
24802
|
-
}
|
|
24803
|
-
|
|
24804
|
-
//#endregion
|
|
24805
|
-
//#region ../theme-core/src/site-styles/lookResolution.ts
|
|
24806
|
-
function blockAppearancePresetSupportsBlockKind(preset, blockKind) {
|
|
24807
|
-
return preset.blockKinds.some((candidate$1) => candidate$1 === blockKind);
|
|
24808
|
-
}
|
|
24809
|
-
function preferredAppearanceTargetForBlockKind(blockKind) {
|
|
24810
|
-
switch (blockKind) {
|
|
24811
|
-
case "block.event-calendar":
|
|
24812
|
-
case "block.event-listing": return "events";
|
|
24813
|
-
default: return null;
|
|
24814
|
-
}
|
|
24815
|
-
}
|
|
24816
|
-
function sortCompatibleBlockAppearancePresets(blockKind, options) {
|
|
24817
|
-
const preferredTarget = preferredAppearanceTargetForBlockKind(blockKind);
|
|
24818
|
-
if (!preferredTarget) {
|
|
24819
|
-
return options;
|
|
24820
|
-
}
|
|
24821
|
-
return [...options].sort((left, right) => {
|
|
24822
|
-
const leftPreset = appearancePresets.find((preset) => preset.id === left.id);
|
|
24823
|
-
const rightPreset = appearancePresets.find((preset) => preset.id === right.id);
|
|
24824
|
-
const leftPreferred = leftPreset?.target === preferredTarget;
|
|
24825
|
-
const rightPreferred = rightPreset?.target === preferredTarget;
|
|
24826
|
-
if (leftPreferred === rightPreferred) {
|
|
24827
|
-
return 0;
|
|
24828
|
-
}
|
|
24829
|
-
return leftPreferred ? -1 : 1;
|
|
24830
|
-
});
|
|
24831
|
-
}
|
|
24832
|
-
function blockAppearancePresetSupportsLayoutProfile(preset, profile, input = {}) {
|
|
24833
|
-
const constraints = preset.constraints;
|
|
24834
|
-
if (!constraints || !constraints.layoutFamilies && !constraints.layoutVariantKeys) {
|
|
24835
|
-
return true;
|
|
24836
|
-
}
|
|
24837
|
-
if (!profile) {
|
|
24838
|
-
return input.allowLayoutConstrainedPresetWithoutProfile ?? true;
|
|
24839
|
-
}
|
|
24840
|
-
return layoutProfileSupportsConstraints(profile, constraints);
|
|
24841
|
-
}
|
|
24842
|
-
function resolveBlockAppearancePreset(preset, layoutProfile = null) {
|
|
24843
|
-
return {
|
|
24844
|
-
id: asAppearancePresetId(preset.id),
|
|
24845
|
-
label: preset.label,
|
|
24846
|
-
design: resolveBlockAppearancePresetDesign(preset, layoutProfile)
|
|
24847
|
-
};
|
|
24848
|
-
}
|
|
24849
|
-
function getCompatibleBlockAppearancePresets(input) {
|
|
24850
|
-
const options = appearancePresets.flatMap((preset) => {
|
|
24851
|
-
if (!blockAppearancePresetSupportsBlockKind(preset, input.blockKind) || !blockAppearancePresetSupportsLayoutProfile(preset, input.layoutProfile ?? null, { allowLayoutConstrainedPresetWithoutProfile: input.allowLayoutConstrainedPresetWithoutProfile })) {
|
|
24852
|
-
return [];
|
|
24853
|
-
}
|
|
24854
|
-
return [resolveBlockAppearancePreset(preset, input.layoutProfile ?? null)];
|
|
24855
|
-
});
|
|
24856
|
-
const sortedOptions = sortCompatibleBlockAppearancePresets(input.blockKind, options);
|
|
24857
|
-
const recommendedIds = input.siteStyle?.recommendedAppearancePresetIds ?? [];
|
|
24858
|
-
if (recommendedIds.length === 0) {
|
|
24859
|
-
return sortedOptions;
|
|
24860
|
-
}
|
|
24861
|
-
const recommended = recommendedIds.flatMap((presetId) => sortedOptions.find((option) => option.id === presetId) ?? []);
|
|
24862
|
-
const alreadyIncludedIds = new Set(recommended.map((option) => option.id));
|
|
24863
|
-
return [...recommended, ...sortedOptions.filter((option) => !alreadyIncludedIds.has(option.id))];
|
|
25557
|
+
const siteStyle = theme?.siteStyleId ? getCuratedSiteStyle(theme.siteStyleId) : null;
|
|
25558
|
+
return resolveHeaderStyleRecipe(siteStyle, styleId);
|
|
24864
25559
|
}
|
|
24865
|
-
|
|
24866
|
-
|
|
24867
|
-
//#region ../theme-core/src/site-styles/siteStyleBlockPolicies.ts
|
|
24868
|
-
const defaultPolicyPageFlowPresetId = asPageFlowPresetId("generated-default");
|
|
24869
|
-
const southWestTwerkSchoolSiteStyleId = asSiteStyleId("site-style:south-west-twerk-school");
|
|
24870
|
-
const heroBrandScrimFixedFrameLookId = asAppearancePresetId("hero-brand-scrim-fixed-frame");
|
|
24871
|
-
const classicHeroLayoutVariantKey = asLayoutVariantKey("classic");
|
|
24872
|
-
const microHeroLayoutVariantKey = asLayoutVariantKey("micro");
|
|
24873
|
-
const waveBoundaryOptionId = asBoundaryOptionId("break:wave");
|
|
24874
|
-
const registeredSiteStyleBlockPolicies = [{
|
|
24875
|
-
siteStyleId: southWestTwerkSchoolSiteStyleId,
|
|
24876
|
-
kind: "locked-look-and-layouts",
|
|
24877
|
-
blockKind: "block.hero",
|
|
24878
|
-
lookId: heroBrandScrimFixedFrameLookId,
|
|
24879
|
-
allowedLayoutVariantKeys: [classicHeroLayoutVariantKey, microHeroLayoutVariantKey],
|
|
24880
|
-
defaultLayoutVariantKey: classicHeroLayoutVariantKey,
|
|
24881
|
-
defaultBoundaryAfter: {
|
|
24882
|
-
optionId: waveBoundaryOptionId,
|
|
24883
|
-
mode: "default-only"
|
|
24884
|
-
},
|
|
24885
|
-
customize: {
|
|
24886
|
-
hideDisallowedLooks: true,
|
|
24887
|
-
hideDisallowedLayouts: true
|
|
24888
|
-
}
|
|
24889
|
-
}];
|
|
24890
|
-
function siteStyleBlockPolicies() {
|
|
24891
|
-
return registeredSiteStyleBlockPolicies;
|
|
25560
|
+
function getCuratedSiteStyle(id) {
|
|
25561
|
+
return curatedSiteStylesById.get(id) ?? null;
|
|
24892
25562
|
}
|
|
24893
|
-
function
|
|
24894
|
-
return
|
|
24895
|
-
schemaVersion: pageDesignIntentSchemaVersion,
|
|
24896
|
-
siteStyleId,
|
|
24897
|
-
pageFlowPresetId: defaultPolicyPageFlowPresetId,
|
|
24898
|
-
blockLookPins: [],
|
|
24899
|
-
boundaryPins: []
|
|
24900
|
-
};
|
|
25563
|
+
function designRuntimeRulesForSiteStyle(siteStyle) {
|
|
25564
|
+
return siteStyle?.designRuntimeRules ?? defaultDesignRuntimeRules;
|
|
24901
25565
|
}
|
|
24902
|
-
function
|
|
24903
|
-
|
|
24904
|
-
|
|
24905
|
-
|
|
24906
|
-
}).kind !== "open");
|
|
25566
|
+
function designRuntimeRulesForTheme(theme) {
|
|
25567
|
+
const siteStyleId = theme?.siteStyleId;
|
|
25568
|
+
if (!siteStyleId) return defaultDesignRuntimeRules;
|
|
25569
|
+
return designRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24907
25570
|
}
|
|
24908
|
-
function
|
|
24909
|
-
return
|
|
25571
|
+
function componentRuntimeRulesForSiteStyle(siteStyle) {
|
|
25572
|
+
return siteStyle?.componentRuntimeRules ?? defaultComponentRuntimeRules;
|
|
24910
25573
|
}
|
|
24911
|
-
function
|
|
24912
|
-
|
|
24913
|
-
|
|
24914
|
-
|
|
24915
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
24916
|
-
}
|
|
25574
|
+
function componentRuntimeRulesForTheme(theme) {
|
|
25575
|
+
const siteStyleId = theme?.siteStyleId;
|
|
25576
|
+
if (!siteStyleId) return defaultComponentRuntimeRules;
|
|
25577
|
+
return componentRuntimeRulesForSiteStyle(curatedSiteStylesById.get(asSiteStyleId(siteStyleId)) ?? null);
|
|
24917
25578
|
}
|
|
24918
|
-
function
|
|
24919
|
-
|
|
24920
|
-
case "open": return layoutVariantKey ?? null;
|
|
24921
|
-
case "locked-look-and-layouts": return layoutVariantKey && isLayoutVariantAllowedByPolicy(policy, layoutVariantKey) ? layoutVariantKey : policy.defaultLayoutVariantKey;
|
|
24922
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
24923
|
-
}
|
|
25579
|
+
function defaultBlockVariantForSiteStyle(siteStyle, blockKind) {
|
|
25580
|
+
return siteStyle.defaultBlockVariants?.[blockKind] ?? null;
|
|
24924
25581
|
}
|
|
24925
|
-
|
|
24926
|
-
|
|
24927
|
-
|
|
24928
|
-
|
|
24929
|
-
|
|
24930
|
-
}
|
|
25582
|
+
|
|
25583
|
+
//#endregion
|
|
25584
|
+
//#region ../theme-core/src/site-styles/pageDesignEditorCapabilities.ts
|
|
25585
|
+
function cardRoleCapabilityOf(capability) {
|
|
25586
|
+
return capability?.kind === "designed" ? capability.cardRoles : "unsupported";
|
|
24931
25587
|
}
|
|
24932
|
-
function
|
|
24933
|
-
|
|
24934
|
-
|
|
24935
|
-
|
|
24936
|
-
|
|
25588
|
+
function backgroundSupportForCapability(capability) {
|
|
25589
|
+
if (capability === null) {
|
|
25590
|
+
return {
|
|
25591
|
+
kind: "unsupported",
|
|
25592
|
+
reason: "missing-design-capability"
|
|
25593
|
+
};
|
|
24937
25594
|
}
|
|
24938
|
-
|
|
24939
|
-
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
24943
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
25595
|
+
if (capability.kind === "not-designed") {
|
|
25596
|
+
return {
|
|
25597
|
+
kind: "unsupported",
|
|
25598
|
+
reason: capability.reason
|
|
25599
|
+
};
|
|
24944
25600
|
}
|
|
24945
|
-
|
|
24946
|
-
|
|
24947
|
-
|
|
24948
|
-
|
|
24949
|
-
|
|
25601
|
+
return capability.sectionSurfaces === "supported" ? {
|
|
25602
|
+
kind: "supported",
|
|
25603
|
+
richBackgrounds: capability.richBackgrounds ?? "unsupported"
|
|
25604
|
+
} : {
|
|
25605
|
+
kind: "unsupported",
|
|
25606
|
+
reason: "section-surfaces-unsupported"
|
|
24950
25607
|
};
|
|
24951
25608
|
}
|
|
24952
|
-
|
|
25609
|
+
/**
|
|
25610
|
+
* The capability-derived half of a block's editor read model, in one call so
|
|
25611
|
+
* the read-model builder does not grow a projection per axis.
|
|
25612
|
+
*/
|
|
25613
|
+
function capabilitySupportFor(capability) {
|
|
24953
25614
|
return {
|
|
24954
|
-
|
|
24955
|
-
|
|
25615
|
+
backgroundSupport: backgroundSupportForCapability(capability),
|
|
25616
|
+
cardRoles: cardRoleCapabilityOf(capability)
|
|
24956
25617
|
};
|
|
24957
25618
|
}
|
|
24958
|
-
|
|
24959
|
-
|
|
24960
|
-
|
|
24961
|
-
|
|
24962
|
-
|
|
24963
|
-
|
|
24964
|
-
|
|
24965
|
-
|
|
24966
|
-
|
|
24967
|
-
|
|
24968
|
-
|
|
24969
|
-
|
|
24970
|
-
|
|
24971
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
24972
|
-
}
|
|
25619
|
+
|
|
25620
|
+
//#endregion
|
|
25621
|
+
//#region ../theme-core/src/site-styles/pageDesignEditorBoundaries.ts
|
|
25622
|
+
function buildBoundaryReadModels(input) {
|
|
25623
|
+
return input.blocks.flatMap((previousBlock, index) => {
|
|
25624
|
+
const nextBlock = input.blocks[index + 1];
|
|
25625
|
+
return nextBlock ? [buildBoundaryReadModel({
|
|
25626
|
+
siteStyleId: input.siteStyleId,
|
|
25627
|
+
pageFlowPresetId: input.intent.pageFlowPresetId,
|
|
25628
|
+
pin: resolvePageDesignBoundaryChoice(input.intent, previousBlock.blockId, nextBlock.blockId),
|
|
25629
|
+
previousBlock,
|
|
25630
|
+
nextBlock
|
|
25631
|
+
})] : [];
|
|
24973
25632
|
});
|
|
24974
|
-
|
|
24975
|
-
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
24980
|
-
|
|
24981
|
-
|
|
24982
|
-
});
|
|
24983
|
-
switch (policy.kind) {
|
|
24984
|
-
case "open": return [];
|
|
24985
|
-
case "locked-look-and-layouts": {
|
|
24986
|
-
const defaultBoundary = policy.defaultBoundaryAfter;
|
|
24987
|
-
if (!defaultBoundary) {
|
|
24988
|
-
return [];
|
|
24989
|
-
}
|
|
24990
|
-
const currentChoice = resolvePageDesignBoundaryChoice(intent, block.blockId, nextBlock.blockId);
|
|
24991
|
-
return currentChoice.kind === "auto" ? [buildBoundaryPin(block.blockId, nextBlock.blockId, requiredBoundaryChoice(defaultBoundary.optionId))] : [];
|
|
24992
|
-
}
|
|
24993
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
24994
|
-
}
|
|
25633
|
+
}
|
|
25634
|
+
function buildBoundaryReadModel(input) {
|
|
25635
|
+
const previousBlockId = input.previousBlock.blockId;
|
|
25636
|
+
const nextBlockId = input.nextBlock.blockId;
|
|
25637
|
+
const defaults = pageDesignDefaultJoinCandidates({
|
|
25638
|
+
siteStyleId: input.siteStyleId,
|
|
25639
|
+
pageFlowPresetId: input.pageFlowPresetId,
|
|
25640
|
+
previousBlockKind: input.previousBlock.blockKind
|
|
24995
25641
|
});
|
|
24996
|
-
|
|
24997
|
-
|
|
24998
|
-
|
|
24999
|
-
|
|
25642
|
+
const projection = input.pin.kind === "user-pinned" ? pinnedBreakChoice(resolveJoinTreatment({
|
|
25643
|
+
candidates: [{
|
|
25644
|
+
source: { kind: "user-pinned" },
|
|
25645
|
+
treatment: input.pin.value
|
|
25646
|
+
}, ...defaults],
|
|
25647
|
+
previousBlockId,
|
|
25648
|
+
nextBlockId
|
|
25649
|
+
})) : autoBreakChoice(resolveJoinTreatment({
|
|
25650
|
+
candidates: defaults,
|
|
25651
|
+
previousBlockId,
|
|
25652
|
+
nextBlockId
|
|
25653
|
+
}), input.pageFlowPresetId);
|
|
25000
25654
|
return {
|
|
25001
|
-
|
|
25002
|
-
|
|
25003
|
-
|
|
25655
|
+
boundary: {
|
|
25656
|
+
boundaryId: makeBoundaryId(previousBlockId, nextBlockId),
|
|
25657
|
+
previousBlockId,
|
|
25658
|
+
nextBlockId,
|
|
25659
|
+
breakChoice: projection.breakChoice,
|
|
25660
|
+
availableBreaks: boundaryOptions
|
|
25661
|
+
},
|
|
25662
|
+
issues: projection.issues
|
|
25004
25663
|
};
|
|
25005
25664
|
}
|
|
25006
|
-
function
|
|
25007
|
-
|
|
25008
|
-
|
|
25009
|
-
|
|
25010
|
-
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
|
|
25014
|
-
|
|
25015
|
-
}
|
|
25016
|
-
default: return assertNever$1(input.policy, "Unhandled site style block policy");
|
|
25017
|
-
}
|
|
25018
|
-
}
|
|
25019
|
-
function applyBlockContentVariantPolicy(input) {
|
|
25020
|
-
const plan = planBlockContentVariantPolicyUpdate(input);
|
|
25021
|
-
switch (plan.kind) {
|
|
25022
|
-
case "unchanged": return input.content;
|
|
25023
|
-
case "set-variant": return {
|
|
25024
|
-
...input.content,
|
|
25025
|
-
variant: plan.variantKey
|
|
25026
|
-
};
|
|
25027
|
-
default: return assertNever$1(plan, "Unhandled block content variant policy plan");
|
|
25028
|
-
}
|
|
25029
|
-
}
|
|
25030
|
-
function auditPageDesignIntentPolicy(input) {
|
|
25031
|
-
return input.blocks.flatMap((block) => {
|
|
25032
|
-
const policy = deriveSiteStyleBlockPolicy({
|
|
25033
|
-
siteStyleId: input.intent.siteStyleId,
|
|
25034
|
-
blockKind: block.blockKind
|
|
25035
|
-
});
|
|
25036
|
-
switch (policy.kind) {
|
|
25037
|
-
case "open": return [];
|
|
25038
|
-
case "locked-look-and-layouts": {
|
|
25039
|
-
const choice = resolvePageDesignBlockLookChoice(input.intent, block.blockId);
|
|
25040
|
-
const lookIssue = choice.kind === "auto" ? {
|
|
25041
|
-
kind: "missing-required-look-pin",
|
|
25042
|
-
blockId: block.blockId,
|
|
25043
|
-
blockKind: block.blockKind,
|
|
25044
|
-
requiredLookId: policy.lookId
|
|
25045
|
-
} : choice.value === policy.lookId ? null : {
|
|
25046
|
-
kind: "unsupported-look-pin",
|
|
25047
|
-
blockId: block.blockId,
|
|
25048
|
-
blockKind: block.blockKind,
|
|
25049
|
-
actualLookId: choice.value,
|
|
25050
|
-
requiredLookId: policy.lookId
|
|
25051
|
-
};
|
|
25052
|
-
const layoutIssue = block.currentLayoutVariantKey && !isLayoutVariantAllowedByPolicy(policy, block.currentLayoutVariantKey) ? {
|
|
25053
|
-
kind: "unsupported-layout-variant",
|
|
25054
|
-
blockId: block.blockId,
|
|
25055
|
-
blockKind: block.blockKind,
|
|
25056
|
-
actualLayoutVariantKey: block.currentLayoutVariantKey,
|
|
25057
|
-
defaultLayoutVariantKey: policy.defaultLayoutVariantKey
|
|
25058
|
-
} : null;
|
|
25059
|
-
const issues = [];
|
|
25060
|
-
if (lookIssue) {
|
|
25061
|
-
issues.push(lookIssue);
|
|
25062
|
-
}
|
|
25063
|
-
if (layoutIssue) {
|
|
25064
|
-
issues.push(layoutIssue);
|
|
25065
|
-
}
|
|
25066
|
-
return issues;
|
|
25067
|
-
}
|
|
25068
|
-
default: return assertNever$1(policy, "Unhandled site style block policy");
|
|
25069
|
-
}
|
|
25070
|
-
});
|
|
25071
|
-
}
|
|
25072
|
-
function auditPageDesignAuthorityPolicy(input) {
|
|
25073
|
-
if (input.intent) {
|
|
25074
|
-
return auditPageDesignIntentPolicy({
|
|
25075
|
-
intent: input.intent,
|
|
25076
|
-
blocks: input.blocks
|
|
25077
|
-
});
|
|
25078
|
-
}
|
|
25079
|
-
const policyBlockCount = input.blocks.filter((block) => deriveSiteStyleBlockPolicy({
|
|
25080
|
-
siteStyleId: input.siteStyleId,
|
|
25081
|
-
blockKind: block.blockKind
|
|
25082
|
-
}).kind !== "open").length;
|
|
25083
|
-
return policyBlockCount === 0 ? [] : [{
|
|
25084
|
-
kind: "missing-page-design-authority",
|
|
25085
|
-
siteStyleId: input.siteStyleId,
|
|
25086
|
-
policyBlockCount
|
|
25087
|
-
}];
|
|
25088
|
-
}
|
|
25089
|
-
function assertRegisteredSiteStyleBlockPoliciesAreValid() {
|
|
25090
|
-
registeredSiteStyleBlockPolicies.forEach((policy) => {
|
|
25091
|
-
if (!policy.allowedLayoutVariantKeys.includes(policy.defaultLayoutVariantKey)) {
|
|
25092
|
-
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} has a default layout outside its allowed layouts.`);
|
|
25093
|
-
}
|
|
25094
|
-
const preset = appearancePresets.find((candidate$1) => candidate$1.id === policy.lookId && blockAppearancePresetSupportsBlockKind(candidate$1, policy.blockKind));
|
|
25095
|
-
if (!preset) {
|
|
25096
|
-
throw new Error(`Site style block policy for ${policy.siteStyleId} ${policy.blockKind} references an unavailable Look ${policy.lookId}.`);
|
|
25097
|
-
}
|
|
25098
|
-
});
|
|
25665
|
+
function autoBreakChoice(resolution, pageFlowPresetId) {
|
|
25666
|
+
return {
|
|
25667
|
+
breakChoice: {
|
|
25668
|
+
kind: "auto",
|
|
25669
|
+
source: resolution.selectedSource ?? pageFlowDefaultJoinCandidate(pageFlowPresetId).source,
|
|
25670
|
+
effectiveValue: effectiveBreak(resolution)
|
|
25671
|
+
},
|
|
25672
|
+
issues: resolution.issues
|
|
25673
|
+
};
|
|
25099
25674
|
}
|
|
25100
|
-
function
|
|
25101
|
-
|
|
25102
|
-
|
|
25103
|
-
case "
|
|
25104
|
-
|
|
25675
|
+
function pinnedBreakChoice(resolution) {
|
|
25676
|
+
const effectiveValue = effectiveBreak(resolution);
|
|
25677
|
+
switch (resolution.pin.kind) {
|
|
25678
|
+
case "unsupported": return {
|
|
25679
|
+
breakChoice: {
|
|
25680
|
+
kind: "user-pinned",
|
|
25681
|
+
value: resolution.pin.optionId,
|
|
25682
|
+
status: "unsupported",
|
|
25683
|
+
effectiveValue
|
|
25684
|
+
},
|
|
25685
|
+
issues: resolution.issues
|
|
25686
|
+
};
|
|
25687
|
+
case "supported":
|
|
25688
|
+
case "none": return {
|
|
25689
|
+
breakChoice: {
|
|
25690
|
+
kind: "user-pinned",
|
|
25691
|
+
value: effectiveValue ?? noneBoundaryOption.id,
|
|
25692
|
+
status: "supported",
|
|
25693
|
+
effectiveValue
|
|
25694
|
+
},
|
|
25695
|
+
issues: resolution.issues
|
|
25696
|
+
};
|
|
25697
|
+
default: return assertNever$1(resolution.pin, "Unhandled join pin status");
|
|
25698
|
+
}
|
|
25699
|
+
}
|
|
25700
|
+
/** The effective break as the option the editor shows; null when nothing was usable. */
|
|
25701
|
+
function effectiveBreak(resolution) {
|
|
25702
|
+
if (resolution.join) {
|
|
25703
|
+
return boundaryOptionForTransitionIntent(resolution.join.treatment).id;
|
|
25105
25704
|
}
|
|
25705
|
+
return resolution.selectedSource ? noneBoundaryOption.id : null;
|
|
25706
|
+
}
|
|
25707
|
+
/**
|
|
25708
|
+
* Re-resolves one boundary of an editor model for a changed break choice,
|
|
25709
|
+
* through the same rules the model was built with. The preview uses it for
|
|
25710
|
+
* optimistic updates, so a reset lands on whichever default the rules pick
|
|
25711
|
+
* (site style or Page Flow). Null when either block is not in the model.
|
|
25712
|
+
*/
|
|
25713
|
+
function resolvePageDesignEditorBoundaryForChoice(input) {
|
|
25714
|
+
const previousBlock = input.editorModel.blocks.find((block) => block.blockId === input.previousBlockId);
|
|
25715
|
+
const nextBlock = input.editorModel.blocks.find((block) => block.blockId === input.nextBlockId);
|
|
25716
|
+
if (!previousBlock || !nextBlock) return null;
|
|
25717
|
+
return buildBoundaryReadModel({
|
|
25718
|
+
siteStyleId: input.editorModel.siteStyleId,
|
|
25719
|
+
pageFlowPresetId: input.editorModel.pageFlow.value,
|
|
25720
|
+
pin: input.choice,
|
|
25721
|
+
previousBlock,
|
|
25722
|
+
nextBlock
|
|
25723
|
+
}).boundary;
|
|
25106
25724
|
}
|
|
25107
25725
|
|
|
25108
25726
|
//#endregion
|
|
@@ -25129,29 +25747,6 @@ const backgroundImagePromotedFieldPath = "_sectionStyles.background.image";
|
|
|
25129
25747
|
* Look/Layout semantics support them.
|
|
25130
25748
|
*/
|
|
25131
25749
|
const normalEditorCuratedPromotedFieldPaths = [backgroundImagePromotedFieldPath];
|
|
25132
|
-
/**
|
|
25133
|
-
* Must remain non-empty; downstream code indexes `[0]` as the documented default.
|
|
25134
|
-
*/
|
|
25135
|
-
const pageFlowPresets = [
|
|
25136
|
-
{
|
|
25137
|
-
id: asPageFlowPresetId("flow:quiet"),
|
|
25138
|
-
label: "Quiet",
|
|
25139
|
-
boundaryStrategy: "quiet",
|
|
25140
|
-
defaultBoundaryOptionId: noneBoundaryOption.id
|
|
25141
|
-
},
|
|
25142
|
-
{
|
|
25143
|
-
id: asPageFlowPresetId("flow:balanced"),
|
|
25144
|
-
label: "Balanced",
|
|
25145
|
-
boundaryStrategy: "balanced",
|
|
25146
|
-
defaultBoundaryOptionId: softBoundaryOption.id
|
|
25147
|
-
},
|
|
25148
|
-
{
|
|
25149
|
-
id: asPageFlowPresetId("flow:expressive"),
|
|
25150
|
-
label: "Expressive",
|
|
25151
|
-
boundaryStrategy: "expressive",
|
|
25152
|
-
defaultBoundaryOptionId: spaciousBoundaryOption.id
|
|
25153
|
-
}
|
|
25154
|
-
];
|
|
25155
25750
|
function buildPageDesignEditorReadModel(input) {
|
|
25156
25751
|
const defaultPageFlow = pageFlowPresets[0];
|
|
25157
25752
|
const currentPageFlow = pageFlowPresets.find((preset) => preset.id === input.intent.pageFlowPresetId) ?? null;
|
|
@@ -25239,8 +25834,8 @@ function buildPageDesignEditorReadModel(input) {
|
|
|
25239
25834
|
};
|
|
25240
25835
|
});
|
|
25241
25836
|
const boundaryResults = buildBoundaryReadModels({
|
|
25242
|
-
|
|
25243
|
-
blocks:
|
|
25837
|
+
...input,
|
|
25838
|
+
blocks: blockResults.map((result) => result.block)
|
|
25244
25839
|
});
|
|
25245
25840
|
return {
|
|
25246
25841
|
siteStyleId: input.siteStyleId,
|
|
@@ -25484,62 +26079,6 @@ function editorChoiceForLook(input) {
|
|
|
25484
26079
|
})
|
|
25485
26080
|
});
|
|
25486
26081
|
}
|
|
25487
|
-
function buildBoundaryReadModels(input) {
|
|
25488
|
-
return input.blocks.flatMap((previous, index) => {
|
|
25489
|
-
const next = input.blocks[index + 1];
|
|
25490
|
-
if (!next) {
|
|
25491
|
-
return [];
|
|
25492
|
-
}
|
|
25493
|
-
const boundaryId = makeBoundaryId(previous.blockId, next.blockId);
|
|
25494
|
-
const choice = resolvePageDesignBoundaryChoice(input.intent, previous.blockId, next.blockId);
|
|
25495
|
-
const breakResult = boundaryEditorChoiceFromResolvedChoice({
|
|
25496
|
-
choice,
|
|
25497
|
-
defaultValue: autoBoundaryOptionForIntent(input.intent),
|
|
25498
|
-
unsupportedIssue: (presetId) => ({
|
|
25499
|
-
kind: "pinned-boundary-option-unavailable",
|
|
25500
|
-
boundaryId,
|
|
25501
|
-
presetId,
|
|
25502
|
-
feedback: "user-facing"
|
|
25503
|
-
})
|
|
25504
|
-
});
|
|
25505
|
-
return {
|
|
25506
|
-
boundary: {
|
|
25507
|
-
boundaryId,
|
|
25508
|
-
previousBlockId: previous.blockId,
|
|
25509
|
-
nextBlockId: next.blockId,
|
|
25510
|
-
breakChoice: breakResult.choice,
|
|
25511
|
-
availableBreaks: boundaryOptions
|
|
25512
|
-
},
|
|
25513
|
-
issues: compactIssues([breakResult.issue])
|
|
25514
|
-
};
|
|
25515
|
-
});
|
|
25516
|
-
}
|
|
25517
|
-
function boundaryEditorChoiceFromResolvedChoice(input) {
|
|
25518
|
-
switch (input.choice.kind) {
|
|
25519
|
-
case "auto": return {
|
|
25520
|
-
choice: {
|
|
25521
|
-
kind: "auto",
|
|
25522
|
-
effectiveValue: input.defaultValue
|
|
25523
|
-
},
|
|
25524
|
-
issue: null
|
|
25525
|
-
};
|
|
25526
|
-
case "user-pinned": {
|
|
25527
|
-
const option = boundaryOptionForTreatment(input.choice.value);
|
|
25528
|
-
const fallbackValue = boundaryOptionIdForTreatment(input.choice.value);
|
|
25529
|
-
const issueValue = fallbackValue ?? input.defaultValue ?? noneBoundaryOption.id;
|
|
25530
|
-
return {
|
|
25531
|
-
choice: {
|
|
25532
|
-
kind: "user-pinned",
|
|
25533
|
-
value: issueValue,
|
|
25534
|
-
status: option ? "supported" : "unsupported",
|
|
25535
|
-
effectiveValue: option?.id ?? input.defaultValue
|
|
25536
|
-
},
|
|
25537
|
-
issue: option ? null : input.unsupportedIssue(issueValue)
|
|
25538
|
-
};
|
|
25539
|
-
}
|
|
25540
|
-
default: return assertNever$1(input.choice, "Unhandled boundary design choice");
|
|
25541
|
-
}
|
|
25542
|
-
}
|
|
25543
26082
|
function editorChoiceFromResolvedChoice(input) {
|
|
25544
26083
|
switch (input.choice.kind) {
|
|
25545
26084
|
case "auto": return {
|
|
@@ -25564,10 +26103,6 @@ function editorChoiceFromResolvedChoice(input) {
|
|
|
25564
26103
|
default: return assertNever$1(input.choice, "Unhandled page design choice");
|
|
25565
26104
|
}
|
|
25566
26105
|
}
|
|
25567
|
-
function autoBoundaryOptionForIntent(intent) {
|
|
25568
|
-
const pageFlow = pageFlowPresets.find((preset) => preset.id === intent.pageFlowPresetId);
|
|
25569
|
-
return pageFlow?.defaultBoundaryOptionId ?? boundaryOptions[0].id;
|
|
25570
|
-
}
|
|
25571
26106
|
function compactIssues(issues) {
|
|
25572
26107
|
return issues.filter((issue$1) => issue$1 !== null);
|
|
25573
26108
|
}
|
|
@@ -25618,7 +26153,6 @@ const repairActionsByIssueKind = {
|
|
|
25618
26153
|
"image-surface-treatment-without-image-surface": ["fallback-image-surface-treatment"],
|
|
25619
26154
|
"image-surface-motion-without-image-surface": ["fallback-image-surface-motion"],
|
|
25620
26155
|
"hero-legibility-overridden-by-image-surface-treatment": ["remove-hero-legibility"],
|
|
25621
|
-
"removed-transition-for-flush-frame": ["remove-transition"],
|
|
25622
26156
|
"hero-image-without-legibility": ["fallback-hero-legibility"]
|
|
25623
26157
|
};
|
|
25624
26158
|
function repairActionsForIssue(issueKind) {
|
|
@@ -25706,11 +26240,6 @@ function repairDesignIssue(issue$1) {
|
|
|
25706
26240
|
issue: issue$1,
|
|
25707
26241
|
action: issue$1.allowedRepairActions[0]
|
|
25708
26242
|
};
|
|
25709
|
-
case "removed-transition-for-flush-frame": return {
|
|
25710
|
-
kind: "repaired",
|
|
25711
|
-
issue: issue$1,
|
|
25712
|
-
action: issue$1.allowedRepairActions[0]
|
|
25713
|
-
};
|
|
25714
26243
|
case "hero-image-without-legibility": return {
|
|
25715
26244
|
kind: "fallbackApplied",
|
|
25716
26245
|
issue: issue$1,
|
|
@@ -25753,13 +26282,9 @@ function supportsBlockComposition(capability, composition) {
|
|
|
25753
26282
|
default: return assertNever$1(composition);
|
|
25754
26283
|
}
|
|
25755
26284
|
}
|
|
25756
|
-
function isDecorativeTransition(transition) {
|
|
25757
|
-
return transition !== "none";
|
|
25758
|
-
}
|
|
25759
26285
|
const blockDesignFallback = {
|
|
25760
26286
|
sectionSurface: "base",
|
|
25761
26287
|
contentFrame: plainFrame,
|
|
25762
|
-
transitionAfter: "none",
|
|
25763
26288
|
sectionHeight: "default",
|
|
25764
26289
|
heroLegibility: "none",
|
|
25765
26290
|
imageSurfaceTreatment: { kind: "none" },
|
|
@@ -25775,7 +26300,6 @@ const appliedBlockDesignFallback = {
|
|
|
25775
26300
|
appliedSectionSurface: blockDesignFallback.sectionSurface,
|
|
25776
26301
|
appliedContentFrame: blockDesignFallback.contentFrame,
|
|
25777
26302
|
appliedCardRole: null,
|
|
25778
|
-
appliedTransitionAfter: blockDesignFallback.transitionAfter,
|
|
25779
26303
|
appliedSectionHeight: blockDesignFallback.sectionHeight,
|
|
25780
26304
|
appliedHeroLegibility: blockDesignFallback.heroLegibility,
|
|
25781
26305
|
appliedImageSurfaceTreatment: blockDesignFallback.imageSurfaceTreatment,
|
|
@@ -25801,7 +26325,6 @@ function blockDesignRequest(block) {
|
|
|
25801
26325
|
sectionSurface: block.sectionSurface,
|
|
25802
26326
|
contentFrame: block.contentFrame,
|
|
25803
26327
|
...block.cardRole ? { cardRole: block.cardRole } : {},
|
|
25804
|
-
transitionAfter: block.transitionAfter,
|
|
25805
26328
|
sectionHeight: block.sectionHeight,
|
|
25806
26329
|
heroLegibility: block.heroLegibility,
|
|
25807
26330
|
imageSurfaceTreatment: block.imageSurfaceTreatment,
|
|
@@ -25820,7 +26343,6 @@ function resolveBlockDesignPlan(input) {
|
|
|
25820
26343
|
let appliedSectionSurface = block.sectionSurface;
|
|
25821
26344
|
let appliedContentFrame = block.contentFrame;
|
|
25822
26345
|
const appliedCardRole = appliedCardRoleFor(block, capability);
|
|
25823
|
-
let appliedTransitionAfter = block.transitionAfter;
|
|
25824
26346
|
let appliedSectionHeight = block.sectionHeight ?? "default";
|
|
25825
26347
|
let appliedHeroLegibility = block.heroLegibility ?? "none";
|
|
25826
26348
|
let appliedImageSurfaceTreatment = block.imageSurfaceTreatment ?? { kind: "none" };
|
|
@@ -26085,7 +26607,6 @@ function resolveBlockDesignPlan(input) {
|
|
|
26085
26607
|
appliedSectionSurface,
|
|
26086
26608
|
appliedContentFrame,
|
|
26087
26609
|
appliedCardRole,
|
|
26088
|
-
appliedTransitionAfter,
|
|
26089
26610
|
appliedSectionHeight,
|
|
26090
26611
|
appliedHeroLegibility,
|
|
26091
26612
|
appliedImageSurfaceTreatment,
|
|
@@ -26097,29 +26618,8 @@ function resolveBlockDesignPlan(input) {
|
|
|
26097
26618
|
appliedComposition
|
|
26098
26619
|
};
|
|
26099
26620
|
});
|
|
26100
|
-
const transitionSafeBlocks = blocks.map((block, index) => {
|
|
26101
|
-
const nextBlock = blocks[index + 1];
|
|
26102
|
-
if (!nextBlock || !isDecorativeTransition(block.appliedTransitionAfter) || block.appliedContentFrame.kind !== "flush-panel" && nextBlock.appliedContentFrame.kind !== "flush-panel") {
|
|
26103
|
-
return block;
|
|
26104
|
-
}
|
|
26105
|
-
issues.push({
|
|
26106
|
-
kind: "removed-transition-for-flush-frame",
|
|
26107
|
-
blockId: block.blockId,
|
|
26108
|
-
blockKind: block.blockKind,
|
|
26109
|
-
purpose: block.purpose,
|
|
26110
|
-
requested: block.appliedTransitionAfter,
|
|
26111
|
-
fallback: "none",
|
|
26112
|
-
policy: input.policy,
|
|
26113
|
-
severity: designIssueSeverityForPolicy(input.policy),
|
|
26114
|
-
allowedRepairActions: repairActionsForIssue("removed-transition-for-flush-frame")
|
|
26115
|
-
});
|
|
26116
|
-
return {
|
|
26117
|
-
...block,
|
|
26118
|
-
appliedTransitionAfter: "none"
|
|
26119
|
-
};
|
|
26120
|
-
});
|
|
26121
26621
|
return {
|
|
26122
|
-
blocks
|
|
26622
|
+
blocks,
|
|
26123
26623
|
issues
|
|
26124
26624
|
};
|
|
26125
26625
|
}
|
|
@@ -27006,80 +27506,6 @@ function recompileSiteChromeHeaderFromPersistedIntent(theme, siteStyle, requeste
|
|
|
27006
27506
|
};
|
|
27007
27507
|
}
|
|
27008
27508
|
|
|
27009
|
-
//#endregion
|
|
27010
|
-
//#region ../theme-core/src/site-styles/runtimeBackgroundResolution.ts
|
|
27011
|
-
function parseCanonicalRuntimeBackground(content) {
|
|
27012
|
-
const sectionStyles = readRecord$1(content._sectionStyles);
|
|
27013
|
-
const background = readRecord$1(sectionStyles?.background);
|
|
27014
|
-
if (!background) return { kind: "none" };
|
|
27015
|
-
const parsed = boxBackgroundSchema.safeParse(background);
|
|
27016
|
-
if (!parsed.success) return { kind: "none" };
|
|
27017
|
-
return parsed.data.contentOwner === pageDesignEditorBackgroundOverrideOwner ? {
|
|
27018
|
-
kind: "page-design-override",
|
|
27019
|
-
background: parsed.data
|
|
27020
|
-
} : {
|
|
27021
|
-
kind: "block-authored",
|
|
27022
|
-
background: parsed.data
|
|
27023
|
-
};
|
|
27024
|
-
}
|
|
27025
|
-
function resolveSectionBackground(source, lookDefault) {
|
|
27026
|
-
if (source.kind === "page-design-override") {
|
|
27027
|
-
return {
|
|
27028
|
-
kind: "page-design-override",
|
|
27029
|
-
background: source.background
|
|
27030
|
-
};
|
|
27031
|
-
}
|
|
27032
|
-
if (lookDefault) {
|
|
27033
|
-
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
27034
|
-
return {
|
|
27035
|
-
kind: "block-authored",
|
|
27036
|
-
background: mergeLookForegroundWithAuthoredMedia(lookDefault, source.background)
|
|
27037
|
-
};
|
|
27038
|
-
}
|
|
27039
|
-
return {
|
|
27040
|
-
kind: "look-default",
|
|
27041
|
-
background: lookDefault
|
|
27042
|
-
};
|
|
27043
|
-
}
|
|
27044
|
-
if (source.kind === "block-authored" && (source.background.type === "image" || source.background.type === "video")) {
|
|
27045
|
-
return {
|
|
27046
|
-
kind: "block-authored",
|
|
27047
|
-
background: source.background
|
|
27048
|
-
};
|
|
27049
|
-
}
|
|
27050
|
-
return source.kind === "block-authored" ? {
|
|
27051
|
-
kind: "block-authored",
|
|
27052
|
-
background: source.background
|
|
27053
|
-
} : { kind: "none" };
|
|
27054
|
-
}
|
|
27055
|
-
function resolveSectionForeground(background, palette) {
|
|
27056
|
-
return resolveSurfaceForeground(background.kind === "none" ? null : background.background, palette, {}, { compositeBase: "background" });
|
|
27057
|
-
}
|
|
27058
|
-
/**
|
|
27059
|
-
* Read foreground authority from post-compiler block content. The preview
|
|
27060
|
-
* compiler has already materialized any Look-owned background into
|
|
27061
|
-
* `_sectionStyles`; raw authored content must be composed with its Look through
|
|
27062
|
-
* `resolveSectionBackground` instead.
|
|
27063
|
-
*/
|
|
27064
|
-
function resolveCompiledSectionForegroundFromContent(content, palette) {
|
|
27065
|
-
if (!content) return resolveSurfaceForeground(null, palette);
|
|
27066
|
-
return resolveSectionForeground(resolveSectionBackground(parseCanonicalRuntimeBackground(content), null), palette);
|
|
27067
|
-
}
|
|
27068
|
-
function mergeLookForegroundWithAuthoredMedia(lookDefault, authored) {
|
|
27069
|
-
const merged = boxBackgroundSchema.safeParse({
|
|
27070
|
-
...lookDefault,
|
|
27071
|
-
type: authored.type,
|
|
27072
|
-
image: authored.image,
|
|
27073
|
-
objectFit: authored.objectFit,
|
|
27074
|
-
scale: authored.scale,
|
|
27075
|
-
position: authored.position
|
|
27076
|
-
});
|
|
27077
|
-
return merged.success ? merged.data : authored;
|
|
27078
|
-
}
|
|
27079
|
-
function readRecord$1(value) {
|
|
27080
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
27081
|
-
}
|
|
27082
|
-
|
|
27083
27509
|
//#endregion
|
|
27084
27510
|
//#region ../theme-core/src/site-styles/previewRuntimeCapabilities.ts
|
|
27085
27511
|
function cardRoleCapabilitiesByBlockKind(blocks) {
|
|
@@ -27555,7 +27981,6 @@ function compileEditorModelRuntime(input) {
|
|
|
27555
27981
|
blockKind: block.blockKind,
|
|
27556
27982
|
purpose: previewCustomizePurpose,
|
|
27557
27983
|
...look ? { appearancePresetId: look.id } : {},
|
|
27558
|
-
transitionAfter: "none",
|
|
27559
27984
|
emphasis: "medium",
|
|
27560
27985
|
sectionSurface: "base",
|
|
27561
27986
|
contentFrame: { kind: "plain" },
|
|
@@ -27565,30 +27990,31 @@ function compileEditorModelRuntime(input) {
|
|
|
27565
27990
|
if (blocks.length === 0) {
|
|
27566
27991
|
return {
|
|
27567
27992
|
blocks: [],
|
|
27568
|
-
|
|
27993
|
+
joins: []
|
|
27569
27994
|
};
|
|
27570
27995
|
}
|
|
27571
|
-
|
|
27572
|
-
const compiled = compilePageRuntimeFields({
|
|
27996
|
+
return compilePageRuntimeFields({
|
|
27573
27997
|
resolved: resolveBlockDesignPlan({
|
|
27574
27998
|
policy: "user",
|
|
27575
27999
|
blocks,
|
|
27576
28000
|
capabilities: runtimeCapabilitiesForBlocks(blocks, cardRoleCapabilitiesByBlockKind(input.editorModel.blocks))
|
|
27577
28001
|
}),
|
|
28002
|
+
joins: input.editorModel.boundaries.flatMap(runtimeJoinForEditorBoundary),
|
|
27578
28003
|
surfaceResolutionContext: input.surfaceResolutionContext,
|
|
27579
28004
|
designRules: input.designRules,
|
|
27580
28005
|
componentRules: input.componentRules,
|
|
27581
28006
|
sectionSpacing: input.sectionSpacing
|
|
27582
28007
|
});
|
|
27583
|
-
|
|
27584
|
-
|
|
27585
|
-
|
|
27586
|
-
|
|
27587
|
-
|
|
27588
|
-
|
|
27589
|
-
|
|
27590
|
-
|
|
27591
|
-
|
|
28008
|
+
}
|
|
28009
|
+
/** The editor boundary's effective break as an intent-only join; none for no break. */
|
|
28010
|
+
function runtimeJoinForEditorBoundary(boundary) {
|
|
28011
|
+
const option = boundary.availableBreaks.find((candidate$1) => candidate$1.id === boundary.breakChoice.effectiveValue);
|
|
28012
|
+
const treatment = option?.transitionAfter;
|
|
28013
|
+
return treatment && isDecorativeTransitionIntent(treatment) ? [{
|
|
28014
|
+
previousBlockId: boundary.previousBlockId,
|
|
28015
|
+
nextBlockId: boundary.nextBlockId,
|
|
28016
|
+
treatment
|
|
28017
|
+
}] : [];
|
|
27592
28018
|
}
|
|
27593
28019
|
function buildCompiledRuntimeFieldsByBlockId(compiled) {
|
|
27594
28020
|
return new Map(compiled.blocks.map((block) => [block.blockId, block.fields]));
|
|
@@ -27596,31 +28022,6 @@ function buildCompiledRuntimeFieldsByBlockId(compiled) {
|
|
|
27596
28022
|
function buildEditorModelRuntimeFieldsByBlockId(input) {
|
|
27597
28023
|
return buildCompiledRuntimeFieldsByBlockId(compileEditorModelRuntime(input));
|
|
27598
28024
|
}
|
|
27599
|
-
function buildEditorModelRuntimeBoundaries(input) {
|
|
27600
|
-
return compileEditorModelRuntime(input).boundaries;
|
|
27601
|
-
}
|
|
27602
|
-
function compileEditorBoundaryRuntime(input) {
|
|
27603
|
-
const blockById = new Map(input.blocks.map((block) => [block.blockId, block]));
|
|
27604
|
-
return input.boundaries.flatMap((boundary) => {
|
|
27605
|
-
const previousBlock = blockById.get(boundary.previousBlockId);
|
|
27606
|
-
const nextBlock = blockById.get(boundary.nextBlockId);
|
|
27607
|
-
const transitionAfter = transitionAfterForEditorBoundary(boundary) ?? input.fallbackTransitionAfterByPreviousBlockId.get(boundary.previousBlockId) ?? null;
|
|
27608
|
-
if (!previousBlock || !nextBlock || !transitionAfter) return [];
|
|
27609
|
-
const compiled = compileBoundaryRuntime({
|
|
27610
|
-
boundaryId: boundary.boundaryId,
|
|
27611
|
-
previousBlockId: boundary.previousBlockId,
|
|
27612
|
-
nextBlockId: boundary.nextBlockId,
|
|
27613
|
-
treatment: transitionAfter,
|
|
27614
|
-
fromSurface: previousBlock.visualSectionSurface,
|
|
27615
|
-
toSurface: nextBlock.visualSectionSurface,
|
|
27616
|
-
rules: input.designRules
|
|
27617
|
-
});
|
|
27618
|
-
return compiled ? [compiled] : [];
|
|
27619
|
-
});
|
|
27620
|
-
}
|
|
27621
|
-
function transitionAfterForEditorBoundary(boundary) {
|
|
27622
|
-
return boundary.availableBreaks.find((candidate$1) => candidate$1.id === boundary.breakChoice.effectiveValue)?.transitionAfter ?? null;
|
|
27623
|
-
}
|
|
27624
28025
|
function compileEditorModelRuntimeFieldsForBlock(input) {
|
|
27625
28026
|
return buildEditorModelRuntimeFieldsByBlockId(input).get(input.blockId) ?? null;
|
|
27626
28027
|
}
|
|
@@ -27631,54 +28032,6 @@ function applyCompiledRuntimeFieldsToContent(content, fields) {
|
|
|
27631
28032
|
...runtimeFields
|
|
27632
28033
|
};
|
|
27633
28034
|
}
|
|
27634
|
-
function retargetCompiledRuntimeFieldsForContentAdjacency(fields, adjacency) {
|
|
27635
|
-
if (!fields?._transitionStyles) return fields;
|
|
27636
|
-
const transition = fields._transitionStyles;
|
|
27637
|
-
const fromSurface = contentOwnedBackgroundEndpoint(adjacency.currentContent) ?? transition.from;
|
|
27638
|
-
const toSurface = contentOwnedBackgroundEndpoint(adjacency.nextContent) ?? transition.to;
|
|
27639
|
-
if (fromSurface === transition.from && toSurface === transition.to) {
|
|
27640
|
-
return fields;
|
|
27641
|
-
}
|
|
27642
|
-
return {
|
|
27643
|
-
...fields,
|
|
27644
|
-
_transitionStyles: compileTransitionRuntime({
|
|
27645
|
-
treatment: transition.treatment,
|
|
27646
|
-
from: fromSurface,
|
|
27647
|
-
to: toSurface
|
|
27648
|
-
})
|
|
27649
|
-
};
|
|
27650
|
-
}
|
|
27651
|
-
function retargetCompiledBoundaryRuntimeForContentAdjacency(boundary, adjacency) {
|
|
27652
|
-
const fromSurface = contentOwnedBackgroundEndpoint(adjacency.currentContent) ?? boundary.from;
|
|
27653
|
-
const toSurface = contentOwnedBackgroundEndpoint(adjacency.nextContent) ?? boundary.to;
|
|
27654
|
-
if (fromSurface === boundary.from && toSurface === boundary.to) {
|
|
27655
|
-
return boundary;
|
|
27656
|
-
}
|
|
27657
|
-
const transition = compileTransitionRuntime({
|
|
27658
|
-
treatment: boundary.treatment,
|
|
27659
|
-
from: fromSurface,
|
|
27660
|
-
to: toSurface
|
|
27661
|
-
});
|
|
27662
|
-
return {
|
|
27663
|
-
...boundary,
|
|
27664
|
-
from: transition.from,
|
|
27665
|
-
to: transition.to,
|
|
27666
|
-
cssVars: transition.cssVars
|
|
27667
|
-
};
|
|
27668
|
-
}
|
|
27669
|
-
function contentOwnedBackgroundEndpoint(content) {
|
|
27670
|
-
const sectionStyles = readRecord(content?._sectionStyles);
|
|
27671
|
-
const background = readRecord(sectionStyles?.background);
|
|
27672
|
-
if (background?.contentOwner !== pageDesignEditorBackgroundOverrideOwner || background.type !== "color") {
|
|
27673
|
-
return null;
|
|
27674
|
-
}
|
|
27675
|
-
const token = parseThemeColorToken(background.color);
|
|
27676
|
-
if (!token) return null;
|
|
27677
|
-
return {
|
|
27678
|
-
kind: "color-token",
|
|
27679
|
-
token
|
|
27680
|
-
};
|
|
27681
|
-
}
|
|
27682
28035
|
function preserveContentOwnedBackgroundFields(content, fields) {
|
|
27683
28036
|
const source = parseCanonicalRuntimeBackground(content);
|
|
27684
28037
|
const resolved = resolveSectionBackground(source, fields._sectionStyles?.background);
|
|
@@ -27693,9 +28046,6 @@ function preserveContentOwnedBackgroundFields(content, fields) {
|
|
|
27693
28046
|
}
|
|
27694
28047
|
};
|
|
27695
28048
|
}
|
|
27696
|
-
function readRecord(value) {
|
|
27697
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
27698
|
-
}
|
|
27699
28049
|
function restoreCompiledRuntimeFieldsFromContent(currentContent, previousContent) {
|
|
27700
28050
|
const nextContent = stripCompiledRuntimeStyleFields(currentContent);
|
|
27701
28051
|
for (const fieldName of compiledRuntimeStyleFieldNames) {
|
|
@@ -27742,7 +28092,7 @@ function compileContentTemplateRuntimeFields(input) {
|
|
|
27742
28092
|
}));
|
|
27743
28093
|
return {
|
|
27744
28094
|
blocks,
|
|
27745
|
-
|
|
28095
|
+
joins: compiled.joins,
|
|
27746
28096
|
fieldsByBlockId: new Map(blocks.map((block) => [block.blockId, block.fields])),
|
|
27747
28097
|
issues: editorModel.issues
|
|
27748
28098
|
};
|
|
@@ -28149,9 +28499,6 @@ function defaultContentFrame() {
|
|
|
28149
28499
|
function cardIntentFor(design, lookDefaults) {
|
|
28150
28500
|
return { cardRole: valueOrLookDefault(design.cardRole, lookDefaults?.cardRole, "none") };
|
|
28151
28501
|
}
|
|
28152
|
-
function defaultTransition() {
|
|
28153
|
-
return "none";
|
|
28154
|
-
}
|
|
28155
28502
|
function defaultEmphasis(block) {
|
|
28156
28503
|
return isHeroBlock(block) ? "high" : "medium";
|
|
28157
28504
|
}
|
|
@@ -28176,8 +28523,24 @@ function isDefaultLookSafeForStyle(preset, siteStyle) {
|
|
|
28176
28523
|
}
|
|
28177
28524
|
return preset.design.contentFrame.kind === "plain" && preset.design.cardRole === "none";
|
|
28178
28525
|
}
|
|
28179
|
-
|
|
28180
|
-
|
|
28526
|
+
/**
|
|
28527
|
+
* The generated pipeline's joins: candidates come from the generated intent
|
|
28528
|
+
* and `resolveJoinTreatment` decides. Joins that resolve to no break are
|
|
28529
|
+
* absent; whether one draws is composition's call.
|
|
28530
|
+
*/
|
|
28531
|
+
function resolveGeneratedJoins(input) {
|
|
28532
|
+
const intentByBlockId = new Map(input.intent.blocks.map((block) => [block.blockId, block]));
|
|
28533
|
+
return input.resolved.blocks.flatMap((block, index) => {
|
|
28534
|
+
const next = input.resolved.blocks[index + 1];
|
|
28535
|
+
const blockIntent = intentByBlockId.get(block.blockId);
|
|
28536
|
+
if (!next || !blockIntent) return [];
|
|
28537
|
+
const { join } = resolveJoinTreatment({
|
|
28538
|
+
candidates: joinCandidatesFromGeneratedIntent(blockIntent),
|
|
28539
|
+
previousBlockId: block.blockId,
|
|
28540
|
+
nextBlockId: next.blockId
|
|
28541
|
+
});
|
|
28542
|
+
return join ? [join] : [];
|
|
28543
|
+
});
|
|
28181
28544
|
}
|
|
28182
28545
|
function materializeBlockDesignPlan(block, siteStyle) {
|
|
28183
28546
|
const lookDefaults = defaultAppearanceDesignForBlock({
|
|
@@ -28194,7 +28557,6 @@ function materializeBlockDesignPlan(block, siteStyle) {
|
|
|
28194
28557
|
sectionSurface,
|
|
28195
28558
|
contentFrame: valueOrLookDefault(block.design.contentFrame, lookDefaults?.contentFrame, defaultContentFrame()),
|
|
28196
28559
|
...cardIntentFor(block.design, lookDefaults),
|
|
28197
|
-
transitionAfter: materializeBoundaryTransition(block.design, block.boundaryIntent, defaultTransition()),
|
|
28198
28560
|
emphasis: valueOrDefault(block.design.emphasis, defaultEmphasis(block)),
|
|
28199
28561
|
heroLegibility: valueOrLookDefault(block.mediaIntent.heroLegibility, lookDefaults?.heroLegibility, defaultLegibility),
|
|
28200
28562
|
...lookDefaults?.sectionHeight ? { sectionHeight: lookDefaults.sectionHeight } : {},
|
|
@@ -28250,7 +28612,6 @@ function resolvedBlockToPlan(block) {
|
|
|
28250
28612
|
sectionSurface: block.appliedSectionSurface,
|
|
28251
28613
|
contentFrame: block.appliedContentFrame,
|
|
28252
28614
|
...block.appliedCardRole ? { cardRole: block.appliedCardRole } : {},
|
|
28253
|
-
transitionAfter: block.appliedTransitionAfter,
|
|
28254
28615
|
emphasis: block.emphasis,
|
|
28255
28616
|
sectionHeight: block.appliedSectionHeight,
|
|
28256
28617
|
heroLegibility: block.appliedHeroLegibility,
|
|
@@ -28387,10 +28748,15 @@ function runGeneratedPageDesignPipeline(input) {
|
|
|
28387
28748
|
})
|
|
28388
28749
|
};
|
|
28389
28750
|
}
|
|
28751
|
+
const joins = resolveGeneratedJoins({
|
|
28752
|
+
intent,
|
|
28753
|
+
resolved
|
|
28754
|
+
});
|
|
28390
28755
|
const compositionIssues = validateCompositionBudget({
|
|
28391
28756
|
policy: "generated",
|
|
28392
28757
|
budget: input.siteStyle.template.compositionBudget,
|
|
28393
28758
|
resolved,
|
|
28759
|
+
joins,
|
|
28394
28760
|
blockContexts: intent.blocks.map((block) => ({
|
|
28395
28761
|
blockId: block.blockId,
|
|
28396
28762
|
mediaIntent: block.mediaIntent.media,
|
|
@@ -28414,6 +28780,7 @@ function runGeneratedPageDesignPipeline(input) {
|
|
|
28414
28780
|
}
|
|
28415
28781
|
const compiledRuntime = compilePageRuntimeFields({
|
|
28416
28782
|
resolved,
|
|
28783
|
+
joins,
|
|
28417
28784
|
surfaceResolutionContext: surfaceResolutionContextFromTheme(compileTokenRecipes(input.siteStyle.template.tokenRecipes)),
|
|
28418
28785
|
designRules: designRuntimeRulesForSiteStyle(input.siteStyle),
|
|
28419
28786
|
componentRules: componentRuntimeRulesForSiteStyle(input.siteStyle)
|
|
@@ -28432,6 +28799,7 @@ function runGeneratedPageDesignPipeline(input) {
|
|
|
28432
28799
|
intent,
|
|
28433
28800
|
plan,
|
|
28434
28801
|
resolved,
|
|
28802
|
+
joins,
|
|
28435
28803
|
headerOpeningSectionContext: deriveHeaderOpeningSectionContext({ openingBlock: resolved.blocks[0] ?? null }),
|
|
28436
28804
|
headerOpeningSectionRepairs: headerOpeningSectionPlan.repairs,
|
|
28437
28805
|
repairs,
|
|
@@ -28678,9 +29046,7 @@ function isNavUnderlineEffect(effect) {
|
|
|
28678
29046
|
}
|
|
28679
29047
|
/** Concrete hex behind a plain palette token, or null when it is not one. */
|
|
28680
29048
|
function paletteHexForToken(theme, token) {
|
|
28681
|
-
|
|
28682
|
-
if (parts.kind !== "token" || parts.opacityPercent !== null) return null;
|
|
28683
|
-
return expandPalette(theme.palette)[parts.token] ?? null;
|
|
29049
|
+
return opaquePaletteHexForToken(expandPalette(theme.palette), token);
|
|
28684
29050
|
}
|
|
28685
29051
|
function compileHeaderScrollTreatment(theme, recipe, foregroundToken) {
|
|
28686
29052
|
if (recipe.scrollTreatment !== "contrast-glass") return undefined;
|
|
@@ -29822,14 +30188,26 @@ const paidOnlineServiceInputSchema = z.object({
|
|
|
29822
30188
|
priceAmount: z.number().int().positive(),
|
|
29823
30189
|
payment: z.object({ mode: z.literal("paid_online_intent") }).strict()
|
|
29824
30190
|
}).strict();
|
|
30191
|
+
/**
|
|
30192
|
+
* A service input with one of the three category placements: none, a
|
|
30193
|
+
* `categoryRef` to a category upserted in the same batch, or the
|
|
30194
|
+
* `categoryIdentifier` of one that already exists (issue 1403).
|
|
30195
|
+
*/
|
|
30196
|
+
function withAppointmentServiceCategoryPlacement(schema) {
|
|
30197
|
+
return z.union([
|
|
30198
|
+
schema.extend(noAppointmentServiceCategoryFields),
|
|
30199
|
+
schema.extend(appointmentServiceCategoryRefFields),
|
|
30200
|
+
schema.extend(appointmentServiceCategoryIdentifierFields)
|
|
30201
|
+
]);
|
|
30202
|
+
}
|
|
29825
30203
|
const upsertAppointmentServiceCommandSchema = z.object({
|
|
29826
30204
|
type: z.literal("upsertAppointmentService"),
|
|
29827
30205
|
ref: appointmentServiceRefSchema,
|
|
29828
|
-
input: z.union([
|
|
29829
|
-
manualRequestServiceInputSchema,
|
|
29830
|
-
freeServiceInputSchema,
|
|
29831
|
-
paidOnlineServiceInputSchema
|
|
29832
|
-
])
|
|
30206
|
+
input: z.unknown().superRefine(rejectBothAppointmentServiceCategoryKeys).pipe(z.union([
|
|
30207
|
+
withAppointmentServiceCategoryPlacement(manualRequestServiceInputSchema),
|
|
30208
|
+
withAppointmentServiceCategoryPlacement(freeServiceInputSchema),
|
|
30209
|
+
withAppointmentServiceCategoryPlacement(paidOnlineServiceInputSchema)
|
|
30210
|
+
]))
|
|
29833
30211
|
}).strict();
|
|
29834
30212
|
const upsertBookableResourceCommandSchema = z.object({
|
|
29835
30213
|
type: z.literal("upsertBookableResource"),
|
|
@@ -29881,6 +30259,31 @@ function validatePortalOrder(input, ctx) {
|
|
|
29881
30259
|
});
|
|
29882
30260
|
}
|
|
29883
30261
|
|
|
30262
|
+
//#endregion
|
|
30263
|
+
//#region ../site-commands/src/bookingCommandSchemaOptions.ts
|
|
30264
|
+
/**
|
|
30265
|
+
* The booking, entitlement and appointment command schemas, in the order the
|
|
30266
|
+
* site command union lists them. `configureBookingSettings` stays with the
|
|
30267
|
+
* site-level commands at the head of the union.
|
|
30268
|
+
*/
|
|
30269
|
+
const bookingCommandSchemaOptions = [
|
|
30270
|
+
upsertBookingPassProductCommandSchema,
|
|
30271
|
+
upsertBookingMembershipProductCommandSchema,
|
|
30272
|
+
seedBookingCustomerCommandSchema,
|
|
30273
|
+
grantCustomerPassCommandSchema,
|
|
30274
|
+
grantCustomerMembershipCommandSchema,
|
|
30275
|
+
seedAppointmentBookingCommandSchema,
|
|
30276
|
+
seedEventSeriesRegistrationCommandSchema,
|
|
30277
|
+
seedEventRegistrationCommandSchema,
|
|
30278
|
+
seedPassRedemptionCommandSchema,
|
|
30279
|
+
seedPortalOrderCommandSchema,
|
|
30280
|
+
upsertAppointmentServiceCategoryCommandSchema,
|
|
30281
|
+
upsertAppointmentServiceCommandSchema,
|
|
30282
|
+
upsertBookableResourceCommandSchema,
|
|
30283
|
+
assignAppointmentServiceResourcesCommandSchema,
|
|
30284
|
+
configureAppointmentAvailabilityCommandSchema
|
|
30285
|
+
];
|
|
30286
|
+
|
|
29884
30287
|
//#endregion
|
|
29885
30288
|
//#region ../site-commands/src/commands.ts
|
|
29886
30289
|
const mediaRefSchema = resourceRefSchema("media");
|
|
@@ -30349,20 +30752,7 @@ const siteCommandSchema = z.discriminatedUnion("type", [
|
|
|
30349
30752
|
deleteEventCategoryCommandSchema,
|
|
30350
30753
|
upsertEventSeriesCommandSchema,
|
|
30351
30754
|
deleteEventSeriesCommandSchema,
|
|
30352
|
-
|
|
30353
|
-
upsertBookingMembershipProductCommandSchema,
|
|
30354
|
-
seedBookingCustomerCommandSchema,
|
|
30355
|
-
grantCustomerPassCommandSchema,
|
|
30356
|
-
grantCustomerMembershipCommandSchema,
|
|
30357
|
-
seedAppointmentBookingCommandSchema,
|
|
30358
|
-
seedEventSeriesRegistrationCommandSchema,
|
|
30359
|
-
seedEventRegistrationCommandSchema,
|
|
30360
|
-
seedPassRedemptionCommandSchema,
|
|
30361
|
-
seedPortalOrderCommandSchema,
|
|
30362
|
-
upsertAppointmentServiceCommandSchema,
|
|
30363
|
-
upsertBookableResourceCommandSchema,
|
|
30364
|
-
assignAppointmentServiceResourcesCommandSchema,
|
|
30365
|
-
configureAppointmentAvailabilityCommandSchema
|
|
30755
|
+
...bookingCommandSchemaOptions
|
|
30366
30756
|
]);
|
|
30367
30757
|
|
|
30368
30758
|
//#endregion
|
|
@@ -30484,6 +30874,7 @@ const commandScopes = [
|
|
|
30484
30874
|
"order",
|
|
30485
30875
|
"booking_settings",
|
|
30486
30876
|
"appointment_service",
|
|
30877
|
+
"appointment_service_category",
|
|
30487
30878
|
"appointment_resource",
|
|
30488
30879
|
"appointment_availability",
|
|
30489
30880
|
"publish"
|
|
@@ -31112,6 +31503,19 @@ const siteCommandMetadata = {
|
|
|
31112
31503
|
capability: "commerce.orders.write",
|
|
31113
31504
|
support: "supported"
|
|
31114
31505
|
},
|
|
31506
|
+
upsertAppointmentServiceCategory: {
|
|
31507
|
+
scope: "appointment_service_category",
|
|
31508
|
+
risk: "medium",
|
|
31509
|
+
writeSemantics: "upsert",
|
|
31510
|
+
lifecycleIntent: "mutation",
|
|
31511
|
+
idempotencyStrategy: "natural_key",
|
|
31512
|
+
conflictPolicy: "update_existing",
|
|
31513
|
+
previewability: "dry_run_only",
|
|
31514
|
+
allowedRuntimes: allRuntimes,
|
|
31515
|
+
intendedExposure: recipeExposure,
|
|
31516
|
+
capability: "bookings.appointment_service_categories.write",
|
|
31517
|
+
support: "supported"
|
|
31518
|
+
},
|
|
31115
31519
|
upsertAppointmentService: {
|
|
31116
31520
|
scope: "appointment_service",
|
|
31117
31521
|
risk: "medium",
|
|
@@ -31291,6 +31695,7 @@ const bookingRefCommandTypeValues = [
|
|
|
31291
31695
|
"seedEventRegistration",
|
|
31292
31696
|
"seedPassRedemption",
|
|
31293
31697
|
"seedPortalOrder",
|
|
31698
|
+
"upsertAppointmentServiceCategory",
|
|
31294
31699
|
"upsertAppointmentService",
|
|
31295
31700
|
"upsertBookableResource",
|
|
31296
31701
|
"assignAppointmentServiceResources",
|
|
@@ -31304,8 +31709,12 @@ function bookingCommandRefContributions(command) {
|
|
|
31304
31709
|
switch (command.type) {
|
|
31305
31710
|
case "upsertBookingMembershipProduct":
|
|
31306
31711
|
case "seedBookingCustomer":
|
|
31307
|
-
case "
|
|
31712
|
+
case "upsertAppointmentServiceCategory":
|
|
31308
31713
|
case "upsertBookableResource": return provided(command.ref);
|
|
31714
|
+
case "upsertAppointmentService": return providedWithRequirements(command.ref, command.input.categoryRef === undefined ? [] : [{
|
|
31715
|
+
ref: command.input.categoryRef,
|
|
31716
|
+
field: "input.categoryRef"
|
|
31717
|
+
}]);
|
|
31309
31718
|
case "upsertBookingPassProduct": return {
|
|
31310
31719
|
...provided(command.ref),
|
|
31311
31720
|
requires: command.input.appointmentScope?.mode === "selected_services" ? command.input.appointmentScope.serviceRefs.map((ref, index) => ({
|
|
@@ -31838,7 +32247,8 @@ function matchSiteCommand(command, match) {
|
|
|
31838
32247
|
case "seedEventRegistration": return match(command);
|
|
31839
32248
|
case "seedPassRedemption": return match(command);
|
|
31840
32249
|
case "seedPortalOrder": return match(command);
|
|
31841
|
-
case "
|
|
32250
|
+
case "upsertAppointmentServiceCategory":
|
|
32251
|
+
case "upsertAppointmentService":
|
|
31842
32252
|
case "upsertBookableResource": return match(command);
|
|
31843
32253
|
case "assignAppointmentServiceResources": return match(command);
|
|
31844
32254
|
case "configureAppointmentAvailability": return match(command);
|
|
@@ -32848,4 +33258,4 @@ function parseSdkEventRunUpsertInput(input, runIndex, options) {
|
|
|
32848
33258
|
}
|
|
32849
33259
|
|
|
32850
33260
|
//#endregion
|
|
32851
|
-
export {
|
|
33261
|
+
export { resolveContextualButtonRole as $, footerModeSchema as $n, getComponentBorderWidthPx as $t, boundaryLayout as A, surfaceToneFromForegroundToken as An, headerVariantValues as At, require_jsx_runtime as B, oklchToHexGamut as Bn, defineBlockDesignCapability as Bt, mergeHeaderNavTypographyPreference as C, borderColorStyle as Cn, BREAKPOINT_SM as Ct, GRADIENT_PRESET_IDS as D, textColorStyle as Dn, MQ_SM_DOWN as Dt, gradientToCss as E, rgbColorValue as En, MQ_MD_DOWN as Et, transitionCatalogueEntries as F, defaultThemeTokens as Fn, pageDesignEditorBackgroundOverrideOwner as Ft, PUBLIC_BUTTON_ROLES as G, generateShadowValue$1 as Gn, featureCardCompositionTreatmentValues as Gt, pickShadeTowardBackground as H, surfaceForegroundDeclarations as Hn, defineNoBlockDesignCapability as Ht, backgroundAppearanceColorTokenNames as I, ORDINARY_TEXT_MIN_CONTRAST_RATIO as In, stripStaleTransitionStyleGroup as It, resolvedButtonColourDeclarations as J, normalizeCardRole as Jn, makeBoundaryId as Jt, generateButtonCss as K, cardRoleSchema as Kn, headingDecorationColorTokenValues as Kt, backgroundAppearanceQuickColorTokenNames as L, contrastRatio as Ln, asAppearancePresetId as Lt, sectionFactsForContent as M, isOnColorBackgroundCandidateToken as Mn, resolveOnColorForThemeToken as Mt, boundaryRuntimeMetricsForDecorativeTransition as N, onColorTokenName as Nn, resolveThemeColorReferenceValue as Nt, getGradientPreset as O, textColorValue as On, MQ_SM_UP as Ot, anglePolygonCss as P, buildThemeTokens as Pn, resolveTokenOrCssColorValue as Pt, deriveButtonSurfaceContext as Q, persistableMediaSchema as Qn, visibleHeadingDecorationFamilyValues as Qt, parseBackgroundAppearanceColorToken as R, featuresFromHex as Rn, asDesignBlockId as Rt, eventBookingOfferIntentSchema as S, backgroundColorStyle as Sn, BREAKPOINT_MD as St, getCuratedSiteStyle as T, mergeStyles as Tn, MQ_LG_UP as Tt, generateCssVars as U, surfaceForegroundStyle as Un, eventListTreatmentValues as Ut, require_react as V, DEFAULT_SURFACE_TEXT_COLOR as Vn, defineFrameCapability as Vt, buttonStyleSelectionSchema as W, surfaceForegroundValue as Wn, eyebrowTreatmentValues as Wt, contextualButtonSurfaceResetStyles as X, mediaSchema as Xn, testimonialsCompositionTreatmentValues as Xt, resolvedButtonFocusDeclarations as Y, mediaIdentifierSchema as Yn, offeringsPreviewCompositionTreatmentValues as Yt, contextualButtonSurfaceStyles as Z, mediaTypeDiscriminants as Zn, tileTreatmentValues as Zt, entryIdentifierForCommand as _, ICON_SIZE_PX as _n, slugPart as _r, generateHeaderScrollTreatmentStyles as _t, classifySdkEventBookingOffer as a, NAV_LINK_PADDING_MAP as an, createBlocksRef as ar, themeButtonExtraClassesWithTrailingIcon as at, pagePathForCommand as b, generateCardCss as bn, renderHeaderPaintTargetRules as bt, stableStringify as c, FONT_WEIGHT_MAP$1 as cn, createEventCategoryRef as cr, parseThemeForPersistence as ct, mapEventCommandContent as d, LABEL_FONT_SIZE_MAP as dn, createFormRef as dr, generateShadowValue as dt, getComponentShadowVar as en, VARIANT_ROLES as er, generateDefaultButtonSystem as et, evaluateSiteCommandBatchExposure as f, ACCORDION_OPEN_ACCENT_THICKNESS as fn, createNavigationRef as fr, expandPalette as ft, blockOrderIdentifiersForCommand as g, ICON_CONFIG as gn, refSlug as gr, boxBackgroundSchema as gt, blockIdentifierForCommand as h, ACCORDION_TRIGGER_LETTER_SPACING as hn, createVenueRef as hr, boxBackgroundOverlaySchema as ht, classifySdkEventSchedule as i, NAV_LINK_LETTER_SPACING_MAP as in, createBlockRef as ir, parseThemeButtonVariantId as it, composeBoundary as j, resolveSurfaceForeground as jn, isCssColorLiteral as jt, parseGradientPresetId as k, selectLogoVariant as kn, MQ_TABLET_ONLY as kt, createDryRunReport as l, INPUT_FONT_SIZE_MAP as ln, createEventSeriesRef as lr, compileButtonColourStates as lt, getSiteCommandMetadata as m, ACCORDION_TRIGGER_FONT_SCALE as mn, createSiteCommandSiteRef as mr, themeSchema as mt, sdkEventOccurrenceInputSchema as n, parseCustomCssRules as nn, unsafeAsOpaqueButtonColourToken as nr, generateBaseInteractiveCSS as nt, venueManagementFields as o, NAV_LINK_PADDING_X_MAP as on, createCommandRef as or, themeButtonSizeClassName as ot, evaluateSiteCommandExposure as p, ACCORDION_SPACING_MAP as pn, createPageRef as pr, getTextColorForBackground as pt, RESOLVED_BUTTON_DISABLED_DECLARATIONS as q, cardVariantRoleValues as qn, introCompositionTreatmentValues as qt, sdkEventUpsertOptionalFieldSchemas as r, NAV_LINK_BORDER_RADIUS_MAP as rn, parseBlockColorToken as rr, generateInteractiveChildInheritanceCSS as rt, sortRecord as s, NAV_LINK_TEXT_SIZE_MAP as sn, createContentEntryRef as sr, themeButtonVariantClassNames as st, classifySdkEventTiming as t, parseBlockCustomCssRules as tn, buttonVariantIdSchema as tr, generateEffectsCSS as tt, parseAndPlanCommandBatchForTypes as u, INPUT_SPACING_MAP as un, createFooterRef as ur, formatButtonColourContractError as ut, pageIdentifierForBlockCommand as v, generateCardCoreCss as vn, __toESM as vr, generateMobileOverlayBackdropFilterFix as vt, readHeaderNavFontSizePreference as w, cssVarValue as wn, BREAKPOINT_XL as wt, hasConfiguredBookingVertical as x, TokenResolver as xn, BREAKPOINT_LG as xt, pageIdentifierForCommand as y, getDefaultCardVariants as yn, getHeaderPaintTargets as yt, defineBlockDesignMetadata as z, hexToRgb as zn, assertNever$1 as zt };
|