@orion-studios/payload-studio 0.6.0-beta.185 → 0.6.0-beta.186

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 (40) hide show
  1. package/README.md +6 -1
  2. package/bin/init.js +329 -0
  3. package/dist/admin/index.d.mts +1 -1
  4. package/dist/admin/index.d.ts +1 -1
  5. package/dist/admin/index.js +61 -20
  6. package/dist/admin/index.mjs +1 -1
  7. package/dist/blocks/index.mjs +1 -2
  8. package/dist/{chunk-NGLIA2OE.mjs → chunk-DTHBPJXU.mjs} +193 -23
  9. package/dist/{chunk-JQAHXYAM.mjs → chunk-KMYMSR7W.mjs} +163 -3
  10. package/dist/{chunk-KHK6RTGC.mjs → chunk-MMJNHBOF.mjs} +61 -20
  11. package/dist/{chunk-ZADL33R6.mjs → chunk-OF6BATTO.mjs} +56 -111
  12. package/dist/chunk-VA545CHJ.mjs +202 -0
  13. package/dist/forms/index.d.mts +25 -0
  14. package/dist/forms/index.d.ts +25 -0
  15. package/dist/forms/index.js +237 -0
  16. package/dist/forms/index.mjs +25 -0
  17. package/dist/forms/server.d.mts +35 -0
  18. package/dist/forms/server.d.ts +35 -0
  19. package/dist/forms/server.js +442 -0
  20. package/dist/forms/server.mjs +228 -0
  21. package/dist/{index-Dv-Alx4h.d.ts → index-0xXWuOuz.d.ts} +35 -5
  22. package/dist/{index-D5zrOdyv.d.mts → index-BU82akSL.d.mts} +35 -5
  23. package/dist/{index-DLfPOqYA.d.mts → index-BbTcimgH.d.mts} +1 -0
  24. package/dist/{index-D8BNfUJb.d.mts → index-Cen-9wcc.d.mts} +17 -5
  25. package/dist/{index-BV0vEGl6.d.ts → index-DV-nW43e.d.ts} +1 -0
  26. package/dist/{index-DD_E2UfJ.d.ts → index-gxcMPpm-.d.ts} +17 -5
  27. package/dist/index.d.mts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +302 -151
  30. package/dist/index.mjs +11 -12
  31. package/dist/nextjs/index.d.mts +1 -1
  32. package/dist/nextjs/index.d.ts +1 -1
  33. package/dist/nextjs/index.js +56 -111
  34. package/dist/nextjs/index.mjs +1 -1
  35. package/dist/studio-pages/index.d.mts +1 -1
  36. package/dist/studio-pages/index.d.ts +1 -1
  37. package/dist/studio-pages/index.js +1802 -20
  38. package/dist/studio-pages/index.mjs +10 -2
  39. package/package.json +18 -2
  40. package/dist/chunk-OQSEJXC4.mjs +0 -166
