Skip to content

Commit 004b362

Browse files
committed
Fixes the cursor position when clicking on a Slate block
On pages with many blocks, clicking on a Slate block would cause the click position to be lost, with the cursor jumping to the beginning of the text. Now, we save the position and set it on the Slate block after it is selected.
1 parent cfeb611 commit 004b362

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

packages/volto-slate/src/editor/SlateEditor.jsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class SlateEditor extends Component {
5454
this.createEditor = this.createEditor.bind(this);
5555
this.multiDecorator = this.multiDecorator.bind(this);
5656
this.handleChange = this.handleChange.bind(this);
57+
this.handlePointerDown = this.handlePointerDown.bind(this);
5758
this.getSavedSelection = this.getSavedSelection.bind(this);
5859
this.setSavedSelection = this.setSavedSelection.bind(this);
5960
this.scheduleFocus = this.scheduleFocus.bind(this);
@@ -73,6 +74,31 @@ class SlateEditor extends Component {
7374

7475
this.editor = null;
7576
this.selectionTimeout = null;
77+
this.pendingPointerSelection = null;
78+
}
79+
80+
handlePointerDown(event) {
81+
if (this.props.selected) return;
82+
83+
const nativeEvent = event.nativeEvent || event;
84+
const domPoint = document.caretPositionFromPoint?.(
85+
nativeEvent.clientX,
86+
nativeEvent.clientY,
87+
);
88+
if (!domPoint) return;
89+
90+
try {
91+
const point = ReactEditor.toSlatePoint(
92+
this.state.editor,
93+
[domPoint.offsetNode, domPoint.offset],
94+
{ exactMatch: false, suppressThrow: true },
95+
);
96+
if (point) {
97+
this.pendingPointerSelection = { anchor: point, focus: point };
98+
}
99+
} catch {
100+
this.pendingPointerSelection = null;
101+
}
76102
}
77103

78104
getSavedSelection() {
@@ -185,7 +211,10 @@ class SlateEditor extends Component {
185211
if (!prevProps.selected && this.props.selected) {
186212
// if the SlateEditor becomes selected from unselected
187213

188-
if (window.getSelection().type === 'None') {
214+
if (this.pendingPointerSelection) {
215+
Transforms.select(this.state.editor, this.pendingPointerSelection);
216+
this.pendingPointerSelection = null;
217+
} else if (window.getSelection().type === 'None') {
189218
// TODO: why is this condition checked?
190219
Transforms.select(
191220
this.state.editor,
@@ -325,6 +354,7 @@ class SlateEditor extends Component {
325354
this.props.onBlur && this.props.onBlur();
326355
return null;
327356
}}
357+
onPointerDown={this.handlePointerDown}
328358
onClick={this.props.onClick}
329359
onSelect={(e) => {
330360
if (!selected && this.props.onFocus) {

0 commit comments

Comments
 (0)