@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 CHANGED
@@ -1255,6 +1255,43 @@ function EditablePage({
1255
1255
  },
1256
1256
  [ed, selNode]
1257
1257
  );
1258
+ const addNodeAt = react.useCallback(
1259
+ (kind, targetId) => {
1260
+ const doc2 = ed.state.doc;
1261
+ const target = targetId ? doc2.nodes[targetId] : null;
1262
+ const parent = target ? CONTAINER_TYPES2.has(target.type) ? target.id : target.parent : doc2.sections[doc2.sections.length - 1] ?? null;
1263
+ const siblings = childrenOf(doc2, parent);
1264
+ const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
1265
+ const id = `n${doc2.seq + 1}-${Math.floor(performance.now())}`;
1266
+ const def = ADD_DEFAULTS[kind];
1267
+ ed.apply({ t: "insert_node", node: { id, type: def.type, parent, order, props: { ...def.props }, style: { base: { ...def.style } } } });
1268
+ ed.select(id);
1269
+ },
1270
+ [ed]
1271
+ );
1272
+ const [paletteOpen, setPaletteOpen] = react.useState(false);
1273
+ const [draggingEl, setDraggingEl] = react.useState(false);
1274
+ react.useEffect(() => {
1275
+ if (!editing) {
1276
+ setPaletteOpen(false);
1277
+ return;
1278
+ }
1279
+ const onMove = (e) => {
1280
+ if (draggingEl) return;
1281
+ if (e.clientX >= window.innerWidth - 26) setPaletteOpen(true);
1282
+ else if (e.clientX < window.innerWidth - 236) setPaletteOpen(false);
1283
+ };
1284
+ window.addEventListener("mousemove", onMove);
1285
+ return () => window.removeEventListener("mousemove", onMove);
1286
+ }, [editing, draggingEl]);
1287
+ const onPageDrop = (e) => {
1288
+ const kind = e.dataTransfer.getData("application/x-cms-element");
1289
+ if (!kind) return;
1290
+ e.preventDefault();
1291
+ const el = document.elementFromPoint(e.clientX, e.clientY)?.closest("[data-cms]");
1292
+ addNodeAt(kind, el?.getAttribute("data-cms") ?? null);
1293
+ setDraggingEl(false);
1294
+ };
1258
1295
  const setStyle = (patch) => selection && ed.apply({ t: "set_style", id: selection, breakpoint: "base", patch });
1259
1296
  const setProps = (patch) => selection && ed.apply({ t: "set_props", id: selection, patch });
1260
1297
  const setLayout = (layout) => selection && ed.apply({ t: "set_layout", id: selection, layout });
@@ -1322,8 +1359,22 @@ function EditablePage({
1322
1359
  if (el) ed.select(el.getAttribute("data-cms"));
1323
1360
  else ed.select(null);
1324
1361
  };
1325
- const page = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: pageRef, onClickCapture, onContextMenu: onContextMenuSelect, children: /* @__PURE__ */ jsxRuntime.jsx(CmsPage, { doc: ed.state.doc, registry }) });
1326
- const pageShell = pinned ? /* @__PURE__ */ jsxRuntime.jsx("div", { ref: spacerRef, style: { height: `${Math.max(1, frames) * 100}vh` }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "sticky", top: 0, height: "100vh", overflow: "hidden" }, children: page }) }) : page;
1362
+ const page = /* @__PURE__ */ jsxRuntime.jsx(
1363
+ "div",
1364
+ {
1365
+ ref: pageRef,
1366
+ onClickCapture,
1367
+ onContextMenu: onContextMenuSelect,
1368
+ onDragOver: editing ? (e) => e.preventDefault() : void 0,
1369
+ onDrop: editing ? onPageDrop : void 0,
1370
+ children: /* @__PURE__ */ jsxRuntime.jsx(CmsPage, { doc: ed.state.doc, registry })
1371
+ }
1372
+ );
1373
+ const pageShell = pinned ? /* @__PURE__ */ jsxRuntime.jsx("div", { ref: spacerRef, style: { height: `${Math.max(1, frames) * 100}vh` }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "sticky", top: 0, height: "100vh", overflow: "hidden" }, children: page }) }) : frames > 1 ? (
1374
+ // Normal flow, but "expanded" — extra scroll length below the content so a
1375
+ // page can be made longer than its content (the + Frame control).
1376
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { minHeight: `${frames * 100}vh` }, children: page })
1377
+ ) : page;
1327
1378
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
1328
1379
  editing ? /* @__PURE__ */ jsxRuntime.jsxs(reactFancy.ContextMenu, { children: [
1329
1380
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ContextMenu.Trigger, { children: pageShell }),
@@ -1385,9 +1436,72 @@ function EditablePage({
1385
1436
  onAdd: addNode
1386
1437
  }
1387
1438
  ) : null,
1439
+ editing ? /* @__PURE__ */ jsxRuntime.jsx(ElementPalette, { open: paletteOpen, onDragChange: setDraggingEl }) : null,
1388
1440
  editing && timelineDock ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "fixed", left: 0, right: 0, bottom: 0, zIndex: Z2 }, children: timelineDock }) : null
