Block Selection
Select and manipulate entire text blocks.
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
Installation
npm install @udecode/plate-selection @udecode/plate-node-id
Usage
import { NodeIdPlugin } from '@udecode/plate-node-id';
import { BlockSelectionPlugin } from '@udecode/plate-selection/react';
const plugins = [
// ...otherPlugins,
NodeIdPlugin,
BlockSelectionPlugin,
];
Configuration
Set scrollable container
To control the scrollable container, configure the boundaries
and container
options within areaOptions
. These options accept CSS selectors, such as #selection-demo #scroll_container
, which are used with document.querySelector()
.
For this to work effectively:
- Add an
id
orclassName
to your scroll container.If you not sure about the container, you can add it to the<Editor />
component. - Use the appropriate selector in your configuration.
- Don't forget to set
position: relative
to your scroll container.
Example configuration:
{
areaOptions: {
boundaries: '#your-scroll-container-id',
container: '#your-scroll-container-id',
selectables: '#your-scroll-container-id .slate-selectable',
selectionAreaClass: 'slate-selection-area',
}
}
This setup ensures that the block selection functionality is properly constrained within your designated scrollable area.
Set selectable element
Add data-plate-selectable to the container or the element you want to start block selection.
Example:
<PlateContent
aria-disabled={disabled}
className={cn(
editorVariants({
disabled,
focusRing,
focused,
size,
variant,
}),
className
)}
data-plate-selectable
disableDefaultStyles
readOnly={disabled ?? readOnly}
{...props}
/>
Set scroll speed
useing options.areaOptions.behaviour.scrolling.speedDivider
to set the scroll speed.
The value of 1.5
is our recommended speed.Since it's same with the default speed of the browser.
areaOptions: {
behaviour: {
scrolling: {
speedDivider: 1.5,
},
},
},
Full configuration recommended:
options: {
areaOptions: {
behaviour: {
scrolling: {
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. 30 is a good default.
startThreshold: 30,
},
boundaries: '#your-scroll-container-id',
container: '#your-scroll-container-id',
selectables: '#your-scroll-container-id .slate-selectable',
selectionAreaClass: 'slate-selection-area',
},
// if not using plate-ui context menu, set it to false
enableContextMenu: true,
},
Styling
Selection area
Style the selection area using .slate-selection-area
class. For example:
'[&_.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 the new useBlockSelected
hook. You can render a visual indicator around selected blocks using our BlockSelection
component or create your own:
import React from 'react';
import { useBlockSelected } from '@udecode/plate-selection/react';
export function BlockSelection() {
const isBlockSelected = useBlockSelected();
return (
<div
className={`pointer-events-none absolute inset-0 z-10 bg-primary/15 ${
isBlockSelected ? 'opacity-100' : 'opacity-0'
}`}
/>
);
}
This component should be rendered inside each block element for consistent selection feedback. Plate UI is doing it in plate-element.tsx
.
Disable browser default scroll behavior
When selecting text and moving the cursor to the bottom of the page, the browser's default scroll behavior can conflict with the BlockSelectionPlugin
. To mitigate this, you can add a non-selectable area to the right side of the editor:
<div className="absolute right-0 top-0 h-full w-4 select-none" />
This helps prevent unexpected scrolling during selection operations.
Plugins
BlockSelectionPlugin
Options
- Default:
false
- Default:
false
- Default:
{ maxLevel: 1 }
- Default:
new Set()
Options for the selection area. Example:
{
boundaries: ['#selection-demo #scroll_container'],
container: ['#selection-demo #scroll_container'],
selectables: ['#selection-demo #scroll_container .slate-selectable'],
selectionAreaClass: 'slate-selection-area',
}
The padding-right of the editor.
Enables or disables the context menu for block selection.
Indicates whether block selection is currently active.
A function to handle the keydown
event when selecting.
Options for querying nodes during block selection.
A set of IDs for the currently selected blocks.
BlockMenuPlugin
API
editor.api.blockSelection.addSelectedRow
Adds a selected row to the block selection.
Parameters
The ID of the row to be selected.
editor.api.blockSelection.getNodes
Gets the selected blocks in the editor.
Returns
An array of selected block entries.
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.
Parameters
editor.api.blockSelection.unselect
Unselects all blocks and sets the isSelecting
flag to false.
Transforms
editor.tf.blockSelection.duplicate
Duplicates the selected blocks.
Parameters
An array of node entries to duplicate.
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.
Parameters
The properties to set on the selected nodes.
Options for setting nodes.
editor.tf.blockSelection.setTexts
Sets text properties on the selected nodes.
Parameters
The text properties to set on the selected nodes.
Options for setting text nodes, excluding the 'at' property.
API Components
BlockSelectable
Props
BlockSelection
A wrapper component that adds block selection functionality to its children.
Props
The content to be wrapped with block selection functionality.
Hooks
useBlockSelected
Returns true if context block is selected.
useBlockSelectableState
Returns
Whether the block is active for selection.
The element associated with the block.
The path of the block in the editor.
A ref to the block's DOM element.
useBlockSelectable
Returns
Props to be spread on the block's wrapper element.
useSelectionArea
A hook that initializes and manages the selection area functionality.
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.
Customizable and extensible.