@lark-apaas/coding-template-nestjs-react-fullstack 0.1.0-alpha.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 (250) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +41 -0
  3. package/hooks/after-install.mjs +3 -0
  4. package/hooks/after-render.mjs +3 -0
  5. package/hooks/before-render.mjs +3 -0
  6. package/package.json +36 -0
  7. package/template/.codebase/pipelines/ci.yaml +34 -0
  8. package/template/.codebase/pipelines/coco-code-review.yaml +21 -0
  9. package/template/.prettierrc +8 -0
  10. package/template/.spark_project +16 -0
  11. package/template/.stylelintrc.js +12 -0
  12. package/template/_env.local +38 -0
  13. package/template/_gitignore +64 -0
  14. package/template/_npmrc +1 -0
  15. package/template/client/index.html +23 -0
  16. package/template/client/public/favicon.svg +40 -0
  17. package/template/client/src/api/index.ts +19 -0
  18. package/template/client/src/app.tsx +22 -0
  19. package/template/client/src/components/Layout.tsx +11 -0
  20. package/template/client/src/components/business-ui/README.md +519 -0
  21. package/template/client/src/components/business-ui/api/chats/queries.ts +39 -0
  22. package/template/client/src/components/business-ui/api/chats/service.ts +29 -0
  23. package/template/client/src/components/business-ui/api/departments/queries.ts +42 -0
  24. package/template/client/src/components/business-ui/api/departments/service.ts +18 -0
  25. package/template/client/src/components/business-ui/api/files/service.ts +28 -0
  26. package/template/client/src/components/business-ui/api/user-profiles/queries.ts +42 -0
  27. package/template/client/src/components/business-ui/api/user-profiles/service.ts +23 -0
  28. package/template/client/src/components/business-ui/api/users/queries.ts +34 -0
  29. package/template/client/src/components/business-ui/api/users/service.ts +40 -0
  30. package/template/client/src/components/business-ui/chat-select/README.md +128 -0
  31. package/template/client/src/components/business-ui/chat-select/chat-item.tsx +85 -0
  32. package/template/client/src/components/business-ui/chat-select/chat-select-tag.tsx +83 -0
  33. package/template/client/src/components/business-ui/chat-select/chat-select.tsx +197 -0
  34. package/template/client/src/components/business-ui/chat-select/index.tsx +12 -0
  35. package/template/client/src/components/business-ui/chat-select/types.ts +102 -0
  36. package/template/client/src/components/business-ui/chat-select/use-chat-value.ts +180 -0
  37. package/template/client/src/components/business-ui/chat-select/utils.ts +81 -0
  38. package/template/client/src/components/business-ui/department-select/department-item.tsx +55 -0
  39. package/template/client/src/components/business-ui/department-select/department-select-field.tsx +86 -0
  40. package/template/client/src/components/business-ui/department-select/department-select-tag.tsx +56 -0
  41. package/template/client/src/components/business-ui/department-select/department-select.tsx +168 -0
  42. package/template/client/src/components/business-ui/department-select/icon-department.tsx +22 -0
  43. package/template/client/src/components/business-ui/department-select/index.tsx +7 -0
  44. package/template/client/src/components/business-ui/department-select/types.ts +15 -0
  45. package/template/client/src/components/business-ui/department-select/utils.ts +17 -0
  46. package/template/client/src/components/business-ui/entity-combobox/base-combobox-content.tsx +35 -0
  47. package/template/client/src/components/business-ui/entity-combobox/base-combobox-empty.tsx +28 -0
  48. package/template/client/src/components/business-ui/entity-combobox/base-combobox-error.tsx +35 -0
  49. package/template/client/src/components/business-ui/entity-combobox/base-combobox-item.tsx +55 -0
  50. package/template/client/src/components/business-ui/entity-combobox/base-combobox-list.tsx +174 -0
  51. package/template/client/src/components/business-ui/entity-combobox/base-combobox-loading.tsx +19 -0
  52. package/template/client/src/components/business-ui/entity-combobox/base-combobox-search.tsx +31 -0
  53. package/template/client/src/components/business-ui/entity-combobox/base-combobox-trigger.tsx +281 -0
  54. package/template/client/src/components/business-ui/entity-combobox/base-combobox.tsx +132 -0
  55. package/template/client/src/components/business-ui/entity-combobox/context.tsx +19 -0
  56. package/template/client/src/components/business-ui/entity-combobox/entity-combobox.tsx +145 -0
  57. package/template/client/src/components/business-ui/entity-combobox/highlight-text.tsx +52 -0
  58. package/template/client/src/components/business-ui/entity-combobox/hooks.tsx +21 -0
  59. package/template/client/src/components/business-ui/entity-combobox/index.tsx +31 -0
  60. package/template/client/src/components/business-ui/entity-combobox/item-pill.tsx +179 -0
  61. package/template/client/src/components/business-ui/entity-combobox/popover-wrapper.tsx +149 -0
  62. package/template/client/src/components/business-ui/entity-combobox/search-trigger.tsx +262 -0
  63. package/template/client/src/components/business-ui/entity-combobox/shared-types.ts +296 -0
  64. package/template/client/src/components/business-ui/entity-combobox/size-variants.tsx +322 -0
  65. package/template/client/src/components/business-ui/entity-combobox/types.ts +246 -0
  66. package/template/client/src/components/business-ui/entity-combobox/use-fetch-data.tsx +81 -0
  67. package/template/client/src/components/business-ui/entity-combobox/use-infinite-scroll.tsx +99 -0
  68. package/template/client/src/components/business-ui/entity-combobox/use-popover-outside-click.tsx +32 -0
  69. package/template/client/src/components/business-ui/form/checkbox-field.tsx +83 -0
  70. package/template/client/src/components/business-ui/form/context.tsx +38 -0
  71. package/template/client/src/components/business-ui/form/field-layout.tsx +91 -0
  72. package/template/client/src/components/business-ui/form/form.tsx +54 -0
  73. package/template/client/src/components/business-ui/form/hooks/form-context.tsx +4 -0
  74. package/template/client/src/components/business-ui/form/hooks/form-utils.ts +23 -0
  75. package/template/client/src/components/business-ui/form/hooks/form.tsx +40 -0
  76. package/template/client/src/components/business-ui/form/index.tsx +4 -0
  77. package/template/client/src/components/business-ui/form/input-field.tsx +74 -0
  78. package/template/client/src/components/business-ui/form/radio-group-field.tsx +138 -0
  79. package/template/client/src/components/business-ui/form/select-field.tsx +155 -0
  80. package/template/client/src/components/business-ui/form/switch-field.tsx +66 -0
  81. package/template/client/src/components/business-ui/form/textarea-field.tsx +72 -0
  82. package/template/client/src/components/business-ui/form/types.ts +32 -0
  83. package/template/client/src/components/business-ui/tiptap-editor/README.md +324 -0
  84. package/template/client/src/components/business-ui/tiptap-editor/components/attachment-toolbar-button.tsx +74 -0
  85. package/template/client/src/components/business-ui/tiptap-editor/components/blockquote-toolbar-button.tsx +41 -0
  86. package/template/client/src/components/business-ui/tiptap-editor/components/code-block-toolbar-button.tsx +41 -0
  87. package/template/client/src/components/business-ui/tiptap-editor/components/color-highlight-toolbar-button.tsx +141 -0
  88. package/template/client/src/components/business-ui/tiptap-editor/components/heading-toolbar-button.tsx +99 -0
  89. package/template/client/src/components/business-ui/tiptap-editor/components/horizontal-rule-toolbar-button.tsx +39 -0
  90. package/template/client/src/components/business-ui/tiptap-editor/components/image-upload-toolbar-button.tsx +65 -0
  91. package/template/client/src/components/business-ui/tiptap-editor/components/link-edit-form.tsx +127 -0
  92. package/template/client/src/components/business-ui/tiptap-editor/components/link-hover-toolbar.tsx +380 -0
  93. package/template/client/src/components/business-ui/tiptap-editor/components/link-toolbar-button.tsx +96 -0
  94. package/template/client/src/components/business-ui/tiptap-editor/components/list-toolbar-button.tsx +75 -0
  95. package/template/client/src/components/business-ui/tiptap-editor/components/mark-toolbar-button.tsx +118 -0
  96. package/template/client/src/components/business-ui/tiptap-editor/components/text-align-toolbar-button.tsx +84 -0
  97. package/template/client/src/components/business-ui/tiptap-editor/components/undo-redo-toolbar-button.tsx +54 -0
  98. package/template/client/src/components/business-ui/tiptap-editor/extensions/attachment.tsx +539 -0
  99. package/template/client/src/components/business-ui/tiptap-editor/extensions/code-block-shiki.tsx +236 -0
  100. package/template/client/src/components/business-ui/tiptap-editor/extensions/complete-kit.ts +260 -0
  101. package/template/client/src/components/business-ui/tiptap-editor/extensions/image.tsx +456 -0
  102. package/template/client/src/components/business-ui/tiptap-editor/hooks/use-tiptap-editor.ts +47 -0
  103. package/template/client/src/components/business-ui/tiptap-editor/index.ts +38 -0
  104. package/template/client/src/components/business-ui/tiptap-editor/tiptap-editor-complete.tsx +112 -0
  105. package/template/client/src/components/business-ui/tiptap-editor/tiptap-editor.tsx +169 -0
  106. package/template/client/src/components/business-ui/types/user.ts +74 -0
  107. package/template/client/src/components/business-ui/user-display/index.tsx +2 -0
  108. package/template/client/src/components/business-ui/user-display/overflow-tooltip-text.tsx +90 -0
  109. package/template/client/src/components/business-ui/user-display/type.ts +27 -0
  110. package/template/client/src/components/business-ui/user-display/user-display.tsx +99 -0
  111. package/template/client/src/components/business-ui/user-display/user-with-avatar.tsx +158 -0
  112. package/template/client/src/components/business-ui/user-display/utils.ts +37 -0
  113. package/template/client/src/components/business-ui/user-profile/error-image.tsx +302 -0
  114. package/template/client/src/components/business-ui/user-profile/user-external-script.ts +73 -0
  115. package/template/client/src/components/business-ui/user-profile/user-profile.tsx +370 -0
  116. package/template/client/src/components/business-ui/user-select/index.tsx +28 -0
  117. package/template/client/src/components/business-ui/user-select/types.ts +109 -0
  118. package/template/client/src/components/business-ui/user-select/use-user-value.ts +160 -0
  119. package/template/client/src/components/business-ui/user-select/user-item.tsx +98 -0
  120. package/template/client/src/components/business-ui/user-select/user-pill.tsx +140 -0
  121. package/template/client/src/components/business-ui/user-select/user-select-tag.tsx +82 -0
  122. package/template/client/src/components/business-ui/user-select/user-select.tsx +359 -0
  123. package/template/client/src/components/business-ui/user-select/utils.tsx +188 -0
  124. package/template/client/src/components/business-ui/utils/user.ts +72 -0
  125. package/template/client/src/components/ui/README.md +134 -0
  126. package/template/client/src/components/ui/accordion.tsx +66 -0
  127. package/template/client/src/components/ui/alert-dialog.tsx +157 -0
  128. package/template/client/src/components/ui/alert.tsx +71 -0
  129. package/template/client/src/components/ui/aspect-ratio.tsx +11 -0
  130. package/template/client/src/components/ui/avatar.tsx +53 -0
  131. package/template/client/src/components/ui/badge.tsx +42 -0
  132. package/template/client/src/components/ui/breadcrumb.tsx +109 -0
  133. package/template/client/src/components/ui/button-group.tsx +83 -0
  134. package/template/client/src/components/ui/button.tsx +69 -0
  135. package/template/client/src/components/ui/calendar.tsx +213 -0
  136. package/template/client/src/components/ui/card.tsx +82 -0
  137. package/template/client/src/components/ui/carousel.tsx +241 -0
  138. package/template/client/src/components/ui/chart.tsx +357 -0
  139. package/template/client/src/components/ui/checkbox.tsx +32 -0
  140. package/template/client/src/components/ui/collapsible.tsx +33 -0
  141. package/template/client/src/components/ui/command.tsx +208 -0
  142. package/template/client/src/components/ui/context-menu.tsx +324 -0
  143. package/template/client/src/components/ui/dialog.tsx +143 -0
  144. package/template/client/src/components/ui/drawer.tsx +135 -0
  145. package/template/client/src/components/ui/dropdown-menu.tsx +329 -0
  146. package/template/client/src/components/ui/empty.tsx +104 -0
  147. package/template/client/src/components/ui/field.tsx +248 -0
  148. package/template/client/src/components/ui/form.tsx +167 -0
  149. package/template/client/src/components/ui/hover-card.tsx +44 -0
  150. package/template/client/src/components/ui/icons/file-ae-colorful-icon.tsx +21 -0
  151. package/template/client/src/components/ui/icons/file-ai-colorful-icon.tsx +36 -0
  152. package/template/client/src/components/ui/icons/file-android-colorful-icon.tsx +33 -0
  153. package/template/client/src/components/ui/icons/file-audio-colorful-icon.tsx +21 -0
  154. package/template/client/src/components/ui/icons/file-code-colorful-icon.tsx +28 -0
  155. package/template/client/src/components/ui/icons/file-csv-colorful-icon.tsx +21 -0
  156. package/template/client/src/components/ui/icons/file-eml-colorful-icon.tsx +29 -0
  157. package/template/client/src/components/ui/icons/file-ios-colorful-icon.tsx +25 -0
  158. package/template/client/src/components/ui/icons/file-keynote-colorful-icon.tsx +29 -0
  159. package/template/client/src/components/ui/icons/file-pages-colorful-icon.tsx +29 -0
  160. package/template/client/src/components/ui/icons/file-ps-colorful-icon.tsx +21 -0
  161. package/template/client/src/components/ui/icons/file-sketch-colorful-icon.tsx +21 -0
  162. package/template/client/src/components/ui/icons/file-slide-colorful-icon.tsx +21 -0
  163. package/template/client/src/components/ui/icons/file-vcf-colorful-icon.tsx +29 -0
  164. package/template/client/src/components/ui/icons/file-wiki-excel-colorful-icon.tsx +23 -0
  165. package/template/client/src/components/ui/icons/file-wiki-image-colorful-icon.tsx +27 -0
  166. package/template/client/src/components/ui/icons/file-wiki-pdf-colorful-icon.tsx +20 -0
  167. package/template/client/src/components/ui/icons/file-wiki-ppt-colorful-icon.tsx +21 -0
  168. package/template/client/src/components/ui/icons/file-wiki-text-colorful-icon.tsx +12 -0
  169. package/template/client/src/components/ui/icons/file-wiki-unknown-colorful-icon.tsx +14 -0
  170. package/template/client/src/components/ui/icons/file-wiki-video-colorful-icon.tsx +23 -0
  171. package/template/client/src/components/ui/icons/file-wiki-word-colorful-icon.tsx +38 -0
  172. package/template/client/src/components/ui/icons/file-wiki-zip-colorful-icon.tsx +21 -0
  173. package/template/client/src/components/ui/image.tsx +183 -0
  174. package/template/client/src/components/ui/input-group.tsx +166 -0
  175. package/template/client/src/components/ui/input-otp.tsx +77 -0
  176. package/template/client/src/components/ui/input.tsx +21 -0
  177. package/template/client/src/components/ui/item.tsx +193 -0
  178. package/template/client/src/components/ui/kbd.tsx +28 -0
  179. package/template/client/src/components/ui/label.tsx +24 -0
  180. package/template/client/src/components/ui/menubar.tsx +348 -0
  181. package/template/client/src/components/ui/native-select.tsx +48 -0
  182. package/template/client/src/components/ui/navigation-menu.tsx +168 -0
  183. package/template/client/src/components/ui/pagination.tsx +127 -0
  184. package/template/client/src/components/ui/popover.tsx +48 -0
  185. package/template/client/src/components/ui/progress.tsx +31 -0
  186. package/template/client/src/components/ui/radio-group.tsx +45 -0
  187. package/template/client/src/components/ui/resizable.tsx +56 -0
  188. package/template/client/src/components/ui/scroll-area.tsx +58 -0
  189. package/template/client/src/components/ui/select.tsx +243 -0
  190. package/template/client/src/components/ui/separator.tsx +28 -0
  191. package/template/client/src/components/ui/sheet.tsx +139 -0
  192. package/template/client/src/components/ui/sidebar.tsx +727 -0
  193. package/template/client/src/components/ui/skeleton.tsx +13 -0
  194. package/template/client/src/components/ui/slider.tsx +87 -0
  195. package/template/client/src/components/ui/sonner.tsx +67 -0
  196. package/template/client/src/components/ui/spinner.tsx +16 -0
  197. package/template/client/src/components/ui/streamdown.tsx +186 -0
  198. package/template/client/src/components/ui/switch.tsx +31 -0
  199. package/template/client/src/components/ui/table.tsx +116 -0
  200. package/template/client/src/components/ui/tabs.tsx +66 -0
  201. package/template/client/src/components/ui/textarea.tsx +18 -0
  202. package/template/client/src/components/ui/toggle-group.tsx +83 -0
  203. package/template/client/src/components/ui/toggle.tsx +47 -0
  204. package/template/client/src/components/ui/tooltip.tsx +61 -0
  205. package/template/client/src/hooks/use-example.ts +52 -0
  206. package/template/client/src/hooks/use-mobile.ts +19 -0
  207. package/template/client/src/index.css +7 -0
  208. package/template/client/src/index.tsx +36 -0
  209. package/template/client/src/lib/shiki.ts +92 -0
  210. package/template/client/src/lib/utils.ts +6 -0
  211. package/template/client/src/pages/ExamplePage/ExamplePage.tsx +37 -0
  212. package/template/client/src/pages/NotFound/NotFound.tsx +11 -0
  213. package/template/client/src/tailwind-theme.css +257 -0
  214. package/template/client/src/types/common.ts +34 -0
  215. package/template/client/src/types/global.d.ts +53 -0
  216. package/template/client/src/types/index.ts +4 -0
  217. package/template/client/src/typography.css +41 -0
  218. package/template/client/src/utils/img-resources/avatar-placeholders.ts +12 -0
  219. package/template/client/src/utils/img-resources/banner-placeholders.ts +29 -0
  220. package/template/client/src/utils/img-resources/cover-placeholders.ts +47 -0
  221. package/template/components.json +21 -0
  222. package/template/eslint.config.js +50 -0
  223. package/template/nest-cli.json +25 -0
  224. package/template/package-lock.json +29195 -0
  225. package/template/package.json +202 -0
  226. package/template/postcss.config.js +10 -0
  227. package/template/scripts/build.sh +120 -0
  228. package/template/scripts/dev.js +295 -0
  229. package/template/scripts/dev.sh +2 -0
  230. package/template/scripts/lint.js +150 -0
  231. package/template/scripts/prune-smart.js +281 -0
  232. package/template/scripts/run.sh +5 -0
  233. package/template/server/app.module.ts +27 -0
  234. package/template/server/common/constants/api_response_code.ts +54 -0
  235. package/template/server/common/filters/exception.filter.ts +78 -0
  236. package/template/server/common/interfaces/api_response.interface.ts +21 -0
  237. package/template/server/common/interfaces/exception.interface.ts +19 -0
  238. package/template/server/database/schema.ts +90 -0
  239. package/template/server/main.ts +31 -0
  240. package/template/server/modules/hello/hello.controller.ts +16 -0
  241. package/template/server/modules/hello/hello.module.ts +10 -0
  242. package/template/server/modules/hello/hello.service.ts +28 -0
  243. package/template/server/modules/view/view.controller.ts +17 -0
  244. package/template/server/modules/view/view.module.ts +8 -0
  245. package/template/shared/api.interface.ts +1 -0
  246. package/template/tailwind.config.ts +9 -0
  247. package/template/tsconfig.app.json +23 -0
  248. package/template/tsconfig.json +8 -0
  249. package/template/tsconfig.node.json +16 -0
  250. package/template/vite.config.ts +10 -0
