Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/editors/slate/scroll.ts
1691 views
1
import { delay } from "awaiting";
2
import type { SlateEditor } from "./editable-markdown";
3
4
export interface ScrollState {
5
index: number;
6
offset: number;
7
}
8
9
export function getScrollState(editor: SlateEditor): ScrollState | undefined {
10
const startIndex = editor.windowedListRef.current?.visibleRange?.startIndex;
11
if (startIndex == null) return;
12
const endIndex = editor.windowedListRef.current?.visibleRange?.endIndex;
13
if (endIndex == null) return;
14
15
let index, offset;
16
if (endIndex > startIndex) {
17
index = startIndex + 1;
18
offset = editor.windowedListRef.current?.secondItemOffset ?? 0;
19
} else {
20
index = startIndex;
21
offset = editor.windowedListRef.current?.firstItemOffset ?? 0;
22
}
23
24
return { index, offset };
25
}
26
27
export async function setScrollState(editor: SlateEditor, scroll: ScrollState) {
28
const { index, offset } = scroll;
29
const f = async () => {
30
editor.windowedListRef.current?.virtuosoRef.current?.scrollToIndex?.(index);
31
// We have to set this twice, or it sometimes doesn't work. Setting it twice
32
// flickers a lot less than. This might be a bug in virtuoso. Also, we
33
// have to first set it above without the offset, then set it with!. Weird.
34
await new Promise(requestAnimationFrame);
35
editor.windowedListRef.current?.virtuosoRef.current?.scrollToIndex?.({
36
index,
37
offset,
38
});
39
};
40
41
// Do it once:
42
await f();
43
// Then wait until next loop and try again.
44
// This combination seems pretty effective.
45
await delay(0);
46
await f();
47
}
48
49