@particle-academy/fancy-cms-ui 0.0.1-dev.3 → 0.0.1-dev.5
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 +159 -69
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.d.cts +22 -7
- package/dist/editor.d.ts +22 -7
- package/dist/editor.js +159 -69
- package/dist/editor.js.map +1 -1
- package/package.json +1 -1
package/dist/editor.js
CHANGED
|
@@ -368,15 +368,22 @@ var Z = 2147483e3;
|
|
|
368
368
|
function EditablePage({
|
|
369
369
|
doc,
|
|
370
370
|
registry = defaultRegistry,
|
|
371
|
-
timelineDock
|
|
371
|
+
timelineDock,
|
|
372
|
+
transforms,
|
|
373
|
+
onNodeTransform,
|
|
374
|
+
onSelect,
|
|
375
|
+
frames = 1,
|
|
376
|
+
onProgress
|
|
372
377
|
}) {
|
|
373
378
|
const ed = useEditor(doc);
|
|
374
379
|
const [editing, setEditing] = useState(false);
|
|
375
380
|
const [revealed, setRevealed] = useState(false);
|
|
376
381
|
const pageRef = useRef(null);
|
|
382
|
+
const spacerRef = useRef(null);
|
|
377
383
|
const [box, setBox] = useState(null);
|
|
378
384
|
const { selection } = ed.state;
|
|
379
385
|
const selNode = selection ? ed.state.doc.nodes[selection] : null;
|
|
386
|
+
useEffect(() => onSelect?.(selection), [selection, onSelect]);
|
|
380
387
|
useEffect(() => {
|
|
381
388
|
const onKey = (e) => setRevealed(e.ctrlKey && e.shiftKey);
|
|
382
389
|
const onBlur = () => setRevealed(false);
|
|
@@ -389,36 +396,67 @@ function EditablePage({
|
|
|
389
396
|
window.removeEventListener("blur", onBlur);
|
|
390
397
|
};
|
|
391
398
|
}, []);
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
399
|
+
useEffect(() => {
|
|
400
|
+
const root = pageRef.current;
|
|
401
|
+
if (!root) return;
|
|
402
|
+
root.querySelectorAll("[data-cms]").forEach((el) => {
|
|
403
|
+
const id = el.dataset.cms;
|
|
404
|
+
const t = id ? transforms?.[id] : void 0;
|
|
405
|
+
if (t) {
|
|
406
|
+
el.style.transform = `translate3d(${t.x ?? 0}px, ${t.y ?? 0}px, 0) scale(${t.scale ?? 1})`;
|
|
407
|
+
el.style.opacity = t.opacity != null ? String(t.opacity) : "";
|
|
408
|
+
} else {
|
|
409
|
+
el.style.transform = "";
|
|
410
|
+
el.style.opacity = "";
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}, [transforms, ed.state.doc]);
|
|
414
|
+
useEffect(() => {
|
|
415
|
+
const spacer = spacerRef.current;
|
|
416
|
+
if (!spacer || !onProgress) return;
|
|
417
|
+
let raf = 0;
|
|
418
|
+
const compute = () => {
|
|
419
|
+
raf = 0;
|
|
420
|
+
const len = spacer.offsetHeight - window.innerHeight;
|
|
421
|
+
const top = spacer.getBoundingClientRect().top;
|
|
422
|
+
onProgress(len > 0 ? Math.min(1, Math.max(0, -top / len)) : 0);
|
|
423
|
+
};
|
|
424
|
+
const onScroll = () => {
|
|
425
|
+
if (!raf) raf = requestAnimationFrame(compute);
|
|
402
426
|
};
|
|
403
|
-
|
|
404
|
-
window.addEventListener("scroll",
|
|
405
|
-
window.addEventListener("resize",
|
|
427
|
+
compute();
|
|
428
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
429
|
+
window.addEventListener("resize", onScroll);
|
|
406
430
|
return () => {
|
|
407
|
-
window.removeEventListener("scroll",
|
|
408
|
-
window.removeEventListener("resize",
|
|
431
|
+
window.removeEventListener("scroll", onScroll);
|
|
432
|
+
window.removeEventListener("resize", onScroll);
|
|
433
|
+
if (raf) cancelAnimationFrame(raf);
|
|
409
434
|
};
|
|
410
|
-
}, [
|
|
435
|
+
}, [onProgress, frames]);
|
|
436
|
+
const measureBox = useCallback(() => {
|
|
437
|
+
if (!editing || !selection || !pageRef.current) return setBox(null);
|
|
438
|
+
const el = pageRef.current.querySelector(`[data-cms="${cssEscape2(selection)}"]`);
|
|
439
|
+
if (!el) return setBox(null);
|
|
440
|
+
const r = el.getBoundingClientRect();
|
|
441
|
+
setBox({ x: r.left, y: r.top, w: r.width, h: r.height });
|
|
442
|
+
}, [editing, selection]);
|
|
443
|
+
useLayoutEffect(() => {
|
|
444
|
+
measureBox();
|
|
445
|
+
window.addEventListener("scroll", measureBox, { passive: true });
|
|
446
|
+
window.addEventListener("resize", measureBox);
|
|
447
|
+
return () => {
|
|
448
|
+
window.removeEventListener("scroll", measureBox);
|
|
449
|
+
window.removeEventListener("resize", measureBox);
|
|
450
|
+
};
|
|
451
|
+
}, [measureBox, ed.state.doc, transforms]);
|
|
411
452
|
useEffect(() => {
|
|
412
|
-
if (!editing || !selection || !pageRef.current) return;
|
|
413
|
-
if (selNode?.type !== "text") return;
|
|
453
|
+
if (!editing || !selection || !pageRef.current || selNode?.type !== "text") return;
|
|
414
454
|
const el = pageRef.current.querySelector(`[data-cms="${cssEscape2(selection)}"]`);
|
|
415
455
|
if (!el) return;
|
|
416
456
|
el.setAttribute("contenteditable", "true");
|
|
417
457
|
el.style.outline = "none";
|
|
418
458
|
el.focus();
|
|
419
|
-
const commit = () => {
|
|
420
|
-
ed.apply({ t: "set_props", id: selection, patch: { content: el.innerText } });
|
|
421
|
-
};
|
|
459
|
+
const commit = () => ed.apply({ t: "set_props", id: selection, patch: { content: el.innerText } });
|
|
422
460
|
el.addEventListener("blur", commit);
|
|
423
461
|
return () => {
|
|
424
462
|
el.removeEventListener("blur", commit);
|
|
@@ -440,29 +478,21 @@ function EditablePage({
|
|
|
440
478
|
const siblings = childrenOf(ed.state.doc, parent);
|
|
441
479
|
const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
|
|
442
480
|
const id = `n${ed.state.doc.seq + 1}-${Math.floor(performance.now())}`;
|
|
443
|
-
ed.apply({
|
|
444
|
-
t: "insert_node",
|
|
445
|
-
node: { id, type: "text", parent, order, props: { content: "New text" }, style: { base: { color: "inherit" } } }
|
|
446
|
-
});
|
|
481
|
+
ed.apply({ t: "insert_node", node: { id, type: "text", parent, order, props: { content: "New text" }, style: { base: { color: "inherit" } } } });
|
|
447
482
|
ed.select(id);
|
|
448
483
|
}, [ed, selNode]);
|
|
449
484
|
const setStyle = (patch) => selection && ed.apply({ t: "set_style", id: selection, breakpoint: "base", patch });
|
|
450
485
|
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
451
|
-
/* @__PURE__ */ jsx("div", { ref: pageRef, onClickCapture, children: /* @__PURE__ */ jsx(CmsPage, { doc: ed.state.doc, registry }) }),
|
|
452
|
-
editing && box ? /* @__PURE__ */ jsx(
|
|
453
|
-
|
|
486
|
+
/* @__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: /* @__PURE__ */ jsx("div", { ref: pageRef, onClickCapture, children: /* @__PURE__ */ jsx(CmsPage, { doc: ed.state.doc, registry }) }) }) }),
|
|
487
|
+
editing && box && selection ? /* @__PURE__ */ jsx(
|
|
488
|
+
SelectionOverlay,
|
|
454
489
|
{
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
outline: "2px solid #8b5cf6",
|
|
462
|
-
borderRadius: 4,
|
|
463
|
-
pointerEvents: "none",
|
|
464
|
-
zIndex: Z
|
|
465
|
-
}
|
|
490
|
+
box,
|
|
491
|
+
base: transforms?.[selection] ?? {},
|
|
492
|
+
movable: Boolean(onNodeTransform),
|
|
493
|
+
getEl: () => pageRef.current?.querySelector(`[data-cms="${cssEscape2(selection)}"]`) ?? null,
|
|
494
|
+
onTransform: (t) => onNodeTransform?.(selection, t),
|
|
495
|
+
onLive: measureBox
|
|
466
496
|
}
|
|
467
497
|
) : null,
|
|
468
498
|
editing && box && selNode ? /* @__PURE__ */ jsx(FloatingToolbar, { box, isText: selNode.type === "text", base: selNode.style.base, setStyle }) : null,
|
|
@@ -484,17 +514,102 @@ function EditablePage({
|
|
|
484
514
|
editing && timelineDock ? /* @__PURE__ */ jsx("div", { style: { position: "fixed", left: 0, right: 0, bottom: 0, zIndex: Z }, children: timelineDock }) : null
|
|
485
515
|
] });
|
|
486
516
|
}
|
|
517
|
+
function SelectionOverlay({
|
|
518
|
+
box,
|
|
519
|
+
base,
|
|
520
|
+
movable,
|
|
521
|
+
getEl,
|
|
522
|
+
onTransform,
|
|
523
|
+
onLive
|
|
524
|
+
}) {
|
|
525
|
+
const drag = useRef(null);
|
|
526
|
+
const apply = (t) => {
|
|
527
|
+
const el = getEl();
|
|
528
|
+
if (el) {
|
|
529
|
+
el.style.transform = `translate3d(${t.x ?? 0}px, ${t.y ?? 0}px, 0) scale(${t.scale ?? 1})`;
|
|
530
|
+
el.style.opacity = t.opacity != null ? String(t.opacity) : "";
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
const start = (kind) => (e) => {
|
|
534
|
+
e.stopPropagation();
|
|
535
|
+
e.preventDefault();
|
|
536
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
537
|
+
drag.current = { kind, x: e.clientX, y: e.clientY, w: box.w, live: { ...base } };
|
|
538
|
+
};
|
|
539
|
+
const move = (e) => {
|
|
540
|
+
const d = drag.current;
|
|
541
|
+
if (!d) return;
|
|
542
|
+
if (d.kind === "move") {
|
|
543
|
+
d.live = { ...base, x: (base.x ?? 0) + (e.clientX - d.x), y: (base.y ?? 0) + (e.clientY - d.y) };
|
|
544
|
+
} else {
|
|
545
|
+
const factor = Math.max(0.1, (d.w + (e.clientX - d.x)) / d.w);
|
|
546
|
+
d.live = { ...base, scale: Number(((base.scale ?? 1) * factor).toFixed(3)) };
|
|
547
|
+
}
|
|
548
|
+
apply(d.live);
|
|
549
|
+
onLive();
|
|
550
|
+
};
|
|
551
|
+
const end = () => {
|
|
552
|
+
const d = drag.current;
|
|
553
|
+
if (d) onTransform(d.live);
|
|
554
|
+
drag.current = null;
|
|
555
|
+
};
|
|
556
|
+
const outline = {
|
|
557
|
+
position: "fixed",
|
|
558
|
+
left: box.x - 1,
|
|
559
|
+
top: box.y - 1,
|
|
560
|
+
width: box.w + 2,
|
|
561
|
+
height: box.h + 2,
|
|
562
|
+
outline: "2px solid #8b5cf6",
|
|
563
|
+
borderRadius: 4,
|
|
564
|
+
pointerEvents: "none",
|
|
565
|
+
zIndex: Z
|
|
566
|
+
};
|
|
567
|
+
const handle = {
|
|
568
|
+
position: "fixed",
|
|
569
|
+
width: 16,
|
|
570
|
+
height: 16,
|
|
571
|
+
background: "#8b5cf6",
|
|
572
|
+
border: "2px solid #fff",
|
|
573
|
+
borderRadius: 5,
|
|
574
|
+
zIndex: Z + 1,
|
|
575
|
+
touchAction: "none"
|
|
576
|
+
};
|
|
577
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
578
|
+
/* @__PURE__ */ jsx("div", { style: outline }),
|
|
579
|
+
movable ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
580
|
+
/* @__PURE__ */ jsx(
|
|
581
|
+
"div",
|
|
582
|
+
{
|
|
583
|
+
title: "Drag to move",
|
|
584
|
+
onPointerDown: start("move"),
|
|
585
|
+
onPointerMove: move,
|
|
586
|
+
onPointerUp: end,
|
|
587
|
+
style: { ...handle, left: box.x - 9, top: box.y - 9, cursor: "move", borderRadius: 9 }
|
|
588
|
+
}
|
|
589
|
+
),
|
|
590
|
+
/* @__PURE__ */ jsx(
|
|
591
|
+
"div",
|
|
592
|
+
{
|
|
593
|
+
title: "Drag to resize",
|
|
594
|
+
onPointerDown: start("resize"),
|
|
595
|
+
onPointerMove: move,
|
|
596
|
+
onPointerUp: end,
|
|
597
|
+
style: { ...handle, left: box.x + box.w - 7, top: box.y + box.h - 7, cursor: "nwse-resize" }
|
|
598
|
+
}
|
|
599
|
+
)
|
|
600
|
+
] }) : null
|
|
601
|
+
] });
|
|
602
|
+
}
|
|
487
603
|
function FloatingToolbar({
|
|
488
604
|
box,
|
|
489
605
|
isText,
|
|
490
606
|
base,
|
|
491
607
|
setStyle
|
|
492
608
|
}) {
|
|
493
|
-
const top = Math.max(8, box.y - 46);
|
|
494
609
|
const wrap = {
|
|
495
610
|
position: "fixed",
|
|
496
611
|
left: box.x,
|
|
497
|
-
top,
|
|
612
|
+
top: Math.max(8, box.y - 46),
|
|
498
613
|
display: "flex",
|
|
499
614
|
alignItems: "center",
|
|
500
615
|
gap: 8,
|
|
@@ -515,17 +630,7 @@ function FloatingToolbar({
|
|
|
515
630
|
/* @__PURE__ */ jsx("span", { style: { opacity: 0.7 }, children: "A" }),
|
|
516
631
|
/* @__PURE__ */ jsx("input", { type: "color", style: swatch, value: base.color ?? "#0f172a", onChange: (e) => setStyle({ color: e.target.value }) })
|
|
517
632
|
] }) : null,
|
|
518
|
-
isText ? /* @__PURE__ */ jsx(
|
|
519
|
-
"input",
|
|
520
|
-
{
|
|
521
|
-
type: "number",
|
|
522
|
-
title: "Font size (px)",
|
|
523
|
-
style: num,
|
|
524
|
-
placeholder: "size",
|
|
525
|
-
value: base.fontSize?.value ?? "",
|
|
526
|
-
onChange: (e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: "px" } })
|
|
527
|
-
}
|
|
528
|
-
) : null,
|
|
633
|
+
isText ? /* @__PURE__ */ jsx("input", { type: "number", title: "Font size (px)", style: num, placeholder: "size", value: base.fontSize?.value ?? "", onChange: (e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: "px" } }) }) : null,
|
|
529
634
|
/* @__PURE__ */ jsxs("label", { title: "Background", style: { display: "inline-flex", alignItems: "center", gap: 4 }, children: [
|
|
530
635
|
/* @__PURE__ */ jsx("span", { style: { opacity: 0.7 }, children: "BG" }),
|
|
531
636
|
/* @__PURE__ */ jsx("input", { type: "color", style: swatch, value: normalizeColor(base.background), onChange: (e) => setStyle({ background: e.target.value }) })
|
|
@@ -541,22 +646,7 @@ function EditBar({
|
|
|
541
646
|
onRedo,
|
|
542
647
|
onAddText
|
|
543
648
|
}) {
|
|
544
|
-
const bar = {
|
|
545
|
-
position: "fixed",
|
|
546
|
-
top: 12,
|
|
547
|
-
right: 12,
|
|
548
|
-
display: "flex",
|
|
549
|
-
gap: 6,
|
|
550
|
-
alignItems: "center",
|
|
551
|
-
padding: 6,
|
|
552
|
-
background: "#0f172a",
|
|
553
|
-
color: "#fff",
|
|
554
|
-
borderRadius: 999,
|
|
555
|
-
boxShadow: "0 8px 24px -8px rgba(0,0,0,0.4)",
|
|
556
|
-
zIndex: Z + 3,
|
|
557
|
-
fontFamily: "system-ui, sans-serif",
|
|
558
|
-
fontSize: 12
|
|
559
|
-
};
|
|
649
|
+
const bar = { position: "fixed", top: 12, right: 12, display: "flex", gap: 6, alignItems: "center", padding: 6, background: "#0f172a", color: "#fff", borderRadius: 999, boxShadow: "0 8px 24px -8px rgba(0,0,0,0.4)", zIndex: Z + 3, fontFamily: "system-ui, sans-serif", fontSize: 12 };
|
|
560
650
|
const btn = { font: "inherit", border: "none", background: "transparent", color: "inherit", cursor: "pointer", padding: "4px 8px", borderRadius: 999 };
|
|
561
651
|
return /* @__PURE__ */ jsxs("div", { style: bar, children: [
|
|
562
652
|
/* @__PURE__ */ jsx("button", { type: "button", style: { ...btn, background: editing ? "#8b5cf6" : "transparent" }, onClick: onToggle, children: editing ? "\u25CF Editing" : "Edit" }),
|
package/dist/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/editor/state.ts","../src/editor/useEditor.ts","../src/editor/Canvas.tsx","../src/editor/LayersPanel.tsx","../src/editor/Inspector.tsx","../src/editor/Editor.tsx","../src/editor/EditablePage.tsx"],"names":["jsx","jsxs","Fragment","useRef","useState","useEffect","useLayoutEffect","cssEscape","useCallback"],"mappings":"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","file":"editor.js","sourcesContent":["/**\n * Editor state engine — pure and framework-agnostic so it's unit-testable.\n * `useEditor` wraps this with `useReducer`. Undo/redo uses document snapshots\n * (simple + robust); the op-level `invert` in the spine is for collab/op-stream\n * undo.\n */\nimport type { PageDoc } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\nimport { reduce } from \"../document/reduce\";\n\nexport interface EditorState {\n doc: PageDoc;\n past: PageDoc[];\n future: PageDoc[];\n selection: string | null;\n}\n\nexport type EditorAction =\n | { type: \"apply\"; op: PageOp }\n | { type: \"undo\" }\n | { type: \"redo\" }\n | { type: \"select\"; id: string | null }\n | { type: \"replace\"; doc: PageDoc };\n\nconst HISTORY_LIMIT = 100;\n\nexport function initEditor(doc: PageDoc): EditorState {\n return { doc, past: [], future: [], selection: null };\n}\n\nexport function editorReduce(state: EditorState, action: EditorAction): EditorState {\n switch (action.type) {\n case \"apply\": {\n const next = reduce(state.doc, action.op);\n if (next === state.doc) return state; // invalid op → no-op, no history entry\n return {\n ...state,\n doc: next,\n past: [...state.past, state.doc].slice(-HISTORY_LIMIT),\n future: [],\n };\n }\n case \"undo\": {\n if (state.past.length === 0) return state;\n const prev = state.past[state.past.length - 1]!;\n return {\n ...state,\n doc: prev,\n past: state.past.slice(0, -1),\n future: [state.doc, ...state.future],\n };\n }\n case \"redo\": {\n if (state.future.length === 0) return state;\n const next = state.future[0]!;\n return {\n ...state,\n doc: next,\n past: [...state.past, state.doc],\n future: state.future.slice(1),\n };\n }\n case \"select\":\n return state.selection === action.id ? state : { ...state, selection: action.id };\n case \"replace\":\n return state.doc === action.doc ? state : { ...state, doc: action.doc, future: [] };\n default:\n return state;\n }\n}\n","import { useCallback, useMemo, useReducer } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\nimport { editorReduce, initEditor, type EditorState } from \"./state\";\n\nexport interface EditorApi {\n state: EditorState;\n /** Dispatch a mutation through the op-spine (records an undo snapshot). */\n apply: (op: PageOp) => void;\n undo: () => void;\n redo: () => void;\n select: (id: string | null) => void;\n /** Replace the document wholesale (e.g. a controlled `value` change). */\n replace: (doc: PageDoc) => void;\n canUndo: boolean;\n canRedo: boolean;\n}\n\nexport function useEditor(initialDoc: PageDoc): EditorApi {\n const [state, dispatch] = useReducer(editorReduce, initialDoc, initEditor);\n const apply = useCallback((op: PageOp) => dispatch({ type: \"apply\", op }), []);\n const undo = useCallback(() => dispatch({ type: \"undo\" }), []);\n const redo = useCallback(() => dispatch({ type: \"redo\" }), []);\n const select = useCallback((id: string | null) => dispatch({ type: \"select\", id }), []);\n const replace = useCallback((doc: PageDoc) => dispatch({ type: \"replace\", doc }), []);\n\n return useMemo(\n () => ({\n state,\n apply,\n undo,\n redo,\n select,\n replace,\n canUndo: state.past.length > 0,\n canRedo: state.future.length > 0,\n }),\n [state, apply, undo, redo, select, replace],\n );\n}\n","import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n} from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\nimport { CmsPage } from \"../react/CmsPage\";\n\nexport interface CanvasProps {\n doc: PageDoc;\n selection: string | null;\n onSelect: (id: string | null) => void;\n apply: (op: PageOp) => void;\n}\n\ninterface Box {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * The edit surface: renders the live page and overlays a selection box. Click to\n * select; drag the box to move (px constraints). Phase 1 cut: free-parent\n * move + resize handles, stack/grid reordering, and snapping come next.\n */\nexport function Canvas({ doc, selection, onSelect, apply }: CanvasProps): ReactElement {\n const ref = useRef<HTMLDivElement>(null);\n const [box, setBox] = useState<Box | null>(null);\n const drag = useRef<{ x: number; y: number; left: number; top: number } | null>(null);\n\n useLayoutEffect(() => {\n const root = ref.current;\n if (!root || !selection) {\n setBox(null);\n return;\n }\n const el = root.querySelector(`[data-cms=\"${cssEscape(selection)}\"]`);\n if (!el) {\n setBox(null);\n return;\n }\n const r = el.getBoundingClientRect();\n const rootRect = root.getBoundingClientRect();\n setBox({\n x: r.left - rootRect.left + root.scrollLeft,\n y: r.top - rootRect.top + root.scrollTop,\n w: r.width,\n h: r.height,\n });\n }, [selection, doc]);\n\n const handleClick = (e: ReactMouseEvent<HTMLDivElement>) => {\n const target = (e.target as HTMLElement).closest(\"[data-cms]\");\n onSelect(target ? target.getAttribute(\"data-cms\") : null);\n };\n\n const handlePointerDown = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (!selection) return;\n const c = doc.nodes[selection]?.constraints?.base;\n const left = c && c.left && typeof c.left === \"object\" ? c.left.value : 0;\n const top = c && c.top && typeof c.top === \"object\" ? c.top.value : 0;\n drag.current = { x: e.clientX, y: e.clientY, left, top };\n e.currentTarget.setPointerCapture(e.pointerId);\n e.stopPropagation();\n };\n\n const handlePointerMove = (e: ReactPointerEvent<HTMLDivElement>) => {\n const d = drag.current;\n if (!d || !selection) return;\n apply({\n t: \"set_constraints\",\n id: selection,\n breakpoint: \"base\",\n patch: {\n left: { value: Math.round(d.left + (e.clientX - d.x)), unit: \"px\" },\n top: { value: Math.round(d.top + (e.clientY - d.y)), unit: \"px\" },\n },\n });\n };\n\n const handlePointerUp = () => {\n drag.current = null;\n };\n\n const surface: CSSProperties = {\n position: \"relative\",\n overflow: \"auto\",\n height: \"100%\",\n background: \"#f8fafc\",\n };\n const overlay: CSSProperties = box\n ? {\n position: \"absolute\",\n left: box.x,\n top: box.y,\n width: box.w,\n height: box.h,\n outline: \"2px solid #8b5cf6\",\n outlineOffset: -1,\n cursor: \"move\",\n touchAction: \"none\",\n }\n : { display: \"none\" };\n\n return (\n <div ref={ref} onClick={handleClick} style={surface}>\n <CmsPage doc={doc} />\n <div\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n style={overlay}\n />\n </div>\n );\n}\n\nfunction cssEscape(value: string): string {\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n","import { Fragment, type ReactElement } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport { childrenOf } from \"../document/reduce\";\n\nexport interface LayersPanelProps {\n doc: PageDoc;\n selection: string | null;\n onSelect: (id: string) => void;\n}\n\n/** The section/layer tree. Click a row to select. */\nexport function LayersPanel({ doc, selection, onSelect }: LayersPanelProps): ReactElement {\n return (\n <div style={{ overflow: \"auto\", padding: 8, fontSize: 13, fontFamily: \"system-ui, sans-serif\" }}>\n {doc.sections.map((id) => (\n <LayerRow key={id} doc={doc} id={id} depth={0} selection={selection} onSelect={onSelect} />\n ))}\n </div>\n );\n}\n\ninterface LayerRowProps extends LayersPanelProps {\n id: string;\n depth: number;\n}\n\nfunction LayerRow({ doc, id, depth, selection, onSelect }: LayerRowProps): ReactElement | null {\n const node = doc.nodes[id];\n if (!node) return null;\n const selected = selection === id;\n return (\n <Fragment>\n <button\n type=\"button\"\n onClick={() => onSelect(id)}\n style={{\n display: \"block\",\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n borderRadius: 6,\n cursor: \"pointer\",\n padding: \"4px 8px\",\n paddingLeft: 8 + depth * 14,\n background: selected ? \"#ede9fe\" : \"transparent\",\n color: selected ? \"#5b21b6\" : \"#334155\",\n font: \"inherit\",\n }}\n >\n <span style={{ opacity: 0.6 }}>{node.type}</span> · {id}\n </button>\n {childrenOf(doc, id).map((child) => (\n <LayerRow\n key={child.id}\n doc={doc}\n id={child.id}\n depth={depth + 1}\n selection={selection}\n onSelect={onSelect}\n />\n ))}\n </Fragment>\n );\n}\n","import type { CSSProperties, ReactElement } from \"react\";\nimport type { PageDoc, StyleProps } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\n\nexport interface InspectorProps {\n doc: PageDoc;\n selection: string | null;\n apply: (op: PageOp) => void;\n}\n\nconst label: CSSProperties = {\n display: \"block\",\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: \"#94a3b8\",\n margin: \"10px 0 4px\",\n};\nconst input: CSSProperties = {\n width: \"100%\",\n boxSizing: \"border-box\",\n padding: \"6px 8px\",\n borderRadius: 6,\n border: \"1px solid #e2e8f0\",\n font: \"inherit\",\n fontSize: 13,\n};\n\n/** Contextual property editor for the selected node. Every change is one op. */\nexport function Inspector({ doc, selection, apply }: InspectorProps): ReactElement {\n const node = selection ? doc.nodes[selection] : null;\n if (!node) {\n return (\n <div style={{ padding: 16, color: \"#94a3b8\", fontFamily: \"system-ui, sans-serif\", fontSize: 13 }}>\n Select an element to edit.\n </div>\n );\n }\n\n const s = node.style.base;\n const setStyle = (patch: Partial<StyleProps>) =>\n apply({ t: \"set_style\", id: node.id, breakpoint: \"base\", patch });\n const setProp = (key: string, value: unknown) =>\n apply({ t: \"set_props\", id: node.id, patch: { [key]: value } });\n\n return (\n <div style={{ overflow: \"auto\", padding: 16, fontFamily: \"system-ui, sans-serif\", height: \"100%\", boxSizing: \"border-box\" }}>\n <div style={{ fontSize: 13, fontWeight: 600, color: \"#0f172a\" }}>{node.type}</div>\n <div style={{ fontSize: 11, color: \"#94a3b8\", marginBottom: 8 }}>{node.id}</div>\n\n {node.type === \"text\" ? (\n <>\n <label style={label}>Content</label>\n <textarea\n style={{ ...input, minHeight: 64, resize: \"vertical\" }}\n value={typeof node.props.content === \"string\" ? node.props.content : \"\"}\n onChange={(e) => setProp(\"content\", e.target.value)}\n />\n </>\n ) : null}\n\n {node.type === \"image\" ? (\n <>\n <label style={label}>Source</label>\n <input\n style={input}\n value={typeof node.props.src === \"string\" ? node.props.src : \"\"}\n onChange={(e) => setProp(\"src\", e.target.value)}\n />\n </>\n ) : null}\n\n <label style={label}>Background</label>\n <input\n style={input}\n placeholder=\"#ffffff | gradient | url(…)\"\n value={s.background ?? \"\"}\n onChange={(e) => setStyle({ background: e.target.value })}\n />\n\n <label style={label}>Text color</label>\n <input\n style={input}\n placeholder=\"#0f172a\"\n value={s.color ?? \"\"}\n onChange={(e) => setStyle({ color: e.target.value })}\n />\n\n <label style={label}>Font size (px)</label>\n <input\n type=\"number\"\n style={input}\n value={s.fontSize?.value ?? \"\"}\n onChange={(e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: \"px\" } })}\n />\n\n <label style={label}>Padding (px)</label>\n <input\n type=\"number\"\n style={input}\n value={s.padding?.value ?? \"\"}\n onChange={(e) => setStyle({ padding: { value: Number(e.target.value) || 0, unit: \"px\" } })}\n />\n\n <label style={label}>Opacity</label>\n <input\n type=\"number\"\n step=\"0.1\"\n min=\"0\"\n max=\"1\"\n style={input}\n value={s.opacity ?? \"\"}\n onChange={(e) => setStyle({ opacity: Number(e.target.value) })}\n />\n </div>\n );\n}\n","import { useEffect, useRef, type CSSProperties, type ReactElement } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport { useEditor, type EditorApi } from \"./useEditor\";\nimport { Canvas } from \"./Canvas\";\nimport { LayersPanel } from \"./LayersPanel\";\nimport { Inspector } from \"./Inspector\";\n\nexport interface EditorProps {\n /** Initial document; edits are surfaced via {@link EditorProps.onChange}. */\n defaultValue: PageDoc;\n onChange?: (doc: PageDoc) => void;\n}\n\n/**\n * The fancy-cms editor: layers · canvas · inspector over the op-spine. Phase 1\n * cut — chrome is plain markup for now; it graduates to react-fancy next.\n */\nexport function Editor({ defaultValue, onChange }: EditorProps): ReactElement {\n const ed = useEditor(defaultValue);\n const first = useRef(true);\n\n useEffect(() => {\n if (first.current) {\n first.current = false;\n return;\n }\n onChange?.(ed.state.doc);\n }, [ed.state.doc, onChange]);\n\n const shell: CSSProperties = {\n display: \"grid\",\n gridTemplateColumns: \"220px 1fr 300px\",\n height: \"100%\",\n minHeight: 0,\n background: \"#fff\",\n color: \"#0f172a\",\n border: \"1px solid #e2e8f0\",\n borderRadius: 12,\n overflow: \"hidden\",\n };\n\n return (\n <div style={shell}>\n <div style={{ borderRight: \"1px solid #e2e8f0\", display: \"flex\", flexDirection: \"column\", minHeight: 0 }}>\n <Toolbar ed={ed} />\n <LayersPanel doc={ed.state.doc} selection={ed.state.selection} onSelect={ed.select} />\n </div>\n <Canvas doc={ed.state.doc} selection={ed.state.selection} onSelect={ed.select} apply={ed.apply} />\n <div style={{ borderLeft: \"1px solid #e2e8f0\", minHeight: 0 }}>\n <Inspector doc={ed.state.doc} selection={ed.state.selection} apply={ed.apply} />\n </div>\n </div>\n );\n}\n\nfunction Toolbar({ ed }: { ed: EditorApi }): ReactElement {\n const btn: CSSProperties = {\n font: \"inherit\",\n fontSize: 12,\n padding: \"4px 10px\",\n borderRadius: 6,\n border: \"1px solid #e2e8f0\",\n background: \"#fff\",\n cursor: \"pointer\",\n };\n return (\n <div\n style={{\n display: \"flex\",\n gap: 6,\n padding: 8,\n borderBottom: \"1px solid #e2e8f0\",\n fontFamily: \"system-ui, sans-serif\",\n }}\n >\n <button type=\"button\" style={{ ...btn, opacity: ed.canUndo ? 1 : 0.4 }} disabled={!ed.canUndo} onClick={ed.undo}>\n Undo\n </button>\n <button type=\"button\" style={{ ...btn, opacity: ed.canRedo ? 1 : 0.4 }} disabled={!ed.canRedo} onClick={ed.redo}>\n Redo\n </button>\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport type { PageDoc, StyleProps } from \"../document/types\";\nimport { childrenOf } from \"../document/reduce\";\nimport { keyBetween } from \"../document/fractional\";\nimport { CmsPage } from \"../react/CmsPage\";\nimport { defaultRegistry, type ElementRegistry } from \"../react/registry\";\nimport { useEditor } from \"./useEditor\";\n\nexport interface EditablePageProps {\n /** Seeded document (read-only demo: edits are in-memory, never persisted). */\n doc: PageDoc;\n registry?: ElementRegistry;\n /** Slot for the fancy-motion timeline dock (rendered at the bottom in EditMode). */\n timelineDock?: ReactNode;\n}\n\ninterface Box {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst Z = 2147483000;\n\n/**\n * Inline EditMode over a live, seeded CMS page. The Edit affordance is hidden\n * until you hold **Ctrl+Shift** (reveal gesture). Editing is **on the page**:\n * text is edited in place (contentEditable) and a compact **floating toolbar**\n * (dark, dark-mode-safe) sits above the selection for styling — no side flyout.\n * Read-only: edits live in memory, never saved.\n */\nexport function EditablePage({\n doc,\n registry = defaultRegistry,\n timelineDock,\n}: EditablePageProps): ReactElement {\n const ed = useEditor(doc);\n const [editing, setEditing] = useState(false);\n const [revealed, setRevealed] = useState(false);\n const pageRef = useRef<HTMLDivElement>(null);\n const [box, setBox] = useState<Box | null>(null);\n const { selection } = ed.state;\n const selNode = selection ? ed.state.doc.nodes[selection] : null;\n\n // Ctrl+Shift reveal gesture for the Edit affordance.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => setRevealed(e.ctrlKey && e.shiftKey);\n const onBlur = () => setRevealed(false);\n window.addEventListener(\"keydown\", onKey);\n window.addEventListener(\"keyup\", onKey);\n window.addEventListener(\"blur\", onBlur);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"keyup\", onKey);\n window.removeEventListener(\"blur\", onBlur);\n };\n }, []);\n\n // Track the selection box (fixed-positioned, follows scroll/resize).\n useLayoutEffect(() => {\n if (!editing || !selection || !pageRef.current) {\n setBox(null);\n return;\n }\n const update = () => {\n const el = pageRef.current?.querySelector(`[data-cms=\"${cssEscape(selection)}\"]`);\n if (!el) return setBox(null);\n const r = el.getBoundingClientRect();\n setBox({ x: r.left, y: r.top, w: r.width, h: r.height });\n };\n update();\n window.addEventListener(\"scroll\", update, { passive: true });\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update);\n window.removeEventListener(\"resize\", update);\n };\n }, [editing, selection, ed.state.doc]);\n\n // Inline contentEditable: when a text node is selected, make its element\n // editable in place; commit to the doc on blur (so React doesn't fight the caret).\n useEffect(() => {\n if (!editing || !selection || !pageRef.current) return;\n if (selNode?.type !== \"text\") return;\n const el = pageRef.current.querySelector<HTMLElement>(`[data-cms=\"${cssEscape(selection)}\"]`);\n if (!el) return;\n el.setAttribute(\"contenteditable\", \"true\");\n el.style.outline = \"none\";\n el.focus();\n const commit = () => {\n ed.apply({ t: \"set_props\", id: selection, patch: { content: el.innerText } });\n };\n el.addEventListener(\"blur\", commit);\n return () => {\n el.removeEventListener(\"blur\", commit);\n el.removeAttribute(\"contenteditable\");\n };\n }, [editing, selection, selNode?.type, ed]);\n\n const onClickCapture = (e: ReactMouseEvent<HTMLDivElement>) => {\n if (!editing) return;\n const el = (e.target as HTMLElement).closest(\"[data-cms]\");\n if (el) {\n // let an already-editing text element keep the caret on its own clicks\n if (el.getAttribute(\"contenteditable\") === \"true\") return;\n e.preventDefault();\n e.stopPropagation();\n ed.select(el.getAttribute(\"data-cms\"));\n }\n };\n\n const addText = useCallback(() => {\n const parent = selNode && selNode.type !== \"text\" ? selNode.id : (ed.state.doc.sections[0] ?? null);\n const siblings = childrenOf(ed.state.doc, parent);\n const order = keyBetween(siblings.length ? siblings[siblings.length - 1]!.order : null, null);\n const id = `n${ed.state.doc.seq + 1}-${Math.floor(performance.now())}`;\n ed.apply({\n t: \"insert_node\",\n node: { id, type: \"text\", parent, order, props: { content: \"New text\" }, style: { base: { color: \"inherit\" } } },\n });\n ed.select(id);\n }, [ed, selNode]);\n\n const setStyle = (patch: Partial<StyleProps>) =>\n selection && ed.apply({ t: \"set_style\", id: selection, breakpoint: \"base\", patch });\n\n return (\n <div style={{ position: \"relative\" }}>\n <div ref={pageRef} onClickCapture={onClickCapture}>\n <CmsPage doc={ed.state.doc} registry={registry} />\n </div>\n\n {/* selection outline */}\n {editing && box ? (\n <div\n style={{\n position: \"fixed\",\n left: box.x - 1,\n top: box.y - 1,\n width: box.w + 2,\n height: box.h + 2,\n outline: \"2px solid #8b5cf6\",\n borderRadius: 4,\n pointerEvents: \"none\",\n zIndex: Z,\n }}\n />\n ) : null}\n\n {/* floating toolbar above the selection (dark — dark-mode safe) */}\n {editing && box && selNode ? (\n <FloatingToolbar box={box} isText={selNode.type === \"text\"} base={selNode.style.base} setStyle={setStyle} />\n ) : null}\n\n {/* reveal-gated edit affordance / toolbar */}\n {revealed || editing ? (\n <EditBar\n editing={editing}\n onToggle={() => {\n setEditing((v) => !v);\n ed.select(null);\n }}\n canUndo={ed.canUndo}\n canRedo={ed.canRedo}\n onUndo={ed.undo}\n onRedo={ed.redo}\n onAddText={addText}\n />\n ) : null}\n\n {editing && timelineDock ? (\n <div style={{ position: \"fixed\", left: 0, right: 0, bottom: 0, zIndex: Z }}>{timelineDock}</div>\n ) : null}\n </div>\n );\n}\n\nfunction FloatingToolbar({\n box,\n isText,\n base,\n setStyle,\n}: {\n box: Box;\n isText: boolean;\n base: Partial<StyleProps>;\n setStyle: (patch: Partial<StyleProps>) => void;\n}): ReactElement {\n const top = Math.max(8, box.y - 46);\n const wrap: CSSProperties = {\n position: \"fixed\",\n left: box.x,\n top,\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"6px 10px\",\n background: \"#0f172a\",\n color: \"#fff\",\n border: \"1px solid rgba(255,255,255,0.12)\",\n borderRadius: 999,\n boxShadow: \"0 8px 24px -8px rgba(0,0,0,0.5)\",\n zIndex: Z + 2,\n fontFamily: \"system-ui, sans-serif\",\n fontSize: 12,\n };\n const swatch: CSSProperties = { width: 22, height: 22, border: \"none\", background: \"transparent\", padding: 0, cursor: \"pointer\" };\n const num: CSSProperties = { width: 52, background: \"#1e293b\", color: \"#fff\", border: \"1px solid #334155\", borderRadius: 6, padding: \"3px 6px\", font: \"inherit\" };\n\n return (\n <div style={wrap} onMouseDown={(e) => e.preventDefault() /* keep selection */}>\n {isText ? (\n <label title=\"Text color\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4 }}>\n <span style={{ opacity: 0.7 }}>A</span>\n <input type=\"color\" style={swatch} value={base.color ?? \"#0f172a\"} onChange={(e) => setStyle({ color: e.target.value })} />\n </label>\n ) : null}\n {isText ? (\n <input\n type=\"number\"\n title=\"Font size (px)\"\n style={num}\n placeholder=\"size\"\n value={base.fontSize?.value ?? \"\"}\n onChange={(e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: \"px\" } })}\n />\n ) : null}\n <label title=\"Background\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4 }}>\n <span style={{ opacity: 0.7 }}>BG</span>\n <input type=\"color\" style={swatch} value={normalizeColor(base.background)} onChange={(e) => setStyle({ background: e.target.value })} />\n </label>\n </div>\n );\n}\n\nfunction EditBar({\n editing,\n onToggle,\n canUndo,\n canRedo,\n onUndo,\n onRedo,\n onAddText,\n}: {\n editing: boolean;\n onToggle: () => void;\n canUndo: boolean;\n canRedo: boolean;\n onUndo: () => void;\n onRedo: () => void;\n onAddText: () => void;\n}): ReactElement {\n const bar: CSSProperties = {\n position: \"fixed\",\n top: 12,\n right: 12,\n display: \"flex\",\n gap: 6,\n alignItems: \"center\",\n padding: 6,\n background: \"#0f172a\",\n color: \"#fff\",\n borderRadius: 999,\n boxShadow: \"0 8px 24px -8px rgba(0,0,0,0.4)\",\n zIndex: Z + 3,\n fontFamily: \"system-ui, sans-serif\",\n fontSize: 12,\n };\n const btn: CSSProperties = { font: \"inherit\", border: \"none\", background: \"transparent\", color: \"inherit\", cursor: \"pointer\", padding: \"4px 8px\", borderRadius: 999 };\n return (\n <div style={bar}>\n <button type=\"button\" style={{ ...btn, background: editing ? \"#8b5cf6\" : \"transparent\" }} onClick={onToggle}>\n {editing ? \"● Editing\" : \"Edit\"}\n </button>\n {editing ? (\n <>\n <button type=\"button\" style={btn} onClick={onAddText} title=\"Add a text element\">\n + Text\n </button>\n <button type=\"button\" style={{ ...btn, opacity: canUndo ? 1 : 0.4 }} disabled={!canUndo} onClick={onUndo}>\n ↶\n </button>\n <button type=\"button\" style={{ ...btn, opacity: canRedo ? 1 : 0.4 }} disabled={!canRedo} onClick={onRedo}>\n ↷\n </button>\n </>\n ) : null}\n </div>\n );\n}\n\nfunction normalizeColor(v: string | undefined): string {\n return v && /^#[0-9a-fA-F]{6}$/.test(v) ? v : \"#ffffff\";\n}\n\nfunction cssEscape(value: string): string {\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/editor/state.ts","../src/editor/useEditor.ts","../src/editor/Canvas.tsx","../src/editor/LayersPanel.tsx","../src/editor/Inspector.tsx","../src/editor/Editor.tsx","../src/editor/EditablePage.tsx"],"names":["jsx","jsxs","Fragment","useRef","useState","useEffect","useCallback","cssEscape","useLayoutEffect"],"mappings":"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","file":"editor.js","sourcesContent":["/**\n * Editor state engine — pure and framework-agnostic so it's unit-testable.\n * `useEditor` wraps this with `useReducer`. Undo/redo uses document snapshots\n * (simple + robust); the op-level `invert` in the spine is for collab/op-stream\n * undo.\n */\nimport type { PageDoc } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\nimport { reduce } from \"../document/reduce\";\n\nexport interface EditorState {\n doc: PageDoc;\n past: PageDoc[];\n future: PageDoc[];\n selection: string | null;\n}\n\nexport type EditorAction =\n | { type: \"apply\"; op: PageOp }\n | { type: \"undo\" }\n | { type: \"redo\" }\n | { type: \"select\"; id: string | null }\n | { type: \"replace\"; doc: PageDoc };\n\nconst HISTORY_LIMIT = 100;\n\nexport function initEditor(doc: PageDoc): EditorState {\n return { doc, past: [], future: [], selection: null };\n}\n\nexport function editorReduce(state: EditorState, action: EditorAction): EditorState {\n switch (action.type) {\n case \"apply\": {\n const next = reduce(state.doc, action.op);\n if (next === state.doc) return state; // invalid op → no-op, no history entry\n return {\n ...state,\n doc: next,\n past: [...state.past, state.doc].slice(-HISTORY_LIMIT),\n future: [],\n };\n }\n case \"undo\": {\n if (state.past.length === 0) return state;\n const prev = state.past[state.past.length - 1]!;\n return {\n ...state,\n doc: prev,\n past: state.past.slice(0, -1),\n future: [state.doc, ...state.future],\n };\n }\n case \"redo\": {\n if (state.future.length === 0) return state;\n const next = state.future[0]!;\n return {\n ...state,\n doc: next,\n past: [...state.past, state.doc],\n future: state.future.slice(1),\n };\n }\n case \"select\":\n return state.selection === action.id ? state : { ...state, selection: action.id };\n case \"replace\":\n return state.doc === action.doc ? state : { ...state, doc: action.doc, future: [] };\n default:\n return state;\n }\n}\n","import { useCallback, useMemo, useReducer } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\nimport { editorReduce, initEditor, type EditorState } from \"./state\";\n\nexport interface EditorApi {\n state: EditorState;\n /** Dispatch a mutation through the op-spine (records an undo snapshot). */\n apply: (op: PageOp) => void;\n undo: () => void;\n redo: () => void;\n select: (id: string | null) => void;\n /** Replace the document wholesale (e.g. a controlled `value` change). */\n replace: (doc: PageDoc) => void;\n canUndo: boolean;\n canRedo: boolean;\n}\n\nexport function useEditor(initialDoc: PageDoc): EditorApi {\n const [state, dispatch] = useReducer(editorReduce, initialDoc, initEditor);\n const apply = useCallback((op: PageOp) => dispatch({ type: \"apply\", op }), []);\n const undo = useCallback(() => dispatch({ type: \"undo\" }), []);\n const redo = useCallback(() => dispatch({ type: \"redo\" }), []);\n const select = useCallback((id: string | null) => dispatch({ type: \"select\", id }), []);\n const replace = useCallback((doc: PageDoc) => dispatch({ type: \"replace\", doc }), []);\n\n return useMemo(\n () => ({\n state,\n apply,\n undo,\n redo,\n select,\n replace,\n canUndo: state.past.length > 0,\n canRedo: state.future.length > 0,\n }),\n [state, apply, undo, redo, select, replace],\n );\n}\n","import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n} from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\nimport { CmsPage } from \"../react/CmsPage\";\n\nexport interface CanvasProps {\n doc: PageDoc;\n selection: string | null;\n onSelect: (id: string | null) => void;\n apply: (op: PageOp) => void;\n}\n\ninterface Box {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/**\n * The edit surface: renders the live page and overlays a selection box. Click to\n * select; drag the box to move (px constraints). Phase 1 cut: free-parent\n * move + resize handles, stack/grid reordering, and snapping come next.\n */\nexport function Canvas({ doc, selection, onSelect, apply }: CanvasProps): ReactElement {\n const ref = useRef<HTMLDivElement>(null);\n const [box, setBox] = useState<Box | null>(null);\n const drag = useRef<{ x: number; y: number; left: number; top: number } | null>(null);\n\n useLayoutEffect(() => {\n const root = ref.current;\n if (!root || !selection) {\n setBox(null);\n return;\n }\n const el = root.querySelector(`[data-cms=\"${cssEscape(selection)}\"]`);\n if (!el) {\n setBox(null);\n return;\n }\n const r = el.getBoundingClientRect();\n const rootRect = root.getBoundingClientRect();\n setBox({\n x: r.left - rootRect.left + root.scrollLeft,\n y: r.top - rootRect.top + root.scrollTop,\n w: r.width,\n h: r.height,\n });\n }, [selection, doc]);\n\n const handleClick = (e: ReactMouseEvent<HTMLDivElement>) => {\n const target = (e.target as HTMLElement).closest(\"[data-cms]\");\n onSelect(target ? target.getAttribute(\"data-cms\") : null);\n };\n\n const handlePointerDown = (e: ReactPointerEvent<HTMLDivElement>) => {\n if (!selection) return;\n const c = doc.nodes[selection]?.constraints?.base;\n const left = c && c.left && typeof c.left === \"object\" ? c.left.value : 0;\n const top = c && c.top && typeof c.top === \"object\" ? c.top.value : 0;\n drag.current = { x: e.clientX, y: e.clientY, left, top };\n e.currentTarget.setPointerCapture(e.pointerId);\n e.stopPropagation();\n };\n\n const handlePointerMove = (e: ReactPointerEvent<HTMLDivElement>) => {\n const d = drag.current;\n if (!d || !selection) return;\n apply({\n t: \"set_constraints\",\n id: selection,\n breakpoint: \"base\",\n patch: {\n left: { value: Math.round(d.left + (e.clientX - d.x)), unit: \"px\" },\n top: { value: Math.round(d.top + (e.clientY - d.y)), unit: \"px\" },\n },\n });\n };\n\n const handlePointerUp = () => {\n drag.current = null;\n };\n\n const surface: CSSProperties = {\n position: \"relative\",\n overflow: \"auto\",\n height: \"100%\",\n background: \"#f8fafc\",\n };\n const overlay: CSSProperties = box\n ? {\n position: \"absolute\",\n left: box.x,\n top: box.y,\n width: box.w,\n height: box.h,\n outline: \"2px solid #8b5cf6\",\n outlineOffset: -1,\n cursor: \"move\",\n touchAction: \"none\",\n }\n : { display: \"none\" };\n\n return (\n <div ref={ref} onClick={handleClick} style={surface}>\n <CmsPage doc={doc} />\n <div\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n style={overlay}\n />\n </div>\n );\n}\n\nfunction cssEscape(value: string): string {\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n","import { Fragment, type ReactElement } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport { childrenOf } from \"../document/reduce\";\n\nexport interface LayersPanelProps {\n doc: PageDoc;\n selection: string | null;\n onSelect: (id: string) => void;\n}\n\n/** The section/layer tree. Click a row to select. */\nexport function LayersPanel({ doc, selection, onSelect }: LayersPanelProps): ReactElement {\n return (\n <div style={{ overflow: \"auto\", padding: 8, fontSize: 13, fontFamily: \"system-ui, sans-serif\" }}>\n {doc.sections.map((id) => (\n <LayerRow key={id} doc={doc} id={id} depth={0} selection={selection} onSelect={onSelect} />\n ))}\n </div>\n );\n}\n\ninterface LayerRowProps extends LayersPanelProps {\n id: string;\n depth: number;\n}\n\nfunction LayerRow({ doc, id, depth, selection, onSelect }: LayerRowProps): ReactElement | null {\n const node = doc.nodes[id];\n if (!node) return null;\n const selected = selection === id;\n return (\n <Fragment>\n <button\n type=\"button\"\n onClick={() => onSelect(id)}\n style={{\n display: \"block\",\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n borderRadius: 6,\n cursor: \"pointer\",\n padding: \"4px 8px\",\n paddingLeft: 8 + depth * 14,\n background: selected ? \"#ede9fe\" : \"transparent\",\n color: selected ? \"#5b21b6\" : \"#334155\",\n font: \"inherit\",\n }}\n >\n <span style={{ opacity: 0.6 }}>{node.type}</span> · {id}\n </button>\n {childrenOf(doc, id).map((child) => (\n <LayerRow\n key={child.id}\n doc={doc}\n id={child.id}\n depth={depth + 1}\n selection={selection}\n onSelect={onSelect}\n />\n ))}\n </Fragment>\n );\n}\n","import type { CSSProperties, ReactElement } from \"react\";\nimport type { PageDoc, StyleProps } from \"../document/types\";\nimport type { PageOp } from \"../document/ops\";\n\nexport interface InspectorProps {\n doc: PageDoc;\n selection: string | null;\n apply: (op: PageOp) => void;\n}\n\nconst label: CSSProperties = {\n display: \"block\",\n fontSize: 11,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: \"#94a3b8\",\n margin: \"10px 0 4px\",\n};\nconst input: CSSProperties = {\n width: \"100%\",\n boxSizing: \"border-box\",\n padding: \"6px 8px\",\n borderRadius: 6,\n border: \"1px solid #e2e8f0\",\n font: \"inherit\",\n fontSize: 13,\n};\n\n/** Contextual property editor for the selected node. Every change is one op. */\nexport function Inspector({ doc, selection, apply }: InspectorProps): ReactElement {\n const node = selection ? doc.nodes[selection] : null;\n if (!node) {\n return (\n <div style={{ padding: 16, color: \"#94a3b8\", fontFamily: \"system-ui, sans-serif\", fontSize: 13 }}>\n Select an element to edit.\n </div>\n );\n }\n\n const s = node.style.base;\n const setStyle = (patch: Partial<StyleProps>) =>\n apply({ t: \"set_style\", id: node.id, breakpoint: \"base\", patch });\n const setProp = (key: string, value: unknown) =>\n apply({ t: \"set_props\", id: node.id, patch: { [key]: value } });\n\n return (\n <div style={{ overflow: \"auto\", padding: 16, fontFamily: \"system-ui, sans-serif\", height: \"100%\", boxSizing: \"border-box\" }}>\n <div style={{ fontSize: 13, fontWeight: 600, color: \"#0f172a\" }}>{node.type}</div>\n <div style={{ fontSize: 11, color: \"#94a3b8\", marginBottom: 8 }}>{node.id}</div>\n\n {node.type === \"text\" ? (\n <>\n <label style={label}>Content</label>\n <textarea\n style={{ ...input, minHeight: 64, resize: \"vertical\" }}\n value={typeof node.props.content === \"string\" ? node.props.content : \"\"}\n onChange={(e) => setProp(\"content\", e.target.value)}\n />\n </>\n ) : null}\n\n {node.type === \"image\" ? (\n <>\n <label style={label}>Source</label>\n <input\n style={input}\n value={typeof node.props.src === \"string\" ? node.props.src : \"\"}\n onChange={(e) => setProp(\"src\", e.target.value)}\n />\n </>\n ) : null}\n\n <label style={label}>Background</label>\n <input\n style={input}\n placeholder=\"#ffffff | gradient | url(…)\"\n value={s.background ?? \"\"}\n onChange={(e) => setStyle({ background: e.target.value })}\n />\n\n <label style={label}>Text color</label>\n <input\n style={input}\n placeholder=\"#0f172a\"\n value={s.color ?? \"\"}\n onChange={(e) => setStyle({ color: e.target.value })}\n />\n\n <label style={label}>Font size (px)</label>\n <input\n type=\"number\"\n style={input}\n value={s.fontSize?.value ?? \"\"}\n onChange={(e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: \"px\" } })}\n />\n\n <label style={label}>Padding (px)</label>\n <input\n type=\"number\"\n style={input}\n value={s.padding?.value ?? \"\"}\n onChange={(e) => setStyle({ padding: { value: Number(e.target.value) || 0, unit: \"px\" } })}\n />\n\n <label style={label}>Opacity</label>\n <input\n type=\"number\"\n step=\"0.1\"\n min=\"0\"\n max=\"1\"\n style={input}\n value={s.opacity ?? \"\"}\n onChange={(e) => setStyle({ opacity: Number(e.target.value) })}\n />\n </div>\n );\n}\n","import { useEffect, useRef, type CSSProperties, type ReactElement } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport { useEditor, type EditorApi } from \"./useEditor\";\nimport { Canvas } from \"./Canvas\";\nimport { LayersPanel } from \"./LayersPanel\";\nimport { Inspector } from \"./Inspector\";\n\nexport interface EditorProps {\n /** Initial document; edits are surfaced via {@link EditorProps.onChange}. */\n defaultValue: PageDoc;\n onChange?: (doc: PageDoc) => void;\n}\n\n/**\n * The fancy-cms editor: layers · canvas · inspector over the op-spine. Phase 1\n * cut — chrome is plain markup for now; it graduates to react-fancy next.\n */\nexport function Editor({ defaultValue, onChange }: EditorProps): ReactElement {\n const ed = useEditor(defaultValue);\n const first = useRef(true);\n\n useEffect(() => {\n if (first.current) {\n first.current = false;\n return;\n }\n onChange?.(ed.state.doc);\n }, [ed.state.doc, onChange]);\n\n const shell: CSSProperties = {\n display: \"grid\",\n gridTemplateColumns: \"220px 1fr 300px\",\n height: \"100%\",\n minHeight: 0,\n background: \"#fff\",\n color: \"#0f172a\",\n border: \"1px solid #e2e8f0\",\n borderRadius: 12,\n overflow: \"hidden\",\n };\n\n return (\n <div style={shell}>\n <div style={{ borderRight: \"1px solid #e2e8f0\", display: \"flex\", flexDirection: \"column\", minHeight: 0 }}>\n <Toolbar ed={ed} />\n <LayersPanel doc={ed.state.doc} selection={ed.state.selection} onSelect={ed.select} />\n </div>\n <Canvas doc={ed.state.doc} selection={ed.state.selection} onSelect={ed.select} apply={ed.apply} />\n <div style={{ borderLeft: \"1px solid #e2e8f0\", minHeight: 0 }}>\n <Inspector doc={ed.state.doc} selection={ed.state.selection} apply={ed.apply} />\n </div>\n </div>\n );\n}\n\nfunction Toolbar({ ed }: { ed: EditorApi }): ReactElement {\n const btn: CSSProperties = {\n font: \"inherit\",\n fontSize: 12,\n padding: \"4px 10px\",\n borderRadius: 6,\n border: \"1px solid #e2e8f0\",\n background: \"#fff\",\n cursor: \"pointer\",\n };\n return (\n <div\n style={{\n display: \"flex\",\n gap: 6,\n padding: 8,\n borderBottom: \"1px solid #e2e8f0\",\n fontFamily: \"system-ui, sans-serif\",\n }}\n >\n <button type=\"button\" style={{ ...btn, opacity: ed.canUndo ? 1 : 0.4 }} disabled={!ed.canUndo} onClick={ed.undo}>\n Undo\n </button>\n <button type=\"button\" style={{ ...btn, opacity: ed.canRedo ? 1 : 0.4 }} disabled={!ed.canRedo} onClick={ed.redo}>\n Redo\n </button>\n </div>\n );\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type PointerEvent as ReactPointerEvent,\n type ReactElement,\n type ReactNode,\n} from \"react\";\nimport type { PageDoc, StyleProps } from \"../document/types\";\nimport { childrenOf } from \"../document/reduce\";\nimport { keyBetween } from \"../document/fractional\";\nimport { CmsPage } from \"../react/CmsPage\";\nimport { defaultRegistry, type ElementRegistry } from \"../react/registry\";\nimport { useEditor } from \"./useEditor\";\n\n/** Animatable per-node transform (mirrors fancy-motion's NodeState, kept local to avoid a hard dep). */\nexport interface NodeTransform {\n x?: number;\n y?: number;\n scale?: number;\n opacity?: number;\n}\n\nexport interface EditablePageProps {\n doc: PageDoc;\n registry?: ElementRegistry;\n /** Slot for the fancy-motion timeline dock (rendered at the bottom in EditMode). */\n timelineDock?: ReactNode;\n /** Per-node transforms applied to the page (e.g. the sampled keyframe snapshot). */\n transforms?: Record<string, NodeTransform>;\n /** Fired when the user moves/resizes a node — the host writes it into the current keyframe. */\n onNodeTransform?: (id: string, transform: NodeTransform) => void;\n /** Notifies the host of the current selection (e.g. to sync the timeline). */\n onSelect?: (id: string | null) => void;\n /** Scroll length in viewports — the page becomes a tall scroll canvas (extend via the timeline). */\n frames?: number;\n /** Scroll progress 0..1 (scroll = the timeline playhead). The host maps it to transforms. */\n onProgress?: (progress: number) => void;\n}\n\ninterface Box {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst Z = 2147483000;\n\n/**\n * Inline EditMode over a live, seeded CMS page. Hold **Ctrl+Shift** to reveal\n * the Edit toggle. Editing is on the page: text is edited in place, a floating\n * toolbar styles it, and the selection can be **dragged to move** / **resized**\n * — committed as transforms the host captures into a timeline keyframe.\n */\nexport function EditablePage({\n doc,\n registry = defaultRegistry,\n timelineDock,\n transforms,\n onNodeTransform,\n onSelect,\n frames = 1,\n onProgress,\n}: EditablePageProps): ReactElement {\n const ed = useEditor(doc);\n const [editing, setEditing] = useState(false);\n const [revealed, setRevealed] = useState(false);\n const pageRef = useRef<HTMLDivElement>(null);\n const spacerRef = useRef<HTMLDivElement>(null);\n const [box, setBox] = useState<Box | null>(null);\n const { selection } = ed.state;\n const selNode = selection ? ed.state.doc.nodes[selection] : null;\n\n useEffect(() => onSelect?.(selection), [selection, onSelect]);\n\n // Ctrl+Shift reveal gesture.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => setRevealed(e.ctrlKey && e.shiftKey);\n const onBlur = () => setRevealed(false);\n window.addEventListener(\"keydown\", onKey);\n window.addEventListener(\"keyup\", onKey);\n window.addEventListener(\"blur\", onBlur);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"keyup\", onKey);\n window.removeEventListener(\"blur\", onBlur);\n };\n }, []);\n\n // Apply host-provided transforms to the page elements.\n useEffect(() => {\n const root = pageRef.current;\n if (!root) return;\n root.querySelectorAll<HTMLElement>(\"[data-cms]\").forEach((el) => {\n const id = el.dataset.cms;\n const t = id ? transforms?.[id] : undefined;\n if (t) {\n el.style.transform = `translate3d(${t.x ?? 0}px, ${t.y ?? 0}px, 0) scale(${t.scale ?? 1})`;\n el.style.opacity = t.opacity != null ? String(t.opacity) : \"\";\n } else {\n el.style.transform = \"\";\n el.style.opacity = \"\";\n }\n });\n }, [transforms, ed.state.doc]);\n\n // Scroll = the timeline playhead. Report progress (0..1) across the scroll\n // canvas so the host can drive the morph from real scrolling (not the dock).\n useEffect(() => {\n const spacer = spacerRef.current;\n if (!spacer || !onProgress) return;\n let raf = 0;\n const compute = () => {\n raf = 0;\n const len = spacer.offsetHeight - window.innerHeight;\n const top = spacer.getBoundingClientRect().top;\n onProgress(len > 0 ? Math.min(1, Math.max(0, -top / len)) : 0);\n };\n const onScroll = () => {\n if (!raf) raf = requestAnimationFrame(compute);\n };\n compute();\n window.addEventListener(\"scroll\", onScroll, { passive: true });\n window.addEventListener(\"resize\", onScroll);\n return () => {\n window.removeEventListener(\"scroll\", onScroll);\n window.removeEventListener(\"resize\", onScroll);\n if (raf) cancelAnimationFrame(raf);\n };\n }, [onProgress, frames]);\n\n const measureBox = useCallback(() => {\n if (!editing || !selection || !pageRef.current) return setBox(null);\n const el = pageRef.current.querySelector(`[data-cms=\"${cssEscape(selection)}\"]`);\n if (!el) return setBox(null);\n const r = el.getBoundingClientRect();\n setBox({ x: r.left, y: r.top, w: r.width, h: r.height });\n }, [editing, selection]);\n\n useLayoutEffect(() => {\n measureBox();\n window.addEventListener(\"scroll\", measureBox, { passive: true });\n window.addEventListener(\"resize\", measureBox);\n return () => {\n window.removeEventListener(\"scroll\", measureBox);\n window.removeEventListener(\"resize\", measureBox);\n };\n }, [measureBox, ed.state.doc, transforms]);\n\n // Inline contentEditable for text nodes.\n useEffect(() => {\n if (!editing || !selection || !pageRef.current || selNode?.type !== \"text\") return;\n const el = pageRef.current.querySelector<HTMLElement>(`[data-cms=\"${cssEscape(selection)}\"]`);\n if (!el) return;\n el.setAttribute(\"contenteditable\", \"true\");\n el.style.outline = \"none\";\n el.focus();\n const commit = () => ed.apply({ t: \"set_props\", id: selection, patch: { content: el.innerText } });\n el.addEventListener(\"blur\", commit);\n return () => {\n el.removeEventListener(\"blur\", commit);\n el.removeAttribute(\"contenteditable\");\n };\n }, [editing, selection, selNode?.type, ed]);\n\n const onClickCapture = (e: ReactMouseEvent<HTMLDivElement>) => {\n if (!editing) return;\n const el = (e.target as HTMLElement).closest(\"[data-cms]\");\n if (el) {\n if (el.getAttribute(\"contenteditable\") === \"true\") return;\n e.preventDefault();\n e.stopPropagation();\n ed.select(el.getAttribute(\"data-cms\"));\n }\n };\n\n const addText = useCallback(() => {\n const parent = selNode && selNode.type !== \"text\" ? selNode.id : (ed.state.doc.sections[0] ?? null);\n const siblings = childrenOf(ed.state.doc, parent);\n const order = keyBetween(siblings.length ? siblings[siblings.length - 1]!.order : null, null);\n const id = `n${ed.state.doc.seq + 1}-${Math.floor(performance.now())}`;\n ed.apply({ t: \"insert_node\", node: { id, type: \"text\", parent, order, props: { content: \"New text\" }, style: { base: { color: \"inherit\" } } } });\n ed.select(id);\n }, [ed, selNode]);\n\n const setStyle = (patch: Partial<StyleProps>) =>\n selection && ed.apply({ t: \"set_style\", id: selection, breakpoint: \"base\", patch });\n\n return (\n <div style={{ position: \"relative\" }}>\n <div ref={spacerRef} style={{ height: `${Math.max(1, frames) * 100}vh` }}>\n <div style={{ position: \"sticky\", top: 0, height: \"100vh\", overflow: \"hidden\" }}>\n <div ref={pageRef} onClickCapture={onClickCapture}>\n <CmsPage doc={ed.state.doc} registry={registry} />\n </div>\n </div>\n </div>\n\n {editing && box && selection ? (\n <SelectionOverlay\n box={box}\n base={transforms?.[selection] ?? {}}\n movable={Boolean(onNodeTransform)}\n getEl={() => pageRef.current?.querySelector<HTMLElement>(`[data-cms=\"${cssEscape(selection)}\"]`) ?? null}\n onTransform={(t) => onNodeTransform?.(selection, t)}\n onLive={measureBox}\n />\n ) : null}\n\n {editing && box && selNode ? (\n <FloatingToolbar box={box} isText={selNode.type === \"text\"} base={selNode.style.base} setStyle={setStyle} />\n ) : null}\n\n {revealed || editing ? (\n <EditBar\n editing={editing}\n onToggle={() => {\n setEditing((v) => !v);\n ed.select(null);\n }}\n canUndo={ed.canUndo}\n canRedo={ed.canRedo}\n onUndo={ed.undo}\n onRedo={ed.redo}\n onAddText={addText}\n />\n ) : null}\n\n {editing && timelineDock ? <div style={{ position: \"fixed\", left: 0, right: 0, bottom: 0, zIndex: Z }}>{timelineDock}</div> : null}\n </div>\n );\n}\n\nfunction SelectionOverlay({\n box,\n base,\n movable,\n getEl,\n onTransform,\n onLive,\n}: {\n box: Box;\n base: NodeTransform;\n movable: boolean;\n getEl: () => HTMLElement | null;\n onTransform: (t: NodeTransform) => void;\n onLive: () => void;\n}): ReactElement {\n const drag = useRef<{ kind: \"move\" | \"resize\"; x: number; y: number; w: number; live: NodeTransform } | null>(null);\n\n const apply = (t: NodeTransform) => {\n const el = getEl();\n if (el) {\n el.style.transform = `translate3d(${t.x ?? 0}px, ${t.y ?? 0}px, 0) scale(${t.scale ?? 1})`;\n el.style.opacity = t.opacity != null ? String(t.opacity) : \"\";\n }\n };\n\n const start = (kind: \"move\" | \"resize\") => (e: ReactPointerEvent<HTMLDivElement>) => {\n e.stopPropagation();\n e.preventDefault();\n e.currentTarget.setPointerCapture(e.pointerId);\n drag.current = { kind, x: e.clientX, y: e.clientY, w: box.w, live: { ...base } };\n };\n const move = (e: ReactPointerEvent<HTMLDivElement>) => {\n const d = drag.current;\n if (!d) return;\n if (d.kind === \"move\") {\n d.live = { ...base, x: (base.x ?? 0) + (e.clientX - d.x), y: (base.y ?? 0) + (e.clientY - d.y) };\n } else {\n const factor = Math.max(0.1, (d.w + (e.clientX - d.x)) / d.w);\n d.live = { ...base, scale: Number(((base.scale ?? 1) * factor).toFixed(3)) };\n }\n apply(d.live);\n onLive();\n };\n const end = () => {\n const d = drag.current;\n if (d) onTransform(d.live);\n drag.current = null;\n };\n\n const outline: CSSProperties = {\n position: \"fixed\",\n left: box.x - 1,\n top: box.y - 1,\n width: box.w + 2,\n height: box.h + 2,\n outline: \"2px solid #8b5cf6\",\n borderRadius: 4,\n pointerEvents: \"none\",\n zIndex: Z,\n };\n const handle: CSSProperties = {\n position: \"fixed\",\n width: 16,\n height: 16,\n background: \"#8b5cf6\",\n border: \"2px solid #fff\",\n borderRadius: 5,\n zIndex: Z + 1,\n touchAction: \"none\",\n };\n\n return (\n <>\n <div style={outline} />\n {movable ? (\n <>\n {/* move grip — top-left */}\n <div\n title=\"Drag to move\"\n onPointerDown={start(\"move\")}\n onPointerMove={move}\n onPointerUp={end}\n style={{ ...handle, left: box.x - 9, top: box.y - 9, cursor: \"move\", borderRadius: 9 }}\n />\n {/* resize — bottom-right */}\n <div\n title=\"Drag to resize\"\n onPointerDown={start(\"resize\")}\n onPointerMove={move}\n onPointerUp={end}\n style={{ ...handle, left: box.x + box.w - 7, top: box.y + box.h - 7, cursor: \"nwse-resize\" }}\n />\n </>\n ) : null}\n </>\n );\n}\n\nfunction FloatingToolbar({\n box,\n isText,\n base,\n setStyle,\n}: {\n box: Box;\n isText: boolean;\n base: Partial<StyleProps>;\n setStyle: (patch: Partial<StyleProps>) => void;\n}): ReactElement {\n const wrap: CSSProperties = {\n position: \"fixed\",\n left: box.x,\n top: Math.max(8, box.y - 46),\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"6px 10px\",\n background: \"#0f172a\",\n color: \"#fff\",\n border: \"1px solid rgba(255,255,255,0.12)\",\n borderRadius: 999,\n boxShadow: \"0 8px 24px -8px rgba(0,0,0,0.5)\",\n zIndex: Z + 2,\n fontFamily: \"system-ui, sans-serif\",\n fontSize: 12,\n };\n const swatch: CSSProperties = { width: 22, height: 22, border: \"none\", background: \"transparent\", padding: 0, cursor: \"pointer\" };\n const num: CSSProperties = { width: 52, background: \"#1e293b\", color: \"#fff\", border: \"1px solid #334155\", borderRadius: 6, padding: \"3px 6px\", font: \"inherit\" };\n return (\n <div style={wrap} onMouseDown={(e) => e.preventDefault()}>\n {isText ? (\n <label title=\"Text color\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4 }}>\n <span style={{ opacity: 0.7 }}>A</span>\n <input type=\"color\" style={swatch} value={base.color ?? \"#0f172a\"} onChange={(e) => setStyle({ color: e.target.value })} />\n </label>\n ) : null}\n {isText ? (\n <input type=\"number\" title=\"Font size (px)\" style={num} placeholder=\"size\" value={base.fontSize?.value ?? \"\"} onChange={(e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: \"px\" } })} />\n ) : null}\n <label title=\"Background\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: 4 }}>\n <span style={{ opacity: 0.7 }}>BG</span>\n <input type=\"color\" style={swatch} value={normalizeColor(base.background)} onChange={(e) => setStyle({ background: e.target.value })} />\n </label>\n </div>\n );\n}\n\nfunction EditBar({\n editing,\n onToggle,\n canUndo,\n canRedo,\n onUndo,\n onRedo,\n onAddText,\n}: {\n editing: boolean;\n onToggle: () => void;\n canUndo: boolean;\n canRedo: boolean;\n onUndo: () => void;\n onRedo: () => void;\n onAddText: () => void;\n}): ReactElement {\n const bar: CSSProperties = { position: \"fixed\", top: 12, right: 12, display: \"flex\", gap: 6, alignItems: \"center\", padding: 6, background: \"#0f172a\", color: \"#fff\", borderRadius: 999, boxShadow: \"0 8px 24px -8px rgba(0,0,0,0.4)\", zIndex: Z + 3, fontFamily: \"system-ui, sans-serif\", fontSize: 12 };\n const btn: CSSProperties = { font: \"inherit\", border: \"none\", background: \"transparent\", color: \"inherit\", cursor: \"pointer\", padding: \"4px 8px\", borderRadius: 999 };\n return (\n <div style={bar}>\n <button type=\"button\" style={{ ...btn, background: editing ? \"#8b5cf6\" : \"transparent\" }} onClick={onToggle}>\n {editing ? \"● Editing\" : \"Edit\"}\n </button>\n {editing ? (\n <>\n <button type=\"button\" style={btn} onClick={onAddText} title=\"Add a text element\">+ Text</button>\n <button type=\"button\" style={{ ...btn, opacity: canUndo ? 1 : 0.4 }} disabled={!canUndo} onClick={onUndo}>↶</button>\n <button type=\"button\" style={{ ...btn, opacity: canRedo ? 1 : 0.4 }} disabled={!canRedo} onClick={onRedo}>↷</button>\n </>\n ) : null}\n </div>\n );\n}\n\nfunction normalizeColor(v: string | undefined): string {\n return v && /^#[0-9a-fA-F]{6}$/.test(v) ? v : \"#ffffff\";\n}\n\nfunction cssEscape(value: string): string {\n return value.replace(/[\"\\\\]/g, \"\\\\$&\");\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@particle-academy/fancy-cms-ui",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.5",
|
|
4
4
|
"description": "Editor + isomorphic renderer for fancy-cms — the Stages document model, PageOp op-spine, the JS style→CSS emitter (one half of the dual-emitter pair with the PHP particle-academy/fancy-cms), and the React renderer. Built on the Fancy UI suite.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|