Просмотр исходного кода

✨ feat(components): 创建TDesign Swiper组件

- 创建 `mini/src/components/tdesign/swiper/index.tsx` - Swiper组件
- 对照 `mini/tdesign/swiper/` 目录结构和功能
- 集成tcb-theme.css中的Swiper组件样式
- 实现轮播图基础功能,支持自动播放、指示器和点击事件
- 适配tcb-shop-demo设计规范(圆角18rpx,主色调#fa550f)
yourname 1 месяц назад
Родитель
Сommit
ee2348e932

+ 6 - 2
docs/stories/001.004.homepage-ui-refactor.md

@@ -20,7 +20,7 @@ Draft
   - [ ] 创建Taro React版本的TDesign组件
   - [ ] 创建Taro React版本的TDesign组件
     - [x] 创建 `mini/src/components/tdesign/icon/index.tsx` - Icon组件 (对照: `mini/tdesign/icon/`)
     - [x] 创建 `mini/src/components/tdesign/icon/index.tsx` - Icon组件 (对照: `mini/tdesign/icon/`)
     - [x] 创建 `mini/src/components/tdesign/search/index.tsx` - Search组件 (对照: `mini/tdesign/search/`)
     - [x] 创建 `mini/src/components/tdesign/search/index.tsx` - Search组件 (对照: `mini/tdesign/search/`)
-    - [ ] 创建 `mini/src/components/tdesign/swiper/index.tsx` - Swiper组件 (对照: `mini/tdesign/swiper/`)
+    - [x] 创建 `mini/src/components/tdesign/swiper/index.tsx` - Swiper组件 (对照: `mini/tdesign/swiper/`)
     - [ ] 创建 `mini/src/components/tdesign/toast/index.tsx` - Toast组件 (对照: `mini/tdesign/toast/`)
     - [ ] 创建 `mini/src/components/tdesign/toast/index.tsx` - Toast组件 (对照: `mini/tdesign/toast/`)
     - [ ] 创建 `mini/src/components/tdesign/tabs/index.tsx` - Tabs组件 (对照: `mini/tdesign/tabs/`)
     - [ ] 创建 `mini/src/components/tdesign/tabs/index.tsx` - Tabs组件 (对照: `mini/tdesign/tabs/`)
 - [ ] 实现商品卡片组件 (AC: 3)
 - [ ] 实现商品卡片组件 (AC: 3)
@@ -295,9 +295,12 @@ export default function TDesignSwiper({
 ### Completion Notes List
 ### Completion Notes List
 - ✅ 已完成:创建 `mini/src/components/tdesign/search/index.tsx` - Search组件
 - ✅ 已完成:创建 `mini/src/components/tdesign/search/index.tsx` - Search组件
 - ✅ 已完成:创建 `mini/src/components/tdesign/icon/index.tsx` - Icon组件
 - ✅ 已完成:创建 `mini/src/components/tdesign/icon/index.tsx` - Icon组件
+- ✅ 已完成:创建 `mini/src/components/tdesign/swiper/index.tsx` - Swiper组件
 - ✅ 已对照:`mini/tdesign/search/` 目录结构和功能
 - ✅ 已对照:`mini/tdesign/search/` 目录结构和功能
 - ✅ 已对照:`mini/tdesign/icon/` 目录结构和功能
 - ✅ 已对照:`mini/tdesign/icon/` 目录结构和功能
+- ✅ 已对照:`mini/tdesign/swiper/` 目录结构和功能
 - ✅ 已集成:tcb-theme.css 中的 Search 组件样式
 - ✅ 已集成:tcb-theme.css 中的 Search 组件样式
+- ✅ 已集成:tcb-theme.css 中的 Swiper 组件样式
 - ✅ 已应用:tcb-shop-demo 设计规范(圆角32rpx,高度64rpx,主色调 #fa550f)
 - ✅ 已应用:tcb-shop-demo 设计规范(圆角32rpx,高度64rpx,主色调 #fa550f)
 - ✅ 已修复:组件依赖关系(Icon组件在Search组件之前创建)
 - ✅ 已修复:组件依赖关系(Icon组件在Search组件之前创建)
 - ✅ 已验证:TypeScript编译正常,无TDesign相关错误
 - ✅ 已验证:TypeScript编译正常,无TDesign相关错误
@@ -305,7 +308,8 @@ export default function TDesignSwiper({
 ### File List
 ### File List
 - **创建**: `mini/src/components/tdesign/search/index.tsx` - TDesign Search 组件
 - **创建**: `mini/src/components/tdesign/search/index.tsx` - TDesign Search 组件
 - **创建**: `mini/src/components/tdesign/icon/index.tsx` - TDesign Icon 组件
 - **创建**: `mini/src/components/tdesign/icon/index.tsx` - TDesign Icon 组件
-- **修改**: `mini/src/tcb-theme.css` - 添加 Search 组件样式
+- **创建**: `mini/src/components/tdesign/swiper/index.tsx` - TDesign Swiper 组件
+- **修改**: `mini/src/tcb-theme.css` - 添加 Search 和 Swiper 组件样式
 - **修改**: `docs/stories/001.004.homepage-ui-refactor.md` - 更新任务状态和开发记录
 - **修改**: `docs/stories/001.004.homepage-ui-refactor.md` - 更新任务状态和开发记录
 
 
 ### 实施经验总结
 ### 实施经验总结

+ 109 - 0
mini/src/components/tdesign/swiper/index.tsx

@@ -0,0 +1,109 @@
+import { useState } from 'react'
+import { Swiper, SwiperItem, Image, View } from '@tarojs/components'
+
+interface SwiperItemType {
+  value: string
+  ariaLabel?: string
+}
+
+interface SwiperProps {
+  images: string[] | SwiperItemType[]
+  autoplay?: boolean
+  current?: number
+  interval?: number
+  duration?: number
+  loop?: boolean
+  indicatorDots?: boolean
+  indicatorColor?: string
+  indicatorActiveColor?: string
+  vertical?: boolean
+  previousMargin?: string
+  nextMargin?: string
+  displayMultipleItems?: number
+  height?: string
+  onChange?: (current: number) => void
+  onTap?: (index: number) => void
+}
+
+export default function TDesignSwiper({
+  images = [],
+  autoplay = true,
+  current = 0,
+  interval = 5000,
+  duration = 300,
+  loop = true,
+  indicatorDots = true,
+  indicatorColor = '#999',
+  indicatorActiveColor = '#fa550f',
+  vertical = false,
+  previousMargin = '0',
+  nextMargin = '0',
+  displayMultipleItems = 1,
+  height = '192rpx',
+  onChange,
+  onTap
+}: SwiperProps) {
+  const [currentIndex, setCurrentIndex] = useState(current)
+
+  const handleChange = (e: any) => {
+    const newIndex = e.detail.current
+    setCurrentIndex(newIndex)
+    onChange?.(newIndex)
+  }
+
+  const handleTap = (index: number) => {
+    onTap?.(index)
+  }
+
+  const getImageUrl = (item: string | SwiperItemType): string => {
+    return typeof item === 'string' ? item : item.value
+  }
+
+  const getAriaLabel = (item: string | SwiperItemType, index: number): string => {
+    if (typeof item === 'object' && item.ariaLabel) {
+      return item.ariaLabel
+    }
+    return `轮播图 ${index + 1}`
+  }
+
+  return (
+    <View className="tdesign-swiper">
+      <Swiper
+        className="tdesign-swiper__host"
+        autoplay={autoplay}
+        current={currentIndex}
+        interval={interval}
+        duration={duration}
+        circular={loop}
+        vertical={vertical}
+        previousMargin={previousMargin}
+        nextMargin={nextMargin}
+        displayMultipleItems={displayMultipleItems}
+        indicatorDots={indicatorDots}
+        indicatorColor={indicatorColor}
+        indicatorActiveColor={indicatorActiveColor}
+        style={{ height }}
+        onChange={handleChange}
+      >
+        {images.map((item: string | SwiperItemType, index: number) => (
+          <SwiperItem key={index}>
+            <View
+              className="tdesign-swiper__item"
+              onClick={() => handleTap(index)}
+              aria-hidden={currentIndex !== index}
+              aria-role="image"
+              aria-label={getAriaLabel(item, index)}
+            >
+              <Image
+                src={getImageUrl(item)}
+                mode="aspectFill"
+                className="tdesign-swiper__image"
+                style={{ height }}
+              />
+            </View>
+          </SwiperItem>
+        ))}
+      </Swiper>
+    </View>
+  )
+}

+ 23 - 0
mini/src/tcb-theme.css

@@ -509,6 +509,29 @@
 .border-dashed { border-style: dashed; }
 .border-dashed { border-style: dashed; }
 .border-dotted { border-style: dotted; }
 .border-dotted { border-style: dotted; }
 
 
+/* ===== TDesign Swiper 组件样式 ===== */
+.tdesign-swiper {
+  position: relative;
+}
+
+.tdesign-swiper__host {
+  border-radius: var(--td-swiper-radius, 18rpx);
+  overflow: hidden;
+  transform: translateY(0);
+}
+
+.tdesign-swiper__item {
+  display: flex;
+  align-items: center;
+  box-sizing: border-box;
+  padding: var(--td-swiper-item-padding, 0);
+}
+
+.tdesign-swiper__image {
+  width: 100%;
+  transition: all 0.3s ease;
+}
+
 /* ===== TDesign Search 组件样式 ===== */
 /* ===== TDesign Search 组件样式 ===== */
 .tdesign-search {
 .tdesign-search {
   display: flex;
   display: flex;