浏览代码

📝 docs(shadcn): 完善骨架屏和UI组件使用规范

- 添加骨架屏实现方案,包括完整表格骨架和简化版骨架
- 新增日期格式化规范,包含标准格式、仅日期格式和完整时间格式
- 添加日期输入格式示例代码
- 引入相对时间显示功能及示例
- 新增消息通知规范,包含成功、错误、警告和信息四种通知类型
- 添加消息通知与API响应集成的示例代码
yourname 4 月之前
父节点
当前提交
72dd425a10
共有 1 个文件被更改,包括 173 次插入9 次删除
  1. 173 9
      .roo/commands/shadcn-manage-page.md

+ 173 - 9
.roo/commands/shadcn-manage-page.md

@@ -314,27 +314,89 @@ const handleCreateSubmit = async (data: CreateRequest) => {
 ## 加载状态处理
 
 ### 1. 骨架屏模式
+
+#### 1.1 导入依赖
+```typescript
+import { Skeleton } from '@/client/components/ui/skeleton';
+```
+
+#### 1.2 完整骨架屏实现
 ```tsx
 if (isLoading) {
   return (
     <div className="space-y-4">
+      {/* 标题区域骨架 */}
       <div className="flex justify-between items-center">
-        <h1 className="text-2xl font-bold">页面标题</h1>
-        <Button disabled>
-          <Plus className="mr-2 h-4 w-4" />
-          创建实体
-        </Button>
+        <Skeleton className="h-8 w-48" />
+        <Skeleton className="h-10 w-32" />
       </div>
       
+      {/* 搜索区域骨架 */}
       <Card>
         <CardHeader>
           <Skeleton className="h-6 w-1/4" />
         </CardHeader>
         <CardContent>
-          <div className="space-y-2">
-            <Skeleton className="h-4 w-full" />
-            <Skeleton className="h-4 w-full" />
-            <Skeleton className="h-4 w-full" />
+          <Skeleton className="h-10 w-full max-w-sm" />
+        </CardContent>
+      </Card>
+      
+      {/* 表格骨架 */}
+      <Card>
+        <CardHeader>
+          <Skeleton className="h-6 w-1/3" />
+        </CardHeader>
+        <CardContent>
+          <Table>
+            <TableHeader>
+              <TableRow>
+                {[...Array(5)].map((_, i) => (
+                  <TableHead key={i}>
+                    <Skeleton className="h-4 w-full" />
+                  </TableHead>
+                ))}
+              </TableRow>
+            </TableHeader>
+            <TableBody>
+              {[...Array(5)].map((_, i) => (
+                <TableRow key={i}>
+                  {[...Array(5)].map((_, j) => (
+                    <TableCell key={j}>
+                      <Skeleton className="h-4 w-full" />
+                    </TableCell>
+                  ))}
+                </TableRow>
+              ))}
+            </TableBody>
+          </Table>
+        </CardContent>
+      </Card>
+    </div>
+  );
+}
+```
+
+#### 1.3 简化骨架屏(推荐)
+```tsx
+if (isLoading) {
+  return (
+    <div className="space-y-4">
+      <div className="flex justify-between items-center">
+        <Skeleton className="h-8 w-48" />
+        <Skeleton className="h-10 w-32" />
+      </div>
+      
+      <Card>
+        <CardContent className="pt-6">
+          <div className="space-y-3">
+            {[...Array(5)].map((_, i) => (
+              <div key={i} className="flex gap-4">
+                <Skeleton className="h-10 flex-1" />
+                <Skeleton className="h-10 flex-1" />
+                <Skeleton className="h-10 flex-1" />
+                <Skeleton className="h-10 w-20" />
+              </div>
+            ))}
           </div>
         </CardContent>
       </Card>
@@ -667,4 +729,106 @@ import ImageSelector from '@/client/admin-shadcn/components/ImageSelector';
     </FormItem>
   )}
 />
+```
+
+### 4.3 日期格式化规范
+
+#### 4.3.1 导入依赖
+```typescript
+import { format } from 'date-fns';
+```
+
+#### 4.3.2 日期显示格式
+```tsx
+// 标准日期时间格式:yyyy-MM-dd HH:mm
+<TableCell>
+  {user.createdAt ? format(new Date(user.createdAt), 'yyyy-MM-dd HH:mm') : '-'}
+</TableCell>
+
+// 仅日期格式:yyyy-MM-dd
+<TableCell>
+  {user.birthday ? format(new Date(user.birthday), 'yyyy-MM-dd') : '-'}
+</TableCell>
+
+// 完整时间格式:yyyy-MM-dd HH:mm:ss
+<TableCell>
+  {user.updatedAt ? format(new Date(user.updatedAt), 'yyyy-MM-dd HH:mm:ss') : '-'}
+</TableCell>
+```
+
+#### 4.3.3 日期输入格式
+```tsx
+// 在表单中使用日期选择器
+<FormField
+  control={form.control}
+  name="startDate"
+  render={({ field }) => (
+    <FormItem>
+      <FormLabel>开始日期</FormLabel>
+      <FormControl>
+        <Input
+          type="date"
+          {...field}
+          value={field.value ? format(new Date(field.value), 'yyyy-MM-dd') : ''}
+          onChange={(e) => field.onChange(e.target.value)}
+        />
+      </FormControl>
+    </FormItem>
+  )}
+/>
+```
+
+#### 4.3.4 相对时间显示(可选)
+```typescript
+import { formatDistanceToNow } from 'date-fns';
+import { zhCN } from 'date-fns/locale';
+
+// 相对时间显示
+<TableCell>
+  {user.createdAt ? formatDistanceToNow(new Date(user.createdAt), { addSuffix: true, locale: zhCN }) : '-'}
+</TableCell>
+```
+
+### 4.4 消息通知规范
+
+#### 4.4.1 导入依赖
+```typescript
+import { toast } from 'sonner';
+```
+
+#### 4.4.2 使用规范
+```typescript
+// 成功通知
+toast.success('操作成功');
+toast.success('用户创建成功');
+
+// 错误通知
+toast.error('操作失败');
+toast.error('创建用户失败,请重试');
+
+// 警告通知
+toast.warning('请确认操作');
+toast.warning('该操作将删除所有相关数据');
+
+// 信息通知
+toast.info('操作提示');
+toast.info('正在处理中,请稍候...');
+```
+
+#### 4.4.3 与API响应集成
+```typescript
+try {
+  const res = await entityClient.$post({ json: data });
+  if (res.status === 201) {
+    toast.success('创建成功');
+    setIsModalOpen(false);
+    refetch();
+  } else {
+    const error = await res.json();
+    toast.error(error.message || '操作失败');
+  }
+} catch (error) {
+  console.error('操作失败:', error);
+  toast.error('网络错误,请重试');
+}
 ```