@particle-academy/fancy-cms-ui 0.0.1-dev.12 → 0.0.1-dev.13
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/{chunk-ZV7CV54P.js → chunk-E5AAQX7P.js} +10 -2
- package/dist/chunk-E5AAQX7P.js.map +1 -0
- package/dist/editor.cjs +29 -7
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.js +22 -8
- package/dist/editor.js.map +1 -1
- package/dist/react.cjs +8 -0
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-ZV7CV54P.js.map +0 -1
|
@@ -13,8 +13,16 @@ var defaultRegistry = {
|
|
|
13
13
|
grid: ({ children }) => children,
|
|
14
14
|
frame: ({ children }) => children,
|
|
15
15
|
shape: ({ children }) => children,
|
|
16
|
+
card: ({ children }) => children,
|
|
16
17
|
text: ({ node }) => literal(node.props.content),
|
|
17
18
|
heading: ({ node }) => literal(node.props.content) || "Heading",
|
|
19
|
+
link: ({ node }) => /* @__PURE__ */ jsx("a", { href: literal(node.props.href) || "#", style: { color: "inherit", textDecoration: "underline" }, children: literal(node.props.content) || "link" }),
|
|
20
|
+
divider: () => /* @__PURE__ */ jsx("hr", { style: { border: "none", borderTop: "1px solid #e2e8f0", margin: 0 } }),
|
|
21
|
+
callout: ({ node }) => {
|
|
22
|
+
const tone = { info: "#3b82f6", success: "#10b981", warning: "#f59e0b", danger: "#ef4444" }[literal(node.props.variant)] ?? "#3b82f6";
|
|
23
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 10, padding: "12px 14px", borderRadius: 10, background: `${tone}14`, borderLeft: `3px solid ${tone}` }, children: /* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: literal(node.props.content) || "Callout" }) });
|
|
24
|
+
},
|
|
25
|
+
code: ({ node }) => /* @__PURE__ */ jsx("pre", { style: { margin: 0, padding: "12px 14px", borderRadius: 10, background: "#0b1220", color: "#e2e8f0", fontFamily: "ui-monospace, monospace", fontSize: 13, overflowX: "auto" }, children: /* @__PURE__ */ jsx("code", { children: literal(node.props.content) }) }),
|
|
18
26
|
button: ({ node }) => {
|
|
19
27
|
const label = literal(node.props.label) || literal(node.props.content) || "Button";
|
|
20
28
|
const variant = literal(node.props.variant) || "primary";
|
|
@@ -74,5 +82,5 @@ function CmsPage({
|
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
export { CmsPage, RenderNode, defaultRegistry };
|
|
77
|
-
//# sourceMappingURL=chunk-
|
|
78
|
-
//# sourceMappingURL=chunk-
|
|
85
|
+
//# sourceMappingURL=chunk-E5AAQX7P.js.map
|
|
86
|
+
//# sourceMappingURL=chunk-E5AAQX7P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/registry.tsx","../src/react/RenderNode.tsx","../src/react/CmsPage.tsx"],"names":["jsx"],"mappings":"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","file":"chunk-E5AAQX7P.js","sourcesContent":["import type { ReactNode } from \"react\";\nimport { isBinding, type Bound, type Json, type Node, type PageDoc } from \"../document/types\";\n\nexport interface ElementContext {\n node: Node;\n doc: PageDoc;\n /** Pre-rendered child nodes, in order. */\n children: ReactNode;\n}\n\n/**\n * Renders the INNER content of a node. The outer `[data-cms]` wrapper is added\n * by {@link RenderNode}, so a renderer only returns what goes inside.\n */\nexport type ElementRenderer = (ctx: ElementContext) => ReactNode;\n\nexport type ElementRegistry = Record<string, ElementRenderer>;\n\n/** Resolve a literal prop to a string (bindings resolve in Phase 3). */\nfunction literal(v: Bound<Json> | undefined): string {\n if (v === undefined || v === null) return \"\";\n if (isBinding(v)) return \"\";\n return String(v);\n}\n\n/** Built-in native elements. Containers render their children; leaves render content. */\nexport const defaultRegistry: ElementRegistry = {\n section: ({ children }) => children,\n stack: ({ children }) => children,\n grid: ({ children }) => children,\n frame: ({ children }) => children,\n shape: ({ children }) => children,\n card: ({ children }) => children,\n text: ({ node }) => literal(node.props.content),\n heading: ({ node }) => literal(node.props.content) || \"Heading\",\n link: ({ node }) => (\n <a href={literal(node.props.href) || \"#\"} style={{ color: \"inherit\", textDecoration: \"underline\" }}>\n {literal(node.props.content) || \"link\"}\n </a>\n ),\n divider: () => <hr style={{ border: \"none\", borderTop: \"1px solid #e2e8f0\", margin: 0 }} />,\n callout: ({ node }) => {\n const tone = ({ info: \"#3b82f6\", success: \"#10b981\", warning: \"#f59e0b\", danger: \"#ef4444\" } as Record<string, string>)[literal(node.props.variant)] ?? \"#3b82f6\";\n return (\n <div style={{ display: \"flex\", gap: 10, padding: \"12px 14px\", borderRadius: 10, background: `${tone}14`, borderLeft: `3px solid ${tone}` }}>\n <span style={{ fontSize: 13 }}>{literal(node.props.content) || \"Callout\"}</span>\n </div>\n );\n },\n code: ({ node }) => (\n <pre style={{ margin: 0, padding: \"12px 14px\", borderRadius: 10, background: \"#0b1220\", color: \"#e2e8f0\", fontFamily: \"ui-monospace, monospace\", fontSize: 13, overflowX: \"auto\" }}>\n <code>{literal(node.props.content)}</code>\n </pre>\n ),\n button: ({ node }) => {\n const label = literal(node.props.label) || literal(node.props.content) || \"Button\";\n const variant = literal(node.props.variant) || \"primary\";\n return <span data-cms-button={variant} style={buttonStyle(variant)}>{label}</span>;\n },\n image: ({ node }) => (\n <img\n src={literal(node.props.src)}\n alt={literal(node.props.alt)}\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\", display: \"block\" }}\n />\n ),\n};\n\n/**\n * A self-contained button look so the `button` primitive renders sensibly with\n * zero host CSS. Hosts that want their own button classes override the `button`\n * renderer in their registry (e.g. the sandbox maps it to `.btn .btn-primary`).\n */\nfunction buttonStyle(variant: string): import(\"react\").CSSProperties {\n const base: import(\"react\").CSSProperties = {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"9px 16px\",\n borderRadius: 8,\n fontWeight: 600,\n fontSize: 14,\n lineHeight: 1,\n cursor: \"pointer\",\n userSelect: \"none\",\n };\n if (variant === \"ghost\") return { ...base, background: \"transparent\", color: \"inherit\", border: \"1px solid currentColor\" };\n if (variant === \"outline\") return { ...base, background: \"transparent\", color: \"#7c3aed\", border: \"1px solid #7c3aed\" };\n return { ...base, background: \"#7c3aed\", color: \"#fff\", border: \"1px solid #7c3aed\" };\n}\n","import type { ReactElement } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport { childrenOf } from \"../document/reduce\";\nimport { defaultRegistry, type ElementRegistry } from \"./registry\";\n\nexport interface RenderNodeProps {\n doc: PageDoc;\n id: string;\n registry?: ElementRegistry;\n}\n\n/**\n * Render one node (and its subtree) to a `[data-cms]`-tagged element. The CSS\n * emitted by `emitDocCss` targets these `data-cms` handles. Interactive /\n * 3rd-party **islands** with no registered renderer become an empty, sized\n * placeholder the host hydrates client-side — mirroring the PHP renderer.\n */\nexport function RenderNode({ doc, id, registry = defaultRegistry }: RenderNodeProps): ReactElement | null {\n const node = doc.nodes[id];\n if (!node) return null;\n\n const kids = childrenOf(doc, id).map((child) => (\n <RenderNode key={child.id} doc={doc} id={child.id} registry={registry} />\n ));\n\n const renderer = registry[node.type];\n const inner = renderer ? renderer({ node, doc, children: kids }) : node.island ? null : kids;\n\n return (\n <div\n data-cms={node.id}\n data-cms-island={node.island ? node.type : undefined}\n className={node.className}\n >\n {inner}\n </div>\n );\n}\n","import { Fragment, type ReactElement } from \"react\";\nimport type { PageDoc } from \"../document/types\";\nimport { emitDocCss } from \"../render/css\";\nimport { RenderNode } from \"./RenderNode\";\nimport { defaultRegistry, type ElementRegistry } from \"./registry\";\n\nexport interface CmsPageProps {\n doc: PageDoc;\n registry?: ElementRegistry;\n /** Inject the compiled stylesheet. Set false when the host emits CSS itself. */\n includeStyles?: boolean;\n}\n\n/** Render a full page document: the compiled stylesheet + every section. */\nexport function CmsPage({\n doc,\n registry = defaultRegistry,\n includeStyles = true,\n}: CmsPageProps): ReactElement {\n return (\n <Fragment>\n {includeStyles ? <style data-cms-styles=\"\">{emitDocCss(doc)}</style> : null}\n {doc.sections.map((id) => (\n <RenderNode key={id} doc={doc} id={id} registry={registry} />\n ))}\n </Fragment>\n );\n}\n"]}
|
package/dist/editor.cjs
CHANGED
|
@@ -372,8 +372,16 @@ var defaultRegistry = {
|
|
|
372
372
|
grid: ({ children }) => children,
|
|
373
373
|
frame: ({ children }) => children,
|
|
374
374
|
shape: ({ children }) => children,
|
|
375
|
+
card: ({ children }) => children,
|
|
375
376
|
text: ({ node }) => literal(node.props.content),
|
|
376
377
|
heading: ({ node }) => literal(node.props.content) || "Heading",
|
|
378
|
+
link: ({ node }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href: literal(node.props.href) || "#", style: { color: "inherit", textDecoration: "underline" }, children: literal(node.props.content) || "link" }),
|
|
379
|
+
divider: () => /* @__PURE__ */ jsxRuntime.jsx("hr", { style: { border: "none", borderTop: "1px solid #e2e8f0", margin: 0 } }),
|
|
380
|
+
callout: ({ node }) => {
|
|
381
|
+
const tone = { info: "#3b82f6", success: "#10b981", warning: "#f59e0b", danger: "#ef4444" }[literal(node.props.variant)] ?? "#3b82f6";
|
|
382
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: 10, padding: "12px 14px", borderRadius: 10, background: `${tone}14`, borderLeft: `3px solid ${tone}` }, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 13 }, children: literal(node.props.content) || "Callout" }) });
|
|
383
|
+
},
|
|
384
|
+
code: ({ node }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { style: { margin: 0, padding: "12px 14px", borderRadius: 10, background: "#0b1220", color: "#e2e8f0", fontFamily: "ui-monospace, monospace", fontSize: 13, overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: literal(node.props.content) }) }),
|
|
377
385
|
button: ({ node }) => {
|
|
378
386
|
const label2 = literal(node.props.label) || literal(node.props.content) || "Button";
|
|
379
387
|
const variant = literal(node.props.variant) || "primary";
|
|
@@ -802,7 +810,7 @@ function Toolbar({ ed }) {
|
|
|
802
810
|
}
|
|
803
811
|
);
|
|
804
812
|
}
|
|
805
|
-
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape"]);
|
|
813
|
+
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape", "card", "device"]);
|
|
806
814
|
function NodeInspector({
|
|
807
815
|
node,
|
|
808
816
|
transform,
|
|
@@ -1250,7 +1258,7 @@ function EditablePage({
|
|
|
1250
1258
|
const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
|
|
1251
1259
|
const id = `n${doc2.seq + 1}-${Math.floor(performance.now())}`;
|
|
1252
1260
|
const def = ADD_DEFAULTS[kind];
|
|
1253
|
-
ed.apply({ t: "insert_node", node: { id, type: def.type, parent, order, props: { ...def.props }, style: { base: { ...def.style } } } });
|
|
1261
|
+
ed.apply({ t: "insert_node", node: { id, type: def.type, parent, order, layout: def.layout, props: { ...def.props }, style: { base: { ...def.style } } } });
|
|
1254
1262
|
ed.select(id);
|
|
1255
1263
|
},
|
|
1256
1264
|
[ed, selNode]
|
|
@@ -1264,7 +1272,7 @@ function EditablePage({
|
|
|
1264
1272
|
const order = keyBetween(siblings.length ? siblings[siblings.length - 1].order : null, null);
|
|
1265
1273
|
const id = `n${doc2.seq + 1}-${Math.floor(performance.now())}`;
|
|
1266
1274
|
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 } } } });
|
|
1275
|
+
ed.apply({ t: "insert_node", node: { id, type: def.type, parent, order, layout: def.layout, props: { ...def.props }, style: { base: { ...def.style } } } });
|
|
1268
1276
|
ed.select(id);
|
|
1269
1277
|
},
|
|
1270
1278
|
[ed]
|
|
@@ -1502,13 +1510,20 @@ function ElementPalette({ open, onDragChange }) {
|
|
|
1502
1510
|
}
|
|
1503
1511
|
);
|
|
1504
1512
|
}
|
|
1505
|
-
var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape"]);
|
|
1513
|
+
var CONTAINER_TYPES2 = /* @__PURE__ */ new Set(["section", "frame", "stack", "grid", "shape", "card", "device"]);
|
|
1506
1514
|
var ADD_DEFAULTS = {
|
|
1507
1515
|
text: { type: "text", props: { content: "New text" }, style: { color: "inherit" } },
|
|
1508
1516
|
heading: { type: "heading", props: { content: "New heading" }, style: { fontSize: { value: 28, unit: "px" }, fontWeight: 700 } },
|
|
1509
1517
|
button: { type: "button", props: { label: "Button", href: "#", variant: "primary" }, style: {} },
|
|
1518
|
+
link: { type: "link", props: { content: "link text", href: "#" }, style: { color: "#7c3aed" } },
|
|
1510
1519
|
image: { type: "image", props: { src: "", alt: "" }, style: {} },
|
|
1511
|
-
box: { type: "frame", props: {}, style: { padding: { value: 16, unit: "px" } } }
|
|
1520
|
+
box: { type: "frame", props: {}, style: { padding: { value: 16, unit: "px" } } },
|
|
1521
|
+
stack: { type: "stack", props: {}, style: { gap: { value: 12, unit: "px" } }, layout: "stack" },
|
|
1522
|
+
grid: { type: "grid", props: {}, style: { gap: { value: 12, unit: "px" } }, layout: "grid" },
|
|
1523
|
+
card: { type: "card", props: {}, style: { padding: { value: 16, unit: "px" }, radius: { value: 12, unit: "px" }, border: "1px solid #e2e8f0" } },
|
|
1524
|
+
callout: { type: "callout", props: { content: "Heads up \u2014 this is a callout.", variant: "info" }, style: {} },
|
|
1525
|
+
divider: { type: "divider", props: {}, style: {} },
|
|
1526
|
+
code: { type: "code", props: { content: "npm install @particle-academy/react-fancy", lang: "bash" }, style: {} }
|
|
1512
1527
|
};
|
|
1513
1528
|
var GRIPS = [
|
|
1514
1529
|
{ key: "nw", north: true, west: true, cursor: "nwse-resize" },
|
|
@@ -1708,11 +1723,18 @@ function FloatingToolbar({
|
|
|
1708
1723
|
] });
|
|
1709
1724
|
}
|
|
1710
1725
|
var ADD_MENU = [
|
|
1711
|
-
{ kind: "text", label: "Text" },
|
|
1712
1726
|
{ kind: "heading", label: "Heading" },
|
|
1727
|
+
{ kind: "text", label: "Text" },
|
|
1713
1728
|
{ kind: "button", label: "Button" },
|
|
1729
|
+
{ kind: "link", label: "Link" },
|
|
1714
1730
|
{ kind: "image", label: "Image" },
|
|
1715
|
-
{ kind: "
|
|
1731
|
+
{ kind: "card", label: "Card" },
|
|
1732
|
+
{ kind: "callout", label: "Callout" },
|
|
1733
|
+
{ kind: "stack", label: "Stack" },
|
|
1734
|
+
{ kind: "grid", label: "Grid" },
|
|
1735
|
+
{ kind: "box", label: "Box" },
|
|
1736
|
+
{ kind: "divider", label: "Divider" },
|
|
1737
|
+
{ kind: "code", label: "Code" }
|
|
1716
1738
|
];
|
|
1717
1739
|
function EditBar({
|
|
1718
1740
|
editing,
|