@teamix-evo/ui 0.2.0 → 0.3.0

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 (282) hide show
  1. package/README.md +184 -184
  2. package/manifest.json +680 -492
  3. package/package.json +15 -9
  4. package/src/components/accordion/accordion.meta.md +5 -9
  5. package/src/components/accordion/accordion.stories.tsx +3 -3
  6. package/src/components/accordion/accordion.tsx +104 -8
  7. package/src/components/affix/affix.meta.md +21 -12
  8. package/src/components/affix/affix.stories.tsx +101 -26
  9. package/src/components/affix/affix.tsx +79 -9
  10. package/src/components/alert/alert.meta.md +52 -26
  11. package/src/components/alert/alert.stories.tsx +66 -21
  12. package/src/components/alert/alert.tsx +81 -34
  13. package/src/components/alert-dialog/alert-dialog.meta.md +48 -16
  14. package/src/components/alert-dialog/alert-dialog.stories.tsx +145 -3
  15. package/src/components/alert-dialog/alert-dialog.tsx +60 -13
  16. package/src/components/anchor/anchor.meta.md +10 -14
  17. package/src/components/anchor/anchor.stories.tsx +3 -3
  18. package/src/components/anchor/anchor.tsx +2 -2
  19. package/src/components/app/app.meta.md +10 -14
  20. package/src/components/app/app.stories.tsx +6 -6
  21. package/src/components/aspect-ratio/aspect-ratio.meta.md +4 -8
  22. package/src/components/aspect-ratio/aspect-ratio.stories.tsx +3 -3
  23. package/src/components/auto-complete/auto-complete.meta.md +19 -20
  24. package/src/components/auto-complete/auto-complete.stories.tsx +44 -3
  25. package/src/components/auto-complete/auto-complete.tsx +119 -71
  26. package/src/components/avatar/avatar.meta.md +9 -22
  27. package/src/components/avatar/avatar.stories.tsx +21 -3
  28. package/src/components/avatar/avatar.tsx +24 -23
  29. package/src/components/badge/badge.meta.md +14 -18
  30. package/src/components/badge/badge.stories.tsx +2 -2
  31. package/src/components/badge/badge.tsx +2 -2
  32. package/src/components/breadcrumb/breadcrumb.meta.md +29 -20
  33. package/src/components/breadcrumb/breadcrumb.stories.tsx +120 -5
  34. package/src/components/breadcrumb/breadcrumb.tsx +22 -8
  35. package/src/components/button/button.meta.md +261 -29
  36. package/src/components/button/button.stories.tsx +549 -41
  37. package/src/components/button/button.tsx +335 -33
  38. package/src/components/calendar/calendar.meta.md +19 -14
  39. package/src/components/calendar/calendar.stories.tsx +5 -5
  40. package/src/components/calendar/calendar.tsx +73 -8
  41. package/src/components/card/card.meta.md +31 -34
  42. package/src/components/card/card.stories.tsx +34 -3
  43. package/src/components/card/card.tsx +146 -63
  44. package/src/components/carousel/carousel.meta.md +10 -14
  45. package/src/components/carousel/carousel.stories.tsx +1 -1
  46. package/src/components/cascader/cascader.meta.md +43 -22
  47. package/src/components/cascader/cascader.stories.tsx +13 -2
  48. package/src/components/cascader/cascader.tsx +427 -84
  49. package/src/components/checkbox/checkbox.meta.md +74 -24
  50. package/src/components/checkbox/checkbox.stories.tsx +160 -2
  51. package/src/components/checkbox/checkbox.tsx +77 -9
  52. package/src/components/collapsible/collapsible.meta.md +7 -6
  53. package/src/components/collapsible/collapsible.stories.tsx +2 -2
  54. package/src/components/collapsible/collapsible.tsx +93 -6
  55. package/src/components/color-picker/color-picker.meta.md +16 -20
  56. package/src/components/color-picker/color-picker.stories.tsx +86 -7
  57. package/src/components/color-picker/color-picker.tsx +19 -9
  58. package/src/components/command/command.meta.md +7 -11
  59. package/src/components/command/command.stories.tsx +4 -4
  60. package/src/components/command/command.tsx +18 -7
  61. package/src/components/context-menu/context-menu.meta.md +5 -25
  62. package/src/components/context-menu/context-menu.stories.tsx +4 -4
  63. package/src/components/context-menu/context-menu.tsx +21 -8
  64. package/src/components/data-table/data-table.meta.md +14 -18
  65. package/src/components/data-table/data-table.stories.tsx +1 -1
  66. package/src/components/data-table/data-table.tsx +2 -2
  67. package/src/components/date-picker/date-picker.meta.md +90 -41
  68. package/src/components/date-picker/date-picker.stories.tsx +55 -5
  69. package/src/components/date-picker/date-picker.tsx +1489 -91
  70. package/src/components/descriptions/descriptions.meta.md +12 -16
  71. package/src/components/descriptions/descriptions.stories.tsx +2 -2
  72. package/src/components/descriptions/descriptions.tsx +22 -14
  73. package/src/components/dialog/dialog.meta.md +67 -17
  74. package/src/components/dialog/dialog.stories.tsx +182 -20
  75. package/src/components/dialog/dialog.tsx +67 -15
  76. package/src/components/dialog/imperative.tsx +252 -0
  77. package/src/components/drawer/drawer.meta.md +27 -39
  78. package/src/components/drawer/drawer.stories.tsx +29 -12
  79. package/src/components/drawer/drawer.tsx +22 -114
  80. package/src/components/dropdown-menu/dropdown-menu.meta.md +64 -24
  81. package/src/components/dropdown-menu/dropdown-menu.stories.tsx +81 -3
  82. package/src/components/dropdown-menu/dropdown-menu.tsx +24 -10
  83. package/src/components/ellipsis/ellipsis.meta.md +87 -0
  84. package/src/components/ellipsis/ellipsis.stories.tsx +72 -0
  85. package/src/components/ellipsis/ellipsis.tsx +153 -0
  86. package/src/components/empty/empty.meta.md +10 -14
  87. package/src/components/empty/empty.stories.tsx +3 -3
  88. package/src/components/empty/empty.tsx +10 -3
  89. package/src/components/field/field.meta.md +46 -25
  90. package/src/components/field/field.stories.tsx +380 -3
  91. package/src/components/field/field.tsx +263 -35
  92. package/src/components/filter-bar/filter-bar.meta.md +92 -0
  93. package/src/components/filter-bar/filter-bar.stories.tsx +1083 -0
  94. package/src/components/filter-bar/filter-bar.tsx +568 -0
  95. package/src/components/flex/flex.meta.md +59 -20
  96. package/src/components/flex/flex.stories.tsx +65 -10
  97. package/src/components/flex/flex.tsx +27 -4
  98. package/src/components/float-button/float-button.meta.md +10 -29
  99. package/src/components/float-button/float-button.stories.tsx +6 -6
  100. package/src/components/form/form.meta.md +31 -52
  101. package/src/components/form/form.stories.tsx +350 -3
  102. package/src/components/form/form.tsx +101 -35
  103. package/src/components/grid/grid.meta.md +4 -24
  104. package/src/components/grid/grid.stories.tsx +2 -2
  105. package/src/components/hover-card/hover-card.meta.md +9 -10
  106. package/src/components/hover-card/hover-card.stories.tsx +29 -4
  107. package/src/components/hover-card/hover-card.tsx +51 -13
  108. package/src/components/icon/DEVELOPMENT.md +809 -0
  109. package/src/components/icon/icon.meta.md +170 -0
  110. package/src/components/icon/icon.stories.tsx +344 -0
  111. package/src/components/icon/icon.tsx +248 -0
  112. package/src/components/image/image.meta.md +14 -18
  113. package/src/components/image/image.stories.tsx +3 -3
  114. package/src/components/image/image.tsx +2 -0
  115. package/src/components/input/demo/sizes.tsx +2 -2
  116. package/src/components/input/input.meta.md +44 -43
  117. package/src/components/input/input.stories.tsx +62 -35
  118. package/src/components/input/input.tsx +96 -101
  119. package/src/components/input-group/input-group.meta.md +53 -39
  120. package/src/components/input-group/input-group.stories.tsx +49 -16
  121. package/src/components/input-group/input-group.tsx +43 -8
  122. package/src/components/input-number/input-number.meta.md +68 -20
  123. package/src/components/input-number/input-number.stories.tsx +33 -6
  124. package/src/components/input-number/input-number.tsx +79 -20
  125. package/src/components/input-otp/input-otp.meta.md +8 -20
  126. package/src/components/input-otp/input-otp.stories.tsx +3 -3
  127. package/src/components/input-otp/input-otp.tsx +1 -1
  128. package/src/components/item/item.meta.md +8 -26
  129. package/src/components/item/item.stories.tsx +3 -3
  130. package/src/components/item/item.tsx +7 -6
  131. package/src/components/kbd/kbd.meta.md +7 -19
  132. package/src/components/kbd/kbd.stories.tsx +4 -4
  133. package/src/components/kbd/kbd.tsx +8 -4
  134. package/src/components/label/label.meta.md +21 -18
  135. package/src/components/label/label.stories.tsx +64 -6
  136. package/src/components/label/label.tsx +91 -19
  137. package/src/components/masonry/masonry.meta.md +8 -12
  138. package/src/components/masonry/masonry.stories.tsx +4 -4
  139. package/src/components/mentions/mentions.meta.md +42 -21
  140. package/src/components/mentions/mentions.stories.tsx +120 -6
  141. package/src/components/mentions/mentions.tsx +10 -5
  142. package/src/components/menubar/menubar.meta.md +4 -8
  143. package/src/components/menubar/menubar.stories.tsx +55 -3
  144. package/src/components/menubar/menubar.tsx +9 -9
  145. package/src/components/native-select/native-select.meta.md +7 -11
  146. package/src/components/native-select/native-select.stories.tsx +4 -4
  147. package/src/components/native-select/native-select.tsx +1 -1
  148. package/src/components/navigation-menu/navigation-menu.meta.md +4 -8
  149. package/src/components/navigation-menu/navigation-menu.stories.tsx +106 -3
  150. package/src/components/navigation-menu/navigation-menu.tsx +6 -3
  151. package/src/components/notification/notification.meta.md +41 -8
  152. package/src/components/notification/notification.stories.tsx +9 -9
  153. package/src/components/notification/notification.tsx +34 -19
  154. package/src/components/page-header/DEVELOPMENT.md +842 -0
  155. package/src/components/page-header/page-header.meta.md +208 -0
  156. package/src/components/page-header/page-header.stories.tsx +421 -0
  157. package/src/components/page-header/page-header.tsx +281 -0
  158. package/src/components/pagination/pagination.meta.md +122 -50
  159. package/src/components/pagination/pagination.stories.tsx +227 -11
  160. package/src/components/pagination/pagination.tsx +355 -63
  161. package/src/components/popconfirm/popconfirm.meta.md +19 -23
  162. package/src/components/popconfirm/popconfirm.stories.tsx +2 -2
  163. package/src/components/popconfirm/popconfirm.tsx +1 -1
  164. package/src/components/popover/popover.meta.md +64 -12
  165. package/src/components/popover/popover.stories.tsx +83 -7
  166. package/src/components/popover/popover.tsx +77 -28
  167. package/src/components/progress/progress.meta.md +43 -26
  168. package/src/components/progress/progress.stories.tsx +2 -2
  169. package/src/components/progress/progress.tsx +19 -11
  170. package/src/components/radio-group/radio-group.meta.md +78 -11
  171. package/src/components/radio-group/radio-group.stories.tsx +38 -2
  172. package/src/components/radio-group/radio-group.tsx +149 -18
  173. package/src/components/rate/rate.meta.md +41 -19
  174. package/src/components/rate/rate.stories.tsx +2 -2
  175. package/src/components/rate/rate.tsx +37 -10
  176. package/src/components/resizable/resizable.meta.md +4 -12
  177. package/src/components/resizable/resizable.stories.tsx +5 -5
  178. package/src/components/resizable/resizable.tsx +1 -1
  179. package/src/components/result/result.meta.md +10 -14
  180. package/src/components/result/result.stories.tsx +2 -2
  181. package/src/components/result/result.tsx +21 -12
  182. package/src/components/scroll-area/scroll-area.meta.md +4 -8
  183. package/src/components/scroll-area/scroll-area.stories.tsx +5 -5
  184. package/src/components/segmented/segmented.meta.md +15 -17
  185. package/src/components/segmented/segmented.stories.tsx +3 -3
  186. package/src/components/segmented/segmented.tsx +15 -7
  187. package/src/components/select/select.meta.md +199 -67
  188. package/src/components/select/select.stories.tsx +238 -63
  189. package/src/components/select/select.tsx +718 -171
  190. package/src/components/separator/separator.meta.md +10 -14
  191. package/src/components/separator/separator.stories.tsx +2 -2
  192. package/src/components/separator/separator.tsx +3 -7
  193. package/src/components/sheet/sheet.meta.md +26 -21
  194. package/src/components/sheet/sheet.stories.tsx +116 -10
  195. package/src/components/sheet/sheet.tsx +116 -29
  196. package/src/components/sidebar/sidebar.meta.md +28 -38
  197. package/src/components/sidebar/sidebar.stories.tsx +696 -29
  198. package/src/components/sidebar/sidebar.tsx +615 -142
  199. package/src/components/skeleton/skeleton.meta.md +7 -31
  200. package/src/components/skeleton/skeleton.stories.tsx +3 -3
  201. package/src/components/skeleton/skeleton.tsx +7 -7
  202. package/src/components/slider/slider.meta.md +60 -13
  203. package/src/components/slider/slider.stories.tsx +58 -6
  204. package/src/components/slider/slider.tsx +154 -13
  205. package/src/components/sonner/sonner.meta.md +54 -8
  206. package/src/components/sonner/sonner.stories.tsx +79 -11
  207. package/src/components/sonner/sonner.tsx +137 -8
  208. package/src/components/spinner/spinner.meta.md +57 -21
  209. package/src/components/spinner/spinner.stories.tsx +66 -14
  210. package/src/components/spinner/spinner.tsx +111 -9
  211. package/src/components/statistic/statistic.meta.md +14 -30
  212. package/src/components/statistic/statistic.stories.tsx +1 -1
  213. package/src/components/statistic/statistic.tsx +4 -5
  214. package/src/components/steps/steps.meta.md +20 -15
  215. package/src/components/steps/steps.stories.tsx +37 -2
  216. package/src/components/steps/steps.tsx +15 -12
  217. package/src/components/switch/switch.meta.md +56 -15
  218. package/src/components/switch/switch.stories.tsx +5 -5
  219. package/src/components/switch/switch.tsx +59 -13
  220. package/src/components/table/table.meta.md +3 -7
  221. package/src/components/table/table.stories.tsx +1 -1
  222. package/src/components/table/table.tsx +4 -4
  223. package/src/components/tabs/tabs.meta.md +40 -32
  224. package/src/components/tabs/tabs.stories.tsx +104 -26
  225. package/src/components/tabs/tabs.tsx +125 -54
  226. package/src/components/tag/tag.meta.md +104 -68
  227. package/src/components/tag/tag.stories.tsx +183 -15
  228. package/src/components/tag/tag.tsx +222 -21
  229. package/src/components/textarea/textarea.meta.md +42 -31
  230. package/src/components/textarea/textarea.stories.tsx +32 -6
  231. package/src/components/textarea/textarea.tsx +32 -8
  232. package/src/components/time-picker/time-picker.meta.md +119 -50
  233. package/src/components/time-picker/time-picker.stories.tsx +65 -33
  234. package/src/components/time-picker/time-picker.tsx +889 -101
  235. package/src/components/timeline/timeline.meta.md +16 -17
  236. package/src/components/timeline/timeline.stories.tsx +24 -4
  237. package/src/components/timeline/timeline.tsx +32 -12
  238. package/src/components/toggle/toggle.meta.md +8 -12
  239. package/src/components/toggle/toggle.stories.tsx +4 -4
  240. package/src/components/toggle/toggle.tsx +4 -3
  241. package/src/components/toggle-group/toggle-group.meta.md +10 -14
  242. package/src/components/toggle-group/toggle-group.stories.tsx +3 -3
  243. package/src/components/toggle-group/toggle-group.tsx +2 -2
  244. package/src/components/tooltip/tooltip.meta.md +63 -18
  245. package/src/components/tooltip/tooltip.stories.tsx +42 -5
  246. package/src/components/tooltip/tooltip.tsx +81 -21
  247. package/src/components/tour/tour.meta.md +16 -20
  248. package/src/components/tour/tour.stories.tsx +3 -3
  249. package/src/components/tour/tour.tsx +3 -3
  250. package/src/components/transfer/transfer.meta.md +18 -22
  251. package/src/components/transfer/transfer.stories.tsx +2 -2
  252. package/src/components/transfer/transfer.tsx +28 -21
  253. package/src/components/tree/tree.meta.md +67 -22
  254. package/src/components/tree/tree.stories.tsx +1 -1
  255. package/src/components/tree/tree.tsx +9 -8
  256. package/src/components/tree-select/tree-select.meta.md +59 -23
  257. package/src/components/tree-select/tree-select.stories.tsx +2 -2
  258. package/src/components/tree-select/tree-select.tsx +42 -7
  259. package/src/components/typography/typography.meta.md +61 -39
  260. package/src/components/typography/typography.stories.tsx +14 -9
  261. package/src/components/typography/typography.tsx +38 -25
  262. package/src/components/upload/upload.meta.md +61 -25
  263. package/src/components/upload/upload.stories.tsx +69 -3
  264. package/src/components/upload/upload.tsx +170 -37
  265. package/src/components/watermark/watermark.meta.md +15 -19
  266. package/src/components/watermark/watermark.stories.tsx +98 -8
  267. package/src/hooks/use-breakpoint.ts +117 -0
  268. package/src/hooks/use-debounce-callback.ts +52 -0
  269. package/src/hooks/use-mobile.ts +23 -0
  270. package/src/stories/theme-tokens.stories.tsx +747 -0
  271. package/src/utils/trigger-input.ts +53 -0
  272. package/src/components/button-group/button-group.meta.md +0 -101
  273. package/src/components/button-group/button-group.stories.tsx +0 -93
  274. package/src/components/button-group/button-group.tsx +0 -75
  275. package/src/components/combobox/combobox.meta.md +0 -102
  276. package/src/components/combobox/combobox.stories.tsx +0 -55
  277. package/src/components/combobox/combobox.tsx +0 -130
  278. package/src/components/input/demo/addon.tsx +0 -15
  279. package/src/components/input/demo/with-prefix-suffix.tsx +0 -19
  280. package/src/components/space/space.meta.md +0 -103
  281. package/src/components/space/space.stories.tsx +0 -108
  282. package/src/components/space/space.tsx +0 -106
