Block Selection
'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 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,
];
Exclude blocks from selection
You can exclude certain plugins from block selection using:
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, 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:
- Add an
id
orclassName
to your scroll container. If you're not sure about the container, you can add it to the<Editor />
component. We recommend usingid={editor.uid}
. - Use the appropriate selector in your configuration.
- Don't forget to set
position: relative
to the container.
Default configuration:
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.
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:
<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 template. Add the data-plate-selectable
attribute to any component you want to make selectable:
<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:
- Direct API call:
editor.api.blockSelection.unselect();
- Click outside handler:
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:
'[&_.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 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.
Plugins
BlockSelectionPlugin
API
editor.api.blockSelection.add
editor.api.blockSelection.getNodes
editor.api.blockSelection.resetSelectedIds
Reset the set of selected IDs to an empty set.
editor.api.blockSelection.selectedAll
Select all selectable blocks in the editor.
editor.api.blockSelection.setSelectedIds
editor.api.blockSelection.unselect
Unselect all blocks and set isSelecting
to false.
Transforms
editor.tf.blockSelection.duplicate
Duplicate the selected blocks.
editor.tf.blockSelection.removeNodes
Remove the selected nodes from the editor.
editor.tf.blockSelection.select
Select the nodes returned by getNodes()
and reset selected IDs.
editor.tf.blockSelection.setNodes
editor.tf.blockSelection.setTexts
Hooks
useBlockSelectable
useBlockSelected
useBlockSelectionNodes
useBlockSelectionFragment
useBlockSelectionFragmentProp
useSelectionArea
Initialize and manage selection area functionality.