Files
dukang/apps/mini-user/src/components/ProductCarousel.tsx
T
jacy 4372018c09 feat: v3.4.12 ticket iteration
Refund rollback, winery T+3, multi withdraw, mini-user store detail, dev plan batch edit and WeCom dispatch, support ticket edit/attachments/batch status, package imageUrl.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 23:53:31 +08:00

67 lines
1.9 KiB
TypeScript

import { useState } from 'react';
import { View, Image, Swiper, SwiperItem } from '@tarojs/components';
import Taro from '@tarojs/taro';
type ProductCarouselProps = {
images: string[];
alt: string;
variant?: 'home' | 'detail' | 'store';
previewable?: boolean;
};
/** 商品/门店轮播(对齐 h5 ProductCarousel 三变体) */
export default function ProductCarousel({
images,
alt,
variant = 'detail',
previewable = false,
}: 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';
function previewAt(index: number) {
const urls = slides.filter(Boolean);
if (!urls.length) return;
const current = slides[index] || urls[0];
Taro.previewImage({ current, urls }).catch(() => undefined);
}
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}
onClick={previewable ? () => previewAt(index) : undefined}
/>
) : (
<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>
);
}