@@ -27,36 +27,33 @@ package: '@teamix-evo/ui'
27
27
  ## Props
28
28
 
29
29
  <!-- auto:props:begin -->
30
-
31
- | 名称 | 类型 | 默认值 | 必填 | 说明 |
32
- | --------------------- | -------------------------- | ------- | ---- | -------------------------------------------------------------------------- |
33
- | `data` | `TreeNode[]` | | | 树数据(antd `treeData` 并集)|
34
- | `checkable` | `boolean` | `false` | – | 是否启用勾选 checkbox(antd `checkable` 并集) — 父子级联,半选状态自动计算。 |
35
- | `selectable` | `boolean` | `true` | – | 是否启用单击高亮选择(antd `selectable` 并集)。 |
36
- | `checkedKeys` | `string[]` | – | – | 受控已勾选 key 集合(checkable 时生效)。 |
37
- | `defaultCheckedKeys` | `string[]` | – | – | uncontrolled 初值。 |
38
- | `onCheck` | `(next: string[]) => void` | – | – | 勾选变化回调。 |
39
- | `selectedKeys` | `string[]` | – | – | 受控已选中 key 集合(selectable 时生效;通常单选,数组形式与 antd 对齐)。 |
40
- | `defaultSelectedKeys` | `string[]` | – | – | uncontrolled 初值。 |
41
- | `onSelect` | `(next: string[]) => void` | – | – | 选中变化回调。 |
42
- | `expandedKeys` | `string[]` | – | – | 受控已展开 key 集合。 |
43
- | `defaultExpandedKeys` | `string[]` | | – | uncontrolled 初值。 |
44
- | `defaultExpandAll` | `boolean` | `false` | – | 默认展开全部(antd `defaultExpandAll` 并集) — 仅 uncontrolled 模式生效。 |
45
- | `onExpand` | `(next: string[]) => void` | – | – | 展开变化回调。 |
46
-
30
+ | 名称 | 类型 | 默认值 | 必填 | 说明 |
31
+ | --- | --- | --- | --- | --- |
32
+ | `data` | `TreeNode[]` | | | 树数据(antd `treeData` 并集)。 |
33
+ | `checkable` | `boolean` | `false` | | 是否启用勾选 checkbox(antd `checkable` 并集) — 父子级联,半选状态自动计算。 |
34
+ | `selectable` | `boolean` | `true` | – | 是否启用单击高亮选择(antd `selectable` 并集) |
35
+ | `checkedKeys` | `string[]` | | – | 受控已勾选 key 集合(checkable 时生效)。 |
36
+ | `defaultCheckedKeys` | `string[]` | – | – | uncontrolled 初值。 |
37
+ | `onCheck` | `(next: string[]) => void` | – | – | 勾选变化回调。 |
38
+ | `selectedKeys` | `string[]` | – | – | 受控已选中 key 集合(selectable 时生效;通常单选,数组形式与 antd 对齐)。 |
39
+ | `defaultSelectedKeys` | `string[]` | – | – | uncontrolled 初值。 |
40
+ | `onSelect` | `(next: string[]) => void` | – | – | 选中变化回调。 |
41
+ | `expandedKeys` | `string[]` | – | – | 受控已展开 key 集合。 |
42
+ | `defaultExpandedKeys` | `string[]` | – | – | uncontrolled 初值。 |
43
+ | `defaultExpandAll` | `boolean` | `false` | – | 默认展开全部(antd `defaultExpandAll` 并集) — 仅 uncontrolled 模式生效。 |
44
+ | `onExpand` | `(next: string[]) => void` | – | | 展开变化回调。 |
47
45
  <!-- auto:props:end -->
