UNPKG

alinea

Version:
95 lines (93 loc) 3.38 kB
import "../../../chunks/chunk-NZLE2WMY.js"; // src/dashboard/view/diff/RichTextDiff.tsx import { BlockNode, Node } from "alinea/core/TextDoc"; import { Sink } from "alinea/ui/Sink"; import { useMemo } from "react"; import { ChangeBox } from "./ChangeBox.js"; import { diffList, diffRecord } from "./DiffUtils.js"; import { ScalarDiff } from "./ScalarDiff.js"; import { jsx } from "react/jsx-runtime"; var blockTypes = /* @__PURE__ */ new Set(["heading", "paragraph", "listItem"]); function contentToString({ _type: type, content }) { const withNewLine = blockTypes.has(type); if (!content || !Array.isArray(content)) return ""; return content.map((block) => { if (Node.isText(block)) return `${block.text} `; return contentToString(block); }).join("") + (withNewLine ? "\n\n" : ""); } function textDocParts(textDoc) { const parts = []; let text = ""; if (!Array.isArray(textDoc)) return parts; for (const block of textDoc) { if (Node.isText(block)) { text += `${block.text} `; } else if (Node.isElement(block)) { text += contentToString(block); } else if (Node.isBlock(block)) { if (text) { parts.push({ type: "text", text }); text = ""; } parts.push({ type: "block", block }); } } if (text) parts.push({ type: "text", text }); return parts; } function RichTextDiff({ FieldsDiff, shape, valueA, valueB }) { const parts = useMemo(() => { return { a: textDocParts(valueA), b: textDocParts(valueB) }; }, [valueA, valueB]); const length = Math.max(parts.a.length, parts.b.length); const res = []; const equals = (partA, partB) => { if (partA.type !== partA.type) return false; if (partA.type === "block" && partB.type === "block") return partA.block[BlockNode.id] === partB.block[BlockNode.id]; return true; }; const changes = diffList(parts.a, parts.b, equals); return /* @__PURE__ */ jsx(Sink.Root, { children: changes.map((change, i) => { switch (change.value.type) { case "block": { const name = change.value.block[Node.type]; const kind = shape.blocks?.[name]; const compare = change.type === "keep" ? [ "block" in change.old && change.old.block || {}, change.value.block ] : change.type === "removal" ? [change.value.block, {}] : [{}, change.value.block]; const changes2 = diffRecord( kind, compare[0], compare[1] ); if (changes2.length === 0) return /* @__PURE__ */ jsx(ChangeBox, { change: "equal" }, i); return /* @__PURE__ */ jsx(ChangeBox, { change: change.type, children: /* @__PURE__ */ jsx( FieldsDiff, { changes: changes2, targetA: compare[0], targetB: compare[1] } ) }, i); } case "text": { const compare = change.type === "keep" ? ["text" in change.old && change.old.text, change.value.text] : change.type === "removal" ? [change.value.text, ""] : ["", change.value.text]; if (compare[0] === compare[1]) return /* @__PURE__ */ jsx(ChangeBox, { change: "equal" }, i); return /* @__PURE__ */ jsx(ChangeBox, { change: change.type, children: /* @__PURE__ */ jsx(ScalarDiff, { valueA: compare[0], valueB: compare[1] }) }, i); } } }) }); } export { RichTextDiff };