From 30771337f34149d982bc7bf06c3540eb32720ad8 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Wed, 26 Mar 2025 00:01:55 -0500 Subject: [PATCH] Create FadedScroll component --- src/components/FadedScroll.tsx | 75 ++++++++++++++++++++++++++++++++++ src/photo/PhotoGridPage.tsx | 29 ++++++------- 2 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 src/components/FadedScroll.tsx diff --git a/src/components/FadedScroll.tsx b/src/components/FadedScroll.tsx new file mode 100644 index 00000000..b118332a --- /dev/null +++ b/src/components/FadedScroll.tsx @@ -0,0 +1,75 @@ +import clsx from 'clsx/lite'; +import { + HTMLAttributes, + RefObject, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; + +export default function FadedScroll({ + ref: containerRef, + direction = 'vertical', + fadeHeight = 24, + hideScrollbar, + classNameContent, + children, + ...props +}: HTMLAttributes & { + ref: RefObject + direction?: 'vertical' | 'horizontal' + fadeHeight?: number + classNameContent?: string + hideScrollbar?: boolean +}) { + const contentRef = useRef(null); + + const [position, setPosition] = useState<'start' | 'middle' | 'end'>('start'); + + const isVertical = direction === 'vertical'; + + useEffect(() => { + const ref = contentRef.current; + if (ref) { + const handleScroll = () => { + const isStart = isVertical + ? ref.scrollTop === 0 + : ref.scrollLeft === 0; + const isEnd = isVertical + ? ref.scrollHeight - ref.scrollTop === ref.clientHeight + : ref.scrollWidth - ref.scrollLeft === ref.clientWidth; + setPosition(isStart ? 'start' : isEnd ? 'end' : 'middle'); + }; + ref.addEventListener('scroll', handleScroll); + return () => ref.removeEventListener('scroll', handleScroll); + } + }, [isVertical]); + + const maskImage = useMemo(() => { + // eslint-disable-next-line max-len + let mask = `linear-gradient(to ${isVertical ? 'bottom' : 'right'}, transparent, black `; + mask += `${position !== 'start' ? fadeHeight : 0}px, black calc(100% - `; + mask += `${position !== 'end' ? fadeHeight : 0}px), transparent)`; + return mask; + }, [fadeHeight, isVertical, position]); + + return
+
+ {children} +
+
; +} diff --git a/src/photo/PhotoGridPage.tsx b/src/photo/PhotoGridPage.tsx index b5857e3a..21c939e5 100644 --- a/src/photo/PhotoGridPage.tsx +++ b/src/photo/PhotoGridPage.tsx @@ -9,6 +9,7 @@ import { useAppState } from '@/state/AppState'; import clsx from 'clsx/lite'; import { PhotoSetCategories } from '@/category'; import useElementHeight from '@/utility/useElementHeight'; +import FadedScroll from '@/components/FadedScroll'; export default function PhotoGridPage({ photos, @@ -35,29 +36,23 @@ export default function PhotoGridPage({ photos={photos} count={photosCount} sidebar={ -
-
- -
-
+ + } canSelect />