@orion-studios/payload-studio 0.6.0-beta.57 → 0.6.0-beta.59
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 +111 -8
- package/dist/builder-v2/client.mjs +111 -8
- package/dist/builder-v2/styles.css +46 -0
- package/package.json +1 -1
|
@@ -839,6 +839,9 @@ var bindEditablePreview = (view, editor) => {
|
|
|
839
839
|
const placeholder = element.dataset.orionPlaceholder || "";
|
|
840
840
|
element.setAttribute("title", isImage ? "Click to replace image" : "Click and type to edit");
|
|
841
841
|
element.style.cursor = "text";
|
|
842
|
+
element.addEventListener("pointerdown", () => {
|
|
843
|
+
editor.select?.(view.model);
|
|
844
|
+
}, true);
|
|
842
845
|
element.addEventListener("click", (event) => {
|
|
843
846
|
event.stopPropagation();
|
|
844
847
|
editor.select?.(view.model);
|
|
@@ -953,6 +956,24 @@ var registerProjectDynamicComponents = (editor, adapter) => {
|
|
|
953
956
|
|
|
954
957
|
// src/builder-v2/editor/GrapesPageEditor.tsx
|
|
955
958
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
959
|
+
var decodeHtmlAttribute3 = (value) => {
|
|
960
|
+
if (typeof value !== "string") {
|
|
961
|
+
return "";
|
|
962
|
+
}
|
|
963
|
+
return value.replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
964
|
+
};
|
|
965
|
+
var parseItemsJson = (value) => {
|
|
966
|
+
const decoded = decodeHtmlAttribute3(value);
|
|
967
|
+
if (!decoded) {
|
|
968
|
+
return [];
|
|
969
|
+
}
|
|
970
|
+
try {
|
|
971
|
+
const parsed = JSON.parse(decoded);
|
|
972
|
+
return Array.isArray(parsed) ? parsed.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item))) : [];
|
|
973
|
+
} catch {
|
|
974
|
+
return [];
|
|
975
|
+
}
|
|
976
|
+
};
|
|
956
977
|
var postToParent = (payload) => {
|
|
957
978
|
window.parent?.postMessage(
|
|
958
979
|
{
|
|
@@ -1153,6 +1174,7 @@ function GrapesPageEditor({
|
|
|
1153
1174
|
const editorRef = (0, import_react.useRef)(null);
|
|
1154
1175
|
const autosaveTimerRef = (0, import_react.useRef)(null);
|
|
1155
1176
|
const saveRef = (0, import_react.useRef)(async () => void 0);
|
|
1177
|
+
const selectedComponentRef = (0, import_react.useRef)(null);
|
|
1156
1178
|
const [error, setError] = (0, import_react.useState)("");
|
|
1157
1179
|
const [historyState, setHistoryState] = (0, import_react.useState)({ canRedo: false, canUndo: false });
|
|
1158
1180
|
const [lastSavedAt, setLastSavedAt] = (0, import_react.useState)("");
|
|
@@ -1164,6 +1186,37 @@ function GrapesPageEditor({
|
|
|
1164
1186
|
const [validationIssues, setValidationIssues] = (0, import_react.useState)([]);
|
|
1165
1187
|
const editorPageBasePath = initialData?.meta?.editorPageBasePath || "/admin/pages";
|
|
1166
1188
|
const pageTree = initialData?.meta?.pageTree || [];
|
|
1189
|
+
const summarizeSelectedComponent = (component) => {
|
|
1190
|
+
if (!component) {
|
|
1191
|
+
return null;
|
|
1192
|
+
}
|
|
1193
|
+
const attrs = component.getAttributes?.() || {};
|
|
1194
|
+
const componentType = String(attrs["data-orion-component"] || component.get?.("type") || "Section");
|
|
1195
|
+
const rawName = String(component.get?.("name") || componentType || "Section");
|
|
1196
|
+
const label = rawName.replace(/^orion-/, "").replace(/^xo/, "XO ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").trim();
|
|
1197
|
+
const items = parseItemsJson(attrs["data-orion-items-json"]).map((item, index) => ({
|
|
1198
|
+
index,
|
|
1199
|
+
title: typeof item.title === "string" && item.title.trim() ? item.title.trim() : `Item ${index + 1}`
|
|
1200
|
+
}));
|
|
1201
|
+
return {
|
|
1202
|
+
items: items.length > 0 ? items : void 0,
|
|
1203
|
+
label: label || "Section",
|
|
1204
|
+
type: componentType
|
|
1205
|
+
};
|
|
1206
|
+
};
|
|
1207
|
+
const updateSelectedItems = (updater) => {
|
|
1208
|
+
const component = selectedComponentRef.current;
|
|
1209
|
+
if (!component) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const attrs = component.getAttributes?.() || {};
|
|
1213
|
+
const currentItems = parseItemsJson(attrs["data-orion-items-json"]);
|
|
1214
|
+
const nextItems = updater(currentItems);
|
|
1215
|
+
component.addAttributes?.({
|
|
1216
|
+
"data-orion-items-json": JSON.stringify(nextItems)
|
|
1217
|
+
});
|
|
1218
|
+
setSelectionSummary(summarizeSelectedComponent(component));
|
|
1219
|
+
};
|
|
1167
1220
|
const updateHistoryState = (editor) => {
|
|
1168
1221
|
const next = {
|
|
1169
1222
|
canRedo: editor.UndoManager.hasRedo(),
|
|
@@ -1289,14 +1342,8 @@ function GrapesPageEditor({
|
|
|
1289
1342
|
});
|
|
1290
1343
|
editor.on("component:selected", (component) => {
|
|
1291
1344
|
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
|
-
});
|
|
1345
|
+
selectedComponentRef.current = typed;
|
|
1346
|
+
setSelectionSummary(summarizeSelectedComponent(typed));
|
|
1300
1347
|
setSaveMessage("Selection ready");
|
|
1301
1348
|
});
|
|
1302
1349
|
setSelectedDevice(editor.getDevice() || "desktop");
|
|
@@ -1540,6 +1587,62 @@ function GrapesPageEditor({
|
|
|
1540
1587
|
/* @__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
1588
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { id: "orion-builder-v2-traits" })
|
|
1542
1589
|
] }),
|
|
1590
|
+
selectionSummary?.items ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "orion-builder-v2-panel", children: [
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Items" }),
|
|
1592
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Add, duplicate, remove, then click item text or images on the canvas to edit them." }),
|
|
1593
|
+
/* @__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: [
|
|
1594
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.title }),
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1596
|
+
"button",
|
|
1597
|
+
{
|
|
1598
|
+
onClick: () => {
|
|
1599
|
+
updateSelectedItems((items) => {
|
|
1600
|
+
const source = items[item.index];
|
|
1601
|
+
if (!source) {
|
|
1602
|
+
return items;
|
|
1603
|
+
}
|
|
1604
|
+
const copy = [...items];
|
|
1605
|
+
copy.splice(item.index + 1, 0, {
|
|
1606
|
+
...source,
|
|
1607
|
+
title: typeof source.title === "string" ? `${source.title} copy` : source.title
|
|
1608
|
+
});
|
|
1609
|
+
return copy;
|
|
1610
|
+
});
|
|
1611
|
+
},
|
|
1612
|
+
type: "button",
|
|
1613
|
+
children: "Duplicate"
|
|
1614
|
+
}
|
|
1615
|
+
),
|
|
1616
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1617
|
+
"button",
|
|
1618
|
+
{
|
|
1619
|
+
onClick: () => {
|
|
1620
|
+
updateSelectedItems((items) => items.filter((_, index) => index !== item.index));
|
|
1621
|
+
},
|
|
1622
|
+
type: "button",
|
|
1623
|
+
children: "Remove"
|
|
1624
|
+
}
|
|
1625
|
+
)
|
|
1626
|
+
] }, `${item.index}-${item.title}`)) }),
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1628
|
+
"button",
|
|
1629
|
+
{
|
|
1630
|
+
className: "orion-builder-v2-wide-action",
|
|
1631
|
+
onClick: () => {
|
|
1632
|
+
updateSelectedItems((items) => [
|
|
1633
|
+
...items,
|
|
1634
|
+
{
|
|
1635
|
+
description: "Describe this feature.",
|
|
1636
|
+
imageURL: "",
|
|
1637
|
+
title: "New feature"
|
|
1638
|
+
}
|
|
1639
|
+
]);
|
|
1640
|
+
},
|
|
1641
|
+
type: "button",
|
|
1642
|
+
children: "Add item"
|
|
1643
|
+
}
|
|
1644
|
+
)
|
|
1645
|
+
] }) : null,
|
|
1543
1646
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "orion-builder-v2-panel", children: [
|
|
1544
1647
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "Design" }),
|
|
1545
1648
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "Adjust spacing, layout, typography, color, borders, and shadows for the selected section." }),
|
|
@@ -715,6 +715,9 @@ var bindEditablePreview = (view, editor) => {
|
|
|
715
715
|
const placeholder = element.dataset.orionPlaceholder || "";
|
|
716
716
|
element.setAttribute("title", isImage ? "Click to replace image" : "Click and type to edit");
|
|
717
717
|
element.style.cursor = "text";
|
|
718
|
+
element.addEventListener("pointerdown", () => {
|
|
719
|
+
editor.select?.(view.model);
|
|
720
|
+
}, true);
|
|
718
721
|
element.addEventListener("click", (event) => {
|
|
719
722
|
event.stopPropagation();
|
|
720
723
|
editor.select?.(view.model);
|
|
@@ -829,6 +832,24 @@ var registerProjectDynamicComponents = (editor, adapter) => {
|
|
|
829
832
|
|
|
830
833
|
// src/builder-v2/editor/GrapesPageEditor.tsx
|
|
831
834
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
835
|
+
var decodeHtmlAttribute3 = (value) => {
|
|
836
|
+
if (typeof value !== "string") {
|
|
837
|
+
return "";
|
|
838
|
+
}
|
|
839
|
+
return value.replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
840
|
+
};
|
|
841
|
+
var parseItemsJson = (value) => {
|
|
842
|
+
const decoded = decodeHtmlAttribute3(value);
|
|
843
|
+
if (!decoded) {
|
|
844
|
+
return [];
|
|
845
|
+
}
|
|
846
|
+
try {
|
|
847
|
+
const parsed = JSON.parse(decoded);
|
|
848
|
+
return Array.isArray(parsed) ? parsed.filter((item) => Boolean(item && typeof item === "object" && !Array.isArray(item))) : [];
|
|
849
|
+
} catch {
|
|
850
|
+
return [];
|
|
851
|
+
}
|
|
852
|
+
};
|
|
832
853
|
var postToParent = (payload) => {
|
|
833
854
|
window.parent?.postMessage(
|
|
834
855
|
{
|
|
@@ -1029,6 +1050,7 @@ function GrapesPageEditor({
|
|
|
1029
1050
|
const editorRef = useRef(null);
|
|
1030
1051
|
const autosaveTimerRef = useRef(null);
|
|
1031
1052
|
const saveRef = useRef(async () => void 0);
|
|
1053
|
+
const selectedComponentRef = useRef(null);
|
|
1032
1054
|
const [error, setError] = useState("");
|
|
1033
1055
|
const [historyState, setHistoryState] = useState({ canRedo: false, canUndo: false });
|
|
1034
1056
|
const [lastSavedAt, setLastSavedAt] = useState("");
|
|
@@ -1040,6 +1062,37 @@ function GrapesPageEditor({
|
|
|
1040
1062
|
const [validationIssues, setValidationIssues] = useState([]);
|
|
1041
1063
|
const editorPageBasePath = initialData?.meta?.editorPageBasePath || "/admin/pages";
|
|
1042
1064
|
const pageTree = initialData?.meta?.pageTree || [];
|
|
1065
|
+
const summarizeSelectedComponent = (component) => {
|
|
1066
|
+
if (!component) {
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
const attrs = component.getAttributes?.() || {};
|
|
1070
|
+
const componentType = String(attrs["data-orion-component"] || component.get?.("type") || "Section");
|
|
1071
|
+
const rawName = String(component.get?.("name") || componentType || "Section");
|
|
1072
|
+
const label = rawName.replace(/^orion-/, "").replace(/^xo/, "XO ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/-/g, " ").trim();
|
|
1073
|
+
const items = parseItemsJson(attrs["data-orion-items-json"]).map((item, index) => ({
|
|
1074
|
+
index,
|
|
1075
|
+
title: typeof item.title === "string" && item.title.trim() ? item.title.trim() : `Item ${index + 1}`
|
|
1076
|
+
}));
|
|
1077
|
+
return {
|
|
1078
|
+
items: items.length > 0 ? items : void 0,
|
|
1079
|
+
label: label || "Section",
|
|
1080
|
+
type: componentType
|
|
1081
|
+
};
|
|
1082
|
+
};
|
|
1083
|
+
const updateSelectedItems = (updater) => {
|
|
1084
|
+
const component = selectedComponentRef.current;
|
|
1085
|
+
if (!component) {
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
const attrs = component.getAttributes?.() || {};
|
|
1089
|
+
const currentItems = parseItemsJson(attrs["data-orion-items-json"]);
|
|
1090
|
+
const nextItems = updater(currentItems);
|
|
1091
|
+
component.addAttributes?.({
|
|
1092
|
+
"data-orion-items-json": JSON.stringify(nextItems)
|
|
1093
|
+
});
|
|
1094
|
+
setSelectionSummary(summarizeSelectedComponent(component));
|
|
1095
|
+
};
|
|
1043
1096
|
const updateHistoryState = (editor) => {
|
|
1044
1097
|
const next = {
|
|
1045
1098
|
canRedo: editor.UndoManager.hasRedo(),
|
|
@@ -1165,14 +1218,8 @@ function GrapesPageEditor({
|
|
|
1165
1218
|
});
|
|
1166
1219
|
editor.on("component:selected", (component) => {
|
|
1167
1220
|
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
|
-
});
|
|
1221
|
+
selectedComponentRef.current = typed;
|
|
1222
|
+
setSelectionSummary(summarizeSelectedComponent(typed));
|
|
1176
1223
|
setSaveMessage("Selection ready");
|
|
1177
1224
|
});
|
|
1178
1225
|
setSelectedDevice(editor.getDevice() || "desktop");
|
|
@@ -1416,6 +1463,62 @@ function GrapesPageEditor({
|
|
|
1416
1463
|
/* @__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
1464
|
/* @__PURE__ */ jsx("div", { id: "orion-builder-v2-traits" })
|
|
1418
1465
|
] }),
|
|
1466
|
+
selectionSummary?.items ? /* @__PURE__ */ jsxs("div", { className: "orion-builder-v2-panel", children: [
|
|
1467
|
+
/* @__PURE__ */ jsx("h2", { children: "Items" }),
|
|
1468
|
+
/* @__PURE__ */ jsx("p", { children: "Add, duplicate, remove, then click item text or images on the canvas to edit them." }),
|
|
1469
|
+
/* @__PURE__ */ jsx("div", { className: "orion-builder-v2-items", children: selectionSummary.items.map((item) => /* @__PURE__ */ jsxs("div", { className: "orion-builder-v2-item-row", children: [
|
|
1470
|
+
/* @__PURE__ */ jsx("span", { children: item.title }),
|
|
1471
|
+
/* @__PURE__ */ jsx(
|
|
1472
|
+
"button",
|
|
1473
|
+
{
|
|
1474
|
+
onClick: () => {
|
|
1475
|
+
updateSelectedItems((items) => {
|
|
1476
|
+
const source = items[item.index];
|
|
1477
|
+
if (!source) {
|
|
1478
|
+
return items;
|
|
1479
|
+
}
|
|
1480
|
+
const copy = [...items];
|
|
1481
|
+
copy.splice(item.index + 1, 0, {
|
|
1482
|
+
...source,
|
|
1483
|
+
title: typeof source.title === "string" ? `${source.title} copy` : source.title
|
|
1484
|
+
});
|
|
1485
|
+
return copy;
|
|
1486
|
+
});
|
|
1487
|
+
},
|
|
1488
|
+
type: "button",
|
|
1489
|
+
children: "Duplicate"
|
|
1490
|
+
}
|
|
1491
|
+
),
|
|
1492
|
+
/* @__PURE__ */ jsx(
|
|
1493
|
+
"button",
|
|
1494
|
+
{
|
|
1495
|
+
onClick: () => {
|
|
1496
|
+
updateSelectedItems((items) => items.filter((_, index) => index !== item.index));
|
|
1497
|
+
},
|
|
1498
|
+
type: "button",
|
|
1499
|
+
children: "Remove"
|
|
1500
|
+
}
|
|
1501
|
+
)
|
|
1502
|
+
] }, `${item.index}-${item.title}`)) }),
|
|
1503
|
+
/* @__PURE__ */ jsx(
|
|
1504
|
+
"button",
|
|
1505
|
+
{
|
|
1506
|
+
className: "orion-builder-v2-wide-action",
|
|
1507
|
+
onClick: () => {
|
|
1508
|
+
updateSelectedItems((items) => [
|
|
1509
|
+
...items,
|
|
1510
|
+
{
|
|
1511
|
+
description: "Describe this feature.",
|
|
1512
|
+
imageURL: "",
|
|
1513
|
+
title: "New feature"
|
|
1514
|
+
}
|
|
1515
|
+
]);
|
|
1516
|
+
},
|
|
1517
|
+
type: "button",
|
|
1518
|
+
children: "Add item"
|
|
1519
|
+
}
|
|
1520
|
+
)
|
|
1521
|
+
] }) : null,
|
|
1419
1522
|
/* @__PURE__ */ jsxs("div", { className: "orion-builder-v2-panel", children: [
|
|
1420
1523
|
/* @__PURE__ */ jsx("h2", { children: "Design" }),
|
|
1421
1524
|
/* @__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