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:
parent
9adcd50519
commit
0e5960f6d5
1 changed files with 49 additions and 41 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue