import React, { useCallback, useEffect } from 'react' import { EditorContent, useEditor } from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import Link from '@tiptap/extension-link' import Placeholder from '@tiptap/extension-placeholder' function ToolbarButton({ onClick, active, disabled, title, children }) { return ( ) } function Divider() { return
} function Toolbar({ editor }) { if (!editor) return null const addLink = useCallback(() => { const previous = editor.getAttributes('link').href const url = window.prompt('URL', previous ?? 'https://') if (url === null) return if (url === '') { editor.chain().focus().extendMarkRange('link').unsetLink().run() return } editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run() }, [editor]) return (
editor.chain().focus().toggleBold().run()} active={editor.isActive('bold')} title="Bold"> editor.chain().focus().toggleItalic().run()} active={editor.isActive('italic')} title="Italic"> editor.chain().focus().toggleHeading({ level: 2 }).run()} active={editor.isActive('heading', { level: 2 })} title="Heading 2"> H2 editor.chain().focus().toggleHeading({ level: 3 }).run()} active={editor.isActive('heading', { level: 3 })} title="Heading 3"> H3 editor.chain().focus().toggleBulletList().run()} active={editor.isActive('bulletList')} title="Bullet list"> editor.chain().focus().toggleOrderedList().run()} active={editor.isActive('orderedList')} title="Numbered list"> 123 editor.chain().focus().toggleBlockquote().run()} active={editor.isActive('blockquote')} title="Quote">
editor.chain().focus().undo().run()} disabled={!editor.can().undo()} title="Undo"> editor.chain().focus().redo().run()} disabled={!editor.can().redo()} title="Redo">
) } export default function HomepageAnnouncementEditor({ content = '', onChange, placeholder = 'Write the announcement message…', error, minHeight = 14, }) { const editor = useEditor({ extensions: [ StarterKit.configure({ link: false, heading: { levels: [2, 3] }, code: false, codeBlock: false, horizontalRule: false, }), Link.configure({ openOnClick: false, HTMLAttributes: { class: 'text-sky-300 underline hover:text-sky-200', rel: 'noopener noreferrer nofollow', }, }), Placeholder.configure({ placeholder }), ], immediatelyRender: false, content, editorProps: { attributes: { class: [ 'prose prose-invert prose-sm max-w-none', 'focus:outline-none', 'px-4 py-3', 'prose-headings:text-white prose-headings:font-bold', 'prose-p:text-zinc-200 prose-p:leading-relaxed', 'prose-a:text-sky-300 prose-a:no-underline hover:prose-a:text-sky-200', 'prose-blockquote:border-l-sky-500/50 prose-blockquote:text-zinc-400', 'prose-ul:text-zinc-200 prose-ol:text-zinc-200', ].join(' '), style: `min-height: ${minHeight}rem`, }, }, onUpdate: ({ editor: currentEditor }) => { onChange?.(currentEditor.getHTML()) }, }) useEffect(() => { if (editor && content !== editor.getHTML()) { editor.commands.setContent(content || '', false) onChange?.(content || '') } }, [content, editor, onChange]) return (
{error ?

{error}

: null}
) }