Reinstantiate editor on changes

We can't dynamically update the content, so we have to recreate the Editor whenever something changes (page loads and updates)
This commit is contained in:
Justin Edmund 2023-07-06 00:42:37 -07:00
parent 9adcd50519
commit 0e5960f6d5

View file

@ -1,4 +1,4 @@
import { ComponentProps, useCallback } from 'react' import { ComponentProps, useCallback, useEffect, useState } from 'react'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { useEditor, EditorContent } from '@tiptap/react' import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit' import StarterKit from '@tiptap/starter-kit'
@ -8,6 +8,7 @@ import CustomMention from '~extensions/CustomMention'
import classNames from 'classnames' import classNames from 'classnames'
import { mentionSuggestionOptions } from '~utils/mentionSuggestions' import { mentionSuggestionOptions } from '~utils/mentionSuggestions'
import { Editor as TiptapEditor } from '@tiptap/core'
import type { JSONContent } from '@tiptap/core' import type { JSONContent } from '@tiptap/core'
import styles from './index.module.scss' import styles from './index.module.scss'
@ -30,6 +31,8 @@ const Editor = ({
const router = useRouter() const router = useRouter()
const locale = router.locale || 'en' const locale = router.locale || 'en'
const [editor, setEditor] = useState<TiptapEditor | undefined>(undefined)
function isJSON(content?: string) { function isJSON(content?: string) {
if (!content) return false if (!content) return false
@ -41,25 +44,9 @@ const Editor = ({
return true return true
} }
function formatContent(content?: string) { useEffect(() => {
if (!content) return '' editor?.destroy()
if (isJSON(content)) return JSON.parse(content) const newEditor: TiptapEditor = new TiptapEditor({
else {
// Otherwise, create a new <p> tag after each double newline.
// Add < br /> tags for single newlines.
// Add a < br /> after each paragraph.
const paragraphs = content.split('\n\n')
const formatted = paragraphs
.map((p) => {
const lines = p.split('\n')
return lines.join('<br />')
})
.join('</p><br /><p>')
return formatted
}
}
const editor = useEditor({
content: formatContent(content), content: formatContent(content),
editable: editable, editable: editable,
editorProps: { editorProps: {
@ -99,6 +86,27 @@ const Editor = ({
}, },
}) })
setEditor(newEditor)
}, [content])
function formatContent(content?: string) {
if (!content) return ''
if (isJSON(content)) return JSON.parse(content)
else {
// Otherwise, create a new <p> tag after each double newline.
// Add < br /> tags for single newlines.
// Add a < br /> after each paragraph.
const paragraphs = content.split('\n\n')
const formatted = paragraphs
.map((p) => {
const lines = p.split('\n')
return lines.join('<br />')
})
.join('</p><br /><p>')
return formatted
}
}
const setLink = useCallback(() => { const setLink = useCallback(() => {
const previousUrl = editor?.getAttributes('link').href const previousUrl = editor?.getAttributes('link').href
const url = window.prompt('URL', previousUrl) const url = window.prompt('URL', previousUrl)