---
title: Block Selection
docs:
  - route: /docs/components/block-selection
    title: Block Selection
---

<ComponentPreview name="block-selection-demo" />

<PackageInfo>

The Block Selection feature allows users to select and manipulate entire text blocks, as opposed to individual words or characters. This powerful functionality enhances the editing experience by providing efficient ways to manage large sections of content.

## Features

- Select entire blocks with a single action
- Multi-block selection
- Copy, cut, and delete operations on selected blocks
- Keyboard shortcuts for quick selection:
  - `Cmd+A`:
    - First press: select the current block
    - Double press: select all blocks
  - Arrow keys: select the block above or below
- Customizable styling for selected blocks

</PackageInfo>

## Installation

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

## Usage

```tsx
import { NodeIdPlugin } from '@udecode/plate-node-id';
import { BlockSelectionPlugin } from '@udecode/plate-selection/react';

const plugins = [
  // ...otherPlugins,
  NodeIdPlugin,
  BlockSelectionPlugin,
];
```

### Exclude blocks from selection

You can exclude certain plugins from block selection using:

```ts
BlockSelectionPlugin.configure({
  inject: {
    // Exclude blocks below table rows
    excludeBelowPlugins: ['tr'],
    // Exclude block types
    excludePlugins: ['table', 'code_line', 'column_group', 'column'],
  }
})
```

- `excludeBelowPlugins`: Plugin keys of non-selectable block descendants. Use this to prevent selection below specific blocks. For example, excluding 'tr' prevents selecting individual cells while still allowing table row selection.

- `excludePlugins`: Plugin keys of non-selectable blocks.

### Set scrollable container

If you're using `EditorContainer` from [Editor](/docs/components/editor), you can skip this section.

To control the scrollable container, configure the `boundaries` and `container` options within `areaOptions`. These options accept CSS selectors, such as `#selection-demo #${editor.uid}`, which are used with `document.querySelector()`.

For this to work effectively:

1. Add an `id` or `className` to your scroll container. If you're not sure about the container, you can add it to the `<Editor />` component. We recommend using `id={editor.uid}`.
2. Use the appropriate selector in your configuration.
3. Don't forget to set `position: relative` to the container.

Default configuration:

