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

📝 docs(commands): 重构开发指令文档结构

- 统一将开发规范文档从 .roo/rules 移动到 .roo/commands 目录
- 更新 generic-crud.md 中管理后台表单规范的引用路径
- 为 mini-form.md 添加小程序表单开发指令描述
- 扩展 mini-ui.md 为完整的小程序UI开发规范文档
- 删除已废弃的 13-ui-style.md 和 16-mini-program-ui.md 规则文件
yourname 6 месяцев назад
Родитель
Сommit
57f7ed7f28

+ 1 - 1
.roo/commands/generic-crud.md

@@ -11,5 +11,5 @@ description: "通用curd开发指令"
 创建通用CRUD路由
 注册路由到API
 创建客户端API调用方法
-创建管理后台页面,按照 管理后台界面开发规范
+创建管理后台页面,按照 .roo/commands/shadcn-manage-form.md 指令规范
 注册路由和菜单

+ 4 - 0
.roo/rules/17-mini-program-forms.md → .roo/commands/mini-form.md

@@ -1,3 +1,7 @@
+---
+description: "小程序表单开发指令"
+---
+
 # 小程序表单开发规范 (Tailwind CSS版)
 
 ## 概述

+ 486 - 1
.roo/commands/mini-ui.md

@@ -2,4 +2,489 @@
 description: "小程序ui开发指令"
 ---
 
