UNPKG

reactjs-tiptap-editor

Version:

A modern WYSIWYG rich text editor based on tiptap and shadcn ui for React

185 lines (184 loc) 5.04 kB
import { N as b, m as v } from "./index-CXIIg9Sq.js"; import { N as C, c as g, R as N } from "./dom-dataset-2RXYq9wp.js"; import { jsx as l, jsxs as T } from "react/jsx-runtime"; import { useState as p, useCallback as m, useEffect as d } from "react"; import { u as _ } from "./index-D-DR0FPY.js"; import { _ as O, A as y } from "./RichTextEditor-iSPxjLdO.js"; const x = "_toc_aag8a_1", A = "_visible_aag8a_7", w = "_list_aag8a_11", E = "_item_aag8a_16", f = { toc: x, visible: A, list: w, item: E }; function k(t) { const o = [], a = [o]; return t.forEach((n) => { let e = -1, s = a[n.level + e]; for (; !s; ) e -= 1, s = a[n.level + e]; s.push({ ...n, children: a[n.level] = [] }); }), o; } function M({ editor: t }) { const o = O(), [a, n] = p([]), { t: e } = _(), s = m(() => { const i = [], r = t.state.tr; t.state.doc.descendants((c, h) => { if (c.type.name === "heading") { const u = `heading-${i.length + 1}`; c.attrs.id !== u && r.setNodeMarkup(h, void 0, { ...c.attrs, id: u }), i.push({ level: c.attrs.level, text: c.textContent, id: u }); } }), r.setMeta("addToHistory", !1), r.setMeta("preventUpdate", !0), t.view.dispatch(r), n(i), t.eventEmitter && t.eventEmitter.emit("TableOfContents", k(i)); }, [t]); return d(() => { if (t) { if (!t.options.editable) { s(); return; } return t.on("update", s), () => { t.off("update", s); }; } }, [t, s]), d(() => { s(); }, []), /* @__PURE__ */ l(C, { className: g("tableOfContent", f.toc, o && f.visible), children: o ? /* @__PURE__ */ T("div", { style: { position: "relative" }, children: [ /* @__PURE__ */ l("p", { className: "text-[20px] richtext-mb-[8px] richtext-font-semibold", children: e("editor.table_of_content") }), /* @__PURE__ */ l("ul", { className: f.list, children: a.map((i, r) => /* @__PURE__ */ l( "li", { className: f.item, style: { paddingLeft: `${i.level - 1}rem` }, children: /* @__PURE__ */ l("a", { href: `#${i.id}`, children: i.text }) }, `table-of-content-${r}` )) }) ] }) : null }); } function B(t, ...o) { const [a, n] = p(!1); return d(() => { const e = () => { n(t.isActive.apply(t, o)); }; return t.on("selectionUpdate", e), t.on("transaction", e), () => { t.off("selectionUpdate", e), t.off("transaction", e); }; }, [t, o, n]), a; } function H({ editor: t, icon: o, tooltip: a }) { const n = B(t, z.name), e = m(() => { if (n) { t.chain().focus().removeTableOfContents().run(); return; } t.chain().focus().setTableOfContents().run(); }, [t, n]); return /* @__PURE__ */ l( y, { action: e, isActive: () => n || !1, icon: o, tooltip: a } ); } function L(t) { return t && t.type.name === "title"; } function S(t, o) { const n = [t.getJSON()], e = []; for (; n.length > 0; ) { const s = n.shift(); s.type === o && e.push(s), s.content && s.content.length > 0 && n.push(...s.content); } return e; } const z = /* @__PURE__ */ b.create({ name: "tableOfContents", group: "block", atom: !0, addOptions() { var t; return { ...(t = this.parent) == null ? void 0 : t.call(this), onHasOneBeforeInsert: () => { }, resizable: !0, lastColumnResizable: !0, allowTableNodeSelection: !1, button: ({ editor: o, t: a }) => ({ component: H, componentProps: { disabled: !1, icon: "BookMarked", tooltip: a("editor.table_of_content"), editor: o } }) }; }, parseHTML() { return [ { tag: "toc" } ]; }, renderHTML({ HTMLAttributes: t }) { return ["toc", v(t)]; }, addNodeView() { return N(M); }, // @ts-expect-error addCommands() { return { setTableOfContents: () => ({ commands: t, editor: o, view: a }) => { if (S(o, this.name).length > 0) { this.options.onHasOneBeforeInsert(); return; } const e = a.props.state.doc.content.firstChild; if (L(e)) { const s = (e.firstChild && e.firstChild.nodeSize || 0) + 1; return t.insertContentAt(s, { type: this.name }); } return t.insertContent({ type: this.name }); }, removeTableOfContents: () => ({ state: t, dispatch: o }) => { const { tr: a } = t, n = t.schema.nodes.tableOfContents; return t.doc.descendants((e, s) => { if (e.type === n) { const i = s, r = s + e.nodeSize; a.delete(i, r); } }), a.docChanged ? (o(a), !0) : !1; } }; }, addGlobalAttributes() { return [ { types: ["heading"], attributes: { id: { default: null } } } ]; } }); export { z as TableOfContents };