@openconsole/shadcn 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/accordion.tsx +66 -66
  2. package/alert-dialog.tsx +196 -196
  3. package/alert.tsx +66 -66
  4. package/aspect-ratio.tsx +11 -11
  5. package/avatar.tsx +53 -53
  6. package/badge.tsx +46 -46
  7. package/breadcrumb.tsx +109 -109
  8. package/button-group.tsx +83 -83
  9. package/button.tsx +60 -60
  10. package/calendar.tsx +219 -219
  11. package/card.tsx +92 -92
  12. package/carousel.tsx +241 -241
  13. package/chart.tsx +374 -374
  14. package/checkbox.tsx +32 -32
  15. package/collapsible.tsx +33 -33
  16. package/command.tsx +184 -184
  17. package/context-menu.tsx +252 -252
  18. package/dialog.tsx +143 -143
  19. package/direction.tsx +22 -22
  20. package/drawer.tsx +135 -135
  21. package/dropdown-menu.tsx +257 -257
  22. package/empty.tsx +104 -104
  23. package/field.tsx +248 -248
  24. package/form.tsx +167 -167
  25. package/hooks/index.ts +1 -1
  26. package/hooks/use-mobile.ts +19 -19
  27. package/hover-card.tsx +44 -44
  28. package/icon.tsx +21 -21
  29. package/index.ts +59 -59
  30. package/input-group.tsx +170 -170
  31. package/input-otp.tsx +77 -77
  32. package/input.tsx +21 -21
  33. package/item.tsx +193 -193
  34. package/kbd.tsx +28 -28
  35. package/label.tsx +24 -24
  36. package/lib/index.ts +1 -1
  37. package/lib/utils.ts +6 -6
  38. package/menubar.tsx +276 -276
  39. package/native-select.tsx +62 -62
  40. package/navigation-menu.tsx +168 -168
  41. package/package.json +10 -2
  42. package/pagination.tsx +127 -127
  43. package/popover.tsx +89 -89
  44. package/progress.tsx +31 -31
  45. package/radio-group.tsx +45 -45
  46. package/resizable.tsx +53 -53
  47. package/scroll-area.tsx +58 -58
  48. package/select.tsx +187 -187
  49. package/separator.tsx +28 -28
  50. package/sheet.tsx +139 -139
  51. package/sidebar.tsx +724 -724
  52. package/skeleton.tsx +13 -13
  53. package/skill/SKILL.md +620 -599
  54. package/skill/customization.md +301 -263
  55. package/skill/rules/base-vs-radix.md +167 -167
  56. package/skill/rules/composition.md +240 -240
  57. package/skill/rules/forms.md +271 -271
  58. package/skill/rules/icons.md +136 -136
  59. package/skill/rules/styling.md +180 -180
  60. package/slider.tsx +63 -63
  61. package/sonner.tsx +40 -40
  62. package/spinner.tsx +16 -16
  63. package/styles.css +122 -0
  64. package/switch.tsx +35 -35
  65. package/table.tsx +116 -116
  66. package/tabs.tsx +66 -66
  67. package/textarea.tsx +18 -18
  68. package/toggle-group.tsx +83 -83
  69. package/toggle.tsx +47 -47
  70. package/tooltip.tsx +61 -61
  71. package/tsconfig.json +12 -12
