@orion-studios/payload-studio 0.6.0-beta.13 → 0.6.0-beta.131

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 (38) hide show
  1. package/dist/admin/client.js +2061 -538
  2. package/dist/admin/client.mjs +2078 -568
  3. package/dist/admin/index.js +124 -15
  4. package/dist/admin/index.mjs +1 -1
  5. package/dist/admin-app/client.js +14 -5
  6. package/dist/admin-app/client.mjs +1 -1
  7. package/dist/admin-app/styles.css +277 -1
  8. package/dist/admin.css +98 -2
  9. package/dist/builder-v2/client.d.mts +18 -0
  10. package/dist/builder-v2/client.d.ts +18 -0
  11. package/dist/builder-v2/client.js +3837 -0
  12. package/dist/builder-v2/client.mjs +3712 -0
  13. package/dist/builder-v2/index.d.mts +248 -0
  14. package/dist/builder-v2/index.d.ts +248 -0
  15. package/dist/builder-v2/index.js +805 -0
  16. package/dist/builder-v2/index.mjs +755 -0
  17. package/dist/builder-v2/styles.css +2514 -0
  18. package/dist/{chunk-PF3EBZXF.mjs → chunk-7ZMXZRBP.mjs} +39 -3
  19. package/dist/{chunk-XZQILJK3.mjs → chunk-JC3UV74N.mjs} +124 -15
  20. package/dist/{chunk-KPIX7OSV.mjs → chunk-NF37A575.mjs} +14 -5
  21. package/dist/{chunk-XKUTZ7IU.mjs → chunk-NGLIA2OE.mjs} +53 -2
  22. package/dist/{chunk-OTHERBGX.mjs → chunk-ZADL33R6.mjs} +1 -1
  23. package/dist/{index-Cv-6qnrw.d.mts → index-D5zrOdyv.d.mts} +3 -1
  24. package/dist/{index-Crx_MtPw.d.ts → index-Dv-Alx4h.d.ts} +3 -1
  25. package/dist/index.d.mts +1 -1
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.js +215 -19
  28. package/dist/index.mjs +4 -4
  29. package/dist/nextjs/index.js +39 -3
  30. package/dist/nextjs/index.mjs +2 -2
  31. package/dist/studio-pages/builder.css +66 -5
  32. package/dist/studio-pages/client.js +618 -73
  33. package/dist/studio-pages/client.mjs +641 -96
  34. package/dist/studio-pages/index.d.mts +1 -1
  35. package/dist/studio-pages/index.d.ts +1 -1
  36. package/dist/studio-pages/index.js +91 -4
  37. package/dist/studio-pages/index.mjs +2 -2
  38. package/package.json +22 -3
@@ -6,7 +6,7 @@ import {
6
6
  } from "../chunk-ROTPP5CU.mjs";
7
7
 
8
8
  // src/studio-pages/builder/BuilderPageEditor.tsx
9
- import { useCallback, useEffect as useEffect5, useMemo as useMemo2, useRef as useRef3, useState as useState6 } from "react";
9
+ import { useCallback, useEffect as useEffect6, useMemo as useMemo2, useRef as useRef3, useState as useState6 } from "react";
10
10
 
11
11
  // src/blocks/blocks/sectionStyleFields.ts
