@particle-academy/fancy-cms-ui 0.0.1-dev.10 → 0.0.1-dev.12
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/editor.cjs +118 -4
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +118 -4
- package/dist/editor.js.map +1 -1
- package/package.json +1 -1
package/dist/editor.js
CHANGED
|
@@ -851,6 +851,43 @@ function EditablePage({
|
|
|
851
851
|
},
|
|
852
852
|
[ed, selNode]
|
|
853
853
|
);
|
|
854
|
+
const addNodeAt = useCallback(
|
|
855
|
+
(kind, targetId) => {
|
|
856
|
+
const doc2 = ed.state.doc;
|
|
857
|
+
const target = targetId ? doc2.nodes[targetId] : null;
|
|
858
|
+
const parent = target ? CONTAINER_TYPES2.has(target.type) ? target.id : target.parent : doc2.sections[doc2.sections.length - 1] ?? null;
|
|
859
|
+
const siblings = childrenOf(doc2, parent);
|
|
860
|
+
const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
|
|
861
|
+
const id = `n${doc2.seq + 1}-${Math.floor(performance.now())}`;
|
|
862
|
+
const def = ADD_DEFAULTS[kind];
|
|
863
|
+
ed.apply({ t: "insert_node", node: { id, type: def.type, parent, order, props: { ...def.props }, style: { base: { ...def.style } } } });
|
|
864
|
+
ed.select(id);
|
|
865
|
+
},
|
|
866
|
+
[ed]
|
|
867
|
+
);
|
|
868
|
+
const [paletteOpen, setPaletteOpen] = useState(false);
|
|
869
|
+
const [draggingEl, setDraggingEl] = useState(false);
|
|
870
|
+
useEffect(() => {
|
|
871
|
+
if (!editing) {
|
|
872
|
+
setPaletteOpen(false);
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
const onMove = (e) => {
|
|
876
|
+
if (draggingEl) return;
|
|
877
|
+
if (e.clientX >= window.innerWidth - 26) setPaletteOpen(true);
|
|
878
|
+
else if (e.clientX < window.innerWidth - 236) setPaletteOpen(false);
|
|
879
|
+
};
|
|
880
|
+
window.addEventListener("mousemove", onMove);
|
|
881
|
+
return () => window.removeEventListener("mousemove", onMove);
|
|
882
|
+
}, [editing, draggingEl]);
|
|
883
|
+
const onPageDrop = (e) => {
|
|
884
|
+
const kind = e.dataTransfer.getData("application/x-cms-element");
|
|
885
|
+
if (!kind) return;
|
|
886
|
+
e.preventDefault();
|
|
887
|
+
const el = document.elementFromPoint(e.clientX, e.clientY)?.closest("[data-cms]");
|
|
888
|
+
addNodeAt(kind, el?.getAttribute("data-cms") ?? null);
|
|
889
|
+
setDraggingEl(false);
|
|
890
|
+
};
|
|
854
891
|
const setStyle = (patch) => selection && ed.apply({ t: "set_style", id: selection, breakpoint: "base", patch });
|
|
855
892
|
const setProps = (patch) => selection && ed.apply({ t: "set_props", id: selection, patch });
|
|
856
893
|
const setLayout = (layout) => selection && ed.apply({ t: "set_layout", id: selection, layout });
|
|
@@ -918,8 +955,22 @@ function EditablePage({
|
|
|
918
955
|
if (el) ed.select(el.getAttribute("data-cms"));
|
|
919
956
|
else ed.select(null);
|
|
920
957
|
};
|
|
921
|
-
const page = /* @__PURE__ */ jsx(
|
|
922
|
-
|
|
958
|
+
const page = /* @__PURE__ */ jsx(
|
|
959
|
+
"div",
|
|
960
|
+
{
|
|
961
|
+
ref: pageRef,
|
|
962
|
+
onClickCapture,
|
|
963
|
+
onContextMenu: onContextMenuSelect,
|
|
964
|
+
onDragOver: editing ? (e) => e.preventDefault() : void 0,
|
|
965
|
+
onDrop: editing ? onPageDrop : void 0,
|
|
966
|
+
children: /* @__PURE__ */ jsx(CmsPage, { doc: ed.state.doc, registry })
|
|
967
|
+
}
|
|
968
|
+
);
|
|
969
|
+
const pageShell = pinned ? /* @__PURE__ */ jsx("div", { ref: spacerRef, style: { height: `${Math.max(1, frames) * 100}vh` }, children: /* @__PURE__ */ jsx("div", { style: { position: "sticky", top: 0, height: "100vh", overflow: "hidden" }, children: page }) }) : frames > 1 ? (
|
|
970
|
+
// Normal flow, but "expanded" — extra scroll length below the content so a
|
|
971
|
+
// page can be made longer than its content (the + Frame control).
|
|
972
|
+
/* @__PURE__ */ jsx("div", { style: { minHeight: `${frames * 100}vh` }, children: page })
|
|
973
|
+
) : page;
|
|
923
974
|
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
924
975
|
editing ? /* @__PURE__ */ jsxs(ContextMenu, { children: [
|
|
925
976
|
/* @__PURE__ */ jsx(ContextMenu.Trigger, { children: pageShell }),
|
|
@@ -981,9 +1032,72 @@ function EditablePage({
|
|
|
981
1032
|
onAdd: addNode
|
|
982
1033
|
}
|
|
983
1034
|
) : null,
|
|
1035
|
+
editing ? /* @__PURE__ */ jsx(ElementPalette, { open: paletteOpen, onDragChange: setDraggingEl }) : null,
|
|
984
1036
|
editing && timelineDock ? /* @__PURE__ */ jsx("div", { style: { position: "fixed", left: 0, right: 0, bottom: 0, zIndex: Z2 }, children: timelineDock }) : null
|
|
985
1037
|
] });
|
|
986
1038
|
}
|
|
1039
|
+
function ElementPalette({ open, onDragChange }) {
|
|
1040
|
+
return /* @__PURE__ */ jsxs(
|
|
1041
|
+
"div",
|
|
1042
|
+
{
|
|
1043
|
+
style: {
|
|
1044
|
+
position: "fixed",
|
|
1045
|
+
top: 64,
|
|
1046
|
+
bottom: 96,
|
|
1047
|
+
right: 0,
|
|
1048
|
+
width: 216,
|
|
1049
|
+
transform: open ? "translateX(0)" : "translateX(100%)",
|
|
1050
|
+
transition: "transform 0.18s ease",
|
|
1051
|
+
background: "#0b1220",
|
|
1052
|
+
color: "#e2e8f0",
|
|
1053
|
+
borderLeft: "1px solid #1e293b",
|
|
1054
|
+
borderTopLeftRadius: 12,
|
|
1055
|
+
borderBottomLeftRadius: 12,
|
|
1056
|
+
boxShadow: "-18px 0 48px -20px rgba(0,0,0,0.6)",
|
|
1057
|
+
zIndex: Z2 + 2,
|
|
1058
|
+
fontFamily: "system-ui, sans-serif",
|
|
1059
|
+
padding: 12,
|
|
1060
|
+
overflowY: "auto"
|
|
1061
|
+
},
|
|
1062
|
+
children: [
|
|
1063
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: 11, letterSpacing: "0.06em", textTransform: "uppercase", opacity: 0.5, marginBottom: 10 }, children: "Elements" }),
|
|
1064
|
+
/* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, children: ADD_MENU.map((m) => /* @__PURE__ */ jsxs(
|
|
1065
|
+
"div",
|
|
1066
|
+
{
|
|
1067
|
+
draggable: true,
|
|
1068
|
+
onDragStart: (e) => {
|
|
1069
|
+
e.dataTransfer.setData("application/x-cms-element", m.kind);
|
|
1070
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
1071
|
+
onDragChange(true);
|
|
1072
|
+
},
|
|
1073
|
+
onDragEnd: () => onDragChange(false),
|
|
1074
|
+
title: `Drag "${m.label}" onto the page`,
|
|
1075
|
+
style: {
|
|
1076
|
+
display: "flex",
|
|
1077
|
+
flexDirection: "column",
|
|
1078
|
+
alignItems: "center",
|
|
1079
|
+
justifyContent: "center",
|
|
1080
|
+
gap: 4,
|
|
1081
|
+
height: 56,
|
|
1082
|
+
borderRadius: 8,
|
|
1083
|
+
background: "#0f172a",
|
|
1084
|
+
border: "1px solid #1e293b",
|
|
1085
|
+
cursor: "grab",
|
|
1086
|
+
fontSize: 12,
|
|
1087
|
+
userSelect: "none"
|
|
1088
|
+
},
|
|
1089
|
+
children: [
|
|
1090
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 16, opacity: 0.7 }, children: "\uFF0B" }),
|
|
1091
|
+
m.label
|
|
1092
|
+
]
|
|
1093
|
+
},
|
|
1094
|
+
m.kind
|
|
1095
|
+
)) }),
|
|
1096
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: 10.5, opacity: 0.45, marginTop: 12, lineHeight: 1.4 }, children: "Drag an Element onto the page. It drops into the container you release over." })
|
|
1097
|
+
]
|
|
1098
|
+
}
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
987
1101
|
var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape"]);
|
|
988
1102
|
var ADD_DEFAULTS = {
|
|
989
1103
|
text: { type: "text", props: { content: "New text" }, style: { color: "inherit" } },
|
|
@@ -1212,7 +1326,7 @@ function EditBar({
|
|
|
1212
1326
|
/* @__PURE__ */ jsx("button", { type: "button", style: { ...btn, background: editing ? "#8b5cf6" : "transparent" }, onClick: onToggle, children: editing ? "\u25CF Editing" : "Edit" }),
|
|
1213
1327
|
editing ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1214
1328
|
/* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
1215
|
-
/* @__PURE__ */ jsx("button", { type: "button", style: { ...btn, background: open ? "#1e293b" : "transparent" }, onClick: () => setOpen((v) => !v), title: "Add an
|
|
1329
|
+
/* @__PURE__ */ jsx("button", { type: "button", style: { ...btn, background: open ? "#1e293b" : "transparent" }, onClick: () => setOpen((v) => !v), title: "Add an Element (or drag from the right-edge palette)", children: "\uFF0B Element \u25BE" }),
|
|
1216
1330
|
open ? /* @__PURE__ */ jsx("div", { style: { position: "absolute", top: "calc(100% + 6px)", right: 0, background: "#0f172a", border: "1px solid #1e293b", borderRadius: 10, padding: 4, display: "flex", flexDirection: "column", minWidth: 132, boxShadow: "0 12px 32px -10px rgba(0,0,0,0.6)" }, children: ADD_MENU.map((m) => /* @__PURE__ */ jsx(
|
|
1217
1331
|
"button",
|
|
1218
1332
|
{
|
|
@@ -1250,7 +1364,7 @@ function EditMenuItems({
|
|
|
1250
1364
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1251
1365
|
editable ? /* @__PURE__ */ jsx(ContextMenu.Item, { onClick: onEditText, children: "Edit text" }) : null,
|
|
1252
1366
|
/* @__PURE__ */ jsxs(ContextMenu.Sub, { children: [
|
|
1253
|
-
/* @__PURE__ */ jsx(ContextMenu.SubTrigger, { children: isContainer ? "Add inside" : "Add" }),
|
|
1367
|
+
/* @__PURE__ */ jsx(ContextMenu.SubTrigger, { children: isContainer ? "Add Element inside" : "Add Element" }),
|
|
1254
1368
|
/* @__PURE__ */ jsx(ContextMenu.SubContent, { className: "!z-[2147483647]", children: ADD_MENU.map((m) => /* @__PURE__ */ jsx(ContextMenu.Item, { onClick: () => onAdd(m.kind), children: m.label }, m.kind)) })
|
|
1255
1369
|
] }),
|
|
1256
1370
|
node ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|