From de0bcca409585acc318081b976cff022ffc8413c Mon Sep 17 00:00:00 2001 From: Adrian Bonpin Date: Sun, 26 Apr 2026 10:13:17 -0500 Subject: [PATCH] feat: add reusable Tiptap editor component --- components/tiptap-editor.tsx | 138 +++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 components/tiptap-editor.tsx diff --git a/components/tiptap-editor.tsx b/components/tiptap-editor.tsx new file mode 100644 index 0000000..1c44bc5 --- /dev/null +++ b/components/tiptap-editor.tsx @@ -0,0 +1,138 @@ +"use client" + +import { useEditor, EditorContent } from "@tiptap/react" +import StarterKit from "@tiptap/starter-kit" +import Link from "@tiptap/extension-link" +import Placeholder from "@tiptap/extension-placeholder" +import { + Bold, + Italic, + List, + ListOrdered, + Link as LinkIcon, + Unlink, +} from "lucide-react" + +interface TiptapEditorProps { + content?: string + onChange?: (json: Record) => void + placeholder?: string + className?: string +} + +export function TiptapEditor({ + content, + onChange, + placeholder = "Write your notes here...", + className = "", +}: TiptapEditorProps) { + const editor = useEditor({ + extensions: [ + StarterKit.configure({ + heading: false, + codeBlock: false, + code: false, + blockquote: false, + horizontalRule: false, + }), + Link.configure({ + openOnClick: false, + HTMLAttributes: { + class: "text-primary underline", + }, + }), + Placeholder.configure({ + placeholder, + }), + ], + content: content ? JSON.parse(content) : undefined, + onUpdate: ({ editor }) => { + onChange?.(editor.getJSON()) + }, + editorProps: { + attributes: { + class: + "prose prose-invert prose-sm max-w-none min-h-[120px] px-4 py-3 outline-none", + }, + }, + }) + + if (!editor) { + return null + } + + const toggleLink = () => { + if (editor.isActive("link")) { + editor.chain().focus().unsetLink().run() + } else { + const url = window.prompt("Enter URL:") + if (url) { + editor.chain().focus().setLink({ href: url }).run() + } + } + } + + return ( +
+ {/* Toolbar */} +
+ + +
+ + +
+ +
+ + {/* Editor */} + +
+ ) +}