@@ -1,6 +1,3 @@
1
- import {
2
- sectionStyleDefaults
3
- } from "./chunk-OQSEJXC4.mjs";
4
1
  import {
5
2
  createDefaultStudioDocument,
6
3
  defaultBuilderThemeTokens,
@@ -14,6 +11,10 @@ import {
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,
@@ -461,6 +466,13 @@ var inspectorDefinitionByBlockType = {
461
466
  };
462
467
 
463
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
+ };
464
476
  var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
465
477
  var toRecordArray = (value) => Array.isArray(value) ? value.filter((item) => isRecord2(item)) : [];
466
478
  var getRelationID = (value) => {
@@ -488,7 +500,7 @@ var hydrateRelationship = (valueFromStudio, valueFromLayout) => {
488
500
  }
489
501
  return valueFromLayout;
490
502
  };
491
- var hydrateDocumentWithLayoutRelations = (document, layout) => {
503
+ var hydrateDocumentWithLayoutRelations = (document, layout, hydrationMap = defaultRelationshipHydrationMap) => {
492
504
  const nextNodes = document.nodes.map((node, index) => {
493
505
  const layoutBlock = layout[index];
494
506
  if (!isRecord2(layoutBlock)) {
@@ -497,17 +509,18 @@ var hydrateDocumentWithLayoutRelations = (document, layout) => {
497
509
  if (typeof layoutBlock.blockType !== "string" || layoutBlock.blockType !== node.type) {
498
510
  return node;
499
511
  }
500
- const nextData = { ...node.data };
501
- if (node.type === "hero") {
502
- nextData.media = hydrateRelationship(nextData.media, layoutBlock.media);
512
+ const rule = hydrationMap[node.type];
513
+ if (!rule) {
514
+ return node;
503
515
  }
504
- if (node.type === "media") {
505
- 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]);
506
519
  }
507
- if (node.type === "featureGrid" || node.type === "logoWall" || node.type === "beforeAfter") {
508
- const studioItems = Array.isArray(nextData.items) ? nextData.items : [];
509
- const layoutItems = Array.isArray(layoutBlock.items) ? layoutBlock.items : [];
510
- 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) => {
511
524
  if (!isRecord2(rawStudioItem)) {
512
525
  return rawStudioItem;
513
526
  }
@@ -516,9 +529,9 @@ var hydrateDocumentWithLayoutRelations = (document, layout) => {
516
529
  return rawStudioItem;
517
530
  }
518
531
  const nextItem = { ...rawStudioItem };
519
- nextItem.media = hydrateRelationship(nextItem.media, layoutItem.media);
520
- nextItem.beforeMedia = hydrateRelationship(nextItem.beforeMedia, layoutItem.beforeMedia);
521
- nextItem.afterMedia = hydrateRelationship(nextItem.afterMedia, layoutItem.afterMedia);
532
+ for (const itemField of itemFields) {
533
+ nextItem[itemField] = hydrateRelationship(nextItem[itemField], layoutItem[itemField]);
534
+ }
522
535
  return nextItem;
523
536
  });
524
537
  }
@@ -537,7 +550,12 @@ var normalizeDocument = (document) => ({
537
550
  schemaVersion: 1,
538
551
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
539
552
  });
540
- 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());
541
559
  const nodes = document.nodes.map((node) => {
542
560
  if (node.type !== "hero" || !isRecord2(node.data)) {
543
561
  return node;
@@ -547,7 +565,7 @@ var normalizeLegacyHeroDefaults = (document) => {
547
565
  const sectionBackgroundMode = typeof nextData.sectionBackgroundMode === "string" ? nextData.sectionBackgroundMode : "none";
548
566
  const hasBackgroundImageURL = typeof nextData.backgroundImageURL === "string" && nextData.backgroundImageURL.trim().length > 0;
549
567
  const mediaRelation = getRelationID(nextData.media);
550
- if (heroBackgroundColor === "#124a37" && sectionBackgroundMode === "none" && !hasBackgroundImageURL && mediaRelation === null) {
568
+ if (normalizedLegacyColors.includes(heroBackgroundColor) && sectionBackgroundMode === "none" && !hasBackgroundImageURL && mediaRelation === null) {
551
569
  nextData.backgroundColor = "";
552
570
  }
553
571
  return {
@@ -566,13 +584,13 @@ var assertCanPublish = (issues) => {
566
584
  throw new Error(`Cannot publish page: ${publishErrors[0].message}`);
567
585
  }
568
586
  };
569
- var getStudioDocumentFromPage = (doc) => {
587
+ var getStudioDocumentFromPage = (doc, relationshipHydration = defaultRelationshipHydrationMap) => {
570
588
  const title = typeof doc.title === "string" ? doc.title : void 0;
571
589
  const layout = asLayoutArray(doc.layout);
572
590
  try {
573
591
  const studioDocument = assertStudioDocumentV1(doc.studioDocument);
574
592
  if (layout.length > 0) {
575
- return hydrateDocumentWithLayoutRelations(studioDocument, layout);
593
+ return hydrateDocumentWithLayoutRelations(studioDocument, layout, relationshipHydration);
576
594
  }
577
595
  return studioDocument;
578
596
  } catch {
@@ -584,8 +602,10 @@ var getStudioDocumentFromPage = (doc) => {
584
602
  };
585
603
  var createStudioPageService = ({
586
604
  collectionSlug = "pages",
605
+ legacyHeroBackgroundColors = DEFAULT_LEGACY_HERO_BACKGROUND_COLORS,
587
606
  modules,
588
607
  payload,
608
+ relationshipHydration = defaultRelationshipHydrationMap,
589
609
  user
590
610
  }) => ({
591
611
  getPageForStudio: async (pageID) => {
@@ -597,7 +617,7 @@ var createStudioPageService = ({
597
617
  overrideAccess: false,
598
618
  user
599
619
  });
600
- const studioDocument = getStudioDocumentFromPage(page);
620
+ const studioDocument = getStudioDocumentFromPage(page, relationshipHydration);
601
621
  return {
602
622
  id: String(page.id),
603
623
  slug: typeof page.slug === "string" ? page.slug : "",
@@ -607,7 +627,10 @@ var createStudioPageService = ({
607
627
  },
608
628
  validateStudioDocument: (document) => validateStudioDocument(document, modules),
609
629
  saveDraft: async (pageID, document, _metadata) => {
610
- const normalizedDocument = normalizeLegacyHeroDefaults(normalizeDocument(document));
630
+ const normalizedDocument = normalizeLegacyHeroDefaults(
631
+ normalizeDocument(document),
632
+ legacyHeroBackgroundColors
633
+ );
611
634
  const compileResult = compileStudioDocument(normalizedDocument, modules);
612
635
  await payload.update({
613
636
  collection: collectionSlug,
@@ -628,7 +651,10 @@ var createStudioPageService = ({
628
651
  };
629
652
  },
630
653
  publish: async (pageID, document, _metadata) => {
631
- const normalizedDocument = normalizeLegacyHeroDefaults(normalizeDocument(document));
654
+ const normalizedDocument = normalizeLegacyHeroDefaults(
655
+ normalizeDocument(document),
656
+ legacyHeroBackgroundColors
657
+ );
632
658
  const compileResult = compileStudioDocument(normalizedDocument, modules);
633
659
  assertCanPublish(compileResult.issues);
634
660
  await payload.update({
@@ -657,6 +683,146 @@ var toEditorInitialDoc = (payloadPage) => ({
657
683
  title: payloadPage.title
658
684
  });
659
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
+
660
826
  // src/studio-pages/migrations.ts
661
827
  var isRecord3 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
662
828
  var assertPageStudioDocumentV1 = (value) => {
@@ -1012,9 +1178,13 @@ var pageStudioModuleManifest = {
1012
1178
 
1013
1179
  export {
1014
1180
  resolveBuilderThemeTokens,
1181
+ defaultRelationshipHydrationMap,
1182
+ DEFAULT_LEGACY_HERO_BACKGROUND_COLORS,
1015
1183
  getStudioDocumentFromPage,
1016
1184
  createStudioPageService,
1017
1185
  toEditorInitialDoc,
1186
+ createStudioPageFields,
1187
+ createStudioPagesCollection,
1018
1188
  pageNodeTypes,
1019
1189
  pagePaletteGroups,
1020
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,
@@ -231,23 +231,33 @@ function configureAdmin(config) {
231
231
  if (cssSources.length === 0) {
232
232
  cssPath = sourceCssPath;
233
233
  } else {
234
- let css = cssSources.map((filePath) => fs.readFileSync(filePath, "utf-8")).join("\n\n");
235
- css = css.replace(
236
- "--orion-cms-brand-primary-fallback: #3b82f6;",
237
- `--orion-cms-brand-primary-fallback: ${brandPrimary};`
238
- );
239
- css = css.replace(
240
- "--orion-cms-brand-secondary-fallback: #8b5cf6;",
241
- `--orion-cms-brand-secondary-fallback: ${brandSecondary};`
242
- );
243
- const outputBasePath = config.basePath || process.cwd();
244
- const genDir = path.resolve(outputBasePath, ".generated");
245
- if (!fs.existsSync(genDir)) {
246
- fs.mkdirSync(genDir, { recursive: true });
234
+ try {
235
+ let css = cssSources.map((filePath) => fs.readFileSync(filePath, "utf-8")).join("\n\n");
236
+ css = css.replace(
237
+ "--orion-cms-brand-primary-fallback: #3b82f6;",
238
+ `--orion-cms-brand-primary-fallback: ${brandPrimary};`
239
+ );
240
+ css = css.replace(
241
+ "--orion-cms-brand-secondary-fallback: #8b5cf6;",
242
+ `--orion-cms-brand-secondary-fallback: ${brandSecondary};`
243
+ );
244
+ const outputBasePath = config.basePath || process.cwd();
245
+ const genDir = path.resolve(outputBasePath, ".generated");
246
+ const genPath = path.resolve(genDir, "admin.css");
247
+ let existing = null;
248
+ try {
249
+ existing = fs.readFileSync(genPath, "utf-8");
250
+ } catch {
251
+ existing = null;
252
+ }
253
+ if (existing !== css) {
254
+ fs.mkdirSync(genDir, { recursive: true });
255
+ fs.writeFileSync(genPath, css);
256
+ }
257
+ cssPath = genPath;
258
+ } catch {
259
+ cssPath = sourceCssPath;
247
260
  }
248
- const genPath = path.resolve(genDir, "admin.css");
249
- fs.writeFileSync(genPath, css);
250
- cssPath = genPath;
251
261
  }
252
262
  const clientPath = "@orion-studios/payload-studio/admin/client";
253
263
  const studioNavClientProps = {
@@ -700,16 +710,47 @@ function configureAdmin(config) {
700
710
  });
701
711
  },
702
712
  wrapGlobals(globals2) {
703
- const labelMap = {
713
+ const defaultLabelMap = {
704
714
  header: { group: "Site Design", label: "Header & Navigation" },
705
715
  footer: { group: "Site Design", label: "Footer" },
706
716
  "site-settings": { group: "Site Design", label: "Website Settings" },
707
717
  "social-media": { group: "Site Design", label: "Social Media" },
708
718
  "contact-form": { group: "Lead Forms", label: "Contact Form" }
709
719
  };
720
+ const configuredBySlug = new Map(
721
+ (config.studio?.globals || []).map((link) => [link.slug, link])
722
+ );
723
+ const attachBreadcrumbToGlobal = (global) => {
724
+ if (!studioEnabled) {
725
+ return global;
726
+ }
727
+ const existingControls = global.admin?.components?.elements?.beforeDocumentControls;
728
+ return {
729
+ ...global,
730
+ admin: {
731
+ ...global.admin,
732
+ components: {
733
+ ...global.admin?.components,
734
+ elements: {
735
+ ...global.admin?.components?.elements,
736
+ beforeDocumentControls: appendComponent(
737
+ existingControls,
738
+ studioBackBreadcrumbComponent,
739
+ "StudioBackBreadcrumb"
740
+ )
741
+ }
742
+ }
743
+ }
744
+ };
745
+ };
710
746
  return globals2.map((global) => {
711
- const mapping = labelMap[global.slug];
712
- if (!mapping) return global;
747
+ const configured = configuredBySlug.get(global.slug);
748
+ const defaults = defaultLabelMap[global.slug];
749
+ const mapping = configured || defaults ? {
750
+ group: configured?.group || defaults?.group,
751
+ label: configured?.label || defaults?.label || global.slug
752
+ } : void 0;
753
+ if (!mapping) return attachBreadcrumbToGlobal(global);
713
754
  const shouldAttachSiteSettingsEditView = studioEnabled && global.slug === "site-settings";
714
755
  const shouldAttachSocialMediaEditView = studioEnabled && global.slug === "social-media";
715
756
  const shouldAttachContactFormRedirect = studioEnabled && global.slug === "contact-form";
@@ -818,7 +859,7 @@ function configureAdmin(config) {
818
859
  ...global,
819
860
  admin: {
820
861
  ...global.admin,
821
- group: mapping.group,
862
+ ...mapping.group ? { group: mapping.group } : {},
822
863
  components: {
823
864
  ...global.admin?.components,
824
865
  elements: {