@rtdui/editor
Version:
React rich text editor based on tiptap
324 lines (320 loc) • 14.7 kB
JavaScript
'use client';
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var clsx = require('clsx');
var react = require('@tiptap/react');
var iconsReact = require('@tabler/icons-react');
var starterKit = require('@tiptap/starter-kit');
var extensionTableCell = require('@tiptap/extension-table-cell');
var extensionTableHeader = require('@tiptap/extension-table-header');
var extensionTableRow = require('@tiptap/extension-table-row');
var extensionLink = require('@tiptap/extension-link');
var extensionTextAlign = require('@tiptap/extension-text-align');
var extensionHighlight = require('@tiptap/extension-highlight');
var SuperScript = require('@tiptap/extension-superscript');
var SubScript = require('@tiptap/extension-subscript');
var extensionPlaceholder = require('@tiptap/extension-placeholder');
var extensionTaskList = require('@tiptap/extension-task-list');
var extensionTaskItem = require('@tiptap/extension-task-item');
var uploadImageWithResizable = require('./tiptap_extensions/extension-image-upload/uploadImageWithResizable.cjs');
var markdownPaste = require('./tiptap_extensions/extension-markdown-paste/markdownPaste.cjs');
var mathKatexInline = require('./tiptap_extensions/extension-math/math-katex-inline.cjs');
var mathKatexBlock = require('./tiptap_extensions/extension-math/math-katex-block.cjs');
var table = require('./tiptap_extensions/extension-table/table.cjs');
var codeBlockShiki = require('./tiptap_extensions/extension-code-block-shiki/code-block-shiki.cjs');
var EditorControl = require('./tiptap_controls/EditorControl.cjs');
var HelperControl = require('./tiptap_controls/HelperControl.cjs');
const RichTextEditor = React.forwardRef(
(props, ref) => {
const {
slots,
editable = true,
placeholder = "\u8F93\u5165\u5185\u5BB9\u6216\u8005\u4ECE\u526A\u8D34\u677F\u7C98\u8D34, \u590D\u5236\u7C98\u8D34\u652F\u6301Markdown",
uploadImageUrl,
imageResizable = true,
...other
} = props;
const editorOptions = {
extensions: [
starterKit.StarterKit.configure({
// history: false, // The Collaboration extension comes with its own history handling
codeBlock: false
// 会使用CodeBlockHighlight替代
}),
table.CustomTable.configure({
resizable: true
}),
extensionTableRow.TableRow,
extensionTableHeader.TableHeader,
extensionTableCell.TableCell,
extensionLink.Link,
extensionTaskList.TaskList,
extensionTaskItem.TaskItem.configure({
nested: true
}),
SuperScript,
SubScript,
extensionHighlight.Highlight,
extensionPlaceholder.Placeholder.configure({
placeholder
}),
extensionTextAlign.TextAlign.configure({
types: ["heading", "paragraph", "tableHeader", "tableCell"]
}),
codeBlockShiki.CodeBlockShiki,
// Register the document with Tiptap
// Collaboration.configure({
// document: ydoc,
// }),
// // Register the collaboration cursor extension
// CollaborationCursor.configure({
// provider,
// user: {
// name,
// color,
// },
// }),
uploadImageWithResizable.UploadImageWithResizable.configure({
resizable: imageResizable,
inline: true,
url: uploadImageUrl,
method: "post"
}),
markdownPaste.MarkdownPaste,
mathKatexInline.MathKatexInline,
mathKatexBlock.MathKatexBlock
],
editable
};
const editor = react.useEditor(editorOptions);
React.useImperativeHandle(ref, () => ({
getJSON: () => {
if (editor) {
return editor.getJSON();
}
return null;
},
setContent: (jsonOrHtml) => {
if (editor) {
editor.commands.setContent(jsonOrHtml);
}
}
}));
if (!editor) {
return null;
}
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...other, children: [
editor && editable && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl, { editor, children: /* @__PURE__ */ jsxRuntime.jsxs(EditorControl.EditorControl.Toolbar, { sticky: true, className: clsx(slots?.toolbar), children: [
/* @__PURE__ */ jsxRuntime.jsxs(EditorControl.EditorControl.ControlsGroup, { children: [
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Bold, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Italic, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Strikethrough, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Highlight, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Code, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.ClearFormatting, {})
] }),
/* @__PURE__ */ jsxRuntime.jsxs(EditorControl.EditorControl.ControlsGroup, { children: [
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.H1, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.H2, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.H3, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.H4, {})
] }),
/* @__PURE__ */ jsxRuntime.jsxs(EditorControl.EditorControl.ControlsGroup, { children: [
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Blockquote, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Hr, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.BulletList, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.OrderedList, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Subscript, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Superscript, {})
] }),
/* @__PURE__ */ jsxRuntime.jsxs(EditorControl.EditorControl.ControlsGroup, { children: [
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.AlignLeft, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.AlignCenter, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.AlignRight, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.AlignJustify, {})
] }),
/* @__PURE__ */ jsxRuntime.jsxs(EditorControl.EditorControl.ControlsGroup, { children: [
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Image, {}),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.Table, {})
] }),
/* @__PURE__ */ jsxRuntime.jsx(EditorControl.EditorControl.ControlsGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(HelperControl.HelperControl, {}) })
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(
react.FloatingMenu,
{
editor,
shouldShow: ({ editor: editor2 }) => editor2.isActive("tableCell") || editor2.isActive("tableHeader"),
tippyOptions: {
placement: "top",
getReferenceClientRect: () => {
const tableNode = react.findParentNodeClosestToPos(
editor.view.state.selection.$from,
(node) => node.type.name === "table"
);
return react.posToDOMRect(
editor.view,
tableNode?.start,
tableNode?.start
);
}
},
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "join", children: [
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u63D2\u5165\u8868\u683C",
onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconTable, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5DE6\u4FA7\u63D2\u5165\u5217",
onClick: () => editor.chain().focus().addColumnBefore().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconColumnInsertLeft, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u53F3\u4FA7\u63D2\u5165\u5217",
onClick: () => editor.chain().focus().addColumnAfter().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconColumnInsertRight, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5220\u9664\u5217",
onClick: () => editor.chain().focus().deleteColumn().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconContainerOff, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u4E0A\u65B9\u63D2\u5165\u884C",
onClick: () => editor.chain().focus().addRowBefore().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconRowInsertTop, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u4E0B\u65B9\u63D2\u5165\u884C",
onClick: () => editor.chain().focus().addRowAfter().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconRowInsertBottom, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5220\u9664\u884C",
onClick: () => editor.chain().focus().deleteRow().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconContainerOff, { className: "rotate-90", stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5220\u9664\u8868\u683C",
onClick: () => editor.chain().focus().deleteTable().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconTableOff, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5408\u5E76\u5355\u5143\u683C",
onClick: () => editor.chain().focus().mergeCells().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconViewportNarrow, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u62C6\u5206\u5355\u5143\u683C",
onClick: () => editor.chain().focus().splitCell().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconArrowBarBoth, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5408\u5E76\u6216\u62C6\u5206",
onClick: () => editor.chain().focus().mergeOrSplit().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconSquareToggle, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u9996\u5217\u5207\u6362",
onClick: () => editor.chain().focus().toggleHeaderColumn().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconBoxAlignLeft, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u9996\u884C\u5207\u6362",
onClick: () => editor.chain().focus().toggleHeaderRow().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconBoxAlignTop, { stroke: 1 })
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"button",
{
type: "button",
className: "join-item btn btn-sm px-1",
title: "\u5355\u5143\u683C\u5207\u6362\u884C\u5934\u6837\u5F0F",
onClick: () => editor.chain().focus().toggleHeaderCell().run(),
children: /* @__PURE__ */ jsxRuntime.jsx(iconsReact.IconBoxAlignTopLeft, { stroke: 1 })
}
)
] })
}
)
] }),
/* @__PURE__ */ jsxRuntime.jsx(
react.EditorContent,
{
editor,
className: clsx("editor-content prose max-w-none!", slots?.content)
}
)
] });
}
);
RichTextEditor.displayName = "@rtdui/RichTextEditor";
exports.RichTextEditor = RichTextEditor;
//# sourceMappingURL=RichTextEditor.cjs.map