init
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import AppImage from '@dukang/shared-ui/AppImage';
|
||||
|
||||
type Props = {
|
||||
images: string[];
|
||||
alt: string;
|
||||
variant?: 'home' | 'detail' | 'store';
|
||||
};
|
||||
|
||||
export default function ProductCarousel({ images, alt, variant = 'home' }: Props) {
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
const slides = images.length > 0 ? images : [''];
|
||||
|
||||
function onScroll() {
|
||||
const el = scrollRef.current;
|
||||
if (!el || el.offsetWidth === 0) return;
|
||||
setActiveIndex(Math.round(el.scrollLeft / el.offsetWidth));
|
||||
}
|
||||
|
||||
const wrapClass =
|
||||
variant === 'store'
|
||||
? 'store-detail-carousel-wrap'
|
||||
: variant === 'detail'
|
||||
? 'detail-carousel-wrap'
|
||||
: 'home-carousel-wrap';
|
||||
const trackClass =
|
||||
variant === 'store'
|
||||
? 'store-detail-carousel'
|
||||
: variant === 'detail'
|
||||
? 'detail-carousel'
|
||||
: 'home-carousel';
|
||||
const dotClass =
|
||||
variant === 'store'
|
||||
? 'store-detail-carousel-dot'
|
||||
: variant === 'detail'
|
||||
? 'detail-carousel-dot'
|
||||
: 'home-carousel-dot';
|
||||
const itemClass =
|
||||
variant === 'store'
|
||||
? 'store-detail-carousel-item'
|
||||
: variant === 'detail'
|
||||
? 'detail-carousel-item'
|
||||
: 'home-carousel-item';
|
||||
const placeholderClass =
|
||||
variant === 'store'
|
||||
? 'store-detail-carousel-placeholder'
|
||||
: variant === 'detail'
|
||||
? 'detail-carousel-placeholder'
|
||||
: 'home-carousel-placeholder';
|
||||
|
||||
return (
|
||||
<div className={wrapClass}>
|
||||
<div className={trackClass} ref={scrollRef} onScroll={onScroll}>
|
||||
{slides.map((src, i) => (
|
||||
<div key={i} className={itemClass}>
|
||||
{src ? (
|
||||
<AppImage src={src} alt={alt} wrapperClassName="app-image--fill" />
|
||||
) : (
|
||||
<div className={placeholderClass} />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{slides.length > 1 && (
|
||||
<div className={variant === 'store' ? 'store-detail-carousel-dots' : variant === 'detail' ? 'detail-carousel-dots' : 'home-carousel-dots'}>
|
||||
{slides.map((_, i) => (
|
||||
<span key={i} className={`${dotClass}${i === activeIndex ? ' active' : ''}`} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user