Skip to content

Basic Editor

A basic editor component.

Installation

extension.ts

To begin, you need to define the editor extensions by creating an extension.ts file.

ts
import { defineBasicExtension } from 'prosekit/basic'

export function defineExtension() {
  return defineBasicExtension()
}

export type EditorExtension = ReturnType<typeof defineExtension>

For now, we simply use the defineBasicExtensions(). You might want to customize the extensions to suit your needs. The extensions defined here will determine the available commands later on. Refer to the Extensions guide for more information.

The EditorExtension type is exported to provide type safety and enhance the developer experience with TypeScript's type hints and autocompletion.

Editor

After that, we can create the Editor component by copying the following code into our project.

tsx
import 'prosekit/basic/style.css'

import { createEditor, jsonFromNode, type NodeJSON } from 'prosekit/core'
import type { ProseMirrorNode } from 'prosekit/pm/model'
import { ProseKit, useDocChange } from 'prosekit/react'
import { useCallback, useMemo } from 'react'

import { defineExtension } from './extension'

export default function Editor({
  defaultContent,
  onDocUpdate,
}: {
  defaultContent?: NodeJSON
  onDocUpdate?: (doc: NodeJSON) => void
}) {
  const editor = useMemo(() => {
    const extension = defineExtension()
    return createEditor({ extension, defaultContent })
  }, [defaultContent])

  const handleDocChange = useCallback(
    (doc: ProseMirrorNode) => onDocUpdate?.(jsonFromNode(doc)),
    [onDocUpdate],
  )
  useDocChange(handleDocChange, { editor })

  return (
    <ProseKit editor={editor}>
      <div className='box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 shadow dark:border-zinc-700 flex flex-col bg-white dark:bg-neutral-900'>
        <div className='relative w-full flex-1 box-border overflow-y-scroll'>
          <div ref={editor.mount} className='ProseMirror box-border min-h-full px-[max(4rem,_calc(50%-20rem))] py-8 outline-none outline-0 [&_span[data-mention="user"]]:text-blue-500 [&_span[data-mention="tag"]]:text-violet-500 [&_pre]:text-white [&_pre]:bg-zinc-800'></div>
        </div>
      </div>
    </ProseKit>
  )
}

Editor accepts defaultDoc and onDocUpdate as props.

  • defaultDoc is the initial document represented as a JSON object.
  • onDocUpdate is a callback that is called when the document is updated.

Now you can import the Editor component and start using it!