48
46
 
49
47
  ## 依赖
50
48
 
51
49
  <!-- auto:deps:begin -->
52
-
53
50
  ### 同库依赖
54
51
 
55
52
  > `teamix-evo ui add tree` 时,以下 entry 会被自动连带安装(无需手动 add)。
56
53
 
57
- | Entry | 类型 | 描述 |
58
- | ---------- | --------- | ---------------------------------------------------------------------------------- |
59
- | `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
54
+ | Entry | 类型 | 描述 |
55
+ | --- | --- | --- |
56
+ | `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
60
57
  | `checkbox` | component | 复选框 — Radix Checkbox(原生 indeterminate)+ antd Checkbox.Group(options 数组驱动) |
61
58
 
62
59
  ### npm 依赖
@@ -66,7 +63,6 @@ package: '@teamix-evo/ui'
66
63
  ```bash
67
64
  pnpm add lucide-react@^0.460.0
68
65
  ```
69
-
70
66
  <!-- auto:deps:end -->
71
67
 
72
68
  ## AI 生成纪律
@@ -75,6 +71,9 @@ pnpm add lucide-react@^0.460.0
75
71
  - **`checkable` 默认级联**:勾选父节点会勾选所有后代,勾选所有后代会自动勾选父节点 — **不要**自己写额外的级联逻辑;`onCheck` 给的是叶子+完全选中的父节点集合(半选不在内)
