This commit is contained in:
cdricms
2025-02-20 19:45:11 +01:00
parent 07c632dafe
commit 5bdfc9ce06
9 changed files with 1554 additions and 3092 deletions

View File

@@ -1,73 +1,65 @@
"use client";
import * as React from "react";
import {
MDXEditor,
headingsPlugin,
listsPlugin,
quotePlugin,
thematicBreakPlugin,
markdownShortcutPlugin,
toolbarPlugin,
linkPlugin,
linkDialogPlugin,
type MDXEditorMethods,
KitchenSinkToolbar,
tablePlugin,
imagePlugin,
frontmatterPlugin,
codeBlockPlugin,
directivesPlugin,
AdmonitionDirectiveDescriptor,
} from "@mdxeditor/editor";
import { cn } from "@/lib/utils";
import { Card } from "@/components/ui/card";
import { EditorContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Underline from "@tiptap/extension-underline";
import Link from "@tiptap/extension-link";
import TTImage from "@tiptap/extension-image";
import TextAlign from "@tiptap/extension-text-align";
import Youtube from "@tiptap/extension-youtube";
import Dropcursor from "@tiptap/extension-dropcursor";
import { EditorMenu } from "./editor-menu";
interface EditorProps {
markdown: string;
content: string;
onChange?: (markdown: string) => void;
className?: string;
}
export function Editor({ markdown, onChange, className }: EditorProps) {
const ref = React.useRef<MDXEditorMethods>(null);
export function Editor({ content, onChange, className }: EditorProps) {
const editor = useEditor({
extensions: [
StarterKit,
Underline,
Link,
Youtube,
Dropcursor,
TTImage.configure({
HTMLAttributes: {
class: "max-w-full w-auto h-auto resize overflow-auto",
},
}),
TextAlign.configure({
alignments: ["left", "center", "right", "justify"],
defaultAlignment: "justify",
types: ["heading", "paragraph"],
}),
],
content,
immediatelyRender: false,
editorProps: {
attributes: {
class: "prose prose-sm sm:prose-base lg:prose-lg xl:prose-2xl m-5 focus:outline-none dark:prose-invert",
},
},
onUpdate: ({ editor }) => {
console.log("Update");
localStorage.setItem("blog_draft", editor.getHTML());
},
});
const onChangeDebounce = (content: string) => {
localStorage.setItem("blog_draft", content);
};
if (!editor) {
return null;
}
return (
<Card className={cn("border rounded-lg overflow-hidden", className)}>
<MDXEditor
ref={ref}
className="mdx-editor dark-theme dark-editor prose dark:prose-invert p-4"
markdown={markdown}
onChange={onChangeDebounce}
spellCheck
plugins={[
toolbarPlugin({
toolbarContents: () => <KitchenSinkToolbar />,
}),
listsPlugin(),
quotePlugin(),
headingsPlugin(),
linkPlugin(),
linkDialogPlugin(),
// eslint-disable-next-line @typescript-eslint/require-await
imagePlugin({
imageUploadHandler: async () => "/sample-image.png",
}),
tablePlugin(),
thematicBreakPlugin(),
frontmatterPlugin(),
codeBlockPlugin({ defaultCodeBlockLanguage: "txt" }),
directivesPlugin({
directiveDescriptors: [AdmonitionDirectiveDescriptor],
}),
markdownShortcutPlugin(),
]}
/>
<EditorMenu editor={editor} />
<EditorContent editor={editor} />
</Card>
);
}