@orion-studios/payload-studio 0.6.0-beta.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +6 -1
  2. package/bin/init.js +329 -0
  3. package/dist/admin/client.js +2106 -585
  4. package/dist/admin/client.mjs +2161 -653
  5. package/dist/admin/index.d.mts +2 -2
  6. package/dist/admin/index.d.ts +2 -2
  7. package/dist/admin/index.js +201 -37
  8. package/dist/admin/index.mjs +2 -2
  9. package/dist/admin-app/client.js +14 -5
  10. package/dist/admin-app/client.mjs +1 -1
  11. package/dist/admin-app/index.d.mts +2 -2
  12. package/dist/admin-app/index.d.ts +2 -2
  13. package/dist/admin-app/styles.css +361 -41
  14. package/dist/admin.css +98 -2
  15. package/dist/blocks/index.mjs +1 -2
  16. package/dist/builder-v2/client.d.mts +18 -0
  17. package/dist/builder-v2/client.d.ts +18 -0
  18. package/dist/builder-v2/client.js +4287 -0
  19. package/dist/builder-v2/client.mjs +4162 -0
  20. package/dist/builder-v2/index.d.mts +249 -0
  21. package/dist/builder-v2/index.d.ts +249 -0
  22. package/dist/builder-v2/index.js +836 -0
  23. package/dist/builder-v2/index.mjs +786 -0
  24. package/dist/builder-v2/styles.css +2705 -0
  25. package/dist/{chunk-PF3EBZXF.mjs → chunk-7ZMXZRBP.mjs} +39 -3
  26. package/dist/{chunk-XKUTZ7IU.mjs → chunk-DTHBPJXU.mjs} +246 -25
  27. package/dist/{chunk-JQAHXYAM.mjs → chunk-KMYMSR7W.mjs} +163 -3
  28. package/dist/{chunk-5FNTVRCR.mjs → chunk-MMJNHBOF.mjs} +204 -40
  29. package/dist/{chunk-KPIX7OSV.mjs → chunk-NF37A575.mjs} +14 -5
  30. package/dist/{chunk-OTHERBGX.mjs → chunk-OF6BATTO.mjs} +57 -112
  31. package/dist/chunk-VA545CHJ.mjs +202 -0
  32. package/dist/forms/index.d.mts +25 -0
  33. package/dist/forms/index.d.ts +25 -0
  34. package/dist/forms/index.js +237 -0
  35. package/dist/forms/index.mjs +25 -0
  36. package/dist/forms/server.d.mts +35 -0
  37. package/dist/forms/server.d.ts +35 -0
  38. package/dist/forms/server.js +442 -0
  39. package/dist/forms/server.mjs +228 -0
  40. package/dist/{index-Crx_MtPw.d.ts → index-0xXWuOuz.d.ts} +38 -6
  41. package/dist/{index-Cv-6qnrw.d.mts → index-BU82akSL.d.mts} +38 -6
  42. package/dist/{index-DyMmaRfI.d.mts → index-BbTcimgH.d.mts} +5 -2
  43. package/dist/{index-D8BNfUJb.d.mts → index-Cen-9wcc.d.mts} +17 -5
  44. package/dist/{index-52HdVLQq.d.ts → index-DAdN56fM.d.ts} +1 -1
  45. package/dist/{index-QPDAedIX.d.ts → index-DV-nW43e.d.ts} +5 -2
  46. package/dist/{index-DEQC3Dwj.d.mts → index-G_uTNffQ.d.mts} +1 -1
  47. package/dist/{index-DD_E2UfJ.d.ts → index-gxcMPpm-.d.ts} +17 -5
  48. package/dist/index.d.mts +5 -5
  49. package/dist/index.d.ts +5 -5
  50. package/dist/index.js +533 -172
  51. package/dist/index.mjs +10 -11
  52. package/dist/nextjs/index.d.mts +1 -1
  53. package/dist/nextjs/index.d.ts +1 -1
  54. package/dist/nextjs/index.js +95 -114
  55. package/dist/nextjs/index.mjs +2 -2
  56. package/dist/{sitePreviewTypes-BkHCWxNW.d.mts → sitePreviewTypes-BrJwGzJj.d.mts} +1 -1
  57. package/dist/{sitePreviewTypes-BkHCWxNW.d.ts → sitePreviewTypes-BrJwGzJj.d.ts} +1 -1
  58. package/dist/studio-pages/builder.css +66 -5
  59. package/dist/studio-pages/client.js +618 -73
  60. package/dist/studio-pages/client.mjs +641 -96
  61. package/dist/studio-pages/index.d.mts +1 -1
  62. package/dist/studio-pages/index.d.ts +1 -1
  63. package/dist/studio-pages/index.js +1893 -24
  64. package/dist/studio-pages/index.mjs +11 -3
  65. package/package.json +38 -3
  66. package/dist/chunk-OQSEJXC4.mjs +0 -166
