Skip to main content
The virtual selection extension provides a visual indicator of the selection range when the editor is not focused, useful for showing selection state in collaboration scenarios or when focus is on a toolbar.

Installation

The virtual selection extension is included in the prosekit package.
import { defineVirtualSelection } from 'prosekit/extensions/virtual-selection'

Styling

You need to import the virtual selection styles:
import 'prosekit/extensions/virtual-selection/style.css'

Usage

import { createEditor } from 'prosekit/core'
import { defineVirtualSelection } from 'prosekit/extensions/virtual-selection'
import 'prosekit/extensions/virtual-selection/style.css'

const editor = createEditor({
  extension: defineVirtualSelection()
})

API reference

defineVirtualSelection()

Creates a virtual selection extension that shows the selection range when the editor loses focus.

Behavior

The virtual selection extension:
  • Shows selection when editor is not focused
  • Hides automatically when editor regains focus
  • Maintains selection state across focus changes
  • Works with collaboration to show other users’ selections

Use cases

Toolbar interaction

Keep selection visible while using toolbar buttons

Collaboration

Show selections of multiple users

Dialogs and popovers

Maintain selection context when opening dialogs

Multi-editor views

Show which editor has the logical selection

Examples

With toolbar

import { useEditor } from 'prosekit/react'
import { defineVirtualSelection } from 'prosekit/extensions/virtual-selection'
import 'prosekit/extensions/virtual-selection/style.css'

export default function Editor() {
  const editor = useEditor({ 
    extension: defineVirtualSelection() 
  })

  return (
    <div>
      <Toolbar editor={editor} />
      <ProseKit editor={editor}>
        <div ref={editor.mount} />
      </ProseKit>
    </div>
  )
}

function Toolbar({ editor }) {
  return (
    <div>
      {/* Selection remains visible while interacting with toolbar */}
      <button onClick={() => editor.exec(toggleBold())}>Bold</button>
      <button onClick={() => editor.exec(toggleItalic())}>Italic</button>
    </div>
  )
}

Custom styling

/* Default virtual selection uses a lighter shade */
.prosekit-virtual-selection {
  background-color: rgba(37, 99, 235, 0.2);
}

/* Customize for your theme */
.prosekit-virtual-selection {
  background-color: rgba(59, 130, 246, 0.15);
  border: 1px solid rgba(59, 130, 246, 0.3);
}
  • Collaboration - Multi-user editing
  • Yjs - Real-time collaboration with Yjs
  • Loro - Real-time collaboration with Loro