@particle-academy/fancy-cms-ui 0.0.1-dev.15 → 0.0.1-dev.17

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { keyBetween } from './chunk-7YYLYBLI.js';
2
- import { CmsPage, defaultRegistry } from './chunk-IXPYY4S2.js';
2
+ import { CmsPage, defaultRegistry } from './chunk-KCJWSR7D.js';
3
3
  import { reduce, childrenOf, isBinding } from './chunk-3YZMELJJ.js';
4
4
  import { useReducer, useCallback, useMemo, useRef, useState, useLayoutEffect, Fragment, useEffect } from 'react';
5
5
  import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
@@ -412,7 +412,7 @@ function NodeInspector({
412
412
  }) {
413
413
  const base = node.style.base ?? {};
414
414
  const setT = (patch) => onTransform({ ...transform, ...patch });
415
- const handled = /* @__PURE__ */ new Set(["content", "label"]);
415
+ const handled = /* @__PURE__ */ new Set(["content", "label", "html"]);
416
416
  const extraKeys = Object.keys(node.props).filter(
417
417
  (k) => !handled.has(k) && (["string", "number", "boolean"].includes(typeof node.props[k]) || isBinding(node.props[k]))
418
418
  );
@@ -427,14 +427,11 @@ function NodeInspector({
427
427
  /* @__PURE__ */ jsx("button", { type: "button", style: iconBtn, title: "Close", onClick: onClose, children: "\u2715" })
428
428
  ] }),
429
429
  /* @__PURE__ */ jsxs("div", { style: body, children: [
430
- "content" in node.props ? /* @__PURE__ */ jsx(Group, { label: "Content", children: /* @__PURE__ */ jsx(
431
- "textarea",
432
- {
433
- style: { ...input2, minHeight: 64, resize: "vertical", lineHeight: 1.4 },
434
- value: String(node.props.content ?? ""),
435
- onChange: (e) => onProps({ content: e.target.value })
436
- }
437
- ) }) : null,
430
+ "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: [
431
+ "\u270E Edit the text ",
432
+ /* @__PURE__ */ jsx("strong", { children: "directly on the page" }),
433
+ " \u2014 click in and type. This panel is for layout, style, and bindings."
434
+ ] }) : null,
438
435
  "label" in node.props ? /* @__PURE__ */ jsx(Group, { label: "Label", children: /* @__PURE__ */ jsx("input", { style: input2, value: String(node.props.label ?? ""), onChange: (e) => onProps({ label: e.target.value }) }) }) : null,
439
436
  extraKeys.length ? /* @__PURE__ */ jsx(Group, { label: "Properties", children: extraKeys.map((k) => /* @__PURE__ */ jsx(PropField, { name: k, value: node.props[k], onChange: (v) => onProps({ [k]: v }) }, k)) }) : null,
440
437
  /* @__PURE__ */ jsxs(Group, { label: "Position & size", children: [
@@ -842,13 +839,17 @@ function EditablePage({
842
839
  };
843
840
  }, [measureBox, ed.state.doc]);
844
841
  useEffect(() => {
845
- if (!editing || !selection || !pageRef.current || selNode?.type !== "text") return;
846
- const el = pageRef.current.querySelector(`[data-cms="${cssEscape2(selection)}"]`);
847
- if (!el) return;
842
+ const t = selNode?.type;
843
+ const editable = t === "text" || t === "heading" || t === "richtext";
844
+ if (!editing || !selection || !pageRef.current || !editable) return;
845
+ const wrapper = pageRef.current.querySelector(`[data-cms="${cssEscape2(selection)}"]`);
846
+ if (!wrapper) return;
847
+ const isRich = t === "richtext";
848
+ const el = (isRich ? wrapper.firstElementChild : wrapper) ?? wrapper;
848
849
  el.setAttribute("contenteditable", "true");
849
850
  el.style.outline = "none";
850
851
  el.focus();
851
- const commit = () => ed.apply({ t: "set_props", id: selection, patch: { content: el.innerText } });
852
+ const commit = () => ed.apply({ t: "set_props", id: selection, patch: isRich ? { html: el.innerHTML } : { content: el.innerText } });
852
853
  el.addEventListener("blur", commit);
853
854
  return () => {
854
855
  el.removeEventListener("blur", commit);
@@ -1189,6 +1190,7 @@ var ADD_DEFAULTS = {
1189
1190
  callout: { type: "callout", props: { content: "Heads up \u2014 this is a callout.", variant: "info" }, style: {} },
1190
1191
  divider: { type: "divider", props: {}, style: {} },
1191
1192
  code: { type: "code", props: { content: "npm install @particle-academy/react-fancy", lang: "bash" }, style: {} },
1193
+ richtext: { type: "richtext", props: { html: "<p>Rich <strong>text</strong> with <em>inline</em> formatting.</p>" }, style: {} },
1192
1194
  repeater: { type: "repeater", props: { items: "" }, style: { gap: { value: 12, unit: "px" } }, layout: "stack" }
1193
1195
  };
1194
1196
  var GRIPS = [
@@ -1401,6 +1403,7 @@ var ADD_MENU = [
1401
1403
  { kind: "box", label: "Box" },
1402
1404
  { kind: "divider", label: "Divider" },
1403
1405
  { kind: "code", label: "Code" },
1406
+ { kind: "richtext", label: "Rich text" },
1404
1407
  { kind: "repeater", label: "Repeater" }
1405
1408
  ];
1406
1409
  function EditBar({