@orion-studios/payload-studio 0.5.0-beta.11 → 0.5.0-beta.111
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/README.md +54 -0
- package/dist/admin/client.d.mts +3 -0
- package/dist/admin/client.d.ts +3 -0
- package/dist/admin/client.js +1745 -200
- package/dist/admin/client.mjs +1756 -214
- package/dist/admin/index.d.mts +2 -1
- package/dist/admin/index.d.ts +2 -1
- package/dist/admin/index.js +424 -11
- package/dist/admin/index.mjs +19 -1
- package/dist/admin-app/client.d.mts +7 -0
- package/dist/admin-app/client.d.ts +7 -0
- package/dist/admin-app/client.js +1270 -3
- package/dist/admin-app/client.mjs +1172 -2
- package/dist/admin-app/index.d.mts +1 -1
- package/dist/admin-app/index.d.ts +1 -1
- package/dist/admin-app/index.js +167 -0
- package/dist/admin-app/index.mjs +13 -1
- package/dist/admin-app/styles.css +247 -0
- package/dist/admin.css +8 -0
- package/dist/blocks/index.js +1011 -191
- package/dist/blocks/index.mjs +2 -2
- package/dist/chunk-ADIIWIYL.mjs +322 -0
- package/dist/{chunk-ZLLNO5FM.mjs → chunk-BET2YLAS.mjs} +104 -15
- package/dist/chunk-DAIZDGHL.mjs +614 -0
- package/dist/chunk-GKMBYYXF.mjs +776 -0
- package/dist/chunk-JQAHXYAM.mjs +1829 -0
- package/dist/chunk-OQSEJXC4.mjs +166 -0
- package/dist/chunk-PF3EBZXF.mjs +326 -0
- package/dist/chunk-ROTPP5CU.mjs +99 -0
- package/dist/chunk-XVH5SCBD.mjs +234 -0
- package/dist/chunk-ZTXJG4K5.mjs +85 -0
- package/dist/index-7lxTrxSG.d.mts +128 -0
- package/dist/index-7lxTrxSG.d.ts +128 -0
- package/dist/index-B7QvY3yF.d.mts +245 -0
- package/dist/index-BK03FiEM.d.ts +245 -0
- package/dist/{index-CmR6NInu.d.ts → index-BzKOThsI.d.mts} +30 -3
- package/dist/{index-CmR6NInu.d.mts → index-BzKOThsI.d.ts} +30 -3
- package/dist/{index-DbH0Ljwp.d.mts → index-D8BNfUJb.d.mts} +17 -2
- package/dist/{index-DbH0Ljwp.d.ts → index-DD_E2UfJ.d.ts} +17 -2
- package/dist/index-DUi_XND6.d.ts +193 -0
- package/dist/index-gLl_358v.d.mts +193 -0
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +2876 -460
- package/dist/index.mjs +12 -10
- package/dist/nextjs/index.d.mts +2 -1
- package/dist/nextjs/index.d.ts +2 -1
- package/dist/nextjs/index.js +497 -16
- package/dist/nextjs/index.mjs +8 -3
- package/dist/socialMedia-C05Iy-SV.d.mts +21 -0
- package/dist/socialMedia-C05Iy-SV.d.ts +21 -0
- package/dist/studio/index.d.mts +2 -1
- package/dist/studio/index.d.ts +2 -1
- package/dist/studio/index.js +171 -5
- package/dist/studio/index.mjs +7 -3
- package/dist/studio-pages/builder.css +517 -32
- package/dist/studio-pages/client.d.mts +75 -1
- package/dist/studio-pages/client.d.ts +75 -1
- package/dist/studio-pages/client.js +5662 -2759
- package/dist/studio-pages/client.mjs +5578 -2767
- package/dist/studio-pages/index.d.mts +4 -2
- package/dist/studio-pages/index.d.ts +4 -2
- package/dist/studio-pages/index.js +859 -71
- package/dist/studio-pages/index.mjs +10 -4
- package/package.json +35 -13
- package/dist/chunk-AAOHJDNS.mjs +0 -67
- package/dist/chunk-ETRRXURT.mjs +0 -141
- package/dist/chunk-J7W5EE3B.mjs +0 -278
- package/dist/chunk-N67KVM2S.mjs +0 -156
- package/dist/chunk-NESLJZFE.mjs +0 -303
- package/dist/chunk-U5BSPWAD.mjs +0 -1034
- package/dist/index-B9N5MyjF.d.mts +0 -39
- package/dist/index-BallJs-K.d.mts +0 -43
- package/dist/index-BallJs-K.d.ts +0 -43
- package/dist/index-DJFhANvJ.d.mts +0 -128
- package/dist/index-DJFhANvJ.d.ts +0 -128
- package/dist/index-g8tBHLKD.d.ts +0 -39
package/dist/index.js
CHANGED
|
@@ -42,8 +42,16 @@ module.exports = __toCommonJS(index_exports);
|
|
|
42
42
|
// src/admin/index.ts
|
|
43
43
|
var admin_exports = {};
|
|
44
44
|
__export(admin_exports, {
|
|
45
|
+
SOCIAL_MEDIA_DEFAULT_ICON_BY_PLATFORM: () => SOCIAL_MEDIA_DEFAULT_ICON_BY_PLATFORM,
|
|
46
|
+
SOCIAL_MEDIA_ICON_OPTIONS: () => SOCIAL_MEDIA_ICON_OPTIONS,
|
|
47
|
+
SOCIAL_MEDIA_PLATFORMS: () => SOCIAL_MEDIA_PLATFORMS,
|
|
48
|
+
SOCIAL_MEDIA_PLATFORM_LABELS: () => SOCIAL_MEDIA_PLATFORM_LABELS,
|
|
45
49
|
configureAdmin: () => configureAdmin,
|
|
50
|
+
createHeaderNavItemsField: () => createHeaderNavItemsField,
|
|
51
|
+
createSocialMediaConnectionsField: () => createSocialMediaConnectionsField,
|
|
52
|
+
createSocialMediaGlobal: () => createSocialMediaGlobal,
|
|
46
53
|
createThemePreferenceField: () => createThemePreferenceField,
|
|
54
|
+
socialMediaConnectionsField: () => socialMediaConnectionsField,
|
|
47
55
|
themePreferenceField: () => themePreferenceField,
|
|
48
56
|
withTooltips: () => withTooltips
|
|
49
57
|
});
|
|
@@ -71,6 +79,113 @@ var createThemePreferenceField = (defaultTheme = "brand-light") => ({
|
|
|
71
79
|
});
|
|
72
80
|
var themePreferenceField = createThemePreferenceField("brand-light");
|
|
73
81
|
|
|
82
|
+
// src/shared/studioSections.ts
|
|
83
|
+
var studioRoles = /* @__PURE__ */ new Set(["admin", "editor", "client"]);
|
|
84
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
85
|
+
var isAbsoluteExternalURL = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
|
|
86
|
+
var normalizePathLikeValue = (value) => {
|
|
87
|
+
const trimmed = value.trim();
|
|
88
|
+
if (!trimmed) {
|
|
89
|
+
return "";
|
|
90
|
+
}
|
|
91
|
+
if (isAbsoluteExternalURL(trimmed)) {
|
|
92
|
+
return trimmed;
|
|
93
|
+
}
|
|
94
|
+
const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
95
|
+
const normalized = withLeadingSlash.replace(/\/+$/, "");
|
|
96
|
+
return normalized || "/";
|
|
97
|
+
};
|
|
98
|
+
var normalizeStringArray = (value) => {
|
|
99
|
+
if (!Array.isArray(value)) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
return value.filter((entry) => typeof entry === "string").map((entry) => normalizePathLikeValue(entry)).filter((entry) => entry.length > 0);
|
|
103
|
+
};
|
|
104
|
+
var normalizeRoles = (value) => {
|
|
105
|
+
if (!Array.isArray(value)) {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
const roles = value.filter((entry) => typeof entry === "string" && studioRoles.has(entry));
|
|
109
|
+
return roles.length > 0 ? roles : void 0;
|
|
110
|
+
};
|
|
111
|
+
var normalizeCard = (value) => {
|
|
112
|
+
if (!isRecord(value) || typeof value.title !== "string") {
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
const title = value.title.trim();
|
|
116
|
+
if (!title) {
|
|
117
|
+
return void 0;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
title,
|
|
121
|
+
...typeof value.description === "string" && value.description.trim().length > 0 ? { description: value.description.trim() } : {}
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
var resolveStudioSections = (value) => {
|
|
125
|
+
if (!Array.isArray(value)) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
const sections = [];
|
|
129
|
+
const seen = /* @__PURE__ */ new Set();
|
|
130
|
+
for (const entry of value) {
|
|
131
|
+
if (!isRecord(entry) || typeof entry.id !== "string" || typeof entry.label !== "string") {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const id = entry.id.trim();
|
|
135
|
+
const label = entry.label.trim();
|
|
136
|
+
if (!id || !label || seen.has(id)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const href = typeof entry.href === "string" && entry.href.trim().length > 0 ? normalizePathLikeValue(entry.href) : isRecord(entry.view) && typeof entry.view.path === "string" ? normalizePathLikeValue(entry.view.path) : "";
|
|
140
|
+
if (!href) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const matchPrefixes = Array.from(/* @__PURE__ */ new Set([href, ...normalizeStringArray(entry.matchPrefixes)]));
|
|
144
|
+
sections.push({
|
|
145
|
+
id,
|
|
146
|
+
label,
|
|
147
|
+
href,
|
|
148
|
+
matchPrefixes,
|
|
149
|
+
...normalizeRoles(entry.roles) ? { roles: normalizeRoles(entry.roles) } : {},
|
|
150
|
+
...normalizeCard(entry.card) ? { card: normalizeCard(entry.card) } : {}
|
|
151
|
+
});
|
|
152
|
+
seen.add(id);
|
|
153
|
+
}
|
|
154
|
+
return sections;
|
|
155
|
+
};
|
|
156
|
+
var resolveStudioSectionViews = (value) => {
|
|
157
|
+
if (!Array.isArray(value)) {
|
|
158
|
+
return {};
|
|
159
|
+
}
|
|
160
|
+
const views = {};
|
|
161
|
+
for (const entry of value) {
|
|
162
|
+
if (!isRecord(entry) || typeof entry.id !== "string" || !isRecord(entry.view)) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const id = entry.id.trim();
|
|
166
|
+
const view = entry.view;
|
|
167
|
+
const component = isRecord(view.Component) ? view.Component : null;
|
|
168
|
+
if (!id || typeof view.path !== "string" || !component || typeof component.exportName !== "string" || typeof component.path !== "string") {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const path2 = normalizePathLikeValue(view.path);
|
|
172
|
+
const componentPath = component.path.trim();
|
|
173
|
+
const exportName = component.exportName.trim();
|
|
174
|
+
if (!path2 || !componentPath || !exportName) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
views[id] = {
|
|
178
|
+
path: path2,
|
|
179
|
+
Component: {
|
|
180
|
+
exportName,
|
|
181
|
+
path: componentPath,
|
|
182
|
+
...isRecord(component.clientProps) ? { clientProps: component.clientProps } : {}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
return views;
|
|
187
|
+
};
|
|
188
|
+
|
|
74
189
|
// src/admin/helpers/configureAdmin.ts
|
|
75
190
|
var import_meta = {};
|
|
76
191
|
function getPkgDistDir() {
|
|
@@ -98,14 +213,31 @@ function configureAdmin(config) {
|
|
|
98
213
|
defaultTheme = "brand-light",
|
|
99
214
|
logoUrl
|
|
100
215
|
} = config;
|
|
101
|
-
const studioEnabled =
|
|
216
|
+
const studioEnabled = config.studio?.enabled ?? true;
|
|
217
|
+
const formsEnabled = config.studio?.forms?.enabled ?? false;
|
|
218
|
+
const formsCollectionSlug = config.studio?.forms?.collectionSlug || "forms";
|
|
219
|
+
const formSubmissionsCollectionSlug = config.studio?.forms?.submissionsCollectionSlug || "form-submissions";
|
|
220
|
+
const formUploadsCollectionSlug = config.studio?.forms?.uploadsCollectionSlug || "form-uploads";
|
|
102
221
|
const pagesCollectionSlug = config.studio?.pages?.collectionSlug || "pages";
|
|
103
222
|
const mediaCollectionSlug = config.studio?.media?.collectionSlug || "media";
|
|
104
|
-
const
|
|
223
|
+
const contactFormStudioPath = "/studio-contact-form";
|
|
224
|
+
const configuredGlobals = config.studio?.globals || [
|
|
105
225
|
{ slug: "site-settings", label: "Website Settings" },
|
|
106
226
|
{ slug: "header", label: "Header & Navigation" },
|
|
107
|
-
{ slug: "footer", label: "Footer" }
|
|
227
|
+
{ slug: "footer", label: "Footer" },
|
|
228
|
+
{ slug: "contact-form", label: "Contact Form" }
|
|
108
229
|
];
|
|
230
|
+
const globals = configuredGlobals.map((global) => {
|
|
231
|
+
if (global.slug !== "contact-form" || global.href) {
|
|
232
|
+
return global;
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
...global,
|
|
236
|
+
href: contactFormStudioPath
|
|
237
|
+
};
|
|
238
|
+
});
|
|
239
|
+
const studioSections = resolveStudioSections(config.studio?.sections || []);
|
|
240
|
+
const studioSectionViews = resolveStudioSectionViews(config.studio?.sections || []);
|
|
109
241
|
let cssPath;
|
|
110
242
|
const pkgDist = getPkgDistDir();
|
|
111
243
|
const sourceCssPath = import_path.default.resolve(pkgDist, "admin.css");
|
|
@@ -135,9 +267,15 @@ function configureAdmin(config) {
|
|
|
135
267
|
clientProps: {
|
|
136
268
|
brandName,
|
|
137
269
|
logoUrl,
|
|
138
|
-
globalsBasePath: "/
|
|
270
|
+
globalsBasePath: "/studio-globals",
|
|
271
|
+
globalsExtraMatchPrefixes: [contactFormStudioPath],
|
|
272
|
+
formSubmissionsCollectionSlug,
|
|
273
|
+
formsCollectionSlug,
|
|
274
|
+
formsEnabled,
|
|
275
|
+
formUploadsCollectionSlug,
|
|
139
276
|
mediaCollectionSlug,
|
|
140
|
-
pagesCollectionSlug
|
|
277
|
+
pagesCollectionSlug,
|
|
278
|
+
sections: studioSections
|
|
141
279
|
}
|
|
142
280
|
}
|
|
143
281
|
} : {},
|
|
@@ -167,9 +305,15 @@ function configureAdmin(config) {
|
|
|
167
305
|
clientProps: {
|
|
168
306
|
brandName,
|
|
169
307
|
logoUrl,
|
|
170
|
-
globalsBasePath: "/
|
|
308
|
+
globalsBasePath: "/studio-globals",
|
|
309
|
+
globalsExtraMatchPrefixes: [contactFormStudioPath],
|
|
310
|
+
formSubmissionsCollectionSlug,
|
|
311
|
+
formsCollectionSlug,
|
|
312
|
+
formsEnabled,
|
|
313
|
+
formUploadsCollectionSlug,
|
|
171
314
|
mediaCollectionSlug,
|
|
172
|
-
pagesCollectionSlug
|
|
315
|
+
pagesCollectionSlug,
|
|
316
|
+
sections: studioSections
|
|
173
317
|
}
|
|
174
318
|
}
|
|
175
319
|
},
|
|
@@ -181,10 +325,44 @@ function configureAdmin(config) {
|
|
|
181
325
|
path: clientPath,
|
|
182
326
|
clientProps: {
|
|
183
327
|
globals,
|
|
184
|
-
globalsBasePath: "/
|
|
328
|
+
globalsBasePath: "/studio-globals"
|
|
185
329
|
}
|
|
186
330
|
}
|
|
187
|
-
}
|
|
331
|
+
},
|
|
332
|
+
studioContactForm: {
|
|
333
|
+
path: "/studio-contact-form",
|
|
334
|
+
Component: {
|
|
335
|
+
exportName: "AdminStudioContactFormView",
|
|
336
|
+
path: clientPath,
|
|
337
|
+
clientProps: {
|
|
338
|
+
globalSlug: "contact-form",
|
|
339
|
+
globalsBasePath: "/studio-globals"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
...formsEnabled ? {
|
|
344
|
+
studioForms: {
|
|
345
|
+
path: "/studio-forms",
|
|
346
|
+
Component: {
|
|
347
|
+
exportName: "AdminStudioFormsView",
|
|
348
|
+
path: clientPath,
|
|
349
|
+
clientProps: {
|
|
350
|
+
formsCollectionSlug,
|
|
351
|
+
formSubmissionsCollectionSlug,
|
|
352
|
+
formUploadsCollectionSlug
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
} : {},
|
|
357
|
+
...Object.fromEntries(
|
|
358
|
+
Object.entries(studioSectionViews).map(([id, view]) => [
|
|
359
|
+
id,
|
|
360
|
+
{
|
|
361
|
+
path: view.path,
|
|
362
|
+
Component: view.Component
|
|
363
|
+
}
|
|
364
|
+
])
|
|
365
|
+
)
|
|
188
366
|
} : {}
|
|
189
367
|
},
|
|
190
368
|
providers: [
|
|
@@ -228,16 +406,48 @@ function configureAdmin(config) {
|
|
|
228
406
|
const labelMap = {
|
|
229
407
|
header: { group: "Site Design", label: "Header & Navigation" },
|
|
230
408
|
footer: { group: "Site Design", label: "Footer" },
|
|
231
|
-
"site-settings": { group: "Site Design", label: "Website Settings" }
|
|
409
|
+
"site-settings": { group: "Site Design", label: "Website Settings" },
|
|
410
|
+
"social-media": { group: "Site Design", label: "Social Media" },
|
|
411
|
+
"contact-form": { group: "Lead Forms", label: "Contact Form" }
|
|
232
412
|
};
|
|
233
413
|
return globals2.map((global) => {
|
|
234
414
|
const mapping = labelMap[global.slug];
|
|
235
415
|
if (!mapping) return global;
|
|
416
|
+
const shouldAttachContactFormRedirect = studioEnabled && global.slug === "contact-form";
|
|
417
|
+
const existingViews = global.admin?.components?.views;
|
|
418
|
+
const existingEditViews = existingViews?.edit;
|
|
419
|
+
const hasCustomContactFormEditView = Boolean(
|
|
420
|
+
existingEditViews?.root || existingEditViews?.default && typeof existingEditViews.default === "object" && existingEditViews.default.Component
|
|
421
|
+
);
|
|
422
|
+
const contactFormEditViews = shouldAttachContactFormRedirect && !hasCustomContactFormEditView ? {
|
|
423
|
+
...existingEditViews,
|
|
424
|
+
default: {
|
|
425
|
+
...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
|
|
426
|
+
Component: {
|
|
427
|
+
exportName: "StudioContactFormRedirect",
|
|
428
|
+
path: clientPath,
|
|
429
|
+
clientProps: {
|
|
430
|
+
studioContactFormPath: contactFormStudioPath
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
} : existingEditViews;
|
|
236
435
|
return {
|
|
237
436
|
...global,
|
|
238
437
|
admin: {
|
|
239
438
|
...global.admin,
|
|
240
|
-
group: mapping.group
|
|
439
|
+
group: mapping.group,
|
|
440
|
+
components: {
|
|
441
|
+
...global.admin?.components,
|
|
442
|
+
...shouldAttachContactFormRedirect ? {
|
|
443
|
+
views: {
|
|
444
|
+
...existingViews,
|
|
445
|
+
...contactFormEditViews ? {
|
|
446
|
+
edit: contactFormEditViews
|
|
447
|
+
} : {}
|
|
448
|
+
}
|
|
449
|
+
} : {}
|
|
450
|
+
}
|
|
241
451
|
},
|
|
242
452
|
label: mapping.label
|
|
243
453
|
};
|
|
@@ -306,12 +516,213 @@ function addTooltipToField(field, tooltips) {
|
|
|
306
516
|
return field;
|
|
307
517
|
}
|
|
308
518
|
|
|
519
|
+
// src/admin/fields/headerNav.ts
|
|
520
|
+
var createHeaderNavItemsField = () => ({
|
|
521
|
+
name: "navItems",
|
|
522
|
+
type: "array",
|
|
523
|
+
labels: { singular: "Navigation Link", plural: "Navigation Links" },
|
|
524
|
+
admin: {
|
|
525
|
+
description: "The links displayed in your website's main navigation menu."
|
|
526
|
+
},
|
|
527
|
+
fields: [
|
|
528
|
+
{
|
|
529
|
+
name: "label",
|
|
530
|
+
type: "text",
|
|
531
|
+
required: true,
|
|
532
|
+
admin: {
|
|
533
|
+
description: "The text shown for this navigation link."
|
|
534
|
+
}
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
name: "href",
|
|
538
|
+
type: "text",
|
|
539
|
+
required: true,
|
|
540
|
+
admin: {
|
|
541
|
+
description: 'The URL this link points to (e.g., "/about" or "https://example.com").'
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
name: "parentHref",
|
|
546
|
+
type: "text",
|
|
547
|
+
admin: {
|
|
548
|
+
description: "Optional parent link URL. If set to another nav item href, this item appears in that dropdown."
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
]
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
// src/shared/socialMedia.ts
|
|
555
|
+
var SOCIAL_MEDIA_PLATFORM_LABELS = {
|
|
556
|
+
facebook: "Facebook",
|
|
557
|
+
instagram: "Instagram",
|
|
558
|
+
x: "X (Twitter)",
|
|
559
|
+
linkedin: "LinkedIn",
|
|
560
|
+
youtube: "YouTube",
|
|
561
|
+
tiktok: "TikTok",
|
|
562
|
+
pinterest: "Pinterest",
|
|
563
|
+
snapchat: "Snapchat"
|
|
564
|
+
};
|
|
565
|
+
var SOCIAL_MEDIA_PLATFORMS = [
|
|
566
|
+
"facebook",
|
|
567
|
+
"instagram",
|
|
568
|
+
"x",
|
|
569
|
+
"linkedin",
|
|
570
|
+
"youtube",
|
|
571
|
+
"tiktok",
|
|
572
|
+
"pinterest",
|
|
573
|
+
"snapchat"
|
|
574
|
+
];
|
|
575
|
+
var SOCIAL_MEDIA_ICON_OPTIONS = {
|
|
576
|
+
facebook: [
|
|
577
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:facebook" },
|
|
578
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:facebook-f" },
|
|
579
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-facebook" },
|
|
580
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:facebook-fill" }
|
|
581
|
+
],
|
|
582
|
+
instagram: [
|
|
583
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:instagram" },
|
|
584
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:instagram" },
|
|
585
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-instagram" },
|
|
586
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:instagram-fill" }
|
|
587
|
+
],
|
|
588
|
+
x: [
|
|
589
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:x" },
|
|
590
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:x-twitter" },
|
|
591
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-x" },
|
|
592
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:twitter-x-fill" }
|
|
593
|
+
],
|
|
594
|
+
linkedin: [
|
|
595
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:linkedin" },
|
|
596
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:linkedin-in" },
|
|
597
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-linkedin" },
|
|
598
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:linkedin-fill" }
|
|
599
|
+
],
|
|
600
|
+
youtube: [
|
|
601
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:youtube" },
|
|
602
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:youtube" },
|
|
603
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-youtube" },
|
|
604
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:youtube-fill" }
|
|
605
|
+
],
|
|
606
|
+
tiktok: [
|
|
607
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:tiktok" },
|
|
608
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:tiktok" },
|
|
609
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-tiktok" },
|
|
610
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:tiktok-fill" }
|
|
611
|
+
],
|
|
612
|
+
pinterest: [
|
|
613
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:pinterest" },
|
|
614
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:pinterest-p" },
|
|
615
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-pinterest" },
|
|
616
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:pinterest-fill" }
|
|
617
|
+
],
|
|
618
|
+
snapchat: [
|
|
619
|
+
{ label: "Simple Icons", library: "simple-icons", value: "simple-icons:snapchat" },
|
|
620
|
+
{ label: "Font Awesome Brands", library: "font-awesome-brands", value: "fa6-brands:snapchat" },
|
|
621
|
+
{ label: "Tabler Brands", library: "tabler-brands", value: "tabler:brand-snapchat" },
|
|
622
|
+
{ label: "Remix Icons", library: "remix-icons", value: "ri:snapchat-fill" }
|
|
623
|
+
]
|
|
624
|
+
};
|
|
625
|
+
var SOCIAL_MEDIA_DEFAULT_ICON_BY_PLATFORM = SOCIAL_MEDIA_PLATFORMS.reduce(
|
|
626
|
+
(acc, platform) => {
|
|
627
|
+
acc[platform] = SOCIAL_MEDIA_ICON_OPTIONS[platform][0].value;
|
|
628
|
+
return acc;
|
|
629
|
+
},
|
|
630
|
+
{}
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
// src/admin/fields/socialMedia.ts
|
|
634
|
+
var DEFAULT_DESCRIPTION = "Add profile URLs and choose one of two icon styles for each platform. Leave a URL blank to hide that profile on your site.";
|
|
635
|
+
function validateOptionalHttpsUrl(value) {
|
|
636
|
+
if (value === null || value === void 0 || value === "") {
|
|
637
|
+
return true;
|
|
638
|
+
}
|
|
639
|
+
if (typeof value !== "string") {
|
|
640
|
+
return "Enter a valid URL.";
|
|
641
|
+
}
|
|
642
|
+
try {
|
|
643
|
+
const url = new URL(value);
|
|
644
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
645
|
+
return "Use an http:// or https:// URL.";
|
|
646
|
+
}
|
|
647
|
+
return true;
|
|
648
|
+
} catch {
|
|
649
|
+
return "Enter a valid URL (for example: https://instagram.com/yourbrand).";
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
function createPlatformField(platform) {
|
|
653
|
+
const platformLabel = SOCIAL_MEDIA_PLATFORM_LABELS[platform];
|
|
654
|
+
const iconOptions = SOCIAL_MEDIA_ICON_OPTIONS[platform].map((option) => ({
|
|
655
|
+
label: option.label,
|
|
656
|
+
value: option.value
|
|
657
|
+
}));
|
|
658
|
+
return {
|
|
659
|
+
name: platform,
|
|
660
|
+
type: "group",
|
|
661
|
+
label: platformLabel,
|
|
662
|
+
fields: [
|
|
663
|
+
{
|
|
664
|
+
name: "url",
|
|
665
|
+
type: "text",
|
|
666
|
+
admin: {
|
|
667
|
+
description: `Full ${platformLabel} profile URL. Leave blank to hide ${platformLabel}.`
|
|
668
|
+
},
|
|
669
|
+
validate: validateOptionalHttpsUrl
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
name: "icon",
|
|
673
|
+
type: "select",
|
|
674
|
+
defaultValue: SOCIAL_MEDIA_DEFAULT_ICON_BY_PLATFORM[platform],
|
|
675
|
+
options: iconOptions,
|
|
676
|
+
admin: {
|
|
677
|
+
description: "Pick which icon style to display for this platform."
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
]
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
var createSocialMediaConnectionsField = (options = {}) => {
|
|
684
|
+
const selectedPlatforms = Array.isArray(options.platforms) && options.platforms.length > 0 ? options.platforms : SOCIAL_MEDIA_PLATFORMS;
|
|
685
|
+
return {
|
|
686
|
+
name: options.name || "profiles",
|
|
687
|
+
type: "group",
|
|
688
|
+
label: options.label || "Social Media Profiles",
|
|
689
|
+
admin: {
|
|
690
|
+
description: options.description || DEFAULT_DESCRIPTION
|
|
691
|
+
},
|
|
692
|
+
fields: selectedPlatforms.map((platform) => createPlatformField(platform))
|
|
693
|
+
};
|
|
694
|
+
};
|
|
695
|
+
var socialMediaConnectionsField = createSocialMediaConnectionsField();
|
|
696
|
+
|
|
697
|
+
// src/admin/globals/socialMedia.ts
|
|
698
|
+
var createSocialMediaGlobal = (options = {}) => ({
|
|
699
|
+
slug: options.slug || "social-media",
|
|
700
|
+
label: "Social Media",
|
|
701
|
+
admin: {
|
|
702
|
+
description: options.description || "Manage social profile links and icon variants used across your website.",
|
|
703
|
+
group: "Site Design"
|
|
704
|
+
},
|
|
705
|
+
fields: [
|
|
706
|
+
createSocialMediaConnectionsField({
|
|
707
|
+
...options.fieldOptions,
|
|
708
|
+
label: "Profiles",
|
|
709
|
+
name: "profiles"
|
|
710
|
+
})
|
|
711
|
+
]
|
|
712
|
+
});
|
|
713
|
+
|
|
309
714
|
// src/admin-app/index.ts
|
|
310
715
|
var admin_app_exports = {};
|
|
311
716
|
__export(admin_app_exports, {
|
|
312
717
|
AdminBreadcrumbs: () => AdminBreadcrumbs,
|
|
313
718
|
AdminPage: () => AdminPage,
|
|
719
|
+
buildAdminPageLinkOptions: () => buildAdminPageLinkOptions,
|
|
720
|
+
buildNestedNavTree: () => buildNestedNavTree,
|
|
721
|
+
getAdminNavRows: () => getAdminNavRows,
|
|
314
722
|
navItemIsActive: () => navItemIsActive,
|
|
723
|
+
normalizeAdminNavInputs: () => normalizeAdminNavInputs,
|
|
724
|
+
normalizeNestedNavItems: () => normalizeNestedNavItems,
|
|
725
|
+
parseAdminHeaderNavFromForm: () => parseAdminHeaderNavFromForm,
|
|
315
726
|
roleCanAccessNav: () => roleCanAccessNav
|
|
316
727
|
});
|
|
317
728
|
|
|
@@ -345,6 +756,161 @@ function AdminPage({ title, description, breadcrumbs, actions, children }) {
|
|
|
345
756
|
] });
|
|
346
757
|
}
|
|
347
758
|
|
|
759
|
+
// src/admin-app/nestedNavigation.ts
|
|
760
|
+
var normalizeNestedNavItems = (items) => {
|
|
761
|
+
const deduped = [];
|
|
762
|
+
const seen = /* @__PURE__ */ new Set();
|
|
763
|
+
for (const item of items) {
|
|
764
|
+
const href = typeof item.href === "string" ? item.href.trim() : "";
|
|
765
|
+
const label = typeof item.label === "string" ? item.label.trim() : "";
|
|
766
|
+
const parentHref = typeof item.parentHref === "string" ? item.parentHref.trim() : "";
|
|
767
|
+
if (!href || !label || seen.has(href)) {
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
seen.add(href);
|
|
771
|
+
deduped.push({
|
|
772
|
+
href,
|
|
773
|
+
label,
|
|
774
|
+
...parentHref ? { parentHref } : {}
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
const hrefs = new Set(deduped.map((item) => item.href));
|
|
778
|
+
return deduped.map((item) => ({
|
|
779
|
+
href: item.href,
|
|
780
|
+
label: item.label,
|
|
781
|
+
...item.parentHref && item.parentHref !== item.href && hrefs.has(item.parentHref) ? { parentHref: item.parentHref } : {}
|
|
782
|
+
}));
|
|
783
|
+
};
|
|
784
|
+
var buildNestedNavTree = (items) => {
|
|
785
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
786
|
+
const topLevel = [];
|
|
787
|
+
for (const item of items) {
|
|
788
|
+
if (!item.parentHref) {
|
|
789
|
+
topLevel.push(item);
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
const children = childrenByParent.get(item.parentHref) || [];
|
|
793
|
+
children.push(item);
|
|
794
|
+
childrenByParent.set(item.parentHref, children);
|
|
795
|
+
}
|
|
796
|
+
if (topLevel.length === 0 && items.length > 0) {
|
|
797
|
+
return {
|
|
798
|
+
topLevel: items.map((item) => ({ href: item.href, label: item.label })),
|
|
799
|
+
childrenByParent: /* @__PURE__ */ new Map()
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
return { childrenByParent, topLevel };
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
// src/admin-app/navigationLinks.ts
|
|
806
|
+
var fallbackHomeOption = {
|
|
807
|
+
href: "/",
|
|
808
|
+
label: "Home",
|
|
809
|
+
title: "Home"
|
|
810
|
+
};
|
|
811
|
+
var buildAdminPageLinkOptions = (pages) => {
|
|
812
|
+
const options = pages.map((page) => {
|
|
813
|
+
const href = typeof page.path === "string" ? page.path.trim() : "";
|
|
814
|
+
const title = typeof page.title === "string" && page.title.trim().length > 0 ? page.title.trim() : "Untitled Page";
|
|
815
|
+
if (!href) {
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
818
|
+
const depth = href === "/" ? 0 : href.split("/").filter(Boolean).length;
|
|
819
|
+
const indentLevel = Math.max(depth - 1, 0);
|
|
820
|
+
const indent = indentLevel > 0 ? `${"\u21B3 ".repeat(indentLevel)}` : "";
|
|
821
|
+
return {
|
|
822
|
+
href,
|
|
823
|
+
label: `${indent}${title}`,
|
|
824
|
+
title
|
|
825
|
+
};
|
|
826
|
+
}).filter((option) => option !== null).sort((a, b) => {
|
|
827
|
+
if (a.href === "/" && b.href !== "/") return -1;
|
|
828
|
+
if (b.href === "/" && a.href !== "/") return 1;
|
|
829
|
+
return a.href.localeCompare(b.href);
|
|
830
|
+
});
|
|
831
|
+
if (options.length === 0) {
|
|
832
|
+
return [fallbackHomeOption];
|
|
833
|
+
}
|
|
834
|
+
return options;
|
|
835
|
+
};
|
|
836
|
+
var getAdminNavRows = (navItems, pageOptions, minRows = 6, maxRows = 20) => {
|
|
837
|
+
const preferredRows = Math.max(navItems.length + 2, Math.min(8, pageOptions.length));
|
|
838
|
+
return Math.min(Math.max(minRows, preferredRows), maxRows);
|
|
839
|
+
};
|
|
840
|
+
var normalizeAdminNavInputs = (rows, pageOptions) => {
|
|
841
|
+
const allowedLinks = new Map(pageOptions.map((option) => [option.href, option.title]));
|
|
842
|
+
const deduped = [];
|
|
843
|
+
const seen = /* @__PURE__ */ new Set();
|
|
844
|
+
for (const row of rows) {
|
|
845
|
+
const href = typeof row.href === "string" ? row.href.trim() : "";
|
|
846
|
+
const defaultLabel = allowedLinks.get(href);
|
|
847
|
+
const explicitLabel = typeof row.label === "string" ? row.label.trim() : "";
|
|
848
|
+
const parentHref = typeof row.parentHref === "string" ? row.parentHref.trim() : "";
|
|
849
|
+
if (!href || !defaultLabel || seen.has(href)) {
|
|
850
|
+
continue;
|
|
851
|
+
}
|
|
852
|
+
seen.add(href);
|
|
853
|
+
deduped.push({
|
|
854
|
+
href,
|
|
855
|
+
label: explicitLabel.length > 0 ? explicitLabel : defaultLabel,
|
|
856
|
+
...parentHref.length > 0 ? { parentHref } : {}
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
const hrefs = new Set(deduped.map((item) => item.href));
|
|
860
|
+
const parentByHref = new Map(deduped.map((item) => [item.href, item.parentHref || ""]));
|
|
861
|
+
const createsCycle = (href, parentHref) => {
|
|
862
|
+
const visited = /* @__PURE__ */ new Set([href]);
|
|
863
|
+
let current = parentHref;
|
|
864
|
+
while (current) {
|
|
865
|
+
if (visited.has(current)) {
|
|
866
|
+
return true;
|
|
867
|
+
}
|
|
868
|
+
visited.add(current);
|
|
869
|
+
current = parentByHref.get(current) || "";
|
|
870
|
+
}
|
|
871
|
+
return false;
|
|
872
|
+
};
|
|
873
|
+
return deduped.map((item) => {
|
|
874
|
+
const parentHref = item.parentHref;
|
|
875
|
+
if (!parentHref || parentHref === item.href || !hrefs.has(parentHref) || createsCycle(item.href, parentHref)) {
|
|
876
|
+
return {
|
|
877
|
+
href: item.href,
|
|
878
|
+
label: item.label
|
|
879
|
+
};
|
|
880
|
+
}
|
|
881
|
+
return item;
|
|
882
|
+
});
|
|
883
|
+
};
|
|
884
|
+
var parseAdminHeaderNavFromForm = (formData, pageOptions, maxRows = 24) => {
|
|
885
|
+
const serialized = String(formData.get("navItemsState") || "").trim();
|
|
886
|
+
if (serialized.length > 0) {
|
|
887
|
+
try {
|
|
888
|
+
const parsed = JSON.parse(serialized);
|
|
889
|
+
if (Array.isArray(parsed)) {
|
|
890
|
+
return normalizeAdminNavInputs(parsed.slice(0, maxRows), pageOptions);
|
|
891
|
+
}
|
|
892
|
+
} catch {
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
const rawCount = Number(String(formData.get("navCount") || "0"));
|
|
896
|
+
const navCount = Number.isFinite(rawCount) ? Math.max(0, Math.min(rawCount, maxRows)) : 0;
|
|
897
|
+
const navRows = [];
|
|
898
|
+
for (let index = 0; index < navCount; index += 1) {
|
|
899
|
+
const href = String(formData.get(`navPage_${index}`) || "").trim();
|
|
900
|
+
const label = String(formData.get(`navLabel_${index}`) || "").trim();
|
|
901
|
+
const parentHref = String(formData.get(`navParentHref_${index}`) || "").trim();
|
|
902
|
+
navRows.push({
|
|
903
|
+
href,
|
|
904
|
+
label,
|
|
905
|
+
parentHref
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
if (navRows.length > 0) {
|
|
909
|
+
return normalizeAdminNavInputs(navRows, pageOptions);
|
|
910
|
+
}
|
|
911
|
+
return [];
|
|
912
|
+
};
|
|
913
|
+
|
|
348
914
|
// src/admin-app/routeRegistry.ts
|
|
349
915
|
var roleCanAccessNav = (role, item) => {
|
|
350
916
|
if (!item.roles || item.roles.length === 0) {
|
|
@@ -398,189 +964,315 @@ var sectionStyleDefaults = {
|
|
|
398
964
|
contentGradientAngle: "135",
|
|
399
965
|
contentGradientFrom: "#ffffff",
|
|
400
966
|
contentGradientPreset: "none",
|
|
401
|
-
contentGradientTo: "#
|
|
967
|
+
contentGradientTo: "#f4f6f8",
|
|
402
968
|
contentWidth: "inherit",
|
|
969
|
+
sectionPaddingX: "inherit",
|
|
403
970
|
sectionBackgroundColor: "#ffffff",
|
|
404
971
|
sectionBackgroundMode: "none",
|
|
405
972
|
sectionGradientAngle: "135",
|
|
406
|
-
sectionGradientFrom: "#
|
|
407
|
-
sectionGradientPreset: "
|
|
408
|
-
sectionGradientTo: "#
|
|
973
|
+
sectionGradientFrom: "#334b63",
|
|
974
|
+
sectionGradientPreset: "slate",
|
|
975
|
+
sectionGradientTo: "#496582",
|
|
409
976
|
sectionPaddingY: "md",
|
|
410
977
|
sectionWidth: "content"
|
|
411
978
|
};
|
|
412
|
-
var
|
|
413
|
-
|
|
414
|
-
name: "sectionWidth",
|
|
415
|
-
type: "select",
|
|
416
|
-
defaultValue: sectionStyleDefaults.sectionWidth,
|
|
417
|
-
options: [
|
|
418
|
-
{ label: "Content", value: "content" },
|
|
419
|
-
{ label: "Wide", value: "wide" },
|
|
420
|
-
{ label: "Full", value: "full" }
|
|
421
|
-
]
|
|
422
|
-
},
|
|
423
|
-
{
|
|
424
|
-
name: "contentWidth",
|
|
425
|
-
type: "select",
|
|
426
|
-
defaultValue: sectionStyleDefaults.contentWidth,
|
|
427
|
-
options: [
|
|
428
|
-
{ label: "Inherit", value: "inherit" },
|
|
429
|
-
{ label: "Narrow", value: "narrow" },
|
|
430
|
-
{ label: "Content", value: "content" },
|
|
431
|
-
{ label: "Wide", value: "wide" },
|
|
432
|
-
{ label: "Full", value: "full" }
|
|
433
|
-
]
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
name: "sectionPaddingY",
|
|
437
|
-
type: "select",
|
|
438
|
-
defaultValue: sectionStyleDefaults.sectionPaddingY,
|
|
439
|
-
options: [
|
|
440
|
-
{ label: "Small", value: "sm" },
|
|
441
|
-
{ label: "Medium", value: "md" },
|
|
442
|
-
{ label: "Large", value: "lg" }
|
|
443
|
-
]
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
name: "sectionBackgroundMode",
|
|
447
|
-
type: "select",
|
|
448
|
-
defaultValue: sectionStyleDefaults.sectionBackgroundMode,
|
|
449
|
-
options: [
|
|
450
|
-
{ label: "None", value: "none" },
|
|
451
|
-
{ label: "Color", value: "color" },
|
|
452
|
-
{ label: "Gradient", value: "gradient" }
|
|
453
|
-
]
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
name: "sectionBackgroundColor",
|
|
457
|
-
type: "text",
|
|
458
|
-
defaultValue: sectionStyleDefaults.sectionBackgroundColor
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
name: "sectionGradientPreset",
|
|
462
|
-
type: "select",
|
|
463
|
-
defaultValue: sectionStyleDefaults.sectionGradientPreset,
|
|
464
|
-
options: [
|
|
465
|
-
{ label: "None", value: "none" },
|
|
466
|
-
{ label: "Forest", value: "forest" },
|
|
467
|
-
{ label: "Moss", value: "moss" },
|
|
468
|
-
{ label: "Cream", value: "cream" },
|
|
469
|
-
{ label: "Slate", value: "slate" }
|
|
470
|
-
]
|
|
471
|
-
},
|
|
472
|
-
{
|
|
473
|
-
name: "sectionGradientFrom",
|
|
474
|
-
type: "text",
|
|
475
|
-
defaultValue: sectionStyleDefaults.sectionGradientFrom
|
|
476
|
-
},
|
|
477
|
-
{
|
|
478
|
-
name: "sectionGradientTo",
|
|
479
|
-
type: "text",
|
|
480
|
-
defaultValue: sectionStyleDefaults.sectionGradientTo
|
|
481
|
-
},
|
|
482
|
-
{
|
|
483
|
-
name: "sectionGradientAngle",
|
|
484
|
-
type: "text",
|
|
485
|
-
defaultValue: sectionStyleDefaults.sectionGradientAngle
|
|
486
|
-
},
|
|
487
|
-
{
|
|
488
|
-
name: "contentBackgroundMode",
|
|
489
|
-
type: "select",
|
|
490
|
-
defaultValue: sectionStyleDefaults.contentBackgroundMode,
|
|
491
|
-
options: [
|
|
492
|
-
{ label: "None", value: "none" },
|
|
493
|
-
{ label: "Color", value: "color" },
|
|
494
|
-
{ label: "Gradient", value: "gradient" }
|
|
495
|
-
]
|
|
496
|
-
},
|
|
497
|
-
{
|
|
498
|
-
name: "contentBackgroundColor",
|
|
499
|
-
type: "text",
|
|
500
|
-
defaultValue: sectionStyleDefaults.contentBackgroundColor
|
|
501
|
-
},
|
|
502
|
-
{
|
|
503
|
-
name: "contentGradientPreset",
|
|
504
|
-
type: "select",
|
|
505
|
-
defaultValue: sectionStyleDefaults.contentGradientPreset,
|
|
506
|
-
options: [
|
|
507
|
-
{ label: "None", value: "none" },
|
|
508
|
-
{ label: "Cloud", value: "cloud" },
|
|
509
|
-
{ label: "Sand", value: "sand" },
|
|
510
|
-
{ label: "Mint", value: "mint" },
|
|
511
|
-
{ label: "Night", value: "night" }
|
|
512
|
-
]
|
|
513
|
-
},
|
|
514
|
-
{
|
|
515
|
-
name: "contentGradientFrom",
|
|
516
|
-
type: "text",
|
|
517
|
-
defaultValue: sectionStyleDefaults.contentGradientFrom
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
name: "contentGradientTo",
|
|
521
|
-
type: "text",
|
|
522
|
-
defaultValue: sectionStyleDefaults.contentGradientTo
|
|
523
|
-
},
|
|
524
|
-
{
|
|
525
|
-
name: "contentGradientAngle",
|
|
526
|
-
type: "text",
|
|
527
|
-
defaultValue: sectionStyleDefaults.contentGradientAngle
|
|
528
|
-
}
|
|
529
|
-
];
|
|
530
|
-
|
|
531
|
-
// src/blocks/blocks/BeforeAfter.ts
|
|
532
|
-
var BeforeAfterBlock = {
|
|
533
|
-
slug: "beforeAfter",
|
|
534
|
-
imageURL: "/images/project-before-2.svg",
|
|
535
|
-
imageAltText: "Before and after section preview",
|
|
979
|
+
var hideFromCMS = (field) => ({
|
|
980
|
+
...field,
|
|
536
981
|
admin: {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
plural: "Before / After"
|
|
544
|
-
},
|
|
545
|
-
fields: [
|
|
982
|
+
...field.admin || {},
|
|
983
|
+
hidden: true
|
|
984
|
+
}
|
|
985
|
+
});
|
|
986
|
+
var sectionStyleFields = () => {
|
|
987
|
+
const fields = [
|
|
546
988
|
{
|
|
547
|
-
name: "
|
|
548
|
-
type: "
|
|
549
|
-
|
|
989
|
+
name: "sectionWidth",
|
|
990
|
+
type: "select",
|
|
991
|
+
defaultValue: sectionStyleDefaults.sectionWidth,
|
|
992
|
+
options: [
|
|
993
|
+
{ label: "Content", value: "content" },
|
|
994
|
+
{ label: "Wide", value: "wide" },
|
|
995
|
+
{ label: "Full", value: "full" }
|
|
996
|
+
]
|
|
550
997
|
},
|
|
551
998
|
{
|
|
552
|
-
name: "
|
|
553
|
-
type: "
|
|
999
|
+
name: "contentWidth",
|
|
1000
|
+
type: "select",
|
|
1001
|
+
defaultValue: sectionStyleDefaults.contentWidth,
|
|
1002
|
+
options: [
|
|
1003
|
+
{ label: "Inherit", value: "inherit" },
|
|
1004
|
+
{ label: "Narrow", value: "narrow" },
|
|
1005
|
+
{ label: "Content", value: "content" },
|
|
1006
|
+
{ label: "Wide", value: "wide" },
|
|
1007
|
+
{ label: "Full", value: "full" }
|
|
1008
|
+
]
|
|
554
1009
|
},
|
|
555
1010
|
{
|
|
556
|
-
name: "
|
|
557
|
-
type: "
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
{
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
1011
|
+
name: "sectionPaddingY",
|
|
1012
|
+
type: "select",
|
|
1013
|
+
defaultValue: sectionStyleDefaults.sectionPaddingY,
|
|
1014
|
+
options: [
|
|
1015
|
+
{ label: "None", value: "none" },
|
|
1016
|
+
{ label: "Small", value: "sm" },
|
|
1017
|
+
{ label: "Medium", value: "md" },
|
|
1018
|
+
{ label: "Large", value: "lg" }
|
|
1019
|
+
]
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
name: "sectionPaddingX",
|
|
1023
|
+
type: "select",
|
|
1024
|
+
defaultValue: sectionStyleDefaults.sectionPaddingX,
|
|
1025
|
+
options: [
|
|
1026
|
+
{ label: "Inherit", value: "inherit" },
|
|
1027
|
+
{ label: "None", value: "none" },
|
|
1028
|
+
{ label: "Small", value: "sm" },
|
|
1029
|
+
{ label: "Medium", value: "md" },
|
|
1030
|
+
{ label: "Large", value: "lg" }
|
|
1031
|
+
]
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
name: "sectionBackgroundMode",
|
|
1035
|
+
type: "select",
|
|
1036
|
+
defaultValue: sectionStyleDefaults.sectionBackgroundMode,
|
|
1037
|
+
options: [
|
|
1038
|
+
{ label: "None", value: "none" },
|
|
1039
|
+
{ label: "Color", value: "color" },
|
|
1040
|
+
{ label: "Gradient", value: "gradient" }
|
|
1041
|
+
]
|
|
1042
|
+
},
|
|
1043
|
+
{
|
|
1044
|
+
name: "sectionBackgroundColor",
|
|
1045
|
+
type: "text",
|
|
1046
|
+
defaultValue: sectionStyleDefaults.sectionBackgroundColor
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
name: "sectionGradientPreset",
|
|
1050
|
+
type: "select",
|
|
1051
|
+
defaultValue: sectionStyleDefaults.sectionGradientPreset,
|
|
1052
|
+
options: [
|
|
1053
|
+
{ label: "None", value: "none" },
|
|
1054
|
+
{ label: "Brand", value: "brand" },
|
|
1055
|
+
{ label: "Forest", value: "forest" },
|
|
1056
|
+
{ label: "Moss", value: "moss" },
|
|
1057
|
+
{ label: "Cream", value: "cream" },
|
|
1058
|
+
{ label: "Slate", value: "slate" }
|
|
1059
|
+
]
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
name: "sectionGradientFrom",
|
|
1063
|
+
type: "text",
|
|
1064
|
+
defaultValue: sectionStyleDefaults.sectionGradientFrom
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
name: "sectionGradientTo",
|
|
1068
|
+
type: "text",
|
|
1069
|
+
defaultValue: sectionStyleDefaults.sectionGradientTo
|
|
1070
|
+
},
|
|
1071
|
+
{
|
|
1072
|
+
name: "sectionGradientAngle",
|
|
1073
|
+
type: "text",
|
|
1074
|
+
defaultValue: sectionStyleDefaults.sectionGradientAngle
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
name: "contentBackgroundMode",
|
|
1078
|
+
type: "select",
|
|
1079
|
+
defaultValue: sectionStyleDefaults.contentBackgroundMode,
|
|
1080
|
+
options: [
|
|
1081
|
+
{ label: "None", value: "none" },
|
|
1082
|
+
{ label: "Color", value: "color" },
|
|
1083
|
+
{ label: "Gradient", value: "gradient" }
|
|
1084
|
+
]
|
|
1085
|
+
},
|
|
1086
|
+
{
|
|
1087
|
+
name: "contentBackgroundColor",
|
|
1088
|
+
type: "text",
|
|
1089
|
+
defaultValue: sectionStyleDefaults.contentBackgroundColor
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
name: "contentGradientPreset",
|
|
1093
|
+
type: "select",
|
|
1094
|
+
defaultValue: sectionStyleDefaults.contentGradientPreset,
|
|
1095
|
+
options: [
|
|
1096
|
+
{ label: "None", value: "none" },
|
|
1097
|
+
{ label: "Cloud", value: "cloud" },
|
|
1098
|
+
{ label: "Sand", value: "sand" },
|
|
1099
|
+
{ label: "Mint", value: "mint" },
|
|
1100
|
+
{ label: "Night", value: "night" }
|
|
1101
|
+
]
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
name: "contentGradientFrom",
|
|
1105
|
+
type: "text",
|
|
1106
|
+
defaultValue: sectionStyleDefaults.contentGradientFrom
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
name: "contentGradientTo",
|
|
1110
|
+
type: "text",
|
|
1111
|
+
defaultValue: sectionStyleDefaults.contentGradientTo
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
name: "contentGradientAngle",
|
|
1115
|
+
type: "text",
|
|
1116
|
+
defaultValue: sectionStyleDefaults.contentGradientAngle
|
|
1117
|
+
}
|
|
1118
|
+
];
|
|
1119
|
+
return fields.map(hideFromCMS);
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
// src/blocks/blocks/BeforeAfter.ts
|
|
1123
|
+
var BeforeAfterBlock = {
|
|
1124
|
+
slug: "beforeAfter",
|
|
1125
|
+
imageURL: "/images/project-before-2.svg",
|
|
1126
|
+
imageAltText: "Before and after section preview",
|
|
1127
|
+
admin: {
|
|
1128
|
+
components: {
|
|
1129
|
+
Label: builderBlockLabelComponent
|
|
1130
|
+
}
|
|
1131
|
+
},
|
|
1132
|
+
labels: {
|
|
1133
|
+
singular: "Before / After",
|
|
1134
|
+
plural: "Before / After"
|
|
1135
|
+
},
|
|
1136
|
+
fields: [
|
|
1137
|
+
{
|
|
1138
|
+
name: "title",
|
|
1139
|
+
type: "text",
|
|
1140
|
+
required: true
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
name: "subtitle",
|
|
1144
|
+
type: "textarea"
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
name: "itemsPerRow",
|
|
1148
|
+
type: "number",
|
|
1149
|
+
defaultValue: 2,
|
|
1150
|
+
min: 1,
|
|
1151
|
+
max: 4,
|
|
1152
|
+
admin: {
|
|
1153
|
+
description: "How many project cards to show per row on desktop.",
|
|
1154
|
+
step: 1
|
|
1155
|
+
}
|
|
1156
|
+
},
|
|
1157
|
+
{
|
|
1158
|
+
name: "items",
|
|
1159
|
+
type: "array",
|
|
1160
|
+
minRows: 1,
|
|
1161
|
+
maxRows: 30,
|
|
1162
|
+
fields: [
|
|
1163
|
+
{
|
|
1164
|
+
name: "label",
|
|
1165
|
+
type: "text",
|
|
1166
|
+
required: true
|
|
1167
|
+
},
|
|
1168
|
+
{
|
|
567
1169
|
name: "beforeMedia",
|
|
568
1170
|
type: "upload",
|
|
569
1171
|
relationTo: "media",
|
|
570
1172
|
required: false
|
|
571
1173
|
},
|
|
1174
|
+
{
|
|
1175
|
+
name: "beforeImageURL",
|
|
1176
|
+
type: "text",
|
|
1177
|
+
admin: {
|
|
1178
|
+
description: "Optional direct URL for the before image when using an external asset."
|
|
1179
|
+
}
|
|
1180
|
+
},
|
|
572
1181
|
{
|
|
573
1182
|
name: "afterMedia",
|
|
574
1183
|
type: "upload",
|
|
575
1184
|
relationTo: "media",
|
|
576
1185
|
required: false
|
|
577
1186
|
},
|
|
1187
|
+
{
|
|
1188
|
+
name: "afterImageURL",
|
|
1189
|
+
type: "text",
|
|
1190
|
+
admin: {
|
|
1191
|
+
description: "Optional direct URL for the after image when using an external asset."
|
|
1192
|
+
}
|
|
1193
|
+
},
|
|
1194
|
+
{
|
|
1195
|
+
name: "imageHeight",
|
|
1196
|
+
type: "number",
|
|
1197
|
+
defaultValue: 160,
|
|
1198
|
+
min: 60,
|
|
1199
|
+
max: 600,
|
|
1200
|
+
admin: {
|
|
1201
|
+
description: "Overrides the before/after image height (in pixels).",
|
|
1202
|
+
step: 10
|
|
1203
|
+
}
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
name: "imageFit",
|
|
1207
|
+
type: "select",
|
|
1208
|
+
defaultValue: "cover",
|
|
1209
|
+
options: [
|
|
1210
|
+
{ label: "Cover", value: "cover" },
|
|
1211
|
+
{ label: "Contain", value: "contain" }
|
|
1212
|
+
]
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
name: "imageCornerStyle",
|
|
1216
|
+
type: "select",
|
|
1217
|
+
defaultValue: "rounded",
|
|
1218
|
+
options: [
|
|
1219
|
+
{ label: "Rounded", value: "rounded" },
|
|
1220
|
+
{ label: "Square", value: "square" }
|
|
1221
|
+
]
|
|
1222
|
+
},
|
|
1223
|
+
{
|
|
1224
|
+
name: "imagePosition",
|
|
1225
|
+
type: "select",
|
|
1226
|
+
defaultValue: "center",
|
|
1227
|
+
options: [
|
|
1228
|
+
{ label: "Center", value: "center" },
|
|
1229
|
+
{ label: "Top", value: "top" },
|
|
1230
|
+
{ label: "Bottom", value: "bottom" },
|
|
1231
|
+
{ label: "Left", value: "left" },
|
|
1232
|
+
{ label: "Right", value: "right" }
|
|
1233
|
+
]
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
name: "imagePositionX",
|
|
1237
|
+
type: "number",
|
|
1238
|
+
min: 0,
|
|
1239
|
+
max: 100,
|
|
1240
|
+
admin: {
|
|
1241
|
+
description: "Optional custom horizontal focus (0-100). Overrides Image Position when set.",
|
|
1242
|
+
step: 1
|
|
1243
|
+
}
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
name: "imagePositionY",
|
|
1247
|
+
type: "number",
|
|
1248
|
+
min: 0,
|
|
1249
|
+
max: 100,
|
|
1250
|
+
admin: {
|
|
1251
|
+
description: "Optional custom vertical focus (0-100). Overrides Image Position when set.",
|
|
1252
|
+
step: 1
|
|
1253
|
+
}
|
|
1254
|
+
},
|
|
578
1255
|
{
|
|
579
1256
|
name: "description",
|
|
580
1257
|
type: "textarea"
|
|
1258
|
+
},
|
|
1259
|
+
{
|
|
1260
|
+
name: "settings",
|
|
1261
|
+
type: "json",
|
|
1262
|
+
admin: {
|
|
1263
|
+
hidden: true
|
|
1264
|
+
}
|
|
581
1265
|
}
|
|
582
1266
|
]
|
|
583
1267
|
},
|
|
1268
|
+
{
|
|
1269
|
+
name: "settings",
|
|
1270
|
+
type: "json",
|
|
1271
|
+
admin: {
|
|
1272
|
+
description: "Internal builder settings schema v2.",
|
|
1273
|
+
hidden: true
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
584
1276
|
...sectionStyleFields()
|
|
585
1277
|
]
|
|
586
1278
|
};
|
|
@@ -618,6 +1310,14 @@ var BookingEmbedBlock = {
|
|
|
618
1310
|
type: "text",
|
|
619
1311
|
defaultValue: "/contact"
|
|
620
1312
|
},
|
|
1313
|
+
{
|
|
1314
|
+
name: "settings",
|
|
1315
|
+
type: "json",
|
|
1316
|
+
admin: {
|
|
1317
|
+
description: "Internal builder settings schema v2.",
|
|
1318
|
+
hidden: true
|
|
1319
|
+
}
|
|
1320
|
+
},
|
|
621
1321
|
...sectionStyleFields()
|
|
622
1322
|
]
|
|
623
1323
|
};
|
|
@@ -646,6 +1346,10 @@ var CtaBlock = {
|
|
|
646
1346
|
name: "description",
|
|
647
1347
|
type: "textarea"
|
|
648
1348
|
},
|
|
1349
|
+
{
|
|
1350
|
+
name: "eyebrow",
|
|
1351
|
+
type: "text"
|
|
1352
|
+
},
|
|
649
1353
|
{
|
|
650
1354
|
name: "buttonLabel",
|
|
651
1355
|
type: "text"
|
|
@@ -676,7 +1380,39 @@ var CtaBlock = {
|
|
|
676
1380
|
name: "backgroundColor",
|
|
677
1381
|
type: "text",
|
|
678
1382
|
admin: {
|
|
679
|
-
description: "Optional background color override for the CTA strip (example: #
|
|
1383
|
+
description: "Optional background color override for the CTA strip (example: #334b63)."
|
|
1384
|
+
}
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
name: "media",
|
|
1388
|
+
type: "upload",
|
|
1389
|
+
relationTo: "media",
|
|
1390
|
+
required: false
|
|
1391
|
+
},
|
|
1392
|
+
{
|
|
1393
|
+
name: "imageURL",
|
|
1394
|
+
type: "text",
|
|
1395
|
+
admin: {
|
|
1396
|
+
description: "Optional direct image URL when this CTA should use an external image."
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
name: "bullets",
|
|
1401
|
+
type: "array",
|
|
1402
|
+
fields: [
|
|
1403
|
+
{
|
|
1404
|
+
name: "label",
|
|
1405
|
+
type: "text",
|
|
1406
|
+
required: true
|
|
1407
|
+
}
|
|
1408
|
+
]
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
name: "settings",
|
|
1412
|
+
type: "json",
|
|
1413
|
+
admin: {
|
|
1414
|
+
description: "Internal builder settings schema v2.",
|
|
1415
|
+
hidden: true
|
|
680
1416
|
}
|
|
681
1417
|
},
|
|
682
1418
|
...sectionStyleFields()
|
|
@@ -698,6 +1434,10 @@ var FaqBlock = {
|
|
|
698
1434
|
plural: "FAQs"
|
|
699
1435
|
},
|
|
700
1436
|
fields: [
|
|
1437
|
+
{
|
|
1438
|
+
name: "eyebrow",
|
|
1439
|
+
type: "text"
|
|
1440
|
+
},
|
|
701
1441
|
{
|
|
702
1442
|
name: "title",
|
|
703
1443
|
type: "text",
|
|
@@ -718,9 +1458,24 @@ var FaqBlock = {
|
|
|
718
1458
|
name: "answer",
|
|
719
1459
|
type: "textarea",
|
|
720
1460
|
required: true
|
|
1461
|
+
},
|
|
1462
|
+
{
|
|
1463
|
+
name: "settings",
|
|
1464
|
+
type: "json",
|
|
1465
|
+
admin: {
|
|
1466
|
+
hidden: true
|
|
1467
|
+
}
|
|
721
1468
|
}
|
|
722
1469
|
]
|
|
723
1470
|
},
|
|
1471
|
+
{
|
|
1472
|
+
name: "settings",
|
|
1473
|
+
type: "json",
|
|
1474
|
+
admin: {
|
|
1475
|
+
description: "Internal builder settings schema v2.",
|
|
1476
|
+
hidden: true
|
|
1477
|
+
}
|
|
1478
|
+
},
|
|
724
1479
|
...sectionStyleFields()
|
|
725
1480
|
]
|
|
726
1481
|
};
|
|
@@ -740,10 +1495,28 @@ var FeatureGridBlock = {
|
|
|
740
1495
|
plural: "Feature Grids"
|
|
741
1496
|
},
|
|
742
1497
|
fields: [
|
|
1498
|
+
{
|
|
1499
|
+
name: "eyebrow",
|
|
1500
|
+
type: "text"
|
|
1501
|
+
},
|
|
743
1502
|
{
|
|
744
1503
|
name: "title",
|
|
745
|
-
type: "text"
|
|
746
|
-
|
|
1504
|
+
type: "text"
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
name: "subtitle",
|
|
1508
|
+
type: "textarea"
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
name: "itemsPerRow",
|
|
1512
|
+
type: "number",
|
|
1513
|
+
defaultValue: 3,
|
|
1514
|
+
min: 1,
|
|
1515
|
+
max: 6,
|
|
1516
|
+
admin: {
|
|
1517
|
+
description: "How many items to show per row on desktop.",
|
|
1518
|
+
step: 1
|
|
1519
|
+
}
|
|
747
1520
|
},
|
|
748
1521
|
{
|
|
749
1522
|
name: "items",
|
|
@@ -760,11 +1533,53 @@ var FeatureGridBlock = {
|
|
|
760
1533
|
name: "description",
|
|
761
1534
|
type: "textarea"
|
|
762
1535
|
},
|
|
1536
|
+
{
|
|
1537
|
+
name: "tone",
|
|
1538
|
+
type: "select",
|
|
1539
|
+
defaultValue: "warm",
|
|
1540
|
+
options: [
|
|
1541
|
+
{ label: "Warm", value: "warm" },
|
|
1542
|
+
{ label: "Cool", value: "cool" },
|
|
1543
|
+
{ label: "Neutral", value: "neutral" }
|
|
1544
|
+
]
|
|
1545
|
+
},
|
|
1546
|
+
{
|
|
1547
|
+
name: "iconType",
|
|
1548
|
+
type: "select",
|
|
1549
|
+
defaultValue: "badge",
|
|
1550
|
+
options: [
|
|
1551
|
+
{ label: "Badge Text", value: "badge" },
|
|
1552
|
+
{ label: "Icon", value: "lucide" }
|
|
1553
|
+
],
|
|
1554
|
+
admin: {
|
|
1555
|
+
description: "Choose whether this item uses a short badge label or an icon."
|
|
1556
|
+
}
|
|
1557
|
+
},
|
|
763
1558
|
{
|
|
764
1559
|
name: "icon",
|
|
765
1560
|
type: "text",
|
|
766
1561
|
admin: {
|
|
767
|
-
description: 'Optional short icon label (e.g. "01", "Leaf", "Star").'
|
|
1562
|
+
description: 'Optional short icon label (e.g. "01", "Leaf", "Star").',
|
|
1563
|
+
condition: (_, siblingData) => siblingData?.iconType !== "lucide"
|
|
1564
|
+
}
|
|
1565
|
+
},
|
|
1566
|
+
{
|
|
1567
|
+
name: "iconLucide",
|
|
1568
|
+
type: "select",
|
|
1569
|
+
options: [
|
|
1570
|
+
{ label: "Shield Check", value: "ShieldCheck" },
|
|
1571
|
+
{ label: "Clock", value: "Clock" },
|
|
1572
|
+
{ label: "Leaf", value: "Leaf" },
|
|
1573
|
+
{ label: "Dollar Sign", value: "DollarSign" },
|
|
1574
|
+
{ label: "Hard Hat", value: "HardHat" },
|
|
1575
|
+
{ label: "Sparkles", value: "Sparkles" },
|
|
1576
|
+
{ label: "Tree Pine", value: "TreePine" },
|
|
1577
|
+
{ label: "Badge Check", value: "BadgeCheck" },
|
|
1578
|
+
{ label: "Calendar Clock", value: "CalendarClock" }
|
|
1579
|
+
],
|
|
1580
|
+
admin: {
|
|
1581
|
+
description: "Select an icon for this item.",
|
|
1582
|
+
condition: (_, siblingData) => siblingData?.iconType === "lucide"
|
|
768
1583
|
}
|
|
769
1584
|
},
|
|
770
1585
|
{
|
|
@@ -772,6 +1587,107 @@ var FeatureGridBlock = {
|
|
|
772
1587
|
type: "upload",
|
|
773
1588
|
relationTo: "media",
|
|
774
1589
|
required: false
|
|
1590
|
+
},
|
|
1591
|
+
{
|
|
1592
|
+
name: "imageURL",
|
|
1593
|
+
type: "text",
|
|
1594
|
+
admin: {
|
|
1595
|
+
description: "Optional direct image URL when this item should use an external image."
|
|
1596
|
+
}
|
|
1597
|
+
},
|
|
1598
|
+
{
|
|
1599
|
+
name: "embedURL",
|
|
1600
|
+
type: "text",
|
|
1601
|
+
admin: {
|
|
1602
|
+
description: "Optional iframe/embed URL for items like maps or other embedded content."
|
|
1603
|
+
}
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
name: "buttonLabel",
|
|
1607
|
+
type: "text"
|
|
1608
|
+
},
|
|
1609
|
+
{
|
|
1610
|
+
name: "buttonHref",
|
|
1611
|
+
type: "text"
|
|
1612
|
+
},
|
|
1613
|
+
{
|
|
1614
|
+
name: "bullets",
|
|
1615
|
+
type: "array",
|
|
1616
|
+
fields: [
|
|
1617
|
+
{
|
|
1618
|
+
name: "label",
|
|
1619
|
+
type: "text",
|
|
1620
|
+
required: true
|
|
1621
|
+
}
|
|
1622
|
+
]
|
|
1623
|
+
},
|
|
1624
|
+
{
|
|
1625
|
+
name: "imageHeight",
|
|
1626
|
+
type: "number",
|
|
1627
|
+
defaultValue: 160,
|
|
1628
|
+
min: 40,
|
|
1629
|
+
max: 600,
|
|
1630
|
+
admin: {
|
|
1631
|
+
description: "Overrides the image height in the builder/section (in pixels).",
|
|
1632
|
+
step: 10
|
|
1633
|
+
}
|
|
1634
|
+
},
|
|
1635
|
+
{
|
|
1636
|
+
name: "imageFit",
|
|
1637
|
+
type: "select",
|
|
1638
|
+
defaultValue: "cover",
|
|
1639
|
+
options: [
|
|
1640
|
+
{ label: "Cover", value: "cover" },
|
|
1641
|
+
{ label: "Contain", value: "contain" }
|
|
1642
|
+
]
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
name: "imageCornerStyle",
|
|
1646
|
+
type: "select",
|
|
1647
|
+
defaultValue: "rounded",
|
|
1648
|
+
options: [
|
|
1649
|
+
{ label: "Rounded", value: "rounded" },
|
|
1650
|
+
{ label: "Square", value: "square" }
|
|
1651
|
+
]
|
|
1652
|
+
},
|
|
1653
|
+
{
|
|
1654
|
+
name: "imagePosition",
|
|
1655
|
+
type: "select",
|
|
1656
|
+
defaultValue: "center",
|
|
1657
|
+
options: [
|
|
1658
|
+
{ label: "Center", value: "center" },
|
|
1659
|
+
{ label: "Top", value: "top" },
|
|
1660
|
+
{ label: "Bottom", value: "bottom" },
|
|
1661
|
+
{ label: "Left", value: "left" },
|
|
1662
|
+
{ label: "Right", value: "right" }
|
|
1663
|
+
]
|
|
1664
|
+
},
|
|
1665
|
+
{
|
|
1666
|
+
name: "imagePositionX",
|
|
1667
|
+
type: "number",
|
|
1668
|
+
min: 0,
|
|
1669
|
+
max: 100,
|
|
1670
|
+
admin: {
|
|
1671
|
+
description: "Optional custom horizontal focus (0-100). Overrides Image Position when set.",
|
|
1672
|
+
step: 1
|
|
1673
|
+
}
|
|
1674
|
+
},
|
|
1675
|
+
{
|
|
1676
|
+
name: "imagePositionY",
|
|
1677
|
+
type: "number",
|
|
1678
|
+
min: 0,
|
|
1679
|
+
max: 100,
|
|
1680
|
+
admin: {
|
|
1681
|
+
description: "Optional custom vertical focus (0-100). Overrides Image Position when set.",
|
|
1682
|
+
step: 1
|
|
1683
|
+
}
|
|
1684
|
+
},
|
|
1685
|
+
{
|
|
1686
|
+
name: "settings",
|
|
1687
|
+
type: "json",
|
|
1688
|
+
admin: {
|
|
1689
|
+
hidden: true
|
|
1690
|
+
}
|
|
775
1691
|
}
|
|
776
1692
|
]
|
|
777
1693
|
},
|
|
@@ -787,6 +1703,22 @@ var FeatureGridBlock = {
|
|
|
787
1703
|
{
|
|
788
1704
|
label: "Highlight",
|
|
789
1705
|
value: "highlight"
|
|
1706
|
+
},
|
|
1707
|
+
{
|
|
1708
|
+
label: "Split List",
|
|
1709
|
+
value: "splitList"
|
|
1710
|
+
},
|
|
1711
|
+
{
|
|
1712
|
+
label: "Panels",
|
|
1713
|
+
value: "panels"
|
|
1714
|
+
},
|
|
1715
|
+
{
|
|
1716
|
+
label: "Catalog",
|
|
1717
|
+
value: "catalog"
|
|
1718
|
+
},
|
|
1719
|
+
{
|
|
1720
|
+
label: "Contact Split",
|
|
1721
|
+
value: "contact"
|
|
790
1722
|
}
|
|
791
1723
|
]
|
|
792
1724
|
},
|
|
@@ -794,7 +1726,15 @@ var FeatureGridBlock = {
|
|
|
794
1726
|
name: "backgroundColor",
|
|
795
1727
|
type: "text",
|
|
796
1728
|
admin: {
|
|
797
|
-
description: "Optional background color override when using the Highlight variant (example: #
|
|
1729
|
+
description: "Optional background color override when using the Highlight variant (example: #334b63)."
|
|
1730
|
+
}
|
|
1731
|
+
},
|
|
1732
|
+
{
|
|
1733
|
+
name: "settings",
|
|
1734
|
+
type: "json",
|
|
1735
|
+
admin: {
|
|
1736
|
+
description: "Internal builder settings schema v2.",
|
|
1737
|
+
hidden: true
|
|
798
1738
|
}
|
|
799
1739
|
},
|
|
800
1740
|
...sectionStyleFields()
|
|
@@ -816,6 +1756,10 @@ var FormEmbedBlock = {
|
|
|
816
1756
|
plural: "Form Embeds"
|
|
817
1757
|
},
|
|
818
1758
|
fields: [
|
|
1759
|
+
{
|
|
1760
|
+
name: "eyebrow",
|
|
1761
|
+
type: "text"
|
|
1762
|
+
},
|
|
819
1763
|
{
|
|
820
1764
|
name: "title",
|
|
821
1765
|
type: "text"
|
|
@@ -824,6 +1768,10 @@ var FormEmbedBlock = {
|
|
|
824
1768
|
name: "description",
|
|
825
1769
|
type: "textarea"
|
|
826
1770
|
},
|
|
1771
|
+
{
|
|
1772
|
+
name: "submitLabel",
|
|
1773
|
+
type: "text"
|
|
1774
|
+
},
|
|
827
1775
|
{
|
|
828
1776
|
name: "formType",
|
|
829
1777
|
type: "select",
|
|
@@ -835,6 +1783,14 @@ var FormEmbedBlock = {
|
|
|
835
1783
|
}
|
|
836
1784
|
]
|
|
837
1785
|
},
|
|
1786
|
+
{
|
|
1787
|
+
name: "settings",
|
|
1788
|
+
type: "json",
|
|
1789
|
+
admin: {
|
|
1790
|
+
description: "Internal builder settings schema v2.",
|
|
1791
|
+
hidden: true
|
|
1792
|
+
}
|
|
1793
|
+
},
|
|
838
1794
|
...sectionStyleFields()
|
|
839
1795
|
]
|
|
840
1796
|
};
|
|
@@ -897,18 +1853,39 @@ var HeroBlock = {
|
|
|
897
1853
|
type: "upload",
|
|
898
1854
|
relationTo: "media"
|
|
899
1855
|
},
|
|
1856
|
+
{
|
|
1857
|
+
name: "backgroundImageURL",
|
|
1858
|
+
type: "text",
|
|
1859
|
+
admin: {
|
|
1860
|
+
description: "Optional direct image URL when the hero should use an external image source."
|
|
1861
|
+
}
|
|
1862
|
+
},
|
|
900
1863
|
{
|
|
901
1864
|
name: "backgroundImageFit",
|
|
902
1865
|
type: "select",
|
|
903
1866
|
defaultValue: "cover",
|
|
904
1867
|
options: [
|
|
905
1868
|
{ label: "Cover", value: "cover" },
|
|
906
|
-
{ label: "
|
|
1869
|
+
{ label: "Cover (Square)", value: "cover-square" },
|
|
1870
|
+
{ label: "Contain", value: "contain" },
|
|
1871
|
+
{ label: "Contain (Square)", value: "contain-square" }
|
|
907
1872
|
],
|
|
908
1873
|
admin: {
|
|
909
1874
|
description: "How the hero image should be sized within the section."
|
|
910
1875
|
}
|
|
911
1876
|
},
|
|
1877
|
+
{
|
|
1878
|
+
name: "backgroundImageCornerStyle",
|
|
1879
|
+
type: "select",
|
|
1880
|
+
defaultValue: "rounded",
|
|
1881
|
+
options: [
|
|
1882
|
+
{ label: "Rounded", value: "rounded" },
|
|
1883
|
+
{ label: "Square", value: "square" }
|
|
1884
|
+
],
|
|
1885
|
+
admin: {
|
|
1886
|
+
description: "How the hero image corners should appear."
|
|
1887
|
+
}
|
|
1888
|
+
},
|
|
912
1889
|
{
|
|
913
1890
|
name: "backgroundImagePosition",
|
|
914
1891
|
type: "select",
|
|
@@ -928,7 +1905,114 @@ var HeroBlock = {
|
|
|
928
1905
|
name: "backgroundColor",
|
|
929
1906
|
type: "text",
|
|
930
1907
|
admin: {
|
|
931
|
-
description: "Optional background color override (example: #
|
|
1908
|
+
description: "Optional background color override (example: #334b63)."
|
|
1909
|
+
}
|
|
1910
|
+
},
|
|
1911
|
+
{
|
|
1912
|
+
name: "backgroundOverlayMode",
|
|
1913
|
+
type: "select",
|
|
1914
|
+
defaultValue: "none",
|
|
1915
|
+
options: [
|
|
1916
|
+
{ label: "None", value: "none" },
|
|
1917
|
+
{ label: "Solid", value: "solid" },
|
|
1918
|
+
{ label: "Gradient", value: "gradient" }
|
|
1919
|
+
],
|
|
1920
|
+
admin: {
|
|
1921
|
+
description: "Optional overlay on top of the hero image (applies when an image is present)."
|
|
1922
|
+
}
|
|
1923
|
+
},
|
|
1924
|
+
{
|
|
1925
|
+
name: "backgroundOverlayOpacity",
|
|
1926
|
+
type: "number",
|
|
1927
|
+
defaultValue: 45,
|
|
1928
|
+
min: 0,
|
|
1929
|
+
max: 100,
|
|
1930
|
+
admin: {
|
|
1931
|
+
description: "Overlay opacity (0-100).",
|
|
1932
|
+
step: 1
|
|
1933
|
+
}
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
name: "backgroundOverlayColor",
|
|
1937
|
+
type: "text",
|
|
1938
|
+
admin: {
|
|
1939
|
+
description: "Overlay solid color (example: #000000). Used when Overlay Mode is Solid."
|
|
1940
|
+
}
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
name: "backgroundOverlayGradientFrom",
|
|
1944
|
+
type: "text",
|
|
1945
|
+
admin: {
|
|
1946
|
+
description: "Gradient overlay start color (example: #334b63). Used when Overlay Mode is Gradient."
|
|
1947
|
+
}
|
|
1948
|
+
},
|
|
1949
|
+
{
|
|
1950
|
+
name: "backgroundOverlayGradientTo",
|
|
1951
|
+
type: "text",
|
|
1952
|
+
admin: {
|
|
1953
|
+
description: "Gradient overlay end color (example: #496582). Used when Overlay Mode is Gradient."
|
|
1954
|
+
}
|
|
1955
|
+
},
|
|
1956
|
+
{
|
|
1957
|
+
name: "backgroundOverlayGradientAngle",
|
|
1958
|
+
type: "text",
|
|
1959
|
+
admin: {
|
|
1960
|
+
description: "Gradient overlay angle in degrees (0-360). Used when Overlay Mode is Gradient."
|
|
1961
|
+
}
|
|
1962
|
+
},
|
|
1963
|
+
{
|
|
1964
|
+
name: "backgroundOverlayGradientFromStrength",
|
|
1965
|
+
type: "number",
|
|
1966
|
+
defaultValue: 100,
|
|
1967
|
+
min: 0,
|
|
1968
|
+
max: 100,
|
|
1969
|
+
admin: {
|
|
1970
|
+
description: "Gradient start strength (0-100). Set to 0 for transparent.",
|
|
1971
|
+
step: 1
|
|
1972
|
+
}
|
|
1973
|
+
},
|
|
1974
|
+
{
|
|
1975
|
+
name: "backgroundOverlayGradientToStrength",
|
|
1976
|
+
type: "number",
|
|
1977
|
+
defaultValue: 100,
|
|
1978
|
+
min: 0,
|
|
1979
|
+
max: 100,
|
|
1980
|
+
admin: {
|
|
1981
|
+
description: "Gradient end strength (0-100). Set to 0 for transparent.",
|
|
1982
|
+
step: 1
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
{
|
|
1986
|
+
name: "backgroundOverlayGradientStart",
|
|
1987
|
+
type: "number",
|
|
1988
|
+
defaultValue: 0,
|
|
1989
|
+
min: 0,
|
|
1990
|
+
max: 100,
|
|
1991
|
+
admin: {
|
|
1992
|
+
description: "Where the gradient starts (0-100).",
|
|
1993
|
+
step: 1
|
|
1994
|
+
}
|
|
1995
|
+
},
|
|
1996
|
+
{
|
|
1997
|
+
name: "backgroundOverlayGradientEnd",
|
|
1998
|
+
type: "number",
|
|
1999
|
+
defaultValue: 100,
|
|
2000
|
+
min: 0,
|
|
2001
|
+
max: 100,
|
|
2002
|
+
admin: {
|
|
2003
|
+
description: "Where the gradient ends (0-100).",
|
|
2004
|
+
step: 1
|
|
2005
|
+
}
|
|
2006
|
+
},
|
|
2007
|
+
{
|
|
2008
|
+
name: "backgroundOverlayGradientFeather",
|
|
2009
|
+
type: "number",
|
|
2010
|
+
defaultValue: 100,
|
|
2011
|
+
min: 0,
|
|
2012
|
+
max: 100,
|
|
2013
|
+
admin: {
|
|
2014
|
+
description: "How soft the transition is (0 = hard edge, 100 = smooth).",
|
|
2015
|
+
step: 1
|
|
932
2016
|
}
|
|
933
2017
|
},
|
|
934
2018
|
{
|
|
@@ -946,6 +2030,36 @@ var HeroBlock = {
|
|
|
946
2030
|
}
|
|
947
2031
|
]
|
|
948
2032
|
},
|
|
2033
|
+
{
|
|
2034
|
+
name: "heroHeight",
|
|
2035
|
+
type: "select",
|
|
2036
|
+
defaultValue: "sm",
|
|
2037
|
+
options: [
|
|
2038
|
+
{
|
|
2039
|
+
label: "Small",
|
|
2040
|
+
value: "sm"
|
|
2041
|
+
},
|
|
2042
|
+
{
|
|
2043
|
+
label: "Medium (Half Screen)",
|
|
2044
|
+
value: "md"
|
|
2045
|
+
},
|
|
2046
|
+
{
|
|
2047
|
+
label: "Full Screen",
|
|
2048
|
+
value: "full"
|
|
2049
|
+
}
|
|
2050
|
+
],
|
|
2051
|
+
admin: {
|
|
2052
|
+
description: "Controls the vertical height of the hero section."
|
|
2053
|
+
}
|
|
2054
|
+
},
|
|
2055
|
+
{
|
|
2056
|
+
name: "settings",
|
|
2057
|
+
type: "json",
|
|
2058
|
+
admin: {
|
|
2059
|
+
description: "Internal builder settings schema v2.",
|
|
2060
|
+
hidden: true
|
|
2061
|
+
}
|
|
2062
|
+
},
|
|
949
2063
|
...sectionStyleFields()
|
|
950
2064
|
]
|
|
951
2065
|
};
|
|
@@ -991,12 +2105,95 @@ var LogoWallBlock = {
|
|
|
991
2105
|
relationTo: "media",
|
|
992
2106
|
required: false
|
|
993
2107
|
},
|
|
2108
|
+
{
|
|
2109
|
+
name: "imageURL",
|
|
2110
|
+
type: "text",
|
|
2111
|
+
admin: {
|
|
2112
|
+
description: "Optional direct image URL for this logo when using an external asset."
|
|
2113
|
+
}
|
|
2114
|
+
},
|
|
2115
|
+
{
|
|
2116
|
+
name: "imageHeight",
|
|
2117
|
+
type: "number",
|
|
2118
|
+
defaultValue: 64,
|
|
2119
|
+
min: 24,
|
|
2120
|
+
max: 200,
|
|
2121
|
+
admin: {
|
|
2122
|
+
description: "Overrides the logo image height (in pixels).",
|
|
2123
|
+
step: 4
|
|
2124
|
+
}
|
|
2125
|
+
},
|
|
2126
|
+
{
|
|
2127
|
+
name: "imageFit",
|
|
2128
|
+
type: "select",
|
|
2129
|
+
defaultValue: "contain",
|
|
2130
|
+
options: [
|
|
2131
|
+
{ label: "Cover", value: "cover" },
|
|
2132
|
+
{ label: "Contain", value: "contain" }
|
|
2133
|
+
]
|
|
2134
|
+
},
|
|
2135
|
+
{
|
|
2136
|
+
name: "imageCornerStyle",
|
|
2137
|
+
type: "select",
|
|
2138
|
+
defaultValue: "rounded",
|
|
2139
|
+
options: [
|
|
2140
|
+
{ label: "Rounded", value: "rounded" },
|
|
2141
|
+
{ label: "Square", value: "square" }
|
|
2142
|
+
]
|
|
2143
|
+
},
|
|
2144
|
+
{
|
|
2145
|
+
name: "imagePosition",
|
|
2146
|
+
type: "select",
|
|
2147
|
+
defaultValue: "center",
|
|
2148
|
+
options: [
|
|
2149
|
+
{ label: "Center", value: "center" },
|
|
2150
|
+
{ label: "Top", value: "top" },
|
|
2151
|
+
{ label: "Bottom", value: "bottom" },
|
|
2152
|
+
{ label: "Left", value: "left" },
|
|
2153
|
+
{ label: "Right", value: "right" }
|
|
2154
|
+
]
|
|
2155
|
+
},
|
|
2156
|
+
{
|
|
2157
|
+
name: "imagePositionX",
|
|
2158
|
+
type: "number",
|
|
2159
|
+
min: 0,
|
|
2160
|
+
max: 100,
|
|
2161
|
+
admin: {
|
|
2162
|
+
description: "Optional custom horizontal focus (0-100). Overrides Image Position when set.",
|
|
2163
|
+
step: 1
|
|
2164
|
+
}
|
|
2165
|
+
},
|
|
2166
|
+
{
|
|
2167
|
+
name: "imagePositionY",
|
|
2168
|
+
type: "number",
|
|
2169
|
+
min: 0,
|
|
2170
|
+
max: 100,
|
|
2171
|
+
admin: {
|
|
2172
|
+
description: "Optional custom vertical focus (0-100). Overrides Image Position when set.",
|
|
2173
|
+
step: 1
|
|
2174
|
+
}
|
|
2175
|
+
},
|
|
994
2176
|
{
|
|
995
2177
|
name: "href",
|
|
996
2178
|
type: "text"
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
name: "settings",
|
|
2182
|
+
type: "json",
|
|
2183
|
+
admin: {
|
|
2184
|
+
hidden: true
|
|
2185
|
+
}
|
|
997
2186
|
}
|
|
998
2187
|
]
|
|
999
2188
|
},
|
|
2189
|
+
{
|
|
2190
|
+
name: "settings",
|
|
2191
|
+
type: "json",
|
|
2192
|
+
admin: {
|
|
2193
|
+
description: "Internal builder settings schema v2.",
|
|
2194
|
+
hidden: true
|
|
2195
|
+
}
|
|
2196
|
+
},
|
|
1000
2197
|
...sectionStyleFields()
|
|
1001
2198
|
]
|
|
1002
2199
|
};
|
|
@@ -1020,7 +2217,14 @@ var MediaBlock = {
|
|
|
1020
2217
|
name: "image",
|
|
1021
2218
|
type: "upload",
|
|
1022
2219
|
relationTo: "media",
|
|
1023
|
-
required:
|
|
2220
|
+
required: false
|
|
2221
|
+
},
|
|
2222
|
+
{
|
|
2223
|
+
name: "imageURL",
|
|
2224
|
+
type: "text",
|
|
2225
|
+
admin: {
|
|
2226
|
+
description: "Optional direct image URL when this section should use an external image."
|
|
2227
|
+
}
|
|
1024
2228
|
},
|
|
1025
2229
|
{
|
|
1026
2230
|
name: "caption",
|
|
@@ -1041,6 +2245,44 @@ var MediaBlock = {
|
|
|
1041
2245
|
}
|
|
1042
2246
|
]
|
|
1043
2247
|
},
|
|
2248
|
+
{
|
|
2249
|
+
name: "imageFit",
|
|
2250
|
+
type: "select",
|
|
2251
|
+
defaultValue: "cover",
|
|
2252
|
+
options: [
|
|
2253
|
+
{ label: "Cover", value: "cover" },
|
|
2254
|
+
{ label: "Contain", value: "contain" }
|
|
2255
|
+
]
|
|
2256
|
+
},
|
|
2257
|
+
{
|
|
2258
|
+
name: "imageCornerStyle",
|
|
2259
|
+
type: "select",
|
|
2260
|
+
defaultValue: "rounded",
|
|
2261
|
+
options: [
|
|
2262
|
+
{ label: "Rounded", value: "rounded" },
|
|
2263
|
+
{ label: "Square", value: "square" }
|
|
2264
|
+
]
|
|
2265
|
+
},
|
|
2266
|
+
{
|
|
2267
|
+
name: "imagePosition",
|
|
2268
|
+
type: "select",
|
|
2269
|
+
defaultValue: "center",
|
|
2270
|
+
options: [
|
|
2271
|
+
{ label: "Center", value: "center" },
|
|
2272
|
+
{ label: "Top", value: "top" },
|
|
2273
|
+
{ label: "Bottom", value: "bottom" },
|
|
2274
|
+
{ label: "Left", value: "left" },
|
|
2275
|
+
{ label: "Right", value: "right" }
|
|
2276
|
+
]
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
name: "settings",
|
|
2280
|
+
type: "json",
|
|
2281
|
+
admin: {
|
|
2282
|
+
description: "Internal builder settings schema v2.",
|
|
2283
|
+
hidden: true
|
|
2284
|
+
}
|
|
2285
|
+
},
|
|
1044
2286
|
...sectionStyleFields()
|
|
1045
2287
|
]
|
|
1046
2288
|
};
|
|
@@ -1060,6 +2302,21 @@ var RichTextBlock = {
|
|
|
1060
2302
|
plural: "Rich Text Sections"
|
|
1061
2303
|
},
|
|
1062
2304
|
fields: [
|
|
2305
|
+
{
|
|
2306
|
+
name: "variant",
|
|
2307
|
+
type: "select",
|
|
2308
|
+
defaultValue: "default",
|
|
2309
|
+
options: [
|
|
2310
|
+
{
|
|
2311
|
+
label: "Default",
|
|
2312
|
+
value: "default"
|
|
2313
|
+
},
|
|
2314
|
+
{
|
|
2315
|
+
label: "Quote Banner",
|
|
2316
|
+
value: "quoteBanner"
|
|
2317
|
+
}
|
|
2318
|
+
]
|
|
2319
|
+
},
|
|
1063
2320
|
{
|
|
1064
2321
|
name: "title",
|
|
1065
2322
|
type: "text"
|
|
@@ -1069,6 +2326,54 @@ var RichTextBlock = {
|
|
|
1069
2326
|
type: "richText",
|
|
1070
2327
|
required: true
|
|
1071
2328
|
},
|
|
2329
|
+
{
|
|
2330
|
+
name: "statsItems",
|
|
2331
|
+
type: "array",
|
|
2332
|
+
fields: [
|
|
2333
|
+
{
|
|
2334
|
+
name: "value",
|
|
2335
|
+
type: "text",
|
|
2336
|
+
required: true
|
|
2337
|
+
},
|
|
2338
|
+
{
|
|
2339
|
+
name: "label",
|
|
2340
|
+
type: "text",
|
|
2341
|
+
required: true
|
|
2342
|
+
}
|
|
2343
|
+
]
|
|
2344
|
+
},
|
|
2345
|
+
{
|
|
2346
|
+
name: "cards",
|
|
2347
|
+
type: "array",
|
|
2348
|
+
fields: [
|
|
2349
|
+
{
|
|
2350
|
+
name: "eyebrow",
|
|
2351
|
+
type: "text"
|
|
2352
|
+
},
|
|
2353
|
+
{
|
|
2354
|
+
name: "title",
|
|
2355
|
+
type: "text",
|
|
2356
|
+
required: true
|
|
2357
|
+
},
|
|
2358
|
+
{
|
|
2359
|
+
name: "description",
|
|
2360
|
+
type: "textarea"
|
|
2361
|
+
},
|
|
2362
|
+
{
|
|
2363
|
+
name: "media",
|
|
2364
|
+
type: "upload",
|
|
2365
|
+
relationTo: "media",
|
|
2366
|
+
required: false
|
|
2367
|
+
},
|
|
2368
|
+
{
|
|
2369
|
+
name: "imageURL",
|
|
2370
|
+
type: "text",
|
|
2371
|
+
admin: {
|
|
2372
|
+
description: "Optional direct image URL when this card should use an external image."
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
]
|
|
2376
|
+
},
|
|
1072
2377
|
{
|
|
1073
2378
|
name: "width",
|
|
1074
2379
|
type: "select",
|
|
@@ -1084,6 +2389,14 @@ var RichTextBlock = {
|
|
|
1084
2389
|
}
|
|
1085
2390
|
]
|
|
1086
2391
|
},
|
|
2392
|
+
{
|
|
2393
|
+
name: "settings",
|
|
2394
|
+
type: "json",
|
|
2395
|
+
admin: {
|
|
2396
|
+
description: "Internal builder settings schema v2.",
|
|
2397
|
+
hidden: true
|
|
2398
|
+
}
|
|
2399
|
+
},
|
|
1087
2400
|
...sectionStyleFields()
|
|
1088
2401
|
]
|
|
1089
2402
|
};
|
|
@@ -1131,9 +2444,24 @@ var StatsBlock = {
|
|
|
1131
2444
|
{
|
|
1132
2445
|
name: "description",
|
|
1133
2446
|
type: "text"
|
|
2447
|
+
},
|
|
2448
|
+
{
|
|
2449
|
+
name: "settings",
|
|
2450
|
+
type: "json",
|
|
2451
|
+
admin: {
|
|
2452
|
+
hidden: true
|
|
2453
|
+
}
|
|
1134
2454
|
}
|
|
1135
2455
|
]
|
|
1136
2456
|
},
|
|
2457
|
+
{
|
|
2458
|
+
name: "settings",
|
|
2459
|
+
type: "json",
|
|
2460
|
+
admin: {
|
|
2461
|
+
description: "Internal builder settings schema v2.",
|
|
2462
|
+
hidden: true
|
|
2463
|
+
}
|
|
2464
|
+
},
|
|
1137
2465
|
...sectionStyleFields()
|
|
1138
2466
|
]
|
|
1139
2467
|
};
|
|
@@ -1158,11 +2486,41 @@ var TestimonialsBlock = {
|
|
|
1158
2486
|
type: "text",
|
|
1159
2487
|
required: true
|
|
1160
2488
|
},
|
|
2489
|
+
{
|
|
2490
|
+
name: "visibleCount",
|
|
2491
|
+
type: "number",
|
|
2492
|
+
defaultValue: 3,
|
|
2493
|
+
min: 1,
|
|
2494
|
+
max: 6,
|
|
2495
|
+
admin: {
|
|
2496
|
+
description: "How many testimonials to show at once.",
|
|
2497
|
+
step: 1
|
|
2498
|
+
}
|
|
2499
|
+
},
|
|
2500
|
+
{
|
|
2501
|
+
name: "autoRotate",
|
|
2502
|
+
type: "checkbox",
|
|
2503
|
+
defaultValue: true,
|
|
2504
|
+
admin: {
|
|
2505
|
+
description: "Automatically rotates through all testimonials."
|
|
2506
|
+
}
|
|
2507
|
+
},
|
|
2508
|
+
{
|
|
2509
|
+
name: "rotateIntervalSeconds",
|
|
2510
|
+
type: "number",
|
|
2511
|
+
defaultValue: 7,
|
|
2512
|
+
min: 2,
|
|
2513
|
+
max: 30,
|
|
2514
|
+
admin: {
|
|
2515
|
+
description: "How often to rotate (in seconds).",
|
|
2516
|
+
step: 1
|
|
2517
|
+
}
|
|
2518
|
+
},
|
|
1161
2519
|
{
|
|
1162
2520
|
name: "items",
|
|
1163
2521
|
type: "array",
|
|
1164
2522
|
minRows: 1,
|
|
1165
|
-
maxRows:
|
|
2523
|
+
maxRows: 30,
|
|
1166
2524
|
fields: [
|
|
1167
2525
|
{
|
|
1168
2526
|
name: "quote",
|
|
@@ -1177,9 +2535,35 @@ var TestimonialsBlock = {
|
|
|
1177
2535
|
{
|
|
1178
2536
|
name: "location",
|
|
1179
2537
|
type: "text"
|
|
2538
|
+
},
|
|
2539
|
+
{
|
|
2540
|
+
name: "rating",
|
|
2541
|
+
type: "number",
|
|
2542
|
+
defaultValue: 5,
|
|
2543
|
+
min: 1,
|
|
2544
|
+
max: 5,
|
|
2545
|
+
admin: {
|
|
2546
|
+
description: "Star rating (1-5).",
|
|
2547
|
+
step: 1
|
|
2548
|
+
}
|
|
2549
|
+
},
|
|
2550
|
+
{
|
|
2551
|
+
name: "settings",
|
|
2552
|
+
type: "json",
|
|
2553
|
+
admin: {
|
|
2554
|
+
hidden: true
|
|
2555
|
+
}
|
|
1180
2556
|
}
|
|
1181
2557
|
]
|
|
1182
2558
|
},
|
|
2559
|
+
{
|
|
2560
|
+
name: "settings",
|
|
2561
|
+
type: "json",
|
|
2562
|
+
admin: {
|
|
2563
|
+
description: "Internal builder settings schema v2.",
|
|
2564
|
+
hidden: true
|
|
2565
|
+
}
|
|
2566
|
+
},
|
|
1183
2567
|
...sectionStyleFields()
|
|
1184
2568
|
]
|
|
1185
2569
|
};
|
|
@@ -1244,18 +2628,18 @@ var sectionPresets = [
|
|
|
1244
2628
|
blocks: [
|
|
1245
2629
|
{
|
|
1246
2630
|
blockType: "hero",
|
|
1247
|
-
kicker: "
|
|
1248
|
-
headline: "
|
|
1249
|
-
subheadline: "
|
|
1250
|
-
primaryLabel: "Get
|
|
2631
|
+
kicker: "Trusted Team",
|
|
2632
|
+
headline: "A clear headline for your primary offer",
|
|
2633
|
+
subheadline: "Explain what you offer, who it is for, and why it matters in one strong supporting sentence.",
|
|
2634
|
+
primaryLabel: "Get Started",
|
|
1251
2635
|
primaryHref: "/contact",
|
|
1252
|
-
secondaryLabel: "
|
|
1253
|
-
secondaryHref: "/
|
|
2636
|
+
secondaryLabel: "Learn More",
|
|
2637
|
+
secondaryHref: "/about"
|
|
1254
2638
|
},
|
|
1255
2639
|
{
|
|
1256
2640
|
blockType: "cta",
|
|
1257
|
-
headline: "
|
|
1258
|
-
description: "
|
|
2641
|
+
headline: "Ready for the next step?",
|
|
2642
|
+
description: "Use a short call to action with a direct path to contact or purchase.",
|
|
1259
2643
|
buttonLabel: "Contact Us",
|
|
1260
2644
|
buttonHref: "/contact",
|
|
1261
2645
|
style: "light"
|
|
@@ -1273,19 +2657,19 @@ var sectionPresets = [
|
|
|
1273
2657
|
variant: "cards",
|
|
1274
2658
|
items: [
|
|
1275
2659
|
{
|
|
1276
|
-
title: "
|
|
1277
|
-
description: "
|
|
1278
|
-
icon: "
|
|
2660
|
+
title: "Service One",
|
|
2661
|
+
description: "Briefly describe this offer or outcome.",
|
|
2662
|
+
icon: "01"
|
|
1279
2663
|
},
|
|
1280
2664
|
{
|
|
1281
|
-
title: "
|
|
1282
|
-
description: "
|
|
1283
|
-
icon: "
|
|
2665
|
+
title: "Service Two",
|
|
2666
|
+
description: "Briefly describe this offer or outcome.",
|
|
2667
|
+
icon: "02"
|
|
1284
2668
|
},
|
|
1285
2669
|
{
|
|
1286
|
-
title: "
|
|
1287
|
-
description: "
|
|
1288
|
-
icon: "
|
|
2670
|
+
title: "Service Three",
|
|
2671
|
+
description: "Briefly describe this offer or outcome.",
|
|
2672
|
+
icon: "03"
|
|
1289
2673
|
}
|
|
1290
2674
|
]
|
|
1291
2675
|
}
|
|
@@ -1301,14 +2685,16 @@ var sectionPresets = [
|
|
|
1301
2685
|
title: "What Homeowners Say",
|
|
1302
2686
|
items: [
|
|
1303
2687
|
{
|
|
1304
|
-
quote: "
|
|
1305
|
-
name: "
|
|
1306
|
-
location: "
|
|
2688
|
+
quote: "The experience was smooth, thoughtful, and exactly what we hoped for.",
|
|
2689
|
+
name: "Customer Name",
|
|
2690
|
+
location: "City, ST",
|
|
2691
|
+
rating: 5
|
|
1307
2692
|
},
|
|
1308
2693
|
{
|
|
1309
|
-
quote: "
|
|
1310
|
-
name: "
|
|
1311
|
-
location: "
|
|
2694
|
+
quote: "Fast communication, strong service, and a result we would happily recommend.",
|
|
2695
|
+
name: "Customer Name",
|
|
2696
|
+
location: "City, ST",
|
|
2697
|
+
rating: 5
|
|
1312
2698
|
}
|
|
1313
2699
|
]
|
|
1314
2700
|
},
|
|
@@ -1317,12 +2703,12 @@ var sectionPresets = [
|
|
|
1317
2703
|
title: "Common Questions",
|
|
1318
2704
|
items: [
|
|
1319
2705
|
{
|
|
1320
|
-
question: "How quickly
|
|
1321
|
-
answer: "
|
|
2706
|
+
question: "How quickly do you respond?",
|
|
2707
|
+
answer: "Replace this with a concise answer to a common customer question."
|
|
1322
2708
|
},
|
|
1323
2709
|
{
|
|
1324
|
-
question: "
|
|
1325
|
-
answer: "
|
|
2710
|
+
question: "What is included?",
|
|
2711
|
+
answer: "Replace this with another concise answer that reduces buying friction."
|
|
1326
2712
|
}
|
|
1327
2713
|
]
|
|
1328
2714
|
}
|
|
@@ -1336,13 +2722,13 @@ var sectionPresets = [
|
|
|
1336
2722
|
{
|
|
1337
2723
|
blockType: "formEmbed",
|
|
1338
2724
|
title: "Request a Quote",
|
|
1339
|
-
description: "Share
|
|
2725
|
+
description: "Share a few details and your team can follow up with next steps.",
|
|
1340
2726
|
formType: "quote"
|
|
1341
2727
|
},
|
|
1342
2728
|
{
|
|
1343
2729
|
blockType: "bookingEmbed",
|
|
1344
2730
|
title: "Prefer to book a consultation?",
|
|
1345
|
-
description: "
|
|
2731
|
+
description: "Offer an alternative scheduling path for visitors who prefer to book directly.",
|
|
1346
2732
|
buttonLabel: "Book Consultation",
|
|
1347
2733
|
buttonHref: "/contact"
|
|
1348
2734
|
}
|
|
@@ -1354,14 +2740,14 @@ var templateStarterPresets = {
|
|
|
1354
2740
|
{
|
|
1355
2741
|
blockType: "hero",
|
|
1356
2742
|
headline: "Contact Us",
|
|
1357
|
-
subheadline: "
|
|
1358
|
-
primaryLabel: "
|
|
1359
|
-
primaryHref: "
|
|
2743
|
+
subheadline: "Tell visitors exactly how to reach you and what to expect next.",
|
|
2744
|
+
primaryLabel: "Email Us",
|
|
2745
|
+
primaryHref: "mailto:hello@example.com"
|
|
1360
2746
|
},
|
|
1361
2747
|
{
|
|
1362
2748
|
blockType: "formEmbed",
|
|
1363
2749
|
title: "Request a Quote",
|
|
1364
|
-
description: "
|
|
2750
|
+
description: "Use this space for a form embed or lead capture flow.",
|
|
1365
2751
|
formType: "quote"
|
|
1366
2752
|
},
|
|
1367
2753
|
{
|
|
@@ -1369,8 +2755,8 @@ var templateStarterPresets = {
|
|
|
1369
2755
|
title: "Common Questions",
|
|
1370
2756
|
items: [
|
|
1371
2757
|
{
|
|
1372
|
-
question: "How quickly
|
|
1373
|
-
answer: "
|
|
2758
|
+
question: "How quickly will you respond?",
|
|
2759
|
+
answer: "Replace with the answer that best fits your operating process."
|
|
1374
2760
|
}
|
|
1375
2761
|
]
|
|
1376
2762
|
}
|
|
@@ -1379,27 +2765,27 @@ var templateStarterPresets = {
|
|
|
1379
2765
|
{
|
|
1380
2766
|
blockType: "hero",
|
|
1381
2767
|
kicker: "Locally Owned",
|
|
1382
|
-
headline: "
|
|
1383
|
-
subheadline: "
|
|
1384
|
-
primaryLabel: "Get
|
|
2768
|
+
headline: "Lead with your strongest offer",
|
|
2769
|
+
subheadline: "Support the headline with a concise sentence that clarifies benefits and audience.",
|
|
2770
|
+
primaryLabel: "Get Started",
|
|
1385
2771
|
primaryHref: "/contact",
|
|
1386
2772
|
secondaryLabel: "View Services",
|
|
1387
2773
|
secondaryHref: "/services"
|
|
1388
2774
|
},
|
|
1389
2775
|
{
|
|
1390
2776
|
blockType: "featureGrid",
|
|
1391
|
-
title: "Why
|
|
2777
|
+
title: "Why clients choose us",
|
|
1392
2778
|
variant: "highlight",
|
|
1393
2779
|
items: [
|
|
1394
|
-
{ title: "
|
|
1395
|
-
{ title: "
|
|
1396
|
-
{ title: "
|
|
2780
|
+
{ title: "Clear Value", description: "Explain your first differentiator.", icon: "01" },
|
|
2781
|
+
{ title: "Reliable Process", description: "Explain your second differentiator.", icon: "02" },
|
|
2782
|
+
{ title: "Strong Results", description: "Explain your third differentiator.", icon: "03" }
|
|
1397
2783
|
]
|
|
1398
2784
|
},
|
|
1399
2785
|
{
|
|
1400
2786
|
blockType: "cta",
|
|
1401
|
-
headline: "
|
|
1402
|
-
description: "
|
|
2787
|
+
headline: "Ready to take the next step?",
|
|
2788
|
+
description: "Add a direct conversion prompt with a clear primary action.",
|
|
1403
2789
|
buttonLabel: "Contact Us",
|
|
1404
2790
|
buttonHref: "/contact",
|
|
1405
2791
|
style: "light"
|
|
@@ -1408,9 +2794,9 @@ var templateStarterPresets = {
|
|
|
1408
2794
|
services: [
|
|
1409
2795
|
{
|
|
1410
2796
|
blockType: "hero",
|
|
1411
|
-
headline: "
|
|
1412
|
-
subheadline: "
|
|
1413
|
-
primaryLabel: "
|
|
2797
|
+
headline: "Services Built Around Your Process",
|
|
2798
|
+
subheadline: "Summarize the core offerings with a short clarity-first introduction.",
|
|
2799
|
+
primaryLabel: "Request Info",
|
|
1414
2800
|
primaryHref: "/contact"
|
|
1415
2801
|
},
|
|
1416
2802
|
{
|
|
@@ -1419,19 +2805,19 @@ var templateStarterPresets = {
|
|
|
1419
2805
|
variant: "cards",
|
|
1420
2806
|
items: [
|
|
1421
2807
|
{
|
|
1422
|
-
title: "
|
|
1423
|
-
description: "
|
|
1424
|
-
icon: "
|
|
2808
|
+
title: "Service One",
|
|
2809
|
+
description: "Replace with a short description.",
|
|
2810
|
+
icon: "01"
|
|
1425
2811
|
},
|
|
1426
2812
|
{
|
|
1427
|
-
title: "
|
|
1428
|
-
description: "
|
|
1429
|
-
icon: "
|
|
2813
|
+
title: "Service Two",
|
|
2814
|
+
description: "Replace with a short description.",
|
|
2815
|
+
icon: "02"
|
|
1430
2816
|
},
|
|
1431
2817
|
{
|
|
1432
|
-
title: "
|
|
1433
|
-
description: "
|
|
1434
|
-
icon: "
|
|
2818
|
+
title: "Service Three",
|
|
2819
|
+
description: "Replace with a short description.",
|
|
2820
|
+
icon: "03"
|
|
1435
2821
|
}
|
|
1436
2822
|
]
|
|
1437
2823
|
},
|
|
@@ -1440,8 +2826,8 @@ var templateStarterPresets = {
|
|
|
1440
2826
|
title: "Frequently Asked Questions",
|
|
1441
2827
|
items: [
|
|
1442
2828
|
{
|
|
1443
|
-
question: "Do you
|
|
1444
|
-
answer: "
|
|
2829
|
+
question: "Do you offer custom scopes?",
|
|
2830
|
+
answer: "Replace this with an answer that fits your business."
|
|
1445
2831
|
}
|
|
1446
2832
|
]
|
|
1447
2833
|
}
|
|
@@ -1512,7 +2898,8 @@ __export(nextjs_exports, {
|
|
|
1512
2898
|
createPageQueries: () => createPageQueries,
|
|
1513
2899
|
createPayloadClient: () => createPayloadClient,
|
|
1514
2900
|
createSiteQueries: () => createSiteQueries,
|
|
1515
|
-
resolveMedia: () => resolveMedia
|
|
2901
|
+
resolveMedia: () => resolveMedia,
|
|
2902
|
+
resolveSocialMediaLinks: () => resolveSocialMediaLinks
|
|
1516
2903
|
});
|
|
1517
2904
|
|
|
1518
2905
|
// src/nextjs/client/payload.ts
|
|
@@ -1530,43 +2917,696 @@ function createPayloadClient(config) {
|
|
|
1530
2917
|
|
|
1531
2918
|
// src/nextjs/queries/pages.ts
|
|
1532
2919
|
var import_cache = require("next/cache");
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
2920
|
+
|
|
2921
|
+
// src/studio/index.ts
|
|
2922
|
+
var studio_exports = {};
|
|
2923
|
+
__export(studio_exports, {
|
|
2924
|
+
assertStudioDocumentV1: () => assertStudioDocumentV1,
|
|
2925
|
+
compileStudioDocument: () => compileStudioDocument,
|
|
2926
|
+
createEmptyStudioDocument: () => createEmptyStudioDocument,
|
|
2927
|
+
createImageUploadOptimizationHook: () => createImageUploadOptimizationHook,
|
|
2928
|
+
createStudioRegistry: () => createStudioRegistry,
|
|
2929
|
+
migrateStudioDocument: () => migrateStudioDocument,
|
|
2930
|
+
validateStudioDocument: () => validateStudioDocument,
|
|
2931
|
+
withImageUploadOptimization: () => withImageUploadOptimization
|
|
2932
|
+
});
|
|
2933
|
+
|
|
2934
|
+
// src/studio/imageUploadOptimization.ts
|
|
2935
|
+
var import_promises = require("fs/promises");
|
|
2936
|
+
var DEFAULT_SUPPORTED_MIME_TYPES = [
|
|
2937
|
+
"image/jpeg",
|
|
2938
|
+
"image/jpg",
|
|
2939
|
+
"image/png",
|
|
2940
|
+
"image/webp",
|
|
2941
|
+
"image/avif",
|
|
2942
|
+
"image/tiff"
|
|
2943
|
+
];
|
|
2944
|
+
var DEFAULT_OPTIONS = {
|
|
2945
|
+
avifQuality: 50,
|
|
2946
|
+
enforceSmallerForLossy: true,
|
|
2947
|
+
jpegQuality: 78,
|
|
2948
|
+
minBytes: 48 * 1024,
|
|
2949
|
+
minQualityFloor: 42,
|
|
2950
|
+
onlyIfSmaller: true,
|
|
2951
|
+
pngCompressionLevel: 9,
|
|
2952
|
+
skipAnimated: true,
|
|
2953
|
+
tiffQuality: 75,
|
|
2954
|
+
webpQuality: 78
|
|
2955
|
+
};
|
|
2956
|
+
var clamp = (value, min, max) => Math.max(min, Math.min(max, Math.round(value)));
|
|
2957
|
+
var isUploadMutationOperation = (operation) => operation === "create" || operation === "update" || operation === "updateByID";
|
|
2958
|
+
var isLossyMimeType = (mimetype) => mimetype === "image/jpeg" || mimetype === "image/jpg" || mimetype === "image/webp" || mimetype === "image/avif" || mimetype === "image/tiff";
|
|
2959
|
+
var readIncomingBuffer = async (file) => {
|
|
2960
|
+
if (file.tempFilePath) {
|
|
2961
|
+
return (0, import_promises.readFile)(file.tempFilePath);
|
|
2962
|
+
}
|
|
2963
|
+
return file.data;
|
|
2964
|
+
};
|
|
2965
|
+
var writeOptimizedBuffer = async (file, buffer) => {
|
|
2966
|
+
if (file.tempFilePath) {
|
|
2967
|
+
await (0, import_promises.unlink)(file.tempFilePath).catch(() => void 0);
|
|
2968
|
+
}
|
|
2969
|
+
return {
|
|
2970
|
+
...file,
|
|
2971
|
+
data: buffer,
|
|
2972
|
+
size: buffer.length,
|
|
2973
|
+
tempFilePath: void 0
|
|
2974
|
+
};
|
|
2975
|
+
};
|
|
2976
|
+
var createImageUploadOptimizationHook = (options = {}) => {
|
|
2977
|
+
const supportedMimeTypes = new Set(options.supportedMimeTypes || DEFAULT_SUPPORTED_MIME_TYPES);
|
|
2978
|
+
const settings = { ...DEFAULT_OPTIONS, ...options };
|
|
2979
|
+
return async ({ operation, req }) => {
|
|
2980
|
+
if (!isUploadMutationOperation(operation)) {
|
|
2981
|
+
return;
|
|
2982
|
+
}
|
|
2983
|
+
const file = req.file;
|
|
2984
|
+
if (!file) {
|
|
2985
|
+
return;
|
|
2986
|
+
}
|
|
2987
|
+
if (!supportedMimeTypes.has(file.mimetype)) {
|
|
2988
|
+
return;
|
|
2989
|
+
}
|
|
2990
|
+
if (typeof file.size === "number" && file.size < settings.minBytes) {
|
|
2991
|
+
return;
|
|
2992
|
+
}
|
|
2993
|
+
const sharpFactory = req.payload?.config?.sharp;
|
|
2994
|
+
if (typeof sharpFactory !== "function") {
|
|
2995
|
+
return;
|
|
2996
|
+
}
|
|
2997
|
+
const originalBuffer = await readIncomingBuffer(file);
|
|
2998
|
+
if (!Buffer.isBuffer(originalBuffer) || originalBuffer.length === 0) {
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
const animatedInput = file.mimetype === "image/avif" || file.mimetype === "image/webp";
|
|
3002
|
+
const metadataProbe = await sharpFactory(
|
|
3003
|
+
originalBuffer,
|
|
3004
|
+
animatedInput ? {
|
|
3005
|
+
animated: true
|
|
3006
|
+
} : void 0
|
|
3007
|
+
).metadata();
|
|
3008
|
+
if (settings.skipAnimated && typeof metadataProbe.pages === "number" && metadataProbe.pages > 1) {
|
|
3009
|
+
return;
|
|
3010
|
+
}
|
|
3011
|
+
const buildPipeline = (qualityOverride) => {
|
|
3012
|
+
let pipeline = sharpFactory(
|
|
3013
|
+
originalBuffer,
|
|
3014
|
+
animatedInput ? {
|
|
3015
|
+
animated: true
|
|
3016
|
+
} : void 0
|
|
3017
|
+
);
|
|
3018
|
+
switch (file.mimetype) {
|
|
3019
|
+
case "image/jpeg":
|
|
3020
|
+
case "image/jpg":
|
|
3021
|
+
pipeline = pipeline.jpeg({
|
|
3022
|
+
mozjpeg: true,
|
|
3023
|
+
progressive: true,
|
|
3024
|
+
quality: clamp(qualityOverride ?? settings.jpegQuality, 20, 100)
|
|
3025
|
+
});
|
|
3026
|
+
break;
|
|
3027
|
+
case "image/png":
|
|
3028
|
+
pipeline = pipeline.png({
|
|
3029
|
+
compressionLevel: clamp(settings.pngCompressionLevel, 0, 9),
|
|
3030
|
+
palette: false
|
|
3031
|
+
});
|
|
3032
|
+
break;
|
|
3033
|
+
case "image/webp":
|
|
3034
|
+
pipeline = pipeline.webp({
|
|
3035
|
+
quality: clamp(qualityOverride ?? settings.webpQuality, 20, 100)
|
|
3036
|
+
});
|
|
3037
|
+
break;
|
|
3038
|
+
case "image/avif":
|
|
3039
|
+
pipeline = pipeline.avif({
|
|
3040
|
+
quality: clamp(qualityOverride ?? settings.avifQuality, 20, 100)
|
|
3041
|
+
});
|
|
3042
|
+
break;
|
|
3043
|
+
case "image/tiff":
|
|
3044
|
+
pipeline = pipeline.tiff({
|
|
3045
|
+
quality: clamp(qualityOverride ?? settings.tiffQuality, 20, 100)
|
|
3046
|
+
});
|
|
3047
|
+
break;
|
|
3048
|
+
default:
|
|
3049
|
+
return null;
|
|
3050
|
+
}
|
|
3051
|
+
return pipeline;
|
|
3052
|
+
};
|
|
3053
|
+
const initialPipeline = buildPipeline();
|
|
3054
|
+
if (!initialPipeline) {
|
|
3055
|
+
return;
|
|
3056
|
+
}
|
|
3057
|
+
let optimizedBuffer = await initialPipeline.toBuffer();
|
|
3058
|
+
const shouldSweepQuality = settings.enforceSmallerForLossy && isLossyMimeType(file.mimetype);
|
|
3059
|
+
if (shouldSweepQuality) {
|
|
3060
|
+
const initialQuality = file.mimetype === "image/jpeg" || file.mimetype === "image/jpg" ? settings.jpegQuality : file.mimetype === "image/webp" ? settings.webpQuality : file.mimetype === "image/avif" ? settings.avifQuality : settings.tiffQuality;
|
|
3061
|
+
let bestBuffer = optimizedBuffer;
|
|
3062
|
+
let quality = clamp(initialQuality - 5, settings.minQualityFloor, 100);
|
|
3063
|
+
while (quality >= settings.minQualityFloor) {
|
|
3064
|
+
const retryPipeline = buildPipeline(quality);
|
|
3065
|
+
if (!retryPipeline) {
|
|
3066
|
+
break;
|
|
3067
|
+
}
|
|
3068
|
+
const retryBuffer = await retryPipeline.toBuffer();
|
|
3069
|
+
if (retryBuffer.length < bestBuffer.length) {
|
|
3070
|
+
bestBuffer = retryBuffer;
|
|
3071
|
+
}
|
|
3072
|
+
quality -= 5;
|
|
3073
|
+
}
|
|
3074
|
+
optimizedBuffer = bestBuffer;
|
|
3075
|
+
}
|
|
3076
|
+
if (settings.onlyIfSmaller && optimizedBuffer.length >= originalBuffer.length) {
|
|
3077
|
+
return;
|
|
3078
|
+
}
|
|
3079
|
+
req.file = await writeOptimizedBuffer(file, optimizedBuffer);
|
|
3080
|
+
};
|
|
3081
|
+
};
|
|
3082
|
+
var withImageUploadOptimization = (collection, options = {}) => {
|
|
3083
|
+
if (!collection.upload) {
|
|
3084
|
+
return collection;
|
|
3085
|
+
}
|
|
3086
|
+
const existingHooks = collection.hooks || {};
|
|
3087
|
+
const beforeOperation = existingHooks.beforeOperation || [];
|
|
3088
|
+
return {
|
|
3089
|
+
...collection,
|
|
3090
|
+
hooks: {
|
|
3091
|
+
...existingHooks,
|
|
3092
|
+
beforeOperation: [createImageUploadOptimizationHook(options), ...beforeOperation]
|
|
3093
|
+
}
|
|
3094
|
+
};
|
|
3095
|
+
};
|
|
3096
|
+
|
|
3097
|
+
// src/studio/index.ts
|
|
3098
|
+
var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3099
|
+
var makeIssue = (message, path2, code = "studio.invalid") => ({
|
|
3100
|
+
code,
|
|
3101
|
+
message,
|
|
3102
|
+
path: path2,
|
|
3103
|
+
severity: "error"
|
|
3104
|
+
});
|
|
3105
|
+
var createEmptyStudioDocument = (title) => ({
|
|
3106
|
+
metadata: {},
|
|
3107
|
+
schemaVersion: 1,
|
|
3108
|
+
title,
|
|
3109
|
+
nodes: [],
|
|
3110
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3111
|
+
});
|
|
3112
|
+
function assertStudioDocumentV1(input) {
|
|
3113
|
+
if (!isRecord2(input)) {
|
|
3114
|
+
throw new Error("Studio document must be an object");
|
|
3115
|
+
}
|
|
3116
|
+
if (input.schemaVersion !== 1) {
|
|
3117
|
+
throw new Error("Unsupported studio schemaVersion");
|
|
3118
|
+
}
|
|
3119
|
+
if (!Array.isArray(input.nodes)) {
|
|
3120
|
+
throw new Error("Studio document nodes must be an array");
|
|
3121
|
+
}
|
|
3122
|
+
const nodes = input.nodes.map((node, index) => {
|
|
3123
|
+
if (!isRecord2(node)) {
|
|
3124
|
+
throw new Error(`Node at index ${index} must be an object`);
|
|
3125
|
+
}
|
|
3126
|
+
if (typeof node.id !== "string" || node.id.length === 0) {
|
|
3127
|
+
throw new Error(`Node at index ${index} has invalid id`);
|
|
3128
|
+
}
|
|
3129
|
+
if (typeof node.type !== "string" || node.type.length === 0) {
|
|
3130
|
+
throw new Error(`Node at index ${index} has invalid type`);
|
|
3131
|
+
}
|
|
3132
|
+
if (!isRecord2(node.data)) {
|
|
3133
|
+
throw new Error(`Node at index ${index} has invalid data`);
|
|
3134
|
+
}
|
|
3135
|
+
return {
|
|
3136
|
+
id: node.id,
|
|
3137
|
+
type: node.type,
|
|
3138
|
+
data: node.data
|
|
3139
|
+
};
|
|
3140
|
+
});
|
|
3141
|
+
return {
|
|
3142
|
+
metadata: isRecord2(input.metadata) ? input.metadata : void 0,
|
|
3143
|
+
schemaVersion: 1,
|
|
3144
|
+
title: typeof input.title === "string" ? input.title : void 0,
|
|
3145
|
+
nodes,
|
|
3146
|
+
updatedAt: typeof input.updatedAt === "string" ? input.updatedAt : void 0
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
function createStudioRegistry(modules) {
|
|
3150
|
+
const moduleByID = new Map(modules.map((mod) => [mod.id, mod]));
|
|
3151
|
+
const nodeTypes = modules.flatMap((mod) => mod.nodeTypes);
|
|
3152
|
+
const nodeTypeByName = new Map(nodeTypes.map((definition) => [definition.type, definition]));
|
|
3153
|
+
return {
|
|
3154
|
+
getModuleByID: (id) => moduleByID.get(id),
|
|
3155
|
+
getNodeTypeByName: (type) => nodeTypeByName.get(type),
|
|
3156
|
+
listInspectorPanels: () => modules.flatMap((mod) => mod.inspectorPanels),
|
|
3157
|
+
listModules: () => [...modules],
|
|
3158
|
+
listPaletteGroups: () => modules.flatMap((mod) => mod.paletteGroups),
|
|
3159
|
+
listNodeTypes: () => [...nodeTypes]
|
|
3160
|
+
};
|
|
3161
|
+
}
|
|
3162
|
+
function validateStudioDocument(document, modules) {
|
|
3163
|
+
const issues = [];
|
|
3164
|
+
if (document.schemaVersion !== 1) {
|
|
3165
|
+
issues.push(makeIssue("Unsupported schema version", "schemaVersion", "studio.schemaVersion"));
|
|
3166
|
+
}
|
|
3167
|
+
if (!Array.isArray(document.nodes)) {
|
|
3168
|
+
issues.push(makeIssue("Nodes must be an array", "nodes", "studio.nodes"));
|
|
3169
|
+
return issues;
|
|
3170
|
+
}
|
|
3171
|
+
const registry = createStudioRegistry(modules);
|
|
3172
|
+
const nodeIDs = /* @__PURE__ */ new Set();
|
|
3173
|
+
document.nodes.forEach((node, index) => {
|
|
3174
|
+
if (!node.id) {
|
|
3175
|
+
issues.push(makeIssue("Node id is required", `nodes.${index}.id`, "studio.node.id"));
|
|
3176
|
+
}
|
|
3177
|
+
if (nodeIDs.has(node.id)) {
|
|
3178
|
+
issues.push(makeIssue("Node id must be unique", `nodes.${index}.id`, "studio.node.id.duplicate"));
|
|
3179
|
+
}
|
|
3180
|
+
nodeIDs.add(node.id);
|
|
3181
|
+
if (!registry.getNodeTypeByName(node.type)) {
|
|
3182
|
+
issues.push(makeIssue("Unsupported node type", `nodes.${index}.type`, "studio.node.type"));
|
|
3183
|
+
}
|
|
3184
|
+
});
|
|
3185
|
+
for (const module2 of modules) {
|
|
3186
|
+
for (const validate of module2.validators) {
|
|
3187
|
+
issues.push(...validate(document));
|
|
3188
|
+
}
|
|
3189
|
+
}
|
|
3190
|
+
return issues;
|
|
3191
|
+
}
|
|
3192
|
+
function compileStudioDocument(document, modules) {
|
|
3193
|
+
const issues = validateStudioDocument(document, modules);
|
|
3194
|
+
const compilerEntries = modules.filter((mod) => typeof mod.compiler?.compileNode === "function").map((mod) => mod.compiler?.compileNode);
|
|
3195
|
+
const layout = document.nodes.map((node) => {
|
|
3196
|
+
for (const compileNode of compilerEntries) {
|
|
3197
|
+
if (!compileNode) {
|
|
3198
|
+
continue;
|
|
3199
|
+
}
|
|
3200
|
+
const compiled = compileNode(node);
|
|
3201
|
+
if (compiled) {
|
|
3202
|
+
return compiled;
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
return {
|
|
3206
|
+
id: node.id,
|
|
3207
|
+
blockType: node.type,
|
|
3208
|
+
...node.data
|
|
3209
|
+
};
|
|
3210
|
+
});
|
|
3211
|
+
return {
|
|
3212
|
+
issues,
|
|
3213
|
+
layout
|
|
3214
|
+
};
|
|
3215
|
+
}
|
|
3216
|
+
function migrateStudioDocument(value, migrations) {
|
|
3217
|
+
const sorted = [...migrations].sort((a, b) => a.fromVersion - b.fromVersion);
|
|
3218
|
+
let current = value;
|
|
3219
|
+
for (const migration of sorted) {
|
|
3220
|
+
if (!isRecord2(current) || current.schemaVersion !== migration.fromVersion) {
|
|
3221
|
+
continue;
|
|
3222
|
+
}
|
|
3223
|
+
current = migration.migrate(current);
|
|
3224
|
+
}
|
|
3225
|
+
return assertStudioDocumentV1(current);
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
// src/studio-pages/builder/settings-v2/types.ts
|
|
3229
|
+
var defaultBuilderBlockSettingsV2 = {
|
|
3230
|
+
advanced: {
|
|
3231
|
+
customClassName: "",
|
|
3232
|
+
editCopyInPanel: false,
|
|
3233
|
+
hideOnMobile: false
|
|
3234
|
+
},
|
|
3235
|
+
appearance: {
|
|
3236
|
+
contentBackgroundColor: "#ffffff",
|
|
3237
|
+
contentBackgroundMode: "none",
|
|
3238
|
+
contentGradientAngle: "135",
|
|
3239
|
+
contentGradientFrom: "#ffffff",
|
|
3240
|
+
contentGradientPreset: "none",
|
|
3241
|
+
contentGradientTo: "#f4f6f8",
|
|
3242
|
+
sectionBackgroundColor: "#ffffff",
|
|
3243
|
+
sectionBackgroundMode: "none",
|
|
3244
|
+
sectionGradientAngle: "135",
|
|
3245
|
+
sectionGradientFrom: "#334b63",
|
|
3246
|
+
sectionGradientPreset: "slate",
|
|
3247
|
+
sectionGradientTo: "#496582"
|
|
3248
|
+
},
|
|
3249
|
+
layout: {
|
|
3250
|
+
contentWidth: "inherit",
|
|
3251
|
+
linkHorizontalPadding: true,
|
|
3252
|
+
linkVerticalPadding: true,
|
|
3253
|
+
paddingBottomPt: null,
|
|
3254
|
+
paddingLeftPt: null,
|
|
3255
|
+
paddingRightPt: null,
|
|
3256
|
+
paddingTopPt: null,
|
|
3257
|
+
sectionPaddingX: "inherit",
|
|
3258
|
+
sectionPaddingY: "md"
|
|
3259
|
+
},
|
|
3260
|
+
media: {
|
|
3261
|
+
cornerStyle: "rounded",
|
|
3262
|
+
fit: "cover",
|
|
3263
|
+
height: null,
|
|
3264
|
+
position: "center",
|
|
3265
|
+
positionX: null,
|
|
3266
|
+
positionY: null
|
|
3267
|
+
},
|
|
3268
|
+
typography: {
|
|
3269
|
+
bodyAlign: "left",
|
|
3270
|
+
headingAlign: "left",
|
|
3271
|
+
letterSpacingPreset: "normal",
|
|
3272
|
+
lineHeightPreset: "normal",
|
|
3273
|
+
maxTextWidth: "auto"
|
|
3274
|
+
},
|
|
3275
|
+
version: 2
|
|
3276
|
+
};
|
|
3277
|
+
var defaultBuilderItemSettingsV2 = {
|
|
3278
|
+
layout: {
|
|
3279
|
+
contentWidth: "inherit",
|
|
3280
|
+
linkHorizontalPadding: true,
|
|
3281
|
+
linkVerticalPadding: true,
|
|
3282
|
+
paddingBottomPt: null,
|
|
3283
|
+
paddingLeftPt: null,
|
|
3284
|
+
paddingRightPt: null,
|
|
3285
|
+
paddingTopPt: null,
|
|
3286
|
+
sectionPaddingX: "inherit",
|
|
3287
|
+
sectionPaddingY: "md"
|
|
3288
|
+
},
|
|
3289
|
+
media: {
|
|
3290
|
+
cornerStyle: "rounded",
|
|
3291
|
+
fit: "cover",
|
|
3292
|
+
height: null,
|
|
3293
|
+
position: "center",
|
|
3294
|
+
positionX: null,
|
|
3295
|
+
positionY: null
|
|
3296
|
+
},
|
|
3297
|
+
typography: {
|
|
3298
|
+
bodyAlign: "left",
|
|
3299
|
+
headingAlign: "left",
|
|
3300
|
+
letterSpacingPreset: "normal",
|
|
3301
|
+
lineHeightPreset: "normal",
|
|
3302
|
+
maxTextWidth: "auto"
|
|
3303
|
+
},
|
|
3304
|
+
version: 2
|
|
3305
|
+
};
|
|
3306
|
+
var defaultBuilderThemeTokens = {
|
|
3307
|
+
colors: {
|
|
3308
|
+
accent: "#334b63",
|
|
3309
|
+
bodyText: "#425163",
|
|
3310
|
+
headingText: "#182332",
|
|
3311
|
+
surface: "#ffffff"
|
|
3312
|
+
},
|
|
3313
|
+
radii: {
|
|
3314
|
+
card: 16,
|
|
3315
|
+
panel: 14
|
|
3316
|
+
},
|
|
3317
|
+
spacing: {
|
|
3318
|
+
sectionGap: "md",
|
|
3319
|
+
sectionPadding: "md"
|
|
3320
|
+
},
|
|
3321
|
+
typography: {
|
|
3322
|
+
bodySize: "md",
|
|
3323
|
+
headingSize: "md"
|
|
3324
|
+
}
|
|
3325
|
+
};
|
|
3326
|
+
|
|
3327
|
+
// src/studio-pages/builder/adapters/settingsV2.ts
|
|
3328
|
+
var isRecord3 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3329
|
+
var parsePercent = (value) => {
|
|
3330
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
3331
|
+
return Math.max(0, Math.min(100, value));
|
|
3332
|
+
}
|
|
3333
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
3334
|
+
const parsed = Number(value);
|
|
3335
|
+
if (Number.isFinite(parsed)) {
|
|
3336
|
+
return Math.max(0, Math.min(100, parsed));
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
return null;
|
|
3340
|
+
};
|
|
3341
|
+
var parsePixel = (value) => {
|
|
3342
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
3343
|
+
return value;
|
|
3344
|
+
}
|
|
3345
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
3346
|
+
const parsed = Number(value);
|
|
3347
|
+
if (Number.isFinite(parsed)) {
|
|
3348
|
+
return parsed;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
return null;
|
|
3352
|
+
};
|
|
3353
|
+
var mergeSettings = (defaults, input) => {
|
|
3354
|
+
if (!isRecord3(input)) {
|
|
3355
|
+
return structuredClone(defaults);
|
|
3356
|
+
}
|
|
3357
|
+
const next = structuredClone(defaults);
|
|
3358
|
+
for (const [key, value] of Object.entries(input)) {
|
|
3359
|
+
if (isRecord3(value) && isRecord3(next[key])) {
|
|
3360
|
+
next[key] = mergeSettings(next[key], value);
|
|
3361
|
+
continue;
|
|
3362
|
+
}
|
|
3363
|
+
if (typeof value !== "undefined") {
|
|
3364
|
+
next[key] = value;
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
return next;
|
|
3368
|
+
};
|
|
3369
|
+
var legacyBlockToV2Settings = (block) => {
|
|
3370
|
+
const current = structuredClone(defaultBuilderBlockSettingsV2);
|
|
3371
|
+
current.layout.contentWidth = block.contentWidth === "narrow" || block.contentWidth === "content" || block.contentWidth === "wide" || block.contentWidth === "full" || block.contentWidth === "inherit" ? block.contentWidth : current.layout.contentWidth;
|
|
3372
|
+
current.layout.sectionPaddingX = block.sectionPaddingX === "none" || block.sectionPaddingX === "sm" || block.sectionPaddingX === "md" || block.sectionPaddingX === "lg" || block.sectionPaddingX === "inherit" ? block.sectionPaddingX : current.layout.sectionPaddingX;
|
|
3373
|
+
current.layout.sectionPaddingY = block.sectionPaddingY === "none" || block.sectionPaddingY === "sm" || block.sectionPaddingY === "lg" ? block.sectionPaddingY : current.layout.sectionPaddingY;
|
|
3374
|
+
current.appearance.sectionBackgroundMode = block.sectionBackgroundMode === "none" || block.sectionBackgroundMode === "color" || block.sectionBackgroundMode === "gradient" ? block.sectionBackgroundMode : current.appearance.sectionBackgroundMode;
|
|
3375
|
+
current.appearance.sectionBackgroundColor = typeof block.sectionBackgroundColor === "string" ? block.sectionBackgroundColor : current.appearance.sectionBackgroundColor;
|
|
3376
|
+
current.appearance.sectionGradientPreset = typeof block.sectionGradientPreset === "string" ? block.sectionGradientPreset : current.appearance.sectionGradientPreset;
|
|
3377
|
+
current.appearance.sectionGradientFrom = typeof block.sectionGradientFrom === "string" ? block.sectionGradientFrom : current.appearance.sectionGradientFrom;
|
|
3378
|
+
current.appearance.sectionGradientTo = typeof block.sectionGradientTo === "string" ? block.sectionGradientTo : current.appearance.sectionGradientTo;
|
|
3379
|
+
current.appearance.sectionGradientAngle = typeof block.sectionGradientAngle === "string" ? block.sectionGradientAngle : current.appearance.sectionGradientAngle;
|
|
3380
|
+
current.appearance.contentBackgroundMode = block.contentBackgroundMode === "none" || block.contentBackgroundMode === "color" || block.contentBackgroundMode === "gradient" ? block.contentBackgroundMode : current.appearance.contentBackgroundMode;
|
|
3381
|
+
current.appearance.contentBackgroundColor = typeof block.contentBackgroundColor === "string" ? block.contentBackgroundColor : current.appearance.contentBackgroundColor;
|
|
3382
|
+
current.appearance.contentGradientPreset = typeof block.contentGradientPreset === "string" ? block.contentGradientPreset : current.appearance.contentGradientPreset;
|
|
3383
|
+
current.appearance.contentGradientFrom = typeof block.contentGradientFrom === "string" ? block.contentGradientFrom : current.appearance.contentGradientFrom;
|
|
3384
|
+
current.appearance.contentGradientTo = typeof block.contentGradientTo === "string" ? block.contentGradientTo : current.appearance.contentGradientTo;
|
|
3385
|
+
current.appearance.contentGradientAngle = typeof block.contentGradientAngle === "string" ? block.contentGradientAngle : current.appearance.contentGradientAngle;
|
|
3386
|
+
if (block.backgroundImageFit === "cover" || block.backgroundImageFit === "contain") {
|
|
3387
|
+
current.media.fit = block.backgroundImageFit;
|
|
3388
|
+
}
|
|
3389
|
+
if (block.imageFit === "cover" || block.imageFit === "contain") {
|
|
3390
|
+
current.media.fit = block.imageFit;
|
|
3391
|
+
}
|
|
3392
|
+
if (block.backgroundImageCornerStyle === "rounded" || block.backgroundImageCornerStyle === "square") {
|
|
3393
|
+
current.media.cornerStyle = block.backgroundImageCornerStyle;
|
|
3394
|
+
}
|
|
3395
|
+
if (block.imageCornerStyle === "rounded" || block.imageCornerStyle === "square") {
|
|
3396
|
+
current.media.cornerStyle = block.imageCornerStyle;
|
|
3397
|
+
}
|
|
3398
|
+
if (block.backgroundImagePosition === "top" || block.backgroundImagePosition === "bottom" || block.backgroundImagePosition === "left" || block.backgroundImagePosition === "right" || block.backgroundImagePosition === "center") {
|
|
3399
|
+
current.media.position = block.backgroundImagePosition;
|
|
3400
|
+
}
|
|
3401
|
+
if (block.imagePosition === "top" || block.imagePosition === "bottom" || block.imagePosition === "left" || block.imagePosition === "right" || block.imagePosition === "center") {
|
|
3402
|
+
current.media.position = block.imagePosition;
|
|
3403
|
+
}
|
|
3404
|
+
current.media.positionX = parsePercent(block.imagePositionX ?? block.backgroundImagePositionX);
|
|
3405
|
+
current.media.positionY = parsePercent(block.imagePositionY ?? block.backgroundImagePositionY);
|
|
3406
|
+
current.media.height = parsePixel(block.imageHeight);
|
|
3407
|
+
current.typography.headingAlign = block.textHeadingAlign === "left" || block.textHeadingAlign === "center" || block.textHeadingAlign === "right" || block.textHeadingAlign === "justify" ? block.textHeadingAlign : current.typography.headingAlign;
|
|
3408
|
+
current.typography.bodyAlign = block.textBodyAlign === "left" || block.textBodyAlign === "center" || block.textBodyAlign === "right" || block.textBodyAlign === "justify" ? block.textBodyAlign : current.typography.bodyAlign;
|
|
3409
|
+
current.typography.maxTextWidth = block.textMaxWidth === "auto" || block.textMaxWidth === "sm" || block.textMaxWidth === "md" || block.textMaxWidth === "lg" || block.textMaxWidth === "full" ? block.textMaxWidth : current.typography.maxTextWidth;
|
|
3410
|
+
current.typography.lineHeightPreset = block.textLineHeightPreset === "tight" || block.textLineHeightPreset === "normal" || block.textLineHeightPreset === "relaxed" ? block.textLineHeightPreset : current.typography.lineHeightPreset;
|
|
3411
|
+
current.typography.letterSpacingPreset = block.textLetterSpacingPreset === "tight" || block.textLetterSpacingPreset === "normal" || block.textLetterSpacingPreset === "relaxed" ? block.textLetterSpacingPreset : current.typography.letterSpacingPreset;
|
|
3412
|
+
current.advanced.editCopyInPanel = Boolean(block.editCopyInPanel ?? current.advanced.editCopyInPanel);
|
|
3413
|
+
current.advanced.customClassName = typeof block.customClassName === "string" ? block.customClassName : current.advanced.customClassName;
|
|
3414
|
+
current.advanced.hideOnMobile = Boolean(block.hideOnMobile ?? current.advanced.hideOnMobile);
|
|
3415
|
+
return mergeSettings(current, block.settings);
|
|
3416
|
+
};
|
|
3417
|
+
var v2SettingsToLegacyBlock = (blockWithSettings) => {
|
|
3418
|
+
const settings = legacyBlockToV2Settings(blockWithSettings);
|
|
3419
|
+
const next = {
|
|
3420
|
+
...blockWithSettings,
|
|
3421
|
+
settings
|
|
3422
|
+
};
|
|
3423
|
+
const blockType = typeof next.blockType === "string" ? next.blockType : "";
|
|
3424
|
+
next.contentWidth = settings.layout.contentWidth;
|
|
3425
|
+
next.sectionPaddingX = settings.layout.sectionPaddingX;
|
|
3426
|
+
next.sectionPaddingY = settings.layout.sectionPaddingY;
|
|
3427
|
+
next.sectionBackgroundMode = settings.appearance.sectionBackgroundMode;
|
|
3428
|
+
next.sectionBackgroundColor = settings.appearance.sectionBackgroundColor;
|
|
3429
|
+
next.sectionGradientPreset = settings.appearance.sectionGradientPreset;
|
|
3430
|
+
next.sectionGradientFrom = settings.appearance.sectionGradientFrom;
|
|
3431
|
+
next.sectionGradientTo = settings.appearance.sectionGradientTo;
|
|
3432
|
+
next.sectionGradientAngle = settings.appearance.sectionGradientAngle;
|
|
3433
|
+
next.contentBackgroundMode = settings.appearance.contentBackgroundMode;
|
|
3434
|
+
next.contentBackgroundColor = settings.appearance.contentBackgroundColor;
|
|
3435
|
+
next.contentGradientPreset = settings.appearance.contentGradientPreset;
|
|
3436
|
+
next.contentGradientFrom = settings.appearance.contentGradientFrom;
|
|
3437
|
+
next.contentGradientTo = settings.appearance.contentGradientTo;
|
|
3438
|
+
next.contentGradientAngle = settings.appearance.contentGradientAngle;
|
|
3439
|
+
next.textHeadingAlign = settings.typography.headingAlign;
|
|
3440
|
+
next.textBodyAlign = settings.typography.bodyAlign;
|
|
3441
|
+
next.textMaxWidth = settings.typography.maxTextWidth;
|
|
3442
|
+
next.textLineHeightPreset = settings.typography.lineHeightPreset;
|
|
3443
|
+
next.textLetterSpacingPreset = settings.typography.letterSpacingPreset;
|
|
3444
|
+
next.editCopyInPanel = settings.advanced.editCopyInPanel;
|
|
3445
|
+
next.customClassName = settings.advanced.customClassName;
|
|
3446
|
+
next.hideOnMobile = settings.advanced.hideOnMobile;
|
|
3447
|
+
delete next.backgroundImagePositionX;
|
|
3448
|
+
delete next.backgroundImagePositionY;
|
|
3449
|
+
delete next.imageHeight;
|
|
3450
|
+
delete next.imagePositionX;
|
|
3451
|
+
delete next.imagePositionY;
|
|
3452
|
+
if (blockType === "hero") {
|
|
3453
|
+
next.backgroundImageFit = settings.media.fit;
|
|
3454
|
+
next.backgroundImageCornerStyle = settings.media.cornerStyle;
|
|
3455
|
+
next.backgroundImagePosition = settings.media.position;
|
|
3456
|
+
} else if (blockType === "media") {
|
|
3457
|
+
next.imageFit = settings.media.fit;
|
|
3458
|
+
next.imageCornerStyle = settings.media.cornerStyle;
|
|
3459
|
+
next.imagePosition = settings.media.position;
|
|
3460
|
+
}
|
|
3461
|
+
if (Array.isArray(next.items)) {
|
|
3462
|
+
next.items = next.items.map((rawItem) => isRecord3(rawItem) ? v2SettingsToLegacyItem(rawItem) : rawItem);
|
|
3463
|
+
}
|
|
3464
|
+
return next;
|
|
3465
|
+
};
|
|
3466
|
+
var legacyItemToV2Settings = (item) => {
|
|
3467
|
+
const current = structuredClone(defaultBuilderItemSettingsV2);
|
|
3468
|
+
if (item.imageFit === "cover" || item.imageFit === "contain") {
|
|
3469
|
+
current.media.fit = item.imageFit;
|
|
3470
|
+
}
|
|
3471
|
+
if (item.imageCornerStyle === "rounded" || item.imageCornerStyle === "square") {
|
|
3472
|
+
current.media.cornerStyle = item.imageCornerStyle;
|
|
3473
|
+
}
|
|
3474
|
+
if (item.imagePosition === "top" || item.imagePosition === "bottom" || item.imagePosition === "left" || item.imagePosition === "right" || item.imagePosition === "center") {
|
|
3475
|
+
current.media.position = item.imagePosition;
|
|
3476
|
+
}
|
|
3477
|
+
current.media.positionX = parsePercent(item.imagePositionX);
|
|
3478
|
+
current.media.positionY = parsePercent(item.imagePositionY);
|
|
3479
|
+
current.media.height = parsePixel(item.imageHeight);
|
|
3480
|
+
return mergeSettings(current, item.settings);
|
|
3481
|
+
};
|
|
3482
|
+
var v2SettingsToLegacyItem = (itemWithSettings) => {
|
|
3483
|
+
const settings = legacyItemToV2Settings(itemWithSettings);
|
|
3484
|
+
return {
|
|
3485
|
+
...itemWithSettings,
|
|
3486
|
+
imageCornerStyle: settings.media.cornerStyle,
|
|
3487
|
+
imageFit: settings.media.fit,
|
|
3488
|
+
imageHeight: settings.media.height,
|
|
3489
|
+
imagePosition: settings.media.position,
|
|
3490
|
+
imagePositionX: settings.media.positionX,
|
|
3491
|
+
imagePositionY: settings.media.positionY,
|
|
3492
|
+
settings
|
|
3493
|
+
};
|
|
3494
|
+
};
|
|
3495
|
+
var migrateBlockToSettingsV2 = (block) => {
|
|
3496
|
+
const withLegacyMirrors = v2SettingsToLegacyBlock(block);
|
|
3497
|
+
if (!Array.isArray(withLegacyMirrors.items)) {
|
|
3498
|
+
return withLegacyMirrors;
|
|
3499
|
+
}
|
|
3500
|
+
return {
|
|
3501
|
+
...withLegacyMirrors,
|
|
3502
|
+
items: withLegacyMirrors.items.map((rawItem) => isRecord3(rawItem) ? v2SettingsToLegacyItem(rawItem) : rawItem)
|
|
3503
|
+
};
|
|
3504
|
+
};
|
|
3505
|
+
|
|
3506
|
+
// src/studio-pages/document.ts
|
|
3507
|
+
var ensureNodeID = (value, index) => {
|
|
3508
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
3509
|
+
return value.trim();
|
|
3510
|
+
}
|
|
3511
|
+
return `node-${index + 1}`;
|
|
3512
|
+
};
|
|
3513
|
+
var layoutToStudioDocument = (layout, title, metadata) => {
|
|
3514
|
+
const nodes = layout.filter((block) => typeof block.blockType === "string").map((rawBlock, index) => {
|
|
3515
|
+
const block = migrateBlockToSettingsV2(rawBlock);
|
|
3516
|
+
const blockType = String(block.blockType);
|
|
3517
|
+
const { id, blockType: _ignoredBlockType, ...data } = block;
|
|
3518
|
+
return {
|
|
3519
|
+
id: ensureNodeID(id, index),
|
|
3520
|
+
type: blockType,
|
|
3521
|
+
data
|
|
3522
|
+
};
|
|
3523
|
+
});
|
|
3524
|
+
return {
|
|
3525
|
+
metadata,
|
|
3526
|
+
schemaVersion: 1,
|
|
3527
|
+
title,
|
|
3528
|
+
nodes,
|
|
3529
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3530
|
+
};
|
|
3531
|
+
};
|
|
3532
|
+
var studioDocumentToLayout = (document) => document.nodes.map(
|
|
3533
|
+
(node) => migrateBlockToSettingsV2({
|
|
3534
|
+
id: node.id,
|
|
3535
|
+
blockType: node.type,
|
|
3536
|
+
...node.data
|
|
3537
|
+
})
|
|
3538
|
+
);
|
|
3539
|
+
var createDefaultStudioDocument = (title) => ({
|
|
3540
|
+
metadata: {},
|
|
3541
|
+
schemaVersion: 1,
|
|
3542
|
+
title,
|
|
3543
|
+
nodes: [],
|
|
3544
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3545
|
+
});
|
|
3546
|
+
|
|
3547
|
+
// src/nextjs/queries/pages.ts
|
|
3548
|
+
var PAGE_QUERY_CACHE_VERSION = "v4-published-only-public";
|
|
3549
|
+
function withStudioDocumentLayout(page) {
|
|
3550
|
+
if (!page) {
|
|
3551
|
+
return null;
|
|
3552
|
+
}
|
|
3553
|
+
try {
|
|
3554
|
+
const studioDocument = assertStudioDocumentV1(page.studioDocument);
|
|
3555
|
+
const compiledLayout = studioDocumentToLayout(studioDocument);
|
|
3556
|
+
if (Array.isArray(compiledLayout) && compiledLayout.length > 0) {
|
|
3557
|
+
return {
|
|
3558
|
+
...page,
|
|
3559
|
+
layout: compiledLayout
|
|
3560
|
+
};
|
|
3561
|
+
}
|
|
3562
|
+
} catch {
|
|
3563
|
+
}
|
|
3564
|
+
return page;
|
|
3565
|
+
}
|
|
3566
|
+
function normalizePath(segments) {
|
|
3567
|
+
if (!segments || segments.length === 0) {
|
|
3568
|
+
return "/";
|
|
3569
|
+
}
|
|
3570
|
+
const cleaned = segments.map((segment) => segment.trim()).filter(Boolean).join("/");
|
|
3571
|
+
return cleaned.length > 0 ? `/${cleaned}` : "/";
|
|
3572
|
+
}
|
|
3573
|
+
async function queryPageByPath(payload, path2, draft) {
|
|
3574
|
+
const pathWhere = {
|
|
3575
|
+
path: {
|
|
3576
|
+
equals: path2
|
|
3577
|
+
}
|
|
3578
|
+
};
|
|
3579
|
+
const publishedWhere = {
|
|
3580
|
+
_status: {
|
|
3581
|
+
equals: "published"
|
|
3582
|
+
}
|
|
3583
|
+
};
|
|
3584
|
+
const result = await payload.find({
|
|
1542
3585
|
collection: "pages",
|
|
1543
3586
|
depth: 2,
|
|
1544
3587
|
draft,
|
|
1545
3588
|
limit: 1,
|
|
1546
3589
|
overrideAccess: false,
|
|
1547
|
-
where: {
|
|
1548
|
-
path: {
|
|
1549
|
-
equals: path2
|
|
1550
|
-
}
|
|
1551
|
-
}
|
|
3590
|
+
where: draft ? pathWhere : { and: [pathWhere, publishedWhere] }
|
|
1552
3591
|
});
|
|
1553
3592
|
if (result.docs.length > 0) {
|
|
1554
|
-
return result.docs[0] || null;
|
|
3593
|
+
return withStudioDocumentLayout(result.docs[0] || null);
|
|
1555
3594
|
}
|
|
1556
3595
|
if (path2 === "/") {
|
|
3596
|
+
const homeWhere = {
|
|
3597
|
+
slug: {
|
|
3598
|
+
equals: "home"
|
|
3599
|
+
}
|
|
3600
|
+
};
|
|
1557
3601
|
const homeResult = await payload.find({
|
|
1558
3602
|
collection: "pages",
|
|
1559
3603
|
depth: 2,
|
|
1560
3604
|
draft,
|
|
1561
3605
|
limit: 1,
|
|
1562
3606
|
overrideAccess: false,
|
|
1563
|
-
where: {
|
|
1564
|
-
slug: {
|
|
1565
|
-
equals: "home"
|
|
1566
|
-
}
|
|
1567
|
-
}
|
|
3607
|
+
where: draft ? homeWhere : { and: [homeWhere, publishedWhere] }
|
|
1568
3608
|
});
|
|
1569
|
-
return homeResult.docs[0] || null;
|
|
3609
|
+
return withStudioDocumentLayout(homeResult.docs[0] || null);
|
|
1570
3610
|
}
|
|
1571
3611
|
return null;
|
|
1572
3612
|
}
|
|
@@ -1576,7 +3616,7 @@ function createPageQueries(getPayloadClient, contentTag = "website-content") {
|
|
|
1576
3616
|
const payload = await getPayloadClient();
|
|
1577
3617
|
return queryPageByPath(payload, path2, false);
|
|
1578
3618
|
},
|
|
1579
|
-
["page-by-path"],
|
|
3619
|
+
["page-by-path", PAGE_QUERY_CACHE_VERSION],
|
|
1580
3620
|
{ tags: [contentTag] }
|
|
1581
3621
|
);
|
|
1582
3622
|
async function getPageBySegments(segments, draft = false) {
|
|
@@ -1656,6 +3696,18 @@ function createSiteQueries(getPayloadClient, contentTag = "website-content") {
|
|
|
1656
3696
|
["footer-global"],
|
|
1657
3697
|
{ tags: [contentTag] }
|
|
1658
3698
|
);
|
|
3699
|
+
const getSocialMediaCached = (0, import_cache2.unstable_cache)(
|
|
3700
|
+
async () => {
|
|
3701
|
+
const payload = await getPayloadClient();
|
|
3702
|
+
const socialMedia = await payload.findGlobal({
|
|
3703
|
+
slug: "social-media",
|
|
3704
|
+
depth: 1
|
|
3705
|
+
});
|
|
3706
|
+
return socialMedia;
|
|
3707
|
+
},
|
|
3708
|
+
["social-media-global"],
|
|
3709
|
+
{ tags: [contentTag] }
|
|
3710
|
+
);
|
|
1659
3711
|
async function getSiteSettings(draft = false) {
|
|
1660
3712
|
if (draft) {
|
|
1661
3713
|
const payload = await getPayloadClient();
|
|
@@ -1692,10 +3744,23 @@ function createSiteQueries(getPayloadClient, contentTag = "website-content") {
|
|
|
1692
3744
|
}
|
|
1693
3745
|
return getFooterCached();
|
|
1694
3746
|
}
|
|
3747
|
+
async function getSocialMedia(draft = false) {
|
|
3748
|
+
if (draft) {
|
|
3749
|
+
const payload = await getPayloadClient();
|
|
3750
|
+
const socialMedia = await payload.findGlobal({
|
|
3751
|
+
slug: "social-media",
|
|
3752
|
+
depth: 1,
|
|
3753
|
+
draft: true
|
|
3754
|
+
});
|
|
3755
|
+
return socialMedia;
|
|
3756
|
+
}
|
|
3757
|
+
return getSocialMediaCached();
|
|
3758
|
+
}
|
|
1695
3759
|
return {
|
|
1696
3760
|
getSiteSettings,
|
|
1697
3761
|
getHeader,
|
|
1698
|
-
getFooter
|
|
3762
|
+
getFooter,
|
|
3763
|
+
getSocialMedia
|
|
1699
3764
|
};
|
|
1700
3765
|
}
|
|
1701
3766
|
|
|
@@ -1704,60 +3769,465 @@ function resolveMedia(media) {
|
|
|
1704
3769
|
if (!media) {
|
|
1705
3770
|
return null;
|
|
1706
3771
|
}
|
|
1707
|
-
if (typeof media === "number" || typeof media === "string") {
|
|
1708
|
-
return null;
|
|
3772
|
+
if (typeof media === "number" || typeof media === "string") {
|
|
3773
|
+
return null;
|
|
3774
|
+
}
|
|
3775
|
+
if (media.url) {
|
|
3776
|
+
return {
|
|
3777
|
+
url: media.url,
|
|
3778
|
+
alt: media.alt || ""
|
|
3779
|
+
};
|
|
3780
|
+
}
|
|
3781
|
+
if (media.filename) {
|
|
3782
|
+
return {
|
|
3783
|
+
url: `/media/${media.filename}`,
|
|
3784
|
+
alt: media.alt || ""
|
|
3785
|
+
};
|
|
3786
|
+
}
|
|
3787
|
+
return null;
|
|
3788
|
+
}
|
|
3789
|
+
|
|
3790
|
+
// src/nextjs/utilities/socialMedia.ts
|
|
3791
|
+
function resolveSocialMediaLinks(data) {
|
|
3792
|
+
const profiles = data?.profiles;
|
|
3793
|
+
if (!profiles || typeof profiles !== "object") {
|
|
3794
|
+
return [];
|
|
3795
|
+
}
|
|
3796
|
+
return SOCIAL_MEDIA_PLATFORMS.reduce((acc, platform) => {
|
|
3797
|
+
const profile = profiles[platform];
|
|
3798
|
+
if (!profile || typeof profile !== "object") {
|
|
3799
|
+
return acc;
|
|
3800
|
+
}
|
|
3801
|
+
const url = typeof profile.url === "string" ? profile.url.trim() : "";
|
|
3802
|
+
if (!url) {
|
|
3803
|
+
return acc;
|
|
3804
|
+
}
|
|
3805
|
+
const icon = typeof profile.icon === "string" && profile.icon.trim().length > 0 ? profile.icon.trim() : SOCIAL_MEDIA_DEFAULT_ICON_BY_PLATFORM[platform];
|
|
3806
|
+
acc.push({
|
|
3807
|
+
icon,
|
|
3808
|
+
label: SOCIAL_MEDIA_PLATFORM_LABELS[platform],
|
|
3809
|
+
platform,
|
|
3810
|
+
url
|
|
3811
|
+
});
|
|
3812
|
+
return acc;
|
|
3813
|
+
}, []);
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3816
|
+
// src/studio-pages/index.ts
|
|
3817
|
+
var studio_pages_exports = {};
|
|
3818
|
+
__export(studio_pages_exports, {
|
|
3819
|
+
createDefaultStudioDocument: () => createDefaultStudioDocument,
|
|
3820
|
+
defaultBuilderThemeTokens: () => defaultBuilderThemeTokens,
|
|
3821
|
+
layoutToStudioDocument: () => layoutToStudioDocument,
|
|
3822
|
+
pageInspectorPanels: () => pageInspectorPanels,
|
|
3823
|
+
pageNodeTypes: () => pageNodeTypes,
|
|
3824
|
+
pagePaletteGroups: () => pagePaletteGroups,
|
|
3825
|
+
pageStudioModuleManifest: () => pageStudioModuleManifest,
|
|
3826
|
+
resolveBuilderThemeTokens: () => resolveBuilderThemeTokens,
|
|
3827
|
+
studioDocumentToLayout: () => studioDocumentToLayout
|
|
3828
|
+
});
|
|
3829
|
+
|
|
3830
|
+
// src/studio-pages/builder/settings-v2/themeTokens.ts
|
|
3831
|
+
var isRecord4 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
3832
|
+
var merge = (base, next) => {
|
|
3833
|
+
if (!next || !isRecord4(next)) {
|
|
3834
|
+
return base;
|
|
3835
|
+
}
|
|
3836
|
+
const merged = { ...base };
|
|
3837
|
+
for (const [key, value] of Object.entries(next)) {
|
|
3838
|
+
if (isRecord4(value) && isRecord4(merged[key])) {
|
|
3839
|
+
merged[key] = merge(merged[key], value);
|
|
3840
|
+
continue;
|
|
3841
|
+
}
|
|
3842
|
+
if (typeof value !== "undefined") {
|
|
3843
|
+
merged[key] = value;
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
return merged;
|
|
3847
|
+
};
|
|
3848
|
+
var resolveBuilderThemeTokens = (layers) => {
|
|
3849
|
+
const withSite = merge(defaultBuilderThemeTokens, layers.site);
|
|
3850
|
+
const withPage = merge(withSite, layers.page);
|
|
3851
|
+
return merge(withPage, layers.block);
|
|
3852
|
+
};
|
|
3853
|
+
|
|
3854
|
+
// src/studio-pages/builder/settings-v2/BlockInspectorRenderer.tsx
|
|
3855
|
+
var import_react2 = require("react");
|
|
3856
|
+
|
|
3857
|
+
// src/studio-pages/builder/ui/Accordion.tsx
|
|
3858
|
+
var import_react = require("react");
|
|
3859
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3860
|
+
|
|
3861
|
+
// src/studio-pages/builder/ui/ImageControls.tsx
|
|
3862
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3863
|
+
|
|
3864
|
+
// src/studio-pages/builder/settings-v2/inspectorSchema.ts
|
|
3865
|
+
var alignOptions = [
|
|
3866
|
+
{ label: "Left", value: "left" },
|
|
3867
|
+
{ label: "Center", value: "center" },
|
|
3868
|
+
{ label: "Right", value: "right" },
|
|
3869
|
+
{ label: "Justify", value: "justify" }
|
|
3870
|
+
];
|
|
3871
|
+
var layoutFieldSet = [];
|
|
3872
|
+
var typographyFieldSet = [
|
|
3873
|
+
{
|
|
3874
|
+
group: "typography",
|
|
3875
|
+
key: "settings.typography.headingAlign",
|
|
3876
|
+
label: "Heading Alignment",
|
|
3877
|
+
options: alignOptions,
|
|
3878
|
+
tags: ["text", "align", "heading"],
|
|
3879
|
+
type: "select"
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
group: "typography",
|
|
3883
|
+
key: "settings.typography.bodyAlign",
|
|
3884
|
+
label: "Body Alignment",
|
|
3885
|
+
options: alignOptions,
|
|
3886
|
+
tags: ["text", "align", "paragraph"],
|
|
3887
|
+
type: "select"
|
|
3888
|
+
},
|
|
3889
|
+
{
|
|
3890
|
+
group: "typography",
|
|
3891
|
+
key: "settings.typography.maxTextWidth",
|
|
3892
|
+
label: "Text Width",
|
|
3893
|
+
options: [
|
|
3894
|
+
{ label: "Auto", value: "auto" },
|
|
3895
|
+
{ label: "Small", value: "sm" },
|
|
3896
|
+
{ label: "Medium", value: "md" },
|
|
3897
|
+
{ label: "Large", value: "lg" },
|
|
3898
|
+
{ label: "Full", value: "full" }
|
|
3899
|
+
],
|
|
3900
|
+
tags: ["readability", "measure", "line length"],
|
|
3901
|
+
type: "select"
|
|
3902
|
+
},
|
|
3903
|
+
{
|
|
3904
|
+
advanced: true,
|
|
3905
|
+
group: "typography",
|
|
3906
|
+
key: "settings.typography.lineHeightPreset",
|
|
3907
|
+
label: "Line Height",
|
|
3908
|
+
options: [
|
|
3909
|
+
{ label: "Tight", value: "tight" },
|
|
3910
|
+
{ label: "Normal", value: "normal" },
|
|
3911
|
+
{ label: "Relaxed", value: "relaxed" }
|
|
3912
|
+
],
|
|
3913
|
+
type: "select"
|
|
3914
|
+
},
|
|
3915
|
+
{
|
|
3916
|
+
advanced: true,
|
|
3917
|
+
group: "typography",
|
|
3918
|
+
key: "settings.typography.letterSpacingPreset",
|
|
3919
|
+
label: "Letter Spacing",
|
|
3920
|
+
options: [
|
|
3921
|
+
{ label: "Tight", value: "tight" },
|
|
3922
|
+
{ label: "Normal", value: "normal" },
|
|
3923
|
+
{ label: "Relaxed", value: "relaxed" }
|
|
3924
|
+
],
|
|
3925
|
+
type: "select"
|
|
3926
|
+
}
|
|
3927
|
+
];
|
|
3928
|
+
var styleFieldSet = [];
|
|
3929
|
+
var commonAdvanced = [
|
|
3930
|
+
{
|
|
3931
|
+
group: "advanced",
|
|
3932
|
+
inlineEditable: false,
|
|
3933
|
+
key: "settings.advanced.editCopyInPanel",
|
|
3934
|
+
label: "Edit Copy In Panel",
|
|
3935
|
+
tags: ["inline", "copy", "text"],
|
|
3936
|
+
type: "checkbox"
|
|
3937
|
+
},
|
|
3938
|
+
{
|
|
3939
|
+
advanced: true,
|
|
3940
|
+
group: "advanced",
|
|
3941
|
+
key: "settings.advanced.hideOnMobile",
|
|
3942
|
+
label: "Hide On Mobile",
|
|
3943
|
+
type: "checkbox"
|
|
3944
|
+
},
|
|
3945
|
+
{
|
|
3946
|
+
advanced: true,
|
|
3947
|
+
group: "advanced",
|
|
3948
|
+
key: "settings.advanced.customClassName",
|
|
3949
|
+
label: "Custom Class Name",
|
|
3950
|
+
type: "text"
|
|
1709
3951
|
}
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
3952
|
+
];
|
|
3953
|
+
var mediaFieldSet = [
|
|
3954
|
+
{
|
|
3955
|
+
group: "media",
|
|
3956
|
+
key: "settings.media.fit",
|
|
3957
|
+
label: "Image Fit",
|
|
3958
|
+
options: [
|
|
3959
|
+
{ label: "Cover", value: "cover" },
|
|
3960
|
+
{ label: "Contain", value: "contain" }
|
|
3961
|
+
],
|
|
3962
|
+
tags: ["image", "media"],
|
|
3963
|
+
type: "select"
|
|
3964
|
+
},
|
|
3965
|
+
{
|
|
3966
|
+
group: "media",
|
|
3967
|
+
key: "settings.media.cornerStyle",
|
|
3968
|
+
label: "Image Corners",
|
|
3969
|
+
options: [
|
|
3970
|
+
{ label: "Rounded", value: "rounded" },
|
|
3971
|
+
{ label: "Square", value: "square" }
|
|
3972
|
+
],
|
|
3973
|
+
tags: ["image", "radius", "corners"],
|
|
3974
|
+
type: "select"
|
|
1715
3975
|
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
3976
|
+
];
|
|
3977
|
+
var inspectorDefinitionByBlockType = {
|
|
3978
|
+
beforeAfter: {
|
|
3979
|
+
blockType: "beforeAfter",
|
|
3980
|
+
fields: [
|
|
3981
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
3982
|
+
{ group: "basics", inlineEditable: true, key: "subtitle", label: "Subtitle", type: "textarea" },
|
|
3983
|
+
{ group: "basics", key: "itemsPerRow", label: "Items Per Row", max: 4, min: 1, type: "number" },
|
|
3984
|
+
...layoutFieldSet,
|
|
3985
|
+
...typographyFieldSet,
|
|
3986
|
+
...styleFieldSet,
|
|
3987
|
+
...commonAdvanced
|
|
3988
|
+
]
|
|
3989
|
+
},
|
|
3990
|
+
bookingEmbed: {
|
|
3991
|
+
blockType: "bookingEmbed",
|
|
3992
|
+
fields: [
|
|
3993
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
3994
|
+
{ group: "basics", inlineEditable: true, key: "description", label: "Description", type: "textarea" },
|
|
3995
|
+
{ group: "basics", inlineEditable: false, key: "buttonLabel", label: "Button Label", type: "text" },
|
|
3996
|
+
{ group: "basics", inlineEditable: false, key: "buttonHref", label: "Button URL", type: "text" },
|
|
3997
|
+
...layoutFieldSet,
|
|
3998
|
+
...typographyFieldSet,
|
|
3999
|
+
...styleFieldSet,
|
|
4000
|
+
...commonAdvanced
|
|
4001
|
+
]
|
|
4002
|
+
},
|
|
4003
|
+
cta: {
|
|
4004
|
+
blockType: "cta",
|
|
4005
|
+
fields: [
|
|
4006
|
+
{ group: "basics", inlineEditable: true, key: "headline", label: "Headline", type: "text" },
|
|
4007
|
+
{ group: "basics", inlineEditable: true, key: "description", label: "Description", type: "textarea" },
|
|
4008
|
+
{ group: "basics", inlineEditable: false, key: "buttonLabel", label: "Button Label", type: "text" },
|
|
4009
|
+
{ group: "basics", inlineEditable: false, key: "buttonHref", label: "Button URL", type: "text" },
|
|
4010
|
+
{
|
|
4011
|
+
group: "basics",
|
|
4012
|
+
key: "style",
|
|
4013
|
+
label: "Variant",
|
|
4014
|
+
options: [
|
|
4015
|
+
{ label: "Light", value: "light" },
|
|
4016
|
+
{ label: "Dark", value: "dark" }
|
|
4017
|
+
],
|
|
4018
|
+
type: "select"
|
|
4019
|
+
},
|
|
4020
|
+
...layoutFieldSet,
|
|
4021
|
+
...typographyFieldSet,
|
|
4022
|
+
...styleFieldSet,
|
|
4023
|
+
...commonAdvanced
|
|
4024
|
+
]
|
|
4025
|
+
},
|
|
4026
|
+
faq: {
|
|
4027
|
+
blockType: "faq",
|
|
4028
|
+
fields: [
|
|
4029
|
+
{ group: "basics", inlineEditable: true, key: "eyebrow", label: "Eyebrow", type: "text" },
|
|
4030
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4031
|
+
...layoutFieldSet,
|
|
4032
|
+
...typographyFieldSet,
|
|
4033
|
+
...styleFieldSet,
|
|
4034
|
+
...commonAdvanced
|
|
4035
|
+
]
|
|
4036
|
+
},
|
|
4037
|
+
featureGrid: {
|
|
4038
|
+
blockType: "featureGrid",
|
|
4039
|
+
fields: [
|
|
4040
|
+
{ group: "basics", inlineEditable: true, key: "eyebrow", label: "Eyebrow", type: "text" },
|
|
4041
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4042
|
+
{
|
|
4043
|
+
group: "basics",
|
|
4044
|
+
key: "variant",
|
|
4045
|
+
label: "Variant",
|
|
4046
|
+
options: [
|
|
4047
|
+
{ label: "Cards", value: "cards" },
|
|
4048
|
+
{ label: "Highlight", value: "highlight" },
|
|
4049
|
+
{ label: "Split List", value: "splitList" },
|
|
4050
|
+
{ label: "Panels", value: "panels" },
|
|
4051
|
+
{ label: "Catalog", value: "catalog" },
|
|
4052
|
+
{ label: "Contact Split", value: "contact" }
|
|
4053
|
+
],
|
|
4054
|
+
type: "select"
|
|
4055
|
+
},
|
|
4056
|
+
{ group: "basics", key: "itemsPerRow", label: "Items Per Row", max: 6, min: 1, type: "number" },
|
|
4057
|
+
...layoutFieldSet,
|
|
4058
|
+
...typographyFieldSet,
|
|
4059
|
+
...mediaFieldSet,
|
|
4060
|
+
...styleFieldSet,
|
|
4061
|
+
...commonAdvanced
|
|
4062
|
+
]
|
|
4063
|
+
},
|
|
4064
|
+
formEmbed: {
|
|
4065
|
+
blockType: "formEmbed",
|
|
4066
|
+
fields: [
|
|
4067
|
+
{ group: "basics", inlineEditable: true, key: "eyebrow", label: "Eyebrow", type: "text" },
|
|
4068
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4069
|
+
{ group: "basics", inlineEditable: true, key: "description", label: "Description", type: "textarea" },
|
|
4070
|
+
{
|
|
4071
|
+
group: "basics",
|
|
4072
|
+
key: "formType",
|
|
4073
|
+
label: "Form Type",
|
|
4074
|
+
options: [{ label: "Quote", value: "quote" }],
|
|
4075
|
+
type: "select"
|
|
4076
|
+
},
|
|
4077
|
+
...layoutFieldSet,
|
|
4078
|
+
...typographyFieldSet,
|
|
4079
|
+
...styleFieldSet,
|
|
4080
|
+
...commonAdvanced
|
|
4081
|
+
]
|
|
4082
|
+
},
|
|
4083
|
+
hero: {
|
|
4084
|
+
blockType: "hero",
|
|
4085
|
+
fields: [
|
|
4086
|
+
{ group: "basics", inlineEditable: true, key: "kicker", label: "Kicker", type: "text" },
|
|
4087
|
+
{ group: "basics", inlineEditable: true, key: "headline", label: "Headline", type: "text" },
|
|
4088
|
+
{ group: "basics", inlineEditable: true, key: "subheadline", label: "Subheadline", type: "textarea" },
|
|
4089
|
+
{
|
|
4090
|
+
group: "basics",
|
|
4091
|
+
key: "variant",
|
|
4092
|
+
label: "Variant",
|
|
4093
|
+
options: [
|
|
4094
|
+
{ label: "Default", value: "default" },
|
|
4095
|
+
{ label: "Centered", value: "centered" }
|
|
4096
|
+
],
|
|
4097
|
+
type: "select"
|
|
4098
|
+
},
|
|
4099
|
+
{
|
|
4100
|
+
group: "basics",
|
|
4101
|
+
key: "heroHeight",
|
|
4102
|
+
label: "Hero Height",
|
|
4103
|
+
options: [
|
|
4104
|
+
{ label: "Small", value: "sm" },
|
|
4105
|
+
{ label: "Medium (Half Screen)", value: "md" },
|
|
4106
|
+
{ label: "Full Screen", value: "full" }
|
|
4107
|
+
],
|
|
4108
|
+
type: "select"
|
|
4109
|
+
},
|
|
4110
|
+
...layoutFieldSet,
|
|
4111
|
+
...typographyFieldSet,
|
|
4112
|
+
...mediaFieldSet,
|
|
4113
|
+
...styleFieldSet,
|
|
4114
|
+
...commonAdvanced
|
|
4115
|
+
]
|
|
4116
|
+
},
|
|
4117
|
+
logoWall: {
|
|
4118
|
+
blockType: "logoWall",
|
|
4119
|
+
fields: [
|
|
4120
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4121
|
+
{ group: "basics", inlineEditable: true, key: "subtitle", label: "Subtitle", type: "textarea" },
|
|
4122
|
+
...layoutFieldSet,
|
|
4123
|
+
...typographyFieldSet,
|
|
4124
|
+
...mediaFieldSet,
|
|
4125
|
+
...styleFieldSet,
|
|
4126
|
+
...commonAdvanced
|
|
4127
|
+
]
|
|
4128
|
+
},
|
|
4129
|
+
media: {
|
|
4130
|
+
blockType: "media",
|
|
4131
|
+
fields: [
|
|
4132
|
+
{ group: "basics", inlineEditable: true, key: "caption", label: "Caption", type: "text" },
|
|
4133
|
+
{
|
|
4134
|
+
group: "basics",
|
|
4135
|
+
key: "size",
|
|
4136
|
+
label: "Size",
|
|
4137
|
+
options: [
|
|
4138
|
+
{ label: "Default", value: "default" },
|
|
4139
|
+
{ label: "Wide", value: "wide" }
|
|
4140
|
+
],
|
|
4141
|
+
type: "select"
|
|
4142
|
+
},
|
|
4143
|
+
...layoutFieldSet,
|
|
4144
|
+
...typographyFieldSet,
|
|
4145
|
+
...mediaFieldSet,
|
|
4146
|
+
...styleFieldSet,
|
|
4147
|
+
...commonAdvanced
|
|
4148
|
+
]
|
|
4149
|
+
},
|
|
4150
|
+
richText: {
|
|
4151
|
+
blockType: "richText",
|
|
4152
|
+
fields: [
|
|
4153
|
+
{
|
|
4154
|
+
group: "basics",
|
|
4155
|
+
key: "variant",
|
|
4156
|
+
label: "Variant",
|
|
4157
|
+
options: [
|
|
4158
|
+
{ label: "Default", value: "default" },
|
|
4159
|
+
{ label: "Quote Banner", value: "quoteBanner" }
|
|
4160
|
+
],
|
|
4161
|
+
type: "select"
|
|
4162
|
+
},
|
|
4163
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4164
|
+
{
|
|
4165
|
+
group: "basics",
|
|
4166
|
+
key: "width",
|
|
4167
|
+
label: "Rich Text Width",
|
|
4168
|
+
options: [
|
|
4169
|
+
{ label: "Normal", value: "normal" },
|
|
4170
|
+
{ label: "Narrow", value: "narrow" }
|
|
4171
|
+
],
|
|
4172
|
+
type: "select"
|
|
4173
|
+
},
|
|
4174
|
+
...layoutFieldSet,
|
|
4175
|
+
...typographyFieldSet,
|
|
4176
|
+
...styleFieldSet,
|
|
4177
|
+
...commonAdvanced
|
|
4178
|
+
]
|
|
4179
|
+
},
|
|
4180
|
+
stats: {
|
|
4181
|
+
blockType: "stats",
|
|
4182
|
+
fields: [
|
|
4183
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4184
|
+
{ group: "basics", inlineEditable: true, key: "subtitle", label: "Subtitle", type: "textarea" },
|
|
4185
|
+
...layoutFieldSet,
|
|
4186
|
+
...typographyFieldSet,
|
|
4187
|
+
...styleFieldSet,
|
|
4188
|
+
...commonAdvanced
|
|
4189
|
+
]
|
|
4190
|
+
},
|
|
4191
|
+
testimonials: {
|
|
4192
|
+
blockType: "testimonials",
|
|
4193
|
+
fields: [
|
|
4194
|
+
{ group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
|
|
4195
|
+
{ group: "basics", key: "visibleCount", label: "Visible At Once", max: 6, min: 1, type: "number" },
|
|
4196
|
+
{ group: "basics", key: "autoRotate", label: "Auto Rotate", type: "checkbox" },
|
|
4197
|
+
{
|
|
4198
|
+
advanced: true,
|
|
4199
|
+
group: "advanced",
|
|
4200
|
+
key: "rotateIntervalSeconds",
|
|
4201
|
+
label: "Rotate Interval Seconds",
|
|
4202
|
+
max: 30,
|
|
4203
|
+
min: 2,
|
|
4204
|
+
type: "number"
|
|
4205
|
+
},
|
|
4206
|
+
...layoutFieldSet,
|
|
4207
|
+
...typographyFieldSet,
|
|
4208
|
+
...styleFieldSet,
|
|
4209
|
+
...commonAdvanced
|
|
4210
|
+
]
|
|
1721
4211
|
}
|
|
1722
|
-
|
|
1723
|
-
}
|
|
4212
|
+
};
|
|
1724
4213
|
|
|
1725
|
-
// src/studio/
|
|
1726
|
-
var
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
migrateStudioDocument: () => migrateStudioDocument,
|
|
1733
|
-
validateStudioDocument: () => validateStudioDocument
|
|
1734
|
-
});
|
|
1735
|
-
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1736
|
-
var makeIssue = (message, path2, code = "studio.invalid") => ({
|
|
1737
|
-
code,
|
|
1738
|
-
message,
|
|
1739
|
-
path: path2,
|
|
1740
|
-
severity: "error"
|
|
1741
|
-
});
|
|
1742
|
-
var createEmptyStudioDocument = (title) => ({
|
|
1743
|
-
metadata: {},
|
|
1744
|
-
schemaVersion: 1,
|
|
1745
|
-
title,
|
|
1746
|
-
nodes: [],
|
|
1747
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1748
|
-
});
|
|
1749
|
-
function assertStudioDocumentV1(input) {
|
|
1750
|
-
if (!isRecord(input)) {
|
|
4214
|
+
// src/studio-pages/builder/settings-v2/BlockInspectorRenderer.tsx
|
|
4215
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4216
|
+
|
|
4217
|
+
// src/studio-pages/migrations.ts
|
|
4218
|
+
var isRecord5 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4219
|
+
var assertPageStudioDocumentV1 = (value) => {
|
|
4220
|
+
if (!isRecord5(value)) {
|
|
1751
4221
|
throw new Error("Studio document must be an object");
|
|
1752
4222
|
}
|
|
1753
|
-
if (
|
|
4223
|
+
if (value.schemaVersion !== 1) {
|
|
1754
4224
|
throw new Error("Unsupported studio schemaVersion");
|
|
1755
4225
|
}
|
|
1756
|
-
if (!Array.isArray(
|
|
4226
|
+
if (!Array.isArray(value.nodes)) {
|
|
1757
4227
|
throw new Error("Studio document nodes must be an array");
|
|
1758
4228
|
}
|
|
1759
|
-
const nodes =
|
|
1760
|
-
if (!
|
|
4229
|
+
const nodes = value.nodes.map((node, index) => {
|
|
4230
|
+
if (!isRecord5(node)) {
|
|
1761
4231
|
throw new Error(`Node at index ${index} must be an object`);
|
|
1762
4232
|
}
|
|
1763
4233
|
if (typeof node.id !== "string" || node.id.length === 0) {
|
|
@@ -1766,116 +4236,50 @@ function assertStudioDocumentV1(input) {
|
|
|
1766
4236
|
if (typeof node.type !== "string" || node.type.length === 0) {
|
|
1767
4237
|
throw new Error(`Node at index ${index} has invalid type`);
|
|
1768
4238
|
}
|
|
1769
|
-
if (!
|
|
4239
|
+
if (!isRecord5(node.data)) {
|
|
1770
4240
|
throw new Error(`Node at index ${index} has invalid data`);
|
|
1771
4241
|
}
|
|
1772
4242
|
return {
|
|
4243
|
+
data: node.data,
|
|
1773
4244
|
id: node.id,
|
|
1774
|
-
type: node.type
|
|
1775
|
-
data: node.data
|
|
4245
|
+
type: node.type
|
|
1776
4246
|
};
|
|
1777
4247
|
});
|
|
1778
4248
|
return {
|
|
1779
|
-
metadata:
|
|
1780
|
-
schemaVersion: 1,
|
|
1781
|
-
title: typeof input.title === "string" ? input.title : void 0,
|
|
4249
|
+
metadata: isRecord5(value.metadata) ? value.metadata : void 0,
|
|
1782
4250
|
nodes,
|
|
1783
|
-
|
|
4251
|
+
schemaVersion: 1,
|
|
4252
|
+
title: typeof value.title === "string" ? value.title : void 0,
|
|
4253
|
+
updatedAt: typeof value.updatedAt === "string" ? value.updatedAt : void 0
|
|
1784
4254
|
};
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
const
|
|
1788
|
-
|
|
1789
|
-
|
|
4255
|
+
};
|
|
4256
|
+
var migratePageNodeToSettingsV2 = (node) => {
|
|
4257
|
+
const normalized = migrateBlockToSettingsV2({
|
|
4258
|
+
blockType: node.type,
|
|
4259
|
+
...node.data
|
|
4260
|
+
});
|
|
4261
|
+
const { blockType: _ignoredBlockType, ...data } = normalized;
|
|
1790
4262
|
return {
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
listInspectorPanels: () => modules.flatMap((mod) => mod.inspectorPanels),
|
|
1794
|
-
listModules: () => [...modules],
|
|
1795
|
-
listPaletteGroups: () => modules.flatMap((mod) => mod.paletteGroups),
|
|
1796
|
-
listNodeTypes: () => [...nodeTypes]
|
|
4263
|
+
...node,
|
|
4264
|
+
data
|
|
1797
4265
|
};
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
const
|
|
1801
|
-
if (document.schemaVersion !== 1) {
|
|
1802
|
-
issues.push(makeIssue("Unsupported schema version", "schemaVersion", "studio.schemaVersion"));
|
|
1803
|
-
}
|
|
1804
|
-
if (!Array.isArray(document.nodes)) {
|
|
1805
|
-
issues.push(makeIssue("Nodes must be an array", "nodes", "studio.nodes"));
|
|
1806
|
-
return issues;
|
|
1807
|
-
}
|
|
1808
|
-
const registry = createStudioRegistry(modules);
|
|
1809
|
-
const nodeIDs = /* @__PURE__ */ new Set();
|
|
1810
|
-
document.nodes.forEach((node, index) => {
|
|
1811
|
-
if (!node.id) {
|
|
1812
|
-
issues.push(makeIssue("Node id is required", `nodes.${index}.id`, "studio.node.id"));
|
|
1813
|
-
}
|
|
1814
|
-
if (nodeIDs.has(node.id)) {
|
|
1815
|
-
issues.push(makeIssue("Node id must be unique", `nodes.${index}.id`, "studio.node.id.duplicate"));
|
|
1816
|
-
}
|
|
1817
|
-
nodeIDs.add(node.id);
|
|
1818
|
-
if (!registry.getNodeTypeByName(node.type)) {
|
|
1819
|
-
issues.push(makeIssue("Unsupported node type", `nodes.${index}.type`, "studio.node.type"));
|
|
1820
|
-
}
|
|
1821
|
-
});
|
|
1822
|
-
for (const module2 of modules) {
|
|
1823
|
-
for (const validate of module2.validators) {
|
|
1824
|
-
issues.push(...validate(document));
|
|
1825
|
-
}
|
|
1826
|
-
}
|
|
1827
|
-
return issues;
|
|
1828
|
-
}
|
|
1829
|
-
function compileStudioDocument(document, modules) {
|
|
1830
|
-
const issues = validateStudioDocument(document, modules);
|
|
1831
|
-
const compilerEntries = modules.filter((mod) => typeof mod.compiler?.compileNode === "function").map((mod) => mod.compiler?.compileNode);
|
|
1832
|
-
const layout = document.nodes.map((node) => {
|
|
1833
|
-
for (const compileNode of compilerEntries) {
|
|
1834
|
-
if (!compileNode) {
|
|
1835
|
-
continue;
|
|
1836
|
-
}
|
|
1837
|
-
const compiled = compileNode(node);
|
|
1838
|
-
if (compiled) {
|
|
1839
|
-
return compiled;
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
return {
|
|
1843
|
-
id: node.id,
|
|
1844
|
-
blockType: node.type,
|
|
1845
|
-
...node.data
|
|
1846
|
-
};
|
|
1847
|
-
});
|
|
4266
|
+
};
|
|
4267
|
+
var migratePageDocumentSettingsToV2 = (value) => {
|
|
4268
|
+
const current = assertPageStudioDocumentV1(value);
|
|
1848
4269
|
return {
|
|
1849
|
-
|
|
1850
|
-
|
|
4270
|
+
...current,
|
|
4271
|
+
nodes: current.nodes.map(migratePageNodeToSettingsV2)
|
|
1851
4272
|
};
|
|
1852
|
-
}
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
let current = value;
|
|
1859
|
-
for (const migration of sorted) {
|
|
1860
|
-
if (!isRecord(current) || current.schemaVersion !== migration.fromVersion) {
|
|
1861
|
-
continue;
|
|
1862
|
-
}
|
|
1863
|
-
current = migration.migrate(current);
|
|
4273
|
+
};
|
|
4274
|
+
var pageStudioMigrations = [
|
|
4275
|
+
{
|
|
4276
|
+
fromVersion: 1,
|
|
4277
|
+
migrate: migratePageDocumentSettingsToV2,
|
|
4278
|
+
toVersion: 1
|
|
1864
4279
|
}
|
|
1865
|
-
|
|
1866
|
-
}
|
|
4280
|
+
];
|
|
1867
4281
|
|
|
1868
4282
|
// src/studio-pages/index.ts
|
|
1869
|
-
var studio_pages_exports = {};
|
|
1870
|
-
__export(studio_pages_exports, {
|
|
1871
|
-
createDefaultStudioDocument: () => createDefaultStudioDocument,
|
|
1872
|
-
layoutToStudioDocument: () => layoutToStudioDocument,
|
|
1873
|
-
pageInspectorPanels: () => pageInspectorPanels,
|
|
1874
|
-
pageNodeTypes: () => pageNodeTypes,
|
|
1875
|
-
pagePaletteGroups: () => pagePaletteGroups,
|
|
1876
|
-
pageStudioModuleManifest: () => pageStudioModuleManifest,
|
|
1877
|
-
studioDocumentToLayout: () => studioDocumentToLayout
|
|
1878
|
-
});
|
|
1879
4283
|
var withSectionStyleDefaults = (value) => ({
|
|
1880
4284
|
...sectionStyleDefaults,
|
|
1881
4285
|
...value
|
|
@@ -1889,9 +4293,13 @@ var defaultNodeData = {
|
|
|
1889
4293
|
title: "Book a Time"
|
|
1890
4294
|
},
|
|
1891
4295
|
beforeAfter: withSectionStyleDefaults({
|
|
4296
|
+
itemsPerRow: 2,
|
|
1892
4297
|
items: [
|
|
1893
4298
|
{
|
|
1894
4299
|
description: "Before and after result summary.",
|
|
4300
|
+
imageCornerStyle: "rounded",
|
|
4301
|
+
imageFit: "cover",
|
|
4302
|
+
imagePosition: "center",
|
|
1895
4303
|
label: "Project One"
|
|
1896
4304
|
}
|
|
1897
4305
|
],
|
|
@@ -1900,11 +4308,14 @@ var defaultNodeData = {
|
|
|
1900
4308
|
}),
|
|
1901
4309
|
cta: {
|
|
1902
4310
|
...withSectionStyleDefaults({}),
|
|
1903
|
-
backgroundColor: "
|
|
4311
|
+
backgroundColor: "",
|
|
4312
|
+
bullets: [],
|
|
1904
4313
|
buttonHref: "/contact",
|
|
1905
4314
|
buttonLabel: "Contact Us",
|
|
1906
4315
|
description: "Optional supporting copy.",
|
|
4316
|
+
eyebrow: "",
|
|
1907
4317
|
headline: "Ready to get started?",
|
|
4318
|
+
imageURL: "",
|
|
1908
4319
|
style: "light"
|
|
1909
4320
|
},
|
|
1910
4321
|
faq: {
|
|
@@ -1914,11 +4325,13 @@ var defaultNodeData = {
|
|
|
1914
4325
|
},
|
|
1915
4326
|
featureGrid: {
|
|
1916
4327
|
...withSectionStyleDefaults({}),
|
|
4328
|
+
itemsPerRow: 3,
|
|
1917
4329
|
items: [
|
|
1918
|
-
{ description: "Explain this point.", icon: "01", title: "Feature One" },
|
|
1919
|
-
{ description: "Explain this point.", icon: "02", title: "Feature Two" },
|
|
1920
|
-
{ description: "Explain this point.", icon: "03", title: "Feature Three" }
|
|
4330
|
+
{ description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
|
|
4331
|
+
{ description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
|
|
4332
|
+
{ description: "Explain this point.", iconType: "badge", icon: "03", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Three" }
|
|
1921
4333
|
],
|
|
4334
|
+
subtitle: "",
|
|
1922
4335
|
title: "Section Title",
|
|
1923
4336
|
variant: "cards"
|
|
1924
4337
|
},
|
|
@@ -1926,13 +4339,28 @@ var defaultNodeData = {
|
|
|
1926
4339
|
...withSectionStyleDefaults({}),
|
|
1927
4340
|
description: "Collect lead details from visitors.",
|
|
1928
4341
|
formType: "quote",
|
|
4342
|
+
submitLabel: "Submit",
|
|
1929
4343
|
title: "Request a Quote"
|
|
1930
4344
|
},
|
|
1931
4345
|
hero: {
|
|
1932
4346
|
...withSectionStyleDefaults({}),
|
|
1933
4347
|
backgroundColor: "",
|
|
4348
|
+
backgroundImageURL: "",
|
|
4349
|
+
backgroundOverlayMode: "none",
|
|
4350
|
+
backgroundOverlayOpacity: 45,
|
|
4351
|
+
backgroundOverlayColor: "#000000",
|
|
4352
|
+
backgroundOverlayGradientFrom: "#334b63",
|
|
4353
|
+
backgroundOverlayGradientTo: "#496582",
|
|
4354
|
+
backgroundOverlayGradientAngle: "135",
|
|
4355
|
+
backgroundOverlayGradientFromStrength: 100,
|
|
4356
|
+
backgroundOverlayGradientToStrength: 100,
|
|
4357
|
+
backgroundOverlayGradientStart: 0,
|
|
4358
|
+
backgroundOverlayGradientEnd: 100,
|
|
4359
|
+
backgroundOverlayGradientFeather: 100,
|
|
4360
|
+
backgroundImageCornerStyle: "rounded",
|
|
1934
4361
|
backgroundImageFit: "cover",
|
|
1935
4362
|
backgroundImagePosition: "center",
|
|
4363
|
+
heroHeight: "sm",
|
|
1936
4364
|
headline: "New Hero Section",
|
|
1937
4365
|
kicker: "Optional kicker",
|
|
1938
4366
|
primaryHref: "/contact",
|
|
@@ -1945,19 +4373,23 @@ var defaultNodeData = {
|
|
|
1945
4373
|
media: {
|
|
1946
4374
|
...withSectionStyleDefaults({}),
|
|
1947
4375
|
caption: "Add a caption",
|
|
4376
|
+
imageCornerStyle: "rounded",
|
|
4377
|
+
imageFit: "cover",
|
|
4378
|
+
imagePosition: "center",
|
|
1948
4379
|
size: "default"
|
|
1949
4380
|
},
|
|
1950
4381
|
logoWall: withSectionStyleDefaults({
|
|
1951
4382
|
items: [
|
|
1952
|
-
{ name: "Trusted Partner 1" },
|
|
1953
|
-
{ name: "Trusted Partner 2" },
|
|
1954
|
-
{ name: "Trusted Partner 3" }
|
|
4383
|
+
{ imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 1" },
|
|
4384
|
+
{ imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 2" },
|
|
4385
|
+
{ imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 3" }
|
|
1955
4386
|
],
|
|
1956
|
-
subtitle: "
|
|
1957
|
-
title: "Trusted by
|
|
4387
|
+
subtitle: "Show logos from trusted associations, partners, or collaborators.",
|
|
4388
|
+
title: "Trusted by Great Partners"
|
|
1958
4389
|
}),
|
|
1959
4390
|
richText: {
|
|
1960
4391
|
...withSectionStyleDefaults({}),
|
|
4392
|
+
cards: [],
|
|
1961
4393
|
content: {
|
|
1962
4394
|
root: {
|
|
1963
4395
|
children: [
|
|
@@ -1987,19 +4419,23 @@ var defaultNodeData = {
|
|
|
1987
4419
|
version: 1
|
|
1988
4420
|
}
|
|
1989
4421
|
},
|
|
4422
|
+
statsItems: [],
|
|
1990
4423
|
title: "Section Heading",
|
|
1991
4424
|
width: "normal"
|
|
1992
4425
|
},
|
|
1993
4426
|
testimonials: {
|
|
1994
4427
|
...withSectionStyleDefaults({}),
|
|
1995
|
-
|
|
1996
|
-
|
|
4428
|
+
autoRotate: true,
|
|
4429
|
+
items: [{ location: "City, ST", name: "Customer Name", quote: "Customer feedback goes here.", rating: 5 }],
|
|
4430
|
+
rotateIntervalSeconds: 7,
|
|
4431
|
+
title: "What Customers Say",
|
|
4432
|
+
visibleCount: 3
|
|
1997
4433
|
},
|
|
1998
4434
|
stats: withSectionStyleDefaults({
|
|
1999
4435
|
items: [
|
|
2000
|
-
{ description: "Average response
|
|
2001
|
-
{ description: "
|
|
2002
|
-
{ description: "
|
|
4436
|
+
{ description: "Average first response", label: "Response Time", value: "24h" },
|
|
4437
|
+
{ description: "Client satisfaction score", label: "Satisfaction", value: "4.9/5" },
|
|
4438
|
+
{ description: "Recent projects or clients served", label: "Recent Work", value: "150+" }
|
|
2003
4439
|
],
|
|
2004
4440
|
subtitle: "Highlight measurable outcomes to build trust quickly.",
|
|
2005
4441
|
title: "Performance Highlights"
|
|
@@ -2023,7 +4459,11 @@ var pageNodeTypes = Object.keys(defaultNodeData).map((type) => ({
|
|
|
2023
4459
|
type,
|
|
2024
4460
|
displayName: nodeTypeLabels[type] || type,
|
|
2025
4461
|
description: `Page node for ${nodeTypeLabels[type] || type}`,
|
|
2026
|
-
getDefaultData: () =>
|
|
4462
|
+
getDefaultData: () => {
|
|
4463
|
+
const migrated = migrateBlockToSettingsV2(structuredClone(defaultNodeData[type]));
|
|
4464
|
+
const { blockType: _ignoredBlockType, ...data } = migrated;
|
|
4465
|
+
return data;
|
|
4466
|
+
}
|
|
2027
4467
|
}));
|
|
2028
4468
|
var validatePageDocument = (document) => {
|
|
2029
4469
|
const issues = [];
|
|
@@ -2075,17 +4515,24 @@ var pagePaletteGroups = [
|
|
|
2075
4515
|
]
|
|
2076
4516
|
}
|
|
2077
4517
|
];
|
|
2078
|
-
var
|
|
2079
|
-
id: `${nodeType}-panel`,
|
|
2080
|
-
label: `${nodeTypeLabels[nodeType] || nodeType} Settings`,
|
|
4518
|
+
var pageInspectorPanelRegistry = Object.keys(defaultNodeData).map((nodeType) => ({
|
|
2081
4519
|
nodeType,
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
4520
|
+
panelID: `${nodeType}-panel`,
|
|
4521
|
+
panelLabel: `${nodeTypeLabels[nodeType] || nodeType} Settings`
|
|
4522
|
+
}));
|
|
4523
|
+
var resolvePanelFields = (nodeType) => inspectorDefinitionByBlockType[nodeType]?.fields.map((field) => ({
|
|
4524
|
+
advanced: field.advanced,
|
|
4525
|
+
group: field.group,
|
|
4526
|
+
inlineEditable: field.inlineEditable,
|
|
4527
|
+
key: field.key,
|
|
4528
|
+
label: field.label,
|
|
4529
|
+
type: field.type
|
|
4530
|
+
})) || [];
|
|
4531
|
+
var pageInspectorPanels = pageInspectorPanelRegistry.map((entry) => ({
|
|
4532
|
+
fields: resolvePanelFields(entry.nodeType),
|
|
4533
|
+
id: entry.panelID,
|
|
4534
|
+
label: entry.panelLabel,
|
|
4535
|
+
nodeType: entry.nodeType
|
|
2089
4536
|
}));
|
|
2090
4537
|
var pageStudioModuleManifest = {
|
|
2091
4538
|
id: "studio-pages",
|
|
@@ -2095,13 +4542,18 @@ var pageStudioModuleManifest = {
|
|
|
2095
4542
|
paletteGroups: pagePaletteGroups,
|
|
2096
4543
|
inspectorPanels: pageInspectorPanels,
|
|
2097
4544
|
validators: [validatePageDocument],
|
|
2098
|
-
migrations:
|
|
4545
|
+
migrations: pageStudioMigrations,
|
|
2099
4546
|
compiler: {
|
|
2100
|
-
compileNode: (node) =>
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
4547
|
+
compileNode: (node) => {
|
|
4548
|
+
const normalized = migrateBlockToSettingsV2({
|
|
4549
|
+
blockType: node.type,
|
|
4550
|
+
...node.data
|
|
4551
|
+
});
|
|
4552
|
+
return {
|
|
4553
|
+
id: node.id,
|
|
4554
|
+
...normalized
|
|
4555
|
+
};
|
|
4556
|
+
}
|
|
2105
4557
|
},
|
|
2106
4558
|
permissions: [
|
|
2107
4559
|
{ action: "read", role: "admin" },
|
|
@@ -2114,42 +4566,6 @@ var pageStudioModuleManifest = {
|
|
|
2114
4566
|
{ action: "publish", role: "editor" }
|
|
2115
4567
|
]
|
|
2116
4568
|
};
|
|
2117
|
-
var ensureNodeID = (inputID, index) => {
|
|
2118
|
-
if (typeof inputID === "string" && inputID.length > 0) {
|
|
2119
|
-
return inputID;
|
|
2120
|
-
}
|
|
2121
|
-
return `node-${index + 1}`;
|
|
2122
|
-
};
|
|
2123
|
-
var layoutToStudioDocument = (layout, title, metadata) => {
|
|
2124
|
-
const nodes = layout.filter((block) => typeof block.blockType === "string").map((block, index) => {
|
|
2125
|
-
const blockType = String(block.blockType);
|
|
2126
|
-
const { id, blockType: _, ...data } = block;
|
|
2127
|
-
return {
|
|
2128
|
-
id: ensureNodeID(id, index),
|
|
2129
|
-
type: blockType,
|
|
2130
|
-
data
|
|
2131
|
-
};
|
|
2132
|
-
});
|
|
2133
|
-
return {
|
|
2134
|
-
metadata,
|
|
2135
|
-
schemaVersion: 1,
|
|
2136
|
-
title,
|
|
2137
|
-
nodes,
|
|
2138
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2139
|
-
};
|
|
2140
|
-
};
|
|
2141
|
-
var studioDocumentToLayout = (document) => document.nodes.map((node) => ({
|
|
2142
|
-
id: node.id,
|
|
2143
|
-
blockType: node.type,
|
|
2144
|
-
...node.data
|
|
2145
|
-
}));
|
|
2146
|
-
var createDefaultStudioDocument = (title) => ({
|
|
2147
|
-
metadata: {},
|
|
2148
|
-
schemaVersion: 1,
|
|
2149
|
-
title,
|
|
2150
|
-
nodes: [],
|
|
2151
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2152
|
-
});
|
|
2153
4569
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2154
4570
|
0 && (module.exports = {
|
|
2155
4571
|
admin,
|