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)

124 lines (122 loc) 4 kB
import "../chunks/chunk-U5RRZUYZ.js"; // src/ui/RichText.tsx import { slugify } from "alinea/core"; import { Fragment, isValidElement } from "react"; import { Fragment as Fragment2, jsx } from "react/jsx-runtime"; var Elements = /* @__PURE__ */ ((Elements2) => { Elements2["h1"] = "h1"; Elements2["h2"] = "h2"; Elements2["h3"] = "h3"; Elements2["h4"] = "h4"; Elements2["h5"] = "h5"; Elements2["h6"] = "h6"; Elements2["p"] = "p"; Elements2["b"] = "b"; Elements2["i"] = "i"; Elements2["ul"] = "ul"; Elements2["ol"] = "ol"; Elements2["li"] = "li"; Elements2["a"] = "a"; Elements2["hr"] = "hr"; Elements2["br"] = "br"; Elements2["small"] = "small"; return Elements2; })(Elements || {}); function textContent(doc) { return doc.reduce((text, node) => { switch (node.type) { case "text": return text + node.text; default: if ("content" in node && Array.isArray(node.content)) return text + textContent(node.content); return text; } }, ""); } function nodeElement(type, attributes, content) { const style = { textAlign: attributes?.textAlign === "left" ? void 0 : attributes?.textAlign }; switch (type) { case "heading": const Tag = `h${attributes?.level || 1}`; const id = attributes?.id ?? (content ? slugify(textContent(content)) : void 0); return /* @__PURE__ */ jsx(Tag, { style, id }); case "paragraph": return /* @__PURE__ */ jsx("p", { style }); case "bold": return /* @__PURE__ */ jsx("b", {}); case "italic": return /* @__PURE__ */ jsx("i", {}); case "bulletList": return /* @__PURE__ */ jsx("ul", { style }); case "orderedList": return /* @__PURE__ */ jsx("ol", { style }); case "listItem": return /* @__PURE__ */ jsx("li", {}); case "blockquote": return /* @__PURE__ */ jsx("blockquote", { style }); case "horizontalRule": return /* @__PURE__ */ jsx("hr", {}); case "hardBreak": return /* @__PURE__ */ jsx("br", {}); case "small": return /* @__PURE__ */ jsx("small", {}); case "link": return /* @__PURE__ */ jsx("a", { ...attributes }); } } function RichTextNodeView({ views, node }) { switch (node.type) { case "text": { const { text, marks } = node; const content = typeof views.text === "function" ? /* @__PURE__ */ jsx(views.text, { children: text }) : text; const wrappers = marks?.map((mark) => nodeElement(mark.type, mark.attrs)) || []; return wrappers.reduce((children, element) => { if (!element?.type) return /* @__PURE__ */ jsx(Fragment2, { children }); const View = views[element.type]; if (View && !isValidElement(View)) { return /* @__PURE__ */ jsx(View, { ...element.props, children }); } else { const node2 = View ?? element; return /* @__PURE__ */ jsx(node2.type, { ...element?.props, ...node2.props, children }); } }, /* @__PURE__ */ jsx(Fragment2, { children: content })); } default: { const { type, content, ...attrs } = node; const element = nodeElement(type, attrs, content); const View = views[element?.type || type]; const inner = content?.map((node2, i) => /* @__PURE__ */ jsx(RichTextNodeView, { views, node: node2 }, i)) || null; if (View && !isValidElement(View)) { return /* @__PURE__ */ jsx(View, { ...element?.props || attrs, children: inner }); } else { const node2 = View ?? element ?? { type: Fragment }; return /* @__PURE__ */ jsx(node2.type, { ...element?.props, ...node2.props, children: inner }); } } } } function RichText({ doc, ...views }) { if (!Array.isArray(doc)) return null; return /* @__PURE__ */ jsx(Fragment2, { children: doc.map((node, i) => { return /* @__PURE__ */ jsx( RichTextNodeView, { views, node }, i ); }) }); } export { Elements, RichText };