@orion-studios/payload-studio 0.5.0-beta.8 → 0.5.0-beta.80

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 (67) hide show
  1. package/README.md +20 -0
  2. package/dist/admin/client.d.mts +2 -0
  3. package/dist/admin/client.d.ts +2 -0
  4. package/dist/admin/client.js +779 -137
  5. package/dist/admin/client.mjs +769 -129
  6. package/dist/admin/index.d.mts +1 -1
  7. package/dist/admin/index.d.ts +1 -1
  8. package/dist/admin/index.js +100 -8
  9. package/dist/admin/index.mjs +3 -1
  10. package/dist/admin-app/client.d.mts +7 -0
  11. package/dist/admin-app/client.d.ts +7 -0
  12. package/dist/admin-app/client.js +1262 -3
  13. package/dist/admin-app/client.mjs +1164 -2
  14. package/dist/admin-app/index.d.mts +1 -1
  15. package/dist/admin-app/index.d.ts +1 -1
  16. package/dist/admin-app/index.js +167 -0
  17. package/dist/admin-app/index.mjs +13 -1
  18. package/dist/admin-app/styles.css +229 -0
  19. package/dist/blocks/index.js +633 -8
  20. package/dist/blocks/index.mjs +2 -2
  21. package/dist/chunk-ADIIWIYL.mjs +322 -0
  22. package/dist/{chunk-ZLLNO5FM.mjs → chunk-AFLEATYB.mjs} +44 -13
  23. package/dist/chunk-FWVVRZ32.mjs +1143 -0
  24. package/dist/{chunk-J7W5EE3B.mjs → chunk-HCEPGEAI.mjs} +100 -8
  25. package/dist/chunk-ROTPP5CU.mjs +99 -0
  26. package/dist/{chunk-ETRRXURT.mjs → chunk-SIL2J5MF.mjs} +14 -0
  27. package/dist/{chunk-PC5622T7.mjs → chunk-XK3K5GRP.mjs} +620 -9
  28. package/dist/chunk-XVH5SCBD.mjs +234 -0
  29. package/dist/index-BBp-3l6M.d.ts +134 -0
  30. package/dist/{index-CmR6NInu.d.ts → index-BIwu3qIH.d.mts} +29 -3
  31. package/dist/{index-CmR6NInu.d.mts → index-BIwu3qIH.d.ts} +29 -3
  32. package/dist/{index-DbH0Ljwp.d.ts → index-CpG3UHcS.d.mts} +1 -0
  33. package/dist/{index-DbH0Ljwp.d.mts → index-CpG3UHcS.d.ts} +1 -0
  34. package/dist/index-DT_Vorvh.d.mts +134 -0
  35. package/dist/index-ZbOx4OCF.d.mts +128 -0
  36. package/dist/index-ZbOx4OCF.d.ts +128 -0
  37. package/dist/{index-DJFhANvJ.d.mts → index-cDYkEj29.d.mts} +20 -2
  38. package/dist/{index-DJFhANvJ.d.ts → index-cDYkEj29.d.ts} +20 -2
  39. package/dist/index.d.mts +5 -5
  40. package/dist/index.d.ts +5 -5
  41. package/dist/index.js +2232 -324
  42. package/dist/index.mjs +7 -7
  43. package/dist/nextjs/index.d.mts +1 -1
  44. package/dist/nextjs/index.d.ts +1 -1
  45. package/dist/nextjs/index.js +1002 -13
  46. package/dist/nextjs/index.mjs +4 -1
  47. package/dist/studio/index.d.mts +2 -1
  48. package/dist/studio/index.d.ts +2 -1
  49. package/dist/studio/index.js +171 -5
  50. package/dist/studio/index.mjs +7 -3
  51. package/dist/studio-pages/builder.css +472 -8
  52. package/dist/studio-pages/client.d.mts +17 -0
  53. package/dist/studio-pages/client.d.ts +17 -0
  54. package/dist/studio-pages/client.js +5057 -2546
  55. package/dist/studio-pages/client.mjs +4972 -2552
  56. package/dist/studio-pages/index.d.mts +3 -2
  57. package/dist/studio-pages/index.d.ts +3 -2
  58. package/dist/studio-pages/index.js +873 -32
  59. package/dist/studio-pages/index.mjs +6 -2
  60. package/package.json +26 -12
  61. package/dist/chunk-AAOHJDNS.mjs +0 -67
  62. package/dist/chunk-N67KVM2S.mjs +0 -156
  63. package/dist/chunk-TVDMZNKU.mjs +0 -301
  64. package/dist/index-B9N5MyjF.d.mts +0 -39
  65. package/dist/index-BallJs-K.d.mts +0 -43
  66. package/dist/index-BallJs-K.d.ts +0 -43
  67. package/dist/index-g8tBHLKD.d.ts +0 -39