@@ -40,7 +40,9 @@ var defaultBuilderBlockSettingsV2 = {
40
40
  },
41
41
  typography: {
42
42
  bodyAlign: "left",
43
+ bodySizePt: null,
43
44
  headingAlign: "left",
45
+ headingSizePt: null,
44
46
  letterSpacingPreset: "normal",
45
47
  lineHeightPreset: "normal",
46
48
  maxTextWidth: "auto"
@@ -69,7 +71,9 @@ var defaultBuilderItemSettingsV2 = {
69
71
  },
70
72
  typography: {
71
73
  bodyAlign: "left",
74
+ bodySizePt: null,
72
75
  headingAlign: "left",
76
+ headingSizePt: null,
73
77
  letterSpacingPreset: "normal",
74
78
  lineHeightPreset: "normal",
75
79
  maxTextWidth: "auto"
@@ -99,6 +103,7 @@ var defaultBuilderThemeTokens = {
99
103
 
100
104
  // src/studio-pages/builder/adapters/settingsV2.ts
101
105
  var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
106
+ var isTextAlign = (value) => value === "left" || value === "center" || value === "right" || value === "justify";
102
107
  var parsePercent = (value) => {
103
108
  if (typeof value === "number" && Number.isFinite(value)) {
104
109
  return Math.max(0, Math.min(100, value));
@@ -123,6 +128,18 @@ var parsePixel = (value) => {
123
128
  }
124
129
  return null;
125
130
  };
131
+ var parsePoint = (value) => {
132
+ if (typeof value === "number" && Number.isFinite(value)) {
133
+ return Math.max(6, Math.min(120, Math.round(value)));
134
+ }
135
+ if (typeof value === "string" && value.trim().length > 0) {
136
+ const parsed = Number(value);
137
+ if (Number.isFinite(parsed)) {
138
+ return Math.max(6, Math.min(120, Math.round(parsed)));
139
+ }
140
+ }
141
+ return null;
142
+ };
126
143
  var mergeSettings = (defaults, input) => {
127
144
  if (!isRecord(input)) {
128
145
  return structuredClone(defaults);
@@ -141,6 +158,10 @@ var mergeSettings = (defaults, input) => {
141
158
  };
142
159
  var legacyBlockToV2Settings = (block) => {
143
160
  const current = structuredClone(defaultBuilderBlockSettingsV2);
161
+ if (block.blockType === "hero" && block.variant === "centered") {
162
+ current.typography.headingAlign = "center";
163
+ current.typography.bodyAlign = "center";
164
+ }
144
165
  current.layout.contentWidth = block.contentWidth === "narrow" || block.contentWidth === "content" || block.contentWidth === "wide" || block.contentWidth === "full" || block.contentWidth === "inherit" ? block.contentWidth : current.layout.contentWidth;
145
166
  current.layout.sectionPaddingX = block.sectionPaddingX === "none" || block.sectionPaddingX === "sm" || block.sectionPaddingX === "md" || block.sectionPaddingX === "lg" || block.sectionPaddingX === "inherit" ? block.sectionPaddingX : current.layout.sectionPaddingX;
146
167
  current.layout.sectionPaddingY = block.sectionPaddingY === "none" || block.sectionPaddingY === "sm" || block.sectionPaddingY === "lg" ? block.sectionPaddingY : current.layout.sectionPaddingY;
@@ -177,15 +198,28 @@ var legacyBlockToV2Settings = (block) => {
177
198
  current.media.positionX = parsePercent(block.imagePositionX ?? block.backgroundImagePositionX);
178
199
  current.media.positionY = parsePercent(block.imagePositionY ?? block.backgroundImagePositionY);
179
200
  current.media.height = parsePixel(block.imageHeight);
180
- current.typography.headingAlign = block.textHeadingAlign === "left" || block.textHeadingAlign === "center" || block.textHeadingAlign === "right" || block.textHeadingAlign === "justify" ? block.textHeadingAlign : current.typography.headingAlign;
181
- current.typography.bodyAlign = block.textBodyAlign === "left" || block.textBodyAlign === "center" || block.textBodyAlign === "right" || block.textBodyAlign === "justify" ? block.textBodyAlign : current.typography.bodyAlign;
201
+ current.typography.headingAlign = isTextAlign(block.textHeadingAlign) ? block.textHeadingAlign : current.typography.headingAlign;
202
+ current.typography.bodyAlign = isTextAlign(block.textBodyAlign) ? block.textBodyAlign : current.typography.bodyAlign;
203
+ current.typography.headingSizePt = parsePoint(block.textHeadingSizePt);
204
+ current.typography.bodySizePt = parsePoint(block.textBodySizePt);
182
205
  current.typography.maxTextWidth = block.textMaxWidth === "auto" || block.textMaxWidth === "sm" || block.textMaxWidth === "md" || block.textMaxWidth === "lg" || block.textMaxWidth === "full" ? block.textMaxWidth : current.typography.maxTextWidth;
183
206
  current.typography.lineHeightPreset = block.textLineHeightPreset === "tight" || block.textLineHeightPreset === "normal" || block.textLineHeightPreset === "relaxed" ? block.textLineHeightPreset : current.typography.lineHeightPreset;
184
207
  current.typography.letterSpacingPreset = block.textLetterSpacingPreset === "tight" || block.textLetterSpacingPreset === "normal" || block.textLetterSpacingPreset === "relaxed" ? block.textLetterSpacingPreset : current.typography.letterSpacingPreset;
185
208
  current.advanced.editCopyInPanel = Boolean(block.editCopyInPanel ?? current.advanced.editCopyInPanel);
186
209
  current.advanced.customClassName = typeof block.customClassName === "string" ? block.customClassName : current.advanced.customClassName;
187
210
  current.advanced.hideOnMobile = Boolean(block.hideOnMobile ?? current.advanced.hideOnMobile);
188
- return mergeSettings(current, block.settings);
211
+ const settings = mergeSettings(current, block.settings);
212
+ if (block.blockType === "hero") {
213
+ const top = settings.layout.paddingTopPt;
214
+ const bottom = settings.layout.paddingBottomPt;
215
+ const hasLegacyLinkedHeroPadding = settings.layout.linkVerticalPadding !== false && (top === null || typeof top === "undefined" || top === 30) && (bottom === null || typeof bottom === "undefined" || bottom === 30 || bottom === 20);
216
+ if (hasLegacyLinkedHeroPadding) {
217
+ settings.layout.linkVerticalPadding = false;
218
+ settings.layout.paddingTopPt = 30;
219
+ settings.layout.paddingBottomPt = 20;
220
+ }
221
+ }
222
+ return settings;
189
223
  };
190
224
  var v2SettingsToLegacyBlock = (blockWithSettings) => {
191
225
  const settings = legacyBlockToV2Settings(blockWithSettings);
@@ -211,6 +245,8 @@ var v2SettingsToLegacyBlock = (blockWithSettings) => {
211
245
  next.contentGradientAngle = settings.appearance.contentGradientAngle;
212
246
  next.textHeadingAlign = settings.typography.headingAlign;
213
247
  next.textBodyAlign = settings.typography.bodyAlign;
248
+ next.textHeadingSizePt = settings.typography.headingSizePt;
249
+ next.textBodySizePt = settings.typography.bodySizePt;
214
250
  next.textMaxWidth = settings.typography.maxTextWidth;
215
251
  next.textLineHeightPreset = settings.typography.lineHeightPreset;
216
252
  next.textLetterSpacingPreset = settings.typography.letterSpacingPreset;
@@ -1,19 +1,20 @@
1
- import {
2
- sectionStyleDefaults
3
- } from "./chunk-OQSEJXC4.mjs";
4
1
  import {
5
2
  createDefaultStudioDocument,
6
3
  defaultBuilderThemeTokens,
7
4
  layoutToStudioDocument,
8
5
  migrateBlockToSettingsV2,
9
6
  studioDocumentToLayout
10
- } from "./chunk-PF3EBZXF.mjs";
7
+ } from "./chunk-7ZMXZRBP.mjs";
11
8
  import {
12
9
  assertStudioDocumentV1,
13
10
  compileStudioDocument,
14
11
  createEmptyStudioDocument,
15
12
  validateStudioDocument
16
13
  } from "./chunk-ADIIWIYL.mjs";
14
+ import {
15
+ defaultPageLayoutBlocks,
16
+ sectionStyleDefaults
17
+ } from "./chunk-KMYMSR7W.mjs";
17
18
  import {
18
19
  __export
19
20
  } from "./chunk-6BWS3CLP.mjs";
@@ -21,9 +22,13 @@ import {
21
22
  // src/studio-pages/index.ts
22
23
  var studio_pages_exports = {};
23
24
  __export(studio_pages_exports, {
25
+ DEFAULT_LEGACY_HERO_BACKGROUND_COLORS: () => DEFAULT_LEGACY_HERO_BACKGROUND_COLORS,
24
26
  createDefaultStudioDocument: () => createDefaultStudioDocument,
27
+ createStudioPageFields: () => createStudioPageFields,
25
28
  createStudioPageService: () => createStudioPageService,
29
+ createStudioPagesCollection: () => createStudioPagesCollection,
26
30
  defaultBuilderThemeTokens: () => defaultBuilderThemeTokens,
31
+ defaultRelationshipHydrationMap: () => defaultRelationshipHydrationMap,
27
32
  getStudioDocumentFromPage: () => getStudioDocumentFromPage,
28
33
  layoutToStudioDocument: () => layoutToStudioDocument,
29
34
  pageInspectorPanels: () => pageInspectorPanels,
@@ -66,8 +71,52 @@ var alignOptions = [
66
71
  { label: "Right", value: "right" },
67
72
  { label: "Justify", value: "justify" }
68
73
  ];
69
- var layoutFieldSet = [];
74
+ var layoutFieldSet = [
75
+ {
76
+ group: "layout",
77
+ key: "settings.layout.linkVerticalPadding",
78
+ label: "Link Top/Bottom Padding",
79
+ tags: ["spacing", "padding", "vertical"],
80
+ type: "checkbox"
81
+ },
82
+ {
83
+ group: "layout",
84
+ key: "settings.layout.paddingTopPt",
85
+ label: "Top Padding (pt)",
86
+ max: 240,
87
+ min: 0,
88
+ tags: ["spacing", "padding", "top"],
89
+ type: "number"
90
+ },
91
+ {
92
+ group: "layout",
93
+ key: "settings.layout.paddingBottomPt",
94
+ label: "Bottom Padding (pt)",
95
+ max: 240,
96
+ min: 0,
97
+ tags: ["spacing", "padding", "bottom"],
98
+ type: "number"
99
+ }
100
+ ];
70
101
  var typographyFieldSet = [
102
+ {
103
+ group: "typography",
104
+ key: "settings.typography.headingSizePt",
105
+ label: "Heading Text Size (pt)",
106
+ max: 120,
107
+ min: 6,
108
+ tags: ["text", "size", "heading", "font"],
109
+ type: "number"
110
+ },
111
+ {
112
+ group: "typography",
113
+ key: "settings.typography.bodySizePt",
114
+ label: "Body Text Size (pt)",
115
+ max: 72,
116
+ min: 6,
117
+ tags: ["text", "size", "body", "paragraph", "font"],
118
+ type: "number"
119
+ },
71
120
  {
72
121
  group: "typography",
73
122
  key: "settings.typography.headingAlign",
@@ -284,6 +333,13 @@ var inspectorDefinitionByBlockType = {
284
333
  { group: "basics", inlineEditable: true, key: "kicker", label: "Kicker", type: "text" },
285
334
  { group: "basics", inlineEditable: true, key: "headline", label: "Headline", type: "text" },
286
335
  { group: "basics", inlineEditable: true, key: "subheadline", label: "Subheadline", type: "textarea" },
336
+ {
337
+ group: "basics",
338
+ key: "settings.marquee.itemsText",
339
+ label: "Scrolling Bar Options",
340
+ tags: ["marquee", "scrolling", "bar", "categories"],
341
+ type: "textarea"
342
+ },
287
343
  {
288
344
  group: "basics",
289
345
  key: "variant",
@@ -410,6 +466,13 @@ var inspectorDefinitionByBlockType = {
410
466
  };
411
467
 
412
468
  // src/studio-pages/pageService.ts
469
+ var defaultRelationshipHydrationMap = {
470
+ beforeAfter: { arrays: { items: ["media", "beforeMedia", "afterMedia"] } },
471
+ featureGrid: { arrays: { items: ["media", "beforeMedia", "afterMedia"] } },
472
+ hero: { fields: ["media"] },
473
+ logoWall: { arrays: { items: ["media", "beforeMedia", "afterMedia"] } },
474
+ media: { fields: ["image"] }
475
+ };
413
476
  var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
414
477
  var toRecordArray = (value) => Array.isArray(value) ? value.filter((item) => isRecord2(item)) : [];
415
478
  var getRelationID = (value) => {
@@ -437,7 +500,7 @@ var hydrateRelationship = (valueFromStudio, valueFromLayout) => {
437
500
  }
438
501
  return valueFromLayout;
439
502
  };
440
- var hydrateDocumentWithLayoutRelations = (document, layout) => {
503
+ var hydrateDocumentWithLayoutRelations = (document, layout, hydrationMap = defaultRelationshipHydrationMap) => {
441
504
  const nextNodes = document.nodes.map((node, index) => {
442
505
  const layoutBlock = layout[index];
443
506
  if (!isRecord2(layoutBlock)) {
@@ -446,17 +509,18 @@ var hydrateDocumentWithLayoutRelations = (document, layout) => {
446
509
  if (typeof layoutBlock.blockType !== "string" || layoutBlock.blockType !== node.type) {
447
510
  return node;
448
511
  }
449
- const nextData = { ...node.data };
450
- if (node.type === "hero") {
451
- nextData.media = hydrateRelationship(nextData.media, layoutBlock.media);
512
+ const rule = hydrationMap[node.type];
513
+ if (!rule) {
514
+ return node;
452
515
  }
453
- if (node.type === "media") {
454
- nextData.image = hydrateRelationship(nextData.image, layoutBlock.image);
516
+ const nextData = { ...node.data };
517
+ for (const fieldName of rule.fields || []) {
518
+ nextData[fieldName] = hydrateRelationship(nextData[fieldName], layoutBlock[fieldName]);
455
519
  }
456
- if (node.type === "featureGrid" || node.type === "logoWall" || node.type === "beforeAfter") {
457
- const studioItems = Array.isArray(nextData.items) ? nextData.items : [];
458
- const layoutItems = Array.isArray(layoutBlock.items) ? layoutBlock.items : [];
459
- nextData.items = studioItems.map((rawStudioItem, itemIndex) => {
520
+ for (const [arrayField, itemFields] of Object.entries(rule.arrays || {})) {
521
+ const studioItems = Array.isArray(nextData[arrayField]) ? nextData[arrayField] : [];
522
+ const layoutItems = Array.isArray(layoutBlock[arrayField]) ? layoutBlock[arrayField] : [];
523
+ nextData[arrayField] = studioItems.map((rawStudioItem, itemIndex) => {
460
524
  if (!isRecord2(rawStudioItem)) {
461
525
  return rawStudioItem;
462
526
  }
@@ -465,9 +529,9 @@ var hydrateDocumentWithLayoutRelations = (document, layout) => {
465
529
  return rawStudioItem;
466
530
  }
467
531
  const nextItem = { ...rawStudioItem };
468
- nextItem.media = hydrateRelationship(nextItem.media, layoutItem.media);
469
- nextItem.beforeMedia = hydrateRelationship(nextItem.beforeMedia, layoutItem.beforeMedia);
470
- nextItem.afterMedia = hydrateRelationship(nextItem.afterMedia, layoutItem.afterMedia);
532
+ for (const itemField of itemFields) {
533
+ nextItem[itemField] = hydrateRelationship(nextItem[itemField], layoutItem[itemField]);
534
+ }
471
535
  return nextItem;
472
536
  });
473
537
  }
@@ -486,7 +550,12 @@ var normalizeDocument = (document) => ({
486
550
  schemaVersion: 1,
487
551
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
488
552
  });
489
- var normalizeLegacyHeroDefaults = (document) => {
553
+ var DEFAULT_LEGACY_HERO_BACKGROUND_COLORS = ["#124a37"];
554
+ var normalizeLegacyHeroDefaults = (document, legacyColors = DEFAULT_LEGACY_HERO_BACKGROUND_COLORS) => {
555
+ if (legacyColors.length === 0) {
556
+ return document;
557
+ }
558
+ const normalizedLegacyColors = legacyColors.map((color) => color.trim().toLowerCase());
490
559
  const nodes = document.nodes.map((node) => {
491
560
  if (node.type !== "hero" || !isRecord2(node.data)) {
492
561
  return node;
@@ -496,7 +565,7 @@ var normalizeLegacyHeroDefaults = (document) => {
496
565
  const sectionBackgroundMode = typeof nextData.sectionBackgroundMode === "string" ? nextData.sectionBackgroundMode : "none";
497
566
  const hasBackgroundImageURL = typeof nextData.backgroundImageURL === "string" && nextData.backgroundImageURL.trim().length > 0;
498
567
  const mediaRelation = getRelationID(nextData.media);
499
- if (heroBackgroundColor === "#124a37" && sectionBackgroundMode === "none" && !hasBackgroundImageURL && mediaRelation === null) {
568
+ if (normalizedLegacyColors.includes(heroBackgroundColor) && sectionBackgroundMode === "none" && !hasBackgroundImageURL && mediaRelation === null) {
500
569
  nextData.backgroundColor = "";
501
570
  }
502
571
  return {
@@ -515,13 +584,13 @@ var assertCanPublish = (issues) => {
515
584
  throw new Error(`Cannot publish page: ${publishErrors[0].message}`);
516
585
  }
517
586
  };
518
- var getStudioDocumentFromPage = (doc) => {
587
+ var getStudioDocumentFromPage = (doc, relationshipHydration = defaultRelationshipHydrationMap) => {
519
588
  const title = typeof doc.title === "string" ? doc.title : void 0;
520
589
  const layout = asLayoutArray(doc.layout);
521
590
  try {
522
591
  const studioDocument = assertStudioDocumentV1(doc.studioDocument);
523
592
  if (layout.length > 0) {
524
- return hydrateDocumentWithLayoutRelations(studioDocument, layout);
593
+ return hydrateDocumentWithLayoutRelations(studioDocument, layout, relationshipHydration);
525
594
  }
526
595
  return studioDocument;
527
596
  } catch {
@@ -533,8 +602,10 @@ var getStudioDocumentFromPage = (doc) => {
533
602
  };
534
603
  var createStudioPageService = ({
535
604
  collectionSlug = "pages",
605
+ legacyHeroBackgroundColors = DEFAULT_LEGACY_HERO_BACKGROUND_COLORS,
536
606
  modules,
537
607
  payload,
608
+ relationshipHydration = defaultRelationshipHydrationMap,
538
609
  user
539
610
  }) => ({
540
611
  getPageForStudio: async (pageID) => {
@@ -546,7 +617,7 @@ var createStudioPageService = ({
546
617
  overrideAccess: false,
547
618
  user
548
619
  });
549
- const studioDocument = getStudioDocumentFromPage(page);
620
+ const studioDocument = getStudioDocumentFromPage(page, relationshipHydration);
550
621
  return {
551
622
  id: String(page.id),
552
623
  slug: typeof page.slug === "string" ? page.slug : "",
@@ -556,7 +627,10 @@ var createStudioPageService = ({
556
627
  },
557
628
  validateStudioDocument: (document) => validateStudioDocument(document, modules),
558
629
  saveDraft: async (pageID, document, _metadata) => {
559
- const normalizedDocument = normalizeLegacyHeroDefaults(normalizeDocument(document));
630
+ const normalizedDocument = normalizeLegacyHeroDefaults(
631
+ normalizeDocument(document),
632
+ legacyHeroBackgroundColors
633
+ );
560
634
  const compileResult = compileStudioDocument(normalizedDocument, modules);
561
635
  await payload.update({
562
636
  collection: collectionSlug,
@@ -577,7 +651,10 @@ var createStudioPageService = ({
577
651
  };
578
652
  },
579
653
  publish: async (pageID, document, _metadata) => {
580
- const normalizedDocument = normalizeLegacyHeroDefaults(normalizeDocument(document));
654
+ const normalizedDocument = normalizeLegacyHeroDefaults(
655
+ normalizeDocument(document),
656
+ legacyHeroBackgroundColors
657
+ );
581
658
  const compileResult = compileStudioDocument(normalizedDocument, modules);
582
659
  assertCanPublish(compileResult.issues);
583
660
  await payload.update({
@@ -606,6 +683,146 @@ var toEditorInitialDoc = (payloadPage) => ({
606
683
  title: payloadPage.title
607
684
  });
608
685
 
686
+ // src/studio-pages/pageFields.ts
687
+ var formatSlugValue = (value) => {
688
+ if (typeof value !== "string") return void 0;
689
+ return value.trim().toLowerCase().replace(/[^a-z0-9/]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
690
+ };
691
+ function createStudioPageFields(options = {}) {
692
+ const {
693
+ blocks = defaultPageLayoutBlocks,
694
+ mediaCollectionSlug = "media",
695
+ additionalFields = []
696
+ } = options;
697
+ return [
698
+ {
699
+ name: "title",
700
+ type: "text",
701
+ required: true
702
+ },
703
+ {
704
+ name: "slug",
705
+ type: "text",
706
+ admin: {
707
+ description: "URL identifier for this page. `home` is served at `/`.",
708
+ position: "sidebar"
709
+ },
710
+ hooks: {
711
+ beforeValidate: [({ value }) => formatSlugValue(value) ?? value]
712
+ },
713
+ index: true,
714
+ required: true,
715
+ unique: true
716
+ },
717
+ {
718
+ name: "path",
719
+ type: "text",
720
+ admin: {
721
+ description: "Full public path. Derived from the slug when left empty.",
722
+ position: "sidebar"
723
+ },
724
+ hooks: {
725
+ beforeValidate: [
726
+ ({ value, data }) => {
727
+ if (typeof value === "string" && value.trim().length > 0) {
728
+ return value.trim();
729
+ }
730
+ const slug = formatSlugValue(data?.slug);
731
+ if (!slug) return value;
732
+ return slug === "home" ? "/" : `/${slug}`;
733
+ }
734
+ ]
735
+ },
736
+ index: true,
737
+ unique: true
738
+ },
739
+ {
740
+ name: "studioDocument",
741
+ type: "json",
742
+ admin: {
743
+ description: "Canonical Studio editor state. Managed by the page builder.",
744
+ hidden: true
745
+ }
746
+ },
747
+ {
748
+ name: "studioValidationIssues",
749
+ type: "json",
750
+ admin: {
751
+ description: "Validation issues from the last Studio compile. Managed by the page builder.",
752
+ hidden: true
753
+ }
754
+ },
755
+ {
756
+ name: "layout",
757
+ type: "blocks",
758
+ admin: {
759
+ description: "Compiled output only \u2014 edit pages through the Studio builder."
760
+ },
761
+ blocks
762
+ },
763
+ {
764
+ name: "seo",
765
+ type: "group",
766
+ fields: [
767
+ { name: "metaTitle", type: "text" },
768
+ { name: "metaDescription", type: "textarea" },
769
+ { name: "canonicalUrl", type: "text" },
770
+ {
771
+ name: "ogImage",
772
+ type: "upload",
773
+ relationTo: mediaCollectionSlug
774
+ }
775
+ ]
776
+ },
777
+ {
778
+ name: "noIndex",
779
+ type: "checkbox",
780
+ admin: { position: "sidebar" },
781
+ defaultValue: false
782
+ },
783
+ {
784
+ name: "noFollow",
785
+ type: "checkbox",
786
+ admin: { position: "sidebar" },
787
+ defaultValue: false
788
+ },
789
+ ...additionalFields
790
+ ];
791
+ }
792
+ function createStudioPagesCollection(options = {}) {
793
+ const { slug = "pages", access, overrides, ...fieldOptions } = options;
794
+ const base = {
795
+ slug,
796
+ access: access || {
797
+ create: ({ req }) => Boolean(req.user),
798
+ delete: ({ req }) => Boolean(req.user),
799
+ read: ({ req }) => {
800
+ if (req.user) return true;
801
+ return { _status: { equals: "published" } };
802
+ },
803
+ update: ({ req }) => Boolean(req.user)
804
+ },
805
+ admin: {
806
+ defaultColumns: ["title", "slug", "_status", "updatedAt"],
807
+ useAsTitle: "title"
808
+ },
809
+ fields: createStudioPageFields(fieldOptions),
810
+ versions: {
811
+ drafts: {
812
+ autosave: false
813
+ },
814
+ maxPerDoc: 50
815
+ }
816
+ };
817
+ if (!overrides) return base;
818
+ return {
819
+ ...base,
820
+ ...overrides,
821
+ admin: { ...base.admin, ...overrides.admin },
822
+ fields: overrides.fields || base.fields
823
+ };
824
+ }
825
+
609
826
  // src/studio-pages/migrations.ts
610
827
  var isRecord3 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
611
828
  var assertPageStudioDocumentV1 = (value) => {
@@ -961,9 +1178,13 @@ var pageStudioModuleManifest = {
961
1178
 
962
1179
  export {
963
1180
  resolveBuilderThemeTokens,
1181
+ defaultRelationshipHydrationMap,
1182
+ DEFAULT_LEGACY_HERO_BACKGROUND_COLORS,
964
1183
  getStudioDocumentFromPage,
965
1184
  createStudioPageService,
966
1185
  toEditorInitialDoc,
1186
+ createStudioPageFields,
1187
+ createStudioPagesCollection,
967
1188
  pageNodeTypes,
968
1189
  pagePaletteGroups,
969
1190
  pageInspectorPanels,
@@ -1,6 +1,3 @@
1
- import {
2
- sectionStyleFields
3
- } from "./chunk-OQSEJXC4.mjs";
4
1
  import {
5
2
  __export
6
3
  } from "./chunk-6BWS3CLP.mjs";
@@ -34,6 +31,168 @@ var builderBlockLabelComponent = {
34
31
  path: "@orion-studios/payload-studio/blocks"
35
32
  };
36
33
 
34
+ // src/blocks/blocks/sectionStyleFields.ts
35
+ var sectionStyleDefaults = {
36
+ contentBackgroundColor: "#ffffff",
37
+ contentBackgroundMode: "none",
38
+ contentGradientAngle: "135",
39
+ contentGradientFrom: "#ffffff",
40
+ contentGradientPreset: "none",
41
+ contentGradientTo: "#f4f6f8",
42
+ contentWidth: "inherit",
43
+ sectionPaddingX: "inherit",
44
+ sectionBackgroundColor: "#ffffff",
45
+ sectionBackgroundMode: "none",
46
+ sectionGradientAngle: "135",
47
+ sectionGradientFrom: "#334b63",
48
+ sectionGradientPreset: "slate",
49
+ sectionGradientTo: "#496582",
50
+ sectionPaddingY: "md",
51
+ sectionWidth: "content"
52
+ };
53
+ var hideFromCMS = (field) => ({
54
+ ...field,
55
+ admin: {
56
+ ...field.admin || {},
57
+ hidden: true
58
+ }
59
+ });
60
+ var sectionStyleFields = () => {
61
+ const fields = [
62
+ {
63
+ name: "sectionWidth",
64
+ type: "select",
65
+ defaultValue: sectionStyleDefaults.sectionWidth,
66
+ options: [
67
+ { label: "Content", value: "content" },
68
+ { label: "Wide", value: "wide" },
69
+ { label: "Full", value: "full" }
70
+ ]
71
+ },
72
+ {
73
+ name: "contentWidth",
74
+ type: "select",
75
+ defaultValue: sectionStyleDefaults.contentWidth,
76
+ options: [
77
+ { label: "Inherit", value: "inherit" },
78
+ { label: "Narrow", value: "narrow" },
79
+ { label: "Content", value: "content" },
80
+ { label: "Wide", value: "wide" },
81
+ { label: "Full", value: "full" }
82
+ ]
83
+ },
84
+ {
85
+ name: "sectionPaddingY",
86
+ type: "select",
87
+ defaultValue: sectionStyleDefaults.sectionPaddingY,
88
+ options: [
89
+ { label: "None", value: "none" },
90
+ { label: "Small", value: "sm" },
91
+ { label: "Medium", value: "md" },
92
+ { label: "Large", value: "lg" }
93
+ ]
94
+ },
95
+ {
96
+ name: "sectionPaddingX",
97
+ type: "select",
98
+ defaultValue: sectionStyleDefaults.sectionPaddingX,
99
+ options: [
100
+ { label: "Inherit", value: "inherit" },
101
+ { label: "None", value: "none" },
102
+ { label: "Small", value: "sm" },
103
+ { label: "Medium", value: "md" },
104
+ { label: "Large", value: "lg" }
105
+ ]
106
+ },
107
+ {
108
+ name: "sectionBackgroundMode",
109
+ type: "select",
110
+ defaultValue: sectionStyleDefaults.sectionBackgroundMode,
111
+ options: [
112
+ { label: "None", value: "none" },
113
+ { label: "Color", value: "color" },
114
+ { label: "Gradient", value: "gradient" }
115
+ ]
116
+ },
117
+ {
118
+ name: "sectionBackgroundColor",
119
+ type: "text",
120
+ defaultValue: sectionStyleDefaults.sectionBackgroundColor
121
+ },
122
+ {
123
+ name: "sectionGradientPreset",
124
+ type: "select",
125
+ defaultValue: sectionStyleDefaults.sectionGradientPreset,
126
+ options: [
127
+ { label: "None", value: "none" },
128
+ { label: "Brand", value: "brand" },
129
+ { label: "Forest", value: "forest" },
130
+ { label: "Moss", value: "moss" },
131
+ { label: "Cream", value: "cream" },
132
+ { label: "Slate", value: "slate" }
133
+ ]
134
+ },
135
+ {
136
+ name: "sectionGradientFrom",
137
+ type: "text",
138
+ defaultValue: sectionStyleDefaults.sectionGradientFrom
139
+ },
140
+ {
141
+ name: "sectionGradientTo",
142
+ type: "text",
143
+ defaultValue: sectionStyleDefaults.sectionGradientTo
144
+ },
145
+ {
146
+ name: "sectionGradientAngle",
147
+ type: "text",
148
+ defaultValue: sectionStyleDefaults.sectionGradientAngle
149
+ },
150
+ {
151
+ name: "contentBackgroundMode",
152
+ type: "select",
153
+ defaultValue: sectionStyleDefaults.contentBackgroundMode,
154
+ options: [
155
+ { label: "None", value: "none" },
156
+ { label: "Color", value: "color" },
157
+ { label: "Gradient", value: "gradient" }
158
+ ]
159
+ },
160
+ {
161
+ name: "contentBackgroundColor",
162
+ type: "text",
163
+ defaultValue: sectionStyleDefaults.contentBackgroundColor
164
+ },
165
+ {
166
+ name: "contentGradientPreset",
167
+ type: "select",
168
+ defaultValue: sectionStyleDefaults.contentGradientPreset,
169
+ options: [
170
+ { label: "None", value: "none" },
171
+ { label: "Cloud", value: "cloud" },
172
+ { label: "Sand", value: "sand" },
173
+ { label: "Mint", value: "mint" },
174
+ { label: "Night", value: "night" }
175
+ ]
176
+ },
177
+ {
178
+ name: "contentGradientFrom",
179
+ type: "text",
180
+ defaultValue: sectionStyleDefaults.contentGradientFrom
181
+ },
182
+ {
183
+ name: "contentGradientTo",
184
+ type: "text",
185
+ defaultValue: sectionStyleDefaults.contentGradientTo
186
+ },
187
+ {
188
+ name: "contentGradientAngle",
189
+ type: "text",
190
+ defaultValue: sectionStyleDefaults.contentGradientAngle
191
+ }
192
+ ];
193
+ return fields.map(hideFromCMS);
194
+ };
195
+
37
196
  // src/blocks/blocks/BeforeAfter.ts
38
197
  var BeforeAfterBlock = {
39
198
  slug: "beforeAfter",
@@ -1808,6 +1967,7 @@ var defaultPageLayoutBlocks = [
1808
1967
 
1809
1968
  export {
1810
1969
  builderBlockLabelComponent,
1970
+ sectionStyleDefaults,
1811
1971
  BeforeAfterBlock,
1812
1972
  BookingEmbedBlock,
1813
1973
  CtaBlock,