Created
June 24, 2024 09:56
-
-
Save Kevin-free/3ec78f2d63aead27119500afafc68479 to your computer and use it in GitHub Desktop.
ScrollingTextRows.tsx
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 React, { useState, useEffect, useRef } from 'react'; | |
import { useNavigate } from 'react-router-dom'; | |
const ScrollingTextRows: React.FC = () => { | |
const [hoveredRow, setHoveredRow] = useState<number | null>(null); | |
const scrollRefs = useRef<HTMLDivElement[]>([]); | |
const navigate = useNavigate(); | |
useEffect(() => { | |
const scroll = (direction: number, index: number) => { | |
const scrollElement = scrollRefs.current[index]; | |
if (scrollElement) { | |
scrollElement.scrollLeft += direction; | |
if (scrollElement.scrollLeft >= scrollElement.scrollWidth / 2) { | |
scrollElement.scrollLeft = 0; | |
} else if (scrollElement.scrollLeft <= 0) { | |
scrollElement.scrollLeft = scrollElement.scrollWidth / 2; | |
} | |
} | |
}; | |
const interval = setInterval(() => { | |
scrollRefs.current.forEach((_, index) => { | |
if (hoveredRow === null || hoveredRow !== index) { | |
const direction = scrollRefs.current[index].classList.contains('scroll-right') ? 1 : -1; | |
scroll(direction, index); | |
} | |
}); | |
}, 30); | |
return () => clearInterval(interval); | |
}, [hoveredRow]); | |
const handleButtonClick = () => { | |
navigate('/login'); | |
}; | |
const renderScrollingRow = (className: string, hoverIndex: number, texts: string[]) => ( | |
<div | |
className={`${className} relative flex overflow-hidden whitespace-nowrap`} | |
onMouseEnter={() => setHoveredRow(hoverIndex)} | |
onMouseLeave={() => setHoveredRow(null)} | |
ref={(el) => { | |
if (el) { | |
scrollRefs.current[hoverIndex] = el; | |
} | |
}} | |
> | |
<div className="my-2 flex space-x-4"> | |
{texts.map((text, index) => ( | |
<ScrollingTextButton text={text} key={index} onClick={handleButtonClick} /> | |
))} | |
{texts.map((text, index) => ( | |
<ScrollingTextButton text={text} key={index + texts.length} onClick={handleButtonClick} /> | |
))} | |
</div> | |
</div> | |
); | |
return ( | |
<div className="w-full bg-white py-10 dark:bg-gray-900"> | |
{renderScrollingRow('scroll-right', 0, [ | |
'Generate a summary of the latest news ↗', | |
'Translate this paragraph into French ↗', | |
'Analyze this sales data for trends ↗', | |
'Create a visual chart from the provided data ↗', | |
])} | |
{renderScrollingRow('scroll-left', 1, [ | |
'Generate a personalized workout plan ↗', | |
'Recommend books based on my preferences ↗', | |
'Create a monthly budget for my expenses ↗', | |
'Automate my daily standup notes ↗', | |
])} | |
{renderScrollingRow('scroll-right', 2, [ | |
'Plan a trip itinerary for Japan ↗', | |
'Draft a business proposal for me ↗', | |
'Generate captions for my photos ↗', | |
'Suggest improvements for my resume ↗', | |
])} | |
</div> | |
); | |
}; | |
interface ButtonProps { | |
text: string; | |
onClick: () => void; | |
} | |
const ScrollingTextButton: React.FC<ButtonProps> = ({ text, onClick }) => ( | |
<div | |
className="mx-4 cursor-pointer rounded-lg bg-gray-100 px-4 py-2 text-black transition-colors duration-300 hover:bg-gray-300 dark:bg-gray-800 dark:text-white dark:hover:bg-gray-700" | |
onClick={onClick} | |
> | |
<a className="border-b-2 border-gray-100 text-black no-underline transition-colors duration-300 hover:border-black dark:border-gray-800 dark:text-white dark:hover:border-white"> | |
{text} | |
</a> | |
</div> | |
); | |
export default ScrollingTextRows; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment