@particle-academy/fancy-cms-ui 0.2.0 → 0.3.1

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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as Canvas, a as CanvasProps, E as Editor, b as EditorAction, c as EditorApi, d as EditorProps, e as EditorState, I as Inspector, f as InspectorProps, L as LayersPanel, g as LayersPanelProps, i as editorReduce, j as initEditor, u as useEditor } from './useEditor-CVT8sTum.cjs';
1
+ export { C as Canvas, a as CanvasProps, E as Editor, b as EditorAction, c as EditorApi, d as EditorProps, e as EditorState, I as Inspector, f as InspectorProps, L as LayersPanel, g as LayersPanelProps, i as editorReduce, j as initEditor, u as useEditor } from './useEditor-BQtAHLHl.cjs';
2
2
  import { ReactNode, ReactElement } from 'react';
3
3
  import { P as PageDoc, h as ElementRegistry, g as DataContext, N as Node, p as StyleProps, L as LayoutMode } from './registry-D5y5IgCR.cjs';
4
4
 
package/dist/editor.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { C as Canvas, a as CanvasProps, E as Editor, b as EditorAction, c as EditorApi, d as EditorProps, e as EditorState, I as Inspector, f as InspectorProps, L as LayersPanel, g as LayersPanelProps, i as editorReduce, j as initEditor, u as useEditor } from './useEditor-CV5jFAgo.js';
1
+ export { C as Canvas, a as CanvasProps, E as Editor, b as EditorAction, c as EditorApi, d as EditorProps, e as EditorState, I as Inspector, f as InspectorProps, L as LayersPanel, g as LayersPanelProps, i as editorReduce, j as initEditor, u as useEditor } from './useEditor-CpX-LbfH.js';
2
2
  import { ReactNode, ReactElement } from 'react';
3
3
  import { P as PageDoc, h as ElementRegistry, g as DataContext, N as Node, p as StyleProps, L as LayoutMode } from './registry-D5y5IgCR.js';
4
4
 
package/dist/editor.js CHANGED
@@ -1,11 +1,11 @@
1
- import { useEditor, useLatestRef, keyBetween } from './chunk-XQ3KHMBJ.js';
2
- export { Canvas, Editor, Inspector, LayersPanel, editorReduce, initEditor, useEditor } from './chunk-XQ3KHMBJ.js';
1
+ import { useEditor, useLatestRef, CONTAINER_TYPES, keyBetween, ADD_DEFAULTS, ADD_MENU } from './chunk-6Q7DKNDZ.js';
2
+ export { Canvas, Editor, Inspector, LayersPanel, editorReduce, initEditor, useEditor } from './chunk-6Q7DKNDZ.js';
3
3
  import { isBinding, childrenOf, CmsPage, defaultRegistry } from './chunk-GOXVGEKU.js';
4
4
  import { useState, useRef, useEffect, useCallback, useLayoutEffect } from 'react';
5
5
  import { ContextMenu } from '@particle-academy/react-fancy';
6
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
7
 
8
- var CONTAINER_TYPES = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape", "card", "device"]);
8
+ var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape", "card", "device"]);
9
9
  function NodeInspector({
10
10
  node,
11
11
  transform,
@@ -30,11 +30,11 @@ function NodeInspector({
30
30
  /* @__PURE__ */ jsx("span", { style: { fontSize: 10, opacity: 0.5, fontFamily: "ui-monospace, monospace", overflow: "hidden", textOverflow: "ellipsis" }, children: node.id })
31
31
  ] }),
32
32
  /* @__PURE__ */ jsx("span", { style: { flex: 1 } }),
33
- /* @__PURE__ */ jsx("button", { type: "button", style: { ...iconBtn, color: "#fca5a5" }, title: "Delete element", onClick: onRemove, children: "\u{1F5D1}" }),
33
+ /* @__PURE__ */ jsx("button", { type: "button", style: { ...iconBtn, color: "var(--fcms-danger, #fca5a5)" }, title: "Delete element", onClick: onRemove, children: "\u{1F5D1}" }),
34
34
  /* @__PURE__ */ jsx("button", { type: "button", style: iconBtn, title: "Close", onClick: onClose, children: "\u2715" })
35
35
  ] }),
