Cursor Overlay

Visual feedback for selections and cursor positions when editor loses focus.

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

import * as React from 'react';

import { Plate, usePlateEditor } from 'platejs/react';

import { EditorKit } from '@/components/editor/editor-kit';
import { Editor, EditorContainer } from '@/components/ui/editor';

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

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

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

Features

  • Maintains selection highlight when another element is focused.
  • Dynamic selection display (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).

Kit Usage

Installation

The fastest way to add cursor overlay functionality is with the CursorOverlayKit, which includes the pre-configured CursorOverlayPlugin and the CursorOverlay UI component.

'use client';
 
import { CursorOverlayPlugin } from '@platejs/selection/react';
 
import { CursorOverlay } from '@/components/ui/cursor-overlay';
 
export const CursorOverlayKit = [
  CursorOverlayPlugin.configure({
    render: {
      afterEditable: () => <CursorOverlay />,
    },
  }),
];

Add Kit

import { createPlateEditor } from 'platejs/react';
import { CursorOverlayKit } from '@/components/editor/plugins/cursor-overlay-kit';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    ...CursorOverlayKit,
  ],
});

Manual Usage

Installation

pnpm add @platejs/selection

Add Plugin

import { CursorOverlayPlugin } from '@platejs/selection/react';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    CursorOverlayPlugin,
  ],
});

Configure Plugin

Configure the cursor overlay with a component to render overlays:

import { CursorOverlayPlugin } from '@platejs/selection/react';
import { CursorOverlay } from '@/components/ui/cursor-overlay';
 
CursorOverlayPlugin.configure({
  render: {
    afterEditable: () => <CursorOverlay />,
  },
});
  • render.afterEditable: Assigns CursorOverlay to render after the editable content.

Editor Container Setup

The cursor overlay requires a container component to ensure correct positioning. If you're using the Editor component, this is handled automatically through EditorContainer.

For custom setups, ensure your editor is wrapped with a container that has the editor's unique ID:

import { PlateContainer } from 'platejs/react';
 
export function EditorContainer(props: React.HTMLAttributes<HTMLDivElement>) {
  return <PlateContainer {...props} />;
}

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>

This prevents the cursor overlay from disappearing when interacting with toolbar buttons or other UI elements.

Plugins

CursorOverlayPlugin

Plugin that manages cursor and selection overlays for visual feedback.

Options

Collapse all

    Object containing cursor states with their unique identifiers.

    • Default: {}

API

api.cursorOverlay.addCursor

Adds a cursor overlay with the specified key and state.

Parameters

Collapse all

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

    The cursor state including selection and optional styling data.

api.cursorOverlay.removeCursor

Removes a cursor overlay by its key.

Parameters

Collapse all

    The key of the cursor to remove.

Hooks

useCursorOverlay

A hook that manages cursor and selection overlay states, providing real-time cursor positions and selection rectangles.

Optionsobject

Collapse all

    Minimum width in pixels for a selection rectangle. Useful for making cursor carets more visible.

    • 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.