Cursor Overlay

Loading...
Files
components/demo.tsx
'use client';

import React from 'react';

import { Plate } from '@udecode/plate/react';

import { editorPlugins } from '@/components/editor/plugins/editor-plugins';
import { useCreateEditor } from '@/components/editor/use-create-editor';
import { Editor, EditorContainer } from '@/components/plate-ui/editor';

import { DEMO_VALUES } from './values/demo-values';

export default function Demo({ id }: { id: string }) {
  const editor = useCreateEditor({
    plugins: [...editorPlugins],
    value: DEMO_VALUES[id],
  });

  return (
    <Plate editor={editor}>
      <EditorContainer variant="demo">
        <Editor />
      </EditorContainer>
    </Plate>
  );
}

The Cursor Overlay feature provides visual feedback for selections and cursor positions, particularly useful for maintaining context when the editor loses focus or during drag operations.

Features

  • Maintains selection highlight when another element is focused
  • Dynamic selection (e.g. during AI streaming)
  • Shows cursor position during drag operations
  • Customizable styling for cursors and selections
  • Essential for external UI interactions (e.g. link toolbar, AI combobox)

Installation

npm install @udecode/plate-selection

Usage

import { CursorOverlayPlugin } from '@udecode/plate-selection/react';
import { CursorOverlay } from '@/components/plate-ui/cursor-overlay';
const plugins = [
  // ...otherPlugins,
  CursorOverlayPlugin.configure({
    render: { afterEditable: () => <CursorOverlay /> },
  }),
];

Editor Container

The editor requires a container component above PlateContent to ensure correct cursor overlay positioning:

export function EditorContainer(props: React.HTMLAttributes<HTMLDivElement>) {
  const editor = useEditorRef();
  const containerRef = useEditorContainerRef();
 
  return <div id={editor.uid} ref={containerRef} {...props} />;
}

This component is available in Editor.

Preserving Selection Focus

To maintain the editor's selection state when focusing UI elements, add the data-plate-focus="true" attribute to those elements:

<ToolbarButton data-plate-focus="true">
  {/* toolbar content */}
</ToolbarButton>

Plugins

CursorOverlayPlugin

Options

Collapse all

    Object containing cursor states.

    • Default: {}

API

editor.api.cursorOverlay.addCursor

Parameters

Collapse all

    Unique identifier for the cursor (e.g., 'blur', 'drag', 'custom').

    The cursor state including selection and optional styling data.

editor.api.cursorOverlay.removeCursor

Parameters

Collapse all

    The key of the cursor to remove.

Hooks

useCursorOverlay

Parameters

Collapse all

    Options for cursor overlay behavior.

Optionsobject

Collapse all

    Minimum width in pixels for a selection rectangle.

    • Default: 1

    Whether to recalculate cursor positions when the container is resized.

    • Default: true

Returnsobject

Collapse all

    Array of cursor states with their corresponding selection rectangles and styling data.

    Function to manually trigger a recalculation of cursor positions.