use-horizontal-scroll.ts47 lines · main
1import * as React from 'react'
2
3export const useHorizontalScroll = (ref: React.RefObject<HTMLDivElement | null>) => {
4 const [hasHorizontalScroll, setHasHorizontalScroll] = React.useState(false)
5 const [canScrollLeft, setCanScrollLeft] = React.useState(false)
6 const [canScrollRight, setCanScrollRight] = React.useState(false)
7
8 React.useEffect(() => {
9 const element = ref.current
10 if (!element) return
11
12 const checkScroll = () => {
13 const hasScroll = element.scrollWidth > element.clientWidth
14 setHasHorizontalScroll(hasScroll)
15
16 if (hasScroll) {
17 const canScrollLeft = element.scrollLeft > 0
18 const canScrollRight = element.scrollLeft < element.scrollWidth - element.clientWidth
19 setCanScrollLeft(canScrollLeft)
20 setCanScrollRight(canScrollRight)
21 } else {
22 setCanScrollLeft(false)
23 setCanScrollRight(false)
24 }
25 }
26
27 const handleScroll = () => {
28 if (hasHorizontalScroll) {
29 const canScrollLeft = element.scrollLeft > 0
30 const canScrollRight = element.scrollLeft < element.scrollWidth - element.clientWidth
31 setCanScrollLeft(canScrollLeft)
32 setCanScrollRight(canScrollRight)
33 }
34 }
35
36 checkScroll()
37 element.addEventListener('scroll', handleScroll)
38 window.addEventListener('resize', checkScroll)
39
40 return () => {
41 element.removeEventListener('scroll', handleScroll)
42 window.removeEventListener('resize', checkScroll)
43 }
44 }, [ref, hasHorizontalScroll])
45
46 return { hasHorizontalScroll, canScrollLeft, canScrollRight }
47}