leumas-private-shared
Version:
Private React JSX Package For Leumas Shared Components, Headers, Footers, Asides, Login Pages, API Key Manager and much more. Styles and everything reusable to avoid DRY code across all of our subdomains
86 lines (79 loc) • 3.78 kB
JSX
import React, { useState } from 'react';
const getTextPositionClasses = (position) => {
switch (position) {
case 'top-center':
return 'top-0 left-1/2 transform -translate-x-1/2';
case 'middle-center':
return 'top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2';
case 'bottom-center':
return 'bottom-0 left-1/2 transform -translate-x-1/2';
default:
return 'bottom-0 left-1/2 transform -translate-x-1/2';
}
};
const AnimatedSlider = ({ images }) => {
const [activeIndex, setActiveIndex] = useState(0);
const goToPrev = () => {
setActiveIndex(prevIndex =>
prevIndex === 0 ? images.length - 1 : prevIndex - 1
);
};
const goToNext = () => {
setActiveIndex(prevIndex =>
prevIndex === images.length - 1 ? 0 : prevIndex + 1
);
};
return (
<div className="relative w-full" data-carousel="static">
<div className="relative h-56 overflow-hidden rounded-lg md:h-96">
{images.map((image, index) => (
<div
key={index}
className={`carousel-item duration-200 ease-linear transition-opacity ${index === activeIndex ? 'opacity-100' : 'opacity-0 hidden'} absolute inset-0 w-full h-full`}
>
<div className="absolute inset-0 bg-black/30"></div> {/* Dark overlay */}
<a href={image.link || '#'} target="_blank" rel="noopener noreferrer">
<img
src={image.src}
className="block w-full h-full object-cover"
alt={image.altText || ''}
/>
</a>
{image.text && (
<div className={`absolute p-4 text-white ${getTextPositionClasses(image.textPosition)}`}>
{image.text}
</div>
)}
</div>
))}
</div>
<button
type="button"
className="absolute top-0 start-0 z-30 flex items-center justify-center h-full px-4 cursor-pointer group focus:outline-none"
data-carousel-prev
onClick={goToPrev}
>
{/* Previous button content */}
<span className="inline-flex items-center justify-center w-10 h-10 rounded-full bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none">
<svg className="w-6 h-6 text-gray-800" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" stroke="currentColor">
<path d="M15 19l-7-7 7-7"></path>
</svg>
</span>
</button>
<button
type="button"
className="absolute top-0 end-0 z-30 flex items-center justify-center h-full px-4 cursor-pointer group focus:outline-none"
data-carousel-next
onClick={goToNext}
>
{/* Next button content */}
<span className="inline-flex items-center justify-center w-10 h-10 rounded-full bg-white/30 dark:bg-gray-800/30 group-hover:bg-white/50 dark:group-hover:bg-gray-800/60 group-focus:ring-4 group-focus:ring-white dark:group-focus:ring-gray-800/70 group-focus:outline-none">
<svg className="w-6 h-6 text-gray-800" fill="none" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" viewBox="0 0 24 24" stroke="currentColor">
<path d="M9 5l7 7-7 7"></path>
</svg>
</span>
</button>
</div>
);
};
export default AnimatedSlider;