@@ -1,240 +1,240 @@
1
- # 组件组合
2
-
3
- ## 目录
4
-
5
- - Item 一定在自己的 Group 里
6
- - 提示框用 `Alert`
7
- - 空状态用 `Empty`
8
- - Toast 用 sonner
9
- - 在不同 overlay 之间选
10
- - `Dialog` / `Sheet` / `Drawer` 一定要有 Title
11
- - `Card` 用完整组合
12
- - `Button` 没有 `isPending` / `isLoading` prop
13
- - `TabsTrigger` 必须在 `TabsList` 里
14
- - `Avatar` 必须带 `AvatarFallback`
15
- - 用组件,别堆裸标签
16
-
17
- ---
18
-
19
- ## Item 一定在自己的 Group 里
20
-
21
- **永远不要**把 Item 直接渲染在 content 容器里。
22
-
23
- **Incorrect:**
24
-
25
- ```tsx
26
- <SelectContent>
27
- <SelectItem value="apple">Apple</SelectItem>
28
- <SelectItem value="banana">Banana</SelectItem>
29
- </SelectContent>
30
- ```
31
-
32
- **Correct:**
33
-
34
- ```tsx
35
- <SelectContent>
36
- <SelectGroup>
37
- <SelectItem value="apple">Apple</SelectItem>
38
- <SelectItem value="banana">Banana</SelectItem>
39
- </SelectGroup>
40
- </SelectContent>
41
- ```
42
-
43
- 适用于所有基于 group 的组件:
44
-
45
- | Item | Group |
46
- |---|---|
47
- | `SelectItem`、`SelectLabel` | `SelectGroup` |
48
- | `DropdownMenuItem`、`DropdownMenuLabel`、`DropdownMenuSub` | `DropdownMenuGroup` |
49
- | `MenubarItem` | `MenubarGroup` |
50
- | `ContextMenuItem` | `ContextMenuGroup` |
51
- | `CommandItem` | `CommandGroup` |
52
-
53
- ---
54
-
55
- ## 提示框用 `Alert`
56
-
57
- ```tsx
58
- import { Alert, AlertTitle, AlertDescription } from "@openconsole/shadcn";
59
-
60
- <Alert>
61
- <AlertTitle>Warning</AlertTitle>
62
- <AlertDescription>Something needs attention.</AlertDescription>
63
- </Alert>
64
- ```
65
-
66
- ---
67
-
68
- ## 空状态用 `Empty`
69
-
70
- ```tsx
71
- import {
72
- Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
73
- Button,
74
- } from "@openconsole/shadcn";
75
-
76
- <Empty>
77
- <EmptyHeader>
78
- <EmptyMedia variant="icon"><FolderIcon /></EmptyMedia>
79
- <EmptyTitle>No projects yet</EmptyTitle>
80
- <EmptyDescription>Get started by creating a new project.</EmptyDescription>
81
- </EmptyHeader>
82
- <EmptyContent>
83
- <Button>Create Project</Button>
84
- </EmptyContent>
85
- </Empty>
86
- ```
87
-
88
- ---
89
-
90
- ## Toast 用 sonner
91
-
92
- `toast()` 从 sonner 直接导入,不在本包里:
93
-
94
- ```tsx
95
- import { toast } from "sonner";
96
-
97
- toast.success("Changes saved.");
98
- toast.error("Something went wrong.");
99
- toast("File deleted.", {
100
- action: { label: "Undo", onClick: () => undoDelete() },
101
- });
102
- ```
103
-
104
- 在 app 根上挂一次本包的 `<Toaster />`:
105
-
106
- ```tsx
107
- import { Toaster } from "@openconsole/shadcn";
108
-
109
- // app/layout.tsx
110
- <body>
111
- {children}
112
- <Toaster />
113
- </body>
114
- ```
115
-
116
- `Toaster` 默认带 success / info / warning / error / loading 五种状态图标
117
- 和适配主题的颜色 —— 不用再传 `theme` 或 `icons`。
118
-
119
- ---
120
-
121
- ## 在不同 overlay 之间选
122
-
123
- | 场景 | 用什么 |
124
- |---|---|
125
- | 需要输入的聚焦任务 | `Dialog` |
126
- | 破坏性操作的二次确认 | `AlertDialog` |
127
- | 带详情或筛选的侧拉面板 | `Sheet` |
128
- | 移动端优先的底部面板 | `Drawer` |
129
- | 悬浮时的快速信息 | `HoverCard` |
130
- | 点击触发的小块上下文内容 | `Popover` |
131
-
132
- ---
133
-
134
- ## `Dialog` / `Sheet` / `Drawer` 一定要有 Title
135
-
136
- `DialogTitle`、`SheetTitle`、`DrawerTitle` 对屏幕阅读器是必需的。
137
- 视觉上不想显示就 `className="sr-only"`。
138
-
139
- ```tsx
140
- <DialogContent>
141
- <DialogHeader>
142
- <DialogTitle>Edit Profile</DialogTitle>
143
- <DialogDescription>Update your profile.</DialogDescription>
144
- </DialogHeader>
145
- ...
146
- </DialogContent>
147
- ```
148
-
149
- 不需要可见 header 的也要带:
150
-
151
- ```tsx
152
- <DialogContent>
153
- <DialogTitle className="sr-only">Settings</DialogTitle>
154
- {/* … */}
155
- </DialogContent>
156
- ```
157
-
158
- ---
159
-
160
- ## `Card` 用完整组合
161
-
162
- **永远不要**把所有东西塞到 `CardContent` 里:
163
-
164
- ```tsx
165
- <Card>
166
- <CardHeader>
167
- <CardTitle>Team Members</CardTitle>
168
- <CardDescription>Manage your team.</CardDescription>
169
- </CardHeader>
170
- <CardContent>...</CardContent>
171
- <CardFooter>
172
- <Button>Invite</Button>
173
- </CardFooter>
174
- </Card>
175
- ```
176
-
177
- ---
178
-
179
- ## `Button` 没有 `isPending` / `isLoading` prop
180
-
181
- 用 `Spinner` + `data-icon` + `disabled` 拼:
182
-
183
- ```tsx
184
- import { Button, Spinner } from "@openconsole/shadcn";
185
-
186
- <Button disabled>
187
- <Spinner data-icon="inline-start" />
188
- Saving...
189
- </Button>
190
- ```
191
-
192
- 带 mutation hook 时:
193
-
194
- ```tsx
195
- <Button disabled={mutation.isPending}>
196
- {mutation.isPending && <Spinner data-icon="inline-start" />}
197
- Save
198
- </Button>
199
- ```
200
-
201
- ---
202
-
203
- ## `TabsTrigger` 必须在 `TabsList` 里
204
-
205
- **永远不要**把 `TabsTrigger` 直接渲染在 `Tabs` 里 —— 一定包在 `TabsList`:
206
-
207
- ```tsx
208
- <Tabs defaultValue="account">
209
- <TabsList>
210
- <TabsTrigger value="account">Account</TabsTrigger>
211
- <TabsTrigger value="password">Password</TabsTrigger>
212
- </TabsList>
213
- <TabsContent value="account">...</TabsContent>
214
- </Tabs>
215
- ```
216
-
217
- ---
218
-
219
- ## `Avatar` 必须带 `AvatarFallback`
220
-
221
- 图片加载失败的兜底,必须有:
222
-
223
- ```tsx
224
- <Avatar>
225
- <AvatarImage src="/avatar.png" alt="User" />
226
- <AvatarFallback>JD</AvatarFallback>
227
- </Avatar>
228
- ```
229
-
230
- ---
231
-
232
- ## 用组件,别堆裸标签
233
-
234
- | 不要 | 改用 |
235
- |---|---|
236
- | `<hr>` 或 `<div className="border-t">` | `<Separator />` |
237
- | `<div className="animate-pulse">` 加样式 | `<Skeleton className="h-4 w-3/4" />` |
238
- | `<span className="rounded-full bg-green-100 …">` | `<Badge variant="secondary">` |
239
- | 自己写 CSS 转圈 | `<Spinner />` |
240
- | 自己加 `<kbd>` 样式 | `<Kbd>` |
1
+ # 组件组合
2
+
3
+ ## 目录
4
+
5
+ - Item 一定在自己的 Group 里
6
+ - 提示框用 `Alert`
7
+ - 空状态用 `Empty`
8
+ - Toast 用 sonner
9
+ - 在不同 overlay 之间选
10
+ - `Dialog` / `Sheet` / `Drawer` 一定要有 Title
11
+ - `Card` 用完整组合
12
+ - `Button` 没有 `isPending` / `isLoading` prop
13
+ - `TabsTrigger` 必须在 `TabsList` 里
14
+ - `Avatar` 必须带 `AvatarFallback`
15
+ - 用组件,别堆裸标签
16
+
17
+ ---
18
+
19
+ ## Item 一定在自己的 Group 里
20
+
21
+ **永远不要**把 Item 直接渲染在 content 容器里。
22
+
23
+ **Incorrect:**
24
+
25
+ ```tsx
26
+ <SelectContent>
27
+ <SelectItem value="apple">Apple</SelectItem>
28
+ <SelectItem value="banana">Banana</SelectItem>
29
+ </SelectContent>
30
+ ```
31
+
32
+ **Correct:**
33
+
34
+ ```tsx
35
+ <SelectContent>
36
+ <SelectGroup>
37
+ <SelectItem value="apple">Apple</SelectItem>
38
+ <SelectItem value="banana">Banana</SelectItem>
39
+ </SelectGroup>
40
+ </SelectContent>
41
+ ```
42
+
43
+ 适用于所有基于 group 的组件:
44
+
45
+ | Item | Group |
46
+ |---|---|
47
+ | `SelectItem`、`SelectLabel` | `SelectGroup` |
48
+ | `DropdownMenuItem`、`DropdownMenuLabel`、`DropdownMenuSub` | `DropdownMenuGroup` |
49
+ | `MenubarItem` | `MenubarGroup` |
50
+ | `ContextMenuItem` | `ContextMenuGroup` |
51
+ | `CommandItem` | `CommandGroup` |
52
+
53
+ ---
54
+
55
+ ## 提示框用 `Alert`
56
+
57
+ ```tsx
58
+ import { Alert, AlertTitle, AlertDescription } from "@openconsole/shadcn";
59
+
60
+ <Alert>
61
+ <AlertTitle>Warning</AlertTitle>
62
+ <AlertDescription>Something needs attention.</AlertDescription>
63
+ </Alert>
64
+ ```
65
+
66
+ ---
67
+
68
+ ## 空状态用 `Empty`
69
+
70
+ ```tsx
71
+ import {
72
+ Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent,
73
+ Button,
74
+ } from "@openconsole/shadcn";
75
+
76
+ <Empty>
77
+ <EmptyHeader>
78
+ <EmptyMedia variant="icon"><FolderIcon /></EmptyMedia>
79
+ <EmptyTitle>No projects yet</EmptyTitle>
80
+ <EmptyDescription>Get started by creating a new project.</EmptyDescription>
81
+ </EmptyHeader>
82
+ <EmptyContent>
83
+ <Button>Create Project</Button>
84
+ </EmptyContent>
85
+ </Empty>
86
+ ```
87
+
88
+ ---
89
+
90
+ ## Toast 用 sonner
91
+
92
+ `toast()` 从 sonner 直接导入,不在本包里:
93
+
94
+ ```tsx
95
+ import { toast } from "sonner";
96
+
97
+ toast.success("Changes saved.");
98
+ toast.error("Something went wrong.");
99
+ toast("File deleted.", {
100
+ action: { label: "Undo", onClick: () => undoDelete() },
101
+ });
102
+ ```
103
+
104
+ 在 app 根上挂一次本包的 `<Toaster />`:
105
+
106
+ ```tsx
107
+ import { Toaster } from "@openconsole/shadcn";
108
+
109
+ // app/layout.tsx
110
+ <body>
111
+ {children}
112
+ <Toaster />
113
+ </body>
114
+ ```
115
+
116
+ `Toaster` 默认带 success / info / warning / error / loading 五种状态图标
117
+ 和适配主题的颜色 —— 不用再传 `theme` 或 `icons`。
118
+
119
+ ---
120
+
121
+ ## 在不同 overlay 之间选
122
+
123
+ | 场景 | 用什么 |
124
+ |---|---|
125
+ | 需要输入的聚焦任务 | `Dialog` |
126
+ | 破坏性操作的二次确认 | `AlertDialog` |
127
+ | 带详情或筛选的侧拉面板 | `Sheet` |
128
+ | 移动端优先的底部面板 | `Drawer` |
129
+ | 悬浮时的快速信息 | `HoverCard` |
130
+ | 点击触发的小块上下文内容 | `Popover` |
131
+
132
+ ---
133
+
134
+ ## `Dialog` / `Sheet` / `Drawer` 一定要有 Title
135
+
136
+ `DialogTitle`、`SheetTitle`、`DrawerTitle` 对屏幕阅读器是必需的。
137
+ 视觉上不想显示就 `className="sr-only"`。
138
+
139
+ ```tsx
140
+ <DialogContent>
141
+ <DialogHeader>
142
+ <DialogTitle>Edit Profile</DialogTitle>
143
+ <DialogDescription>Update your profile.</DialogDescription>
144
+ </DialogHeader>
145
+ ...
146
+ </DialogContent>
147
+ ```
148
+
149
+ 不需要可见 header 的也要带:
150
+
151
+ ```tsx
152
+ <DialogContent>
153
+ <DialogTitle className="sr-only">Settings</DialogTitle>
154
+ {/* … */}
155
+ </DialogContent>
156
+ ```
157
+
158
+ ---
159
+
160
+ ## `Card` 用完整组合
161
+
162
+ **永远不要**把所有东西塞到 `CardContent` 里:
163
+
164
+ ```tsx
165
+ <Card>
166
+ <CardHeader>
167
+ <CardTitle>Team Members</CardTitle>
168
+ <CardDescription>Manage your team.</CardDescription>
169
+ </CardHeader>
170
+ <CardContent>...</CardContent>
171
+ <CardFooter>
172
+ <Button>Invite</Button>
173
+ </CardFooter>
174
+ </Card>
175
+ ```
176
+
177
+ ---
178
+
179
+ ## `Button` 没有 `isPending` / `isLoading` prop
180
+
181
+ 用 `Spinner` + `data-icon` + `disabled` 拼:
182
+
183
+ ```tsx
184
+ import { Button, Spinner } from "@openconsole/shadcn";
185
+
186
+ <Button disabled>
187
+ <Spinner data-icon="inline-start" />
188
+ Saving...
189
+ </Button>
190
+ ```
191
+
192
+ 带 mutation hook 时:
193
+
194
+ ```tsx
195
+ <Button disabled={mutation.isPending}>
196
+ {mutation.isPending && <Spinner data-icon="inline-start" />}
197
+ Save
198
+ </Button>
199
+ ```
200
+
201
+ ---
202
+
203
+ ## `TabsTrigger` 必须在 `TabsList` 里
204
+
205
+ **永远不要**把 `TabsTrigger` 直接渲染在 `Tabs` 里 —— 一定包在 `TabsList`:
206
+
207
+ ```tsx
208
+ <Tabs defaultValue="account">
209
+ <TabsList>
210
+ <TabsTrigger value="account">Account</TabsTrigger>
211
+ <TabsTrigger value="password">Password</TabsTrigger>
212
+ </TabsList>
213
+ <TabsContent value="account">...</TabsContent>
214
+ </Tabs>
215
+ ```
216
+
217
+ ---
218
+
219
+ ## `Avatar` 必须带 `AvatarFallback`
220
+
221
+ 图片加载失败的兜底,必须有:
222
+
223
+ ```tsx
224
+ <Avatar>
225
+ <AvatarImage src="/avatar.png" alt="User" />
226
+ <AvatarFallback>JD</AvatarFallback>
227
+ </Avatar>
228
+ ```
229
+
230
+ ---
231
+
232
+ ## 用组件,别堆裸标签
233
+
234
+ | 不要 | 改用 |
235
+ |---|---|
236
+ | `<hr>` 或 `<div className="border-t">` | `<Separator />` |
237
+ | `<div className="animate-pulse">` 加样式 | `<Skeleton className="h-4 w-3/4" />` |
238
+ | `<span className="rounded-full bg-green-100 …">` | `<Badge variant="secondary">` |
239
+ | 自己写 CSS 转圈 | `<Spinner />` |
240
+ | 自己加 `<kbd>` 样式 | `<Kbd>` |