@particle-academy/fancy-cms-ui 0.0.1-dev.9 → 0.1.0

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/index.cjs CHANGED
@@ -1,5 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+
3
6
  // src/document/types.ts
4
7
  function isBinding(v) {
5
8
  return typeof v === "object" && v !== null && typeof v.$bind === "string";
@@ -401,16 +404,521 @@ ${inner}
401
404
  }
402
405
  return blocks.join("\n\n") + (blocks.length ? "\n" : "");
403
406
  }
407
+ function getPath(data, path) {
408
+ return path.split(".").reduce((o, k) => o == null ? void 0 : o[k], data);
409
+ }
410
+ function resolveValue(v, data) {
411
+ if (v === void 0 || v === null) return v;
412
+ if (isBinding(v)) return getPath(data, v.$bind);
413
+ return v;
414
+ }
415
+ var defaultRegistry = {
416
+ section: ({ children }) => children,
417
+ stack: ({ children }) => children,
418
+ grid: ({ children }) => children,
419
+ frame: ({ children }) => children,
420
+ shape: ({ children }) => children,
421
+ card: ({ children }) => children,
422
+ text: ({ node, text }) => text(node.props.content),
423
+ heading: ({ node, text }) => text(node.props.content) || "Heading",
424
+ // Rich text — inline-formatted HTML (gradient spans, links, <code>, …) that
425
+ // plain `text` can't express. The author owns the markup (it's their content).
426
+ richtext: ({ node, text }) => /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: text(node.props.html) } }),
427
+ link: ({ node, text }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href: text(node.props.href) || "#", style: { color: "inherit", textDecoration: "underline" }, children: text(node.props.content) || "link" }),
428
+ divider: () => /* @__PURE__ */ jsxRuntime.jsx("hr", { style: { border: "none", borderTop: "1px solid #e2e8f0", margin: 0 } }),
429
+ callout: ({ node, text }) => {
430
+ const tone = { info: "#3b82f6", success: "#10b981", warning: "#f59e0b", danger: "#ef4444" }[text(node.props.variant)] ?? "#3b82f6";
431
+ 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: text(node.props.content) || "Callout" }) });
432
+ },
433
+ code: ({ node, text }) => /* @__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: text(node.props.content) }) }),
434
+ button: ({ node, text }) => {
435
+ const label2 = text(node.props.label) || text(node.props.content) || "Button";
436
+ const variant = text(node.props.variant) || "primary";
437
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cms-button": variant, style: buttonStyle(variant), children: label2 });
438
+ },
439
+ image: ({ node, text }) => /* @__PURE__ */ jsxRuntime.jsx(
440
+ "img",
441
+ {
442
+ src: text(node.props.src),
443
+ alt: text(node.props.alt),
444
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
445
+ }
446
+ )
447
+ };
448
+ function buttonStyle(variant) {
449
+ const base = {
450
+ display: "inline-flex",
451
+ alignItems: "center",
452
+ gap: 6,
453
+ padding: "9px 16px",
454
+ borderRadius: 8,
455
+ fontWeight: 600,
456
+ fontSize: 14,
457
+ lineHeight: 1,
458
+ cursor: "pointer",
459
+ userSelect: "none"
460
+ };
461
+ if (variant === "ghost") return { ...base, background: "transparent", color: "inherit", border: "1px solid currentColor" };
462
+ if (variant === "outline") return { ...base, background: "transparent", color: "#7c3aed", border: "1px solid #7c3aed" };
463
+ return { ...base, background: "#7c3aed", color: "#fff", border: "1px solid #7c3aed" };
464
+ }
465
+ function RenderNode({ doc, id, registry = defaultRegistry, data }) {
466
+ const node = doc.nodes[id];
467
+ if (!node) return null;
468
+ if (node.type === "repeater") {
469
+ const arr = resolveValue(node.props.items, data);
470
+ const items = Array.isArray(arr) ? arr : [];
471
+ const template = childrenOf(doc, id)[0];
472
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cms": node.id, className: node.className, children: template ? items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(RenderNode, { doc, id: template.id, registry, data: { ...data, item, index } }, index)) : null });
473
+ }
474
+ const kids = childrenOf(doc, id).map((child) => /* @__PURE__ */ jsxRuntime.jsx(RenderNode, { doc, id: child.id, registry, data }, child.id));
475
+ const resolve = (v) => resolveValue(v, data);
476
+ const text = (v) => {
477
+ const r = resolve(v);
478
+ return r === void 0 || r === null ? "" : String(r);
479
+ };
480
+ const renderer = registry[node.type];
481
+ const inner = renderer ? renderer({ node, doc, children: kids, data, resolve, text }) : node.island ? null : kids;
482
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cms": node.id, "data-cms-island": node.island ? node.type : void 0, className: node.className, children: inner });
483
+ }
484
+ function CmsPage({
485
+ doc,
486
+ registry = defaultRegistry,
487
+ data,
488
+ includeStyles = true
489
+ }) {
490
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
491
+ includeStyles ? /* @__PURE__ */ jsxRuntime.jsx("style", { "data-cms-styles": "", children: emitDocCss(doc) }) : null,
492
+ doc.sections.map((id) => /* @__PURE__ */ jsxRuntime.jsx(RenderNode, { doc, id, registry, data }, id))
493
+ ] });
494
+ }
495
+ function CmsRegion({
496
+ doc,
497
+ root,
498
+ registry = defaultRegistry,
499
+ includeStyles = true
500
+ }) {
501
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
502
+ includeStyles ? /* @__PURE__ */ jsxRuntime.jsx("style", { "data-cms-styles": "", children: emitDocCss(doc) }) : null,
503
+ /* @__PURE__ */ jsxRuntime.jsx(RenderNode, { doc, id: root, registry })
504
+ ] });
505
+ }
506
+ function initEditor(doc) {
507
+ return { doc, past: [], future: [], selection: null };
508
+ }
509
+ function editorReduce(state, action) {
510
+ switch (action.type) {
511
+ case "apply": {
512
+ const next = reduce(state.doc, action.op);
513
+ if (next === state.doc) return state;
514
+ return {
515
+ ...state,
516
+ doc: next,
517
+ past: [...state.past, state.doc].slice(-100),
518
+ future: []
519
+ };
520
+ }
521
+ case "undo": {
522
+ if (state.past.length === 0) return state;
523
+ const prev = state.past[state.past.length - 1];
524
+ return {
525
+ ...state,
526
+ doc: prev,
527
+ past: state.past.slice(0, -1),
528
+ future: [state.doc, ...state.future]
529
+ };
530
+ }
531
+ case "redo": {
532
+ if (state.future.length === 0) return state;
533
+ const next = state.future[0];
534
+ return {
535
+ ...state,
536
+ doc: next,
537
+ past: [...state.past, state.doc],
538
+ future: state.future.slice(1)
539
+ };
540
+ }
541
+ case "select":
542
+ return state.selection === action.id ? state : { ...state, selection: action.id };
543
+ case "replace":
544
+ return state.doc === action.doc ? state : { ...state, doc: action.doc, future: [] };
545
+ default:
546
+ return state;
547
+ }
548
+ }
549
+
550
+ // src/editor/useEditor.ts
551
+ function useEditor(initialDoc) {
552
+ const [state, dispatch] = react.useReducer(editorReduce, initialDoc, initEditor);
553
+ const apply = react.useCallback((op) => dispatch({ type: "apply", op }), []);
554
+ const undo = react.useCallback(() => dispatch({ type: "undo" }), []);
555
+ const redo = react.useCallback(() => dispatch({ type: "redo" }), []);
556
+ const select = react.useCallback((id) => dispatch({ type: "select", id }), []);
557
+ const replace = react.useCallback((doc) => dispatch({ type: "replace", doc }), []);
558
+ return react.useMemo(
559
+ () => ({
560
+ state,
561
+ apply,
562
+ undo,
563
+ redo,
564
+ select,
565
+ replace,
566
+ canUndo: state.past.length > 0,
567
+ canRedo: state.future.length > 0
568
+ }),
569
+ [state, apply, undo, redo, select, replace]
570
+ );
571
+ }
572
+ function Canvas({ doc, selection, onSelect, apply }) {
573
+ const ref = react.useRef(null);
574
+ const [box, setBox] = react.useState(null);
575
+ const drag = react.useRef(null);
576
+ react.useLayoutEffect(() => {
577
+ const root = ref.current;
578
+ if (!root || !selection) {
579
+ setBox(null);
580
+ return;
581
+ }
582
+ const el = root.querySelector(`[data-cms="${cssEscape(selection)}"]`);
583
+ if (!el) {
584
+ setBox(null);
585
+ return;
586
+ }
587
+ const r = el.getBoundingClientRect();
588
+ const rootRect = root.getBoundingClientRect();
589
+ setBox({
590
+ x: r.left - rootRect.left + root.scrollLeft,
591
+ y: r.top - rootRect.top + root.scrollTop,
592
+ w: r.width,
593
+ h: r.height
594
+ });
595
+ }, [selection, doc]);
596
+ const handleClick = (e) => {
597
+ const target = e.target.closest("[data-cms]");
598
+ onSelect(target ? target.getAttribute("data-cms") : null);
599
+ };
600
+ const handlePointerDown = (e) => {
601
+ if (!selection) return;
602
+ const c = doc.nodes[selection]?.constraints?.base;
603
+ const left = c && c.left && typeof c.left === "object" ? c.left.value : 0;
604
+ const top = c && c.top && typeof c.top === "object" ? c.top.value : 0;
605
+ drag.current = { x: e.clientX, y: e.clientY, left, top };
606
+ e.currentTarget.setPointerCapture(e.pointerId);
607
+ e.stopPropagation();
608
+ };
609
+ const handlePointerMove = (e) => {
610
+ const d = drag.current;
611
+ if (!d || !selection) return;
612
+ apply({
613
+ t: "set_constraints",
614
+ id: selection,
615
+ breakpoint: "base",
616
+ patch: {
617
+ left: { value: Math.round(d.left + (e.clientX - d.x)), unit: "px" },
618
+ top: { value: Math.round(d.top + (e.clientY - d.y)), unit: "px" }
619
+ }
620
+ });
621
+ };
622
+ const handlePointerUp = () => {
623
+ drag.current = null;
624
+ };
625
+ const surface = {
626
+ position: "relative",
627
+ overflow: "auto",
628
+ height: "100%",
629
+ background: "#f8fafc"
630
+ };
631
+ const overlay = box ? {
632
+ position: "absolute",
633
+ left: box.x,
634
+ top: box.y,
635
+ width: box.w,
636
+ height: box.h,
637
+ outline: "2px solid #8b5cf6",
638
+ outlineOffset: -1,
639
+ cursor: "move",
640
+ touchAction: "none"
641
+ } : { display: "none" };
642
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, onClick: handleClick, style: surface, children: [
643
+ /* @__PURE__ */ jsxRuntime.jsx(CmsPage, { doc }),
644
+ /* @__PURE__ */ jsxRuntime.jsx(
645
+ "div",
646
+ {
647
+ onPointerDown: handlePointerDown,
648
+ onPointerMove: handlePointerMove,
649
+ onPointerUp: handlePointerUp,
650
+ style: overlay
651
+ }
652
+ )
653
+ ] });
654
+ }
655
+ function cssEscape(value) {
656
+ return value.replace(/["\\]/g, "\\$&");
657
+ }
658
+ var MIME = "application/x-cms-node";
659
+ function isAncestorOrSelf(doc, id, maybeAncestor) {
660
+ for (let cur = id; cur; cur = doc.nodes[cur]?.parent ?? null) {
661
+ if (cur === maybeAncestor) return true;
662
+ }
663
+ return false;
664
+ }
665
+ function LayersPanel({ doc, selection, onSelect, onMove }) {
666
+ const [overId, setOverId] = react.useState(null);
667
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflow: "auto", padding: 8, fontSize: 13, fontFamily: "system-ui, sans-serif" }, children: doc.sections.map((id) => /* @__PURE__ */ jsxRuntime.jsx(LayerRow, { doc, id, depth: 0, selection, onSelect, onMove, overId, setOverId }, id)) });
668
+ }
669
+ function LayerRow({ doc, id, depth, selection, onSelect, onMove, overId, setOverId }) {
670
+ const node = doc.nodes[id];
671
+ if (!node) return null;
672
+ const selected = selection === id;
673
+ const draggable = Boolean(onMove);
674
+ const drop = (e) => {
675
+ e.preventDefault();
676
+ e.stopPropagation();
677
+ setOverId(null);
678
+ if (!onMove) return;
679
+ const dragId = e.dataTransfer.getData(MIME);
680
+ if (!dragId || dragId === id || isAncestorOrSelf(doc, id, dragId)) return;
681
+ const siblings = childrenOf(doc, node.parent);
682
+ const idx = siblings.findIndex((n) => n.id === id);
683
+ const next = siblings[idx + 1];
684
+ onMove(dragId, node.parent, keyBetween(node.order, next ? next.order : null));
685
+ };
686
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
687
+ /* @__PURE__ */ jsxRuntime.jsxs(
688
+ "button",
689
+ {
690
+ type: "button",
691
+ draggable,
692
+ onClick: () => onSelect(id),
693
+ onDragStart: (e) => {
694
+ e.dataTransfer.setData(MIME, id);
695
+ e.dataTransfer.effectAllowed = "move";
696
+ },
697
+ onDragOver: (e) => {
698
+ if (!onMove) return;
699
+ e.preventDefault();
700
+ e.dataTransfer.dropEffect = "move";
701
+ if (overId !== id) setOverId(id);
702
+ },
703
+ onDragLeave: () => overId === id && setOverId(null),
704
+ onDrop: drop,
705
+ style: {
706
+ display: "block",
707
+ width: "100%",
708
+ textAlign: "left",
709
+ border: "none",
710
+ borderRadius: 6,
711
+ cursor: draggable ? "grab" : "pointer",
712
+ padding: "4px 8px",
713
+ paddingLeft: 8 + depth * 14,
714
+ background: selected ? "#ede9fe" : "transparent",
715
+ color: selected ? "#5b21b6" : "#334155",
716
+ font: "inherit",
717
+ boxShadow: overId === id ? "inset 0 -2px 0 0 #8b5cf6" : "none"
718
+ },
719
+ children: [
720
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { opacity: 0.6 }, children: node.type }),
721
+ " \xB7 ",
722
+ id
723
+ ]
724
+ }
725
+ ),
726
+ childrenOf(doc, id).map((child) => /* @__PURE__ */ jsxRuntime.jsx(LayerRow, { doc, id: child.id, depth: depth + 1, selection, onSelect, onMove, overId, setOverId }, child.id))
727
+ ] });
728
+ }
729
+ var label = {
730
+ display: "block",
731
+ fontSize: 11,
732
+ textTransform: "uppercase",
733
+ letterSpacing: "0.04em",
734
+ color: "#94a3b8",
735
+ margin: "10px 0 4px"
736
+ };
737
+ var input = {
738
+ width: "100%",
739
+ boxSizing: "border-box",
740
+ padding: "6px 8px",
741
+ borderRadius: 6,
742
+ border: "1px solid #e2e8f0",
743
+ font: "inherit",
744
+ fontSize: 13
745
+ };
746
+ function Inspector({ doc, selection, apply }) {
747
+ const node = selection ? doc.nodes[selection] : null;
748
+ if (!node) {
749
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: 16, color: "#94a3b8", fontFamily: "system-ui, sans-serif", fontSize: 13 }, children: "Select an element to edit." });
750
+ }
751
+ const s = node.style.base;
752
+ const setStyle = (patch) => apply({ t: "set_style", id: node.id, breakpoint: "base", patch });
753
+ const setProp = (key, value) => apply({ t: "set_props", id: node.id, patch: { [key]: value } });
754
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { overflow: "auto", padding: 16, fontFamily: "system-ui, sans-serif", height: "100%", boxSizing: "border-box" }, children: [
755
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 13, fontWeight: 600, color: "#0f172a" }, children: node.type }),
756
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, color: "#94a3b8", marginBottom: 8 }, children: node.id }),
757
+ node.type === "text" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
758
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Content" }),
759
+ /* @__PURE__ */ jsxRuntime.jsx(
760
+ "textarea",
761
+ {
762
+ style: { ...input, minHeight: 64, resize: "vertical" },
763
+ value: typeof node.props.content === "string" ? node.props.content : "",
764
+ onChange: (e) => setProp("content", e.target.value)
765
+ }
766
+ )
767
+ ] }) : null,
768
+ node.type === "image" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
769
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Source" }),
770
+ /* @__PURE__ */ jsxRuntime.jsx(
771
+ "input",
772
+ {
773
+ style: input,
774
+ value: typeof node.props.src === "string" ? node.props.src : "",
775
+ onChange: (e) => setProp("src", e.target.value)
776
+ }
777
+ )
778
+ ] }) : null,
779
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Background" }),
780
+ /* @__PURE__ */ jsxRuntime.jsx(
781
+ "input",
782
+ {
783
+ style: input,
784
+ placeholder: "#ffffff | gradient | url(\u2026)",
785
+ value: s.background ?? "",
786
+ onChange: (e) => setStyle({ background: e.target.value })
787
+ }
788
+ ),
789
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Text color" }),
790
+ /* @__PURE__ */ jsxRuntime.jsx(
791
+ "input",
792
+ {
793
+ style: input,
794
+ placeholder: "#0f172a",
795
+ value: s.color ?? "",
796
+ onChange: (e) => setStyle({ color: e.target.value })
797
+ }
798
+ ),
799
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Font size (px)" }),
800
+ /* @__PURE__ */ jsxRuntime.jsx(
801
+ "input",
802
+ {
803
+ type: "number",
804
+ style: input,
805
+ value: s.fontSize?.value ?? "",
806
+ onChange: (e) => setStyle({ fontSize: { value: Number(e.target.value) || 0, unit: "px" } })
807
+ }
808
+ ),
809
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Padding (px)" }),
810
+ /* @__PURE__ */ jsxRuntime.jsx(
811
+ "input",
812
+ {
813
+ type: "number",
814
+ style: input,
815
+ value: s.padding?.value ?? "",
816
+ onChange: (e) => setStyle({ padding: { value: Number(e.target.value) || 0, unit: "px" } })
817
+ }
818
+ ),
819
+ /* @__PURE__ */ jsxRuntime.jsx("label", { style: label, children: "Opacity" }),
820
+ /* @__PURE__ */ jsxRuntime.jsx(
821
+ "input",
822
+ {
823
+ type: "number",
824
+ step: "0.1",
825
+ min: "0",
826
+ max: "1",
827
+ style: input,
828
+ value: s.opacity ?? "",
829
+ onChange: (e) => setStyle({ opacity: Number(e.target.value) })
830
+ }
831
+ )
832
+ ] });
833
+ }
834
+ function Editor({ defaultValue, onChange }) {
835
+ const ed = useEditor(defaultValue);
836
+ const first = react.useRef(true);
837
+ react.useEffect(() => {
838
+ if (first.current) {
839
+ first.current = false;
840
+ return;
841
+ }
842
+ onChange?.(ed.state.doc);
843
+ }, [ed.state.doc, onChange]);
844
+ const shell = {
845
+ display: "grid",
846
+ gridTemplateColumns: "220px 1fr 300px",
847
+ height: "100%",
848
+ minHeight: 0,
849
+ background: "#fff",
850
+ color: "#0f172a",
851
+ border: "1px solid #e2e8f0",
852
+ borderRadius: 12,
853
+ overflow: "hidden"
854
+ };
855
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: shell, children: [
856
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { borderRight: "1px solid #e2e8f0", display: "flex", flexDirection: "column", minHeight: 0 }, children: [
857
+ /* @__PURE__ */ jsxRuntime.jsx(Toolbar, { ed }),
858
+ /* @__PURE__ */ jsxRuntime.jsx(
859
+ LayersPanel,
860
+ {
861
+ doc: ed.state.doc,
862
+ selection: ed.state.selection,
863
+ onSelect: ed.select,
864
+ onMove: (id, parent, order) => ed.apply({ t: "move_node", id, parent, order })
865
+ }
866
+ )
867
+ ] }),
868
+ /* @__PURE__ */ jsxRuntime.jsx(Canvas, { doc: ed.state.doc, selection: ed.state.selection, onSelect: ed.select, apply: ed.apply }),
869
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { borderLeft: "1px solid #e2e8f0", minHeight: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(Inspector, { doc: ed.state.doc, selection: ed.state.selection, apply: ed.apply }) })
870
+ ] });
871
+ }
872
+ function Toolbar({ ed }) {
873
+ const btn = {
874
+ font: "inherit",
875
+ fontSize: 12,
876
+ padding: "4px 10px",
877
+ borderRadius: 6,
878
+ border: "1px solid #e2e8f0",
879
+ background: "#fff",
880
+ cursor: "pointer"
881
+ };
882
+ return /* @__PURE__ */ jsxRuntime.jsxs(
883
+ "div",
884
+ {
885
+ style: {
886
+ display: "flex",
887
+ gap: 6,
888
+ padding: 8,
889
+ borderBottom: "1px solid #e2e8f0",
890
+ fontFamily: "system-ui, sans-serif"
891
+ },
892
+ children: [
893
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...btn, opacity: ed.canUndo ? 1 : 0.4 }, disabled: !ed.canUndo, onClick: ed.undo, children: "Undo" }),
894
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", style: { ...btn, opacity: ed.canRedo ? 1 : 0.4 }, disabled: !ed.canRedo, onClick: ed.redo, children: "Redo" })
895
+ ]
896
+ }
897
+ );
898
+ }
404
899
 
