+ reCAPTCHA 脚本加载失败,请检查网络(需可访问 google.com)后刷新重试。 +
+ ) : null} + > + ); +} diff --git a/src/components/admin/RichEditor.tsx b/src/components/admin/RichEditor.tsx new file mode 100644 index 000000000..2248c6228 --- /dev/null +++ b/src/components/admin/RichEditor.tsx @@ -0,0 +1,314 @@ +/** + * # 组件 RichEditor 现代富文本编辑器(TipTap v3 / ProseMirror) + * 体验对齐 WordPress 经典编辑器: + * - 工具栏:撤销重做 / 标题 / 加粗斜体下划线删除线行内代码 / 列表 / 引用 / 分隔线 / + * 链接 / 图片(本地上传 + 媒体库选图)/ 表格 / 代码块 / 清除格式 + * - Markdown:输入即时转换(# 、**、- 等 ProseMirror input rules)+「Markdown 导入」 + * 弹窗(marked 解析为 HTML 后插入光标处或替换正文) + * - HTML 源码模式:与 WordPress「可视化 / 文本」双 Tab 等价 + * - 图片上传走媒体库(uploadMediaFile → /uploads/YYYY/MM/),插入时带 alt + * antd Form.Item 受控:value/onChange 由外部传入。 + */ +import { useCallback, useEffect, useRef, useState } from "react"; +import { EditorContent, useEditor, type Editor } from "@tiptap/react"; +import StarterKit from "@tiptap/starter-kit"; +import Image from "@tiptap/extension-image"; +import { TableKit } from "@tiptap/extension-table"; +import { marked } from "marked"; +import { + Bold, Italic, Underline, Strikethrough, Code, CodeXml, List, ListOrdered, Quote, Minus, + Link2, Link2Off, ImagePlus, LibraryBig, Table as TableIcon, Trash2, RemoveFormatting, + Undo2, Redo2, FileCode2, FileText, +} from "lucide-react"; +import { Button, Dropdown, Input, Modal, Select, Space, Tooltip } from "antd"; +import { MediaPickerModal } from "./MediaPickerModal"; +import { uploadMediaFile } from "~/utils/media-upload"; +import "~/styles/admin-editor.css"; + +/** # 类型 组件属性(value 为 HTML 字符串;受控) **/ +export type RichEditorProps = { + /** # 成员变量 受控 HTML 值 **/ + value?: string; + /** # 成员变量 变更回调(antd Form.Item 注入) **/ + onChange?: (html: string) => void; + /** # 成员变量 编辑区最小高度(px,默认 320) **/ + minHeight?: number; +}; + +/** # 成员变量 工具栏小按钮通用类(样式见 admin-editor.css) **/ +const TIP_CLS = "re-btn"; + +/** # 函数 工具栏按钮(激活态高亮) */ +function TbButton(props: { onAct: () => void; active?: boolean; disabled?: boolean; tip: string; children: React.ReactNode }) { + return ( ++ 支持 # 标题、**加粗**、- 列表、[链接](url)、、表格等(marked 解析)。日常输入时编辑器已自动转换 Markdown 快捷语法。 +
+