Skip to content

Commit 404ef6f

Browse files
authored
fix: overriding scrollselectionintoview to stop scrolling [] (#1887)
1 parent 44e5546 commit 404ef6f

File tree

5 files changed

+65
-34
lines changed

5 files changed

+65
-34
lines changed

packages/rich-text/src/RichTextEditor.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import { FieldAppSDK } from '@contentful/app-sdk';
44
import { EntityProvider } from '@contentful/field-editor-reference';
55
import { FieldConnector } from '@contentful/field-editor-shared';
66
import * as Contentful from '@contentful/rich-text-types';
7-
import { PlateContent, Plate, PlatePlugin } from '@udecode/plate-common';
7+
import { PlateContent, Plate, PlatePlugin, PlateContentProps } from '@udecode/plate-common';
88
import { css, cx } from 'emotion';
99
import deepEquals from 'fast-deep-equal';
1010
import noop from 'lodash/noop';
1111

1212
import { ContentfulEditorIdProvider, getContentfulEditorId } from './ContentfulEditorProvider';
13+
import { defaultScrollSelectionIntoView } from './editor-overrides';
1314
import { toSlateValue } from './helpers/toSlateValue';
1415
import { normalizeInitialValue } from './internal/misc';
1516
import { getPlugins, disableCorePlugins } from './plugins';
@@ -58,7 +59,7 @@ export const ConnectedRichTextEditor = (props: ConnectedRichTextProps) => {
5859
const id = getContentfulEditorId(sdk);
5960
const plugins = React.useMemo(
6061
() => getPlugins(sdk, onAction ?? noop, restrictedMarks),
61-
[sdk, onAction, restrictedMarks]
62+
[sdk, onAction, restrictedMarks],
6263
);
6364

6465
const initialValue = React.useMemo(() => {
@@ -67,7 +68,7 @@ export const ConnectedRichTextEditor = (props: ConnectedRichTextProps) => {
6768
plugins,
6869
disableCorePlugins,
6970
},
70-
toSlateValue(props.value)
71+
toSlateValue(props.value),
7172
);
7273
}, [props.value, plugins]);
7374

@@ -80,7 +81,7 @@ export const ConnectedRichTextEditor = (props: ConnectedRichTextProps) => {
8081
props.maxHeight !== undefined ? css({ maxHeight: props.maxHeight }) : undefined,
8182
props.isDisabled ? styles.disabled : styles.enabled,
8283
props.isToolbarHidden && styles.hiddenToolbar,
83-
direction === 'rtl' ? styles.rtl : styles.ltr
84+
direction === 'rtl' ? styles.rtl : styles.ltr,
8485
);
8586

8687
return (
@@ -103,7 +104,14 @@ export const ConnectedRichTextEditor = (props: ConnectedRichTextProps) => {
103104
</StickyToolbarWrapper>
104105
)}
105106
<SyncEditorChanges incomingValue={initialValue} onChange={props.onChange} />
106-
<PlateContent id={id} className={classNames} readOnly={props.isDisabled} />
107+
<PlateContent
108+
id={id}
109+
className={classNames}
110+
readOnly={props.isDisabled}
111+
scrollSelectionIntoView={
112+
defaultScrollSelectionIntoView as PlateContentProps['scrollSelectionIntoView']
113+
}
114+
/>
107115
</Plate>
108116
</div>
109117
</ContentfulEditorIdProvider>
@@ -124,7 +132,7 @@ const RichTextEditor = (props: RichTextProps) => {
124132
} = props;
125133
const isEmptyValue = React.useCallback(
126134
(value) => !value || deepEquals(value, Contentful.EMPTY_DOCUMENT),
127-
[]
135+
[],
128136
);
129137
React.useEffect(() => {
130138
if (!onChange) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './scroll-selection-into-view';
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* TODO: This is an override from a later version of slate-react
3+
* ultimately instead of overriding we want to upgrade the version
4+
*
5+
* https://github.com/ianstormtaylor/slate/pull/5902/files
6+
*/
7+
import scrollIntoView from 'scroll-into-view-if-needed';
8+
9+
import { DOMRange, ReactEditor, Range } from '../internal';
10+
11+
export const defaultScrollSelectionIntoView = (editor: ReactEditor, domRange: DOMRange) => {
12+
// This was affecting the selection of multiple blocks and dragging behavior,
13+
// so enabled only if the selection has been collapsed.
14+
if (
15+
domRange.getBoundingClientRect &&
16+
(!editor.selection || (editor.selection && Range.isCollapsed(editor.selection)))
17+
) {
18+
const leafEl = domRange.startContainer.parentElement!;
19+
20+
// COMPAT: In Chrome, domRange.getBoundingClientRect() can return zero dimensions for valid ranges (e.g. line breaks).
21+
// When this happens, do not scroll like most editors do.
22+
const domRect = domRange.getBoundingClientRect();
23+
const isZeroDimensionRect =
24+
domRect.width === 0 && domRect.height === 0 && domRect.x === 0 && domRect.y === 0;
25+
26+
if (isZeroDimensionRect) {
27+
const leafRect = leafEl.getBoundingClientRect();
28+
const leafHasDimensions = leafRect.width > 0 || leafRect.height > 0;
29+
30+
if (leafHasDimensions) {
31+
return;
32+
}
33+
}
34+
35+
// Default behavior: use domRange's getBoundingClientRect
36+
leafEl.getBoundingClientRect = domRange.getBoundingClientRect.bind(domRange);
37+
scrollIntoView(leafEl, {
38+
scrollMode: 'if-needed',
39+
});
40+
// @ts-expect-error an unorthodox delete D:
41+
delete leafEl.getBoundingClientRect;
42+
}
43+
};

packages/rich-text/src/internal/types/editor.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { MARKS } from '@contentful/rich-text-types';
55
import * as p from '@udecode/plate-common';
66
import * as s from 'slate';
77
import * as sr from 'slate-react';
8+
import { DOMRange as SlateReactDomRange } from 'slate-react/dist/utils/dom';
89
import type {
910
SelectionMoveOptions as SlateSelectionMoveOptions,
1011
SelectionCollapseOptions as SlateSelectionCollapseOptions,
@@ -67,3 +68,6 @@ export type Span = p.TSpan;
6768
export type BasePoint = s.BasePoint;
6869
export type BaseSelection = s.BaseSelection;
6970
export type PathRef = s.PathRef;
71+
export type DOMRange = SlateReactDomRange;
72+
73+
export const Range = s.Range;

yarn.lock

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22247,7 +22247,7 @@ string-natural-compare@^3.0.1:
2224722247
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
2224822248
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
2224922249

22250-
"string-width-cjs@npm:string-width@^4.2.0":
22250+
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
2225122251
version "4.2.3"
2225222252
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
2225322253
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -22265,15 +22265,6 @@ string-width@^1.0.1:
2226522265
is-fullwidth-code-point "^1.0.0"
2226622266
strip-ansi "^3.0.0"
2226722267

22268-
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
22269-
version "4.2.3"
22270-
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
22271-
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
22272-
dependencies:
22273-
emoji-regex "^8.0.0"
22274-
is-fullwidth-code-point "^3.0.0"
22275-
strip-ansi "^6.0.1"
22276-
2227722268
string-width@^2.0.0, string-width@^2.1.1:
2227822269
version "2.1.1"
2227922270
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
@@ -22412,7 +22403,7 @@ stringify-object@^3.3.0:
2241222403
is-obj "^1.0.1"
2241322404
is-regexp "^1.0.0"
2241422405

22415-
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
22406+
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
2241622407
version "6.0.1"
2241722408
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
2241822409
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -22440,13 +22431,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
2244022431
dependencies:
2244122432
ansi-regex "^4.1.0"
2244222433

22443-
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
22444-
version "6.0.1"
22445-
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
22446-
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
22447-
dependencies:
22448-
ansi-regex "^5.0.1"
22449-
2245022434
strip-ansi@^7.0.0, strip-ansi@^7.0.1, strip-ansi@^7.1.0:
2245122435
version "7.1.0"
2245222436
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -24533,7 +24517,7 @@ workerpool@^6.5.1:
2453324517
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544"
2453424518
integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==
2453524519

24536-
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
24520+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
2453724521
version "7.0.0"
2453824522
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
2453924523
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -24568,15 +24552,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
2456824552
string-width "^4.1.0"
2456924553
strip-ansi "^6.0.0"
2457024554

24571-
wrap-ansi@^7.0.0:
24572-
version "7.0.0"
24573-
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
24574-
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
24575-
dependencies:
24576-
ansi-styles "^4.0.0"
24577-
string-width "^4.1.0"
24578-
strip-ansi "^6.0.0"
24579-
2458024555
wrap-ansi@^8.0.1, wrap-ansi@^8.1.0:
2458124556
version "8.1.0"
2458224557
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"

0 commit comments

Comments
 (0)