900
+ exports.Canvas = Canvas;
901
+ exports.CmsPage = CmsPage;
902
+ exports.CmsRegion = CmsRegion;
405
903
  exports.DEFAULT_BREAKPOINTS = DEFAULT_BREAKPOINTS;
904
+ exports.Editor = Editor;
905
+ exports.Inspector = Inspector;
906
+ exports.LayersPanel = LayersPanel;
907
+ exports.RenderNode = RenderNode;
406
908
  exports.childrenOf = childrenOf;
909
+ exports.defaultRegistry = defaultRegistry;
407
910
  exports.descendantIds = descendantIds;
911
+ exports.editorReduce = editorReduce;
408
912
  exports.emitDocCss = emitDocCss;
409
913
  exports.emptyDoc = emptyDoc;
914
+ exports.getPath = getPath;
915
+ exports.initEditor = initEditor;
410
916
  exports.invert = invert;
411
917
  exports.isBinding = isBinding;
412
918
  exports.keyBetween = keyBetween;
413
919
  exports.reduce = reduce;
414
920
  exports.reduceAll = reduceAll;
921
+ exports.resolveValue = resolveValue;
922
+ exports.useEditor = useEditor;
415
923
  //# sourceMappingURL=index.cjs.map
416
924
  //# sourceMappingURL=index.cjs.map