Closed
Description
Describe the bug
Using the table component may occasionally result in an error when refreshing.
src\components\editor\editor.tsx
'use client'
import { BlockNoteEditor, type Block, type PartialBlock } from '@blocknote/core'
import '@blocknote/core/fonts/inter.css'
import { BlockNoteView } from '@blocknote/mantine'
import '@blocknote/mantine/style.css'
import { FormattingToolbar } from '@blocknote/react'
import './editor.css'
import React from 'react'
// Props interface
interface EditorProps {
onChange: (editor: Block[]) => void
initialContent: PartialBlock[] | undefined | "loading"
editable: boolean
}
// Uploads a file to tmpfiles.org and returns the URL to the uploaded file.
async function uploadFile(file: File) {
const body = new FormData()
body.append('file', file)
const ret = await fetch('https://tmpfiles.org/api/v1/upload', {
method: 'POST',
body: body
})
return (await ret.json()).data.url.replace('tmpfiles.org/', 'tmpfiles.org/dl/')
}
const Editor = ({ onChange, initialContent, editable = true }: EditorProps) => {
// Creates a new editor instance.
// const editor = useCreateBlockNote({
// initialContent: initialContent || [{ type: 'paragraph', content: '' }],
// uploadFile
// })
const editor = React.useMemo(() => {
if (initialContent === "loading") {
return undefined;
}
return BlockNoteEditor.create({ initialContent, uploadFile });
}, [initialContent]);
if (editor === undefined) {
return "載入中";
}
// Renders the editor instance using a React component.
return (
// 強制使用 light theme
<BlockNoteView
editor={editor}
onChange={() => onChange(editor.document)}
editable={editable}
theme='light'
>
<div className='msi-editor-toolbar'>
<FormattingToolbar />
</div>
</BlockNoteView>
)
}
export default Editor
src\components\editor\index.tsx
'use client'
import dynamic from 'next/dynamic'
export default dynamic(() => import('./editor'), { ssr: false })
src\app\[locale]\editor
'use client'
import Editor from '@/components/editor'
import { Block, PartialBlock } from '@blocknote/core'
import React from 'react'
const loadContent = async () => {
const content = localStorage.getItem('content')
return content ? JSON.parse(content) : undefined
}
const EditorPage = () => {
const [content, setContent] = React.useState<PartialBlock[] | undefined | 'loading'>('loading')
React.useEffect(() => {
loadContent().then((content) => {
setContent(content)
})
}, [])
// React.useEffect(() => {
// console.log("content", content)
// }, [content])
const handleContentChange = async (content: Block[]) => {
localStorage.setItem('content', JSON.stringify(content))
}
return (
<div className='w-full flex'>
<div className='shadow-md rounded-md p-4 w-full'>
<Editor onChange={handleContentChange} initialContent={content} editable />
</div>
<div className='w-full'>
<pre>{JSON.stringify(content, null, 2)}</pre>
</div>
</div>
)
}
export default EditorPage
2024-11-21.09-21-08.mp4
To Reproduce
https://stackblitz.com/edit/stackblitz-starters-f4jjzy?file=app%2Fpage.tsx
Misc
- Node version: v20.15.0
- Package manager: pnpm 9.6.0
- Browser:
- I'm a sponsor and would appreciate if you could look into this sooner than later 💖