grafana/public/app/core/components/NativeScrollbar.tsx
Ashley Harrison a54308138f
Navigation: Remove bodyScrolling toggle and make it default (#93652)
* remove bodyScrolling toggle and make it default

* fix e2e tests
2024-09-24 13:23:18 +01:00

45 lines
1.2 KiB
TypeScript

import { useEffect, useRef } from 'react';
export interface Props {
children: React.ReactNode;
onSetScrollRef?: (ref: ScrollRefElement) => void;
divId?: string;
}
export interface ScrollRefElement {
scrollTop: number;
scrollTo: (x: number, y: number) => void;
}
// Shim to provide API-compatibility for Page's scroll-related props
export default function NativeScrollbar({ children, onSetScrollRef, divId }: Props) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (onSetScrollRef) {
onSetScrollRef(new DivScrollElement(document.documentElement));
}
}, [ref, onSetScrollRef]);
return children;
}
class DivScrollElement {
public constructor(private element: HTMLElement) {}
public get scrollTop() {
return this.element.scrollTop;
}
public scrollTo(x: number, y: number, retry = 0) {
// If the element does not have the height we wait a few frames and look again
// Gives the view time to render and get the correct height before we restore scroll position
const canScroll = this.element.scrollHeight - this.element.clientHeight - y >= 0;
if (!canScroll && retry < 10) {
requestAnimationFrame(() => this.scrollTo(x, y, retry + 1));
return;
}
this.element.scrollTo(x, y);
}
}