基于tiny editor封装

39 阅读1分钟

为什么不选择wangEditor

虽然wangEditor很好,但是还是存在限制的,

  1. wangEditor不支持查看源码
  2. wangEditor对于其他平台的 html 不友好,会将原本的html标签全部转换为 p 和 span 标签,且class类会移除

原本我的wordpress平台上的blog在做迁移的时候,wangEditor并不是很理想,所以调查发现tiny还是不错的选择,

自定义功能

自定义上传图片和视频,plugin动态导入

效果图

image.png

image.png

源码

import React, { useState } from "react";
import { Editor } from "@tinymce/tinymce-react";
import clsx from "clsx";
import AddEditImages from "../modal/add-edit-images/V1/view";

type PropsType = {
    value: string;
    handleChangeValue: (value: string) => void;
    editorClassName: string;
};

const BaseEditor: React.FC<PropsType> = ({ value = "", handleChangeValue }) => {
    const [content, setContent] = useState(value);
    const [openFile, setOpenFile] = useState(false);
    const [editor, setEditor] = useState<any>(null);
    return (
        <div className={clsx(["flex-1"])}>
            <Editor
                id="blog-tiny-editor"
                apiKey="c2iuqz8zrfd29cmgvsy3i1269f6addgttms2ed96if9mle2s"
                value={content}
                init={{
                    menubar: true,
                    plugins: [
                        "advlist autolink lists link image charmap preview anchor",
                        "searchreplace visualblocks code fullscreen",
                        "insertdatetime media table paste help wordcount",
                        "image",
                        "media",
                        "link",
                        "table",
                        "hr",
                        "emoticons",
                        "toc",
                        "wordcount",
                        "comments",
                        "code",
                    ],
                    toolbar:
                        "undo redo | formatselect | link bold italic underline strikethrough | alignleft aligncenter alignright | bullist numlist outdent indent | uploadFile | emoticons | table | toc hr | wordcount | addcomment showcomments | code",

                    // file_picker_types: "image video", // 支持图片和视频文件选择
                    // automatic_uploads: true,
                    // file_picker_callback: async (callback, value, meta) => {
                    //     const input = document.createElement("input");
                    //     input.setAttribute("type", "file");
                    //     input.setAttribute("accept", "image/*");
                    //     input.onchange = async (event) => {
                    //         const file = (event.target as HTMLInputElement).files?.[0];
                    //         if (file) {
                    //             try {
                    //                 const url = `https://westshade-erp.s3.us-west-2.amazonaws.com/images/${uuidv4()}-${
                    //                     file.name
                    //                 }`;
                    //                 await uploadFile(url, file);
                    //                 await postImage({
                    //                     name: file.name,
                    //                     src: url,
                    //                     alt: file.name,
                    //                 });
                    //                 callback(url, { alt: file.name });
                    //             } catch (error) {
                    //                 console.error(`${meta.filetype} upload failed:`, error);
                    //             }
                    //         }
                    //     };
                    //     input.click();
                    // },
                    setup: (editor) => {
                        setEditor(editor);
                        editor.ui.registry.addButton("uploadFile", {
                            text: "", // 按钮显示文字
                            icon: "image",
                            onAction: () => {
                                setOpenFile(true);
                            },
                        });
                    },
                    content_css: "/blog-editor.css",
                }}
                onEditorChange={(newContent) => {
                    setContent(newContent);
                    handleChangeValue(newContent);
                }}
            />
            <AddEditImages
                isModalOpen={openFile}
                modalType="add"
                title="Select image"
                handleCancel={() => setOpenFile(false)}
                handleOk={(image) => {
                    if (image) {
                        const new_value =
                            `<figure><img src="${image.src}" alt="${image.alt}" width="600px" height="300px"/></figure >` +
                            value;
                        editor.insertContent(new_value);
                    }
                    setOpenFile(false);
                }}
            />
        </div>
    );
};

export default BaseEditor;