@@ -0,0 +1,296 @@
1
+ import type { FocusEvent, ReactNode } from 'react';
2
+
3
+ import { PopoverContent } from '@client/src/components/ui/popover';
4
+
5
+ // 重新导出 size 相关类型
6
+ export type { ComboboxSize } from '@client/src/components/business-ui/entity-combobox/size-variants';
7
+
8
+ /**
9
+ * 通用选项值类型
10
+ * @template TRaw - 原始数据类型,用于保留完整的原始对象
11
+ */
12
+ export type ItemValue<TRaw = unknown> = {
13
+ id: string;
14
+ name: string;
15
+ avatar?: string;
16
+ raw?: TRaw;
17
+ };
18
+
19
+ /**
20
+ * 触发器类型
21
+ */
22
+ export type TriggerType = 'button' | 'search' | 'custom';
23
+
24
+ /**
25
+ * 触发器渲染属性
26
+ */
27
+ export type TriggerRenderProps<TRaw = unknown> = {
28
+ selectedValue: ItemValue<TRaw> | ItemValue<TRaw>[] | null;
29
+ multiple: boolean;
30
+ open: boolean;
31
+ disabled: boolean;
32
+ };
33
+
34
+ /**
35
+ * 样式类名配置
36
+ * 用于统一配置各个内部元素的自定义 className
37
+ */
38
+ export type ClassNamesConfig = {
39
+ /** 根容器的 className */
40
+ root?: string;
41
+ /** 触发器的 className */
42
+ trigger?: string;
43
+ /** 弹层内容的 className */
44
+ popover?: string;
45
+ /** 搜索框的 className */
46
+ search?: string;
47
+ /** 列表容器的 className */
48
+ list?: string;
49
+ /** 列表项的 className */
50
+ listItem?: string;
51
+ /** 标签的 className(多选模式) */
52
+ tag?: string;
53
+ /** 空状态的 className */
54
+ empty?: string;
55
+ /** 异常态的 className */
56
+ error?: string;
57
+ /** 加载状态的 className */
58
+ loading?: string;
59
+ /** 清除按钮元素的 className */
60
+ clear?: string;
61
+ /** 后缀元素的 className */
62
+ suffix?: string;
63
+ };
64
+
65
+ /**
66
+ * 弹层容器配置
67
+ */
68
+ export type PopoverSlotProps = {
69
+ popover?: React.ComponentProps<typeof PopoverContent>;
70
+ };
71
+
72
+ /**
73
+ * 基础 Select 组件共享的 Props
74
+ * 适用于 UserSelect、DepartmentSelect 等所有实体选择器
75
+ */
76
+ export type BaseEntitySelectProps<TValue = ItemValue<unknown>> = {
77
+ /**
78
+ * 组件尺寸
79
+ * @default "medium"
80
+ */
81
+ size?: 'medium' | 'small' | 'xs';
82
+
83
+ /**
84
+ * 触发器类型
85
+ * - "button": 按钮样式触发器
86
+ * - "search": 搜索框样式触发器
87
+ * - "custom": 自定义触发器,需配合 renderTrigger 使用
88
+ */
89
+ triggerType?: TriggerType;
90
+
91
+ /**
92
+ * 自定义渲染触发器
93
+ * @param props - 触发器渲染属性,包含选中值、多选状态、展开状态、禁用状态
94
+ * @returns 自定义触发器的 ReactNode
95
+ */
96
+ renderTrigger?: (props: TriggerRenderProps<unknown>) => ReactNode;
97
+
98
+ /**
99
+ * 是否多选模式
100
+ * @default false
101
+ */
102
+ multiple?: boolean;
103
+
104
+ /**
105
+ * 当前选中的值(受控模式)
106
+ * - 单选时为 TValue | null
107
+ * - 多选时为 TValue[] | null
108
+ */
109
+ value?: TValue | TValue[] | null;
110
+
111
+ /**
112
+ * 默认选中的值(非受控模式)
113
+ * - 单选时为 TValue | null
114
+ * - 多选时为 TValue[] | null
115
+ */
116
+ defaultValue?: TValue | TValue[] | null;
117
+
118
+ /**
119
+ * 选中值变化时的回调
120
+ * @param value - 新的选中值
121
+ */
122
+ onChange?: (value: TValue | TValue[] | null) => void;
123
+
124
+ /**
125
+ * 弹层默认是否展开(非受控模式)
126
+ * @default false
127
+ */
128
+ defaultOpen?: boolean;
129
+
130
+ /**
131
+ * 是否禁用组件
132
+ * @default false
133
+ */
134
+ disabled?: boolean;
135
+
136
+ /**
137
+ * 是否自动聚焦
138
+ * @default false
139
+ */
140
+ autoFocus?: boolean;
141
+
142
+ /**
143
+ * 是否必填(用于表单校验)
144
+ * @default false
145
+ */
146
+ required?: boolean;
147
+
148
+ /**
149
+ * 表单字段名称
150
+ */
151
+ name?: string;
152
+
153
+ /**
154
+ * 根元素的自定义类名
155
+ */
156
+ className?: string;
157
+
158
+ /**
159
+ * 各元素的自定义类名配置
160
+ * @example
161
+ * classNames={{
162
+ * root: 'my-root',
163
+ * trigger: 'my-trigger',
164
+ * popover: 'my-popover',
165
+ * tag: 'my-tag',
166
+ * }}
167
+ */
168
+ classNames?: ClassNamesConfig;
169
+
170
+ /**
171
+ * 未选中时显示的占位文本
172
+ */
173
+ placeholder?: string;
174
+
175
+ /**
176
+ * 选项列表为空时显示的文本
177
+ */
178
+ emptyText?: string;
179
+
180
+ /**
181
+ * 多选模式下,标签是否可关闭(显示删除按钮)
182
+ * @default true
183
+ */
184
+ tagClosable?: boolean;
185
+
186
+ /**
187
+ * 多选模式下,最多显示的标签数量
188
+ * - 数字: 最多显示指定数量的标签,超出部分显示 "+N"
189
+ * - "responsive": 根据容器宽度自动计算显示数量
190
+ */
191
+ maxTagCount?: number | 'responsive';
192
+
193
+ /**
194
+ * 判断选项是否禁用
195
+ * @param value 选项值
196
+ * @returns 如果返回 true,该选项将被禁用,不能改变选中状态,已选中项的 tag 不显示删除按钮
197
+ */
198
+ getOptionDisabled?: (value: TValue) => boolean;
199
+
200
+ /**
201
+ * 选中选项时的回调
202
+ * @param value - 被选中的选项值
203
+ */
204
+ onSelect?: (value: TValue) => void;
205
+
206
+ /**
207
+ * 取消选中选项时的回调(多选模式下生效)
208
+ * @param value - 被取消选中的选项值
209
+ */
210
+ onDeselect?: (value: TValue) => void;
211
+
212
+ /**
213
+ * 清空所有选中值时的回调
214
+ */
215
+ onClear?: () => void;
216
+
217
+ /**
218
+ * 组件获得焦点时的回调
219
+ * @param event - 焦点事件对象
220
+ */
221
+ onFocus?: (event: FocusEvent<HTMLElement>) => void;
222
+
223
+ /**
224
+ * 组件失去焦点时的回调
225
+ * @param event - 焦点事件对象
226
+ */
227
+ onBlur?: (event: FocusEvent<HTMLElement>) => void;
228
+
229
+ /**
230
+ * 插槽属性配置,用于自定义内部组件的 props
231
+ */
232
+ slotProps?: PopoverSlotProps;
233
+ };
234
+
235
+ /**
236
+ * Combobox 配置相关的 Props
237
+ */
238
+ export type ComboboxConfigProps = {
239
+ pageSize?: number;
240
+ debounce?: number;
241
+ disabled?: boolean;
242
+ loading?: boolean;
243
+ autoFocus?: boolean;
244
+ showSearch?: boolean;
245
+ required?: boolean;
246
+ name?: string;
247
+ };
248
+
249
+ /**
250
+ * Combobox 样式相关的 Props
251
+ */
252
+ export type ComboboxStyleProps = {
253
+ className?: string;
254
+ popoverClassName?: string;
255
+ classNames?: ClassNamesConfig;
256
+ };
257
+
258
+ /**
259
+ * Combobox Placeholder 相关的 Props
260
+ */
261
+ export type ComboboxPlaceholderProps = {
262
+ placeholder?: string;
263
+ searchPlaceholder?: string;
264
+ emptyText?: string;
265
+ loadingText?: string;
266
+ };
267
+
268
+ /**
269
+ * Combobox 标签相关的 Props
270
+ */
271
+ export type ComboboxTagProps = {
272
+ tagClosable?: boolean;
273
+ maxTagCount?: number | 'responsive';
274
+ maxTagTextLength?: number;
275
+ };
276
+
277
+ /**
278
+ * Combobox 弹层配置相关的 Props
279
+ */
280
+ export type ComboboxPopoverProps = {
281
+ placement?: 'top' | 'bottom' | 'left' | 'right';
282
+ align?: 'start' | 'center' | 'end';
283
+ sideOffset?: number;
284
+ };
285
+
286
+ /**
287
+ * Combobox 回调相关的 Props
288
+ */
289
+ export type ComboboxCallbackProps<TRaw = unknown> = {
290
+ onSelect?: (value: ItemValue<TRaw>) => void;
291
+ onDeselect?: (value: ItemValue<TRaw>) => void;
292
+ onSearch?: (value: string) => void;
293
+ onClear?: () => void;
294
+ onFocus?: (event: FocusEvent<HTMLElement>) => void;
295
+ onBlur?: (event: FocusEvent<HTMLElement>) => void;
296
+ };
@@ -0,0 +1,322 @@
1
+ import { cva } from 'class-variance-authority';
2
+
3
+ /**
4
+ * Combobox 尺寸类型
5
+ * - medium: 默认大小,适用于大多数场景
6
+ * - small: 较小尺寸
7
+ * - xs: 最小尺寸
8
+ */
9
+ export type ComboboxSize = 'medium' | 'small' | 'xs';
10
+
11
+ /**
12
+ * Search 模式下的搜索框容器样式
13
+ * medium: 高度36px, padding上下6px左右6px
14
+ * small: 高度32px, padding上下4px左右4px
15
+ * xs: 高度28px, padding上下4px左右4px
16
+ */
17
+ export const searchTriggerVariants = cva(
18
+ [
19
+ 'border-input bg-background',
20
+ 'flex w-full cursor-pointer items-center gap-1 rounded-md border',
21
+ 'hover:border-ring',
22
+ 'focus-visible:ring-3 focus-visible:ring-ring/20',
23
+ 'data-[state=open]:ring-3 data-[state=open]:ring-ring/20',
24
+ 'disabled:cursor-not-allowed disabled:opacity-50',
25
+ 'focus-visible:border-ring focus-visible:outline-none data-[state=open]:border-ring',
26
+ ],
27
+ {
28
+ variants: {
29
+ size: {
30
+ medium: 'min-h-9 px-3 py-1.5 text-sm', // 36px, padding 12px
31
+ small: 'min-h-8 px-3 py-1 text-sm', // 32px, padding 12px
32
+ xs: 'min-h-7 px-2 py-1 text-xs', // 28px, padding 8px
33
+ },
34
+ },
35
+ defaultVariants: {
36
+ size: 'medium',
37
+ },
38
+ },
39
+ );
40
+
41
+ /**
42
+ * Search 模式下输入框文字样式
43
+ * medium/small: text-sm
44
+ * xs: text-xs
45
+ */
46
+ export const searchInputVariants = cva('', {
47
+ variants: {
48
+ size: {
49
+ medium: 'text-sm',
50
+ small: 'text-sm',
51
+ xs: 'text-xs',
52
+ },
53
+ },
54
+ defaultVariants: {
55
+ size: 'medium',
56
+ },
57
+ });
58
+
59
+ /**
60
+ * Search 模式下的标签样式
61
+ * medium/small: 高度24px, 头像20px, 文字text-sm line-height 22px
62
+ * xs: 高度20px, 头像16px, 文字text-xs line-height 16px
63
+ */
64
+ export const searchTagVariants = cva('gap-1 pr-1 font-normal', {
65
+ variants: {
66
+ size: {
67
+ medium: 'h-6 text-sm leading-[22px]', // 24px
68
+ small: 'h-6 text-sm leading-[22px]', // 24px
69
+ xs: 'h-5 text-xs leading-4', // 20px
70
+ },
71
+ },
72
+ defaultVariants: {
73
+ size: 'medium',
74
+ },
75
+ });
76
+
77
+ /**
78
+ * 标签内头像尺寸
79
+ * medium/small: 20px
80
+ * xs: 16px
81
+ */
82
+ export const tagAvatarVariants = cva('', {
83
+ variants: {
84
+ size: {
85
+ medium: 'size-5', // 20px
86
+ small: 'size-5', // 20px
87
+ xs: 'size-4', // 16px
88
+ },
89
+ },
90
+ defaultVariants: {
91
+ size: 'medium',
92
+ },
93
+ });
94
+
95
+ /**
96
+ * 标签内图标尺寸 (如部门图标)
97
+ * medium/small: 16px
98
+ * xs: 12px
99
+ */
100
+ export const tagIconVariants = cva('', {
101
+ variants: {
102
+ size: {
103
+ medium: 'size-5', // 16px
104
+ small: 'size-5', // 16px
105
+ xs: 'size-4', // 12px
106
+ },
107
+ },
108
+ defaultVariants: {
109
+ size: 'medium',
110
+ },
111
+ });
112
+
113
+ /**
114
+ * 标签内关闭按钮图标尺寸
115
+ */
116
+ export const tagCloseIconVariants = cva('text-foreground', {
117
+ variants: {
118
+ size: {
119
+ medium: 'size-2.5', // 10px
120
+ small: 'size-2.5', // 10px
121
+ xs: 'size-2', // 8px
122
+ },
123
+ },
124
+ defaultVariants: {
125
+ size: 'medium',
126
+ },
127
+ });
128
+
129
+ /**
130
+ * Button 模式下的添加按钮样式
131
+ * medium/small: 24px
132
+ * xs: 16px
133
+ */
134
+ export const addButtonVariants = cva(
135
+ [
136
+ 'shrink-0 rounded-full p-0',
137
+ 'bg-neutral-700/10 hover:bg-neutral-700/20! dark:bg-neutral-500/10 dark:hover:bg-neutral-500/20!',
138
+ 'data-[state=open]:bg-neutral-700/20 dark:data-[state=open]:bg-neutral-500/20',
139
+ ],
140
+ {
141
+ variants: {
142
+ size: {
143
+ medium: 'size-6', // 24px
144
+ small: 'size-6', // 24px
145
+ xs: 'size-4', // 16px
146
+ },
147
+ },
148
+ defaultVariants: {
149
+ size: 'medium',
150
+ },
151
+ },
152
+ );
153
+
154
+ /**
155
+ * Button 模式下的加号图标尺寸
156
+ */
157
+ export const addButtonIconVariants = cva('', {
158
+ variants: {
159
+ size: {
160
+ medium: 'size-4', // 16px
161
+ small: 'size-4', // 16px
162
+ xs: 'size-2', // 8px
163
+ },
164
+ },
165
+ defaultVariants: {
166
+ size: 'medium',
167
+ },
168
+ });
169
+
170
+ /**
171
+ * 列表项容器样式
172
+ * medium/small: 高度50px
173
+ * xs: 高度46px
174
+ */
175
+ export const listItemVariants = cva('flex items-center gap-2', {
176
+ variants: {
177
+ size: {
178
+ medium: 'h-[50px] py-2', // 50px
179
+ small: 'h-[50px] py-2', // 50px
180
+ xs: 'h-[46px] py-1.5', // 46px
181
+ },
182
+ },
183
+ defaultVariants: {
184
+ size: 'medium',
185
+ },
186
+ });
187
+
188
+ /**
189
+ * 列表项头像尺寸
190
+ * medium/small: 32px
191
+ * xs: 28px
192
+ */
193
+ export const listItemAvatarVariants = cva('', {
194
+ variants: {
195
+ size: {
196
+ medium: 'size-8', // 32px
197
+ small: 'size-8', // 32px
198
+ xs: 'size-7', // 28px
199
+ },
200
+ },
201
+ defaultVariants: {
202
+ size: 'medium',
203
+ },
204
+ });
205
+
206
+ /**
207
+ * 列表项名称文字样式
208
+ * medium/small: text-sm, line-height 22px
209
+ * xs: text-xs, line-height 16px
210
+ */
211
+ export const listItemNameVariants = cva('truncate', {
212
+ variants: {
213
+ size: {
214
+ medium: 'text-sm leading-[22px]',
215
+ small: 'text-sm leading-[22px]',
216
+ xs: 'text-xs leading-4',
217
+ },
218
+ },
219
+ defaultVariants: {
220
+ size: 'medium',
221
+ },
222
+ });
223
+
224
+ /**
225
+ * 列表项副文本样式 (如 userId)
226
+ * 所有尺寸: text-xs, line-height 16px
227
+ */
228
+ export const listItemSubTextVariants = cva(
229
+ 'truncate leading-4 text-muted-foreground',
230
+ {
231
+ variants: {
232
+ size: {
233
+ medium: 'text-xs',
234
+ small: 'text-xs',
235
+ xs: 'text-[10px]',
236
+ },
237
+ },
238
+ defaultVariants: {
239
+ size: 'medium',
240
+ },
241
+ },
242
+ );
243
+
244
+ /**
245
+ * ItemPill 标签组件样式 (用于 tag 渲染)
246
+ */
247
+ export const itemPillVariants = cva(
248
+ [
249
+ 'w-fit gap-1 rounded-full border-0 bg-[#E8E8E9] font-normal dark:bg-[#3D3E3E]',
250
+ 'pt-px pb-px pl-0.5',
251
+ ],
252
+ {
253
+ variants: {
254
+ size: {
255
+ medium: 'h-[22px] pr-2 text-sm leading-5 [&>svg]:size-5', // 24px
256
+ small: 'h-[22px] pr-2 text-sm leading-5 [&>svg]:size-5', // 24px
257
+ xs: 'h-5 pr-1.5 text-xs leading-4 [&>svg]:size-4', // 20px
258
+ },
259
+ },
260
+ defaultVariants: {
261
+ size: 'medium',
262
+ },
263
+ },
264
+ );
265
+
266
+ /**
267
+ * ItemPill 内文本样式
268
+ */
269
+ export const itemPillTextVariants = cva(
270
+ 'max-w-[120px] truncate text-foreground',
271
+ {
272
+ variants: {
273
+ size: {
274
+ medium: 'text-sm leading-5',
275
+ small: 'text-sm leading-5',
276
+ xs: 'text-xs leading-4',
277
+ },
278
+ },
279
+ defaultVariants: {
280
+ size: 'medium',
281
+ },
282
+ },
283
+ );
284
+
285
+ /**
286
+ * 列表骨架屏项容器样式 (与 listItemVariants 保持一致)
287
+ * medium/small: 高度50px
288
+ * xs: 高度46px
289
+ */
290
+ export const skeletonItemVariants = cva(
291
+ 'flex items-center gap-2 rounded-sm px-2',
292
+ {
293
+ variants: {
294
+ size: {
295
+ medium: 'h-[50px] py-3.5', // 50px
296
+ small: 'h-[50px] py-3.5', // 50px
297
+ xs: 'h-[46px] py-1.5', // 46px
298
+ },
299
+ },
300
+ defaultVariants: {
301
+ size: 'medium',
302
+ },
303
+ },
304
+ );
305
+
306
+ /**
307
+ * 列表骨架屏头像尺寸 (与 listItemAvatarVariants 保持一致)
308
+ * medium/small: 32px
309
+ * xs: 28px
310
+ */
311
+ export const skeletonAvatarVariants = cva('rounded-full', {
312
+ variants: {
313
+ size: {
314
+ medium: 'size-8', // 32px
315
+ small: 'size-8', // 32px
316
+ xs: 'size-7', // 28px
317
+ },
318
+ },
319
+ defaultVariants: {
320
+ size: 'medium',
321
+ },
322
+ });