Plate Editor

This commit is contained in:
2025-07-06 14:54:50 +02:00
parent 946173a557
commit af4c0dcdac
36 changed files with 1901 additions and 3637 deletions

View File

@ -1,44 +1,64 @@
"use client"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { cn } from "@/lib/utils"
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { Bold, Italic, Strikethrough } from "lucide-react"
import type { Value } from 'platejs';
import { BasicBlocksKit } from '@/components/editor/plugins/basic-blocks-kit';
import { BasicMarksKit } from '@/components/editor/plugins/basic-marks-kit';
import { Editor, EditorContainer } from '@/components/ui/editor';
import { FixedToolbar } from '@/components/ui/fixed-toolbar';
import { MarkToolbarButton } from '@/components/ui/mark-toolbar-button';
import { ToolbarButton } from '@/components/ui/toolbar';
import { Plate, usePlateEditor } from 'platejs/react';
const initialValue: Value = [
{
children: [{ text: 'Title' }],
type: 'h3',
},
{
children: [{ text: 'This is a quote.' }],
type: 'blockquote',
},
{
type: 'p',
children: [
{ text: 'Hello! Try out the ' },
{ text: 'bold', bold: true },
{ text: ', ' },
{ text: 'italic', italic: true },
{ text: ', and ' },
{ text: 'underline', underline: true },
{ text: ' formatting.' },
],
},
];
export default function TosEditor() {
const editor = useEditor({
extensions: [StarterKit],
editorProps: {
attributes: {
class: 'prose prose-sm sm:prose-base lg:prose-lg xl:prose-2xl m-5 focus:outline-none',
},
},
content: '<p>Hello World! 🌎️</p>',
onUpdate: ({ editor }) => {
onChange(editor.getHTML())
},
})
if (!editor) return null
const editor = usePlateEditor({
plugins: [
...BasicBlocksKit,
...BasicMarksKit,
], // Add the mark plugins
value: initialValue, // Set initial content
});
return (
<div className="space-y-4">
<ToggleGroup type="multiple" className="flex gap-1">
<ToggleGroupItem onClick={() => editor.chain().focus().toggleBold().run()} pressed={editor.isActive("bold")}>
<Bold className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem onClick={() => editor.chain().focus().toggleItalic().run()} pressed={editor.isActive("italic")}>
<Italic className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem onClick={() => editor.chain().focus().toggleStrike().run()} pressed={editor.isActive("strike")}>
<Strikethrough className="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
<div className={cn("border rounded-md p-4 min-h-[200px]", "bg-background text-foreground")}>
<EditorContent editor={editor} />
</div>
</div>
)
<Plate editor={editor}> {/* Provides editor context */}
<FixedToolbar className="justify-start rounded-t-lg">
{/* Element Toolbar Buttons */}
<ToolbarButton onClick={() => editor.tf.h1.toggle()}>H1</ToolbarButton>
<ToolbarButton onClick={() => editor.tf.h2.toggle()}>H2</ToolbarButton>
<ToolbarButton onClick={() => editor.tf.h3.toggle()}>H3</ToolbarButton>
<ToolbarButton onClick={() => editor.tf.blockquote.toggle()}>Quote</ToolbarButton>
{/* Mark Toolbar Buttons */}
<MarkToolbarButton nodeType="bold" tooltip="Bold (⌘+B)">B</MarkToolbarButton>
<MarkToolbarButton nodeType="italic" tooltip="Italic (⌘+I)">I</MarkToolbarButton>
<MarkToolbarButton nodeType="underline" tooltip="Underline (⌘+U)">U</MarkToolbarButton>
</FixedToolbar>
<EditorContainer> {/* Styles the editor area */}
<Editor placeholder="Type your amazing content here..." />
</EditorContainer>
</Plate>
);
}