76
72
  - **半选(indeterminate)**自动计算,不需要消费方维护
77
73
  - **`selectable` + `checkable` 可共存**,但 UI 上选中高亮与勾选是两套独立状态(对齐 antd)
74
+ - **选中 ≠ hover**:hover 是 `accent/50`(半透明),选中是 `accent` 实色 + `font-medium`,视觉上明显区分;**不要**手动改为其他调色板
75
+ - **节点缩进**:每层 20px刷类 shadcn/cloud-design teamix 规范,**不要**手动调 padding
76
+ - **展开图标**:`size-3` 的 `ChevronRight` 旋转 90°,默认为 `text-muted-foreground` hover 变 `text-foreground` — 不要换 chevron 尺寸
78
77
  - **大数据量警告**:节点数 ≥ 500 时建议拆分为"按需加载子节点"(在 `onExpand` 中拉取),否则首次渲染卡顿
79
78
  - **`disabled` 节点**:展开按钮亦禁用,但**仍参与级联计算** — 父被勾选时禁用子也会变为 checked
80
79
 
@@ -122,3 +121,49 @@ const [checked, setChecked] = React.useState<string[]>([]);
122
121
  onCheck={setChecked}
123
122
  />;
124
123
  ```
124
+
125
+ ## Tree 形态 — 旧库 API → 新库映射
126
+
127
+ > 旧库 `Tree / Tree.Node`(hybridcloud,JSX 子组件式) → 新库 `Tree`(纯数据驱动)。
128
+ > 新库放弃 JSX `<Tree.Node>` 子组件嵌套,改用 `data: TreeNode[]` 数组(对齐 antd 5+ 的 `treeData` 风格)— tree-shake 友好 / 序列化方便 / 异步加载更直观。
129
+
130
+ ### 命名映射
131
+
132
+ | 旧库 API | 新库 API | 备注 |
133
+ | --- | --- | --- |
134
+ | `<Tree>` + `<Tree.Node>` 子组件嵌套 | `<Tree data={[{ key, title, children }]} />` | **Breaking** — 改为数据驱动 |
135
+ | `dataSource` | `data` | 字段命名简化 |
136
+ | `Tree.Node` 的 `key/label/children` | `TreeNode.key/title/children` | `label` → `title`(对齐 antd) |
137
+ | `checkedKeys` / `selectedKeys` / `expandedKeys` | 同名保留 | 受控集合 |
138
+ | `defaultCheckedKeys` / `defaultSelectedKeys` / `defaultExpandedKeys` | 同名保留 | uncontrolled 初值 |
139
+ | `defaultExpandAll` | 同名保留 | 仅 uncontrolled 模式 |
140
+ | `onCheck(keys, extra)` | `onCheck(keys)` | 单参数化(extra 信息可在 data 里查) |
141
+ | `onSelect(keys, extra)` | `onSelect(keys)` | 同上 |
142
+ | `isLeaf`(Node prop) | `TreeNode.isLeaf`(data field) | 数据字段化 |
143
+ | `disabled`(Node prop) | `TreeNode.disabled`(data field) | 同上 |
144
+ | `icon`(Node prop) | `TreeNode.icon`(data field) | 同上 |
145
+
146
+ ### Breaking Changes(从旧库迁移时需改写)
147
+
148
+ 1. **JSX `<Tree.Node>` 全部改写为 `data` 数组** — 这是最大改动,业务工程需要重构数据结构
149
+ 2. `dataSource` → `data`
150
+ 3. `label` → `title`(节点字段)
151
+ 4. `onCheck(keys, extra)` → `onCheck(keys)`(extra 信息消失,业务侧自查 data)
152
+
153
+ ### 不修复 / 后续工序清单(报告 §3 P1/P2)
154
+
155
+ > 以下功能在新库未实现,**业务真有需求时**优先做。多数依赖外部库或较复杂的 source 改造。
156
+
157
+ - **`draggable` 拖拽排序**(P1):需集成 `@dnd-kit/core` + `@dnd-kit/sortable`,本组件不内置;业务侧自接 dnd-kit
158
+ - **`loadData` 异步加载子节点**(P1):点击展开时触发 fetch,目前业务侧用受控 `expandedKeys` + `onExpand` 自管异步;后续工序加 prop
159
+ - **`checkStrictly` 父子不关联**(P1):checkable 模式下严格独立勾选,目前固定级联;后续 prop
160
+ - **`useVirtual` 虚拟滚动**(P1):大数据量(> 1000 节点)首次渲染卡顿,后续可集成 `react-window` 或 `@tanstack/react-virtual`
161
+ - **`editable` 节点编辑**(P2):双击节点变 Input;业务侧用 `title: <Input />` 自定义渲染替代
162
+ - **`filterTreeNode` 过滤高亮**(P2):配合 TreeSelect 的 showSearch 使用,需在 Tree 层先支持
163
+
164
+ ### 不修复(报告 §5 已明确)
165
+
166
+ - **JSX `<Tree.Node>`**:数据驱动是显式优势,不回退
167
+ - **`labelRender` vs `label(ReactNode)`**:`title` 直接接 ReactNode,无需另设 render prop
168
+ - **展开动画**:CSS transition 已内置(对齐 antd 默认)
169
+ - **`focusedKey` / `autoFocus`**:Radix-style 内管,不暴露
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
  import { File, Folder } from 'lucide-react';
4
4
  import { Tree, type TreeNode } from './tree';
5
5
 
@@ -177,12 +177,12 @@ const TreeRow: React.FC<NodeProps> = ({
177
177
  <li role="treeitem" aria-expanded={hasChildren ? isOpen : undefined}>
178
178
  <div
179
179
  className={cn(
180
- 'flex items-center gap-2 rounded-md py-1 pr-2 text-sm transition-colors',
181
- selectable && !node.disabled && 'hover:bg-accent',
182
- isSelected && 'bg-accent text-accent-foreground',
180
+ 'group/tree-row flex items-center gap-1.5 rounded-md py-1 pr-2 text-xs transition-colors',
181
+ selectable && !node.disabled && 'hover:bg-accent/50',
182
+ isSelected && 'bg-accent font-medium text-accent-foreground',
183
183
  node.disabled && 'cursor-not-allowed opacity-50',
184
184
  )}
185
- style={{ paddingLeft: `${depth * 16 + 4}px` }}
185
+ style={{ paddingLeft: `${depth * 20 + 4}px` }}
186
186
  >
187
187
  {hasChildren ? (
188
188
  <button
@@ -190,11 +190,11 @@ const TreeRow: React.FC<NodeProps> = ({
190
190
  aria-label={isOpen ? '收起' : '展开'}
191
191
  onClick={() => onToggleExpand(node.key)}
192
192
  disabled={node.disabled}
193
- className="flex size-5 shrink-0 items-center justify-center rounded-sm transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
193
+ className="flex size-5 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
194
194
  >
195
195
  <ChevronRight
196
196
  className={cn(
197
- 'size-3.5 transition-transform',
197
+ 'size-3 transition-transform duration-150',
198
198
  isOpen && 'rotate-90',
199
199
  )}
200
200
  />
@@ -282,7 +282,8 @@ const Tree = React.forwardRef<HTMLDivElement, TreeProps>(
282
282
  return [];
283
283
  }, [defaultExpandAll, defaultExpandedKeys, data]);
284
284
 
285
- const [internalExpanded, setInternalExpanded] = React.useState<string[]>(initialExpanded);
285
+ const [internalExpanded, setInternalExpanded] =
286
+ React.useState<string[]>(initialExpanded);
286
287
  const [internalSelected, setInternalSelected] = React.useState<string[]>(
287
288
  defaultSelectedKeys ?? [],
288
289
  );
@@ -339,7 +340,7 @@ const Tree = React.forwardRef<HTMLDivElement, TreeProps>(
339
340
  };
340
341
 
341
342
  return (
342
- <div ref={ref} className={cn('text-sm', className)} {...props}>
343
+ <div ref={ref} className={cn('text-xs', className)} {...props}>
343
344
  <ul role="tree" className="flex flex-col gap-0.5">
344
345
  {data.map((n) => (
345
346
  <TreeRow
@@ -3,7 +3,7 @@ id: tree-select
3
3
  name: TreeSelect
4
4
  displayName: 树选择
5
5
  type: component
6
- category: form
6
+ category: data-entry
7
7
  since: 0.1.0
8
8
  package: '@teamix-evo/ui'
9
9
  ---
@@ -27,36 +27,34 @@ package: '@teamix-evo/ui'
27
27
  ## Props
28
28
 
29
29
  <!-- auto:props:begin -->
30
-
31
- | 名称 | 类型 | 默认值 | 必填 | 说明 |
32
- | ------------------ | ------------------------------------- | ----------- | ---- | ----------------------------------------------------------------------------------------------- |
33
- | `data` | `TreeNode[]` | | | 树形数据(antd `treeData` 并集)。 |
34
- | `multiple` | `boolean` | `false` | – | 多选模式 启用后下拉内的 Tree 变为 checkable;value key 数组。 |
35
- | `value` | `string \| string[]` | – | – | 受控 value: - `multiple=false`:`string`(单 key)/ `undefined`(未选) - `multiple=true`:`string[]` |
36
- | `defaultValue` | `string \| string[]` | – | – | uncontrolled 初值。 |
37
- | `onChange` | `(value: string \| string[]) => void` | – | | value 变化回调。 |
38
- | `defaultExpandAll` | `boolean` | `false` | – | 默认展开全部节点(antd `treeDefaultExpandAll` 并集)。 |
39
- | `placeholder` | `string` | `"请选择"` | – | 占位文本。 |
40
- | `disabled` | `boolean` | – | – | 整体禁用。 |
41
- | `className` | `string` | | – | 触发器 className。 |
42
- | `size` | `'sm' \| 'default' \| 'lg'` | `"default"` | – | 触发器尺寸。 |
43
-
30
+ | 名称 | 类型 | 默认值 | 必填 | 说明 |
31
+ | --- | --- | --- | --- | --- |
32
+ | `data` | `TreeNode[]` | | | 树形数据(antd `treeData` 并集)。 |
33
+ | `multiple` | `boolean` | `false` | | 多选模式 启用后下拉内的 Tree 变为 checkable;value 是 key 数组。 |
34
+ | `value` | `string \| string[]` | | – | 受控 value: - `multiple=false`:`string`(单 key)/ `undefined`(未选) - `multiple=true`:`string[]` |
35
+ | `defaultValue` | `string \| string[]` | – | – | uncontrolled 初值。 |
36
+ | `onChange` | `(value: string \| string[]) => void` | – | – | value 变化回调。 |
37
+ | `defaultExpandAll` | `boolean` | `false` | – | 默认展开全部节点(antd `treeDefaultExpandAll` 并集)。 |
38
+ | `placeholder` | `string` | `"请选择"` | – | 占位文本。 |
39
+ | `disabled` | `boolean` | | – | 整体禁用。 |
40
+ | `className` | `string` | – | – | 触发器 className。 |
41
+ | `size` | `'sm' \| 'md' \| 'default' \| 'lg'` | `"default"` | – | 触发器尺寸。 |
42
+ | `allowClear` | `boolean` | `false` | – | 显示清除按钮(antd `allowClear` 并集) — 触发器有值时右侧出现 ✕,点击清空。 |
44
43
  <!-- auto:props:end -->
45
44
 
46
45
  ## 依赖
47
46
 
48
47
  <!-- auto:deps:begin -->
49
-
50
48
  ### 同库依赖
51
49
 
52
50
  > `teamix-evo ui add tree-select` 时,以下 entry 会被自动连带安装(无需手动 add)。
53
51
 
54
- | Entry | 类型 | 描述 |
55
- | --------- | --------- | ----------------------------------------------------------------------------------------------------------------- |
56
- | `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
57
- | `button` | component | 通用按钮 — shadcn 实现 + antd 功能扩展(loading / icon / shape / block / dashed variant) |
58
- | `popover` | component | 可交互浮层 — Radix Popover + antd arrow 并集 |
59
- | `tree` | component | 树形控件 — antd 独有补足。递归层级展示(目录、组织、分类),可展开 / 可选 / 可勾选(父子级联 + 半选),受控与非受控并存 |
52
+ | Entry | 类型 | 描述 |
53
+ | --- | --- | --- |
54
+ | `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
55
+ | `button` | component | 通用按钮 — shadcn 实现 + cloud-design 能力并集(loading / icon / shape / block / dashed variant / color 语义双 prop / disabledTooltip)。同文件合一导出 ButtonGroup + ButtonGroupText(等价 antd Space.Compact + cd SplitButton)。 |
56
+ | `popover` | component | 可交互浮层 — Radix Popover + antd arrow 并集,使用 showArrow 控制尖角(与 Tooltip / HoverCard 命名统一) |
57
+ | `tree` | component | 树形控件 — antd 独有补足。递归层级展示(目录、组织、分类),可展开 / 可选 / 可勾选(父子级联 + 半选),受控与非受控并存 |
60
58
 
61
59
  ### npm 依赖
62
60
 
@@ -65,7 +63,6 @@ package: '@teamix-evo/ui'
65
63
  ```bash
