---
title: Cursor Overlay
docs:
  - route: /docs/components/cursor-overlay
    title: Cursor Overlay
---

<ComponentPreview name="cursor-overlay-demo" />

<PackageInfo>

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)

</PackageInfo>

## Installation

```bash
npm install @udecode/plate-selection
```

## Usage

```tsx
import { CursorOverlayPlugin } from '@udecode/plate-selection/react';
import { CursorOverlay } from '@/components/plate-ui/cursor-overlay';
```

- [CursorOverlay](/docs/components/cursor-overlay)

```tsx
const plugins = [
  // ...otherPlugins,
  CursorOverlayPlugin.configure({
    render: { afterEditable: () => <CursorOverlay /> },
  }),
];
```

### Editor Container

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

```tsx
export const 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](/docs/components/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:

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

## Plugins

### CursorOverlayPlugin

Plugin that manages cursor and selection overlays.

<APIOptions>
<APIItem name="cursors" type="Record<string, CursorState<CursorData>>">
Object containing cursor states. Default: `{}`
</APIItem>
</APIOptions>

## API

### editor.api.cursorOverlay.addCursor

Adds a cursor overlay with the specified key and state.

<APIParameters>
  <APIItem name="key" type="string">
    Unique identifier for the cursor (e.g., 'blur', 'drag', 'custom').
  </APIItem>
  <APIItem name="cursor" type="CursorState<CursorData>">
    The cursor state including selection and optional styling data.
  </APIItem>
</APIParameters>

### editor.api.cursorOverlay.removeCursor

Removes a cursor overlay by its key.

<APIParameters>
  <APIItem name="key" type="string">
    The key of the cursor to remove.
  </APIItem>
</APIParameters>

## Hooks

### useCursorOverlay

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

<APIParameters>
  <APIItem name="options" type="object" optional>
    <APISubList>
      <APISubListItem parent="options" name="minSelectionWidth" type="number" optional>
        Minimum width in pixels for a selection rectangle. Useful for making cursor carets more visible.
        - **Default:** `1`
      </APISubListItem>
      <APISubListItem parent="options" name="refreshOnResize" type="boolean" optional>
        Whether to recalculate cursor positions when the container is resized.
        - **Default:** `true`
      </APISubListItem>
    </APISubList>
  </APIItem>
</APIParameters>

<APIReturns>
  <APIItem name="cursors" type="CursorOverlayState<TCursorData>[]">
    Array of cursor states with their corresponding selection rectangles and styling data.
  </APIItem>
  <APIItem name="refresh" type="() => void">
    Function to manually trigger a recalculation of cursor positions.
  </APIItem>
</APIReturns>
