Improve scrolling behavior for video categories by showing navigation arrows only when applicable
Implement conditional rendering for horizontal scroll navigation buttons in `netflix-grid.tsx` based on scrollable state. Add `checkScrollButtons` function to update button visibility and call it on component mount and scroll events. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/2cd2c0bc-434c-4bc9-ad3f-b99d3897a0d1/4DOsXkx
This commit is contained in:
parent
a863534a9a
commit
45987ab28a
@ -179,6 +179,16 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
|
|||||||
const [isScrolling, setIsScrolling] = useState(false);
|
const [isScrolling, setIsScrolling] = useState(false);
|
||||||
const scrollIntervalRef = useRef<NodeJS.Timeout>();
|
const scrollIntervalRef = useRef<NodeJS.Timeout>();
|
||||||
const [clickedVideoId, setClickedVideoId] = useState<string | null>(null);
|
const [clickedVideoId, setClickedVideoId] = useState<string | null>(null);
|
||||||
|
const [canScrollLeft, setCanScrollLeft] = useState(false);
|
||||||
|
const [canScrollRight, setCanScrollRight] = useState(true);
|
||||||
|
|
||||||
|
const checkScrollButtons = () => {
|
||||||
|
if (scrollRef.current) {
|
||||||
|
const { scrollLeft, scrollWidth, clientWidth } = scrollRef.current;
|
||||||
|
setCanScrollLeft(scrollLeft > 0);
|
||||||
|
setCanScrollRight(scrollLeft < scrollWidth - clientWidth - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const scroll = (direction: 'left' | 'right') => {
|
const scroll = (direction: 'left' | 'right') => {
|
||||||
if (scrollRef.current) {
|
if (scrollRef.current) {
|
||||||
@ -195,6 +205,9 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
|
|||||||
left: targetScroll,
|
left: targetScroll,
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check scroll buttons after animation completes
|
||||||
|
setTimeout(checkScrollButtons, 300);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -221,12 +234,18 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
checkScrollButtons();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (scrollIntervalRef.current) {
|
if (scrollIntervalRef.current) {
|
||||||
clearInterval(scrollIntervalRef.current);
|
clearInterval(scrollIntervalRef.current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, []);
|
}, [category.videos]);
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
checkScrollButtons();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -238,12 +257,12 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
|
|||||||
</h2>
|
</h2>
|
||||||
<div className="relative overflow-hidden">
|
<div className="relative overflow-hidden">
|
||||||
{/* Left scroll button - small circular on videos */}
|
{/* Left scroll button - small circular on videos */}
|
||||||
{!hideScrollButtons && (
|
{!hideScrollButtons && canScrollLeft && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => scroll('left')}
|
onClick={() => scroll('left')}
|
||||||
onMouseEnter={() => startAutoScroll('left')}
|
onMouseEnter={() => startAutoScroll('left')}
|
||||||
onMouseLeave={stopAutoScroll}
|
onMouseLeave={stopAutoScroll}
|
||||||
className="absolute left-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl"
|
className="absolute left-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl opacity-75"
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<ChevronLeft className="w-4 h-4" />
|
<ChevronLeft className="w-4 h-4" />
|
||||||
@ -251,12 +270,12 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Right scroll button - small circular on videos */}
|
{/* Right scroll button - small circular on videos */}
|
||||||
{!hideScrollButtons && (
|
{!hideScrollButtons && canScrollRight && (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => scroll('right')}
|
onClick={() => scroll('right')}
|
||||||
onMouseEnter={() => startAutoScroll('right')}
|
onMouseEnter={() => startAutoScroll('right')}
|
||||||
onMouseLeave={stopAutoScroll}
|
onMouseLeave={stopAutoScroll}
|
||||||
className="absolute right-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl"
|
className="absolute right-2 top-1/2 -translate-y-1/2 z-[60] bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 text-white border-none w-8 h-8 rounded-full transition-all duration-300 hidden md:flex items-center justify-center shadow-xl opacity-75"
|
||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<ChevronRight className="w-4 h-4" />
|
<ChevronRight className="w-4 h-4" />
|
||||||
@ -268,6 +287,7 @@ function CategoryRow({ category, onVideoClick, hideScrollButtons = false }: Cate
|
|||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
className="flex gap-3 overflow-x-auto scrollbar-hide py-4 px-2"
|
className="flex gap-3 overflow-x-auto scrollbar-hide py-4 px-2"
|
||||||
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
|
style={{ scrollbarWidth: 'none', msOverflowStyle: 'none' }}
|
||||||
|
onScroll={handleScroll}
|
||||||
>
|
>
|
||||||
{category.videos.map((video, index) => (
|
{category.videos.map((video, index) => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user