Skip to content

Commit f990759

Browse files
authored
Dashboards: Fixes timing issue when restoring scroll position (grafana#92342)
1 parent 4015711 commit f990759

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

public/app/core/components/NativeScrollbar.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ export default function NativeScrollbar({ children, onSetScrollRef, divId }: Pro
2424

2525
useEffect(() => {
2626
if (config.featureToggles.bodyScrolling && onSetScrollRef) {
27-
onSetScrollRef(new WindowScrollElement());
27+
onSetScrollRef(new DivScrollElement(document.documentElement));
2828
}
2929

3030
if (!config.featureToggles.bodyScrolling && ref.current && onSetScrollRef) {
31-
onSetScrollRef(ref.current);
31+
onSetScrollRef(new DivScrollElement(ref.current));
3232
}
3333
}, [ref, onSetScrollRef]);
3434

@@ -42,13 +42,23 @@ export default function NativeScrollbar({ children, onSetScrollRef, divId }: Pro
4242
);
4343
}
4444

45-
class WindowScrollElement {
45+
class DivScrollElement {
46+
public constructor(private element: HTMLElement) {}
4647
public get scrollTop() {
47-
return window.scrollY;
48+
return this.element.scrollTop;
4849
}
4950

50-
public scrollTo(x: number, y: number) {
51-
window.scrollTo(x, y);
51+
public scrollTo(x: number, y: number, retry = 0) {
52+
// If the element does not have the height we wait a few frames and look again
53+
// Gives the view time to render and get the correct height before we restore scroll position
54+
const canScroll = this.element.scrollHeight - this.element.clientHeight - y >= 0;
55+
56+
if (!canScroll && retry < 10) {
57+
requestAnimationFrame(() => this.scrollTo(x, y, retry + 1));
58+
return;
59+
}
60+
61+
this.element.scrollTo(x, y);
5262
}
5363
}
5464

public/app/features/dashboard-scene/scene/DashboardScene.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -942,9 +942,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
942942

943943
public restoreScrollPos() {
944944
if (this._prevScrollPos !== undefined) {
945-
setTimeout(() => {
946-
this._scrollRef?.scrollTo(0, this._prevScrollPos!);
947-
}, 50);
945+
this._scrollRef?.scrollTo(0, this._prevScrollPos!);
948946
}
949947
}
950948
}

0 commit comments

Comments
 (0)