66
64
  pnpm add lucide-react@^0.460.0
67
65
  ```
68
-
69
66
  <!-- auto:deps:end -->
70
67
 
71
68
  ## AI 生成纪律
@@ -112,4 +109,43 @@ const [v, setV] = React.useState<string[]>(['fe', 'be']);
112
109
  value={v}
113
110
  onChange={(next) => setV(next as string[])}
114
111
  />;
112
+
113
+ // 可清除(hover 时右侧出现 ✕)
114
+ <TreeSelect data={data} allowClear defaultValue="fe" />;
115
115
  ```
116
+
117
+ ## TreeSelect 形态 — 旧库 API → 新库映射
118
+
119
+ > 旧库 `TreeSelect`(hybridcloud) → 新库 `TreeSelect`(命名一致)。
120
+ > 新库基于 Radix Popover + 内嵌 `Tree` 组件,触发器复用 `Button outline variant`。
121
+
122
+ ### 命名映射
123
+
124
+ | 旧库 API | 新库 API | 备注 |
125
+ | --- | --- | --- |
126
+ | `dataSource` | `data` | 字段命名简化(对齐 React 习惯) |
127
+ | `treeDefaultExpandAll` | `defaultExpandAll` | 去 `tree` 前缀 |
128
+ | `treeCheckable` | `multiple` | 与 Select 多选 prop 命名统一 |
129
+ | `value` / `onChange(value, data)` | `value` / `onChange(value)` | 单参数化 |
130
+ | `size="small\|medium\|large"` | `size="sm\|md\|lg"` | 三档对齐 Button(24/32/36) |
131
+ | `hasClear` | `allowClear` | ✅ 本波次落地 — hover 触发器右侧显示 ✕ |
132
+ | `placeholder` | `placeholder` | 同名 |
133
+ | `disabled` | `disabled` | 同名 |
134
+
135
+ ### 不修复 / 后续工序清单(报告 §3 P1)
136
+
137
+ > 以下 P1 缺失项**未在 TreeSelect 层补**,因为它们都依赖底层 `Tree` 组件先具备相应能力。**业务真有需求时**优先在 Tree 层做,然后 TreeSelect 透传 prop 即可。
138
+
139
+ - **showSearch + onSearch 搜索过滤**(P1):Tree 层先实现节点筛选高亮,TreeSelect 在 Popover 顶部加搜索框
140
+ - **loadData 异步加载**(P1):Tree 层先实现节点点击触发异步加载子节点,TreeSelect 透传
141
+ - **treeCheckStrictly 父子不关联**(P1):Tree 层 checkable 模式增 `checkStrictly` prop 关掉父子级联
142
+ - **treeCheckedStrategy 回填策略**(P1):Tree 层暴露 `checkedStrategy: 'all' \| 'parent' \| 'child'`,影响 onCheck 返回的 value 集合
143
+ - **useVirtual 虚拟滚动**(P2):Tree 层加 react-virtual 支持(> 500 节点时显著优化)
144
+
145
+ ### 不修复(报告 §5 已明确)
146
+
147
+ - **`hasArrow` / `hasBorder`**:统一走 Button outline variant 视觉
148
+ - **`label` 内联标签**:外层用 `<Label>` 配合,组件内不内置
149
+ - **`popupStyle` / `popupClassName` / `popupProps`**:Popover 自身已有 `className`,无需中转
150
+ - **`isPreview` / `renderPreview`**:无预览态(antd 也已废弃)
151
+ - **`preserveNonExistentValue`**:简化处理,不识别的 key 直接舍去
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
  import { TreeSelect } from './tree-select';
