ProseMirror / prosemirror

The ProseMirror WYSIWYM editor
http://prosemirror.net/
MIT License
7.53k stars 334 forks source link

unable to find guidance for error: "Plugins passed directly to the view must not have a state component" #1431

Closed vladnicula closed 7 months ago

vladnicula commented 7 months ago

I'm new, and am attempting to run a basic example using a nextjs page bellow:

'use client'

import { Schema, NodeSpec } from 'prosemirror-model'
import { EditorState } from 'prosemirror-state'
import { EditorView } from 'prosemirror-view'
import { baseKeymap } from 'prosemirror-commands'
import { history, undo, redo } from 'prosemirror-history'
import { keymap } from 'prosemirror-keymap'

const initialContent = {
    type: 'doc',
    content: [
        { type: 'paragraph', content: [{ type: 'text', text: 'This is some initial content.' }] },
    ],
}

import { useCallback, useEffect, useRef } from 'react'

import './prose-mirror-editor.css'

export default function Page () {
    const handleContentChange = useCallback((content: Object) => {
        console.log('Editor content changed:', content)
    }, [])

    return (
        <ProseMirrorEditor
            initialContent={initialContent}
            onChange={handleContentChange}
        />
    )
}

const ProseMirrorEditor = (props: {
    initialContent: Record<string, unknown>
    onChange: (content: Record<string, unknown>) => void
}) => {
    const { initialContent, onChange } = props
    const editorRef = useRef<HTMLDivElement>(null)

    useEffect(() => {
        if (!editorRef.current) return
        // Define the nodes in the schema
        const nodes: { [key: string]: NodeSpec } = {
            doc: {
                content: 'paragraph+',
            },
            paragraph: {
                content: 'text*',
                toDOM() { return ['p', 0] }
            },
            text: {
                toDOM(node) { return node.text! }
            }
        }

        // Create a schema with the nodes
        const schema = new Schema({ nodes })

        const initialDoc = schema.nodeFromJSON(initialContent ?? {})

        // Create the editor state
        const state = EditorState.create({
            doc: initialDoc,
            schema
        })

        // Initialize the editor view
        const editorView = new EditorView(editorRef.current, {
            state,
            plugins: [
                keymap({
                    'Mod-z': undo,
                    'Mod-y': redo,
                    'Mod-Shift-z': redo,
                }),
                keymap(baseKeymap),
                history(),
            ],
            dispatchTransaction(transaction) {
                console.log('Document Size:', transaction.doc.content.size)
                const newState = editorView.state.apply(transaction)
                editorView.updateState(newState)
            }
        })

        const handleBlur = () => {
            onChange(state.doc.toJSON())
        }

        editorView.dom.addEventListener('blur', handleBlur)

        return () => {
            editorView.destroy()
            editorView.dom.removeEventListener('blur', handleBlur)
        }
    }, [initialContent, onChange])

    return <div className='prose-mirror' ref={editorRef}></div>
}

I am getting an error which I cannot see any info about by googling, GPT-ing or stackoverflowing it: Plugins passed directly to the view must not have a state component

Screenshot 2023-11-25 at 15 59 04

Any tips, links to docs where I can read about this, or how to tackle it would be great.

Commenting out the history() call prevent the error, but I need undo/redo.

Thanks!

vladnicula commented 7 months ago
plugins: [
                keymap({
                    'Mod-z': undo,
                    'Mod-y': redo,
                    'Mod-Shift-z': redo,
                }),
                keymap(baseKeymap),
                history(),
            ],

should have been defined in the state, not the editor. Found this by looking at the example https://prosemirror.net/examples/basic/.