Files
gpustack-ui/src/hooks/use-overlay-scroller.ts
T
2025-01-09 17:53:26 +08:00

131 lines
3.2 KiB
TypeScript

import { throttle } from 'lodash';
import {
UseOverlayScrollbarsParams,
useOverlayScrollbars
} from 'overlayscrollbars-react';
import React, { useEffect } from 'react';
export const overlaySollerOptions: UseOverlayScrollbarsParams = {
options: {
update: {
debounce: 0
},
overflow: {
x: 'hidden'
},
scrollbars: {
theme: 'os-theme-light',
autoHide: 'scroll',
autoHideDelay: 600,
clickScroll: 'instant'
}
},
defer: true
};
export default function useOverlayScroller(options?: any) {
const scrollEventElement = React.useRef<any>(null);
const instanceRef = React.useRef<any>(null);
const initialized = React.useRef(false);
const [initialize, instance] = useOverlayScrollbars({
options: {
update: {
debounce: 0
},
overflow: {
x: 'hidden'
},
scrollbars: {
theme: options?.theme || 'os-theme-dark',
autoHide: 'scroll',
autoHideDelay: 600,
clickScroll: 'instant'
}
},
defer: true
});
instanceRef.current = instance?.();
scrollEventElement.current =
instanceRef.current?.elements()?.scrollEventElement;
const throttledScroll = React.useCallback(
throttle(() => {
scrollEventElement.current?.scrollTo?.({
top: scrollEventElement.current?.scrollHeight,
behavior: 'smooth'
});
instanceRef.current?.update?.();
}, 100),
[(scrollEventElement.current, instanceRef.current)]
);
const scrollauto = React.useCallback(() => {
scrollEventElement.current?.scrollTo?.({
top: scrollEventElement.current.scrollHeight,
behavior: 'auto'
});
instanceRef.current?.update?.();
}, [scrollEventElement.current, instanceRef.current]);
// scroll to bottom
const throttledUpdateScrollerPosition = React.useCallback(
(delay?: number) => {
if (delay === 0) {
scrollauto();
} else {
throttledScroll();
}
},
[throttledScroll, scrollauto]
);
// scroll to top
const updateScrollerPositionToTop = React.useCallback(() => {
scrollEventElement.current?.scrollTo?.({
top: 0,
behavior: 'auto'
});
instanceRef.current?.update?.();
}, [scrollEventElement.current, instanceRef.current]);
const generateInstance = () => {
instanceRef.current = instance?.();
scrollEventElement.current =
instanceRef.current?.elements()?.scrollEventElement;
};
const createInstance = React.useCallback(
(el: any) => {
if (instanceRef.current) {
return;
}
if (el) {
initialize(el);
initialized.current = true;
instanceRef.current = instance?.();
scrollEventElement.current =
instanceRef.current?.elements()?.scrollEventElement;
}
},
[initialize, instance]
);
useEffect(() => {
return () => {
instanceRef.current?.destroy?.();
};
}, [instance]);
return {
initialize: createInstance,
instance: instanceRef.current,
scrollEventElement: scrollEventElement.current,
initialized: initialized.current,
generateInstance,
updateScrollerPosition: throttledUpdateScrollerPosition,
updateScrollerPositionToTop: updateScrollerPositionToTop
};
}