useComponentScroll.tsx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import { useEffect, useRef, useState } from "react";
  2. export enum SCROLL_DIRECTION {
  3. LEFT = -1,
  4. RIGHT = +1,
  5. }
  6. export default function useComponentScroll({
  7. dependencies,
  8. }: {
  9. dependencies: any[];
  10. }) {
  11. const componentRef = useRef<HTMLDivElement>(null);
  12. const [scrollObj, setScrollObj] = useState<{
  13. scrollLeft?: number;
  14. scrollWidth?: number;
  15. clientWidth?: number;
  16. }>({});
  17. const updateScrollObj = () => {
  18. if (!componentRef.current) {
  19. return;
  20. }
  21. const { scrollLeft, scrollWidth, clientWidth } = componentRef.current;
  22. setScrollObj({ scrollLeft, scrollWidth, clientWidth });
  23. };
  24. useEffect(() => {
  25. if (!componentRef.current) {
  26. return;
  27. }
  28. // Add event listener
  29. componentRef.current?.addEventListener("scroll", updateScrollObj);
  30. // Call handler right away so state gets updated with initial window size
  31. updateScrollObj();
  32. // Remove event listener on cleanup
  33. return () =>
  34. componentRef.current?.removeEventListener(
  35. "resize",
  36. updateScrollObj,
  37. );
  38. }, [componentRef.current]);
  39. useEffect(() => {
  40. updateScrollObj();
  41. }, [...dependencies]);
  42. const scrollComponent = (direction: SCROLL_DIRECTION) => () => {
  43. componentRef.current.scrollBy(250 * direction, 0);
  44. };
  45. const hasScrollBar = scrollObj.scrollWidth > scrollObj.clientWidth;
  46. const onFarLeft = scrollObj.scrollLeft === 0;
  47. const onFarRight =
  48. scrollObj.scrollLeft + scrollObj.clientWidth === scrollObj.scrollWidth;
  49. return {
  50. hasScrollBar,
  51. onFarLeft,
  52. onFarRight,
  53. scrollComponent,
  54. componentRef,
  55. };
  56. }