reactjs-tiptap-editor
Version:
A modern WYSIWYG rich text editor based on tiptap and shadcn ui for React
238 lines (237 loc) • 7.13 kB
JavaScript
import { M as y, m as p, E as l } from "./clsx-DaPvp9ji.js";
var d = 20, u = (t, e = 0) => {
const r = [];
return !t.children.length || e > d || Array.from(t.children).forEach((o) => {
o.tagName === "SPAN" ? r.push(o) : o.children.length && r.push(...u(o, e + 1));
}), r;
}, f = (t) => {
if (!t.children.length)
return;
const e = u(t);
e && e.forEach((r) => {
var o, n;
const s = r.getAttribute("style"), i = (n = (o = r.parentElement) == null ? void 0 : o.closest("span")) == null ? void 0 : n.getAttribute("style");
r.setAttribute("style", `${i};${s}`);
});
}, c = y.create({
name: "textStyle",
priority: 101,
addOptions() {
return {
HTMLAttributes: {},
mergeNestedSpanStyles: !0
};
},
parseHTML() {
return [
{
tag: "span",
consuming: !1,
getAttrs: (t) => t.hasAttribute("style") ? (this.options.mergeNestedSpanStyles && f(t), {}) : !1
}
];
},
renderHTML({ HTMLAttributes: t }) {
return ["span", p(this.options.HTMLAttributes, t), 0];
},
addCommands() {
return {
toggleTextStyle: (t) => ({ commands: e }) => e.toggleMark(this.name, t),
removeEmptyTextStyle: () => ({ tr: t }) => {
const { selection: e } = t;
return t.doc.nodesBetween(e.from, e.to, (r, o) => {
if (r.isTextblock)
return !0;
r.marks.filter((n) => n.type === this.type).some((n) => Object.values(n.attrs).some((s) => !!s)) || t.removeMark(o, o + r.nodeSize, this.type);
}), !0;
}
};
}
}), m = l.create({
name: "backgroundColor",
addOptions() {
return {
types: ["textStyle"]
};
},
addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
backgroundColor: {
default: null,
parseHTML: (t) => {
var e;
const r = t.getAttribute("style");
if (r) {
const o = r.split(";").map((n) => n.trim()).filter(Boolean);
for (let n = o.length - 1; n >= 0; n -= 1) {
const s = o[n].split(":");
if (s.length >= 2) {
const i = s[0].trim().toLowerCase(), a = s.slice(1).join(":").trim();
if (i === "background-color")
return a.replace(/['"]+/g, "");
}
}
}
return (e = t.style.backgroundColor) == null ? void 0 : e.replace(/['"]+/g, "");
},
renderHTML: (t) => t.backgroundColor ? {
style: `background-color: ${t.backgroundColor}`
} : {}
}
}
}
];
},
addCommands() {
return {
setBackgroundColor: (t) => ({ chain: e }) => e().setMark("textStyle", { backgroundColor: t }).run(),
unsetBackgroundColor: () => ({ chain: t }) => t().setMark("textStyle", { backgroundColor: null }).removeEmptyTextStyle().run()
};
}
}), g = l.create({
name: "color",
addOptions() {
return {
types: ["textStyle"]
};
},
addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
color: {
default: null,
parseHTML: (t) => {
var e;
const r = t.getAttribute("style");
if (r) {
const o = r.split(";").map((n) => n.trim()).filter(Boolean);
for (let n = o.length - 1; n >= 0; n -= 1) {
const s = o[n].split(":");
if (s.length >= 2) {
const i = s[0].trim().toLowerCase(), a = s.slice(1).join(":").trim();
if (i === "color")
return a.replace(/['"]+/g, "");
}
}
}
return (e = t.style.color) == null ? void 0 : e.replace(/['"]+/g, "");
},
renderHTML: (t) => t.color ? {
style: `color: ${t.color}`
} : {}
}
}
}
];
},
addCommands() {
return {
setColor: (t) => ({ chain: e }) => e().setMark("textStyle", { color: t }).run(),
unsetColor: () => ({ chain: t }) => t().setMark("textStyle", { color: null }).removeEmptyTextStyle().run()
};
}
}), h = l.create({
name: "fontFamily",
addOptions() {
return {
types: ["textStyle"]
};
},
addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
fontFamily: {
default: null,
parseHTML: (t) => t.style.fontFamily,
renderHTML: (t) => t.fontFamily ? {
style: `font-family: ${t.fontFamily}`
} : {}
}
}
}
];
},
addCommands() {
return {
setFontFamily: (t) => ({ chain: e }) => e().setMark("textStyle", { fontFamily: t }).run(),
unsetFontFamily: () => ({ chain: t }) => t().setMark("textStyle", { fontFamily: null }).removeEmptyTextStyle().run()
};
}
}), S = l.create({
name: "fontSize",
addOptions() {
return {
types: ["textStyle"]
};
},
addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
fontSize: {
default: null,
parseHTML: (t) => t.style.fontSize,
renderHTML: (t) => t.fontSize ? {
style: `font-size: ${t.fontSize}`
} : {}
}
}
}
];
},
addCommands() {
return {
setFontSize: (t) => ({ chain: e }) => e().setMark("textStyle", { fontSize: t }).run(),
unsetFontSize: () => ({ chain: t }) => t().setMark("textStyle", { fontSize: null }).removeEmptyTextStyle().run()
};
}
}), b = l.create({
name: "lineHeight",
addOptions() {
return {
types: ["textStyle"]
};
},
addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
lineHeight: {
default: null,
parseHTML: (t) => t.style.lineHeight,
renderHTML: (t) => t.lineHeight ? {
style: `line-height: ${t.lineHeight}`
} : {}
}
}
}
];
},
addCommands() {
return {
setLineHeight: (t) => ({ chain: e }) => e().setMark("textStyle", { lineHeight: t }).run(),
unsetLineHeight: () => ({ chain: t }) => t().setMark("textStyle", { lineHeight: null }).removeEmptyTextStyle().run()
};
}
});
l.create({
name: "textStyleKit",
addExtensions() {
const t = [];
return this.options.backgroundColor !== !1 && t.push(m.configure(this.options.backgroundColor)), this.options.color !== !1 && t.push(g.configure(this.options.color)), this.options.fontFamily !== !1 && t.push(h.configure(this.options.fontFamily)), this.options.fontSize !== !1 && t.push(S.configure(this.options.fontSize)), this.options.lineHeight !== !1 && t.push(b.configure(this.options.lineHeight)), this.options.textStyle !== !1 && t.push(c.configure(this.options.textStyle)), t;
}
});
export {
g as C,
h as F,
b as L
};