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 (
{children}
)
}
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">
1 2 3
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 (
)
}