-按小程序ui规范,小程序表单开发规范
+按小程序ui规范,小程序表单开发规范(.roo/commands/mini-form.md)
+
+# 小程序UI开发规范 (Tailwind CSS v4)
+
+## 概述
+
+本规范定义了基于Taro框架的小程序UI开发标准,采用Tailwind CSS v4原子化样式和Heroicons图标库,遵循shadcn/ui组件设计模式。
+
+## 技术栈
+
+- **Taro 4** - 跨端小程序框架
+- **React 18** - 前端框架
+- **Tailwind CSS v4** - 原子化CSS框架
+- **@egoist/tailwindcss-icons** - 图标库集成
+- **@weapp-tailwindcss/merge** - Tailwind类名合并工具(小程序版tailwind-merge)
+- **clsx** - 条件样式类名管理
+
+## 目录结构
+
+```
+mini/
+├── src/
+│   ├── components/
+│   │   └── ui/           # UI组件库
+│   │       ├── button.tsx
+│   │       ├── input.tsx
+│   │       ├── card.tsx
+│   │       └── ...
+│   ├── pages/
+│   ├── utils/
+│   └── app.css           # Tailwind样式入口
+├── tailwind.config.js    # Tailwind配置
+└── postcss.config.js     # PostCSS配置
+```
+
+## 样式规范
+
+### 1. Tailwind CSS v4 使用规范
+
+#### 1.1 基础类名使用
+```typescript
+// ✅ 正确使用原子类
+<View className="flex items-center justify-between p-4 bg-white rounded-lg shadow-sm">
+  <Text className="text-lg font-semibold text-gray-900">标题</Text>
+</View>
+
+// ❌ 避免使用内联样式
+<View style={{ display: 'flex', alignItems: 'center', padding: 16 }}>
+  <Text style={{ fontSize: 18, fontWeight: '600' }}>标题</Text>
+</View>
+```
+
+#### 1.2 类名合并规范
+```typescript
+// ✅ 使用twMerge处理动态类名冲突
+import { twMerge } from '@weapp-tailwindcss/merge'
+
+// 处理静态和动态类名的冲突
+<View className={twMerge('px-4 py-2', isActive ? 'bg-blue-500' : 'bg-gray-200')}>
+  <Text>按钮</Text>
+</View>
+
+// 处理多个条件类名的合并
+<View className={twMerge(
+  'flex items-center',
+  isActive && 'bg-blue-500 text-white',
+  isDisabled && 'opacity-50 cursor-not-allowed',
+  customClassName
+)}>
+  <Text>复杂组件</Text>
+</View>
+
+// ❌ 避免手动拼接类名导致冲突
+<View className={`px-4 py-2 ${isActive ? 'bg-blue-500' : 'bg-gray-200'} ${customClassName}`}>
+  <Text>按钮</Text>
+</View>
+```
+
+#### 1.2 响应式设计
+```typescript
+// 使用Tailwind的响应式前缀
+<View className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
+  <View className="w-full sm:w-1/2 md:w-1/3" />
+</View>
+```
+
+#### 1.3 状态样式
+```typescript
+// 悬停和焦点状态
+<Button className="bg-blue-500 hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
+  点击按钮
+</Button>
+
+// 禁用状态
+<Button className="disabled:opacity-50 disabled:cursor-not-allowed">
+  禁用按钮
+</Button>
+```
+
+### 2. 图标使用规范
+
+#### 2.1 图标
+使用`@egoist/tailwindcss-icons`提供的图标类名:
+"mdi", "lucide", "heroicons", "heroicons-outline", "heroicons-solid"
+
+```typescript
+// 基础用法
+<View className="i-heroicons-user-20-solid text-gray-600" />
+<Button className="flex items-center gap-2">
+  <View className="i-heroicons-plus-20-solid" />
+  <Text>添加</Text>
+</Button>
+
+// 图标大小和颜色
+<View className="i-heroicons-home-16-solid w-6 h-6 text-blue-500" />
+<View className="i-heroicons-cog-8-tooth-20-solid w-8 h-8 text-gray-400" />
+
+// 图标变体
+// solid - 实心图标
+// outline - 轮廓图标
+// mini - 迷你图标 (20x20)
+// micro - 微型图标 (16x16)
+<View className="i-heroicons-heart-20-solid text-red-500" />
+<View className="i-heroicons-heart-20-outline text-red-500" />
+```
+
+#### 2.2 图标命名规则
+```
+i-heroicons-[图标名]-[大小]-[变体]
+```
+- 大小: 16 | 20 | 24
+- 变体: solid | outline
+
+### 3. UI组件规范
+
+#### 3.1 组件文件结构
+每个UI组件应包含:
+```typescript
+// mini/src/components/ui/button.tsx
+import { Button as TaroButton, ButtonProps } from '@tarojs/components'
+import { cn } from '@/utils/cn'
+import { cva, type VariantProps } from 'class-variance-authority'
+
+const buttonVariants = cva(
+  'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
+  {
+    variants: {
+      variant: {
+        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
+        destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
+        outline: 'border border-input hover:bg-accent hover:text-accent-foreground',
+        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
+        ghost: 'hover:bg-accent hover:text-accent-foreground',
+        link: 'underline-offset-4 hover:underline text-primary',
+      },
+      size: {
+        default: 'h-10 py-2 px-4',
+        sm: 'h-9 px-3 rounded-md',
+        lg: 'h-11 px-8 rounded-md',
+        icon: 'h-10 w-10',
+      },
+    },
+    defaultVariants: {
+      variant: 'default',
+      size: 'default',
+    },
+  }
+)
+
+interface ButtonProps extends ButtonProps, VariantProps<typeof buttonVariants> {}
+
+export function Button({ className, variant, size, ...props }: ButtonProps) {
+  return (
+    <TaroButton
+      className={cn(buttonVariants({ variant, size, className }))}
+      {...props}
+    />
+  )
+}
+```
+
+#### 3.2 常用组件示例
+
+**按钮组件 (Button)**
+```typescript
+// 使用示例
+<Button variant="primary" size="lg" onClick={handleClick}>
+  <View className="i-heroicons-plus-20-solid mr-2" />
+  创建用户
+</Button>
+
+<Button variant="outline" size="sm" disabled={loading}>
+  {loading && <View className="i-heroicons-arrow-path-20-solid animate-spin mr-2" />}
+  加载中...
+</Button>
+```
+
+**卡片组件 (Card)**
+```typescript
+<Card className="p-6 bg-white rounded-lg shadow-sm">
+  <CardHeader>
+    <View className="flex items-center justify-between">
+      <Text className="text-lg font-semibold">用户信息</Text>
+      <View className="i-heroicons-user-circle-20-solid text-gray-400" />
+    </View>
+  </CardHeader>
+  <CardContent>
+    <Text className="text-gray-600">用户详情内容</Text>
+  </CardContent>
+</Card>
+```
+
+**输入框组件 (Input)**
+```typescript
+<View className="space-y-2">
+  <Label htmlFor="username">用户名</Label>
+  <View className="relative">
+    <View className="absolute left-3 top-1/2 -translate-y-1/2">
+      <View className="i-heroicons-user-20-solid text-gray-400 w-5 h-5" />
+    </View>
+    <Input
+      id="username"
+      className="pl-10"
+      placeholder="请输入用户名"
+      value={username}
+      onInput={handleInput}
+    />
+  </View>
+</View>
+```
+
+### 4. 页面布局规范
+
+#### 4.1 页面容器
+```typescript
+// 主容器
+<View className="min-h-screen bg-gray-50">
+  <View className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
+    {/* 页面内容 */}
+  </View>
+</View>
+
+// 卡片布局
+<View className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
+  {/* 卡片内容 */}
+</View>
+```
+
+#### 4.2 响应式断点
+- `sm`: 640px
+- `md`: 768px  
+- `lg`: 1024px
+- `xl`: 1280px
+- `2xl`: 1536px
+
+### 5. 主题配置
+
+#### 5.1 颜色系统
+```css
+/* 在 app.css 中定义 */
+:root {
+  --primary: 59 130 246;
+  --primary-foreground: 255 255 255;
+  --secondary: 107 114 128;
+  --secondary-foreground: 255 255 255;
+  --accent: 243 244 246;
+  --accent-foreground: 17 24 39;
+  --destructive: 239 68 68;
+  --destructive-foreground: 255 255 255;
+  --muted: 249 250 251;
+  --muted-foreground: 107 114 128;
+  --border: 229 231 235;
+  --input: 255 255 255;
+  --ring: 59 130 246;
+  --background: 255 255 255;
+  --foreground: 17 24 39;
+}
+```
+
+#### 5.2 Tailwind配置
+```javascript
+// tailwind.config.js
+module.exports = {
+  content: [
+    './src/**/*.{js,ts,jsx,tsx}',
+  ],
+  theme: {
+    extend: {
+      colors: {
+        primary: 'rgb(var(--primary))',
+        'primary-foreground': 'rgb(var(--primary-foreground))',
+        secondary: 'rgb(var(--secondary))',
+        'secondary-foreground': 'rgb(var(--secondary-foreground))',
+        accent: 'rgb(var(--accent))',
+        'accent-foreground': 'rgb(var(--accent-foreground))',
+        destructive: 'rgb(var(--destructive))',
+        'destructive-foreground': 'rgb(var(--destructive-foreground))',
+        muted: 'rgb(var(--muted))',
+        'muted-foreground': 'rgb(var(--muted-foreground))',
+        border: 'rgb(var(--border))',
+        input: 'rgb(var(--input))',
+        ring: 'rgb(var(--ring))',
+        background: 'rgb(var(--background))',
+        foreground: 'rgb(var(--foreground))',
+      },
+    },
+  },
+  plugins: [
+    require('@egoist/tailwindcss-icons')({
+      // 配置Heroicons
+      collections: {
+        heroicons: {
+          solid: true,
+          outline: true,
+          mini: true,
+        },
+      },
+    }),
+  ],
+}
+```
+
+### 6. 工具函数
+
+#### 6.1 类名合并工具
+```typescript
+// mini/src/utils/cn.ts
+import { clsx, type ClassValue } from 'clsx'
+import { twMerge } from '@weapp-tailwindcss/merge'
+
+export function cn(...inputs: ClassValue[]) {
+  return twMerge(clsx(inputs))
+}
+```
+
+#### 6.2 小程序专用类名处理
+```typescript
+// 小程序环境下的类名合并
+import { twMerge } from '@weapp-tailwindcss/merge'
+
+// 标准用法(自动处理小程序转义)
+const classes = twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
+// → 'hovercbg-dark-red p-3 bg-_hB91C1C_'
+
+// 手动指定版本(如果需要)
+import { twMerge as twMergeV4 } from '@weapp-tailwindcss/merge/v4'
+import { twMerge as twMergeV3 } from '@weapp-tailwindcss/merge/v3'
+
+// 使用cva进行组件变体管理
+import { cva } from 'class-variance-authority'
+
+const buttonVariants = cva(
+  'inline-flex items-center justify-center rounded-md text-sm font-medium',
+  {
+    variants: {
+      variant: {
+        default: 'bg-blue-500 text-white hover:bg-blue-600',
+        destructive: 'bg-red-500 text-white hover:bg-red-600',
+      },
+      size: {
+        sm: 'h-8 px-3 text-xs',
+        lg: 'h-12 px-6 text-base',
+      },
+    },
+  }
+)
+```
+
+### 7. 最佳实践
+
+#### 7.1 状态管理
+```typescript
+// 使用React Hook进行状态管理
+const [loading, setLoading] = useState(false)
+const [data, setData] = useState<User[]>([])
+
+// 加载状态显示
+{loading ? (
+  <View className="flex justify-center py-8">
+    <View className="i-heroicons-arrow-path-20-solid animate-spin w-8 h-8 text-blue-500" />
+  </View>
+) : (
+  <View className="grid grid-cols-1 gap-4">
+    {data.map(item => <Card key={item.id} {...item} />)}
+  </View>
+)}
+```
+
+#### 7.2 错误处理
+```typescript
+// 错误状态展示
+<View className="text-center py-8">
+  <View className="i-heroicons-exclamation-triangle-20-solid w-12 h-12 text-red-500 mx-auto mb-4" />
+  <Text className="text-gray-600">加载失败,请稍后重试</Text>
+  <Button variant="outline" size="sm" onClick={retry} className="mt-4">
+    重新加载
+  </Button>
+</View>
+```
+
+### 8. 性能优化
+
+#### 8.1 样式优化
+- 使用Tailwind的JIT模式,只生成用到的类名
+- 避免内联样式,全部使用类名
+- 合理使用`@apply`提取重复样式
+
+#### 8.2 图标优化
+- 使用CSS图标而非图片图标
+- 图标按需加载,不使用的图标不会被打包
+- 合理使用图标大小,避免过大图标
+
+### 9. 调试工具
+
+#### 9.1 开发调试
+```typescript
+// 添加调试样式类
+<View className="border border-red-500 debug">
+  <Text>调试内容</Text>
+</View>
+
+// 使用Tailwind的调试工具
+// 在开发环境中添加
+// <View className="outline outline-1 outline-red-500" />
+```
+
+### 10. tailwind-merge使用规范
+
+#### 10.1 基本用法
+```typescript
+// 单类名合并
+const result = twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
+// → 'hovercbg-dark-red p-3 bg-_hB91C1C_'
+
+// 处理冲突类名
+twMerge('px-4', 'px-2') // → 'px-2'
+twMerge('text-red-500', 'text-blue-500') // → 'text-blue-500'
+```
+
+#### 10.2 条件类名处理
+```typescript
+// 使用cn工具函数处理条件类名
+import { cn } from '@/utils/cn'
+
+const Button = ({ variant, size, disabled, className }) => {
+  return (
+    <Button
+      className={cn(
+        'inline-flex items-center justify-center rounded-md',
+        variant === 'primary' && 'bg-blue-500 text-white',
+        variant === 'secondary' && 'bg-gray-200 text-gray-800',
+        size === 'sm' && 'px-3 py-1 text-sm',
+        size === 'lg' && 'px-6 py-3 text-lg',
+        disabled && 'opacity-50 cursor-not-allowed',
+        className // 允许外部覆盖
+      )}
+    >
+      按钮
+    </Button>
+  )
+}
+```
+
+#### 10.3 小程序特殊处理
+```typescript
+// 跨端使用
+import { create } from '@weapp-tailwindcss/merge'
+
+const { twMerge } = create({
+  // 在当前环境为小程序时启用转义
+  disableEscape: true
+})
+
+// 版本选择
+import { twMerge as twMergeV4 } from '@weapp-tailwindcss/merge/v4' // Tailwind v4
+import { twMerge as twMergeV3 } from '@weapp-tailwindcss/merge/v3' // Tailwind v3
+```
+
+## 注意事项
+
+1. **兼容性**:确保所有类名在小程序环境中有效
+2. **性能**:避免过度嵌套和复杂选择器
+3. **可维护性**:保持组件结构清晰,样式统一
+4. **可读性**:合理使用空格和换行,提高代码可读性
+5. **tailwind-merge**:始终使用twMerge或cn工具函数处理动态类名,避免类名冲突
+6. **版本兼容**:根据Tailwind CSS版本选择正确的tailwind-merge版本

