Преглед изворни кода

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

- 创建 `mini/src/components/tdesign/search/index.tsx` - Search组件,实现搜索功能
- 对照 `mini/tdesign/search/` 目录结构和功能进行开发
- 添加Search组件样式到 `mini/src/tcb-theme.css`
- 应用tcb-shop-demo设计规范(圆角32rpx,高度64rpx,主色调 #fa550f)

📝 docs(stories): 更新开发文档和任务状态

- 标记Search组件任务为已完成
- 添加开发代理使用的模型信息(Claude Sonnet 4.5)
- 记录调试日志和完成笔记
- 更新文件列表,添加创建和修改的文件记录
yourname пре 1 месец
родитељ
комит
b15b0288ff

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

@@ -18,9 +18,9 @@ Draft
 ## Tasks / Subtasks
 - [ ] 创建TDesign组件库 (AC: 1, 5)
   - [ ] 创建Taro React版本的TDesign组件
-    - [ ] 创建 `mini/src/components/tdesign/search/index.tsx` - Search组件 (对照: `mini/tdesign/search/`)
-    - [ ] 创建 `mini/src/components/tdesign/swiper/index.tsx` - Swiper组件 (对照: `mini/tdesign/swiper/`)
     - [ ] 创建 `mini/src/components/tdesign/icon/index.tsx` - Icon组件 (对照: `mini/tdesign/icon/`)
+    - [x] 创建 `mini/src/components/tdesign/search/index.tsx` - Search组件 (对照: `mini/tdesign/search/`)
+    - [ ] 创建 `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/tabs/index.tsx` - Tabs组件 (对照: `mini/tdesign/tabs/`)
 - [ ] 实现商品卡片组件 (AC: 3)
@@ -286,16 +286,22 @@ export default function TDesignSwiper({
 *This section is populated by the development agent during implementation*
 
 ### Agent Model Used
-*Record the specific AI agent model and version used for development*
+- Claude Sonnet 4.5 (d8d-model)
 
 ### Debug Log References
-*Reference any debug logs or traces generated during development*
+- 成功读取 TDesign Search 组件源文件:search.js, search.wxml, search.wxss, props.js
+- 成功创建 Taro React 版本的 Search 组件
 
 ### Completion Notes List
-*Notes about the completion of tasks and any issues encountered*
+- ✅ 已完成:创建 `mini/src/components/tdesign/search/index.tsx` - Search组件
+- ✅ 已对照:`mini/tdesign/search/` 目录结构和功能
+- ✅ 已集成:tcb-theme.css 中的 Search 组件样式
+- ✅ 已应用:tcb-shop-demo 设计规范(圆角32rpx,高度64rpx,主色调 #fa550f)
 
 ### File List
-*List all files created, modified, or affected during story implementation*
+- **创建**: `mini/src/components/tdesign/search/index.tsx` - TDesign Search 组件
+- **修改**: `mini/src/tcb-theme.css` - 添加 Search 组件样式
+- **修改**: `docs/stories/001.004.homepage-ui-refactor.md` - 更新任务状态和开发记录
 
 ## QA Results
 *Results from QA Agent QA review of the completed story implementation*

+ 125 - 0
mini/src/components/tdesign/search/index.tsx

@@ -0,0 +1,125 @@
+import { useState } from 'react'
+import { View, Input } from '@tarojs/components'
+import TDesignIcon from '../icon'
+
+interface SearchProps {
+  placeholder?: string
+  disabled?: boolean
+  shape?: 'round' | 'square'
+  value?: string
+  leftIcon?: string
+  clearable?: boolean
+  action?: string
+  center?: boolean
+  onChange?: (value: string) => void
+  onFocus?: () => void
+  onBlur?: () => void
+  onSubmit?: (value: string) => void
+  onClear?: () => void
+  onActionClick?: () => void
+}
+
+export default function TDesignSearch({
+  placeholder = '搜索商品',
+  disabled = false,
+  shape = 'round',
+  value = '',
+  leftIcon = 'search',
+  clearable = true,
+  action = '',
+  center = false,
+  onChange,
+  onFocus,
+  onBlur,
+  onSubmit,
+  onClear,
+  onActionClick
+}: SearchProps) {
+  const [focused, setFocused] = useState(false)
+  const [internalValue, setInternalValue] = useState(value)
+
+  const handleInput = (e) => {
+    const newValue = e.detail.value
+    setInternalValue(newValue)
+    onChange?.(newValue)
+  }
+
+  const handleFocus = () => {
+    setFocused(true)
+    onFocus?.()
+  }
+
+  const handleBlur = () => {
+    setFocused(false)
+    onBlur?.()
+  }
+
+  const handleConfirm = (e) => {
+    onSubmit?.(e.detail.value)
+  }
+
+  const handleClear = () => {
+    setInternalValue('')
+    onChange?.('')
+    onClear?.()
+  }
+
+  const handleActionClick = () => {
+    onActionClick?.()
+  }
+
+  const showClearIcon = clearable && internalValue && !disabled
+
+  return (
+    <View className={`tdesign-search tdesign-search--${shape}`}>
+      <View
+        className={`
+          tdesign-search__input-box
+          ${focused ? 'tdesign-search__input-box--focused' : ''}
+          ${center ? 'tdesign-search__input-box--center' : ''}
+          tdesign-search__input-box--${shape}
+        `}
+      >
+        {leftIcon && (
+          <TDesignIcon
+            name={leftIcon}
+            size="32rpx"
+            color="#fa550f"
+            className="tdesign-search__icon"
+          />
+        )}
+
+        <Input
+          type="text"
+          placeholder={placeholder}
+          disabled={disabled}
+          value={internalValue}
+          onInput={handleInput}
+          onFocus={handleFocus}
+          onBlur={handleBlur}
+          onConfirm={handleConfirm}
+          className={`tdesign-search__input ${disabled ? 'tdesign-search__input--disabled' : ''}`}
+          placeholderClass="tdesign-search__placeholder"
+        />
+
+        {showClearIcon && (
+          <View
+            className="tdesign-search__clear hotspot-expanded"
+            onClick={handleClear}
+          >
+            <TDesignIcon name="close-circle-filled" size="32rpx" color="#999" />
+          </View>
+        )}
+      </View>
+
+      {action && (
+        <View
+          className="tdesign-search__search-action"
+          onClick={handleActionClick}
+        >
+          {action}
+        </View>
+      )}
+    </View>
+  )
+}

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

@@ -509,6 +509,81 @@
 .border-dashed { border-style: dashed; }
 .border-dotted { border-style: dotted; }
 
+/* ===== TDesign Search 组件样式 ===== */
+.tdesign-search {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.tdesign-search__input-box {
+  flex: 1;
+  box-sizing: border-box;
+  display: flex;
+  height: 64rpx;
+  align-items: center;
+  border: 2rpx solid #f3f3f3;
+  background: #f3f3f3;
+  padding: 16rpx 24rpx;
+}
+
+.tdesign-search__input-box--focused {
+  border-color: #fa550f;
+}
+
+.tdesign-search__input-box--round {
+  border-radius: 32rpx;
+}
+
+.tdesign-search__input-box--square {
+  border-radius: 12rpx;
+}
+
+.tdesign-search__input-box--center {
+  text-align: center;
+}
+
+.tdesign-search__icon {
+  color: #fa550f;
+  font-size: 32rpx;
+}
+
+.tdesign-search__input {
+  display: inline-block;
+  flex: 1;
+  color: #333333;
+  font-size: 32rpx;
+  padding-left: 10rpx;
+  min-height: 48rpx;
+  line-height: 48rpx;
+  background: transparent;
+  border: none;
+  outline: none;
+}
+
+.tdesign-search__input--disabled {
+  color: rgba(0, 0, 0, 0.26);
+  cursor: not-allowed;
+  opacity: 1;
+}
+
+.tdesign-search__placeholder {
+  color: #bbbbbb;
+}
+
+.tdesign-search__clear {
+  position: relative;
+  margin-left: 10px;
+  font-size: 32rpx;
+  color: #999;
+}
+
+.tdesign-search__search-action {
+  margin-left: 30rpx;
+  font-size: 32rpx;
+  color: #fa550f;
+}
+
 /* ===== 兼容性处理 ===== */
 /* 确保与现有Tailwind CSS样式兼容 */
 /* 这些类名不会与Tailwind CSS的默认类名冲突 */