47 lines
1.5 KiB
TypeScript
47 lines
1.5 KiB
TypeScript
import { useState } from 'react';
|
|
import { View, Image, Swiper, SwiperItem } from '@tarojs/components';
|
|
|
|
type ProductCarouselProps = {
|
|
images: string[];
|
|
alt: string;
|
|
variant?: 'home' | 'detail' | 'store';
|
|
};
|
|
|
|
/** 商品/门店轮播(对齐 h5 ProductCarousel 三变体) */
|
|
export default function ProductCarousel({ images, alt, variant = 'detail' }: ProductCarouselProps) {
|
|
const slides = images.length > 0 ? images : [''];
|
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
const prefix =
|
|
variant === 'store' ? 'store-detail-carousel' : variant === 'home' ? 'home-carousel' : 'detail-carousel';
|
|
|
|
return (
|
|
<View className={`${prefix}-wrap`}>
|
|
<Swiper
|
|
className={prefix}
|
|
circular={slides.length > 1}
|
|
onChange={(e) => setActiveIndex(e.detail.current)}
|
|
>
|
|
{slides.map((src, index) => (
|
|
<SwiperItem key={`${src}-${index}`} className={`${prefix}-item`}>
|
|
{src ? (
|
|
<Image className={`${prefix}-image`} src={src} mode="aspectFill" alt={alt} />
|
|
) : (
|
|
<View className={`${prefix}-placeholder`} />
|
|
)}
|
|
</SwiperItem>
|
|
))}
|
|
</Swiper>
|
|
{slides.length > 1 ? (
|
|
<View className={`${prefix}-dots`}>
|
|
{slides.map((_, index) => (
|
|
<View
|
|
key={index}
|
|
className={`${prefix}-dot${index === activeIndex ? ` ${prefix}-dot--active` : ''}`}
|
|
/>
|
|
))}
|
|
</View>
|
|
) : null}
|
|
</View>
|
|
);
|
|
}
|