+ 0 - 241
.roo/rules/13-ui-style.md

@@ -1,241 +0,0 @@
-# 管理后台界面开发规范
-
-## 概述
-基于 `src/client/admin-shadcn/pages/Users.tsx` 中用户管理表单的实现,提取可复用的表单开发模式和最佳实践,适用于基于 Shadcn-ui 的管理后台表单开发。
-
-## 核心特性
-
-### 1. 类型安全表单
-- **后端Schema复用**:直接使用后端定义的 Zod Schema
-- **RPC类型提取**:从 Hono 客户端自动推断类型
-- **一致的类型定义**:前后端类型完全同步
-
-### 2. 表单状态管理
-- **创建/编辑模式切换**:单一表单处理两种状态
-- **智能默认值**:根据模式自动设置表单初始值
-- **表单重置**:模式切换时自动重置表单状态
-
-### 3. 统一的UI组件模式
-- **Shadcn-ui组件集成**:使用标准的 Shadcn-ui 表单组件
-- **响应式布局**:适配不同屏幕尺寸
-- **无障碍支持**:完整的 ARIA 属性支持
-
-## 开发模板
-
-### 基础结构模板
-```typescript
-// 1. 类型定义
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
-import { Input } from '@/client/components/ui/input';
-import { Button } from '@/client/components/ui/button';
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';
-
-// 2. 表单配置
-const [isCreateForm, setIsCreateForm] = useState(true);
-const [editingData, setEditingData] = useState<any>(null);
-
-const createForm = useForm<CreateType>({
-  resolver: zodResolver(createSchema),
-  defaultValues: {/* 创建时的默认值 */},
-});
-
-const updateForm = useForm<UpdateType>({
-  resolver: zodResolver(updateSchema),
-  defaultValues: {/* 更新时的默认值 */},
-});
-```
-
-### 表单字段模板
-
-#### 文本输入框
-```typescript
-<FormField
-  control={form.control}
-  name="username"
-  render={({ field }) => (
-    <FormItem>
-      <FormLabel className="flex items-center">
-        用户名
-        <span className="text-red-500 ml-1">*</span>
-      </FormLabel>
-      <FormControl>
-        <Input placeholder="请输入用户名" {...field} />
-      </FormControl>
-      <FormMessage />
-    </FormItem>
-  )}
-/>
-```
-
-#### 邮箱输入框
-```typescript
-<FormField
-  control={form.control}
-  name="email"
-  render={({ field }) => (
-    <FormItem>
-      <FormLabel>邮箱</FormLabel>
-      <FormControl>
-        <Input type="email" placeholder="请输入邮箱" {...field} />
-      </FormControl>
-      <FormMessage />
-    </FormItem>
-  )}
-/>
-```
-
-#### 密码输入框
-```typescript
-<FormField
-  control={form.control}
-  name="password"
-  render={({ field }) => (
-    <FormItem>
-      <FormLabel className="flex items-center">
-        密码
-        <span className="text-red-500 ml-1">*</span>
-      </FormLabel>
-      <FormControl>
-        <Input type="password" placeholder="请输入密码" {...field} />
-      </FormControl>
-      <FormMessage />
-    </FormItem>
-  )}
-/>
-```
-
-#### 开关控件(布尔值)
-```typescript
-<FormField
-  control={form.control}
-  name="isDisabled"
-  render={({ field }) => (
-    <FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
-      <div className="space-y-0.5">
-        <FormLabel className="text-base">状态</FormLabel>
-        <FormDescription>
-          禁用后用户将无法登录系统
-        </FormDescription>
-      </div>
-      <FormControl>
-        <Switch
-          checked={field.value === 1}
-          onCheckedChange={(checked) => field.onChange(checked ? 1 : 0)}
-        />
-      </FormControl>
-    </FormItem>
-  )}
-/>
-```
-
-#### 可选字段处理
-```typescript
-// 创建时:必须提供值
-nickname: z.string().optional()
-
-// 更新时:完全可选
-nickname: z.string().optional()
-```
-
-### 对话框集成模板
-```typescript
-<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
-  <DialogContent className="sm:max-w-[500px]">
-    <DialogHeader>
-      <DialogTitle>{isCreateForm ? '创建' : '编辑'}用户</DialogTitle>
-      <DialogDescription>
-        {isCreateForm ? '创建新记录' : '编辑现有记录'}
-      </DialogDescription>
-    </DialogHeader>
-    
-    <Form {...(isCreateForm ? createForm : updateForm)}>
-      <form onSubmit={form.handleSubmit(isCreateForm ? handleCreate : handleUpdate)} className="space-y-4">
-        {/* 表单字段 */}
-        
-        <DialogFooter>
-          <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-            取消
-          </Button>
-          <Button type="submit">
-            {isCreateForm ? '创建' : '更新'}
-          </Button>
-        </DialogFooter>
-      </form>
-    </Form>
-  </DialogContent>
-</Dialog>
-```
-
-## 最佳实践
-
-### 1. 表单验证
-- 使用 Zod Schema 进行类型验证
-- 必填字段标记红色星号
-- 提供清晰的错误提示
-
-### 2. 用户体验
-- 表单提交时显示加载状态
-- 操作成功后显示 toast 通知
-- 支持键盘导航和提交
-
-### 3. 数据管理
-- 创建后自动刷新数据列表
-- 编辑时回填现有数据
-- 支持表单重置功能
-
-### 4. 响应式设计
-- 对话框最大宽度 `sm:max-w-[500px]`
-- 表单间距统一使用 `space-y-4`
-- 移动端友好的布局
-
-## 使用示例
-
-### 完整实现参考
-```typescript
-// 创建用户
-const handleCreateSubmit = async (data: CreateUserFormData) => {
-  try {
-    const res = await apiClient.$post({ json: data });
-    if (res.status !== 201) throw new Error('创建失败');
-    toast.success('创建成功');
-    setIsModalOpen(false);
-    refetch();
-  } catch (error) {
-    toast.error('创建失败,请重试');
-  }
-};
-
-// 更新用户
-const handleUpdateSubmit = async (data: UpdateUserFormData) => {
-  try {
-    const res = await apiClient[':id']['$put']({
-      param: { id: editingData.id },
-      json: data
-    });
-    if (res.status !== 200) throw new Error('更新失败');
-    toast.success('更新成功');
-    setIsModalOpen(false);
-    refetch();
-  } catch (error) {
-    toast.error('更新失败,请重试');
-  }
-};
-```
-
-## 组件导入清单
-```typescript
-// 表单相关
-import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
-import { Input } from '@/client/components/ui/input';
-import { Button } from '@/client/components/ui/button';
-import { Switch } from '@/client/components/ui/switch';
-
-// 对话框相关
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';
-
-// 表单工具
-import { useForm } from 'react-hook-form';
-import { zodResolver } from '@hookform/resolvers/zod';
-import { toast } from 'sonner';

+ 0 - 484
.roo/rules/16-mini-program-ui.md

@@ -1,484 +0,0 @@
-# 小程序UI开发规范 (Tailwind CSS v4)
-
-## 概述
-
-本规范定义了基于Taro框架的小程序UI开发标准,采用Tailwind CSS v4原子化样式和Heroicons图标库,遵循shadcn/ui组件设计模式。
-
-## 技术栈
-
-- **Taro 4** - 跨端小程序框架
-- **React 18** - 前端框架
-- **Tailwind CSS v4** - 原子化CSS框架
-- **@egoist/tailwindcss-icons** - 图标库集成
-- **@weapp-tailwindcss/merge** - Tailwind类名合并工具(小程序版tailwind-merge)
-- **clsx** - 条件样式类名管理
-
-## 目录结构
-
-```
-mini/
-├── src/
-│   ├── components/
-│   │   └── ui/           # UI组件库
-│   │       ├── button.tsx
-│   │       ├── input.tsx
-│   │       ├── card.tsx
-│   │       └── ...
-│   ├── pages/
-│   ├── utils/
-│   └── app.css           # Tailwind样式入口
-├── tailwind.config.js    # Tailwind配置
-└── postcss.config.js     # PostCSS配置
-```
-
-## 样式规范
-
-### 1. Tailwind CSS v4 使用规范
-
-#### 1.1 基础类名使用
-```typescript
-// ✅ 正确使用原子类
-<View className="flex items-center justify-between p-4 bg-white rounded-lg shadow-sm">
-  <Text className="text-lg font-semibold text-gray-900">标题</Text>
-</View>
-
-// ❌ 避免使用内联样式
-<View style={{ display: 'flex', alignItems: 'center', padding: 16 }}>
-  <Text style={{ fontSize: 18, fontWeight: '600' }}>标题</Text>
-</View>
-```
-
-#### 1.2 类名合并规范
-```typescript
-// ✅ 使用twMerge处理动态类名冲突
-import { twMerge } from '@weapp-tailwindcss/merge'
-
-// 处理静态和动态类名的冲突
-<View className={twMerge('px-4 py-2', isActive ? 'bg-blue-500' : 'bg-gray-200')}>
-  <Text>按钮</Text>
-</View>
-
-// 处理多个条件类名的合并
-<View className={twMerge(
-  'flex items-center',
-  isActive && 'bg-blue-500 text-white',
-  isDisabled && 'opacity-50 cursor-not-allowed',
-  customClassName
-)}>
-  <Text>复杂组件</Text>
-</View>
-
-// ❌ 避免手动拼接类名导致冲突
-<View className={`px-4 py-2 ${isActive ? 'bg-blue-500' : 'bg-gray-200'} ${customClassName}`}>
-  <Text>按钮</Text>
-</View>
-```
-
-#### 1.2 响应式设计
-```typescript
-// 使用Tailwind的响应式前缀
-<View className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
-  <View className="w-full sm:w-1/2 md:w-1/3" />
-</View>
-```
-
-#### 1.3 状态样式
-```typescript
-// 悬停和焦点状态
-<Button className="bg-blue-500 hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
-  点击按钮
-</Button>
-
-// 禁用状态
-<Button className="disabled:opacity-50 disabled:cursor-not-allowed">
-  禁用按钮
-</Button>
-```
-
-### 2. 图标使用规范
-
-#### 2.1 图标
-使用`@egoist/tailwindcss-icons`提供的图标类名:
-"mdi", "lucide", "heroicons", "heroicons-outline", "heroicons-solid"
-
-```typescript
-// 基础用法
-<View className="i-heroicons-user-20-solid text-gray-600" />
-<Button className="flex items-center gap-2">
-  <View className="i-heroicons-plus-20-solid" />
-  <Text>添加</Text>
-</Button>
-
-// 图标大小和颜色
-<View className="i-heroicons-home-16-solid w-6 h-6 text-blue-500" />
-<View className="i-heroicons-cog-8-tooth-20-solid w-8 h-8 text-gray-400" />
-
-// 图标变体
-// solid - 实心图标
-// outline - 轮廓图标
-// mini - 迷你图标 (20x20)
-// micro - 微型图标 (16x16)
-<View className="i-heroicons-heart-20-solid text-red-500" />
-<View className="i-heroicons-heart-20-outline text-red-500" />
-```
-
-#### 2.2 图标命名规则
-```
-i-heroicons-[图标名]-[大小]-[变体]
-```
-- 大小: 16 | 20 | 24
-- 变体: solid | outline
-
-### 3. UI组件规范
-
-#### 3.1 组件文件结构
-每个UI组件应包含:
-```typescript
-// mini/src/components/ui/button.tsx
-import { Button as TaroButton, ButtonProps } from '@tarojs/components'
-import { cn } from '@/utils/cn'
-import { cva, type VariantProps } from 'class-variance-authority'
-
-const buttonVariants = cva(
-  'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background',
-  {
-    variants: {
-      variant: {
-        default: 'bg-primary text-primary-foreground hover:bg-primary/90',
-        destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
-        outline: 'border border-input hover:bg-accent hover:text-accent-foreground',
-        secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
-        ghost: 'hover:bg-accent hover:text-accent-foreground',
-        link: 'underline-offset-4 hover:underline text-primary',
-      },
-      size: {
-        default: 'h-10 py-2 px-4',
-        sm: 'h-9 px-3 rounded-md',
-        lg: 'h-11 px-8 rounded-md',
-        icon: 'h-10 w-10',
-      },
-    },
-    defaultVariants: {
-      variant: 'default',
-      size: 'default',
-    },
-  }
-)
-
-interface ButtonProps extends ButtonProps, VariantProps<typeof buttonVariants> {}
-
-export function Button({ className, variant, size, ...props }: ButtonProps) {
-  return (
-    <TaroButton
-      className={cn(buttonVariants({ variant, size, className }))}
-      {...props}
-    />
-  )
-}
-```
-
-#### 3.2 常用组件示例
-
-**按钮组件 (Button)**
-```typescript
-// 使用示例
-<Button variant="primary" size="lg" onClick={handleClick}>
-  <View className="i-heroicons-plus-20-solid mr-2" />
-  创建用户
-</Button>
-
-<Button variant="outline" size="sm" disabled={loading}>
-  {loading && <View className="i-heroicons-arrow-path-20-solid animate-spin mr-2" />}
-  加载中...
-</Button>
-```
-
-**卡片组件 (Card)**
-```typescript
-<Card className="p-6 bg-white rounded-lg shadow-sm">
-  <CardHeader>
-    <View className="flex items-center justify-between">
-      <Text className="text-lg font-semibold">用户信息</Text>
-      <View className="i-heroicons-user-circle-20-solid text-gray-400" />
-    </View>
-  </CardHeader>
-  <CardContent>
-    <Text className="text-gray-600">用户详情内容</Text>
-  </CardContent>
-</Card>
-```
-
-**输入框组件 (Input)**
-```typescript
-<View className="space-y-2">
-  <Label htmlFor="username">用户名</Label>
-  <View className="relative">
-    <View className="absolute left-3 top-1/2 -translate-y-1/2">
-      <View className="i-heroicons-user-20-solid text-gray-400 w-5 h-5" />
-    </View>
-    <Input
-      id="username"
-      className="pl-10"
-      placeholder="请输入用户名"
-      value={username}
-      onInput={handleInput}
-    />
-  </View>
-</View>
-```
-
-### 4. 页面布局规范
-
-#### 4.1 页面容器
-```typescript
-// 主容器
-<View className="min-h-screen bg-gray-50">
-  <View className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
-    {/* 页面内容 */}
-  </View>
-</View>
-
-// 卡片布局
-<View className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
-  {/* 卡片内容 */}
-</View>
-```
-
-#### 4.2 响应式断点
-- `sm`: 640px
-- `md`: 768px  
-- `lg`: 1024px
-- `xl`: 1280px
-- `2xl`: 1536px
-
-### 5. 主题配置
-
-#### 5.1 颜色系统
-```css
-/* 在 app.css 中定义 */
-:root {
-  --primary: 59 130 246;
-  --primary-foreground: 255 255 255;
-  --secondary: 107 114 128;
-  --secondary-foreground: 255 255 255;
-  --accent: 243 244 246;
-  --accent-foreground: 17 24 39;
-  --destructive: 239 68 68;
-  --destructive-foreground: 255 255 255;
-  --muted: 249 250 251;
-  --muted-foreground: 107 114 128;
-  --border: 229 231 235;
-  --input: 255 255 255;
-  --ring: 59 130 246;
-  --background: 255 255 255;
-  --foreground: 17 24 39;
-}
-```
-
-#### 5.2 Tailwind配置
-```javascript
-// tailwind.config.js
-module.exports = {
-  content: [
-    './src/**/*.{js,ts,jsx,tsx}',
-  ],
-  theme: {
-    extend: {
-      colors: {
-        primary: 'rgb(var(--primary))',
-        'primary-foreground': 'rgb(var(--primary-foreground))',
-        secondary: 'rgb(var(--secondary))',
-        'secondary-foreground': 'rgb(var(--secondary-foreground))',
-        accent: 'rgb(var(--accent))',
-        'accent-foreground': 'rgb(var(--accent-foreground))',
-        destructive: 'rgb(var(--destructive))',
-        'destructive-foreground': 'rgb(var(--destructive-foreground))',
-        muted: 'rgb(var(--muted))',
-        'muted-foreground': 'rgb(var(--muted-foreground))',
-        border: 'rgb(var(--border))',
-        input: 'rgb(var(--input))',
-        ring: 'rgb(var(--ring))',
-        background: 'rgb(var(--background))',
-        foreground: 'rgb(var(--foreground))',
-      },
-    },
-  },
-  plugins: [
-    require('@egoist/tailwindcss-icons')({
-      // 配置Heroicons
-      collections: {
-        heroicons: {
-          solid: true,
-          outline: true,
-          mini: true,
-        },
-      },
-    }),
-  ],
-}
-```
-
-### 6. 工具函数
-
-#### 6.1 类名合并工具
-```typescript
-// mini/src/utils/cn.ts
-import { clsx, type ClassValue } from 'clsx'
-import { twMerge } from '@weapp-tailwindcss/merge'
-
-export function cn(...inputs: ClassValue[]) {
-  return twMerge(clsx(inputs))
-}
-```
-
-#### 6.2 小程序专用类名处理
-```typescript
-// 小程序环境下的类名合并
-import { twMerge } from '@weapp-tailwindcss/merge'
-
-// 标准用法(自动处理小程序转义)
-const classes = twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
-// → 'hovercbg-dark-red p-3 bg-_hB91C1C_'
-
-// 手动指定版本(如果需要)
-import { twMerge as twMergeV4 } from '@weapp-tailwindcss/merge/v4'
-import { twMerge as twMergeV3 } from '@weapp-tailwindcss/merge/v3'
-
-// 使用cva进行组件变体管理
-import { cva } from 'class-variance-authority'
-
-const buttonVariants = cva(
-  'inline-flex items-center justify-center rounded-md text-sm font-medium',
-  {
-    variants: {
-      variant: {
-        default: 'bg-blue-500 text-white hover:bg-blue-600',
-        destructive: 'bg-red-500 text-white hover:bg-red-600',
-      },
-      size: {
-        sm: 'h-8 px-3 text-xs',
-        lg: 'h-12 px-6 text-base',
-      },
-    },
-  }
-)
-```
-
-### 7. 最佳实践
-
-#### 7.1 状态管理
-```typescript
-// 使用React Hook进行状态管理
-const [loading, setLoading] = useState(false)
-const [data, setData] = useState<User[]>([])
-
-// 加载状态显示
-{loading ? (
-  <View className="flex justify-center py-8">
-    <View className="i-heroicons-arrow-path-20-solid animate-spin w-8 h-8 text-blue-500" />
-  </View>
-) : (
-  <View className="grid grid-cols-1 gap-4">
-    {data.map(item => <Card key={item.id} {...item} />)}
-  </View>
-)}
-```
-
-#### 7.2 错误处理
-```typescript
-// 错误状态展示
-<View className="text-center py-8">
-  <View className="i-heroicons-exclamation-triangle-20-solid w-12 h-12 text-red-500 mx-auto mb-4" />
-  <Text className="text-gray-600">加载失败,请稍后重试</Text>
-  <Button variant="outline" size="sm" onClick={retry} className="mt-4">
-    重新加载
-  </Button>
-</View>
-```
-
-### 8. 性能优化
-
-#### 8.1 样式优化
-- 使用Tailwind的JIT模式,只生成用到的类名
-- 避免内联样式,全部使用类名
-- 合理使用`@apply`提取重复样式
-
-#### 8.2 图标优化
-- 使用CSS图标而非图片图标
-- 图标按需加载,不使用的图标不会被打包
-- 合理使用图标大小,避免过大图标
-
-### 9. 调试工具
-
-#### 9.1 开发调试
-```typescript
-// 添加调试样式类
-<View className="border border-red-500 debug">
-  <Text>调试内容</Text>
-</View>
-
-// 使用Tailwind的调试工具
-// 在开发环境中添加
-// <View className="outline outline-1 outline-red-500" />
-```
-
-### 10. tailwind-merge使用规范
-
-#### 10.1 基本用法
-```typescript
-// 单类名合并
-const result = twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
-// → 'hovercbg-dark-red p-3 bg-_hB91C1C_'
-
-// 处理冲突类名
-twMerge('px-4', 'px-2') // → 'px-2'
-twMerge('text-red-500', 'text-blue-500') // → 'text-blue-500'
-```
-
-#### 10.2 条件类名处理
-```typescript
-// 使用cn工具函数处理条件类名
-import { cn } from '@/utils/cn'
-
-const Button = ({ variant, size, disabled, className }) => {
-  return (
-    <Button
-      className={cn(
-        'inline-flex items-center justify-center rounded-md',
-        variant === 'primary' && 'bg-blue-500 text-white',
-        variant === 'secondary' && 'bg-gray-200 text-gray-800',
-        size === 'sm' && 'px-3 py-1 text-sm',
-        size === 'lg' && 'px-6 py-3 text-lg',
-        disabled && 'opacity-50 cursor-not-allowed',
-        className // 允许外部覆盖
-      )}
-    >
-      按钮
-    </Button>
-  )
-}
-```
-
-#### 10.3 小程序特殊处理
-```typescript
-// 跨端使用
-import { create } from '@weapp-tailwindcss/merge'
-
-const { twMerge } = create({
-  // 在当前环境为小程序时启用转义
-  disableEscape: true
-})
-
-// 版本选择
-import { twMerge as twMergeV4 } from '@weapp-tailwindcss/merge/v4' // Tailwind v4
-import { twMerge as twMergeV3 } from '@weapp-tailwindcss/merge/v3' // Tailwind v3
-```
-
-## 注意事项
-
-1. **兼容性**:确保所有类名在小程序环境中有效
-2. **性能**:避免过度嵌套和复杂选择器
-3. **可维护性**:保持组件结构清晰,样式统一
-4. **可读性**:合理使用空格和换行,提高代码可读性
-5. **tailwind-merge**:始终使用twMerge或cn工具函数处理动态类名,避免类名冲突
-6. **版本兼容**:根据Tailwind CSS版本选择正确的tailwind-merge版本