4
4
 
5
5
  const meta: Meta<typeof TreeSelect> = {
6
- title: '表单与输入 · Form/TreeSelect',
6
+ title: '数据录入 · Data Entry/TreeSelect',
7
7
  component: TreeSelect,
8
8
  tags: ['autodocs'],
9
9
  parameters: {
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { ChevronDown } from 'lucide-react';
2
+ import { ChevronDown, X } from 'lucide-react';
3
3
 
4
4
  import { cn } from '@/utils/cn';
5
5
  import { Button } from '@/components/button/button';
@@ -43,7 +43,12 @@ export interface TreeSelectProps {
43
43
  * 触发器尺寸。
44
44
  * @default "default"
45
45
  */
46
- size?: 'sm' | 'default' | 'lg';
46
+ size?: 'sm' | 'md' | 'default' | 'lg';
47
+ /**
48
+ * 显示清除按钮(antd `allowClear` 并集) — 触发器有值时右侧出现 ✕,点击清空。
49
+ * @default false
50
+ */
51
+ allowClear?: boolean;
47
52
  }
48
53
 
49
54
  function flattenLabelMap(nodes: TreeNode[]): Map<string, React.ReactNode> {
@@ -72,7 +77,8 @@ const TreeSelect = React.forwardRef<HTMLButtonElement, TreeSelectProps>(
72
77
  placeholder = '请选择',
73
78
  disabled = false,
74
79
  className,
75
- size = 'default',
80
+ size = 'md',
81
+ allowClear = false,
76
82
  },
77
83
  ref,
78
84
  ) => {
@@ -105,7 +111,7 @@ const TreeSelect = React.forwardRef<HTMLButtonElement, TreeSelectProps>(
105
111
  {display.map((d, i) => (
106
112
  <span
107
113
  key={i}
108
- className="inline-flex rounded-sm bg-muted px-1.5 py-0.5 text-xs"
114
+ className="inline-flex items-center rounded-md bg-muted px-1.5 py-0.5 text-xs text-muted-foreground"
109
115
  >
110
116
  {d}
111
117
  </span>
@@ -116,6 +122,18 @@ const TreeSelect = React.forwardRef<HTMLButtonElement, TreeSelectProps>(
116
122
  return <span className="truncate">{display}</span>;
117
123
  };
118
124
 
125
+ const hasValue = multiple
126
+ ? Array.isArray(current) && current.length > 0
127
+ : !!current;
128
+
129
+ const handleClear = (e: React.MouseEvent) => {
130
+ e.preventDefault();
131
+ e.stopPropagation();
132
+ const next = multiple ? [] : '';
133
+ if (!isControlled) setInternal(next);
134
+ onChange?.(next);
135
+ };
136
+
119
137
  return (
120
138
  <Popover open={open} onOpenChange={setOpen}>
121
139
  <PopoverTrigger asChild>
@@ -126,16 +144,33 @@ const TreeSelect = React.forwardRef<HTMLButtonElement, TreeSelectProps>(
126
144
  size={size}
127
145
  disabled={disabled}
128
146
  className={cn(
129
- 'min-w-panel-sm justify-between font-normal',
147
+ 'group/treeselect min-w-panel-sm justify-between font-normal',
130
148
  !display && 'text-muted-foreground',
131
149
  className,
132
150
  )}
133
151
  >
134
152
  <span className="min-w-0 flex-1 text-left">{renderDisplay()}</span>
135
- <ChevronDown className="ml-2 size-4 shrink-0 opacity-50" />
153
+ {allowClear && hasValue && !disabled ? (
154
+ <span
155
+ role="button"
156
+ tabIndex={-1}
157
+ aria-label="清除"
158
+ onClick={handleClear}
159
+ onMouseDown={(e) => e.stopPropagation()}
160
+ className="ml-2 hidden shrink-0 rounded-sm text-muted-foreground transition-colors hover:text-foreground group-hover/treeselect:inline-flex"
161
+ >
162
+ <X className="size-3.5" />
163
+ </span>
164
+ ) : null}
165
+ <ChevronDown
166
+ className={cn(
167
+ 'ml-2 size-4 shrink-0 opacity-50',
168
+ allowClear && hasValue && 'group-hover/treeselect:hidden',
169
+ )}
170
+ />
136
171
  </Button>
137
172
  </PopoverTrigger>
138
- <PopoverContent className="w-72 p-2" align="start">
173
+ <PopoverContent className="w-72 p-1" align="start">
139
174
  {multiple ? (
140
175
  <Tree
141
176
  data={data}
@@ -3,24 +3,24 @@ id: typography
3
3
  name: Typography
4
4
  displayName: 排版
5
5
  type: component
6
- category: data-display
6
+ category: general
7
7
  since: 0.1.0
8
8
  package: '@teamix-evo/ui'
9
9
  ---
10
10
 
11
11
  # Typography 排版
12
12
 
13
- 排版组件 — `Prose`(富文本容器)+ shadcn 风格 `Title / Paragraph / Text / Link` + antd `Text` 的 `type / strong / delete / disabled / code / ellipsis / copyable` 并集。
13
+ 排版组件 — `Prose`(富文本容器)+ shadcn 风格 `Title / Paragraph / Text / Link` + antd `Text` 的 `strong / delete / disabled / code / ellipsis / copyable` 并集。语义色采用 [ADR 0021](../../../../../docs/adr/0021-semantic-color-api-unification.md) 统一 `color` API。
14
14
 
15
15
  > Prose 不依赖 `@tailwindcss/typography` 插件,样式手写并对齐 OpenTrek tokens。
16
16
 
17
17
  ## When to use
18
18
 
19
19
  - **Prose**:Markdown / CMS 富文本渲染容器(自动套排版样式)
20
- - **Title**:页面 / 区块标题(`level={1..5}` 自动映射 `<h1>~<h5>`)
20
+ - **Title**:页面 / 区块标题(`level={1..6}` 自动映射 `<h1>~<h6>`,对齐 antd `Typography.Title.level`)
21
21
  - **Paragraph**:正文段落(行高 / 字号 / 颜色统一)
22
- - **Text**:行内文本带语义色 / 强调 / 复制
23
- - **Link**:语义化链接(类型 + 默认下划线 hover)
22
+ - **Text**:行内文本带语义色(`color`) / 强调 / 复制
23
+ - **Link**:语义化链接(`color` + 默认下划线 hover)
24
24
 
25
25
  ## When NOT to use
26
26
 
@@ -33,31 +33,15 @@ package: '@teamix-evo/ui'
33
33
  > 以下表格由 `pnpm --filter @teamix-evo/ui gen:meta` 自动生成,数据源是 [`typography.tsx`](./typography.tsx) 的 `TextProps` interface JSDoc。
34
34
 
35
35
  <!-- auto:props:begin -->
36
-
37
- #### Text
38
-
39
- | 名称 | 类型 | 默认值 | 必填 | 说明 |
40
- | ---------- | ---------------------------------------------------------- | ----------- | ---- | --------------------------------------------------------------------------------------------------------------------------------- |
41
- | `type` | `TextType` | `"default"` | – | 语义色(antd `type` 并集)。 |
42
- | `delete` | `boolean` | `false` | – | 删除线。 |
43
- | `disabled` | `boolean` | `false` | – | 不可用(灰色 + 不可选)。 |
44
- | `strong` | `boolean` | `false` | – | 加粗。 |
45
- | `code` | `boolean` | `false` | – | 行内代码样式(`code`)。 |
46
- | `ellipsis` | `boolean` | `false` | – | 单行省略(antd `ellipsis` 简化版 — 只支持 boolean,行数 / suffix 留 v0.x)。 |
47
- | `copyable` | `boolean \| { text: string; tooltips?: [string, string] }` | `false` | – | 可复制(antd `copyable` 并集)— 末尾追加复制图标按钮。 传对象时可指定要复制的文本(默认是 children 的纯文本);传 `true` 用 children。 |
48
-
49
- #### Title
50
-
51
- | 名称 | 类型 | 默认值 | 必填 | 说明 |
52
- | ------- | ----------------------- | ------ | ---- | ------------------------------------------------------- |
53
- | `level` | `1 \| 2 \| 3 \| 4 \| 5` | `1` | – | 层级(1~5),决定字号 / 粗细;同时映射为 `<h1>~<h5>` 标签。 |
54
-
55
- #### Link
56
-
57
- | 名称 | 类型 | 默认值 | 必填 | 说明 |
58
- | ------ | ---------- | ----------- | ---- | ------------------------- |
59
- | `type` | `TextType` | `"default"` | – | 语义色(同 Text 的 type)。 |
60
-
36
+ | 名称 | 类型 | 默认值 | 必填 | 说明 |
37
+ | --- | --- | --- | --- | --- |
38
+ | `color` | `TextColor` | `"default"` | – | 语义色 — 6 档枚举,字面与 OpenTrek tokens 对齐(见 [ADR 0021](../../../../../docs/adr/0021-semantic-color-api-unification.md))。 antd `type` 迁移:`secondary`→`muted`、`danger`→`destructive`。 |
39
+ | `delete` | `boolean` | `false` | | 删除线。 |
40
+ | `disabled` | `boolean` | `false` | | 不可用(灰色 + 不可选)。 |
41
+ | `strong` | `boolean` | `false` | – | 加粗。 |
42
+ | `code` | `boolean` | `false` | – | 行内代码样式(`code`)。 |
43
+ | `ellipsis` | `boolean` | `false` | – | 单行省略(antd `ellipsis` 简化版 — 只支持 boolean,行数 / suffix 留 v0.x)。 |
44
+ | `copyable` | `boolean \| { text: string; tooltips?: [string, string] }` | `false` | – | 可复制(antd `copyable` 并集)— 末尾追加复制图标按钮。 传对象时可指定要复制的文本(默认是 children 的纯文本);传 `true` 用 children。 |
61
45
  <!-- auto:props:end -->
62
46
 
63
47
  ## 依赖
@@ -65,14 +49,13 @@ package: '@teamix-evo/ui'
65
49
  > 以下表格由 `pnpm --filter @teamix-evo/ui gen:meta` 自动生成,数据源是 [`manifest.json`](../../../manifest.json)。**手工编辑 marker 之间的内容会在下次生成时被覆盖**。
66
50
 
67
51
  <!-- auto:deps:begin -->
68
-
69
52
  ### 同库依赖
70
53
 
71
54
  > `teamix-evo ui add typography` 时,以下 entry 会被自动连带安装(无需手动 add)。
72
55
 
73
- | Entry | 类型 | 描述 |
74
- | ----- | ---- | -------------------------------------------------- |
75
- | `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
56
+ | Entry | 类型 | 描述 |
57
+ | --- | --- | --- |
58
+ | `cn` | util | Tailwind className 合并工具(clsx + tailwind-merge) |
76
59
 
77
60
  ### npm 依赖
78
61
 
@@ -81,17 +64,56 @@ package: '@teamix-evo/ui'
81
64
  ```bash
82
65
  pnpm add lucide-react@^0.460.0
83
66
  ```
84
-
85
67
  <!-- auto:deps:end -->
86
68
 
87
69
  ## AI 生成纪律
88
70
 
89
71
  - **`Title level` 决定标签**:不要用 `<h2>` 配 `level={1}`,语义会冲突
90
- - **`Text type` 优先于 className 颜色**:语义色让暗色模式自动适配
72
+ - **`Text color` 优先于 className 颜色**:语义色让暗色模式自动适配
91
73
  - **`copyable` 仅当 children 是 string**:富节点请显式传 `copyable={{ text: '...' }}`
92
74
  - **`ellipsis` 单行**:多行省略请直接 `className="line-clamp-2"`
93
75
  - **Prose 内部不要嵌套 Prose**:嵌套排版会双倍间距
94
76
 
77
+ ## Typography 形态 — 旧库 API → 新库映射
78
+
79
+ 旧库(Teamix 1.0 / `@alifd/next.Typography` + `Typography.Text` / `Typography.Paragraph` / `Typography.H1`~`H6`)与新库(`Typography` / `Title` / `Paragraph` / `Text` / `Link` / `Prose`)逐项对应。
80
+
81
+ ### 组件拆合
82
+
83
+ | 旧库 | 新库 | 备注 |
84
+ | --- | --- | --- |
85
+ | `Typography` | `Prose` | 富文本容器,渲染 Markdown / CMS 输出 |
86
+ | `Typography.H1` ~ `Typography.H6` | `<Title level={1..6}>` | level 决定字号 + 标签;新增 level=6 对齐 antd |
87
+ | `Typography.Paragraph` | `Paragraph` | 同义 |
88
+ | `Typography.Text` | `Text` | 行内文本 |
89
+ | — | `Link` | 新增 — 语义化 `<a>` 元素 |
90
+
91
+ ### Props / 值映射
92
+
93
+ | 旧库 | 新库 | 备注 |
94
+ | --- | --- | --- |
95
+ | `<Text type="secondary">` | `<Text color="muted">` | ADR 0021 语义色重命名 |
96
+ | `<Text type="danger">` | `<Text color="destructive">` | ADR 0021 — 不收 antd `error` / `danger` 别名 |
97
+ | `<Text strong>` | `<Text strong>` | 行为一致 |
98
+ | `<Text delete>` | `<Text delete>` | 行为一致 |
99
+ | `<Text code>` | `<Text code>` | 行为一致 |
100
+ | `<Text disabled>` | `<Text disabled>` | 行为一致 |
101
+ | `<Text ellipsis>` | `<Text ellipsis>` | P0 已实现 — 单行 truncate;多行用 `className="line-clamp-N"` |
102
+ | `<Text copyable>` | `<Text copyable>` | P0 已实现 — 默认复制 children;传对象指定 `text` |
103
+ | `<Text copyable={{ text }}>` | `<Text copyable={{ text }}>` | 对象签名一致 |
104
+ | `size="body1/body2/caption/overline"` | className `text-sm/text-xs/...` | shadcn 字号通过 Tailwind 直控,不抽 prop |
105
+ | `mark` 黄色高亮 | 直接用 `<mark>` 标签 | HTML 原生 |
106
+ | `underline` | `className="underline"` | Tailwind utility |
107
+ | `editable` 行内编辑 | 不修复 — 用 Tiptap / Lexical / Input + state | 复杂度高,业务低频 |
108
+
109
+ ### 不修复清单
110
+
111
+ | 旧库能力 | 理由 |
112
+ | --- | --- |
113
+ | `mark` / `underline` / `delete` / `code` 全 prop | 直接用 HTML 原生 / Tailwind utility 更简洁,只保留 `delete` / `code` 的便捷 prop |
114
+ | `editable` 行内编辑 | 业务低频 + 复杂度高,推荐用 Tiptap 等编辑器 |
115
+ | `component` 自定义根标签 | shadcn 走 `asChild` (Slot) 替代 — 需要时用 `<Title asChild><span>...</span></Title>` |
116
+
95
117
  ## Examples
96
118
 
97
119
  ```tsx
@@ -105,8 +127,8 @@ import { Prose, Title, Paragraph, Text, Link } from '@/components/ui/typography'
105
127
  <Paragraph>正文段落,统一字号 / 行高 / 颜色。</Paragraph>
106
128
 
107
129
  // 行内文本
108
- <Text type="success" strong>成功</Text>
109
- <Text type="danger" delete>已废弃</Text>
130
+ <Text color="success" strong>成功</Text>
131
+ <Text color="destructive" delete>已废弃</Text>
110
132
  <Text disabled>不可用</Text>
111
133
  <Text code>const x = 1</Text>
112
134
  <Text ellipsis>这是一段非常长的文字...被截断</Text>
@@ -115,7 +137,7 @@ import { Prose, Title, Paragraph, Text, Link } from '@/components/ui/typography'
115
137
 
116
138
  // 链接
117
139
  <Link href="/docs">文档</Link>
118
- <Link href="/danger" type="danger">危险链接</Link>
140
+ <Link href="/danger" color="destructive">危险链接</Link>
119
141
 
120
142
  // Prose 容器(渲染 Markdown 等富文本)
121
143
  <Prose>
@@ -1,15 +1,15 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
  import { Prose, Title, Paragraph, Text, Link } from './typography';
3
3
 
4
4
  const meta: Meta<typeof Text> = {
5
- title: '数据展示 · Data Display/Typography',
5
+ title: '通用 · General/Typography',
6
6
  component: Text,
7
7
  tags: ['autodocs'],
8
8
  parameters: {
9
9
  docs: {
10
10
  description: {
11
11
  component:
12
- '排版组件 — Prose 富文本容器 + Title / Paragraph / Text / Link,合并 antd 的 `type` / `strong` / `delete` / `disabled` / `code` / `ellipsis` / `copyable` 能力。',
12
+ '排版组件 — Prose 富文本容器 + Title / Paragraph / Text / Link,合并 antd 的 `type` / `strong` / `delete` / `disabled` / `code` / `ellipsis` / `copyable` 能力。语义色采用 [ADR 0021](../../../../../docs/adr/0021-semantic-color-api-unification.md) 统一 `color` API(antd `type` 的 secondary/success/warning/danger 合并为 `color` 的 muted/success/warning/destructive)。',
13
13
  },
14
14
  },
15
15
  },
@@ -31,15 +31,16 @@ export const Titles: Story = {
31
31
  ),
32
32
  };
33
33
 
34
- export const TextTypes: Story = {
34
+ export const TextColors: Story = {
35
35
  parameters: { controls: { disable: true } },
36
36
  render: () => (
37
37
  <div className="flex flex-col gap-2 text-sm">
38
38
  <Text>默认</Text>
39
- <Text type="secondary">次要</Text>
40
- <Text type="success">成功</Text>
41
- <Text type="warning">警告</Text>
42
- <Text type="danger">危险</Text>
39
+ <Text color="muted">次要</Text>
40
+ <Text color="primary">信息 / 主颜色</Text>
41
+ <Text color="success">成功</Text>
42
+ <Text color="warning">警告</Text>
43
+ <Text color="destructive">危险</Text>
43
44
  <Text strong>加粗</Text>
44
45
  <Text delete>已废弃</Text>
45
46
  <Text disabled>不可用</Text>
@@ -76,7 +77,11 @@ export const Links: Story = {
76
77
  <Link href="#docs" onClick={(e) => e.preventDefault()}>
77
78
  文档
78
79
  </Link>
79
- <Link href="#delete" type="danger" onClick={(e) => e.preventDefault()}>
80
+ <Link
81
+ href="#delete"
82
+ color="destructive"
83
+ onClick={(e) => e.preventDefault()}
84
+ >
80
85
  危险操作链接
81
86
  </Link>
82
87
  </div>