@particle-academy/fancy-cms-ui 0.0.1-dev.11 → 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.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,7 +955,17 @@ 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("div", { ref: pageRef, onClickCapture, onContextMenu: onContextMenuSelect, children: /* @__PURE__ */ jsx(CmsPage, { doc: ed.state.doc, registry }) });
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
+ );
922
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 ? (
923
970
  // Normal flow, but "expanded" — extra scroll length below the content so a
924
971
  // page can be made longer than its content (the + Frame control).
@@ -985,9 +1032,72 @@ function EditablePage({
985
1032
  onAdd: addNode
986
1033
  }
987
1034
  ) : null,
1035
+ editing ? /* @__PURE__ */ jsx(ElementPalette, { open: paletteOpen, onDragChange: setDraggingEl }) : null,
988
1036
  editing && timelineDock ? /* @__PURE__ */ jsx("div", { style: { position: "fixed", left: 0, right: 0, bottom: 0, zIndex: Z2 }, children: timelineDock }) : null
989
1037
  ] });
990
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
+ }
991
1101
  var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape"]);
992
1102
  var ADD_DEFAULTS = {
993
1103
  text: { type: "text", props: { content: "New text" }, style: { color: "inherit" } },
@@ -1216,7 +1326,7 @@ function EditBar({
1216
1326
  /* @__PURE__ */ jsx("button", { type: "button", style: { ...btn, background: editing ? "#8b5cf6" : "transparent" }, onClick: onToggle, children: editing ? "\u25CF Editing" : "Edit" }),
1217
1327
  editing ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
1218
1328
  /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
1219
- /* @__PURE__ */ jsx("button", { type: "button", style: { ...btn, background: open ? "#1e293b" : "transparent" }, onClick: () => setOpen((v) => !v), title: "Add an element", children: "\uFF0B Add \u25BE" }),
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" }),
1220
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(
1221
1331
  "button",
1222
1332
  {
@@ -1254,7 +1364,7 @@ function EditMenuItems({
1254
1364
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1255
1365
  editable ? /* @__PURE__ */ jsx(ContextMenu.Item, { onClick: onEditText, children: "Edit text" }) : null,
1256
1366
  /* @__PURE__ */ jsxs(ContextMenu.Sub, { children: [
1257
- /* @__PURE__ */ jsx(ContextMenu.SubTrigger, { children: isContainer ? "Add inside" : "Add" }),
1367
+ /* @__PURE__ */ jsx(ContextMenu.SubTrigger, { children: isContainer ? "Add Element inside" : "Add Element" }),
1258
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)) })
1259
1369
  ] }),
1260
1370
  node ? /* @__PURE__ */ jsxs(Fragment$1, { children: [