1389
1441
  ] });
1390
1442
  }
1443
+ function ElementPalette({ open, onDragChange }) {
1444
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1445
+ "div",
1446
+ {
1447
+ style: {
1448
+ position: "fixed",
1449
+ top: 64,
1450
+ bottom: 96,
1451
+ right: 0,
1452
+ width: 216,
1453
+ transform: open ? "translateX(0)" : "translateX(100%)",
1454
+ transition: "transform 0.18s ease",
1455
+ background: "#0b1220",
1456
+ color: "#e2e8f0",
1457
+ borderLeft: "1px solid #1e293b",
1458
+ borderTopLeftRadius: 12,
1459
+ borderBottomLeftRadius: 12,
1460
+ boxShadow: "-18px 0 48px -20px rgba(0,0,0,0.6)",
1461
+ zIndex: Z2 + 2,
1462
+ fontFamily: "system-ui, sans-serif",
1463
+ padding: 12,
1464
+ overflowY: "auto"
1465
+ },
1466
+ children: [
1467
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, letterSpacing: "0.06em", textTransform: "uppercase", opacity: 0.5, marginBottom: 10 }, children: "Elements" }),
1468
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }, children: ADD_MENU.map((m) => /* @__PURE__ */ jsxRuntime.jsxs(
1469
+ "div",
1470
+ {
1471
+ draggable: true,
1472
+ onDragStart: (e) => {
1473
+ e.dataTransfer.setData("application/x-cms-element", m.kind);
1474
+ e.dataTransfer.effectAllowed = "copy";
1475
+ onDragChange(true);
1476
+ },
1477
+ onDragEnd: () => onDragChange(false),
1478
+ title: `Drag "${m.label}" onto the page`,
1479
+ style: {
1480
+ display: "flex",
1481
+ flexDirection: "column",
1482
+ alignItems: "center",
1483
+ justifyContent: "center",
1484
+ gap: 4,
1485
+ height: 56,
1486
+ borderRadius: 8,
1487
+ background: "#0f172a",
1488
+ border: "1px solid #1e293b",
1489
+ cursor: "grab",
1490
+ fontSize: 12,
1491
+ userSelect: "none"
1492
+ },
1493
+ children: [
1494
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 16, opacity: 0.7 }, children: "\uFF0B" }),
1495
+ m.label
1496
+ ]
1497
+ },
1498
+ m.kind
1499
+ )) }),
1500
+ /* @__PURE__ */ jsxRuntime.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." })
1501
+ ]
1502
+ }
1503
+ );
1504
+ }
1391
1505
  var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape"]);
1392
1506
  var ADD_DEFAULTS = {
1393
1507
  text: { type: "text", props: { content: "New text" }, style: { color: "inherit" } },
@@ -1616,7 +1730,7 @@ function EditBar({
1616
1730
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...btn, background: editing ? "#8b5cf6" : "transparent" }, onClick: onToggle, children: editing ? "\u25CF Editing" : "Edit" }),
1617
1731
  editing ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1618
1732
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
1619
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...btn, background: open ? "#1e293b" : "transparent" }, onClick: () => setOpen((v) => !v), title: "Add an element", children: "\uFF0B Add \u25BE" }),
1733
+ /* @__PURE__ */ jsxRuntime.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" }),
1620
1734
  open ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
1621
1735
  "button",
1622
1736
  {
@@ -1654,7 +1768,7 @@ function EditMenuItems({
1654
1768
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1655
1769
  editable ? /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ContextMenu.Item, { onClick: onEditText, children: "Edit text" }) : null,
1656
1770
  /* @__PURE__ */ jsxRuntime.jsxs(reactFancy.ContextMenu.Sub, { children: [
1657
- /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ContextMenu.SubTrigger, { children: isContainer ? "Add inside" : "Add" }),
1771
+ /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ContextMenu.SubTrigger, { children: isContainer ? "Add Element inside" : "Add Element" }),
1658
1772
  /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ContextMenu.SubContent, { className: "!z-[2147483647]", children: ADD_MENU.map((m) => /* @__PURE__ */ jsxRuntime.jsx(reactFancy.ContextMenu.Item, { onClick: () => onAdd(m.kind), children: m.label }, m.kind)) })
1659
1773
  ] }),
1660
1774
  node ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [