| "use client"; | |
| import { useRef, useState, useEffect } from "react"; | |
| import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | |
| import { faAngleRight, faCaretLeft, faCaretRight } from "@fortawesome/free-solid-svg-icons"; | |
| import "./ScrollSection.css"; | |
| import Link from "next/link"; | |
| const ScrollSection = ({ title, children, link=null }) => { | |
| const scrollRef = useRef(null); | |
| const [canScrollLeft, setCanScrollLeft] = useState(false); | |
| const [canScrollRight, setCanScrollRight] = useState(true); | |
| useEffect(() => { | |
| const currentScrollRef = scrollRef.current; | |
| const firstChild = currentScrollRef?.firstElementChild; | |
| const lastChild = currentScrollRef?.lastElementChild; | |
| if (!firstChild || !lastChild) return; | |
| const observerOptions = { | |
| root: currentScrollRef, | |
| threshold: 1.0 | |
| }; | |
| const callback = (entries) => { | |
| entries.forEach((entry) => { | |
| if (entry.target === firstChild) { | |
| setCanScrollLeft(!entry.isIntersecting); | |
| } else if (entry.target === lastChild) { | |
| setCanScrollRight(!entry.isIntersecting); | |
| } | |
| }); | |
| }; | |
| const observer = new IntersectionObserver(callback, observerOptions); | |
| observer.observe(firstChild); | |
| observer.observe(lastChild); | |
| return () => { | |
| observer.disconnect(); | |
| }; | |
| }, [children]); | |
| const scroll = (direction) => { | |
| if (scrollRef.current) { | |
| const scrollAmount = direction === "left" ? -360 : 360; | |
| scrollRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" }); | |
| } | |
| }; | |
| return ( | |
| <section className="scroll-section"> | |
| <div className="scroll-section-controls"> | |
| {link ? ( | |
| <Link href={link}> | |
| <h2> | |
| {title} <FontAwesomeIcon icon={faAngleRight} size="lg" /> | |
| </h2> | |
| </Link> | |
| ) : ( | |
| <h2>{title}</h2> | |
| )} | |
| <div className="scroll-controls"> | |
| <button | |
| onClick={() => scroll("left")} | |
| className="scroll-button" | |
| disabled={!canScrollLeft} | |
| > | |
| <FontAwesomeIcon icon={faCaretLeft} size="2xl" /> | |
| </button> | |
| <button | |
| onClick={() => scroll("right")} | |
| className="scroll-button" | |
| disabled={!canScrollRight} | |
| > | |
| <FontAwesomeIcon icon={faCaretRight} size="2xl" /> | |
| </button> | |
| </div> | |
| </div> | |
| <div className="items-grid" ref={scrollRef}> | |
| {children} | |
| </div> | |
| </section> | |
| ); | |
| }; | |
| export default ScrollSection; | |