```js
BlockSelectionPlugin.configure({
  options: {
    areaOptions: {
      boundaries: `#${editor.uid}`,
      container: `#${editor.uid}`,
      selectables: `#${editor.uid} .slate-selectable`,
    },
  },
});
```

### Set scroll speed

Use `options.areaOptions.behaviour.scrolling.speedDivider` to set the scroll speed.

The value `0.8` is our recommended speed since it's near the browser-native speed.


```ts
BlockSelectionPlugin.configure({
  options: {
    areaOptions: {
      behaviour: {
      scrolling: {
        // You can slow down the scroll speed by setting a bigger value.
        speedDivider: 1.5,
      },
      // The distance needed to move for the selection area to appear.
      // If it’s too small, it may cause the mouse click event to be blocked. 10 is a good default.
      startThreshold: 4,
    },
  },
}
```

### Add selectable element

Add `data-plate-selectable="true"` to any element you want to start block selection.

### Prevent unselect

To prevent unselecting blocks when clicking on certain elements, add the `data-plate-prevent-unselect` attribute to those components

For example:
```tsx
  <YourSpecialButtoon data-plate-prevent-unselect />
```

### Full Page Selection

#### Making Elements Selectable

You can enable block selection for elements outside the `<Editor />` component, similar to the [Potion](https://potion.platejs.org/) template. Add the `data-plate-selectable` attribute to any component you want to make selectable:

```tsx
<Cover data-plate-selectable />
<Sidebar data-plate-selectable />
```

This works for any element, even those outside the editor's DOM tree.

#### Resetting Selection

There are two ways to handle resetting selection across the full page:

1. Direct API call:
```tsx
editor.api.blockSelection.unselect();
```

2. Click outside handler:
```tsx
const handleClickOutside = (event: MouseEvent) => {
  if (!(event.target as HTMLElement).closest('[data-plate-selectable]')) {
    editor.api.blockSelection.unselect();
  }
};
```

## Styling

### Selection area

Style the selection area by adding the `.slate-selection-area` class to your editor container component. For example:

```js
'[&_.slate-selection-area]:border [&_.slate-selection-area]:border-primary [&_.slate-selection-area]:bg-primary/10'
```

### Selected element

To determine if an element is selected, use `useBlockSelected` hook. You can render a visual indicator around selected blocks using our [BlockSelection](/docs/components/block-selection) component or create your own.

This component should be rendered inside each block element for consistent selection feedback. Plate UI is doing it in [PlateElement](/docs/components/plate-element).

## Plugins

### BlockSelectionPlugin

<APIOptions>
<APIItem name="areaOptions" type="PartialSelectionOptions" optional>
Options for the selection area. Example:

```ts
{
  boundaries: [`#${editor.uid}`],
  container: [`#${editor.uid}`],
  selectables: [`#${editor.uid} .slate-selectable`],
  selectionAreaClass: 'slate-selection-area',
}
```
</APIItem>

<APIItem name="editorPaddingRight" type="CSSProperties['width']" optional>
The padding-right of the editor.
</APIItem>

<APIItem name="enableContextMenu" type="boolean" optional>
Enables or disables the context menu for block selection.

- **Default:** `false`
</APIItem>

<APIItem name="isSelecting" type="boolean" optional>
Indicates whether block selection is currently active.

- **Default:** `false`
</APIItem>

<APIItem name="onKeyDownSelecting" type="(e: KeyboardEvent) => void" optional>
A function to handle the **`keydown`** event when selecting.
</APIItem>

<APIItem name="query" type="QueryNodeOptions" optional>
Options for querying nodes during block selection.

- **Default:** `{ maxLevel: 1 }`
</APIItem>

<APIItem name="selectedIds" type="Set<string>" optional>
A set of IDs for the currently selected blocks.

- **Default:** `new Set()`
</APIItem>
</APIOptions>

### BlockMenuPlugin

## API

### editor.api.blockSelection.focus
Focuses the block selection shadow input. This input handles copy, delete, and paste events for selected blocks.

### editor.api.blockSelection.addSelectedRow

Adds a selected row to the block selection.

<APIParameters>
  <APIItem name="id" type="string">
    The ID of the row to be selected.
  </APIItem>
  <APIItem name="options" type="object" optional>
    <APISubList>
      <APISubListItem parent="options" name="clear" type="boolean" optional>
        Whether to clear existing selections before adding the new one.
        - **Default:** `true`
      </APISubListItem>
    </APISubList>
  </APIItem>
</APIParameters>

### editor.api.blockSelection.getNodes

Gets the selected blocks in the editor.

<APIReturns>
  <APIItem type="TNodeEntry[]">
    An array of selected block entries.
  </APIItem>
</APIReturns>

### editor.api.blockSelection.resetSelectedIds

Resets the set of selected IDs to an empty set.

### editor.api.blockSelection.selectedAll

Selects all selectable blocks in the editor.

### editor.api.blockSelection.setSelectedIds

Sets the selected IDs based on added and removed elements.

<APIParameters>
  <APIItem name="options" type="ChangedElements">
    <APISubList>
      <APISubListItem parent="options" name="added" type="HTMLElement[]">
        Array of HTML elements to be added to the selection.
      </APISubListItem>
      <APISubListItem parent="options" name="removed" type="HTMLElement[]">
        Array of HTML elements to be removed from the selection.
      </APISubListItem>
    </APISubList>
  </APIItem>
</APIParameters>

### editor.api.blockSelection.unselect

Unselects all blocks and sets the `isSelecting` flag to false.

## Transforms

### editor.tf.blockSelection.duplicate

Duplicates the selected blocks.

<APIParameters>
  <APIItem name="blocks" type="TNodeEntry[]">
    An array of node entries to duplicate.
  </APIItem>
</APIParameters>

### editor.tf.blockSelection.removeNodes

Removes the selected nodes from the editor.

### editor.tf.blockSelection.select

Selects the nodes returned by `getNodes()` and resets the selected IDs.

### editor.tf.blockSelection.setNodes

Sets properties on the selected nodes.

<APIParameters>
  <APIItem name="props" type="Partial<TNodeProps<TElement>>">
    The properties to set on the selected nodes.
  </APIItem>
  <APIItem name="options" type="SetNodesOptions" optional>
    Options for setting nodes.
  </APIItem>
</APIParameters>

### editor.tf.blockSelection.setTexts

Sets text properties on the selected nodes.

<APIParameters>
  <APIItem name="props" type="Partial<TNodeProps<TText>>">
    The text properties to set on the selected nodes.
  </APIItem>
  <APIItem name="options" type="Omit<SetNodesOptions, 'at'>" optional>
    Options for setting text nodes, excluding the 'at' property.
  </APIItem>
</APIParameters>

## Hooks

### useBlockSelectable

A hook that provides props for making a block element selectable, including context menu behavior.

<APIReturns>
  <APIItem name="props" type="object">
    Props to be spread on the block element:
    <APISubList>
      <APISubListItem parent="props" name="className" type="string">
        `'slate-selectable'` - Required class for selection functionality
      </APISubListItem>
      <APISubListItem parent="props" name="onContextMenu" type="(event: React.MouseEvent) => void">
        Handles right-click context menu behavior:
        - Opens context menu for selected blocks
        - Opens for void elements
        - Opens for elements with `data-plate-open-context-menu="true"`
        - Adds block to selection with Shift key for multi-select
      </APISubListItem>
    </APISubList>
  </APIItem>
</APIReturns>

### useBlockSelected

Returns true if context block is selected.

### useBlockSelectionNodes

Returns an array of node entries for the currently selected blocks.

### useBlockSelectionFragment

Returns an array of nodes for the currently selected blocks.

### useBlockSelectionFragmentProp

Returns fragment prop for the currently selected blocks.

### useSelectionArea

A hook that initializes and manages the selection area functionality.
