-
-
Save dax70/20e70c02b5d1147227176a211ffa86da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {ChevronLeft, ChevronRight} from 'lucide-react'; | |
import {useEffect, useState} from 'react'; | |
export function Pagination({carousel}: {carousel: HTMLElement}) { | |
// Scroll by 1 page in the given direction (-1 or +1). | |
// This uses the width of the carousel minus the padding and gap between items. | |
// Use behavior: 'smooth' and the browser will animate the scrolling. | |
let scroll = (dir: number) => { | |
let style = window.getComputedStyle(carousel); | |
carousel.scrollBy({ | |
left: dir * (carousel.clientWidth - parseInt(style.paddingLeft, 10) - parseInt(style.paddingRight, 10) + parseInt(style.columnGap, 10)), | |
behavior: 'smooth' | |
}); | |
}; | |
let [isPrevDisabled, setPrevDisabled] = useState(true); | |
let [isNextDisabled, setNextDisabled] = useState(false); | |
// Use the scroll position to determine if we are at the start or end of the carousel. | |
// This controls whether the previous and next buttons are enabled. | |
useEffect(() => { | |
let update = () => { | |
setPrevDisabled(carousel.scrollLeft <= 0); | |
setNextDisabled(carousel.scrollLeft >= carousel.scrollWidth - carousel.clientWidth); | |
}; | |
update(); | |
// Use the scrollend event if supported for better perf, with fallback to regular scroll. | |
if ('onscrollend' in document) { | |
carousel.addEventListener('scrollend', update); | |
return () => carousel.removeEventListener('scrollend', update); | |
} else { | |
carousel.addEventListener('scroll', update); | |
return () => carousel.removeEventListener('scroll', update); | |
} | |
}, [carousel]); | |
return ( | |
<div className="flex gap-2 justify-end"> | |
<button | |
className="..." | |
aria-label="Previous Page" | |
disabled={isPrevDisabled} | |
onClick={() => scroll(-1)}> | |
<ChevronLeft className="w-5 h-5" /> | |
</button> | |
<button | |
className="..." | |
aria-label="Next Page" | |
disabled={isNextDisabled} | |
onClick={() => scroll(1)}> | |
<ChevronRight className="w-5 h-5" /> | |
</button> | |
</div> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment