UNPKG

alinea

Version:

[![npm](https://img.shields.io/npm/v/alinea.svg)](https://npmjs.org/package/alinea) [![install size](https://packagephobia.com/badge?p=alinea)](https://packagephobia.com/result?p=alinea)

102 lines (100 loc) 3.52 kB
import "../../../chunks/chunk-U5RRZUYZ.js"; // src/dashboard/view/diff/RichTextDiff.tsx import { Sink } from "alinea/ui/Sink"; import { useMemo } from "react"; import { ChangeBox } from "./ChangeBox.js"; import { diffList, diffRecord } from "./DiffUtils.js"; import { FieldsDiff } from "./FieldsDiff.js"; import { ScalarDiff } from "./ScalarDiff.js"; import { jsx } from "react/jsx-runtime"; var blockTypes = /* @__PURE__ */ new Set(["heading", "paragraph", "listItem"]); function contentToString({ type, content }) { const withNewLine = blockTypes.has(type); if (!content || !Array.isArray(content)) return ""; return content.map((block) => { if ("text" in 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) { switch (block.type) { case "text": text += block.text + " "; default: const firstChar = block.type[0]; if (!firstChar) continue; const isCustomBlock = firstChar === firstChar.toUpperCase(); if (isCustomBlock) { if (text) { parts.push({ type: "text", text }); text = ""; } parts.push({ type: "block", block }); } else { text += contentToString(block); } } } if (text) parts.push({ type: "text", text }); return parts; } function RichTextDiff({ 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.id === partB.block.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.type; const kind = shape.values?.[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 };