@@ -0,0 +1,1143 @@
1
+ import {
2
+ sectionStyleDefaults
3
+ } from "./chunk-SIL2J5MF.mjs";
4
+ import {
5
+ __export
6
+ } from "./chunk-6BWS3CLP.mjs";
7
+
8
+ // src/studio-pages/index.ts
9
+ var studio_pages_exports = {};
10
+ __export(studio_pages_exports, {
11
+ createDefaultStudioDocument: () => createDefaultStudioDocument,
12
+ defaultBuilderThemeTokens: () => defaultBuilderThemeTokens,
13
+ layoutToStudioDocument: () => layoutToStudioDocument,
14
+ pageInspectorPanels: () => pageInspectorPanels,
15
+ pageNodeTypes: () => pageNodeTypes,
16
+ pagePaletteGroups: () => pagePaletteGroups,
17
+ pageStudioModuleManifest: () => pageStudioModuleManifest,
18
+ resolveBuilderThemeTokens: () => resolveBuilderThemeTokens,
19
+ studioDocumentToLayout: () => studioDocumentToLayout
20
+ });
21
+
22
+ // src/studio-pages/builder/settings-v2/types.ts
23
+ var defaultBuilderBlockSettingsV2 = {
24
+ advanced: {
25
+ customClassName: "",
26
+ editCopyInPanel: false,
27
+ hideOnMobile: false
28
+ },
29
+ appearance: {
30
+ contentBackgroundColor: "#ffffff",
31
+ contentBackgroundMode: "none",
32
+ contentGradientAngle: "135",
33
+ contentGradientFrom: "#ffffff",
34
+ contentGradientPreset: "none",
35
+ contentGradientTo: "#f4f6f2",
36
+ sectionBackgroundColor: "#ffffff",
37
+ sectionBackgroundMode: "none",
38
+ sectionGradientAngle: "135",
39
+ sectionGradientFrom: "#124a37",
40
+ sectionGradientPreset: "forest",
41
+ sectionGradientTo: "#1f684f"
42
+ },
43
+ layout: {
44
+ contentWidth: "inherit",
45
+ sectionPaddingX: "inherit",
46
+ sectionPaddingY: "md"
47
+ },
48
+ media: {
49
+ cornerStyle: "rounded",
50
+ fit: "cover",
51
+ height: null,
52
+ position: "center",
53
+ positionX: null,
54
+ positionY: null
55
+ },
56
+ typography: {
57
+ bodyAlign: "left",
58
+ headingAlign: "left",
59
+ letterSpacingPreset: "normal",
60
+ lineHeightPreset: "normal",
61
+ maxTextWidth: "auto"
62
+ },
63
+ version: 2
64
+ };
65
+ var defaultBuilderItemSettingsV2 = {
66
+ layout: {
67
+ contentWidth: "inherit",
68
+ sectionPaddingX: "inherit",
69
+ sectionPaddingY: "md"
70
+ },
71
+ media: {
72
+ cornerStyle: "rounded",
73
+ fit: "cover",
74
+ height: null,
75
+ position: "center",
76
+ positionX: null,
77
+ positionY: null
78
+ },
79
+ typography: {
80
+ bodyAlign: "left",
81
+ headingAlign: "left",
82
+ letterSpacingPreset: "normal",
83
+ lineHeightPreset: "normal",
84
+ maxTextWidth: "auto"
85
+ },
86
+ version: 2
87
+ };
88
+ var defaultBuilderThemeTokens = {
89
+ colors: {
90
+ accent: "#0d4a37",
91
+ bodyText: "#13211c",
92
+ headingText: "#13211c",
93
+ surface: "#ffffff"
94
+ },
95
+ radii: {
96
+ card: 16,
97
+ panel: 14
98
+ },
99
+ spacing: {
100
+ sectionGap: "md",
101
+ sectionPadding: "md"
102
+ },
103
+ typography: {
104
+ bodySize: "md",
105
+ headingSize: "md"
106
+ }
107
+ };
108
+
109
+ // src/studio-pages/builder/adapters/settingsV2.ts
110
+ var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
111
+ var parsePercent = (value) => {
112
+ if (typeof value === "number" && Number.isFinite(value)) {
113
+ return Math.max(0, Math.min(100, value));
114
+ }
115
+ if (typeof value === "string" && value.trim().length > 0) {
116
+ const parsed = Number(value);
117
+ if (Number.isFinite(parsed)) {
118
+ return Math.max(0, Math.min(100, parsed));
119
+ }
120
+ }
121
+ return null;
122
+ };
123
+ var parsePixel = (value) => {
124
+ if (typeof value === "number" && Number.isFinite(value)) {
125
+ return value;
126
+ }
127
+ if (typeof value === "string" && value.trim().length > 0) {
128
+ const parsed = Number(value);
129
+ if (Number.isFinite(parsed)) {
130
+ return parsed;
131
+ }
132
+ }
133
+ return null;
134
+ };
135
+ var mergeSettings = (defaults, input) => {
136
+ if (!isRecord(input)) {
137
+ return structuredClone(defaults);
138
+ }
139
+ const next = structuredClone(defaults);
140
+ for (const [key, value] of Object.entries(input)) {
141
+ if (isRecord(value) && isRecord(next[key])) {
142
+ next[key] = mergeSettings(next[key], value);
143
+ continue;
144
+ }
145
+ if (typeof value !== "undefined") {
146
+ next[key] = value;
147
+ }
148
+ }
149
+ return next;
150
+ };
151
+ var legacyBlockToV2Settings = (block) => {
152
+ const current = structuredClone(defaultBuilderBlockSettingsV2);
153
+ current.layout.contentWidth = block.contentWidth === "narrow" || block.contentWidth === "content" || block.contentWidth === "wide" || block.contentWidth === "full" || block.contentWidth === "inherit" ? block.contentWidth : current.layout.contentWidth;
154
+ current.layout.sectionPaddingX = block.sectionPaddingX === "none" || block.sectionPaddingX === "sm" || block.sectionPaddingX === "md" || block.sectionPaddingX === "lg" || block.sectionPaddingX === "inherit" ? block.sectionPaddingX : current.layout.sectionPaddingX;
155
+ current.layout.sectionPaddingY = block.sectionPaddingY === "none" || block.sectionPaddingY === "sm" || block.sectionPaddingY === "lg" ? block.sectionPaddingY : current.layout.sectionPaddingY;
156
+ current.appearance.sectionBackgroundMode = block.sectionBackgroundMode === "none" || block.sectionBackgroundMode === "color" || block.sectionBackgroundMode === "gradient" ? block.sectionBackgroundMode : current.appearance.sectionBackgroundMode;
157
+ current.appearance.sectionBackgroundColor = typeof block.sectionBackgroundColor === "string" ? block.sectionBackgroundColor : current.appearance.sectionBackgroundColor;
158
+ current.appearance.sectionGradientPreset = typeof block.sectionGradientPreset === "string" ? block.sectionGradientPreset : current.appearance.sectionGradientPreset;
159
+ current.appearance.sectionGradientFrom = typeof block.sectionGradientFrom === "string" ? block.sectionGradientFrom : current.appearance.sectionGradientFrom;
160
+ current.appearance.sectionGradientTo = typeof block.sectionGradientTo === "string" ? block.sectionGradientTo : current.appearance.sectionGradientTo;
161
+ current.appearance.sectionGradientAngle = typeof block.sectionGradientAngle === "string" ? block.sectionGradientAngle : current.appearance.sectionGradientAngle;
162
+ current.appearance.contentBackgroundMode = block.contentBackgroundMode === "none" || block.contentBackgroundMode === "color" || block.contentBackgroundMode === "gradient" ? block.contentBackgroundMode : current.appearance.contentBackgroundMode;
163
+ current.appearance.contentBackgroundColor = typeof block.contentBackgroundColor === "string" ? block.contentBackgroundColor : current.appearance.contentBackgroundColor;
164
+ current.appearance.contentGradientPreset = typeof block.contentGradientPreset === "string" ? block.contentGradientPreset : current.appearance.contentGradientPreset;
165
+ current.appearance.contentGradientFrom = typeof block.contentGradientFrom === "string" ? block.contentGradientFrom : current.appearance.contentGradientFrom;
166
+ current.appearance.contentGradientTo = typeof block.contentGradientTo === "string" ? block.contentGradientTo : current.appearance.contentGradientTo;
167
+ current.appearance.contentGradientAngle = typeof block.contentGradientAngle === "string" ? block.contentGradientAngle : current.appearance.contentGradientAngle;
168
+ if (block.backgroundImageFit === "cover" || block.backgroundImageFit === "contain") {
169
+ current.media.fit = block.backgroundImageFit;
170
+ }
171
+ if (block.imageFit === "cover" || block.imageFit === "contain") {
172
+ current.media.fit = block.imageFit;
173
+ }
174
+ if (block.backgroundImageCornerStyle === "rounded" || block.backgroundImageCornerStyle === "square") {
175
+ current.media.cornerStyle = block.backgroundImageCornerStyle;
176
+ }
177
+ if (block.imageCornerStyle === "rounded" || block.imageCornerStyle === "square") {
178
+ current.media.cornerStyle = block.imageCornerStyle;
179
+ }
180
+ if (block.backgroundImagePosition === "top" || block.backgroundImagePosition === "bottom" || block.backgroundImagePosition === "left" || block.backgroundImagePosition === "right" || block.backgroundImagePosition === "center") {
181
+ current.media.position = block.backgroundImagePosition;
182
+ }
183
+ if (block.imagePosition === "top" || block.imagePosition === "bottom" || block.imagePosition === "left" || block.imagePosition === "right" || block.imagePosition === "center") {
184
+ current.media.position = block.imagePosition;
185
+ }
186
+ current.media.positionX = parsePercent(block.imagePositionX ?? block.backgroundImagePositionX);
187
+ current.media.positionY = parsePercent(block.imagePositionY ?? block.backgroundImagePositionY);
188
+ current.media.height = parsePixel(block.imageHeight);
189
+ current.typography.headingAlign = block.textHeadingAlign === "left" || block.textHeadingAlign === "center" || block.textHeadingAlign === "right" || block.textHeadingAlign === "justify" ? block.textHeadingAlign : current.typography.headingAlign;
190
+ current.typography.bodyAlign = block.textBodyAlign === "left" || block.textBodyAlign === "center" || block.textBodyAlign === "right" || block.textBodyAlign === "justify" ? block.textBodyAlign : current.typography.bodyAlign;
191
+ current.typography.maxTextWidth = block.textMaxWidth === "auto" || block.textMaxWidth === "sm" || block.textMaxWidth === "md" || block.textMaxWidth === "lg" || block.textMaxWidth === "full" ? block.textMaxWidth : current.typography.maxTextWidth;
192
+ current.typography.lineHeightPreset = block.textLineHeightPreset === "tight" || block.textLineHeightPreset === "normal" || block.textLineHeightPreset === "relaxed" ? block.textLineHeightPreset : current.typography.lineHeightPreset;
193
+ current.typography.letterSpacingPreset = block.textLetterSpacingPreset === "tight" || block.textLetterSpacingPreset === "normal" || block.textLetterSpacingPreset === "relaxed" ? block.textLetterSpacingPreset : current.typography.letterSpacingPreset;
194
+ current.advanced.editCopyInPanel = Boolean(block.editCopyInPanel ?? current.advanced.editCopyInPanel);
195
+ current.advanced.customClassName = typeof block.customClassName === "string" ? block.customClassName : current.advanced.customClassName;
196
+ current.advanced.hideOnMobile = Boolean(block.hideOnMobile ?? current.advanced.hideOnMobile);
197
+ return mergeSettings(current, block.settings);
198
+ };
199
+ var v2SettingsToLegacyBlock = (blockWithSettings) => {
200
+ const settings = legacyBlockToV2Settings(blockWithSettings);
201
+ const next = {
202
+ ...blockWithSettings,
203
+ settings
204
+ };
205
+ next.contentWidth = settings.layout.contentWidth;
206
+ next.sectionPaddingX = settings.layout.sectionPaddingX;
207
+ next.sectionPaddingY = settings.layout.sectionPaddingY;
208
+ next.sectionBackgroundMode = settings.appearance.sectionBackgroundMode;
209
+ next.sectionBackgroundColor = settings.appearance.sectionBackgroundColor;
210
+ next.sectionGradientPreset = settings.appearance.sectionGradientPreset;
211
+ next.sectionGradientFrom = settings.appearance.sectionGradientFrom;
212
+ next.sectionGradientTo = settings.appearance.sectionGradientTo;
213
+ next.sectionGradientAngle = settings.appearance.sectionGradientAngle;
214
+ next.contentBackgroundMode = settings.appearance.contentBackgroundMode;
215
+ next.contentBackgroundColor = settings.appearance.contentBackgroundColor;
216
+ next.contentGradientPreset = settings.appearance.contentGradientPreset;
217
+ next.contentGradientFrom = settings.appearance.contentGradientFrom;
218
+ next.contentGradientTo = settings.appearance.contentGradientTo;
219
+ next.contentGradientAngle = settings.appearance.contentGradientAngle;
220
+ next.textHeadingAlign = settings.typography.headingAlign;
221
+ next.textBodyAlign = settings.typography.bodyAlign;
222
+ next.textMaxWidth = settings.typography.maxTextWidth;
223
+ next.textLineHeightPreset = settings.typography.lineHeightPreset;
224
+ next.textLetterSpacingPreset = settings.typography.letterSpacingPreset;
225
+ next.editCopyInPanel = settings.advanced.editCopyInPanel;
226
+ next.customClassName = settings.advanced.customClassName;
227
+ next.hideOnMobile = settings.advanced.hideOnMobile;
228
+ if (next.blockType === "hero") {
229
+ next.backgroundImageFit = settings.media.fit;
230
+ next.backgroundImageCornerStyle = settings.media.cornerStyle;
231
+ next.backgroundImagePosition = settings.media.position;
232
+ next.backgroundImagePositionX = settings.media.positionX;
233
+ next.backgroundImagePositionY = settings.media.positionY;
234
+ } else {
235
+ next.imageFit = settings.media.fit;
236
+ next.imageCornerStyle = settings.media.cornerStyle;
237
+ next.imagePosition = settings.media.position;
238
+ next.imagePositionX = settings.media.positionX;
239
+ next.imagePositionY = settings.media.positionY;
240
+ next.imageHeight = settings.media.height;
241
+ }
242
+ if (Array.isArray(next.items)) {
243
+ next.items = next.items.map((rawItem) => isRecord(rawItem) ? v2SettingsToLegacyItem(rawItem) : rawItem);
244
+ }
245
+ return next;
246
+ };
247
+ var legacyItemToV2Settings = (item) => {
248
+ const current = structuredClone(defaultBuilderItemSettingsV2);
249
+ if (item.imageFit === "cover" || item.imageFit === "contain") {
250
+ current.media.fit = item.imageFit;
251
+ }
252
+ if (item.imageCornerStyle === "rounded" || item.imageCornerStyle === "square") {
253
+ current.media.cornerStyle = item.imageCornerStyle;
254
+ }
255
+ if (item.imagePosition === "top" || item.imagePosition === "bottom" || item.imagePosition === "left" || item.imagePosition === "right" || item.imagePosition === "center") {
256
+ current.media.position = item.imagePosition;
257
+ }
258
+ current.media.positionX = parsePercent(item.imagePositionX);
259
+ current.media.positionY = parsePercent(item.imagePositionY);
260
+ current.media.height = parsePixel(item.imageHeight);
261
+ return mergeSettings(current, item.settings);
262
+ };
263
+ var v2SettingsToLegacyItem = (itemWithSettings) => {
264
+ const settings = legacyItemToV2Settings(itemWithSettings);
265
+ return {
266
+ ...itemWithSettings,
267
+ imageCornerStyle: settings.media.cornerStyle,
268
+ imageFit: settings.media.fit,
269
+ imageHeight: settings.media.height,
270
+ imagePosition: settings.media.position,
271
+ imagePositionX: settings.media.positionX,
272
+ imagePositionY: settings.media.positionY,
273
+ settings
274
+ };
275
+ };
276
+ var migrateBlockToSettingsV2 = (block) => {
277
+ const withLegacyMirrors = v2SettingsToLegacyBlock(block);
278
+ if (!Array.isArray(withLegacyMirrors.items)) {
279
+ return withLegacyMirrors;
280
+ }
281
+ return {
282
+ ...withLegacyMirrors,
283
+ items: withLegacyMirrors.items.map((rawItem) => isRecord(rawItem) ? v2SettingsToLegacyItem(rawItem) : rawItem)
284
+ };
285
+ };
286
+
287
+ // src/studio-pages/builder/settings-v2/themeTokens.ts
288
+ var isRecord2 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
289
+ var merge = (base, next) => {
290
+ if (!next || !isRecord2(next)) {
291
+ return base;
292
+ }
293
+ const merged = { ...base };
294
+ for (const [key, value] of Object.entries(next)) {
295
+ if (isRecord2(value) && isRecord2(merged[key])) {
296
+ merged[key] = merge(merged[key], value);
297
+ continue;
298
+ }
299
+ if (typeof value !== "undefined") {
300
+ merged[key] = value;
301
+ }
302
+ }
303
+ return merged;
304
+ };
305
+ var resolveBuilderThemeTokens = (layers) => {
306
+ const withSite = merge(defaultBuilderThemeTokens, layers.site);
307
+ const withPage = merge(withSite, layers.page);
308
+ return merge(withPage, layers.block);
309
+ };
310
+
311
+ // src/studio-pages/builder/settings-v2/BlockInspectorRenderer.tsx
312
+ import { useMemo, useState } from "react";
313
+
314
+ // src/studio-pages/builder/ui/Accordion.tsx
315
+ import { jsx, jsxs } from "react/jsx-runtime";
316
+
317
+ // src/studio-pages/builder/ui/ImageControls.tsx
318
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
319
+
320
+ // src/studio-pages/builder/settings-v2/inspectorSchema.ts
321
+ var alignOptions = [
322
+ { label: "Left", value: "left" },
323
+ { label: "Center", value: "center" },
324
+ { label: "Right", value: "right" },
325
+ { label: "Justify", value: "justify" }
326
+ ];
327
+ var layoutFieldSet = [
328
+ {
329
+ group: "layout",
330
+ key: "settings.layout.contentWidth",
331
+ label: "Content Width",
332
+ options: [
333
+ { label: "Inherit Page Default", value: "inherit" },
334
+ { label: "Narrow", value: "narrow" },
335
+ { label: "Content", value: "content" },
336
+ { label: "Wide", value: "wide" },
337
+ { label: "Full", value: "full" }
338
+ ],
339
+ tags: ["width", "container"],
340
+ type: "select"
341
+ },
342
+ {
343
+ group: "layout",
344
+ key: "settings.layout.sectionPaddingY",
345
+ label: "Section Vertical Spacing",
346
+ options: [
347
+ { label: "None", value: "none" },
348
+ { label: "Small", value: "sm" },
349
+ { label: "Medium", value: "md" },
350
+ { label: "Large", value: "lg" }
351
+ ],
352
+ tags: ["spacing", "padding"],
353
+ type: "select"
354
+ },
355
+ {
356
+ group: "layout",
357
+ key: "settings.layout.sectionPaddingX",
358
+ label: "Section Horizontal Spacing",
359
+ options: [
360
+ { label: "Inherit", value: "inherit" },
361
+ { label: "None", value: "none" },
362
+ { label: "Small", value: "sm" },
363
+ { label: "Medium", value: "md" },
364
+ { label: "Large", value: "lg" }
365
+ ],
366
+ tags: ["spacing", "padding"],
367
+ type: "select"
368
+ }
369
+ ];
370
+ var typographyFieldSet = [
371
+ {
372
+ group: "typography",
373
+ key: "settings.typography.headingAlign",
374
+ label: "Heading Alignment",
375
+ options: alignOptions,
376
+ tags: ["text", "align", "heading"],
377
+ type: "select"
378
+ },
379
+ {
380
+ group: "typography",
381
+ key: "settings.typography.bodyAlign",
382
+ label: "Body Alignment",
383
+ options: alignOptions,
384
+ tags: ["text", "align", "paragraph"],
385
+ type: "select"
386
+ },
387
+ {
388
+ group: "typography",
389
+ key: "settings.typography.maxTextWidth",
390
+ label: "Text Width",
391
+ options: [
392
+ { label: "Auto", value: "auto" },
393
+ { label: "Small", value: "sm" },
394
+ { label: "Medium", value: "md" },
395
+ { label: "Large", value: "lg" },
396
+ { label: "Full", value: "full" }
397
+ ],
398
+ tags: ["readability", "measure", "line length"],
399
+ type: "select"
400
+ },
401
+ {
402
+ advanced: true,
403
+ group: "typography",
404
+ key: "settings.typography.lineHeightPreset",
405
+ label: "Line Height",
406
+ options: [
407
+ { label: "Tight", value: "tight" },
408
+ { label: "Normal", value: "normal" },
409
+ { label: "Relaxed", value: "relaxed" }
410
+ ],
411
+ type: "select"
412
+ },
413
+ {
414
+ advanced: true,
415
+ group: "typography",
416
+ key: "settings.typography.letterSpacingPreset",
417
+ label: "Letter Spacing",
418
+ options: [
419
+ { label: "Tight", value: "tight" },
420
+ { label: "Normal", value: "normal" },
421
+ { label: "Relaxed", value: "relaxed" }
422
+ ],
423
+ type: "select"
424
+ }
425
+ ];
426
+ var styleFieldSet = [
427
+ {
428
+ group: "style",
429
+ key: "settings.appearance.sectionBackgroundMode",
430
+ label: "Section Background",
431
+ options: [
432
+ { label: "None", value: "none" },
433
+ { label: "Color", value: "color" },
434
+ { label: "Gradient", value: "gradient" }
435
+ ],
436
+ tags: ["background", "section"],
437
+ type: "select"
438
+ },
439
+ {
440
+ group: "style",
441
+ key: "settings.appearance.sectionBackgroundColor",
442
+ label: "Section Background Color",
443
+ type: "color"
444
+ },
445
+ {
446
+ group: "style",
447
+ key: "settings.appearance.contentBackgroundMode",
448
+ label: "Content Background",
449
+ options: [
450
+ { label: "None", value: "none" },
451
+ { label: "Color", value: "color" },
452
+ { label: "Gradient", value: "gradient" }
453
+ ],
454
+ tags: ["background", "content"],
455
+ type: "select"
456
+ },
457
+ {
458
+ group: "style",
459
+ key: "settings.appearance.contentBackgroundColor",
460
+ label: "Content Background Color",
461
+ type: "color"
462
+ }
463
+ ];
464
+ var commonAdvanced = [
465
+ {
466
+ group: "advanced",
467
+ inlineEditable: false,
468
+ key: "settings.advanced.editCopyInPanel",
469
+ label: "Edit Copy In Panel",
470
+ tags: ["inline", "copy", "text"],
471
+ type: "checkbox"
472
+ },
473
+ {
474
+ advanced: true,
475
+ group: "advanced",
476
+ key: "settings.advanced.hideOnMobile",
477
+ label: "Hide On Mobile",
478
+ type: "checkbox"
479
+ },
480
+ {
481
+ advanced: true,
482
+ group: "advanced",
483
+ key: "settings.advanced.customClassName",
484
+ label: "Custom Class Name",
485
+ type: "text"
486
+ }
487
+ ];
488
+ var mediaFieldSet = [
489
+ {
490
+ group: "media",
491
+ key: "settings.media.fit",
492
+ label: "Image Fit",
493
+ options: [
494
+ { label: "Cover", value: "cover" },
495
+ { label: "Contain", value: "contain" }
496
+ ],
497
+ tags: ["image", "media"],
498
+ type: "select"
499
+ },
500
+ {
501
+ group: "media",
502
+ key: "settings.media.cornerStyle",
503
+ label: "Image Corners",
504
+ options: [
505
+ { label: "Rounded", value: "rounded" },
506
+ { label: "Square", value: "square" }
507
+ ],
508
+ tags: ["image", "radius", "corners"],
509
+ type: "select"
510
+ },
511
+ {
512
+ group: "media",
513
+ key: "settings.media.position",
514
+ label: "Image Position",
515
+ options: [
516
+ { label: "Center", value: "center" },
517
+ { label: "Top", value: "top" },
518
+ { label: "Bottom", value: "bottom" },
519
+ { label: "Left", value: "left" },
520
+ { label: "Right", value: "right" }
521
+ ],
522
+ type: "select"
523
+ }
524
+ ];
525
+ var inspectorDefinitionByBlockType = {
526
+ beforeAfter: {
527
+ blockType: "beforeAfter",
528
+ fields: [
529
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
530
+ { group: "basics", inlineEditable: true, key: "subtitle", label: "Subtitle", type: "textarea" },
531
+ { group: "basics", key: "itemsPerRow", label: "Items Per Row", max: 4, min: 1, type: "number" },
532
+ ...layoutFieldSet,
533
+ ...typographyFieldSet,
534
+ ...styleFieldSet,
535
+ ...commonAdvanced
536
+ ]
537
+ },
538
+ bookingEmbed: {
539
+ blockType: "bookingEmbed",
540
+ fields: [
541
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
542
+ { group: "basics", inlineEditable: true, key: "description", label: "Description", type: "textarea" },
543
+ { group: "basics", inlineEditable: false, key: "buttonLabel", label: "Button Label", type: "text" },
544
+ { group: "basics", inlineEditable: false, key: "buttonHref", label: "Button URL", type: "text" },
545
+ ...layoutFieldSet,
546
+ ...typographyFieldSet,
547
+ ...styleFieldSet,
548
+ ...commonAdvanced
549
+ ]
550
+ },
551
+ cta: {
552
+ blockType: "cta",
553
+ fields: [
554
+ { group: "basics", inlineEditable: true, key: "headline", label: "Headline", type: "text" },
555
+ { group: "basics", inlineEditable: true, key: "description", label: "Description", type: "textarea" },
556
+ { group: "basics", inlineEditable: false, key: "buttonLabel", label: "Button Label", type: "text" },
557
+ { group: "basics", inlineEditable: false, key: "buttonHref", label: "Button URL", type: "text" },
558
+ {
559
+ group: "basics",
560
+ key: "style",
561
+ label: "Variant",
562
+ options: [
563
+ { label: "Light", value: "light" },
564
+ { label: "Dark", value: "dark" }
565
+ ],
566
+ type: "select"
567
+ },
568
+ ...layoutFieldSet,
569
+ ...typographyFieldSet,
570
+ ...styleFieldSet,
571
+ ...commonAdvanced
572
+ ]
573
+ },
574
+ faq: {
575
+ blockType: "faq",
576
+ fields: [
577
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
578
+ ...layoutFieldSet,
579
+ ...typographyFieldSet,
580
+ ...styleFieldSet,
581
+ ...commonAdvanced
582
+ ]
583
+ },
584
+ featureGrid: {
585
+ blockType: "featureGrid",
586
+ fields: [
587
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
588
+ {
589
+ group: "basics",
590
+ key: "variant",
591
+ label: "Variant",
592
+ options: [
593
+ { label: "Cards", value: "cards" },
594
+ { label: "Highlight", value: "highlight" }
595
+ ],
596
+ type: "select"
597
+ },
598
+ { group: "basics", key: "itemsPerRow", label: "Items Per Row", max: 6, min: 1, type: "number" },
599
+ ...layoutFieldSet,
600
+ ...typographyFieldSet,
601
+ ...mediaFieldSet,
602
+ ...styleFieldSet,
603
+ ...commonAdvanced
604
+ ]
605
+ },
606
+ formEmbed: {
607
+ blockType: "formEmbed",
608
+ fields: [
609
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
610
+ { group: "basics", inlineEditable: true, key: "description", label: "Description", type: "textarea" },
611
+ {
612
+ group: "basics",
613
+ key: "formType",
614
+ label: "Form Type",
615
+ options: [{ label: "Quote", value: "quote" }],
616
+ type: "select"
617
+ },
618
+ ...layoutFieldSet,
619
+ ...typographyFieldSet,
620
+ ...styleFieldSet,
621
+ ...commonAdvanced
622
+ ]
623
+ },
624
+ hero: {
625
+ blockType: "hero",
626
+ fields: [
627
+ { group: "basics", inlineEditable: true, key: "kicker", label: "Kicker", type: "text" },
628
+ { group: "basics", inlineEditable: true, key: "headline", label: "Headline", type: "text" },
629
+ { group: "basics", inlineEditable: true, key: "subheadline", label: "Subheadline", type: "textarea" },
630
+ {
631
+ group: "basics",
632
+ key: "variant",
633
+ label: "Variant",
634
+ options: [
635
+ { label: "Default", value: "default" },
636
+ { label: "Centered", value: "centered" }
637
+ ],
638
+ type: "select"
639
+ },
640
+ {
641
+ group: "layout",
642
+ key: "heroHeight",
643
+ label: "Hero Height",
644
+ options: [
645
+ { label: "Small", value: "sm" },
646
+ { label: "Medium (Half Screen)", value: "md" },
647
+ { label: "Full Screen", value: "full" }
648
+ ],
649
+ type: "select"
650
+ },
651
+ ...layoutFieldSet,
652
+ ...typographyFieldSet,
653
+ ...mediaFieldSet,
654
+ ...styleFieldSet,
655
+ ...commonAdvanced
656
+ ]
657
+ },
658
+ logoWall: {
659
+ blockType: "logoWall",
660
+ fields: [
661
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
662
+ { group: "basics", inlineEditable: true, key: "subtitle", label: "Subtitle", type: "textarea" },
663
+ ...layoutFieldSet,
664
+ ...typographyFieldSet,
665
+ ...mediaFieldSet,
666
+ ...styleFieldSet,
667
+ ...commonAdvanced
668
+ ]
669
+ },
670
+ media: {
671
+ blockType: "media",
672
+ fields: [
673
+ { group: "basics", inlineEditable: true, key: "caption", label: "Caption", type: "text" },
674
+ {
675
+ group: "basics",
676
+ key: "size",
677
+ label: "Size",
678
+ options: [
679
+ { label: "Default", value: "default" },
680
+ { label: "Wide", value: "wide" }
681
+ ],
682
+ type: "select"
683
+ },
684
+ ...layoutFieldSet,
685
+ ...typographyFieldSet,
686
+ ...mediaFieldSet,
687
+ ...styleFieldSet,
688
+ ...commonAdvanced
689
+ ]
690
+ },
691
+ richText: {
692
+ blockType: "richText",
693
+ fields: [
694
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
695
+ {
696
+ group: "basics",
697
+ key: "width",
698
+ label: "Rich Text Width",
699
+ options: [
700
+ { label: "Normal", value: "normal" },
701
+ { label: "Narrow", value: "narrow" }
702
+ ],
703
+ type: "select"
704
+ },
705
+ ...layoutFieldSet,
706
+ ...typographyFieldSet,
707
+ ...styleFieldSet,
708
+ ...commonAdvanced
709
+ ]
710
+ },
711
+ stats: {
712
+ blockType: "stats",
713
+ fields: [
714
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
715
+ { group: "basics", inlineEditable: true, key: "subtitle", label: "Subtitle", type: "textarea" },
716
+ ...layoutFieldSet,
717
+ ...typographyFieldSet,
718
+ ...styleFieldSet,
719
+ ...commonAdvanced
720
+ ]
721
+ },
722
+ testimonials: {
723
+ blockType: "testimonials",
724
+ fields: [
725
+ { group: "basics", inlineEditable: true, key: "title", label: "Title", type: "text" },
726
+ { group: "basics", key: "visibleCount", label: "Visible At Once", max: 6, min: 1, type: "number" },
727
+ { group: "basics", key: "autoRotate", label: "Auto Rotate", type: "checkbox" },
728
+ {
729
+ advanced: true,
730
+ group: "advanced",
731
+ key: "rotateIntervalSeconds",
732
+ label: "Rotate Interval Seconds",
733
+ max: 30,
734
+ min: 2,
735
+ type: "number"
736
+ },
737
+ ...layoutFieldSet,
738
+ ...typographyFieldSet,
739
+ ...styleFieldSet,
740
+ ...commonAdvanced
741
+ ]
742
+ }
743
+ };
744
+
745
+ // src/studio-pages/builder/settings-v2/BlockInspectorRenderer.tsx
746
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
747
+
748
+ // src/studio-pages/migrations.ts
749
+ var isRecord3 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
750
+ var assertPageStudioDocumentV1 = (value) => {
751
+ if (!isRecord3(value)) {
752
+ throw new Error("Studio document must be an object");
753
+ }
754
+ if (value.schemaVersion !== 1) {
755
+ throw new Error("Unsupported studio schemaVersion");
756
+ }
757
+ if (!Array.isArray(value.nodes)) {
758
+ throw new Error("Studio document nodes must be an array");
759
+ }
760
+ const nodes = value.nodes.map((node, index) => {
761
+ if (!isRecord3(node)) {
762
+ throw new Error(`Node at index ${index} must be an object`);
763
+ }
764
+ if (typeof node.id !== "string" || node.id.length === 0) {
765
+ throw new Error(`Node at index ${index} has invalid id`);
766
+ }
767
+ if (typeof node.type !== "string" || node.type.length === 0) {
768
+ throw new Error(`Node at index ${index} has invalid type`);
769
+ }
770
+ if (!isRecord3(node.data)) {
771
+ throw new Error(`Node at index ${index} has invalid data`);
772
+ }
773
+ return {
774
+ data: node.data,
775
+ id: node.id,
776
+ type: node.type
777
+ };
778
+ });
779
+ return {
780
+ metadata: isRecord3(value.metadata) ? value.metadata : void 0,
781
+ nodes,
782
+ schemaVersion: 1,
783
+ title: typeof value.title === "string" ? value.title : void 0,
784
+ updatedAt: typeof value.updatedAt === "string" ? value.updatedAt : void 0
785
+ };
786
+ };
787
+ var migratePageNodeToSettingsV2 = (node) => {
788
+ const normalized = migrateBlockToSettingsV2({
789
+ blockType: node.type,
790
+ ...node.data
791
+ });
792
+ const { blockType: _ignoredBlockType, ...data } = normalized;
793
+ return {
794
+ ...node,
795
+ data
796
+ };
797
+ };
798
+ var migratePageDocumentSettingsToV2 = (value) => {
799
+ const current = assertPageStudioDocumentV1(value);
800
+ return {
801
+ ...current,
802
+ nodes: current.nodes.map(migratePageNodeToSettingsV2)
803
+ };
804
+ };
805
+ var pageStudioMigrations = [
806
+ {
807
+ fromVersion: 1,
808
+ migrate: migratePageDocumentSettingsToV2,
809
+ toVersion: 1
810
+ }
811
+ ];
812
+
813
+ // src/studio-pages/index.ts
814
+ var withSectionStyleDefaults = (value) => ({
815
+ ...sectionStyleDefaults,
816
+ ...value
817
+ });
818
+ var defaultNodeData = {
819
+ bookingEmbed: {
820
+ ...withSectionStyleDefaults({}),
821
+ buttonHref: "/contact",
822
+ buttonLabel: "Book Consultation",
823
+ description: "Let visitors book a consultation.",
824
+ title: "Book a Time"
825
+ },
826
+ beforeAfter: withSectionStyleDefaults({
827
+ itemsPerRow: 2,
828
+ items: [
829
+ {
830
+ description: "Before and after result summary.",
831
+ imageCornerStyle: "rounded",
832
+ imageFit: "cover",
833
+ imagePosition: "center",
834
+ label: "Project One"
835
+ }
836
+ ],
837
+ subtitle: "Show visual proof from real projects.",
838
+ title: "Before & After Results"
839
+ }),
840
+ cta: {
841
+ ...withSectionStyleDefaults({}),
842
+ backgroundColor: "#1f684f",
843
+ buttonHref: "/contact",
844
+ buttonLabel: "Contact Us",
845
+ description: "Optional supporting copy.",
846
+ headline: "Ready to get started?",
847
+ style: "light"
848
+ },
849
+ faq: {
850
+ ...withSectionStyleDefaults({}),
851
+ items: [{ answer: "Answer goes here.", question: "Frequently asked question?" }],
852
+ title: "Frequently Asked Questions"
853
+ },
854
+ featureGrid: {
855
+ ...withSectionStyleDefaults({}),
856
+ itemsPerRow: 3,
857
+ items: [
858
+ { description: "Explain this point.", iconType: "badge", icon: "01", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature One" },
859
+ { description: "Explain this point.", iconType: "badge", icon: "02", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Two" },
860
+ { description: "Explain this point.", iconType: "badge", icon: "03", imageCornerStyle: "rounded", imageFit: "cover", imagePosition: "center", title: "Feature Three" }
861
+ ],
862
+ title: "Section Title",
863
+ variant: "cards"
864
+ },
865
+ formEmbed: {
866
+ ...withSectionStyleDefaults({}),
867
+ description: "Collect lead details from visitors.",
868
+ formType: "quote",
869
+ title: "Request a Quote"
870
+ },
871
+ hero: {
872
+ ...withSectionStyleDefaults({}),
873
+ backgroundColor: "",
874
+ backgroundOverlayMode: "none",
875
+ backgroundOverlayOpacity: 45,
876
+ backgroundOverlayColor: "#000000",
877
+ backgroundOverlayGradientFrom: "#0d4a37",
878
+ backgroundOverlayGradientTo: "#1f684f",
879
+ backgroundOverlayGradientAngle: "135",
880
+ backgroundOverlayGradientFromStrength: 100,
881
+ backgroundOverlayGradientToStrength: 100,
882
+ backgroundOverlayGradientStart: 0,
883
+ backgroundOverlayGradientEnd: 100,
884
+ backgroundOverlayGradientFeather: 100,
885
+ backgroundImageCornerStyle: "rounded",
886
+ backgroundImageFit: "cover",
887
+ backgroundImagePosition: "center",
888
+ heroHeight: "sm",
889
+ headline: "New Hero Section",
890
+ kicker: "Optional kicker",
891
+ primaryHref: "/contact",
892
+ primaryLabel: "Primary Action",
893
+ secondaryHref: "/services",
894
+ secondaryLabel: "Secondary Action",
895
+ subheadline: "Describe your offer clearly for website visitors.",
896
+ variant: "default"
897
+ },
898
+ media: {
899
+ ...withSectionStyleDefaults({}),
900
+ caption: "Add a caption",
901
+ imageCornerStyle: "rounded",
902
+ imageFit: "cover",
903
+ imagePosition: "center",
904
+ size: "default"
905
+ },
906
+ logoWall: withSectionStyleDefaults({
907
+ items: [
908
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 1" },
909
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 2" },
910
+ { imageCornerStyle: "rounded", imageFit: "contain", imagePosition: "center", name: "Trusted Partner 3" }
911
+ ],
912
+ subtitle: "Trusted by teams and homeowners across Central Texas.",
913
+ title: "Trusted by Local Organizations"
914
+ }),
915
+ richText: {
916
+ ...withSectionStyleDefaults({}),
917
+ content: {
918
+ root: {
919
+ children: [
920
+ {
921
+ children: [
922
+ {
923
+ detail: 0,
924
+ format: 0,
925
+ mode: "normal",
926
+ style: "",
927
+ text: "Write your content here.",
928
+ type: "text",
929
+ version: 1
930
+ }
931
+ ],
932
+ direction: "ltr",
933
+ format: "",
934
+ indent: 0,
935
+ type: "paragraph",
936
+ version: 1
937
+ }
938
+ ],
939
+ direction: "ltr",
940
+ format: "",
941
+ indent: 0,
942
+ type: "root",
943
+ version: 1
944
+ }
945
+ },
946
+ title: "Section Heading",
947
+ width: "normal"
948
+ },
949
+ testimonials: {
950
+ ...withSectionStyleDefaults({}),
951
+ autoRotate: true,
952
+ items: [{ location: "City, ST", name: "Customer Name", quote: "Customer feedback goes here.", rating: 5 }],
953
+ rotateIntervalSeconds: 7,
954
+ title: "What Customers Say",
955
+ visibleCount: 3
956
+ },
957
+ stats: withSectionStyleDefaults({
958
+ items: [
959
+ { description: "Average response time", label: "Same-Day Quotes", value: "24h" },
960
+ { description: "Projects completed", label: "Completed Jobs", value: "1,200+" },
961
+ { description: "Client satisfaction score", label: "Satisfaction", value: "4.9/5" }
962
+ ],
963
+ subtitle: "Highlight measurable outcomes to build trust quickly.",
964
+ title: "Performance Highlights"
965
+ })
966
+ };
967
+ var nodeTypeLabels = {
968
+ bookingEmbed: "Booking Embed",
969
+ beforeAfter: "Before / After",
970
+ cta: "Call To Action",
971
+ faq: "FAQ",
972
+ featureGrid: "Feature Grid",
973
+ formEmbed: "Form Embed",
974
+ hero: "Hero",
975
+ logoWall: "Logo Wall",
976
+ media: "Media",
977
+ richText: "Rich Text",
978
+ stats: "Stats",
979
+ testimonials: "Testimonials"
980
+ };
981
+ var pageNodeTypes = Object.keys(defaultNodeData).map((type) => ({
982
+ type,
983
+ displayName: nodeTypeLabels[type] || type,
984
+ description: `Page node for ${nodeTypeLabels[type] || type}`,
985
+ getDefaultData: () => {
986
+ const migrated = migrateBlockToSettingsV2(structuredClone(defaultNodeData[type]));
987
+ const { blockType: _ignoredBlockType, ...data } = migrated;
988
+ return data;
989
+ }
990
+ }));
991
+ var validatePageDocument = (document) => {
992
+ const issues = [];
993
+ if (!document.title || document.title.trim().length === 0) {
994
+ issues.push({
995
+ code: "pages.title.required",
996
+ message: "Page title is required before publishing.",
997
+ path: "title",
998
+ severity: "error"
999
+ });
1000
+ }
1001
+ if (document.nodes.length === 0) {
1002
+ issues.push({
1003
+ code: "pages.nodes.required",
1004
+ message: "At least one section is required.",
1005
+ path: "nodes",
1006
+ severity: "error"
1007
+ });
1008
+ }
1009
+ document.nodes.forEach((node, index) => {
1010
+ if (node.type === "hero" && typeof node.data.headline !== "string") {
1011
+ issues.push({
1012
+ code: "pages.hero.headline",
1013
+ message: "Hero section requires a headline.",
1014
+ path: `nodes.${index}.data.headline`,
1015
+ severity: "error"
1016
+ });
1017
+ }
1018
+ });
1019
+ return issues;
1020
+ };
1021
+ var pagePaletteGroups = [
1022
+ {
1023
+ id: "page-core",
1024
+ label: "Core Sections",
1025
+ items: [
1026
+ { nodeType: "hero", title: "Hero", description: "Top-of-page headline and CTA" },
1027
+ { nodeType: "featureGrid", title: "Feature Grid", description: "Service or value cards" },
1028
+ { nodeType: "stats", title: "Stats", description: "Key performance highlights" },
1029
+ { nodeType: "logoWall", title: "Logo Wall", description: "Trust logos and badges" },
1030
+ { nodeType: "beforeAfter", title: "Before / After", description: "Visual before-and-after gallery" },
1031
+ { nodeType: "richText", title: "Rich Text", description: "Long-form content area" },
1032
+ { nodeType: "media", title: "Media", description: "Image/video section" },
1033
+ { nodeType: "testimonials", title: "Testimonials", description: "Social proof quotes" },
1034
+ { nodeType: "faq", title: "FAQ", description: "Question-and-answer section" },
1035
+ { nodeType: "cta", title: "Call To Action", description: "Conversion strip with button" },
1036
+ { nodeType: "formEmbed", title: "Form Embed", description: "Lead capture form" },
1037
+ { nodeType: "bookingEmbed", title: "Booking Embed", description: "Scheduling panel" }
1038
+ ]
1039
+ }
1040
+ ];
1041
+ var pageInspectorPanelRegistry = Object.keys(defaultNodeData).map((nodeType) => ({
1042
+ nodeType,
1043
+ panelID: `${nodeType}-panel`,
1044
+ panelLabel: `${nodeTypeLabels[nodeType] || nodeType} Settings`
1045
+ }));
1046
+ var resolvePanelFields = (nodeType) => inspectorDefinitionByBlockType[nodeType]?.fields.map((field) => ({
1047
+ advanced: field.advanced,
1048
+ group: field.group,
1049
+ inlineEditable: field.inlineEditable,
1050
+ key: field.key,
1051
+ label: field.label,
1052
+ type: field.type
1053
+ })) || [];
1054
+ var pageInspectorPanels = pageInspectorPanelRegistry.map((entry) => ({
1055
+ fields: resolvePanelFields(entry.nodeType),
1056
+ id: entry.panelID,
1057
+ label: entry.panelLabel,
1058
+ nodeType: entry.nodeType
1059
+ }));
1060
+ var pageStudioModuleManifest = {
1061
+ id: "studio-pages",
1062
+ version: "0.1.0-beta.0",
1063
+ displayName: "Pages Studio Module",
1064
+ nodeTypes: pageNodeTypes,
1065
+ paletteGroups: pagePaletteGroups,
1066
+ inspectorPanels: pageInspectorPanels,
1067
+ validators: [validatePageDocument],
1068
+ migrations: pageStudioMigrations,
1069
+ compiler: {
1070
+ compileNode: (node) => {
1071
+ const normalized = migrateBlockToSettingsV2({
1072
+ blockType: node.type,
1073
+ ...node.data
1074
+ });
1075
+ return {
1076
+ id: node.id,
1077
+ ...normalized
1078
+ };
1079
+ }
1080
+ },
1081
+ permissions: [
1082
+ { action: "read", role: "admin" },
1083
+ { action: "read", role: "editor" },
1084
+ { action: "read", role: "client" },
1085
+ { action: "update", role: "admin" },
1086
+ { action: "update", role: "editor" },
1087
+ { action: "update", role: "client" },
1088
+ { action: "publish", role: "admin" },
1089
+ { action: "publish", role: "editor" }
1090
+ ]
1091
+ };
1092
+ var ensureNodeID = (inputID, index) => {
1093
+ if (typeof inputID === "string" && inputID.length > 0) {
1094
+ return inputID;
1095
+ }
1096
+ return `node-${index + 1}`;
1097
+ };
1098
+ var layoutToStudioDocument = (layout, title, metadata) => {
1099
+ const nodes = layout.filter((block) => typeof block.blockType === "string").map((rawBlock, index) => {
1100
+ const block = migrateBlockToSettingsV2(rawBlock);
1101
+ const blockType = String(block.blockType);
1102
+ const { id, blockType: _ignoredBlockType, ...data } = block;
1103
+ return {
1104
+ id: ensureNodeID(id, index),
1105
+ type: blockType,
1106
+ data
1107
+ };
1108
+ });
1109
+ return {
1110
+ metadata,
1111
+ schemaVersion: 1,
1112
+ title,
1113
+ nodes,
1114
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1115
+ };
1116
+ };
1117
+ var studioDocumentToLayout = (document) => document.nodes.map(
1118
+ (node) => migrateBlockToSettingsV2({
1119
+ id: node.id,
1120
+ blockType: node.type,
1121
+ ...node.data
1122
+ })
1123
+ );
1124
+ var createDefaultStudioDocument = (title) => ({
1125
+ metadata: {},
1126
+ schemaVersion: 1,
1127
+ title,
1128
+ nodes: [],
1129
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1130
+ });
1131
+
1132
+ export {
1133
+ defaultBuilderThemeTokens,
1134
+ resolveBuilderThemeTokens,
1135
+ pageNodeTypes,
1136
+ pagePaletteGroups,
1137
+ pageInspectorPanels,
1138
+ pageStudioModuleManifest,
1139
+ layoutToStudioDocument,
1140
+ studioDocumentToLayout,
1141
+ createDefaultStudioDocument,
1142
+ studio_pages_exports
1143
+ };