mirror of
https://github.com/Radarr/Radarr.git
synced 2026-04-21 22:05:43 -04:00
d99a7e9b8a
(cherry picked from commit e1cbc4a78249881de96160739a50c0a399ea4313) Closes #10378 Fixed: Links tooltip closing too quickly (cherry picked from commit 0b9a212f33381d07ff67e2453753aaab64cc8041) Closes #10400 Fixed: Movie links not opening on iOS (cherry picked from commit f20ac9dc348e1f5ded635f12ab925d982b1b8957) Closes #10425
128 lines
3.1 KiB
TypeScript
128 lines
3.1 KiB
TypeScript
import React, { ComponentPropsWithoutRef, useCallback, useRef } from 'react';
|
|
import { Scrollbars } from 'react-custom-scrollbars-2';
|
|
import { ScrollDirection } from 'Helpers/Props/scrollDirections';
|
|
import { OnScroll } from './Scroller';
|
|
import styles from './OverlayScroller.css';
|
|
|
|
const SCROLLBAR_SIZE = 10;
|
|
|
|
interface OverlayScrollerProps {
|
|
className?: string;
|
|
trackClassName?: string;
|
|
scrollTop?: number;
|
|
scrollDirection: ScrollDirection;
|
|
autoHide: boolean;
|
|
autoScroll: boolean;
|
|
children?: React.ReactNode;
|
|
onScroll?: (payload: OnScroll) => void;
|
|
}
|
|
|
|
interface ScrollbarTrackProps {
|
|
style: React.CSSProperties;
|
|
props: ComponentPropsWithoutRef<'div'>;
|
|
}
|
|
|
|
function OverlayScroller(props: OverlayScrollerProps) {
|
|
const {
|
|
autoHide = false,
|
|
autoScroll = true,
|
|
className = styles.scroller,
|
|
trackClassName = styles.thumb,
|
|
children,
|
|
onScroll,
|
|
} = props;
|
|
const scrollBarRef = useRef<Scrollbars>(null);
|
|
const isScrolling = useRef(false);
|
|
|
|
const handleScrollStart = useCallback(() => {
|
|
isScrolling.current = true;
|
|
}, []);
|
|
const handleScrollStop = useCallback(() => {
|
|
isScrolling.current = false;
|
|
}, []);
|
|
|
|
const handleScroll = useCallback(() => {
|
|
if (!scrollBarRef.current) {
|
|
return;
|
|
}
|
|
|
|
const { scrollTop, scrollLeft } = scrollBarRef.current.getValues();
|
|
isScrolling.current = true;
|
|
|
|
if (onScroll) {
|
|
onScroll({ scrollTop, scrollLeft });
|
|
}
|
|
}, [onScroll]);
|
|
|
|
const renderThumb = useCallback(
|
|
(props: ComponentPropsWithoutRef<'div'>) => {
|
|
return <div className={trackClassName} {...props} />;
|
|
},
|
|
[trackClassName]
|
|
);
|
|
|
|
const renderTrackHorizontal = useCallback(
|
|
({ style, props: trackProps }: ScrollbarTrackProps) => {
|
|
const finalStyle = {
|
|
...style,
|
|
right: 2,
|
|
bottom: 2,
|
|
left: 2,
|
|
borderRadius: 3,
|
|
height: SCROLLBAR_SIZE,
|
|
};
|
|
|
|
return (
|
|
<div className={styles.track} style={finalStyle} {...trackProps} />
|
|
);
|
|
},
|
|
[]
|
|
);
|
|
|
|
const renderTrackVertical = useCallback(
|
|
({ style, props: trackProps }: ScrollbarTrackProps) => {
|
|
const finalStyle = {
|
|
...style,
|
|
right: 2,
|
|
bottom: 2,
|
|
top: 2,
|
|
borderRadius: 3,
|
|
width: SCROLLBAR_SIZE,
|
|
};
|
|
|
|
return (
|
|
<div className={styles.track} style={finalStyle} {...trackProps} />
|
|
);
|
|
},
|
|
[]
|
|
);
|
|
|
|
const renderView = useCallback(
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
(props: any) => {
|
|
return <div className={className} {...props} />;
|
|
},
|
|
[className]
|
|
);
|
|
|
|
return (
|
|
<Scrollbars
|
|
ref={scrollBarRef}
|
|
autoHide={autoHide}
|
|
hideTracksWhenNotNeeded={autoScroll}
|
|
renderTrackHorizontal={renderTrackHorizontal}
|
|
renderTrackVertical={renderTrackVertical}
|
|
renderThumbHorizontal={renderThumb}
|
|
renderThumbVertical={renderThumb}
|
|
renderView={renderView}
|
|
onScrollStart={handleScrollStart}
|
|
onScrollStop={handleScrollStop}
|
|
onScroll={handleScroll}
|
|
>
|
|
{children}
|
|
</Scrollbars>
|
|
);
|
|
}
|
|
|
|
export default OverlayScroller;
|