reactjs-tiptap-editor
Version:
A modern WYSIWYG rich text editor based on tiptap and shadcn ui for React
328 lines (327 loc) • 11.5 kB
JavaScript
import { jsx as t, jsxs as p } from "react/jsx-runtime";
import * as k from "react";
import { useCallback as m, useState as w, useEffect as L, useRef as $, useMemo as M } from "react";
import { Plus as B } from "lucide-react";
import { HexColorPicker as F } from "react-colorful";
import { j as I, B as _, c as T } from "./index-RcSPeQHn.js";
import "./theme.js";
import { u as N, C as j } from "./index-C07N8gA1.js";
import { P as z, a as E, b as y } from "./popover-CtinPbiy.js";
import * as R from "@radix-ui/react-separator";
function D() {
return /* @__PURE__ */ t("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24", children: /* @__PURE__ */ t("path", { fill: "currentColor", d: "M18 14c0-4-6-10.8-6-10.8s-1.33 1.51-2.73 3.52l8.59 8.59c.09-.42.14-.86.14-1.31m-.88 3.12L12.5 12.5L5.27 5.27L4 6.55l3.32 3.32C6.55 11.32 6 12.79 6 14c0 3.31 2.69 6 6 6c1.52 0 2.9-.57 3.96-1.5l2.63 2.63l1.27-1.27z" }) });
}
const C = typeof window > "u";
function S(e, r, c = window) {
const d = $(void 0);
L(() => {
d.current = r;
}, [r]), L(() => {
if (!(c && c.addEventListener)) return;
const u = (a) => {
d.current && d.current(a);
};
return c.addEventListener(e, u), () => {
c.removeEventListener(e, u);
};
}, [e, c]);
}
function J(e, r, c = {}) {
const { initializeWithValue: d = !0 } = c, n = m(
(o) => c.serializer ? c.serializer(o) : JSON.stringify(o),
[c]
), u = m(
(o) => {
if (c.deserializer)
return c.deserializer(o);
if (o === "undefined")
return;
const s = r instanceof Function ? r() : r;
let i;
try {
i = JSON.parse(o);
} catch (l) {
return console.error("Error parsing JSON:", l), s;
}
return i;
},
[c, r]
), a = m(() => {
const o = r instanceof Function ? r() : r;
if (C)
return o;
try {
const s = window.localStorage.getItem(e);
return s ? u(s) : o;
} catch (s) {
return console.warn(
`Error reading localStorage key “${e}”:`,
s
), o;
}
}, [r, e, u]), [h, f] = w(() => d ? a() : r instanceof Function ? r() : r), b = m((o) => {
C && console.warn(
`Tried setting localStorage key “${e}” even though environment is not a client`
);
try {
const s = o instanceof Function ? o(a()) : o;
window.localStorage.setItem(e, n(s)), f(s), window.dispatchEvent(
new StorageEvent("local-storage", {
key: e
})
);
} catch (s) {
console.warn(
`Error setting localStorage key “${e}”:`,
s
);
}
}, [e, n, a]), g = m(() => {
C && console.warn(
`Tried removing localStorage key “${e}” even though environment is not a client`
);
const o = r instanceof Function ? r() : r;
window.localStorage.removeItem(e), f(o), window.dispatchEvent(
new StorageEvent("local-storage", {
key: e
})
);
}, [e, r]);
L(() => {
f(a());
}, [e]);
const v = m(
(o) => {
o.key && o.key !== e || f(a());
},
[e, a]
);
return S("storage", v), S("local-storage", v), [h, b, g];
}
function X(e) {
const { t: r } = N(), {
disabled: c = !1,
value: d,
onChange: n,
colors: u = j,
highlight: a
} = e, [h, f] = w(!1), b = M(() => {
const i = u, l = [];
for (let x = 0; x < i.length; x += 10)
l.push(i.slice(x, x + 10));
return l;
}, [u]), [g, v] = J(a ? "richtext-recent-highlight" : "richtext-recent-colors", []), o = (i) => {
const l = [...g], x = l.indexOf(i);
x !== -1 && l.splice(x, 1), l.unshift(i), l.length > 10 && l.pop(), v(l);
};
function s(i) {
if (i === void 0) {
n == null || n(i), f(!1);
return;
}
/^#([\da-f]{3}){1,2}$/i.test(i) && (n == null || n(i), o(i), f(!1));
}
return /* @__PURE__ */ p(
z,
{
modal: !0,
onOpenChange: f,
open: h,
children: [
/* @__PURE__ */ t(
E,
{
asChild: !0,
className: "!richtext-p-0",
disabled: c,
children: e == null ? void 0 : e.children
}
),
/* @__PURE__ */ t(
y,
{
align: "start",
className: "richtext-size-full !richtext-p-2",
hideWhenDetached: !0,
side: "bottom",
children: /* @__PURE__ */ p("div", { className: "richtext-flex richtext-flex-col", children: [
/* @__PURE__ */ p(
"div",
{
className: "rd-1 richtext-flex richtext-cursor-pointer richtext-items-center richtext-gap-[4px] richtext-p-1 hover:richtext-bg-accent",
onClick: () => {
s(void 0);
},
children: [
/* @__PURE__ */ t(D, {}),
/* @__PURE__ */ t("span", { className: "richtext-ml-1 richtext-text-sm", children: r(a ? "editor.nofill" : "editor.default") })
]
}
),
b.map((i, l) => /* @__PURE__ */ t(
"span",
{
className: "richtext-relative richtext-flex richtext-h-auto richtext-w-full richtext-p-0 last:richtext-pb-2",
children: i.map((x, P) => /* @__PURE__ */ t(
"span",
{
className: "richtext-inline-block richtext-size-6 richtext-flex-[0_0_auto] richtext-cursor-pointer richtext-rounded-sm !richtext-border richtext-border-solid !richtext-border-transparent richtext-p-0.5 hover:!richtext-border-border",
onClick: () => s(x),
children: /* @__PURE__ */ t(
"span",
{
className: "richtext-relative richtext-block richtext-size-[18px] richtext-rounded-[2px]",
style: {
backgroundColor: x
},
children: x === d ? /* @__PURE__ */ t(
"svg",
{
className: "richtext-absolute -richtext-top-px richtext-left-px richtext-block richtext-size-3",
viewBox: "0 0 18 18",
style: {
fill: "rgb(255, 255, 255)"
},
children: /* @__PURE__ */ t("path", { d: "M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" })
}
) : /* @__PURE__ */ t(
"svg",
{
viewBox: "0 0 18 18",
style: {
fill: "rgb(255, 255, 255)",
display: "none"
},
children: /* @__PURE__ */ t("path", { d: "M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" })
}
)
}
)
},
`sub-color-${P}`
))
},
`color-row-${l}`
)),
/* @__PURE__ */ p("div", { children: [
/* @__PURE__ */ t("div", { className: "richtext-my-1 richtext-text-sm", children: r("editor.recent") }),
/* @__PURE__ */ t("span", { className: "richtext-relative richtext-flex richtext-h-auto richtext-w-full richtext-flex-wrap richtext-p-0 last:richtext-pb-2", children: g == null ? void 0 : g.map((i, l) => /* @__PURE__ */ t(
"span",
{
className: "richtext-inline-block richtext-size-6 richtext-flex-[0_0_auto] richtext-cursor-pointer richtext-rounded-sm !richtext-border richtext-border-transparent richtext-p-0.5 hover:richtext-border-border hover:richtext-shadow-sm",
onClick: () => s(i),
children: /* @__PURE__ */ t(
"span",
{
className: "richtext-relative richtext-block richtext-size-[18px] richtext-rounded-[2px] richtext-border-transparent",
style: {
backgroundColor: i
},
children: /* @__PURE__ */ t(
"svg",
{
viewBox: "0 0 18 18",
style: {
fill: "rgb(255, 255, 255)",
display: "none"
},
children: /* @__PURE__ */ t("path", { d: "M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" })
}
)
}
)
},
`sub-color-recent-${l}`
)) })
] }),
/* @__PURE__ */ t(Z, { setColor: s })
] })
}
)
]
}
);
}
function Z({ setColor: e }) {
const { t: r } = N(), [c, d] = w(!1), [n, u] = w("#000000"), a = m(
(h) => {
u(h);
},
[]
);
return /* @__PURE__ */ p(
z,
{
onOpenChange: d,
open: c,
children: [
/* @__PURE__ */ t(E, { asChild: !0, children: /* @__PURE__ */ p(
"div",
{
className: "richtext-p-1.5 richtext-text-sm hover:richtext-cursor-pointer hover:richtext-bg-accent",
children: [
r("editor.color.more"),
"..."
]
}
) }),
/* @__PURE__ */ p(y, { children: [
/* @__PURE__ */ p("div", { className: "richtext-flex richtext-flex-col richtext-items-center richtext-justify-center", children: [
/* @__PURE__ */ t(
F,
{
color: n,
onChange: (h) => {
a(h);
}
}
),
/* @__PURE__ */ t(
I,
{
className: "richtext-mt-[8px] richtext-w-full",
type: "text",
value: n.replace("#", ""),
onChange: (h) => {
h.preventDefault(), h.stopPropagation(), a(`#${h.target.value}`);
}
}
)
] }),
/* @__PURE__ */ t(O, { className: "richtext-my-[10px]" }),
/* @__PURE__ */ t(
_,
{
className: "richtext-w-full",
onClick: (h) => {
h.preventDefault(), h.stopPropagation(), e(n), d(!1);
},
children: /* @__PURE__ */ t(B, { size: 16 })
}
)
] })
]
}
);
}
const O = k.forwardRef(
({ className: e, orientation: r = "horizontal", decorative: c = !0, ...d }, n) => /* @__PURE__ */ t(
R.Root,
{
ref: n,
decorative: c,
orientation: r,
className: T(
"richtext-shrink-0 richtext-bg-border",
r === "horizontal" ? "richtext-h-[1px] richtext-w-full" : "richtext-h-full richtext-w-[1px]",
e
),
...d
}
)
);
O.displayName = R.Root.displayName;
export {
X as C,
O as S
};