From bcd7b761acc18c03cb512031f2c6a02a71e4f517 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Wed, 3 Jan 2024 15:16:48 +0800 Subject: [PATCH] Optimize code --- src/components/common/Card.tsx | 5 +- src/components/common/FitCenter.tsx | 5 +- src/components/common/FitFullscreen.tsx | 31 +- src/components/common/FlexBox.tsx | 27 +- src/components/common/HideScrollbar.tsx | 1062 +++++++++-------- src/components/common/Indicator.tsx | 4 +- .../common/sidebar/SidebarSeparate.tsx | 6 +- src/pages/system/index.tsx | 58 +- src/pages/system/statistics/shared.ts | 2 +- src/router/system.tsx | 2 +- 10 files changed, 609 insertions(+), 593 deletions(-) diff --git a/src/components/common/Card.tsx b/src/components/common/Card.tsx index 633326e..aaf0fa9 100644 --- a/src/components/common/Card.tsx +++ b/src/components/common/Card.tsx @@ -4,9 +4,8 @@ import '@/assets/css/components/common/card.scss' interface CardProps extends React.DetailedHTMLProps, HTMLDivElement> {} -const Card = forwardRef((props, ref) => { - const { className, ..._props } = props - return
+const Card = forwardRef(({ className, ...props }, ref) => { + return
}) export default Card diff --git a/src/components/common/FitCenter.tsx b/src/components/common/FitCenter.tsx index 44f7449..d735fcf 100644 --- a/src/components/common/FitCenter.tsx +++ b/src/components/common/FitCenter.tsx @@ -6,14 +6,13 @@ interface FitCenterProps vertical?: boolean } -const FitCenter: React.FC = (props) => { - const { className, vertical, ..._props } = props +const FitCenter: React.FC = ({ className, vertical, ...props }) => { return (
) } diff --git a/src/components/common/FitFullscreen.tsx b/src/components/common/FitFullscreen.tsx index 09d3658..e236247 100644 --- a/src/components/common/FitFullscreen.tsx +++ b/src/components/common/FitFullscreen.tsx @@ -7,20 +7,21 @@ interface FitFullscreenProps backgroundColor?: string } -const FitFullscreen = forwardRef((props, ref) => { - const { zIndex, backgroundColor, className, style, ..._props } = props - return ( -
- ) -}) +const FitFullscreen = forwardRef( + ({ zIndex, backgroundColor, className, style, ...props }, ref) => { + return ( +
+ ) + } +) export default FitFullscreen diff --git a/src/components/common/FlexBox.tsx b/src/components/common/FlexBox.tsx index e9b3271..606ce43 100644 --- a/src/components/common/FlexBox.tsx +++ b/src/components/common/FlexBox.tsx @@ -7,18 +7,19 @@ interface FlexBoxProps gap?: number } -const FlexBox = forwardRef((props, ref) => { - const { className, direction, gap, style, ..._props } = props - return ( -
- ) -}) +const FlexBox = forwardRef( + ({ className, direction, gap, style, ...props }, ref) => { + return ( +
+ ) + } +) export default FlexBox diff --git a/src/components/common/HideScrollbar.tsx b/src/components/common/HideScrollbar.tsx index 6200598..f444182 100644 --- a/src/components/common/HideScrollbar.tsx +++ b/src/components/common/HideScrollbar.tsx @@ -49,557 +49,575 @@ export interface HideScrollbarElement { refreshLayout(): void } -const HideScrollbar = forwardRef((props, ref) => { - useImperativeHandle( - ref, - () => { - return { - scrollTo(x, y, smooth?: boolean) { +const HideScrollbar = forwardRef( + ( + { + isPreventScroll, + isPreventVerticalScroll, + isPreventHorizontalScroll, + isShowVerticalScrollbar, + isHiddenVerticalScrollbarWhenFull, + isShowHorizontalScrollbar, + isHiddenHorizontalScrollbarWhenFull, + minWidth, + minHeight, + scrollbarWidth, + autoHideWaitingTime, + children, + style, + className, + ...props + }, + ref + ) => { + useImperativeHandle( + ref, + () => { + return { + scrollTo(x, y, smooth?: boolean) { + rootRef.current?.scrollTo({ + left: x, + top: y, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + scrollX(x, smooth?: boolean) { + rootRef.current?.scrollTo({ + left: x, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + scrollY(y, smooth?: boolean) { + rootRef.current?.scrollTo({ + top: y, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + scrollLeft(length, smooth?: boolean) { + rootRef.current?.scrollTo({ + left: rootRef.current?.scrollLeft - length, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + scrollRight(length, smooth?: boolean) { + rootRef.current?.scrollTo({ + left: rootRef.current?.scrollLeft + length, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + scrollUp(length, smooth?: boolean) { + rootRef.current?.scrollTo({ + top: rootRef.current?.scrollTop - length, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + scrollDown(length, smooth?: boolean) { + rootRef.current?.scrollTo({ + top: rootRef.current?.scrollTop + length, + behavior: smooth === false ? 'instant' : 'smooth' + }) + }, + getX() { + return rootRef.current?.scrollLeft ?? 0 + }, + getY() { + return rootRef.current?.scrollTop ?? 0 + }, + addEventListenerWithType( + type: K, + listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => never, + options?: boolean | AddEventListenerOptions + ): void { + rootRef.current?.addEventListener(type, listener, options) + }, + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions + ): void { + rootRef.current?.addEventListener(type, listener, options) + }, + removeEventListenerWithType( + type: K, + listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => never, + options?: boolean | EventListenerOptions + ): void { + rootRef.current?.removeEventListener(type, listener, options) + }, + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void { + rootRef.current?.removeEventListener(type, listener, options) + }, + refreshLayout(): void { + refreshLayout() + } + } + }, + [] + ) + + const maskRef = useRef(null) + const rootRef = useRef(null) + const contentRef = useRef(null) + const wheelListenerRef = useRef<(event: WheelEvent) => void>(() => undefined) + const lastScrollbarClickPositionRef = useRef({ x: -1, y: -1 }) + const lastScrollbarTouchPositionRef = useRef({ x: -1, y: -1 }) + const lastTouchPositionRef = useRef({ x: -1, y: -1 }) + const [refreshTime, setRefreshTime] = useState(0) + + const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) + const [verticalScrollbarLength, setVerticalScrollbarLength] = useState(100) + const [verticalScrollbarPosition, setVerticalScrollbarPosition] = useState(0) + const [verticalScrollbarOnClick, setVerticalScrollbarOnClick] = useState(false) + const [verticalScrollbarOnTouch, setVerticalScrollbarOnTouch] = useState(false) + const [verticalScrollbarAutoHide, setVerticalScrollbarAutoHide] = useState(false) + + const [horizontalScrollbarWidth, setHorizontalScrollbarWidth] = useState(0) + const [horizontalScrollbarLength, setHorizontalScrollbarLength] = useState(100) + const [horizontalScrollbarPosition, setHorizontalScrollbarPosition] = useState(0) + const [horizontalScrollbarOnClick, setHorizontalScrollbarOnClick] = useState(false) + const [horizontalScrollbarOnTouch, setHorizontalScrollbarOnTouch] = useState(false) + const [horizontalScrollbarAutoHide, setHorizontalScrollbarAutoHide] = useState(false) + + const isPreventAnyScroll = + isPreventScroll || isPreventVerticalScroll || isPreventHorizontalScroll + + useEffect(() => { + if (autoHideWaitingTime === undefined) { + return + } + setVerticalScrollbarAutoHide(false) + if (autoHideWaitingTime > 0) { + setTimeout(() => { + setVerticalScrollbarAutoHide(true) + }, autoHideWaitingTime) + } + }, [autoHideWaitingTime, verticalScrollbarPosition]) + + useEffect(() => { + if (autoHideWaitingTime === undefined) { + return + } + setHorizontalScrollbarAutoHide(false) + if (autoHideWaitingTime > 0) { + setTimeout(() => { + setHorizontalScrollbarAutoHide(true) + }, autoHideWaitingTime) + } + }, [autoHideWaitingTime, horizontalScrollbarPosition]) + + const handleDefaultTouchStart = useCallback( + (event: React.TouchEvent) => { + if (event.touches.length !== 1 || isPreventScroll) { + lastTouchPositionRef.current = { x: -1, y: -1 } + return + } + + const { clientX, clientY } = event.touches[0] + lastTouchPositionRef.current = { x: clientX, y: clientY } + }, + [isPreventScroll] + ) + + const handleDefaultTouchmove = useCallback( + (event: React.TouchEvent) => { + if (event.touches.length !== 1 || isPreventScroll) { + lastTouchPositionRef.current = { x: -1, y: -1 } + return + } + const { clientX, clientY } = event.touches[0] + + if (!isPreventVerticalScroll) { rootRef.current?.scrollTo({ - left: x, - top: y, - behavior: smooth === false ? 'instant' : 'smooth' + top: + rootRef.current?.scrollTop + (lastTouchPositionRef.current.y - clientY), + behavior: 'instant' }) - }, - scrollX(x, smooth?: boolean) { + } + + if (!isPreventHorizontalScroll) { rootRef.current?.scrollTo({ - left: x, - behavior: smooth === false ? 'instant' : 'smooth' + left: + rootRef.current?.scrollLeft + + (lastTouchPositionRef.current.x - clientX), + behavior: 'instant' }) - }, - scrollY(y, smooth?: boolean) { - rootRef.current?.scrollTo({ - top: y, - behavior: smooth === false ? 'instant' : 'smooth' - }) - }, - scrollLeft(length, smooth?: boolean) { - rootRef.current?.scrollTo({ - left: rootRef.current?.scrollLeft - length, - behavior: smooth === false ? 'instant' : 'smooth' - }) - }, - scrollRight(length, smooth?: boolean) { - rootRef.current?.scrollTo({ - left: rootRef.current?.scrollLeft + length, - behavior: smooth === false ? 'instant' : 'smooth' - }) - }, - scrollUp(length, smooth?: boolean) { - rootRef.current?.scrollTo({ - top: rootRef.current?.scrollTop - length, - behavior: smooth === false ? 'instant' : 'smooth' - }) - }, - scrollDown(length, smooth?: boolean) { - rootRef.current?.scrollTo({ - top: rootRef.current?.scrollTop + length, - behavior: smooth === false ? 'instant' : 'smooth' - }) - }, - getX() { - return rootRef.current?.scrollLeft ?? 0 - }, - getY() { - return rootRef.current?.scrollTop ?? 0 - }, - addEventListenerWithType( - type: K, - listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => never, - options?: boolean | AddEventListenerOptions - ): void { - rootRef.current?.addEventListener(type, listener, options) - }, - addEventListener( - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | AddEventListenerOptions - ): void { - rootRef.current?.addEventListener(type, listener, options) - }, - removeEventListenerWithType( - type: K, - listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => never, - options?: boolean | EventListenerOptions - ): void { - rootRef.current?.removeEventListener(type, listener, options) - }, - removeEventListener( - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | EventListenerOptions - ): void { - rootRef.current?.removeEventListener(type, listener, options) - }, - refreshLayout(): void { - refreshLayout() + } + + lastTouchPositionRef.current = { x: clientX, y: clientY } + }, + [isPreventHorizontalScroll, isPreventScroll, isPreventVerticalScroll] + ) + + const handleDefaultMouseDown = (event: React.MouseEvent) => { + if (isPreventAnyScroll) + if (event.button === 1) { + event.preventDefault() + } + } + + const handleDefaultKeyDown = useCallback( + (event: React.KeyboardEvent) => { + if ( + isPreventScroll && + [ + 'ArrowUp', + 'ArrowDown', + 'ArrowLeft', + 'ArrowRight', + ' ', + '', + 'PageUp', + 'PageDown', + 'Home', + 'End' + ].find((value) => value === event.key) + ) { + event.preventDefault() + } + if ( + isPreventVerticalScroll && + ['ArrowUp', 'ArrowDown', ' ', '', 'PageUp', 'PageDown', 'Home', 'End'].find( + (value) => value === event.key + ) + ) { + event.preventDefault() + } + if ( + isPreventHorizontalScroll && + ['ArrowLeft', 'ArrowRight'].find((value) => value === event.key) + ) { + event.preventDefault() + } + }, + [isPreventHorizontalScroll, isPreventScroll, isPreventVerticalScroll] + ) + + const handleScrollbarMouseEvent = (eventFlag: string, scrollbarFlag: string) => { + return (event: React.MouseEvent) => { + switch (eventFlag) { + case 'down': + lastScrollbarClickPositionRef.current = { + x: event.clientX, + y: event.clientY + } + switch (scrollbarFlag) { + case 'vertical': + setVerticalScrollbarOnClick(true) + break + case 'horizontal': + setHorizontalScrollbarOnClick(true) + break + } + break + case 'up': + case 'leave': + setVerticalScrollbarOnClick(false) + setHorizontalScrollbarOnClick(false) + break + case 'move': + if (verticalScrollbarOnClick) { + rootRef.current?.scrollTo({ + top: + rootRef.current?.scrollTop + + ((event.clientY - lastScrollbarClickPositionRef.current.y) / + (rootRef.current?.clientHeight ?? 1)) * + (contentRef.current?.clientHeight ?? 0), + behavior: 'instant' + }) + } + if (horizontalScrollbarOnClick) { + rootRef.current?.scrollTo({ + left: + rootRef.current?.scrollLeft + + ((event.clientX - lastScrollbarClickPositionRef.current.x) / + (rootRef.current?.clientWidth ?? 1)) * + (contentRef.current?.clientWidth ?? 0), + behavior: 'instant' + }) + } + lastScrollbarClickPositionRef.current = { + x: event.clientX, + y: event.clientY + } } } - }, - [] - ) - - const maskRef = useRef(null) - const rootRef = useRef(null) - const contentRef = useRef(null) - const wheelListenerRef = useRef<(event: WheelEvent) => void>(() => undefined) - const lastScrollbarClickPositionRef = useRef({ x: -1, y: -1 }) - const lastScrollbarTouchPositionRef = useRef({ x: -1, y: -1 }) - const lastTouchPositionRef = useRef({ x: -1, y: -1 }) - const [refreshTime, setRefreshTime] = useState(0) - - const [verticalScrollbarWidth, setVerticalScrollbarWidth] = useState(0) - const [verticalScrollbarLength, setVerticalScrollbarLength] = useState(100) - const [verticalScrollbarPosition, setVerticalScrollbarPosition] = useState(0) - const [verticalScrollbarOnClick, setVerticalScrollbarOnClick] = useState(false) - const [verticalScrollbarOnTouch, setVerticalScrollbarOnTouch] = useState(false) - const [verticalScrollbarAutoHide, setVerticalScrollbarAutoHide] = useState(false) - - const [horizontalScrollbarWidth, setHorizontalScrollbarWidth] = useState(0) - const [horizontalScrollbarLength, setHorizontalScrollbarLength] = useState(100) - const [horizontalScrollbarPosition, setHorizontalScrollbarPosition] = useState(0) - const [horizontalScrollbarOnClick, setHorizontalScrollbarOnClick] = useState(false) - const [horizontalScrollbarOnTouch, setHorizontalScrollbarOnTouch] = useState(false) - const [horizontalScrollbarAutoHide, setHorizontalScrollbarAutoHide] = useState(false) - - const { - isPreventScroll, - isPreventVerticalScroll, - isPreventHorizontalScroll, - isShowVerticalScrollbar, - isHiddenVerticalScrollbarWhenFull, - isShowHorizontalScrollbar, - isHiddenHorizontalScrollbarWhenFull, - minWidth, - minHeight, - scrollbarWidth, - autoHideWaitingTime, - children, - style, - className, - ..._props - } = props - - const isPreventAnyScroll = - isPreventScroll || isPreventVerticalScroll || isPreventHorizontalScroll - - useEffect(() => { - if (autoHideWaitingTime === undefined) { - return } - setVerticalScrollbarAutoHide(false) - if (autoHideWaitingTime > 0) { - setTimeout(() => { - setVerticalScrollbarAutoHide(true) - }, autoHideWaitingTime) + + const handleScrollbarTouchEvent = (eventFlag: string, scrollbarFlag: string) => { + return (event: React.TouchEvent) => { + switch (eventFlag) { + case 'start': + if (event.touches.length !== 1) { + return + } + lastScrollbarTouchPositionRef.current = { + x: event.touches[0].clientX, + y: event.touches[0].clientY + } + switch (scrollbarFlag) { + case 'vertical': + setVerticalScrollbarOnTouch(true) + break + case 'horizontal': + setHorizontalScrollbarOnTouch(true) + break + } + break + case 'end': + case 'cancel': + setVerticalScrollbarOnTouch(false) + setHorizontalScrollbarOnTouch(false) + break + case 'move': + if (event.touches.length !== 1) { + return + } + if (verticalScrollbarOnTouch) { + rootRef.current?.scrollTo({ + top: + rootRef.current?.scrollTop + + ((event.touches[0].clientY - + lastScrollbarClickPositionRef.current.y) / + (rootRef.current?.clientHeight ?? 1)) * + (contentRef.current?.clientHeight ?? 0), + behavior: 'instant' + }) + } + if (horizontalScrollbarOnTouch) { + rootRef.current?.scrollTo({ + left: + rootRef.current?.scrollLeft + + ((event.touches[0].clientX - + lastScrollbarClickPositionRef.current.x) / + (rootRef.current?.clientWidth ?? 1)) * + (contentRef.current?.clientWidth ?? 0), + behavior: 'instant' + }) + } + lastScrollbarClickPositionRef.current = { + x: event.touches[0].clientX, + y: event.touches[0].clientY + } + } + } } - }, [autoHideWaitingTime, verticalScrollbarPosition]) - useEffect(() => { - if (autoHideWaitingTime === undefined) { - return + const handleDefaultScroll = () => { + setVerticalScrollbarPosition( + ((rootRef.current?.scrollTop ?? 0) / (contentRef.current?.clientHeight ?? 1)) * 100 + ) + setHorizontalScrollbarPosition( + ((rootRef.current?.scrollLeft ?? 0) / (contentRef.current?.clientWidth ?? 1)) * 100 + ) } - setHorizontalScrollbarAutoHide(false) - if (autoHideWaitingTime > 0) { - setTimeout(() => { - setHorizontalScrollbarAutoHide(true) - }, autoHideWaitingTime) + + const refreshLayout = () => { + setRefreshTime(Date.now()) } - }, [autoHideWaitingTime, horizontalScrollbarPosition]) - const handleDefaultTouchStart = useCallback( - (event: React.TouchEvent) => { - if (event.touches.length !== 1 || isPreventScroll) { - lastTouchPositionRef.current = { x: -1, y: -1 } - return - } + const reloadScrollbar = () => { + setVerticalScrollbarWidth( + (rootRef.current?.offsetWidth ?? 0) - (rootRef.current?.clientWidth ?? 0) + ) + setHorizontalScrollbarWidth( + (rootRef.current?.offsetHeight ?? 0) - (rootRef.current?.clientHeight ?? 0) + ) - const { clientX, clientY } = event.touches[0] - lastTouchPositionRef.current = { x: clientX, y: clientY } - }, - [isPreventScroll] - ) - - const handleDefaultTouchmove = useCallback( - (event: React.TouchEvent) => { - if (event.touches.length !== 1 || isPreventScroll) { - lastTouchPositionRef.current = { x: -1, y: -1 } - return - } - const { clientX, clientY } = event.touches[0] - - if (!isPreventVerticalScroll) { - rootRef.current?.scrollTo({ - top: rootRef.current?.scrollTop + (lastTouchPositionRef.current.y - clientY), - behavior: 'instant' - }) - } - - if (!isPreventHorizontalScroll) { - rootRef.current?.scrollTo({ - left: rootRef.current?.scrollLeft + (lastTouchPositionRef.current.x - clientX), - behavior: 'instant' - }) - } - - lastTouchPositionRef.current = { x: clientX, y: clientY } - }, - [isPreventHorizontalScroll, isPreventScroll, isPreventVerticalScroll] - ) - - const handleDefaultMouseDown = (event: React.MouseEvent) => { - if (isPreventAnyScroll) - if (event.button === 1) { - event.preventDefault() - } - } - - const handleDefaultKeyDown = useCallback( - (event: React.KeyboardEvent) => { - if ( - isPreventScroll && - [ - 'ArrowUp', - 'ArrowDown', - 'ArrowLeft', - 'ArrowRight', - ' ', - '', - 'PageUp', - 'PageDown', - 'Home', - 'End' - ].find((value) => value === event.key) - ) { - event.preventDefault() - } - if ( - isPreventVerticalScroll && - ['ArrowUp', 'ArrowDown', ' ', '', 'PageUp', 'PageDown', 'Home', 'End'].find( - (value) => value === event.key + rootRef.current && + setVerticalScrollbarLength( + (rootRef.current.clientHeight / (contentRef.current?.clientHeight ?? 0)) * 100 ) - ) { - event.preventDefault() - } - if ( - isPreventHorizontalScroll && - ['ArrowLeft', 'ArrowRight'].find((value) => value === event.key) - ) { - event.preventDefault() - } - }, - [isPreventHorizontalScroll, isPreventScroll, isPreventVerticalScroll] - ) - const handleScrollbarMouseEvent = (eventFlag: string, scrollbarFlag: string) => { - return (event: React.MouseEvent) => { - switch (eventFlag) { - case 'down': - lastScrollbarClickPositionRef.current = { x: event.clientX, y: event.clientY } - switch (scrollbarFlag) { - case 'vertical': - setVerticalScrollbarOnClick(true) - break - case 'horizontal': - setHorizontalScrollbarOnClick(true) - break - } - break - case 'up': - case 'leave': - setVerticalScrollbarOnClick(false) - setHorizontalScrollbarOnClick(false) - break - case 'move': - if (verticalScrollbarOnClick) { - rootRef.current?.scrollTo({ - top: - rootRef.current?.scrollTop + - ((event.clientY - lastScrollbarClickPositionRef.current.y) / - (rootRef.current?.clientHeight ?? 1)) * - (contentRef.current?.clientHeight ?? 0), - behavior: 'instant' - }) - } - if (horizontalScrollbarOnClick) { - rootRef.current?.scrollTo({ - left: - rootRef.current?.scrollLeft + - ((event.clientX - lastScrollbarClickPositionRef.current.x) / - (rootRef.current?.clientWidth ?? 1)) * - (contentRef.current?.clientWidth ?? 0), - behavior: 'instant' - }) - } - lastScrollbarClickPositionRef.current = { - x: event.clientX, - y: event.clientY - } - } + rootRef.current && + setHorizontalScrollbarLength( + (rootRef.current.clientWidth / (contentRef.current?.clientWidth ?? 0)) * 100 + ) + + refreshLayout() } - } - const handleScrollbarTouchEvent = (eventFlag: string, scrollbarFlag: string) => { - return (event: React.TouchEvent) => { - switch (eventFlag) { - case 'start': - if (event.touches.length !== 1) { - return - } - lastScrollbarTouchPositionRef.current = { - x: event.touches[0].clientX, - y: event.touches[0].clientY - } - switch (scrollbarFlag) { - case 'vertical': - setVerticalScrollbarOnTouch(true) - break - case 'horizontal': - setHorizontalScrollbarOnTouch(true) - break - } - break - case 'end': - case 'cancel': - setVerticalScrollbarOnTouch(false) - setHorizontalScrollbarOnTouch(false) - break - case 'move': - if (event.touches.length !== 1) { - return - } - if (verticalScrollbarOnTouch) { - rootRef.current?.scrollTo({ - top: - rootRef.current?.scrollTop + - ((event.touches[0].clientY - - lastScrollbarClickPositionRef.current.y) / - (rootRef.current?.clientHeight ?? 1)) * - (contentRef.current?.clientHeight ?? 0), - behavior: 'instant' - }) - } - if (horizontalScrollbarOnTouch) { - rootRef.current?.scrollTo({ - left: - rootRef.current?.scrollLeft + - ((event.touches[0].clientX - - lastScrollbarClickPositionRef.current.x) / - (rootRef.current?.clientWidth ?? 1)) * - (contentRef.current?.clientWidth ?? 0), - behavior: 'instant' - }) - } - lastScrollbarClickPositionRef.current = { - x: event.touches[0].clientX, - y: event.touches[0].clientY - } + useEffect(() => { + setTimeout(() => { + reloadScrollbar() + }, 500) + const resizeObserver = new ResizeObserver(() => { + reloadScrollbar() + }) + maskRef.current && resizeObserver.observe(maskRef.current) + contentRef.current && resizeObserver.observe(contentRef.current) + + return () => { + maskRef.current && resizeObserver.unobserve(maskRef.current) + contentRef.current && resizeObserver.unobserve(contentRef.current) } - } - } + }, []) - const handleDefaultScroll = () => { - setVerticalScrollbarPosition( - ((rootRef.current?.scrollTop ?? 0) / (contentRef.current?.clientHeight ?? 1)) * 100 - ) - setHorizontalScrollbarPosition( - ((rootRef.current?.scrollLeft ?? 0) / (contentRef.current?.clientWidth ?? 1)) * 100 - ) - } - - const refreshLayout = () => { - setRefreshTime(Date.now()) - } - - const reloadScrollbar = () => { - setVerticalScrollbarWidth( - (rootRef.current?.offsetWidth ?? 0) - (rootRef.current?.clientWidth ?? 0) - ) - setHorizontalScrollbarWidth( - (rootRef.current?.offsetHeight ?? 0) - (rootRef.current?.clientHeight ?? 0) - ) - - rootRef.current && - setVerticalScrollbarLength( - (rootRef.current.clientHeight / (contentRef.current?.clientHeight ?? 0)) * 100 - ) - - rootRef.current && - setHorizontalScrollbarLength( - (rootRef.current.clientWidth / (contentRef.current?.clientWidth ?? 0)) * 100 - ) - - refreshLayout() - } - - useEffect(() => { - setTimeout(() => { - reloadScrollbar() - }, 500) - const resizeObserver = new ResizeObserver(() => { - reloadScrollbar() - }) - maskRef.current && resizeObserver.observe(maskRef.current) - contentRef.current && resizeObserver.observe(contentRef.current) - - return () => { - maskRef.current && resizeObserver.unobserve(maskRef.current) - contentRef.current && resizeObserver.unobserve(contentRef.current) - } - }, []) - - useEffect(() => { - rootRef.current?.removeEventListener('wheel', wheelListenerRef.current) - if (isPreventAnyScroll) { - const handleDefaultWheel = (event: WheelEvent) => { - if (!event.altKey && !event.ctrlKey) { - if (isPreventScroll) { - event.preventDefault() - return - } - if (isPreventVerticalScroll && !event.shiftKey && !event.deltaX) { - event.preventDefault() - return - } - if (isPreventHorizontalScroll && (event.shiftKey || !event.deltaY)) { - event.preventDefault() - return + useEffect(() => { + rootRef.current?.removeEventListener('wheel', wheelListenerRef.current) + if (isPreventAnyScroll) { + const handleDefaultWheel = (event: WheelEvent) => { + if (!event.altKey && !event.ctrlKey) { + if (isPreventScroll) { + event.preventDefault() + return + } + if (isPreventVerticalScroll && !event.shiftKey && !event.deltaX) { + event.preventDefault() + return + } + if (isPreventHorizontalScroll && (event.shiftKey || !event.deltaY)) { + event.preventDefault() + return + } } } + wheelListenerRef.current = handleDefaultWheel + rootRef.current?.addEventListener('wheel', handleDefaultWheel, { passive: false }) } - wheelListenerRef.current = handleDefaultWheel - rootRef.current?.addEventListener('wheel', handleDefaultWheel, { passive: false }) - } - }, [isPreventAnyScroll, isPreventHorizontalScroll, isPreventScroll, isPreventVerticalScroll]) + }, [ + isPreventAnyScroll, + isPreventHorizontalScroll, + isPreventScroll, + isPreventVerticalScroll + ]) - return ( - <> -
+ return ( + <>
- {children} -
-
-