UNPKG

reactjs-tiptap-editor

Version:

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

252 lines (251 loc) 8.83 kB
import { jsx as d, jsxs as b } from "react/jsx-runtime"; import { forwardRef as y, useState as w, useRef as v, useImperativeHandle as S, useEffect as B, Fragment as D } from "react"; import { E as N, z as L, L as T, c as V, I as z } from "./index-RcSPeQHn.js"; import "./theme.js"; import { H as A, u as G } from "./index-C07N8gA1.js"; import { y as $, V as q } from "./index-BG0kQamI.js"; function X({ t: i }) { const a = [ { name: "format", title: i("editor.slash.format"), commands: [] }, { name: "insert", title: i("editor.slash.insert"), commands: [] } ]; return A.forEach((e) => { a[0].commands.push({ name: `heading${e}`, label: i(e === "Paragraph" ? "editor.paragraph.tooltip" : `editor.heading.h${e}.tooltip`), aliases: [`h${e}`, "bt", `bt${e}`], iconName: `Heading${e}`, isActive: (t) => e === "Paragraph" ? !1 : t.isActive("heading", { level: e }) || !1, action: ({ editor: t, range: l }) => { const s = A.find((m) => t.isActive("heading", { level: m })); if (e === "Paragraph") { s !== void 0 && s !== "Paragraph" && t.commands.toggleHeading({ level: s }), t.chain().focus().deleteRange(l).run(); return; } if (e) { t.chain().focus().deleteRange(l).setHeading({ level: e }).run(); return; } t.chain().focus().deleteRange(l).run(); } }); }), a[0].commands.push({ name: "bulletList", label: i("editor.bulletlist.tooltip"), aliases: ["ul", "yxlb"], iconName: "List", isActive: (e) => e.isActive("bulletList"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).toggleBulletList().run(); } }), a[0].commands.push({ name: "orderedlist", label: i("editor.orderedlist.tooltip"), aliases: ["ol", "yxlb"], iconName: "ListOrdered", isActive: (e) => e.isActive("orderedList"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).toggleOrderedList().run(); } }), a[0].commands.push({ name: "taskList", label: i("editor.tasklist.tooltip"), iconName: "ListTodo", description: "Task list with todo items", aliases: ["todo"], isActive: (e) => e.isActive("taskList"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).toggleTaskList().run(); } }), a[0].commands.push({ name: "blockquote", label: i("editor.blockquote.tooltip"), description: "插入引入格式", aliases: ["yr"], iconName: "TextQuote", isActive: (e) => e.isActive("blockquote"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).setBlockquote().run(); } }), a[0].commands.push({ name: "codeBlock", label: i("editor.codeblock.tooltip"), iconName: "Code2", description: "Code block with syntax highlighting", shouldBeHidden: (e) => e.isActive("columns"), isActive: (e) => e.isActive("codeBlock"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).setCodeBlock().run(); } }), a[1].commands.push({ name: "image", label: i("editor.image.tooltip"), iconName: "ImageUp", description: "Insert a image", aliases: ["image", "tp", "tupian"], shouldBeHidden: (e) => e.isActive("columns"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).run(); const l = N.UPLOAD_IMAGE(e.id); L(l, !0); } }), a[1].commands.push({ name: "video", label: i("editor.video.tooltip"), iconName: "Video", description: "Insert a video", aliases: ["video", "sp", "shipin"], shouldBeHidden: (e) => e.isActive("columns"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).run(); const l = N.UPLOAD_VIDEO(e.id); L(l, !0); } }), a[1].commands.push({ name: "table", label: i("editor.table.tooltip"), iconName: "Table", description: "Insert a table", aliases: ["table", "bg", "biaoge", "biao"], shouldBeHidden: (e) => e.isActive("columns"), action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).insertTable({ rows: 3, cols: 3, withHeaderRow: !1 }).run(); } }), a[1].commands.push({ name: "horizontalRule", label: i("editor.horizontalrule.tooltip"), iconName: "Minus", description: "Insert a horizontal divider", aliases: ["hr", "fgx", "fg"], action: ({ editor: e, range: t }) => { e.chain().focus().deleteRange(t).setHorizontalRule().run(); } }), a[1].commands.push({ name: "columns", label: i("editor.columns.tooltip"), iconName: "Columns2", description: "Add two column content", action: ({ editor: e }) => { e.chain().focus().insertColumns({ cols: 2 }).run(); } }), a; } function P(i, a) { return i.map((l) => ({ ...l, commands: l.commands.filter((s) => { const m = s.label.toLowerCase().trim(), u = a.toLowerCase().trim(); if (s.aliases) { const p = s.aliases.map((h) => h.toLowerCase().trim()), r = m.match(u), f = p.some((h) => h.match(u)); return r || f; } return m.match(u); }) })).filter((l) => l.commands.length > 0); } const U = $([]); function O() { const [i, a] = q(U); return [i, a]; } function F(i, a) { const [e] = O(), [t, l] = w(0), [s, m] = w(0), u = v(null), { t: p } = G(), r = P(e, i.query), f = v([]); S(a, () => ({ onKeyDown: h })), B(() => { if (!u.current) return; const o = s * 1e3 + t, n = f.current[o]; n && n.scrollIntoView({ behavior: "smooth", block: "nearest" }); }, [t, s]); function h({ event: o }) { return o.key === "ArrowUp" ? (C(), !0) : o.key === "ArrowDown" ? (I(), !0) : o.key === "Enter" ? (k(), !0) : !1; } function C() { var c; if (r.length === 0) return !1; let o = t - 1, n = s; o < 0 && (n = s - 1, o = ((c = r[n]) == null ? void 0 : c.commands.length) - 1 || 0), n < 0 && (n = r.length - 1, o = r[n].commands.length - 1), l(o), m(n); } function I() { if (r.length === 0) return !1; const o = r[s].commands; let n = t + 1, c = s; o.length - 1 < n && (n = 0, c = s + 1), r.length - 1 < c && (c = 0), l(n), m(c); } function k() { if (r.length === 0 || s === -1 || t === -1) return !1; g(s, t); } function g(o, n) { const c = r[o].commands[n]; i == null || i.command(c); } function R(o, n) { g(o, n); } function H(o, n, c) { f.current[o * 1e3 + n] = c; } return /* @__PURE__ */ d( "div", { className: "richtext-max-h-[min(80vh,24rem)] richtext-flex-wrap richtext-overflow-y-auto richtext-overflow-x-hidden richtext-rounded-md !richtext-border !richtext-border-solid !richtext-border-border richtext-bg-popover richtext-p-1 richtext-text-popover-foreground richtext-shadow-md richtext-outline-none", "data-richtext-portal": !0, ref: u, children: r != null && r.length ? /* @__PURE__ */ d("div", { className: "richtext-grid richtext-min-w-48 richtext-grid-cols-1 richtext-gap-0.5", children: r == null ? void 0 : r.map((o, n) => /* @__PURE__ */ b(D, { children: [ /* @__PURE__ */ d(T, { className: "richtext-mx-[4px] richtext-mb-[4px] richtext-mt-[8px] !richtext-text-[0.65rem] richtext-uppercase ", children: o.title }), o.commands.map((c, x) => /* @__PURE__ */ b( "button", { onClick: () => R(n, x), ref: (E) => H(n, x, E), className: V("richtext-flex richtext-items-center richtext-gap-3 richtext-px-2 richtext-py-1.5 richtext-text-sm richtext-text-foreground richtext-text-left richtext-w-full richtext-rounded-sm !richtext-outline-none !richtext-border-none richtext-transition-colors !richtext-bg-transparent hover:!richtext-bg-accent ", { "bg-item-active": s === n && t === x }), children: [ c.iconUrl && /* @__PURE__ */ d( "img", { alt: "", className: "richtext-size-6", src: c.iconUrl } ), c.iconName && /* @__PURE__ */ d( z, { className: "!richtext-mr-1 !richtext-text-lg", name: c.iconName } ), c.label ] }, `command-${x}` )) ] }, `slash-${o.title}`)) }) : /* @__PURE__ */ d("div", { className: "richtext-p-3", children: /* @__PURE__ */ d("span", { className: "richtext-text-xs richtext-text-foreground", children: p("editor.slash.empty") }) }) } ); } const Y = y(F); export { Y as S, P as a, X as r, O as u };