Rich text editor

This commit is contained in:
2025-11-13 22:15:59 +01:00
parent fb116d1b68
commit 07ebca03d4
3 changed files with 313 additions and 37 deletions
+52 -29
View File
@@ -1,37 +1,60 @@
import { SetState } from "@/lib/types";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/shadcn";
import { useEffect } from "react";
"use client";
export default function DocView({
doc,
setDoc,
}: {
doc: string;
setDoc: SetState<string>;
}) {
const editor = useCreateBlockNote();
import { useEffect, useRef, useState } from "react";
import Header from "@editorjs/header";
import List from "@editorjs/list";
import Quote from "@editorjs/quote";
import Code from "@editorjs/code";
import Table from "@editorjs/table";
import Delimiter from "@editorjs/delimiter";
import Warning from "@editorjs/warning";
import InlineCode from "@editorjs/inline-code";
export default function DocView() {
const holderRef = useRef<HTMLDivElement | null>(null);
const [doc, setDoc] = useState({ blocks: [] });
useEffect(() => {
if (editor && doc) {
editor.tryParseMarkdownToBlocks(doc);
}
}, [editor]);
let editor: any;
let isMounted = true;
(async () => {
const EditorJS = (await import("@editorjs/editorjs")).default;
if (!isMounted || !holderRef.current) return;
editor = new EditorJS({
holder: holderRef.current,
placeholder: "Start writing here...",
autofocus: true,
tools: {
list: { class: List, inlineToolbar: true },
quote: { class: Quote, inlineToolbar: true },
code: Code,
table: Table,
header: Header,
delimiter: Delimiter,
warning: Warning,
inlineCode: InlineCode,
},
data: doc,
async onChange() {
const savedData = await editor.save();
setDoc(savedData);
},
});
})();
return () => {
isMounted = false;
if (editor) editor.destroy();
};
}, []);
return (
<div className="h-full w-3xl mx-auto bg-accent/20 rounded-2xl px-4 py-2 docs-view" onClick={() => editor.focus()}>
<BlockNoteView
defaultValue={doc}
editor={editor}
shadCNComponents={{}}
className="w-full focus:outline-none focus:ring-0 appearance-none"
onChange={async () => {
if (editor) {
console.log(editor.blocksToMarkdownLossy(editor.document));
setDoc(editor.blocksToMarkdownLossy(editor.document));
}
}}
/>
<div className="h-full w-3xl mx-auto bg-accent/20 rounded-2xl px-4 py-2">
<div ref={holderRef} className="docs-view min-h-[400px]" />
</div>
);
}