import React, { useRef } from 'react'; import Image from '@tiptap/extension-image'; import Link from '@tiptap/extension-link'; import Placeholder from '@tiptap/extension-placeholder'; import TaskItem from '@tiptap/extension-task-item'; import TaskList from '@tiptap/extension-task-list'; import { Editor as EditorProps, EditorContent, useEditor } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import { TbBold, TbCode, TbH1, TbH2, TbH3, TbItalic, TbLink, TbList, TbListDetails, TbListNumbers, TbPhoto, TbQuote, TbStrikethrough, TbUnlink, } from 'react-icons/tb'; import { useTheme } from '../../../hooks/theme'; import { Button } from '../../Button'; import { Flex } from '../../Flex'; import { IconButton } from '../../IconButton'; import { Separator } from '../../Separator'; import { Tooltip } from '../../Tooltip'; import { Container } from './styles'; interface MenuBarProps { editor: EditorProps | null; } function MenuBar({ editor }: MenuBarProps): JSX.Element { const inputFileRef = useRef(null); function setLink(): void { if (editor) { const previousUrl = editor.getAttributes('link').href; const url = window.prompt('URL', previousUrl); if (url === null) { return; } if (url === '') { editor.chain().focus().extendMarkRange('link').unsetLink().run(); return; } editor .chain() .focus() .extendMarkRange('link') .setLink({ href: url }) .run(); } } if (!editor) { return <>; } return ( <> { if (event.target.files?.length) { const file = event.target.files[0]; const reader = new FileReader(); reader.onloadend = () => { if (editor) { editor .chain() .focus() .setImage({ src: reader.result as string, }) .run(); } }; reader.readAsDataURL(file); } }} style={{ display: 'none' }} /> editor.chain().focus().toggleHeading({ level: 1 }).run() } icon={} variant={ editor.isActive('heading', { level: 1 }) ? 'secondary' : 'ghost' } /> editor.chain().focus().toggleHeading({ level: 2 }).run() } icon={} variant={ editor.isActive('heading', { level: 2 }) ? 'secondary' : 'ghost' } /> editor.chain().focus().toggleHeading({ level: 3 }).run() } icon={} variant={ editor.isActive('heading', { level: 3 }) ? 'secondary' : 'ghost' } /> } onClick={() => editor.chain().focus().toggleBold().run()} variant={editor.isActive('bold') ? 'secondary' : 'ghost'} /> } onClick={() => editor.chain().focus().toggleItalic().run()} variant={editor.isActive('italic') ? 'secondary' : 'ghost'} /> editor.chain().focus().toggleStrike().run()} icon={} variant={editor.isActive('strike') ? 'secondary' : 'ghost'} /> editor.chain().focus().toggleCodeBlock().run()} icon={} variant={editor.isActive('codeBlock') ? 'secondary' : 'ghost'} /> editor.chain().focus().toggleBlockquote().run()} icon={} variant={editor.isActive('blockquote') ? 'secondary' : 'ghost'} /> {editor.isActive('link') ? ( editor.chain().focus().unsetLink().run()} variant="secondary" icon={} /> ) : ( } /> )} editor.chain().focus().toggleBulletList().run()} icon={} variant={editor.isActive('bulletList') ? 'secondary' : 'ghost'} /> editor.chain().focus().toggleOrderedList().run()} icon={} variant={editor.isActive('orderedList') ? 'secondary' : 'ghost'} /> editor.chain().focus().toggleTaskList().run()} icon={} variant={editor.isActive('taskList') ? 'secondary' : 'ghost'} /> } onClick={() => inputFileRef.current?.click()} /> ); } export function Editor(): JSX.Element { const { colorScheme } = useTheme(); const editor = useEditor({ extensions: [ StarterKit, Link.configure({ openOnClick: true, linkOnPaste: true, }), Image, TaskList.configure({ HTMLAttributes: { class: 'editor-task-list', }, }), TaskItem.configure({ nested: true, }), Placeholder.configure({ placeholder: 'Add a description', }), ], content: '', }); function handleSubmit(): void { console.log(editor?.getHTML()); } return ( ); }