36
36
  /* @__PURE__ */ jsxs("div", { style: body, children: [
37
- "content" in node.props || node.type === "richtext" ? /* @__PURE__ */ jsxs("p", { style: { fontSize: 11, color: "var(--fg-3, #94a3b8)", margin: "0 0 12px", lineHeight: 1.45, paddingBottom: 12, borderBottom: "1px solid #1e293b" }, children: [
37
+ "content" in node.props || node.type === "richtext" ? /* @__PURE__ */ jsxs("p", { style: { fontSize: 11, color: "var(--fcms-muted, #94a3b8)", margin: "0 0 12px", lineHeight: 1.45, paddingBottom: 12, borderBottom: "1px solid var(--fcms-border, #1e293b)" }, children: [
38
38
  "\u270E Edit the text ",
39
39
  /* @__PURE__ */ jsx("strong", { children: "directly on the page" }),
40
40
  " \u2014 click in and type. This panel is for layout, style, and bindings."
@@ -59,7 +59,7 @@ function NodeInspector({
59
59
  /* @__PURE__ */ jsx("button", { type: "button", style: { ...miniBtn, alignSelf: "end" }, onClick: () => onTransform({}), title: "Clear transform", children: "Reset" })
60
60
  ] })
61
61
  ] }),
62
- !CONTAINER_TYPES.has(node.type) ? /* @__PURE__ */ jsxs(Group, { label: "Text", children: [
62
+ !CONTAINER_TYPES2.has(node.type) ? /* @__PURE__ */ jsxs(Group, { label: "Text", children: [
63
63
  /* @__PURE__ */ jsxs(Row, { children: [
64
64
  /* @__PURE__ */ jsx(Color, { label: "Color", value: base.color ?? "#0f172a", onChange: (v) => onStyle({ color: v }) }),
65
65
  /* @__PURE__ */ jsx(Num, { label: "Size", value: base.fontSize?.value, placeholder: "16", onChange: (v) => onStyle({ fontSize: v == null ? void 0 : len(v) }) })
@@ -96,7 +96,7 @@ function NodeInspector({
96
96
  ] }),
97
97
  /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Txt, { label: "Border", value: base.border ?? "", placeholder: "1px solid #e2e8f0", onChange: (v) => onStyle({ border: v || void 0 }) }) })
98
98
  ] }),
99
- CONTAINER_TYPES.has(node.type) ? /* @__PURE__ */ jsxs(Group, { label: "Layout", children: [
99
+ CONTAINER_TYPES2.has(node.type) ? /* @__PURE__ */ jsxs(Group, { label: "Layout", children: [
100
100
  /* @__PURE__ */ jsxs(Row, { children: [
101
101
  /* @__PURE__ */ jsx(
102
102
  Sel,
@@ -134,7 +134,7 @@ function NodeInspector({
134
134
  ] });
135
135
  }
136
136
  function Group({ label, children }) {
137
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, paddingBottom: 12, marginBottom: 12, borderBottom: "1px solid #1e293b" }, children: [
137
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8, paddingBottom: 12, marginBottom: 12, borderBottom: "1px solid var(--fcms-border, #1e293b)" }, children: [
138
138
  /* @__PURE__ */ jsx("span", { style: { fontSize: 10, letterSpacing: "0.06em", textTransform: "uppercase", opacity: 0.5 }, children: label }),
139
139
  children
140
140
  ] });
@@ -150,7 +150,7 @@ function PropField({ name, value, onChange }) {
150
150
  type: "button",
151
151
  title: bound ? "Unbind (use a literal value)" : "Bind to data (e.g. item.name)",
152
152
  onClick: () => onChange(bound ? "" : { $bind: "" }),
153
- style: { background: "none", border: "none", cursor: "pointer", padding: 0, fontSize: 11, color: bound ? "#a78bfa" : "#64748b" },
153
+ style: { background: "none", border: "none", cursor: "pointer", padding: 0, fontSize: 11, color: bound ? "var(--fcms-accent, #a78bfa)" : "var(--fcms-muted, #64748b)" },
154
154
  children: "\u{1F517}"
155
155
  }
156
156
  );
@@ -161,7 +161,7 @@ function PropField({ name, value, onChange }) {
161
161
  " ",
162
162
  link
163
163
  ] }),
164
- /* @__PURE__ */ jsx("input", { style: { ...input, borderColor: "#7c3aed" }, placeholder: "data path \xB7 e.g. item.name", value: value.$bind, onChange: (e) => onChange({ $bind: e.target.value }) })
164
+ /* @__PURE__ */ jsx("input", { style: { ...input, borderColor: "var(--fcms-accent, #7c3aed)" }, placeholder: "data path \xB7 e.g. item.name", value: value.$bind, onChange: (e) => onChange({ $bind: e.target.value }) })
165
165
  ] });
166
166
  }
167
167
  if (typeof value === "boolean") {
@@ -248,7 +248,7 @@ var panel = {
248
248
  fontFamily: "system-ui, sans-serif",
249
249
  overflow: "hidden"
250
250
  };
251
- var headRow = { display: "flex", alignItems: "center", gap: 8, padding: "10px 12px", borderBottom: "1px solid #1e293b" };
251
+ var headRow = { display: "flex", alignItems: "center", gap: 8, padding: "10px 12px", borderBottom: "1px solid var(--fcms-border, #1e293b)" };
252
252
  var body = { padding: 12, overflowY: "auto" };
253
253
  var field = { display: "flex", flexDirection: "column", gap: 4, flex: 1, minWidth: 0 };
254
254
  var fieldLabel = { fontSize: 10, opacity: 0.6 };
@@ -479,7 +479,7 @@ function EditablePage({
479
479
  const addNode = useCallback(
480
480
  (kind) => {
481
481
  const doc2 = ed.state.doc;
482
- const parent = selNode ? CONTAINER_TYPES2.has(selNode.type) ? selNode.id : selNode.parent : doc2.sections[doc2.sections.length - 1] ?? null;
482
+ const parent = selNode ? CONTAINER_TYPES.has(selNode.type) ? selNode.id : selNode.parent : doc2.sections[doc2.sections.length - 1] ?? null;
483
483
  const siblings = childrenOf(doc2, parent);
484
484
  const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
485
485
  const id = `n${doc2.seq + 1}-${Math.floor(performance.now())}`;
@@ -493,7 +493,7 @@ function EditablePage({
493
493
  (kind, targetId) => {
494
494
  const doc2 = ed.state.doc;
495
495
  const target = targetId ? doc2.nodes[targetId] : null;
496
- const parent = target ? CONTAINER_TYPES2.has(target.type) ? target.id : target.parent : doc2.sections[doc2.sections.length - 1] ?? null;
496
+ const parent = target ? CONTAINER_TYPES.has(target.type) ? target.id : target.parent : doc2.sections[doc2.sections.length - 1] ?? null;
497
497
  const siblings = childrenOf(doc2, parent);
498
498
  const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
499
499
  const id = `n${doc2.seq + 1}-${Math.floor(performance.now())}`;
@@ -526,7 +526,7 @@ function EditablePage({
526
526
  const node = ed.state.doc.nodes[id];
527
527
  const r = el.getBoundingClientRect();
528
528
  const rect = { x: r.left, y: r.top, w: r.width, h: r.height };
529
- if (node && CONTAINER_TYPES2.has(node.type)) return { id, edge: "inside", rect };
529
+ if (node && CONTAINER_TYPES.has(node.type)) return { id, edge: "inside", rect };
530
530
  return { id, edge: clientY < r.top + r.height / 2 ? "before" : "after", rect };
531
531
  };
532
532
  const onPageDragOver = (e) => {
@@ -582,7 +582,7 @@ function EditablePage({
582
582
  if (id) clip.current = snapshotSubtree(ed.state.doc, id);
583
583
  };
584
584
  const paste = (target) => {
585
- if (clip.current) runOps(pasteOps(ed.state.doc, clip.current, target, CONTAINER_TYPES2));
585
+ if (clip.current) runOps(pasteOps(ed.state.doc, clip.current, target, CONTAINER_TYPES));
586
586
  };
587
587
  const startEditText = (id) => {
588
588
  if (!id) return;
@@ -654,7 +654,7 @@ function EditablePage({
654
654
  {
655
655
  node: selNode ?? null,
656
656
  hasClipboard: Boolean(clip.current),
657
- isContainer: selNode ? CONTAINER_TYPES2.has(selNode.type) : false,
657
+ isContainer: selNode ? CONTAINER_TYPES.has(selNode.type) : false,
658
658
  onEditText: () => startEditText(selection),
659
659
  onAdd: addNode,
660
660
  onDuplicate: () => duplicate(selection),
@@ -717,7 +717,7 @@ function DropIndicator({
717
717
  }) {
718
718
  const r = hint.rect;
719
719
  if (!r) return null;
720
- const color = "#ec4899";
720
+ const color = "var(--fcms-drop, #ec4899)";
721
721
  if (hint.edge === "inside") {
722
722
  return /* @__PURE__ */ jsx("div", { style: { position: "fixed", left: r.x, top: r.y, width: r.w, height: r.h, outline: `2px dashed ${color}`, outlineOffset: -2, borderRadius: 6, pointerEvents: "none", zIndex: Z2 + 4 } });
723
723
  }
@@ -736,9 +736,9 @@ function ElementPalette({ open, onDragChange }) {
736
736
  width: 216,
737
737
  transform: open ? "translateX(0)" : "translateX(100%)",
738
738
  transition: "transform 0.18s ease",
739
- background: "#0b1220",
740
- color: "#e2e8f0",
741
- borderLeft: "1px solid #1e293b",
739
+ background: "var(--fcms-bg, #0b1220)",
740
+ color: "var(--fcms-fg, #e2e8f0)",
741
+ borderLeft: "1px solid var(--fcms-border, #1e293b)",
742
742
  borderTopLeftRadius: 12,
743
743
  borderBottomLeftRadius: 12,
744
744
  boxShadow: "-18px 0 48px -20px rgba(0,0,0,0.6)",
@@ -768,8 +768,8 @@ function ElementPalette({ open, onDragChange }) {
768
768
  gap: 4,
769
769
  height: 56,
770
770
  borderRadius: 8,
771
- background: "#0f172a",
772
- border: "1px solid #1e293b",
771
+ background: "var(--fcms-canvas, #0f172a)",
772
+ border: "1px solid var(--fcms-border, #1e293b)",
773
773
  cursor: "grab",
774
774
  fontSize: 12,
775
775
  userSelect: "none"
@@ -786,23 +786,6 @@ function ElementPalette({ open, onDragChange }) {
786
786
  }
787
787
  );
788
788
  }
789
- var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape", "card", "device", "repeater"]);
790
- var ADD_DEFAULTS = {
791
- text: { type: "text", props: { content: "New text" }, style: { color: "inherit" } },
792
- heading: { type: "heading", props: { content: "New heading" }, style: { fontSize: { value: 28, unit: "px" }, fontWeight: 700 } },
793
- button: { type: "button", props: { label: "Button", href: "#", variant: "primary" }, style: {} },
794
- link: { type: "link", props: { content: "link text", href: "#" }, style: { color: "#7c3aed" } },
795
- image: { type: "image", props: { src: "", alt: "" }, style: {} },
796
- box: { type: "frame", props: {}, style: { padding: { value: 16, unit: "px" } } },
797
- stack: { type: "stack", props: {}, style: { gap: { value: 12, unit: "px" } }, layout: "stack" },
798
- grid: { type: "grid", props: {}, style: { gap: { value: 12, unit: "px" } }, layout: "grid" },
799
- card: { type: "card", props: {}, style: { padding: { value: 16, unit: "px" }, radius: { value: 12, unit: "px" }, border: "1px solid #e2e8f0" } },
800
- callout: { type: "callout", props: { content: "Heads up \u2014 this is a callout.", variant: "info" }, style: {} },
801
- divider: { type: "divider", props: {}, style: {} },
802
- code: { type: "code", props: { content: "npm install @particle-academy/react-fancy", lang: "bash" }, style: {} },
803
- richtext: { type: "richtext", props: { html: "<p>Rich <strong>text</strong> with <em>inline</em> formatting.</p>" }, style: {} },
804
- repeater: { type: "repeater", props: { items: "" }, style: { gap: { value: 12, unit: "px" } }, layout: "stack" }
805
- };
806
789
  var GRIPS = [
807
790
  { key: "nw", north: true, west: true, cursor: "nwse-resize" },
808
791
  { key: "n", north: true, cursor: "ns-resize" },
@@ -913,7 +896,7 @@ function SelectionOverlay({
913
896
  top: box.y - 1,
914
897
  width: box.w + 2,
915
898
  height: box.h + 2,
916
- outline: "2px solid #8b5cf6",
899
+ outline: "2px solid var(--fcms-accent, #8b5cf6)",
917
900
  borderRadius: 4,
918
901
  pointerEvents: "none",
919
902
  zIndex: Z2
@@ -923,7 +906,7 @@ function SelectionOverlay({
923
906
  width: 12,
924
907
  height: 12,
925
908
  background: "#fff",
926
- border: "2px solid #8b5cf6",
909
+ border: "2px solid var(--fcms-accent, #8b5cf6)",
927
910
  borderRadius: 3,
928
911
  zIndex: Z2 + 1,
929
912
  touchAction: "none",
@@ -1000,22 +983,6 @@ function FloatingToolbar({
1000
983
  ] })
1001
984
  ] });
1002
985
  }
1003
- var ADD_MENU = [
1004
- { kind: "heading", label: "Heading" },
1005
- { kind: "text", label: "Text" },
1006
- { kind: "button", label: "Button" },
1007
- { kind: "link", label: "Link" },
1008
- { kind: "image", label: "Image" },
1009
- { kind: "card", label: "Card" },
1010
- { kind: "callout", label: "Callout" },
1011
- { kind: "stack", label: "Stack" },
1012
- { kind: "grid", label: "Grid" },
1013
- { kind: "box", label: "Box" },
1014
- { kind: "divider", label: "Divider" },
1015
- { kind: "code", label: "Code" },
1016
- { kind: "richtext", label: "Rich text" },
1017
- { kind: "repeater", label: "Repeater" }
1018
- ];
1019
986
  function EditBar({
1020
987
  editing,
1021
988
  onToggle,