@orion-studios/payload-studio 0.6.0-beta.57 → 0.6.0-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builder-v2/client.js +108 -8
- package/dist/builder-v2/client.mjs +108 -8
- package/dist/builder-v2/styles.css +46 -0
- package/package.json +1 -1
|
@@ -953,6 +953,24 @@ var registerProjectDynamicComponents = (editor, adapter) => {
|
|
|
953
953
|
|
|
954
954
|
// src/builder-v2/editor/GrapesPageEditor.tsx
|
|
955
955
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
956
|
+
var decodeHtmlAttribute3 = (value) => {
|
|
957
|
+
if (typeof value !== "string") {
|
|
958
|
+
return "";
|
|
959
|
+
}
|
|
960
|
+
return value.replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
961
|
+
};
|
|
962
|
+
var parseItemsJson = (value) => {
|
|
963
|
+
const decoded = decodeHtmlAttribute3(value);
|
|
964
|
+
if (!decoded) {
|
|
965
|
+
return [];
|
|
966
|
+
}
|
|
967
|
+
try {
|
|
968
|
+
const parsed = JSON.parse(decoded);
|
|
969
|
+
return Array.isArray(parsed) ? parsed.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item))) : [];
|
|
970
|
+
} catch {
|
|
971
|
+
return [];
|
|
972
|
+
}
|
|
973
|
+
};
|
|
956
974
|
var postToParent = (payload) => {
|
|
957
975
|
window.parent?.postMessage(
|
|
958
976
|
{
|
|
@@ -1153,6 +1171,7 @@ function GrapesPageEditor({
|
|
|
1153
1171
|
const editorRef = (0, import_react.useRef)(null);
|
|
1154
1172
|
const autosaveTimerRef = (0, import_react.useRef)(null);
|
|
1155
1173
|
const saveRef = (0, import_react.useRef)(async () => void 0);
|
|
1174
|
+
const selectedComponentRef = (0, import_react.useRef)(null);
|
|
1156
1175
|
const [error, setError] = (0, import_react.useState)("");
|
|
1157
1176
|
const [historyState, setHistoryState] = (0, import_react.useState)({ canRedo: false, canUndo: false });
|
|
1158
1177
|
const [lastSavedAt, setLastSavedAt] = (0, import_react.useState)("");
|
|
@@ -1164,6 +1183,37 @@ function GrapesPageEditor({
|
|
|
1164
1183
|
const [validationIssues, setValidationIssues] = (0, import_react.useState)([]);
|
|
1165
1184
|
const editorPageBasePath = initialData?.meta?.editorPageBasePath || "/admin/pages";
|
|
1166
1185
|
const pageTree = initialData?.meta?.pageTree || [];
|
|
1186
|
+
const summarizeSelectedComponent = (component) => {
|
|
1187
|
+
if (!component) {
|
|
1188
|
+
return null;
|
|
1189
|
+
}
|
|
1190
|
+
const attrs = component.getAttributes?.() || {};
|
|
1191
|
+
const componentType = String(attrs["data-orion-component"] || component.get?.("type") || "Section");
|
|
1192
|
+
const rawName = String(component.get?.("name") || componentType || "Section");
|
|
1193
|
+
const label = rawName.replace(/^orion-/, "").replace(/^xo/, "XO ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").trim();
|
|
1194
|
+
const items = parseItemsJson(attrs["data-orion-items-json"]).map((item, index) => ({
|
|
1195
|
+
index,
|
|
1196
|
+
title: typeof item.title === "string" && item.title.trim() ? item.title.trim() : `Item ${index + 1}`
|
|
1197
|
+
}));
|
|
1198
|
+
return {
|
|
1199
|
+
items: items.length > 0 ? items : void 0,
|
|
1200
|
+
label: label || "Section",
|
|
1201
|
+
type: componentType
|
|
1202
|
+
};
|
|
1203
|
+
};
|
|
1204
|
+
const updateSelectedItems = (updater) => {
|
|
1205
|
+
const component = selectedComponentRef.current;
|
|
1206
|
+
if (!component) {
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
const attrs = component.getAttributes?.() || {};
|
|
1210
|
+
const currentItems = parseItemsJson(attrs["data-orion-items-json"]);
|
|
1211
|
+
const nextItems = updater(currentItems);
|
|
1212
|
+
component.addAttributes?.({
|
|
1213
|
+
"data-orion-items-json": JSON.stringify(nextItems)
|
|
1214
|
+
});
|
|
1215
|
+
setSelectionSummary(summarizeSelectedComponent(component));
|
|
1216
|
+
};
|
|
1167
1217
|
const updateHistoryState = (editor) => {
|
|
1168
1218
|
const next = {
|
|
1169
1219
|
canRedo: editor.UndoManager.hasRedo(),
|
|
@@ -1289,14 +1339,8 @@ function GrapesPageEditor({
|
|
|
1289
1339
|
});
|
|
1290
1340
|
editor.on("component:selected", (component) => {
|
|
1291
1341
|
const typed = component;
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
const rawName = String(typed?.get?.("name") || componentType || "Section");
|
|
1295
|
-
const label = rawName.replace(/^orion-/, "").replace(/^xo/, "XO ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").trim();
|
|
1296
|
-
setSelectionSummary({
|
|
1297
|
-
label: label || "Section",
|
|
1298
|
-
type: componentType
|
|
1299
|
-
});
|
|
1342
|
+
selectedComponentRef.current = typed;
|
|
1343
|
+
setSelectionSummary(summarizeSelectedComponent(typed));
|
|
1300
1344
|
setSaveMessage("Selection ready");
|
|
1301
1345
|
});
|
|
1302
1346
|
setSelectedDevice(editor.getDevice() || "desktop");
|
|
@@ -1540,6 +1584,62 @@ function GrapesPageEditor({
|
|
|
1540
1584
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: selectionSummary ? "Edit this section content, images, links, layout, and spacing." : "Select a section or element on the canvas to edit its settings." }),
|
|
1541
1585
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { id: "orion-builder-v2-traits" })
|
|
1542
1586
|
] }),
|
|
1587
|
+
selectionSummary?.items ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "orion-builder-v2-panel", children: [
|
|
1588
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Items" }),
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Add, duplicate, remove, then click item text or images on the canvas to edit them." }),
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "orion-builder-v2-items", children: selectionSummary.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "orion-builder-v2-item-row", children: [
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.title }),
|
|
1592
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1593
|
+
"button",
|
|
1594
|
+
{
|
|
1595
|
+
onClick: () => {
|
|
1596
|
+
updateSelectedItems((items) => {
|
|
1597
|
+
const source = items[item.index];
|
|
1598
|
+
if (!source) {
|
|
1599
|
+
return items;
|
|
1600
|
+
}
|
|
1601
|
+
const copy = [...items];
|
|
1602
|
+
copy.splice(item.index + 1, 0, {
|
|
1603
|
+
...source,
|
|
1604
|
+
title: typeof source.title === "string" ? `${source.title} copy` : source.title
|
|
1605
|
+
});
|
|
1606
|
+
return copy;
|
|
1607
|
+
});
|
|
1608
|
+
},
|
|
1609
|
+
type: "button",
|
|
1610
|
+
children: "Duplicate"
|
|
1611
|
+
}
|
|
1612
|
+
),
|
|
1613
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1614
|
+
"button",
|
|
1615
|
+
{
|
|
1616
|
+
onClick: () => {
|
|
1617
|
+
updateSelectedItems((items) => items.filter((_, index) => index !== item.index));
|
|
1618
|
+
},
|
|
1619
|
+
type: "button",
|
|
1620
|
+
children: "Remove"
|
|
1621
|
+
}
|
|
1622
|
+
)
|
|
1623
|
+
] }, `${item.index}-${item.title}`)) }),
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1625
|
+
"button",
|
|
1626
|
+
{
|
|
1627
|
+
className: "orion-builder-v2-wide-action",
|
|
1628
|
+
onClick: () => {
|
|
1629
|
+
updateSelectedItems((items) => [
|
|
1630
|
+
...items,
|
|
1631
|
+
{
|
|
1632
|
+
description: "Describe this feature.",
|
|
1633
|
+
imageURL: "",
|
|
1634
|
+
title: "New feature"
|
|
1635
|
+
}
|
|
1636
|
+
]);
|
|
1637
|
+
},
|
|
1638
|
+
type: "button",
|
|
1639
|
+
children: "Add item"
|
|
1640
|
+
}
|
|
1641
|
+
)
|
|
1642
|
+
] }) : null,
|
|
1543
1643
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "orion-builder-v2-panel", children: [
|
|
1544
1644
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Design" }),
|
|
1545
1645
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Adjust spacing, layout, typography, color, borders, and shadows for the selected section." }),
|
|
@@ -829,6 +829,24 @@ var registerProjectDynamicComponents = (editor, adapter) => {
|
|
|
829
829
|
|
|
830
830
|
// src/builder-v2/editor/GrapesPageEditor.tsx
|
|
831
831
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
832
|
+
var decodeHtmlAttribute3 = (value) => {
|
|
833
|
+
if (typeof value !== "string") {
|
|
834
|
+
return "";
|
|
835
|
+
}
|
|
836
|
+
return value.replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
837
|
+
};
|
|
838
|
+
var parseItemsJson = (value) => {
|
|
839
|
+
const decoded = decodeHtmlAttribute3(value);
|
|
840
|
+
if (!decoded) {
|
|
841
|
+
return [];
|
|
842
|
+
}
|
|
843
|
+
try {
|
|
844
|
+
const parsed = JSON.parse(decoded);
|
|
845
|
+
return Array.isArray(parsed) ? parsed.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item))) : [];
|
|
846
|
+
} catch {
|
|
847
|
+
return [];
|
|
848
|
+
}
|
|
849
|
+
};
|
|
832
850
|
var postToParent = (payload) => {
|
|
833
851
|
window.parent?.postMessage(
|
|
834
852
|
{
|
|
@@ -1029,6 +1047,7 @@ function GrapesPageEditor({
|
|
|
1029
1047
|
const editorRef = useRef(null);
|
|
1030
1048
|
const autosaveTimerRef = useRef(null);
|
|
1031
1049
|
const saveRef = useRef(async () => void 0);
|
|
1050
|
+
const selectedComponentRef = useRef(null);
|
|
1032
1051
|
const [error, setError] = useState("");
|
|
1033
1052
|
const [historyState, setHistoryState] = useState({ canRedo: false, canUndo: false });
|
|
1034
1053
|
const [lastSavedAt, setLastSavedAt] = useState("");
|
|
@@ -1040,6 +1059,37 @@ function GrapesPageEditor({
|
|
|
1040
1059
|
const [validationIssues, setValidationIssues] = useState([]);
|
|
1041
1060
|
const editorPageBasePath = initialData?.meta?.editorPageBasePath || "/admin/pages";
|
|
1042
1061
|
const pageTree = initialData?.meta?.pageTree || [];
|
|
1062
|
+
const summarizeSelectedComponent = (component) => {
|
|
1063
|
+
if (!component) {
|
|
1064
|
+
return null;
|
|
1065
|
+
}
|
|
1066
|
+
const attrs = component.getAttributes?.() || {};
|
|
1067
|
+
const componentType = String(attrs["data-orion-component"] || component.get?.("type") || "Section");
|
|
1068
|
+
const rawName = String(component.get?.("name") || componentType || "Section");
|
|
1069
|
+
const label = rawName.replace(/^orion-/, "").replace(/^xo/, "XO ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").trim();
|
|
1070
|
+
const items = parseItemsJson(attrs["data-orion-items-json"]).map((item, index) => ({
|
|
1071
|
+
index,
|
|
1072
|
+
title: typeof item.title === "string" && item.title.trim() ? item.title.trim() : `Item ${index + 1}`
|
|
1073
|
+
}));
|
|
1074
|
+
return {
|
|
1075
|
+
items: items.length > 0 ? items : void 0,
|
|
1076
|
+
label: label || "Section",
|
|
1077
|
+
type: componentType
|
|
1078
|
+
};
|
|
1079
|
+
};
|
|
1080
|
+
const updateSelectedItems = (updater) => {
|
|
1081
|
+
const component = selectedComponentRef.current;
|
|
1082
|
+
if (!component) {
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
const attrs = component.getAttributes?.() || {};
|
|
1086
|
+
const currentItems = parseItemsJson(attrs["data-orion-items-json"]);
|
|
1087
|
+
const nextItems = updater(currentItems);
|
|
1088
|
+
component.addAttributes?.({
|
|
1089
|
+
"data-orion-items-json": JSON.stringify(nextItems)
|
|
1090
|
+
});
|
|
1091
|
+
setSelectionSummary(summarizeSelectedComponent(component));
|
|
1092
|
+
};
|
|
1043
1093
|
const updateHistoryState = (editor) => {
|
|
1044
1094
|
const next = {
|
|
1045
1095
|
canRedo: editor.UndoManager.hasRedo(),
|
|
@@ -1165,14 +1215,8 @@ function GrapesPageEditor({
|
|
|
1165
1215
|
});
|
|
1166
1216
|
editor.on("component:selected", (component) => {
|
|
1167
1217
|
const typed = component;
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
const rawName = String(typed?.get?.("name") || componentType || "Section");
|
|
1171
|
-
const label = rawName.replace(/^orion-/, "").replace(/^xo/, "XO ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").trim();
|
|
1172
|
-
setSelectionSummary({
|
|
1173
|
-
label: label || "Section",
|
|
1174
|
-
type: componentType
|
|
1175
|
-
});
|
|
1218
|
+
selectedComponentRef.current = typed;
|
|
1219
|
+
setSelectionSummary(summarizeSelectedComponent(typed));
|
|
1176
1220
|
setSaveMessage("Selection ready");
|
|
1177
1221
|
});
|
|
1178
1222
|
setSelectedDevice(editor.getDevice() || "desktop");
|
|
@@ -1416,6 +1460,62 @@ function GrapesPageEditor({
|
|
|
1416
1460
|
/* @__PURE__ */ jsx("p", { children: selectionSummary ? "Edit this section content, images, links, layout, and spacing." : "Select a section or element on the canvas to edit its settings." }),
|
|
1417
1461
|
/* @__PURE__ */ jsx("div", { id: "orion-builder-v2-traits" })
|
|
1418
1462
|
] }),
|
|
1463
|
+
selectionSummary?.items ? /* @__PURE__ */ jsxs("div", { className: "orion-builder-v2-panel", children: [
|
|
1464
|
+
/* @__PURE__ */ jsx("h2", { children: "Items" }),
|
|
1465
|
+
/* @__PURE__ */ jsx("p", { children: "Add, duplicate, remove, then click item text or images on the canvas to edit them." }),
|
|
1466
|
+
/* @__PURE__ */ jsx("div", { className: "orion-builder-v2-items", children: selectionSummary.items.map((item) => /* @__PURE__ */ jsxs("div", { className: "orion-builder-v2-item-row", children: [
|
|
1467
|
+
/* @__PURE__ */ jsx("span", { children: item.title }),
|
|
1468
|
+
/* @__PURE__ */ jsx(
|
|
1469
|
+
"button",
|
|
1470
|
+
{
|
|
1471
|
+
onClick: () => {
|
|
1472
|
+
updateSelectedItems((items) => {
|
|
1473
|
+
const source = items[item.index];
|
|
1474
|
+
if (!source) {
|
|
1475
|
+
return items;
|
|
1476
|
+
}
|
|
1477
|
+
const copy = [...items];
|
|
1478
|
+
copy.splice(item.index + 1, 0, {
|
|
1479
|
+
...source,
|
|
1480
|
+
title: typeof source.title === "string" ? `${source.title} copy` : source.title
|
|
1481
|
+
});
|
|
1482
|
+
return copy;
|
|
1483
|
+
});
|
|
1484
|
+
},
|
|
1485
|
+
type: "button",
|
|
1486
|
+
children: "Duplicate"
|
|
1487
|
+
}
|
|
1488
|
+
),
|
|
1489
|
+
/* @__PURE__ */ jsx(
|
|
1490
|
+
"button",
|
|
1491
|
+
{
|
|
1492
|
+
onClick: () => {
|
|
1493
|
+
updateSelectedItems((items) => items.filter((_, index) => index !== item.index));
|
|
1494
|
+
},
|
|
1495
|
+
type: "button",
|
|
1496
|
+
children: "Remove"
|
|
1497
|
+
}
|
|
1498
|
+
)
|
|
1499
|
+
] }, `${item.index}-${item.title}`)) }),
|
|
1500
|
+
/* @__PURE__ */ jsx(
|
|
1501
|
+
"button",
|
|
1502
|
+
{
|
|
1503
|
+
className: "orion-builder-v2-wide-action",
|
|
1504
|
+
onClick: () => {
|
|
1505
|
+
updateSelectedItems((items) => [
|
|
1506
|
+
...items,
|
|
1507
|
+
{
|
|
1508
|
+
description: "Describe this feature.",
|
|
1509
|
+
imageURL: "",
|
|
1510
|
+
title: "New feature"
|
|
1511
|
+
}
|
|
1512
|
+
]);
|
|
1513
|
+
},
|
|
1514
|
+
type: "button",
|
|
1515
|
+
children: "Add item"
|
|
1516
|
+
}
|
|
1517
|
+
)
|
|
1518
|
+
] }) : null,
|
|
1419
1519
|
/* @__PURE__ */ jsxs("div", { className: "orion-builder-v2-panel", children: [
|
|
1420
1520
|
/* @__PURE__ */ jsx("h2", { children: "Design" }),
|
|
1421
1521
|
/* @__PURE__ */ jsx("p", { children: "Adjust spacing, layout, typography, color, borders, and shadows for the selected section." }),
|
|
@@ -252,6 +252,52 @@
|
|
|
252
252
|
color: #9f1239;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
+
.orion-builder-v2-items {
|
|
256
|
+
display: grid;
|
|
257
|
+
gap: 8px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.orion-builder-v2-item-row {
|
|
261
|
+
align-items: center;
|
|
262
|
+
background: #fff8ef;
|
|
263
|
+
border: 1px solid rgba(231, 203, 185, 0.9);
|
|
264
|
+
border-radius: 10px;
|
|
265
|
+
display: grid;
|
|
266
|
+
gap: 6px;
|
|
267
|
+
grid-template-columns: minmax(0, 1fr) auto auto;
|
|
268
|
+
padding: 8px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.orion-builder-v2-item-row span {
|
|
272
|
+
color: var(--builder-v2-ink);
|
|
273
|
+
font-size: 0.8rem;
|
|
274
|
+
font-weight: 900;
|
|
275
|
+
overflow: hidden;
|
|
276
|
+
text-overflow: ellipsis;
|
|
277
|
+
white-space: nowrap;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.orion-builder-v2-item-row button,
|
|
281
|
+
.orion-builder-v2-wide-action {
|
|
282
|
+
background: #ffffff;
|
|
283
|
+
border: 1px solid #e7cbb9;
|
|
284
|
+
border-radius: 999px;
|
|
285
|
+
color: var(--builder-v2-ink);
|
|
286
|
+
cursor: pointer;
|
|
287
|
+
font: inherit;
|
|
288
|
+
font-size: 0.72rem;
|
|
289
|
+
font-weight: 900;
|
|
290
|
+
min-height: 30px;
|
|
291
|
+
padding: 6px 9px;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.orion-builder-v2-wide-action {
|
|
295
|
+
background: var(--builder-v2-ink);
|
|
296
|
+
color: #ffffff;
|
|
297
|
+
margin-top: 2px;
|
|
298
|
+
width: 100%;
|
|
299
|
+
}
|
|
300
|
+
|
|
255
301
|
.orion-builder-v2-runtime {
|
|
256
302
|
width: 100%;
|
|
257
303
|
}
|
package/package.json
CHANGED