12
12
  var sectionStyleDefaults = {
@@ -70,7 +70,9 @@ var defaultBuilderBlockSettingsV2 = {
70
70
  },
71
71
  typography: {
72
72
  bodyAlign: "left",
73
+ bodySizePt: null,
73
74
  headingAlign: "left",
75
+ headingSizePt: null,
74
76
  letterSpacingPreset: "normal",
75
77
  lineHeightPreset: "normal",
76
78
  maxTextWidth: "auto"
@@ -99,7 +101,9 @@ var defaultBuilderItemSettingsV2 = {
99
101
  },
100
102
  typography: {
101
103
  bodyAlign: "left",
104
+ bodySizePt: null,
102
105
  headingAlign: "left",
106
+ headingSizePt: null,
103
107
  letterSpacingPreset: "normal",
104
108
  lineHeightPreset: "normal",
105
109
  maxTextWidth: "auto"
@@ -129,6 +133,7 @@ var defaultBuilderThemeTokens = {
129
133
 
130
134
  // src/studio-pages/builder/adapters/settingsV2.ts
131
135
  var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
136
+ var isTextAlign = (value) => value === "left" || value === "center" || value === "right" || value === "justify";
132
137
  var parsePercent = (value) => {
133
138
  if (typeof value === "number" && Number.isFinite(value)) {
134
139
  return Math.max(0, Math.min(100, value));
@@ -153,6 +158,18 @@ var parsePixel = (value) => {
153
158
  }
154
159
  return null;
155
160
  };
161
+ var parsePoint = (value) => {
162
+ if (typeof value === "number" && Number.isFinite(value)) {
163
+ return Math.max(6, Math.min(120, Math.round(value)));
164
+ }
165
+ if (typeof value === "string" && value.trim().length > 0) {
166
+ const parsed = Number(value);
167
+ if (Number.isFinite(parsed)) {
168
+ return Math.max(6, Math.min(120, Math.round(parsed)));
169
+ }
170
+ }
171
+ return null;
172
+ };
156
173
  var mergeSettings = (defaults, input) => {
157
174
  if (!isRecord(input)) {
158
175
  return structuredClone(defaults);
@@ -171,6 +188,10 @@ var mergeSettings = (defaults, input) => {
171
188
  };
172
189
  var legacyBlockToV2Settings = (block) => {
173
190
  const current = structuredClone(defaultBuilderBlockSettingsV2);
191
+ if (block.blockType === "hero" && block.variant === "centered") {
192
+ current.typography.headingAlign = "center";
193
+ current.typography.bodyAlign = "center";
194
+ }
174
195
  current.layout.contentWidth = block.contentWidth === "narrow" || block.contentWidth === "content" || block.contentWidth === "wide" || block.contentWidth === "full" || block.contentWidth === "inherit" ? block.contentWidth : current.layout.contentWidth;
175
196
  current.layout.sectionPaddingX = block.sectionPaddingX === "none" || block.sectionPaddingX === "sm" || block.sectionPaddingX === "md" || block.sectionPaddingX === "lg" || block.sectionPaddingX === "inherit" ? block.sectionPaddingX : current.layout.sectionPaddingX;
176
197
  current.layout.sectionPaddingY = block.sectionPaddingY === "none" || block.sectionPaddingY === "sm" || block.sectionPaddingY === "lg" ? block.sectionPaddingY : current.layout.sectionPaddingY;
@@ -207,15 +228,28 @@ var legacyBlockToV2Settings = (block) => {
207
228
  current.media.positionX = parsePercent(block.imagePositionX ?? block.backgroundImagePositionX);
208
229
  current.media.positionY = parsePercent(block.imagePositionY ?? block.backgroundImagePositionY);
209
230
  current.media.height = parsePixel(block.imageHeight);
210
- current.typography.headingAlign = block.textHeadingAlign === "left" || block.textHeadingAlign === "center" || block.textHeadingAlign === "right" || block.textHeadingAlign === "justify" ? block.textHeadingAlign : current.typography.headingAlign;
211
- current.typography.bodyAlign = block.textBodyAlign === "left" || block.textBodyAlign === "center" || block.textBodyAlign === "right" || block.textBodyAlign === "justify" ? block.textBodyAlign : current.typography.bodyAlign;
231
+ current.typography.headingAlign = isTextAlign(block.textHeadingAlign) ? block.textHeadingAlign : current.typography.headingAlign;
232
+ current.typography.bodyAlign = isTextAlign(block.textBodyAlign) ? block.textBodyAlign : current.typography.bodyAlign;
233
+ current.typography.headingSizePt = parsePoint(block.textHeadingSizePt);
234
+ current.typography.bodySizePt = parsePoint(block.textBodySizePt);
212
235
  current.typography.maxTextWidth = block.textMaxWidth === "auto" || block.textMaxWidth === "sm" || block.textMaxWidth === "md" || block.textMaxWidth === "lg" || block.textMaxWidth === "full" ? block.textMaxWidth : current.typography.maxTextWidth;
213
236
  current.typography.lineHeightPreset = block.textLineHeightPreset === "tight" || block.textLineHeightPreset === "normal" || block.textLineHeightPreset === "relaxed" ? block.textLineHeightPreset : current.typography.lineHeightPreset;
214
237
  current.typography.letterSpacingPreset = block.textLetterSpacingPreset === "tight" || block.textLetterSpacingPreset === "normal" || block.textLetterSpacingPreset === "relaxed" ? block.textLetterSpacingPreset : current.typography.letterSpacingPreset;
215
238
  current.advanced.editCopyInPanel = Boolean(block.editCopyInPanel ?? current.advanced.editCopyInPanel);
216
239
  current.advanced.customClassName = typeof block.customClassName === "string" ? block.customClassName : current.advanced.customClassName;
217
240
  current.advanced.hideOnMobile = Boolean(block.hideOnMobile ?? current.advanced.hideOnMobile);
218
- return mergeSettings(current, block.settings);
241
+ const settings = mergeSettings(current, block.settings);
242
+ if (block.blockType === "hero") {
243
+ const top = settings.layout.paddingTopPt;
244
+ const bottom = settings.layout.paddingBottomPt;
245
+ const hasLegacyLinkedHeroPadding = settings.layout.linkVerticalPadding !== false && (top === null || typeof top === "undefined" || top === 30) && (bottom === null || typeof bottom === "undefined" || bottom === 30 || bottom === 20);
246
+ if (hasLegacyLinkedHeroPadding) {
247
+ settings.layout.linkVerticalPadding = false;
248
+ settings.layout.paddingTopPt = 30;
249
+ settings.layout.paddingBottomPt = 20;
250
+ }
251
+ }
252
+ return settings;
219
253
  };
220
254
  var v2SettingsToLegacyBlock = (blockWithSettings) => {
221
255
  const settings = legacyBlockToV2Settings(blockWithSettings);
@@ -241,6 +275,8 @@ var v2SettingsToLegacyBlock = (blockWithSettings) => {
241
275
  next.contentGradientAngle = settings.appearance.contentGradientAngle;
242
276
  next.textHeadingAlign = settings.typography.headingAlign;
243
277
  next.textBodyAlign = settings.typography.bodyAlign;
278
+ next.textHeadingSizePt = settings.typography.headingSizePt;
279
+ next.textBodySizePt = settings.typography.bodySizePt;
244
280
  next.textMaxWidth = settings.typography.maxTextWidth;
245
281
  next.textLineHeightPreset = settings.typography.lineHeightPreset;
246
282
  next.textLetterSpacingPreset = settings.typography.letterSpacingPreset;
@@ -335,6 +371,7 @@ var resolveTypographyStyleFromSettings = (settings) => {
335
371
  const letterSpacing = settings.letterSpacingPreset === "tight" ? "-0.01em" : settings.letterSpacingPreset === "relaxed" ? "0.02em" : "0.01em";
336
372
  const maxWidth = settings.maxTextWidth === "sm" ? "36ch" : settings.maxTextWidth === "md" ? "52ch" : settings.maxTextWidth === "lg" ? "72ch" : settings.maxTextWidth === "full" ? "100%" : void 0;
337
373
  return {
374
+ ...typeof settings.bodySizePt === "number" && Number.isFinite(settings.bodySizePt) ? { fontSize: `${settings.bodySizePt}pt` } : {},
338
375
  letterSpacing,
339
376
  lineHeight,
340
377
  maxWidth,
@@ -343,7 +380,7 @@ var resolveTypographyStyleFromSettings = (settings) => {
343
380
  };
344
381
 
345
382
  // src/studio-pages/builder/settings-v2/BlockInspectorRenderer.tsx
346
- import { useMemo, useState as useState2 } from "react";
383
+ import { useEffect as useEffect2, useMemo, useState as useState2 } from "react";
347
384
 
348
385
  // src/studio-pages/builder/ui/Accordion.tsx
349
386
  import { useEffect, useState } from "react";
@@ -504,8 +541,52 @@ var alignOptions = [
504
541
  { label: "Right", value: "right" },
505
542
  { label: "Justify", value: "justify" }
506
543
  ];
507
- var layoutFieldSet = [];
544
+ var layoutFieldSet = [
545
+ {
546
+ group: "layout",
547
+ key: "settings.layout.linkVerticalPadding",
548
+ label: "Link Top/Bottom Padding",
549
+ tags: ["spacing", "padding", "vertical"],
550
+ type: "checkbox"
551
+ },
552
+ {
553
+ group: "layout",
554
+ key: "settings.layout.paddingTopPt",
555
+ label: "Top Padding (pt)",
556
+ max: 240,
557
+ min: 0,
558
+ tags: ["spacing", "padding", "top"],
559
+ type: "number"
560
+ },
561
+ {
562
+ group: "layout",
563
+ key: "settings.layout.paddingBottomPt",
564
+ label: "Bottom Padding (pt)",
565
+ max: 240,
566
+ min: 0,
567
+ tags: ["spacing", "padding", "bottom"],
568
+ type: "number"
569
+ }
570
+ ];
508
571
  var typographyFieldSet = [
572
+ {
573
+ group: "typography",
574
+ key: "settings.typography.headingSizePt",
575
+ label: "Heading Text Size (pt)",
576
+ max: 120,
577
+ min: 6,
578
+ tags: ["text", "size", "heading", "font"],
579
+ type: "number"
580
+ },
581
+ {
582
+ group: "typography",
583
+ key: "settings.typography.bodySizePt",
584
+ label: "Body Text Size (pt)",
585
+ max: 72,
586
+ min: 6,
587
+ tags: ["text", "size", "body", "paragraph", "font"],
588
+ type: "number"
589
+ },
509
590
  {
510
591
  group: "typography",
511
592
  key: "settings.typography.headingAlign",
@@ -612,6 +693,7 @@ var mediaFieldSet = [
612
693
  ];
613
694
  var commonInspectorGroups = [
614
695
  { key: "basics", label: "Basics" },
696
+ { key: "layout", label: "Layout" },
615
697
  { key: "typography", label: "Typography" },
616
698
  { key: "media", label: "Media" },
617
699
  { key: "advanced", label: "Advanced" }
@@ -728,6 +810,13 @@ var inspectorDefinitionByBlockType = {
728
810
  { group: "basics", inlineEditable: true, key: "kicker", label: "Kicker", type: "text" },
729
811
  { group: "basics", inlineEditable: true, key: "headline", label: "Headline", type: "text" },
730
812
  { group: "basics", inlineEditable: true, key: "subheadline", label: "Subheadline", type: "textarea" },
813
+ {
814
+ group: "basics",
815
+ key: "settings.marquee.itemsText",
816
+ label: "Scrolling Bar Options",
817
+ tags: ["marquee", "scrolling", "bar", "categories"],
818
+ type: "textarea"
819
+ },
731
820
  {
732
821
  group: "basics",
733
822
  key: "variant",
@@ -897,6 +986,69 @@ var normalizeNumber = (value, fallback) => {
897
986
  }
898
987
  return fallback;
899
988
  };
989
+ var sectionPaddingPointMap = {
990
+ none: 0,
991
+ sm: 17,
992
+ md: 31,
993
+ lg: 41
994
+ };
995
+ var heroDefaultPaddingTopPt = 30;
996
+ var heroDefaultPaddingBottomPt = 20;
997
+ var defaultTextSizePointMap = {
998
+ cta: { body: 14, heading: 36 },
999
+ faq: { body: 12, heading: 18 },
1000
+ featureGrid: { body: 12, heading: 36 },
1001
+ formEmbed: { body: 12, heading: 36 },
1002
+ hero: { body: 14, heading: 48 },
1003
+ media: { body: 12, heading: 36 },
1004
+ richText: { body: 12, heading: 39 },
1005
+ stats: { body: 11, heading: 30 },
1006
+ testimonials: { body: 12, heading: 36 }
1007
+ };
1008
+ var normalizeSectionPaddingY = (value) => value === "none" || value === "sm" || value === "lg" ? value : "md";
1009
+ var normalizePaddingPointValue = (value) => {
1010
+ if (typeof value === "number" && Number.isFinite(value)) {
1011
+ return Math.max(0, Math.min(240, Math.round(value)));
1012
+ }
1013
+ if (typeof value === "string" && value.trim().length > 0) {
1014
+ const parsed = Number(value);
1015
+ if (Number.isFinite(parsed)) {
1016
+ return Math.max(0, Math.min(240, Math.round(parsed)));
1017
+ }
1018
+ }
1019
+ return null;
1020
+ };
1021
+ var normalizeTextSizePointValue = (value) => {
1022
+ if (typeof value === "number" && Number.isFinite(value)) {
1023
+ return Math.max(6, Math.min(120, Math.round(value)));
1024
+ }
1025
+ if (typeof value === "string" && value.trim().length > 0) {
1026
+ const parsed = Number(value);
1027
+ if (Number.isFinite(parsed)) {
1028
+ return Math.max(6, Math.min(120, Math.round(parsed)));
1029
+ }
1030
+ }
1031
+ return null;
1032
+ };
1033
+ var getEffectiveVerticalPaddingValue = (block, key) => {
1034
+ const explicit = normalizePaddingPointValue(getByPath(block, key));
1035
+ if (explicit !== null) {
1036
+ return explicit;
1037
+ }
1038
+ const layoutSectionPaddingY = getByPath(block, "settings.layout.sectionPaddingY");
1039
+ const legacySectionPaddingY = block.sectionPaddingY;
1040
+ const inherited = block.blockType === "hero" ? key === "settings.layout.paddingBottomPt" ? heroDefaultPaddingBottomPt : heroDefaultPaddingTopPt : sectionPaddingPointMap[normalizeSectionPaddingY(layoutSectionPaddingY || legacySectionPaddingY)];
1041
+ return inherited;
1042
+ };
1043
+ var getEffectiveTextSizeValue = (block, key) => {
1044
+ const explicit = normalizeTextSizePointValue(getByPath(block, key));
1045
+ if (explicit !== null) {
1046
+ return explicit;
1047
+ }
1048
+ const blockType = typeof block.blockType === "string" ? block.blockType : "";
1049
+ const defaults = defaultTextSizePointMap[blockType] || { body: 12, heading: 36 };
1050
+ return key === "settings.typography.headingSizePt" ? defaults.heading : defaults.body;
1051
+ };
900
1052
  var getRelationID = (value) => {
901
1053
  if (typeof value === "number" || typeof value === "string") {
902
1054
  return value;
@@ -925,6 +1077,12 @@ var toMediaLibraryItem = (value) => {
925
1077
  };
926
1078
  };
927
1079
  var mediaLabel = (item) => item.filename || item.alt || `Media #${item.id}`;
1080
+ var findMediaLibraryItem = (library, id) => {
1081
+ if (id === null) {
1082
+ return null;
1083
+ }
1084
+ return library.find((item) => String(item.id) === String(id)) || null;
1085
+ };
928
1086
  var groupLabel = (key) => commonInspectorGroups.find((group) => group.key === key)?.label || key;
929
1087
  function BlockInspectorRenderer({
930
1088
  block,
@@ -945,6 +1103,21 @@ function BlockInspectorRenderer({
945
1103
  media: false,
946
1104
  typography: false
947
1105
  });
1106
+ const [supportsEyeDropper, setSupportsEyeDropper] = useState2(false);
1107
+ useEffect2(() => {
1108
+ setSupportsEyeDropper(Boolean(window.EyeDropper));
1109
+ }, []);
1110
+ const pickColorFromScreen = async (onSelect) => {
1111
+ const EyeDropper = window.EyeDropper;
1112
+ if (!EyeDropper) {
1113
+ return;
1114
+ }
1115
+ try {
1116
+ const result = await new EyeDropper().open();
1117
+ onSelect(result.sRGBHex);
1118
+ } catch {
1119
+ }
1120
+ };
948
1121
  const definition = inspectorDefinitionByBlockType[blockType];
949
1122
  const fields = definition?.fields || [];
950
1123
  const resolvedFields = useMemo(() => {
@@ -1048,8 +1221,9 @@ function BlockInspectorRenderer({
1048
1221
  title: group.label,
1049
1222
  children: /* @__PURE__ */ jsxs3("div", { className: "orion-builder-settings-field-list", children: [
1050
1223
  group.key === "media" ? effectiveMediaSources.map((source) => {
1051
- const selectedSourceMedia = toMediaLibraryItem(source.value);
1052
1224
  const selectedSourceMediaID = getRelationID(source.value);
1225
+ const selectedRelationMedia = toMediaLibraryItem(source.value);
1226
+ const selectedSourceMedia = selectedRelationMedia ?? findMediaLibraryItem(source.library, selectedSourceMediaID);
1053
1227
  const sourceOptions = selectedSourceMedia && !source.library.some((item) => String(item.id) === String(selectedSourceMedia.id)) ? [selectedSourceMedia, ...source.library] : source.library;
1054
1228
  return /* @__PURE__ */ jsxs3(
1055
1229
  "div",
@@ -1059,6 +1233,26 @@ function BlockInspectorRenderer({
1059
1233
  children: [
1060
1234
  source.loading ? /* @__PURE__ */ jsx3("div", { className: "orion-builder-settings-note", children: "Loading media library..." }) : null,
1061
1235
  source.error ? /* @__PURE__ */ jsx3("div", { className: "orion-builder-settings-error", children: source.error }) : null,
1236
+ selectedSourceMedia?.url ? (
1237
+ // eslint-disable-next-line @next/next/no-img-element
1238
+ /* @__PURE__ */ jsx3(
1239
+ "img",
1240
+ {
1241
+ alt: selectedSourceMedia.alt || source.label,
1242
+ src: selectedSourceMedia.url,
1243
+ style: {
1244
+ aspectRatio: "16 / 9",
1245
+ border: "1px solid rgba(35, 51, 82, 0.14)",
1246
+ borderRadius: 10,
1247
+ display: "block",
1248
+ marginBottom: "0.7rem",
1249
+ objectFit: effectiveMedia.fit,
1250
+ objectPosition: `${effectiveMedia.positionX}% ${effectiveMedia.positionY}%`,
1251
+ width: "100%"
1252
+ }
1253
+ }
1254
+ )
1255
+ ) : /* @__PURE__ */ jsx3("div", { className: "orion-builder-settings-empty", children: "No image selected." }),
1062
1256
  /* @__PURE__ */ jsxs3("label", { className: "orion-builder-settings-label", children: [
1063
1257
  source.label,
1064
1258
  /* @__PURE__ */ jsxs3(
@@ -1074,6 +1268,10 @@ function BlockInspectorRenderer({
1074
1268
  }
1075
1269
  )
1076
1270
  ] }),
1271
+ selectedSourceMedia?.alt ? /* @__PURE__ */ jsxs3("label", { className: "orion-builder-settings-label", children: [
1272
+ "Media Description",
1273
+ /* @__PURE__ */ jsx3("input", { className: "orion-builder-settings-input", readOnly: true, type: "text", value: selectedSourceMedia.alt })
1274
+ ] }) : selectedSourceMediaID !== null ? /* @__PURE__ */ jsx3("div", { className: "orion-builder-settings-note", children: "This media item does not have a description yet." }) : null,
1077
1275
  /* @__PURE__ */ jsx3(
1078
1276
  "button",
1079
1277
  {
@@ -1130,19 +1328,20 @@ function BlockInspectorRenderer({
1130
1328
  }
1131
1329
  ) : null,
1132
1330
  (hasMediaGroupContent ? group.fields.filter((field) => !(group.key === "media" && field.key.startsWith("settings.media."))) : group.fields).map((field) => {
1133
- if (field.key === "settings.layout.paddingBottomPt" && Boolean(getByPath(block, "settings.layout.linkVerticalPadding"))) {
1331
+ if (field.key === "settings.layout.paddingBottomPt" && getByPath(block, "settings.layout.linkVerticalPadding") !== false && block.blockType !== "hero") {
1134
1332
  return null;
1135
1333
  }
1136
- if (field.key === "settings.layout.paddingRightPt" && Boolean(getByPath(block, "settings.layout.linkHorizontalPadding"))) {
1334
+ if (field.key === "settings.layout.paddingRightPt" && getByPath(block, "settings.layout.linkHorizontalPadding") !== false) {
1137
1335
  return null;
1138
1336
  }
1139
1337
  const fieldValue = getByPath(block, field.key);
1140
1338
  if (field.type === "checkbox") {
1339
+ const checked = field.key === "settings.layout.linkVerticalPadding" || field.key === "settings.layout.linkHorizontalPadding" ? typeof fieldValue === "boolean" ? fieldValue : block.blockType === "hero" ? false : true : Boolean(fieldValue);
1141
1340
  return /* @__PURE__ */ jsxs3("label", { className: "orion-builder-settings-label is-checkbox", children: [
1142
1341
  /* @__PURE__ */ jsx3(
1143
1342
  "input",
1144
1343
  {
1145
- checked: Boolean(fieldValue),
1344
+ checked,
1146
1345
  onChange: (event) => updateForKey(field.key, event.target.checked),
1147
1346
  type: "checkbox"
1148
1347
  }
@@ -1165,8 +1364,10 @@ function BlockInspectorRenderer({
1165
1364
  ] }, field.key);
1166
1365
  }
1167
1366
  if (field.type === "number") {
1168
- const numberValue = typeof fieldValue === "number" ? fieldValue : typeof fieldValue === "string" && fieldValue.trim().length > 0 ? Number(fieldValue) : null;
1169
- const resolvedValue = typeof numberValue === "number" && Number.isFinite(numberValue) ? numberValue : "";
1367
+ const isPaddingPointField = field.key === "settings.layout.paddingTopPt" || field.key === "settings.layout.paddingBottomPt";
1368
+ const isTextSizePointField = field.key === "settings.typography.headingSizePt" || field.key === "settings.typography.bodySizePt";
1369
+ const numberValue = isTextSizePointField ? normalizeTextSizePointValue(fieldValue) : normalizePaddingPointValue(fieldValue);
1370
+ const resolvedValue = numberValue !== null ? numberValue : isPaddingPointField ? getEffectiveVerticalPaddingValue(block, field.key) : isTextSizePointField ? getEffectiveTextSizeValue(block, field.key) : "";
1170
1371
  return /* @__PURE__ */ jsxs3("label", { className: "orion-builder-settings-label", children: [
1171
1372
  field.label,
1172
1373
  /* @__PURE__ */ jsx3(
@@ -1210,15 +1411,35 @@ function BlockInspectorRenderer({
1210
1411
  if (field.type === "color") {
1211
1412
  return /* @__PURE__ */ jsxs3("label", { className: "orion-builder-settings-label", children: [
1212
1413
  field.label,
1213
- /* @__PURE__ */ jsx3(
1214
- "input",
1215
- {
1216
- className: "orion-builder-settings-input is-color",
1217
- onChange: (event) => updateForKey(field.key, event.target.value),
1218
- type: "color",
1219
- value: typeof fieldValue === "string" && fieldValue.length > 0 ? fieldValue : "#ffffff"
1220
- }
1221
- )
1414
+ /* @__PURE__ */ jsxs3("span", { className: "orion-builder-settings-color-control", children: [
1415
+ /* @__PURE__ */ jsx3(
1416
+ "input",
1417
+ {
1418
+ className: "orion-builder-settings-input is-color",
1419
+ onChange: (event) => updateForKey(field.key, event.target.value),
1420
+ type: "color",
1421
+ value: typeof fieldValue === "string" && fieldValue.length > 0 ? fieldValue : "#ffffff"
1422
+ }
1423
+ ),
1424
+ supportsEyeDropper ? /* @__PURE__ */ jsx3(
1425
+ "button",
1426
+ {
1427
+ "aria-label": `Pick ${field.label} from screen`,
1428
+ className: "orion-builder-settings-eyedropper",
1429
+ "data-orion-color-eyedropper": "true",
1430
+ onClick: () => pickColorFromScreen((color) => updateForKey(field.key, color)),
1431
+ title: "Pick color from screen",
1432
+ type: "button",
1433
+ children: /* @__PURE__ */ jsx3("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3(
1434
+ "path",
1435
+ {
1436
+ d: "M14.7 4.3a2.4 2.4 0 0 1 3.4 0l1.6 1.6a2.4 2.4 0 0 1 0 3.4l-1.2 1.2 1 1a1 1 0 1 1-1.4 1.4l-1-1-8.9 8.9H4v-4.2l8.9-8.9-1-1a1 1 0 0 1 1.4-1.4l1 1 1.4-1.4Zm-.4 4.8-8.3 8.3V19h1.6l8.3-8.3-1.6-1.6Z",
1437
+ fill: "currentColor"
1438
+ }
1439
+ ) })
1440
+ }
1441
+ ) : null
1442
+ ] })
1222
1443
  ] }, field.key);
1223
1444
  }
1224
1445
  return /* @__PURE__ */ jsxs3("label", { className: "orion-builder-settings-label", children: [
@@ -1477,7 +1698,7 @@ var pageInspectorPanels = pageInspectorPanelRegistry.map((entry) => ({
1477
1698
  }));
1478
1699
 
1479
1700
  // src/studio-pages/builder/hooks/usePersistentSidebarPanel.ts
1480
- import { useEffect as useEffect2, useState as useState3 } from "react";
1701
+ import { useEffect as useEffect3, useState as useState3 } from "react";
1481
1702
 
1482
1703
  // src/studio-pages/builder/sidebar/types.ts
1483
1704
  var isSidebarPanelKey = (value) => value === "pageDefaults" || value === "addSections" || value === "selected";
@@ -1485,7 +1706,7 @@ var isSidebarPanelKey = (value) => value === "pageDefaults" || value === "addSec
1485
1706
  // src/studio-pages/builder/hooks/usePersistentSidebarPanel.ts
1486
1707
  function usePersistentSidebarPanel(pageID) {
1487
1708
  const [activeSidebarPanel, setActiveSidebarPanel] = useState3("selected");
1488
- useEffect2(() => {
1709
+ useEffect3(() => {
1489
1710
  const storageKey = `orion-builder-panels:${pageID}`;
1490
1711
  const raw = window.localStorage.getItem(storageKey);
1491
1712
  if (!raw) {
@@ -1511,7 +1732,7 @@ function usePersistentSidebarPanel(pageID) {
1511
1732
  } catch {
1512
1733
  }
1513
1734
  }, [pageID]);
1514
- useEffect2(() => {
1735
+ useEffect3(() => {
1515
1736
  const storageKey = `orion-builder-panels:${pageID}`;
1516
1737
  window.localStorage.setItem(storageKey, JSON.stringify({ activePanel: activeSidebarPanel }));
1517
1738
  }, [activeSidebarPanel, pageID]);
@@ -1790,7 +2011,7 @@ var registerBuilderBlockPreviewRenderer = (renderer) => {
1790
2011
  var getRegisteredBuilderBlockPreviewRenderer = () => globalScope.__ORION_STUDIO_BUILDER_BLOCK_PREVIEW_RENDERER__ ?? null;
1791
2012
 
1792
2013
  // src/studio-pages/builder/ui/InlineText.tsx
1793
- import { useEffect as useEffect3, useRef, useState as useState4 } from "react";
2014
+ import { useEffect as useEffect4, useRef, useState as useState4 } from "react";
1794
2015
  import { jsx as jsx5 } from "react/jsx-runtime";
1795
2016
  function InlineText({
1796
2017
  as = "p",
@@ -1810,7 +2031,7 @@ function InlineText({
1810
2031
  }
1811
2032
  return raw.replace(/\r?\n/g, " ").replace(/\s+/g, " ").trim();
1812
2033
  };
1813
- useEffect3(() => {
2034
+ useEffect4(() => {
1814
2035
  if (!editing || !editableRef.current) {
1815
2036
  return;
1816
2037
  }
@@ -1888,7 +2109,7 @@ function UploadOverlay({ label = "Uploading image..." }) {
1888
2109
  }
1889
2110
 
1890
2111
  // src/studio-pages/builder/ui/BlockFrame.tsx
1891
- import { useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
2112
+ import { useEffect as useEffect5, useRef as useRef2, useState as useState5 } from "react";
1892
2113
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1893
2114
  function BlockFrame({
1894
2115
  children,
@@ -1908,7 +2129,7 @@ function BlockFrame({
1908
2129
  const isDropTarget = dragIndex !== null && dragIndex !== index && dropPosition !== null;
1909
2130
  const showDropBefore = isDropTarget && dropPosition === "before";
1910
2131
  const showDropAfter = isDropTarget && dropPosition === "after";
1911
- useEffect4(() => {
2132
+ useEffect5(() => {
1912
2133
  if (dragIndex === null) {
1913
2134
  setDropPosition(null);
1914
2135
  setDropHovered(false);
@@ -2129,8 +2350,8 @@ function renderSimpleBlockPreview(args) {
2129
2350
  getImagePresentationStyle: getImagePresentationStyle2,
2130
2351
  index,
2131
2352
  isBlockUploadTarget,
2132
- normalizeImageCornerStyle: normalizeImageCornerStyle2,
2133
- normalizeImageFit: normalizeImageFit2,
2353
+ normalizeImageCornerStyle: normalizeImageCornerStyle3,
2354
+ normalizeImageFit: normalizeImageFit3,
2134
2355
  normalizeText: normalizeText3,
2135
2356
  onDropAt,
2136
2357
  renderWithSectionShell,
@@ -2314,8 +2535,8 @@ function renderSimpleBlockPreview(args) {
2314
2535
  const imagePositionX = parseOptionalPercentNumber(mediaSettings.positionX ?? block?.imagePositionX);
2315
2536
  const imagePositionY = parseOptionalPercentNumber(mediaSettings.positionY ?? block?.imagePositionY);
2316
2537
  const imageStyle = getImagePresentationStyle2({
2317
- cornerStyle: normalizeImageCornerStyle2(mediaSettings.cornerStyle ?? block?.imageCornerStyle),
2318
- fit: normalizeImageFit2(mediaSettings.fit ?? block?.imageFit),
2538
+ cornerStyle: normalizeImageCornerStyle3(mediaSettings.cornerStyle ?? block?.imageCornerStyle),
2539
+ fit: normalizeImageFit3(mediaSettings.fit ?? block?.imageFit),
2319
2540
  positionX: imagePositionX,
2320
2541
  positionY: imagePositionY
2321
2542
  });
@@ -2845,6 +3066,76 @@ var normalizeNumber2 = (value, fallback) => {
2845
3066
  return fallback;
2846
3067
  };
2847
3068
  var clamp = (value, min, max) => Math.max(min, Math.min(max, value));
3069
+ var getRelationID2 = (value) => {
3070
+ if (typeof value === "number" || typeof value === "string") {
3071
+ return value;
3072
+ }
3073
+ if (!isRecord5(value)) {
3074
+ return null;
3075
+ }
3076
+ const id = value.id;
3077
+ return typeof id === "number" || typeof id === "string" ? id : null;
3078
+ };
3079
+ var toMediaLibraryItem2 = (value) => {
3080
+ if (!isRecord5(value)) {
3081
+ return null;
3082
+ }
3083
+ const id = getRelationID2(value);
3084
+ if (id === null) {
3085
+ return null;
3086
+ }
3087
+ const filename = typeof value.filename === "string" ? value.filename : "";
3088
+ const url = typeof value.url === "string" && value.url.length > 0 ? value.url : filename ? `/api/media/file/${encodeURIComponent(filename)}` : "";
3089
+ return {
3090
+ alt: typeof value.alt === "string" ? value.alt : "",
3091
+ filename,
3092
+ id,
3093
+ url
3094
+ };
3095
+ };
3096
+ var mediaFromImageURL = (url, fallbackLabel) => {
3097
+ if (typeof url !== "string" || url.trim().length === 0) {
3098
+ return null;
3099
+ }
3100
+ const normalizedURL = url.trim();
3101
+ const filename = normalizedURL.split("/").filter(Boolean).pop() || fallbackLabel;
3102
+ return {
3103
+ alt: fallbackLabel,
3104
+ filename,
3105
+ id: `url:${normalizedURL}`,
3106
+ url: normalizedURL
3107
+ };
3108
+ };
3109
+ var mediaLabel2 = (item) => item.filename || item.alt || `Media #${item.id}`;
3110
+ var findMediaLibraryItem2 = (library, id) => {
3111
+ if (id === null) {
3112
+ return null;
3113
+ }
3114
+ return library.find((item) => String(item.id) === String(id)) || null;
3115
+ };
3116
+ var normalizeImageFit = (value) => value === "contain" ? "contain" : "cover";
3117
+ var normalizeImageCornerStyle = (value) => value === "square" ? "square" : "rounded";
3118
+ var getItemMediaSettings = (item) => {
3119
+ const settings = isRecord5(item.settings) ? item.settings : {};
3120
+ const media = isRecord5(settings.media) ? settings.media : {};
3121
+ return {
3122
+ cornerStyle: normalizeImageCornerStyle(media.cornerStyle ?? item.imageCornerStyle),
3123
+ fit: normalizeImageFit(media.fit ?? item.imageFit),
3124
+ height: (() => {
3125
+ const value = media.height ?? item.imageHeight;
3126
+ if (typeof value === "number" && Number.isFinite(value)) {
3127
+ return value;
3128
+ }
3129
+ if (typeof value === "string" && value.trim().length > 0) {
3130
+ const parsed = Number(value);
3131
+ return Number.isFinite(parsed) ? parsed : null;
3132
+ }
3133
+ return null;
3134
+ })(),
3135
+ positionX: clamp(normalizeNumber2(media.positionX ?? item.imagePositionX, 50), 0, 100),
3136
+ positionY: clamp(normalizeNumber2(media.positionY ?? item.imagePositionY, 50), 0, 100)
3137
+ };
3138
+ };
2848
3139
  var hasQueryMatch = (query, ...values) => {
2849
3140
  const normalized = query.trim().toLowerCase();
2850
3141
  if (!normalized) {
@@ -2891,18 +3182,148 @@ var bulletsToTextareaValue = (value) => {
2891
3182
  return value.map((item) => isRecord5(item) && typeof item.label === "string" ? item.label.trim() : "").filter(Boolean).join("\n");
2892
3183
  };
2893
3184
  var textareaValueToBullets = (value) => value.split("\n").map((line) => line.trim()).filter(Boolean).map((label) => ({ label }));
3185
+ function ItemMediaControl({
3186
+ fieldName,
3187
+ imageURLFieldName,
3188
+ item,
3189
+ itemIndex,
3190
+ label,
3191
+ mediaLibrary,
3192
+ mediaLibraryError,
3193
+ mediaLibraryLoading,
3194
+ maxHeight,
3195
+ minHeight,
3196
+ onRemoveItemMedia,
3197
+ onSelectItemMedia,
3198
+ onUpdateItemField,
3199
+ onUpdateItemMediaPresentation,
3200
+ onUploadItemMedia,
3201
+ searchQuery,
3202
+ uploadDisabled,
3203
+ uploadLabel,
3204
+ uploading
3205
+ }) {
3206
+ const directImageURL = normalizeText(item[imageURLFieldName]);
3207
+ const selectedRelationMedia = toMediaLibraryItem2(item[fieldName]) ?? mediaFromImageURL(directImageURL, label);
3208
+ const selectedMediaID = getRelationID2(item[fieldName]) ?? selectedRelationMedia?.id ?? null;
3209
+ const selectedMedia = selectedRelationMedia ?? findMediaLibraryItem2(mediaLibrary, selectedMediaID);
3210
+ const previewURL = selectedMedia?.url || directImageURL;
3211
+ const mediaSettings = getItemMediaSettings(item);
3212
+ const sourceOptions = selectedMedia && !mediaLibrary.some((libraryItem) => String(libraryItem.id) === String(selectedMedia.id)) ? [selectedMedia, ...mediaLibrary] : mediaLibrary;
3213
+ if (!hasQueryMatch(searchQuery, label, "image", "media", "photo", "picture", "url", "fit", "crop", "height")) {
3214
+ return null;
3215
+ }
3216
+ return /* @__PURE__ */ jsxs11("div", { className: "orion-builder-settings-item-card", style: { padding: "0.56rem" }, children: [
3217
+ /* @__PURE__ */ jsx12("div", { className: "orion-builder-settings-label", children: label }),
3218
+ previewURL ? (
3219
+ // eslint-disable-next-line @next/next/no-img-element
3220
+ /* @__PURE__ */ jsx12(
3221
+ "img",
3222
+ {
3223
+ alt: selectedMedia?.alt || label,
3224
+ src: previewURL,
3225
+ style: {
3226
+ aspectRatio: "16 / 9",
3227
+ border: "1px solid rgba(35, 51, 82, 0.14)",
3228
+ borderRadius: mediaSettings.cornerStyle === "square" ? 4 : 10,
3229
+ display: "block",
3230
+ objectFit: mediaSettings.fit,
3231
+ objectPosition: `${mediaSettings.positionX}% ${mediaSettings.positionY}%`,
3232
+ width: "100%"
3233
+ }
3234
+ }
3235
+ )
3236
+ ) : /* @__PURE__ */ jsx12("div", { className: "orion-builder-settings-empty", children: "No image selected." }),
3237
+ mediaLibraryLoading ? /* @__PURE__ */ jsx12("div", { className: "orion-builder-settings-note", children: "Loading media library..." }) : null,
3238
+ mediaLibraryError ? /* @__PURE__ */ jsx12("div", { className: "orion-builder-settings-error", children: mediaLibraryError }) : null,
3239
+ /* @__PURE__ */ jsxs11("label", { className: "orion-builder-settings-label", children: [
3240
+ "Media Library Image",
3241
+ /* @__PURE__ */ jsxs11(
3242
+ "select",
3243
+ {
3244
+ className: "orion-builder-settings-input",
3245
+ onChange: (event) => onSelectItemMedia?.(itemIndex, fieldName, event.target.value),
3246
+ value: selectedMediaID !== null ? String(selectedMediaID) : "",
3247
+ children: [
3248
+ /* @__PURE__ */ jsx12("option", { value: "", children: "No image" }),
3249
+ sourceOptions.map((libraryItem) => /* @__PURE__ */ jsx12("option", { value: String(libraryItem.id), children: mediaLabel2(libraryItem) }, String(libraryItem.id)))
3250
+ ]
3251
+ }
3252
+ )
3253
+ ] }),
3254
+ selectedMedia?.alt ? /* @__PURE__ */ jsxs11("label", { className: "orion-builder-settings-label", children: [
3255
+ "Media Description",
3256
+ /* @__PURE__ */ jsx12("input", { className: "orion-builder-settings-input", readOnly: true, type: "text", value: selectedMedia.alt })
3257
+ ] }) : selectedMediaID !== null ? /* @__PURE__ */ jsx12("div", { className: "orion-builder-settings-note", children: "This media item does not have a description yet." }) : null,
3258
+ /* @__PURE__ */ jsx12(
3259
+ "button",
3260
+ {
3261
+ className: "orion-builder-settings-inline-btn",
3262
+ disabled: selectedMediaID === null,
3263
+ onClick: () => {
3264
+ onRemoveItemMedia?.(itemIndex, fieldName);
3265
+ onUpdateItemField(itemIndex, imageURLFieldName, "");
3266
+ },
3267
+ type: "button",
3268
+ children: "Remove Image"
3269
+ }
3270
+ ),
3271
+ /* @__PURE__ */ jsxs11("label", { className: "orion-builder-settings-label", children: [
3272
+ uploadLabel,
3273
+ /* @__PURE__ */ jsx12(
3274
+ "input",
3275
+ {
3276
+ accept: "image/*",
3277
+ className: "orion-builder-settings-input",
3278
+ disabled: uploadDisabled,
3279
+ onChange: (event) => {
3280
+ const file = event.currentTarget.files?.[0];
3281
+ if (file) {
3282
+ onUploadItemMedia?.(itemIndex, fieldName, file);
3283
+ }
3284
+ event.currentTarget.value = "";
3285
+ },
3286
+ type: "file"
3287
+ }
3288
+ )
3289
+ ] }),
3290
+ uploading ? /* @__PURE__ */ jsx12("div", { className: "orion-builder-settings-note", children: "Uploading image..." }) : null,
3291
+ /* @__PURE__ */ jsx12(
3292
+ ImageControls,
3293
+ {
3294
+ cornerStyle: mediaSettings.cornerStyle,
3295
+ fit: mediaSettings.fit,
3296
+ height: mediaSettings.height,
3297
+ maxHeight,
3298
+ minHeight,
3299
+ onChange: (field, value) => onUpdateItemMediaPresentation?.(itemIndex, field, value),
3300
+ positionX: mediaSettings.positionX,
3301
+ positionY: mediaSettings.positionY
3302
+ }
3303
+ )
3304
+ ] });
3305
+ }
2894
3306
  function ArrayItemsEditor({
2895
3307
  blockType,
2896
3308
  expandedItemIndex,
2897
3309
  items,
3310
+ mediaLibrary = [],
3311
+ mediaLibraryError = "",
3312
+ mediaLibraryLoading = false,
2898
3313
  mode,
2899
3314
  onAddItem,
3315
+ onRemoveItemMedia,
2900
3316
  onRemoveItem,
3317
+ onSelectItemMedia,
2901
3318
  onToggleItem,
2902
3319
  onUpdateItemField,
3320
+ onUpdateItemMediaPresentation,
2903
3321
  onUpdateItemSetting,
3322
+ onUploadItemMedia,
2904
3323
  searchQuery,
2905
- showInlineCopyFields
3324
+ showInlineCopyFields,
3325
+ uploadDisabled = false,
3326
+ isItemMediaUploading
2906
3327
  }) {
2907
3328
  const config = blockConfig[blockType];
2908
3329
  const normalizedQuery = searchQuery.trim().toLowerCase();
@@ -3052,11 +3473,30 @@ function ArrayItemsEditor({
3052
3473
  }
3053
3474
  )
3054
3475
  ] }) : null,
3055
- /* @__PURE__ */ jsxs11("div", { className: "orion-builder-settings-note", children: [
3056
- "Select this item and use the ",
3057
- /* @__PURE__ */ jsx12("strong", { children: "Media" }),
3058
- " group above for image source and presentation."
3059
- ] })
3476
+ /* @__PURE__ */ jsx12(
3477
+ ItemMediaControl,
3478
+ {
3479
+ fieldName: "media",
3480
+ imageURLFieldName: "imageURL",
3481
+ item,
3482
+ itemIndex,
3483
+ label: "Feature Image",
3484
+ maxHeight: 600,
3485
+ mediaLibrary,
3486
+ mediaLibraryError,
3487
+ mediaLibraryLoading,
3488
+ minHeight: 40,
3489
+ onRemoveItemMedia,
3490
+ onSelectItemMedia,
3491
+ onUpdateItemField,
3492
+ onUpdateItemMediaPresentation,
3493
+ onUploadItemMedia,
3494
+ searchQuery: normalizedQuery,
3495
+ uploadDisabled,
3496
+ uploadLabel: "Upload Feature Image",
3497
+ uploading: Boolean(isItemMediaUploading?.(itemIndex, "media"))
3498
+ }
3499
+ )
3060
3500
  ] }) : null,
3061
3501
  blockType === "logoWall" ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
3062
3502
  showInlineCopyFields ? /* @__PURE__ */ jsxs11("label", { className: "orion-builder-settings-label", children: [
@@ -3083,11 +3523,30 @@ function ArrayItemsEditor({
3083
3523
  }
3084
3524
  )
3085
3525
  ] }) : null,
3086
- /* @__PURE__ */ jsxs11("div", { className: "orion-builder-settings-note", children: [
3087
- "Select this item and use the ",
3088
- /* @__PURE__ */ jsx12("strong", { children: "Media" }),
3089
- " group above for image source and presentation."
3090
- ] })
3526
+ /* @__PURE__ */ jsx12(
3527
+ ItemMediaControl,
3528
+ {
3529
+ fieldName: "media",
3530
+ imageURLFieldName: "imageURL",
3531
+ item,
3532
+ itemIndex,
3533
+ label: "Logo Image",
3534
+ maxHeight: 200,
3535
+ mediaLibrary,
3536
+ mediaLibraryError,
3537
+ mediaLibraryLoading,
3538
+ minHeight: 24,
3539
+ onRemoveItemMedia,
3540
+ onSelectItemMedia,
3541
+ onUpdateItemField,
3542
+ onUpdateItemMediaPresentation,
3543
+ onUploadItemMedia,
3544
+ searchQuery: normalizedQuery,
3545
+ uploadDisabled,
3546
+ uploadLabel: "Upload Logo Image",
3547
+ uploading: Boolean(isItemMediaUploading?.(itemIndex, "media"))
3548
+ }
3549
+ )
3091
3550
  ] }) : null,
3092
3551
  blockType === "beforeAfter" ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
3093
3552
  showInlineCopyFields ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
@@ -3115,11 +3574,54 @@ function ArrayItemsEditor({
3115
3574
  )
3116
3575
  ] })
3117
3576
  ] }) : null,
3118
- /* @__PURE__ */ jsxs11("div", { className: "orion-builder-settings-note", children: [
3119
- "Select this item and use the ",
3120
- /* @__PURE__ */ jsx12("strong", { children: "Media" }),
3121
- " group above for before/after image source and presentation."
3122
- ] })
3577
+ /* @__PURE__ */ jsx12(
3578
+ ItemMediaControl,
3579
+ {
3580
+ fieldName: "beforeMedia",
3581
+ imageURLFieldName: "beforeImageURL",
3582
+ item,
3583
+ itemIndex,
3584
+ label: "Before Image",
3585
+ maxHeight: 600,
3586
+ mediaLibrary,
3587
+ mediaLibraryError,
3588
+ mediaLibraryLoading,
3589
+ minHeight: 60,
3590
+ onRemoveItemMedia,
3591
+ onSelectItemMedia,
3592
+ onUpdateItemField,
3593
+ onUpdateItemMediaPresentation,
3594
+ onUploadItemMedia,
3595
+ searchQuery: normalizedQuery,
3596
+ uploadDisabled,
3597
+ uploadLabel: "Upload Before Image",
3598
+ uploading: Boolean(isItemMediaUploading?.(itemIndex, "beforeMedia"))
3599
+ }
3600
+ ),
3601
+ /* @__PURE__ */ jsx12(
3602
+ ItemMediaControl,
3603
+ {
3604
+ fieldName: "afterMedia",
3605
+ imageURLFieldName: "afterImageURL",
3606
+ item,
3607
+ itemIndex,
3608
+ label: "After Image",
3609
+ maxHeight: 600,
3610
+ mediaLibrary,
3611
+ mediaLibraryError,
3612
+ mediaLibraryLoading,
3613
+ minHeight: 60,
3614
+ onRemoveItemMedia,
3615
+ onSelectItemMedia,
3616
+ onUpdateItemField,
3617
+ onUpdateItemMediaPresentation,
3618
+ onUploadItemMedia,
3619
+ searchQuery: normalizedQuery,
3620
+ uploadDisabled,
3621
+ uploadLabel: "Upload After Image",
3622
+ uploading: Boolean(isItemMediaUploading?.(itemIndex, "afterMedia"))
3623
+ }
3624
+ )
3123
3625
  ] }) : null,
3124
3626
  blockType === "stats" ? /* @__PURE__ */ jsx12(Fragment4, { children: showInlineCopyFields ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
3125
3627
  /* @__PURE__ */ jsxs11("label", { className: "orion-builder-settings-label", children: [
@@ -3284,6 +3786,19 @@ var resolveMedia = (value) => {
3284
3786
  }
3285
3787
  return null;
3286
3788
  };
3789
+ var mediaFromImageURL2 = (url, fallbackLabel = "Current image") => {
3790
+ if (typeof url !== "string" || url.trim().length === 0) {
3791
+ return null;
3792
+ }
3793
+ const normalizedURL = url.trim();
3794
+ const filename = normalizedURL.split("/").filter(Boolean).pop() || fallbackLabel;
3795
+ return {
3796
+ alt: fallbackLabel,
3797
+ filename,
3798
+ id: `url:${normalizedURL}`,
3799
+ url: normalizedURL
3800
+ };
3801
+ };
3287
3802
  var resolveMediaWithURL = (value, imageURL, alt) => {
3288
3803
  const resolved = resolveMedia(value);
3289
3804
  if (resolved?.url) {
@@ -3325,8 +3840,8 @@ var resolveBuilderMediumHeroHeight = (topViewportHeight) => {
3325
3840
  }
3326
3841
  return "50svh";
3327
3842
  };
3328
- var normalizeImageFit = (value) => normalizeHeroImageFit(value);
3329
- var normalizeImageCornerStyle = (value, legacyFitValue) => normalizeHeroImageCornerStyle(value, legacyFitValue);
3843
+ var normalizeImageFit2 = (value) => normalizeHeroImageFit(value);
3844
+ var normalizeImageCornerStyle2 = (value, legacyFitValue) => normalizeHeroImageCornerStyle(value, legacyFitValue);
3330
3845
  var positionPercent = (value, fit) => {
3331
3846
  const resolved = fit === "cover" && (value === "left" || value === "right") ? "center" : value;
3332
3847
  switch (resolved) {
@@ -3495,6 +4010,8 @@ var sectionPaddingMap = {
3495
4010
  md: "2.6rem",
3496
4011
  lg: "3.4rem"
3497
4012
  };
4013
+ var heroDefaultPaddingTop = "30pt";
4014
+ var heroDefaultPaddingBottom = "20pt";
3498
4015
  var quickAddBlockTypes = [
3499
4016
  "hero",
3500
4017
  "featureGrid",
@@ -3758,6 +4275,12 @@ function getThemeColorOverride(tokens, colorKey) {
3758
4275
  const normalized = value.trim();
3759
4276
  return normalized.length > 0 ? normalized : null;
3760
4277
  }
4278
+ function normalizeCustomClassName(value) {
4279
+ if (typeof value !== "string") {
4280
+ return "";
4281
+ }
4282
+ return value.split(/\s+/).map((className) => className.trim()).filter(Boolean).join(" ");
4283
+ }
3761
4284
  var sectionStyleFromBlock = (block, pageDefaults) => {
3762
4285
  const settings = isRecord6(block.settings) ? block.settings : {};
3763
4286
  const layoutSettings = isRecord6(settings.layout) ? settings.layout : {};
@@ -3843,15 +4366,15 @@ var sectionStyleFromBlock = (block, pageDefaults) => {
3843
4366
  } : {},
3844
4367
  sectionClass: `orion-builder-shell is-${pageDefaults.pageWidthDefault} padx-${resolvedSectionPaddingX}`,
3845
4368
  sectionInnerStyle: {
3846
- paddingBottom: customPaddingBottom === null ? sectionPaddingMap[sectionPaddingY] : `${customPaddingBottom}pt`,
4369
+ paddingBottom: customPaddingBottom === null ? block.blockType === "hero" ? heroDefaultPaddingBottom : sectionPaddingMap[sectionPaddingY] : `${customPaddingBottom}pt`,
3847
4370
  paddingLeft: customPaddingLeft === null ? void 0 : `${customPaddingLeft}pt`,
3848
4371
  paddingRight: customPaddingRight === null ? void 0 : `${customPaddingRight}pt`,
3849
- paddingTop: customPaddingTop === null ? sectionPaddingMap[sectionPaddingY] : `${customPaddingTop}pt`
4372
+ paddingTop: customPaddingTop === null ? block.blockType === "hero" ? heroDefaultPaddingTop : sectionPaddingMap[sectionPaddingY] : `${customPaddingTop}pt`
3850
4373
  },
3851
4374
  sectionStyle: sectionMode === "color" ? { background: sectionColor } : sectionMode === "gradient" ? { background: sectionGradient } : block.blockType === "hero" ? { background: "transparent" } : {}
3852
4375
  };
3853
4376
  };
3854
- function getRelationID2(value) {
4377
+ function getRelationID3(value) {
3855
4378
  if (typeof value === "number" || typeof value === "string") {
3856
4379
  return value;
3857
4380
  }
@@ -3884,7 +4407,7 @@ function extractUploadedMedia(value) {
3884
4407
  if (!candidate || typeof candidate !== "object") {
3885
4408
  return null;
3886
4409
  }
3887
- const id = getRelationID2(candidate);
4410
+ const id = getRelationID3(candidate);
3888
4411
  if (id === null) {
3889
4412
  return null;
3890
4413
  }
@@ -3895,11 +4418,11 @@ function extractUploadedMedia(value) {
3895
4418
  url: typeof candidate.url === "string" ? candidate.url : ""
3896
4419
  };
3897
4420
  }
3898
- function toMediaLibraryItem2(value) {
4421
+ function toMediaLibraryItem3(value) {
3899
4422
  if (!value || typeof value !== "object") {
3900
4423
  return null;
3901
4424
  }
3902
- const id = getRelationID2(value);
4425
+ const id = getRelationID3(value);
3903
4426
  if (id === null) {
3904
4427
  return null;
3905
4428
  }
@@ -4032,7 +4555,7 @@ function BuilderPageEditor({
4032
4555
  const selectedBlockAdvancedSettings = isRecord6(selectedBlockSettings.advanced) ? selectedBlockSettings.advanced : {};
4033
4556
  const isArrayItemBlockSelected = selectedType === "featureGrid" || selectedType === "logoWall" || selectedType === "beforeAfter" || selectedType === "stats" || selectedType === "faq" || selectedType === "testimonials";
4034
4557
  const selectedBlockHasMediaSource = selectedType === "hero" || selectedType === "media";
4035
- const selectedBlockMediaValue = selectedType === "hero" ? selectedBlock?.media : selectedType === "media" ? selectedBlock?.image : null;
4558
+ const selectedBlockMediaValue = selectedType === "hero" ? selectedBlock?.media ?? mediaFromImageURL2(selectedBlock?.backgroundImageURL, "Hero image") : selectedType === "media" ? selectedBlock?.image ?? mediaFromImageURL2(selectedBlock?.imageURL, "Section image") : null;
4036
4559
  const selectedItemRecord = typeof selectedItemIndex === "number" && selectedItemIndex >= 0 && selectedItemIndex < selectedItems.length && isRecord6(selectedItems[selectedItemIndex]) ? selectedItems[selectedItemIndex] : null;
4037
4560
  const editCopyInPanelEnabled = Boolean(selectedBlockAdvancedSettings.editCopyInPanel);
4038
4561
  const isBlockUploadTarget = (blockIndex, kind) => selectedIndex === blockIndex && uploadingTarget?.kind === kind;
@@ -4077,7 +4600,7 @@ function BuilderPageEditor({
4077
4600
  }
4078
4601
  const json = await response.json();
4079
4602
  const docs = Array.isArray(json.docs) ? json.docs : [];
4080
- const items = docs.map((doc2) => toMediaLibraryItem2(doc2)).filter((item) => item !== null);
4603
+ const items = docs.map((doc2) => toMediaLibraryItem3(doc2)).filter((item) => item !== null);
4081
4604
  setMediaLibrary(items);
4082
4605
  } catch (error) {
4083
4606
  setMediaLibraryError(error instanceof Error ? error.message : "Could not load media library.");
@@ -4085,10 +4608,10 @@ function BuilderPageEditor({
4085
4608
  setMediaLibraryLoading(false);
4086
4609
  }
4087
4610
  }, []);
4088
- useEffect5(() => {
4611
+ useEffect6(() => {
4089
4612
  void loadMediaLibrary();
4090
4613
  }, [loadMediaLibrary]);
4091
- useEffect5(() => {
4614
+ useEffect6(() => {
4092
4615
  const refreshMediaLibrary = () => {
4093
4616
  void loadMediaLibrary();
4094
4617
  };
@@ -4113,7 +4636,7 @@ function BuilderPageEditor({
4113
4636
  document.removeEventListener("visibilitychange", onVisibilityChange);
4114
4637
  };
4115
4638
  }, [loadMediaLibrary]);
4116
- useEffect5(() => {
4639
+ useEffect6(() => {
4117
4640
  let active = true;
4118
4641
  const checkSession = async () => {
4119
4642
  try {
@@ -4431,7 +4954,7 @@ function BuilderPageEditor({
4431
4954
  const nextLayout = cloneBlockLayout(layout);
4432
4955
  const block = nextLayout[selectedIndex];
4433
4956
  if (target.kind === "hero") {
4434
- const uploadedItem = toMediaLibraryItem2(uploaded);
4957
+ const uploadedItem = toMediaLibraryItem3(uploaded);
4435
4958
  nextLayout[selectedIndex] = {
4436
4959
  ...block,
4437
4960
  backgroundImageURL: uploadedItem?.url || normalizeText2(uploaded.url),
@@ -4495,13 +5018,13 @@ function BuilderPageEditor({
4495
5018
  const nextBlock = { ...migrateBlockToSettingsV2(block) };
4496
5019
  const blockType = normalizeText2(nextBlock.blockType);
4497
5020
  if (blockType === "hero") {
4498
- const mediaID = getRelationID2(nextBlock.media);
5021
+ const mediaID = getRelationID3(nextBlock.media);
4499
5022
  if (mediaID !== null) {
4500
5023
  nextBlock.media = mediaID;
4501
5024
  }
4502
5025
  }
4503
5026
  if (blockType === "media") {
4504
- const imageID = getRelationID2(nextBlock.image);
5027
+ const imageID = getRelationID3(nextBlock.image);
4505
5028
  if (imageID !== null) {
4506
5029
  nextBlock.image = imageID;
4507
5030
  }
@@ -4513,15 +5036,15 @@ function BuilderPageEditor({
4513
5036
  return rawItem;
4514
5037
  }
4515
5038
  const nextItem = { ...rawItem };
4516
- const mediaID = getRelationID2(nextItem.media);
5039
+ const mediaID = getRelationID3(nextItem.media);
4517
5040
  if (mediaID !== null) {
4518
5041
  nextItem.media = mediaID;
4519
5042
  }
4520
- const beforeMediaID = getRelationID2(nextItem.beforeMedia);
5043
+ const beforeMediaID = getRelationID3(nextItem.beforeMedia);
4521
5044
  if (beforeMediaID !== null) {
4522
5045
  nextItem.beforeMedia = beforeMediaID;
4523
5046
  }
4524
- const afterMediaID = getRelationID2(nextItem.afterMedia);
5047
+ const afterMediaID = getRelationID3(nextItem.afterMedia);
4525
5048
  if (afterMediaID !== null) {
4526
5049
  nextItem.afterMedia = afterMediaID;
4527
5050
  }
@@ -4577,6 +5100,7 @@ function BuilderPageEditor({
4577
5100
  const inheritProjectStyles = options?.inheritProjectStyles === true;
4578
5101
  const shell = sectionStyleFromBlock(block, pageDefaults);
4579
5102
  const blockSettings = isRecord6(block.settings) ? block.settings : {};
5103
+ const blockAdvanced = isRecord6(blockSettings.advanced) ? blockSettings.advanced : {};
4580
5104
  const blockTypography = isRecord6(blockSettings.typography) ? blockSettings.typography : {};
4581
5105
  const blockTheme = isRecord6(blockSettings.theme) ? blockSettings.theme : {};
4582
5106
  const heroBackgroundColor = normalizeText2(block.backgroundColor).trim();
@@ -4584,23 +5108,35 @@ function BuilderPageEditor({
4584
5108
  const heroMedia = block.blockType === "hero" ? resolveMedia(block.media) : null;
4585
5109
  const heroHasImage = block.blockType === "hero" && Boolean(heroBackgroundImageURL || heroMedia?.url);
4586
5110
  const heroTextColor = block.blockType === "hero" ? heroHasImage ? "#ffffff" : heroBackgroundColor ? getReadableTextColor(heroBackgroundColor, resolvedThemeTokens.colors.headingText, "#ffffff") : resolvedThemeTokens.colors.headingText : null;
5111
+ const bodyAlign = blockTypography.bodyAlign === "center" || blockTypography.bodyAlign === "justify" || blockTypography.bodyAlign === "right" ? blockTypography.bodyAlign : "left";
4587
5112
  const typographyStyle = resolveTypographyStyleFromSettings({
4588
- bodyAlign: blockTypography.bodyAlign === "center" || blockTypography.bodyAlign === "justify" || blockTypography.bodyAlign === "right" ? blockTypography.bodyAlign : "left",
5113
+ bodyAlign,
4589
5114
  letterSpacingPreset: blockTypography.letterSpacingPreset === "tight" || blockTypography.letterSpacingPreset === "relaxed" ? blockTypography.letterSpacingPreset : "normal",
4590
5115
  lineHeightPreset: blockTypography.lineHeightPreset === "tight" || blockTypography.lineHeightPreset === "relaxed" ? blockTypography.lineHeightPreset : "normal",
5116
+ bodySizePt: typeof blockTypography.bodySizePt === "number" && Number.isFinite(blockTypography.bodySizePt) ? blockTypography.bodySizePt : null,
4591
5117
  maxTextWidth: blockTypography.maxTextWidth === "sm" || blockTypography.maxTextWidth === "md" || blockTypography.maxTextWidth === "lg" || blockTypography.maxTextWidth === "full" ? blockTypography.maxTextWidth : "auto"
4592
5118
  });
4593
5119
  const headingAlign = blockTypography.headingAlign === "center" || blockTypography.headingAlign === "justify" || blockTypography.headingAlign === "right" ? blockTypography.headingAlign : "left";
4594
5120
  const headingColor = getThemeColorOverride(blockTheme, "headingText") || getThemeColorOverride(pageDefaults.themePage, "headingText") || getThemeColorOverride(siteThemeTokens, "headingText") || heroTextColor || resolvedThemeTokens.colors.headingText;
4595
5121
  const bodyColor = getThemeColorOverride(blockTheme, "bodyText") || getThemeColorOverride(pageDefaults.themePage, "bodyText") || getThemeColorOverride(siteThemeTokens, "bodyText") || heroTextColor || resolvedThemeTokens.colors.bodyText;
4596
- return /* @__PURE__ */ jsx13("section", { className: `${className} ${shell.sectionClass}`, style: shell.sectionStyle, children: /* @__PURE__ */ jsx13("div", { style: shell.sectionInnerStyle, children: /* @__PURE__ */ jsx13(
5122
+ const customClassName = normalizeCustomClassName(blockAdvanced.customClassName ?? block.customClassName);
5123
+ const hideOnMobile = Boolean(blockAdvanced.hideOnMobile ?? block.hideOnMobile);
5124
+ const sectionClassName = [
5125
+ className,
5126
+ shell.sectionClass,
5127
+ customClassName,
5128
+ hideOnMobile ? "orion-builder-hide-mobile" : ""
5129
+ ].filter(Boolean).join(" ");
5130
+ return /* @__PURE__ */ jsx13("section", { className: sectionClassName, style: shell.sectionStyle, children: /* @__PURE__ */ jsx13("div", { style: shell.sectionInnerStyle, children: /* @__PURE__ */ jsx13(
4597
5131
  "div",
4598
5132
  {
4599
5133
  className: shell.contentClass,
4600
5134
  style: {
4601
5135
  ...shell.contentStyle,
5136
+ "--orion-builder-heading-align": headingAlign,
5137
+ "--orion-builder-body-align": bodyAlign,
5138
+ "--orion-builder-actions-align": bodyAlign === "center" ? "center" : bodyAlign === "right" ? "flex-end" : "flex-start",
4602
5139
  ...inheritProjectStyles ? {} : {
4603
- "--orion-builder-heading-align": headingAlign,
4604
5140
  "--orion-builder-heading-color": headingColor,
4605
5141
  color: bodyColor,
4606
5142
  ...typographyStyle
@@ -4825,7 +5361,7 @@ function BuilderPageEditor({
4825
5361
  }),
4826
5362
  [layout, pageDefaults]
4827
5363
  );
4828
- useEffect5(() => {
5364
+ useEffect6(() => {
4829
5365
  const readTopViewportHeight = () => {
4830
5366
  if (typeof window === "undefined") {
4831
5367
  setTopViewportHeight(null);
@@ -4984,14 +5520,14 @@ function BuilderPageEditor({
4984
5520
  setSavingStatus(null);
4985
5521
  }
4986
5522
  };
4987
- useEffect5(() => {
5523
+ useEffect6(() => {
4988
5524
  if (selectedIndex === null) {
4989
5525
  return;
4990
5526
  }
4991
5527
  setSidebarOpen(true);
4992
5528
  setActiveSidebarPanel("selected");
4993
5529
  }, [selectedIndex]);
4994
- useEffect5(() => {
5530
+ useEffect6(() => {
4995
5531
  if (selectedIndex === null) {
4996
5532
  setSelectedItemIndex(null);
4997
5533
  setExpandedItemIndex(null);
@@ -5009,7 +5545,7 @@ function BuilderPageEditor({
5009
5545
  (current) => typeof current === "number" && current >= 0 && current < selectedItems.length ? current : 0
5010
5546
  );
5011
5547
  }, [selectedIndex, selectedItems.length]);
5012
- useEffect5(() => {
5548
+ useEffect6(() => {
5013
5549
  if (layout.length > 0) {
5014
5550
  return;
5015
5551
  }
@@ -5087,8 +5623,8 @@ function BuilderPageEditor({
5087
5623
  }
5088
5624
  ] : [];
5089
5625
  const selectedMediaImageControls = selectedItemRecord && typeof selectedItemIndex === "number" && (selectedType === "featureGrid" || selectedType === "logoWall" || selectedType === "beforeAfter") ? {
5090
- cornerStyle: normalizeImageCornerStyle(selectedItemRecord.imageCornerStyle),
5091
- fit: normalizeImageFit(selectedItemRecord.imageFit),
5626
+ cornerStyle: normalizeImageCornerStyle2(selectedItemRecord.imageCornerStyle),
5627
+ fit: normalizeImageFit2(selectedItemRecord.imageFit),
5092
5628
  height: (() => {
5093
5629
  if (typeof selectedItemRecord.imageHeight === "number" && Number.isFinite(selectedItemRecord.imageHeight)) {
5094
5630
  return selectedItemRecord.imageHeight;
@@ -5106,10 +5642,10 @@ function BuilderPageEditor({
5106
5642
  positionX: parsePercentNumber(selectedItemRecord.imagePositionX, 50),
5107
5643
  positionY: parsePercentNumber(selectedItemRecord.imagePositionY, 50)
5108
5644
  } : void 0;
5109
- useEffect5(() => {
5645
+ useEffect6(() => {
5110
5646
  return;
5111
5647
  }, [layout]);
5112
- useEffect5(() => {
5648
+ useEffect6(() => {
5113
5649
  if (historyBypassRef.current) {
5114
5650
  historyBypassRef.current = false;
5115
5651
  previousSnapshotRef.current = cloneSnapshot(currentSnapshot);
@@ -5120,7 +5656,7 @@ function BuilderPageEditor({
5120
5656
  setFutureSnapshots([]);
5121
5657
  previousSnapshotRef.current = cloneSnapshot(currentSnapshot);
5122
5658
  }, [currentSnapshot]);
5123
- useEffect5(() => {
5659
+ useEffect6(() => {
5124
5660
  const onKeyDown = (event) => {
5125
5661
  const key = event.key.toLowerCase();
5126
5662
  const isUndo = (event.metaKey || event.ctrlKey) && key === "z" && !event.shiftKey;
@@ -5138,7 +5674,7 @@ function BuilderPageEditor({
5138
5674
  window.addEventListener("keydown", onKeyDown);
5139
5675
  return () => window.removeEventListener("keydown", onKeyDown);
5140
5676
  }, [canRedo, canUndo, futureSnapshots, pastSnapshots, currentSnapshot]);
5141
- useEffect5(() => {
5677
+ useEffect6(() => {
5142
5678
  window.parent?.postMessage(
5143
5679
  {
5144
5680
  dirty: isDirty,
@@ -5148,7 +5684,7 @@ function BuilderPageEditor({
5148
5684
  "*"
5149
5685
  );
5150
5686
  }, [isDirty]);
5151
- useEffect5(() => {
5687
+ useEffect6(() => {
5152
5688
  window.parent?.postMessage(
5153
5689
  {
5154
5690
  canRedo,
@@ -5159,7 +5695,7 @@ function BuilderPageEditor({
5159
5695
  "*"
5160
5696
  );
5161
5697
  }, [canRedo, canUndo]);
5162
- useEffect5(() => {
5698
+ useEffect6(() => {
5163
5699
  const onMessage = (event) => {
5164
5700
  const data = event.data;
5165
5701
  if (!data || data.source !== "payload-visual-builder-parent") {
@@ -5212,7 +5748,7 @@ function BuilderPageEditor({
5212
5748
  window.addEventListener("message", onMessage);
5213
5749
  return () => window.removeEventListener("message", onMessage);
5214
5750
  }, [canRedo, canUndo, isDirty, layout, pageDefaults.pageWidthDefault, title]);
5215
- useEffect5(() => {
5751
+ useEffect6(() => {
5216
5752
  const preventNavigationWhileEditing = (event) => {
5217
5753
  const editorRoot = editorRootRef.current;
5218
5754
  if (!editorRoot) {
@@ -5563,8 +6099,8 @@ function BuilderPageEditor({
5563
6099
  const itemPositionX = parseOptionalPercentNumber2(itemRecord?.imagePositionX);
5564
6100
  const itemPositionY = parseOptionalPercentNumber2(itemRecord?.imagePositionY);
5565
6101
  const itemImageStyle = getImagePresentationStyle({
5566
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
5567
- fit: normalizeImageFit(itemRecord?.imageFit),
6102
+ cornerStyle: normalizeImageCornerStyle2(itemRecord?.imageCornerStyle),
6103
+ fit: normalizeImageFit2(itemRecord?.imageFit),
5568
6104
  positionX: itemPositionX,
5569
6105
  positionY: itemPositionY
5570
6106
  });
@@ -5681,8 +6217,8 @@ function BuilderPageEditor({
5681
6217
  const itemPositionX = parseOptionalPercentNumber2(itemRecord?.imagePositionX);
5682
6218
  const itemPositionY = parseOptionalPercentNumber2(itemRecord?.imagePositionY);
5683
6219
  const itemImageStyle = getImagePresentationStyle({
5684
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
5685
- fit: normalizeImageFit(itemRecord?.imageFit),
6220
+ cornerStyle: normalizeImageCornerStyle2(itemRecord?.imageCornerStyle),
6221
+ fit: normalizeImageFit2(itemRecord?.imageFit),
5686
6222
  positionX: itemPositionX,
5687
6223
  positionY: itemPositionY
5688
6224
  });
@@ -5888,8 +6424,8 @@ function BuilderPageEditor({
5888
6424
  const itemPositionX = parseOptionalPercentNumber2(itemRecord?.imagePositionX);
5889
6425
  const itemPositionY = parseOptionalPercentNumber2(itemRecord?.imagePositionY);
5890
6426
  const imageStyle = getImagePresentationStyle({
5891
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
5892
- fit: normalizeImageFit(itemRecord?.imageFit),
6427
+ cornerStyle: normalizeImageCornerStyle2(itemRecord?.imageCornerStyle),
6428
+ fit: normalizeImageFit2(itemRecord?.imageFit),
5893
6429
  positionX: itemPositionX,
5894
6430
  positionY: itemPositionY,
5895
6431
  roundedRadius: 10
@@ -6002,8 +6538,8 @@ function BuilderPageEditor({
6002
6538
  const itemPositionX = parseOptionalPercentNumber2(itemRecord?.imagePositionX);
6003
6539
  const itemPositionY = parseOptionalPercentNumber2(itemRecord?.imagePositionY);
6004
6540
  const imageStyle = getImagePresentationStyle({
6005
- cornerStyle: normalizeImageCornerStyle(itemRecord?.imageCornerStyle),
6006
- fit: normalizeImageFit(itemRecord?.imageFit),
6541
+ cornerStyle: normalizeImageCornerStyle2(itemRecord?.imageCornerStyle),
6542
+ fit: normalizeImageFit2(itemRecord?.imageFit),
6007
6543
  positionX: itemPositionX,
6008
6544
  positionY: itemPositionY
6009
6545
  });
@@ -6309,8 +6845,8 @@ function BuilderPageEditor({
6309
6845
  getImagePresentationStyle,
6310
6846
  index,
6311
6847
  isBlockUploadTarget,
6312
- normalizeImageCornerStyle,
6313
- normalizeImageFit,
6848
+ normalizeImageCornerStyle: normalizeImageCornerStyle2,
6849
+ normalizeImageFit: normalizeImageFit2,
6314
6850
  normalizeText: normalizeText2,
6315
6851
  onDropAt,
6316
6852
  renderWithSectionShell,
@@ -6539,23 +7075,32 @@ function BuilderPageEditor({
6539
7075
  blockType: selectedType,
6540
7076
  expandedItemIndex,
6541
7077
  items: selectedItems,
7078
+ isItemMediaUploading: isSelectedItemMediaUploading,
7079
+ mediaLibrary,
7080
+ mediaLibraryError,
7081
+ mediaLibraryLoading,
6542
7082
  mode: settingsPanelMode,
6543
7083
  onAddItem: appendDefaultItemToSelected,
6544
7084
  onRemoveItem: (itemIndex) => removeItemFromSelected("items", itemIndex),
7085
+ onRemoveItemMedia: (itemIndex, fieldName) => setSelectedItemMediaFieldFromLibrary(itemIndex, fieldName, ""),
7086
+ onSelectItemMedia: (itemIndex, fieldName, mediaID) => setSelectedItemMediaFieldFromLibrary(itemIndex, fieldName, mediaID),
6545
7087
  onToggleItem: toggleSelectedItem,
6546
7088
  onUpdateItemField: (itemIndex, fieldName, value) => updateArrayItemField(selectedIndex ?? 0, "items", itemIndex, fieldName, value),
7089
+ onUpdateItemMediaPresentation: (itemIndex, fieldName, value) => updateArrayItemSettingField(selectedIndex ?? 0, "items", itemIndex, `media.${fieldName}`, value),
6547
7090
  onUpdateItemSetting: (itemIndex, path, value) => updateArrayItemSettingField(selectedIndex ?? 0, "items", itemIndex, path, value),
7091
+ onUploadItemMedia: uploadItemMediaFromV2,
6548
7092
  searchQuery: settingsSearchQuery,
6549
- showInlineCopyFields: editCopyInPanelEnabled
7093
+ showInlineCopyFields: editCopyInPanelEnabled,
7094
+ uploadDisabled: uploadingTarget !== null
6550
7095
  }
6551
7096
  ) : null,
6552
7097
  /* @__PURE__ */ jsxs12("label", { style: sidebarLabelStyle, children: [
6553
- "Upload Alt Text",
7098
+ "New Upload Alt Text",
6554
7099
  /* @__PURE__ */ jsx13(
6555
7100
  "input",
6556
7101
  {
6557
7102
  onChange: (event) => setUploadAltText(event.target.value),
6558
- placeholder: "Describe the image",
7103
+ placeholder: "Used only when uploading a new image",
6559
7104
  style: sidebarInputStyle,
6560
7105
  type: "text",
6561
7106
  value: uploadAltText