@baishuyun/ai-design 2.0.38 → 2.1.0-alpha.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 (269) hide show
  1. package/.storybook/main.ts +31 -31
  2. package/.storybook/preview.ts +16 -16
  3. package/CHANGELOG.md +512 -501
  4. package/components.json +22 -22
  5. package/package.json +9 -6
  6. package/scripts/strip-layers.cjs +41 -41
  7. package/src/components/abs-fullscreen-gradient-bg.tsx +35 -35
  8. package/src/components/agent-helper/agent-category-select-menu/index.tsx +57 -57
  9. package/src/components/agent-helper/agent-entry-card/index.tsx +94 -94
  10. package/src/components/agent-helper/agent-helper-card/index.tsx +179 -179
  11. package/src/components/agent-helper/agent-helper-card-list/index.tsx +59 -59
  12. package/src/components/agent-helper/agent-helper-main-layout/index.tsx +60 -60
  13. package/src/components/agent-helper/agent-sort-select/index.tsx +89 -89
  14. package/src/components/agent-helper/agent-tag/index.tsx +29 -29
  15. package/src/components/agent-helper/app-select/index.tsx +559 -559
  16. package/src/components/agent-helper/condition-group/index.tsx +75 -75
  17. package/src/components/agent-helper/condition-input/index.tsx +233 -233
  18. package/src/components/agent-helper/condition-item/index.tsx +237 -237
  19. package/src/components/agent-helper/condition-quantifier-select/index.tsx +142 -142
  20. package/src/components/agent-helper/condition-trigger-description/index.tsx +49 -49
  21. package/src/components/agent-helper/date-picker/calendar-panel.tsx +164 -164
  22. package/src/components/agent-helper/date-picker/date-input.tsx +91 -91
  23. package/src/components/agent-helper/date-picker/date-picker.tsx +327 -327
  24. package/src/components/agent-helper/date-picker/footer-panel.tsx +44 -44
  25. package/src/components/agent-helper/date-picker/index.ts +3 -3
  26. package/src/components/agent-helper/date-picker/month-panel.tsx +82 -82
  27. package/src/components/agent-helper/date-picker/time-panel.tsx +146 -146
  28. package/src/components/agent-helper/date-picker/types.ts +37 -37
  29. package/src/components/agent-helper/date-picker/utils.ts +121 -121
  30. package/src/components/agent-helper/date-picker/year-panel.tsx +86 -86
  31. package/src/components/agent-helper/exec-log-filter/index.tsx +232 -232
  32. package/src/components/agent-helper/field-edit-preference-select/index.tsx +291 -291
  33. package/src/components/agent-helper/field-select/index.tsx +466 -466
  34. package/src/components/agent-helper/field-value-input/china-address-data.ts +4117 -4117
  35. package/src/components/agent-helper/field-value-input/display.tsx +71 -71
  36. package/src/components/agent-helper/field-value-input/icons.tsx +38 -38
  37. package/src/components/agent-helper/field-value-input/index.tsx +144 -144
  38. package/src/components/agent-helper/field-value-input/inputs.tsx +247 -247
  39. package/src/components/agent-helper/field-value-input/picker-inputs.tsx +1141 -1141
  40. package/src/components/agent-helper/flow-node-action-trigger-select/index.tsx +57 -57
  41. package/src/components/agent-helper/form-action-trigger-select/index.tsx +60 -60
  42. package/src/components/agent-helper/form-divider/index.tsx +44 -44
  43. package/src/components/agent-helper/form-select/index.tsx +732 -732
  44. package/src/components/agent-helper/monthdays-select/index.tsx +378 -378
  45. package/src/components/agent-helper/offset-preference-select/index.tsx +268 -268
  46. package/src/components/agent-helper/offset-type-select/index.tsx +66 -66
  47. package/src/components/agent-helper/offset-unit-select/index.tsx +54 -54
  48. package/src/components/agent-helper/placeholder-card/index.tsx +75 -75
  49. package/src/components/agent-helper/prompt-input/index.tsx +646 -646
  50. package/src/components/agent-helper/relational-operator-select/index.tsx +179 -179
  51. package/src/components/agent-helper/repeat-by-type-select/index.tsx +53 -53
  52. package/src/components/agent-helper/repeat-preference-select/index.tsx +162 -162
  53. package/src/components/agent-helper/repeat-preference-type-select/index.tsx +58 -58
  54. package/src/components/agent-helper/search-input/index.tsx +35 -35
  55. package/src/components/agent-helper/table/index.tsx +114 -114
  56. package/src/components/agent-helper/trigger-select/index.tsx +121 -121
  57. package/src/components/agent-helper/trigger-time-preference-select/index.tsx +189 -189
  58. package/src/components/agent-helper/trigger-time-source-type-select/index.tsx +53 -53
  59. package/src/components/agent-helper/weekdays-select/index.tsx +230 -230
  60. package/src/components/agent-scroll-selector.tsx +193 -193
  61. package/src/components/agent-select.tsx +154 -154
  62. package/src/components/attachment-part-group.tsx +35 -35
  63. package/src/components/attachment-part.tsx +296 -296
  64. package/src/components/attachments-previewer.tsx +272 -272
  65. package/src/components/base-button.tsx +49 -49
  66. package/src/components/border-animation.tsx +107 -107
  67. package/src/components/border-color-animation.tsx +66 -66
  68. package/src/components/bot-avatar-name.tsx +36 -36
  69. package/src/components/bot-icon.tsx +23 -23
  70. package/src/components/bs-entry-select/app-group-folder.tsx +61 -61
  71. package/src/components/bs-entry-select/bs-entry-select.tsx +296 -296
  72. package/src/components/bs-entry-select/build-tree.ts +265 -265
  73. package/src/components/bs-entry-select/entry-item.tsx +45 -45
  74. package/src/components/bs-entry-select/entry-popover.tsx +99 -99
  75. package/src/components/bs-entry-select/index.ts +7 -7
  76. package/src/components/bs-entry-select/other-app-section.tsx +96 -96
  77. package/src/components/bs-entry-select/scroll-slider.tsx +872 -872
  78. package/src/components/bs-entry-select/search-input.tsx +4 -4
  79. package/src/components/bs-entry-select/tree-item-node.tsx +84 -84
  80. package/src/components/bs-entry-select/types.ts +46 -46
  81. package/src/components/bs-icons.tsx +1362 -1362
  82. package/src/components/card-field.tsx +23 -23
  83. package/src/components/card.tsx +36 -36
  84. package/src/components/chat-area-header.tsx +65 -65
  85. package/src/components/check-card.tsx +77 -77
  86. package/src/components/circle-checker.tsx +66 -66
  87. package/src/components/collapsible-txt-msg.tsx +75 -75
  88. package/src/components/collapsible.tsx +9 -9
  89. package/src/components/confirm-dialog.tsx +139 -139
  90. package/src/components/date-range-picker.tsx +91 -91
  91. package/src/components/fake-bot-msg.tsx +51 -51
  92. package/src/components/field-checker-list-msg.tsx +146 -146
  93. package/src/components/field-checker.tsx +185 -185
  94. package/src/components/field-icon.tsx +13 -13
  95. package/src/components/field-value-checker.tsx +116 -116
  96. package/src/components/fields-design-info-table.tsx +160 -160
  97. package/src/components/fields-generating-indicator.tsx +95 -95
  98. package/src/components/fields-portal.tsx +18 -18
  99. package/src/components/fields-previewer.tsx +216 -216
  100. package/src/components/font-icon.tsx +65 -65
  101. package/src/components/form-info-editor.tsx +263 -263
  102. package/src/components/formula-tag.tsx +32 -32
  103. package/src/components/generate-animation.tsx +56 -56
  104. package/src/components/icon-btn.tsx +43 -43
  105. package/src/components/icon-card.tsx +67 -67
  106. package/src/components/icons/calendar-icon.tsx +5 -5
  107. package/src/components/icons/clear-all-icon.tsx +5 -5
  108. package/src/components/icons/empty-agent-icon.tsx +93 -93
  109. package/src/components/icons/empty-table-icon.tsx +104 -104
  110. package/src/components/icons/grids-icon.tsx +5 -5
  111. package/src/components/img-part.tsx +27 -27
  112. package/src/components/legacy-slot.tsx +110 -110
  113. package/src/components/line-checker.tsx +168 -168
  114. package/src/components/linear-gradient-border-btn.tsx +48 -48
  115. package/src/components/linear-gradient-color-bg-animation.tsx +103 -103
  116. package/src/components/memoized-markdown.tsx +32 -32
  117. package/src/components/message-content.tsx +21 -21
  118. package/src/components/number-part.tsx +46 -46
  119. package/src/components/office-container.tsx +289 -289
  120. package/src/components/option-item.tsx +27 -27
  121. package/src/components/output-config-editor.tsx +478 -478
  122. package/src/components/previewer-header.tsx +270 -270
  123. package/src/components/primary-confirm-btn.tsx +58 -58
  124. package/src/components/primary-entry-btn.tsx +48 -48
  125. package/src/components/radio-card.tsx +63 -63
  126. package/src/components/scroll-to-bottom-btn.tsx +28 -28
  127. package/src/components/split-line.tsx +9 -9
  128. package/src/components/square-checker.tsx +87 -87
  129. package/src/components/subform-fields-value-checker.tsx +184 -184
  130. package/src/components/tab-radio-group.tsx +83 -83
  131. package/src/components/tooltip.tsx +53 -53
  132. package/src/components/ui/button.tsx +51 -51
  133. package/src/components/ui/calendar.tsx +57 -57
  134. package/src/components/ui/dialog.tsx +104 -104
  135. package/src/components/ui/drawer.tsx +279 -279
  136. package/src/components/ui/form.tsx +202 -202
  137. package/src/components/ui/icons.tsx +1267 -1267
  138. package/src/components/ui/input.tsx +28 -28
  139. package/src/components/ui/label.tsx +30 -30
  140. package/src/components/ui/popover.tsx +85 -85
  141. package/src/components/ui/select.tsx +236 -236
  142. package/src/components/ui/spinner.tsx +17 -17
  143. package/src/components/ui/switch.tsx +33 -33
  144. package/src/components/ui/tabs.tsx +62 -62
  145. package/src/components/ui/textarea.tsx +28 -28
  146. package/src/components/ui/tooltip.tsx +53 -53
  147. package/src/components/user-txt-msg-bubble.tsx +47 -47
  148. package/src/components/warning-msg.tsx +27 -27
  149. package/src/const/ui.ts +119 -119
  150. package/src/css.d.ts +4 -4
  151. package/src/hooks/use-column-appear.ts +78 -78
  152. package/src/hooks/use-portal-container.ts +27 -27
  153. package/src/hooks/use-resizable-width.ts +129 -129
  154. package/src/hooks/use-select-popover-position.ts +74 -74
  155. package/src/hooks/use-shadow.ts +127 -127
  156. package/src/index.ts +226 -226
  157. package/src/lib/utils.ts +138 -138
  158. package/src/stories/AbsFullscreenGradientBg.stories.tsx +36 -36
  159. package/src/stories/AgentCategorySelectMenu.stories.tsx +33 -33
  160. package/src/stories/AgentEntryCard.stories.tsx +90 -90
  161. package/src/stories/AgentHelperCard.stories.tsx +105 -105
  162. package/src/stories/AgentHelperCardList.stories.tsx +120 -120
  163. package/src/stories/AgentHelperMainLayout.stories.tsx +71 -71
  164. package/src/stories/AgentScrollSelector.stories.tsx +95 -95
  165. package/src/stories/AgentSelect.stories.tsx +134 -134
  166. package/src/stories/AgentTag.stories.tsx +44 -44
  167. package/src/stories/AppSelect.stories.tsx +250 -250
  168. package/src/stories/AttachmentPart.stories.tsx +122 -122
  169. package/src/stories/AttachmentPartGroup.stories.tsx +152 -152
  170. package/src/stories/AttachmentsPreviewer.stories.tsx +306 -306
  171. package/src/stories/BaseButton.stories.tsx +33 -33
  172. package/src/stories/BorderAnimation.stories.tsx +116 -116
  173. package/src/stories/BorderColorAnimation.stories.tsx +63 -63
  174. package/src/stories/BotAvatarAndName.stories.ts +24 -24
  175. package/src/stories/BotIcon.stories.ts +22 -22
  176. package/src/stories/BsConditionInput.stories.tsx +460 -460
  177. package/src/stories/BsEntrySelect.stories.tsx +343 -343
  178. package/src/stories/BsTooltip.stories.tsx +32 -32
  179. package/src/stories/Card.stories.tsx +28 -28
  180. package/src/stories/CardField.stories.tsx +87 -87
  181. package/src/stories/ChatAreaHeader.stories.ts +26 -26
  182. package/src/stories/CheckCard.stories.tsx +114 -114
  183. package/src/stories/CircleChecker.stories.tsx +89 -89
  184. package/src/stories/CollapsibleTextMsg.stories.ts +44 -44
  185. package/src/stories/ConditionGroup.stories.tsx +216 -216
  186. package/src/stories/ConditionInput.stories.tsx +502 -502
  187. package/src/stories/ConditionItem.stories.tsx +163 -163
  188. package/src/stories/ConditonQuantifierSelect.stories.tsx +54 -54
  189. package/src/stories/ConditonTriggerDescription.stories.tsx +61 -61
  190. package/src/stories/ConfirmDialog.stories.tsx +123 -123
  191. package/src/stories/DataTable.stories.tsx +191 -191
  192. package/src/stories/DatePicker.stories.tsx +174 -174
  193. package/src/stories/ExecLogFilter.stories.tsx +145 -145
  194. package/src/stories/FakeBotMsg.stories.tsx +36 -36
  195. package/src/stories/FieldEditPreferenceSelect.stories.tsx +161 -161
  196. package/src/stories/FieldSelect.stories.tsx +228 -228
  197. package/src/stories/FieldValueInput.stories.tsx +442 -442
  198. package/src/stories/FlowNodeActionTriggerSelect.stories.tsx +80 -80
  199. package/src/stories/Form.stories.tsx +302 -302
  200. package/src/stories/FormActionTriggerSelect.stories.tsx +80 -80
  201. package/src/stories/FormDivider.stories.tsx +31 -31
  202. package/src/stories/FormInfoEditor.stories.tsx +173 -173
  203. package/src/stories/FormSelect.stories.tsx +222 -222
  204. package/src/stories/FormulaTag.stories.tsx +68 -68
  205. package/src/stories/GenerateAnimation.stories.ts +20 -20
  206. package/src/stories/IconBtn.stories.tsx +32 -32
  207. package/src/stories/IconCard.stories.tsx +35 -35
  208. package/src/stories/IconLib.tsx +45 -45
  209. package/src/stories/Icons.stories.ts +22 -22
  210. package/src/stories/ImgMsgPart.stories.tsx +42 -42
  211. package/src/stories/Input.stories.tsx +102 -102
  212. package/src/stories/Label.stories.tsx +66 -66
  213. package/src/stories/LegacySlot.stories.tsx +56 -56
  214. package/src/stories/LineChecker.stories.tsx +133 -133
  215. package/src/stories/LinearGradientBorderBtn.stories.tsx +86 -86
  216. package/src/stories/LinearGradientColorBgAnimation.stories.tsx +60 -60
  217. package/src/stories/MemoizedMarkdown.stories.tsx +102 -102
  218. package/src/stories/MessageContent.stories.tsx +36 -36
  219. package/src/stories/MonthdaysSelect.stories.tsx +78 -78
  220. package/src/stories/NumbersMsgPart.stories.tsx +42 -42
  221. package/src/stories/OfficeContainer.stories.tsx +287 -287
  222. package/src/stories/OffsetPreferenceSelect.stories.tsx +118 -118
  223. package/src/stories/OffsetTypeSelect.stories.tsx +75 -75
  224. package/src/stories/OffsetUnitSelect.stories.tsx +61 -61
  225. package/src/stories/OptionItem.stories.tsx +77 -77
  226. package/src/stories/OutputConfigEditor.stories.tsx +96 -96
  227. package/src/stories/PlaceholderCard.stories.tsx +35 -35
  228. package/src/stories/PreviewerHeader.stories.tsx +91 -91
  229. package/src/stories/PrimaryConfirmBtn.stories.tsx +60 -60
  230. package/src/stories/PrimaryEntryBtn.stories.tsx +74 -74
  231. package/src/stories/PromptInput.stories.tsx +228 -228
  232. package/src/stories/RadioCard.stories.tsx +103 -103
  233. package/src/stories/RelationalOperatorSelect.stories.tsx +61 -61
  234. package/src/stories/RepeatByTypeSelect.stories.tsx +58 -58
  235. package/src/stories/RepeatPreferenceSelect.stories.tsx +107 -107
  236. package/src/stories/RepeatPreferenceTypeSelect.stories.tsx +58 -58
  237. package/src/stories/ScrollToBottom.stories.tsx +24 -24
  238. package/src/stories/SearchInput.stories.tsx +50 -50
  239. package/src/stories/Select.stories.tsx +128 -128
  240. package/src/stories/SplitLine.stories.tsx +40 -40
  241. package/src/stories/SquareChecker.stories.tsx +96 -96
  242. package/src/stories/TabRadioGroup.stories.tsx +84 -84
  243. package/src/stories/Textarea.stories.tsx +67 -67
  244. package/src/stories/TriggerSelect.stories.tsx +48 -48
  245. package/src/stories/TriggerTimePreferenceSelect.stories.tsx +106 -106
  246. package/src/stories/TriggerTimeSourceTypeSelect.stories.tsx +68 -68
  247. package/src/stories/UserTextMsgBubble.stories.ts +24 -24
  248. package/src/stories/WarningMessage.stories.tsx +23 -23
  249. package/src/stories/WeekdaysSelect.stories.tsx +66 -66
  250. package/src/stories/assets/demo.css +539 -539
  251. package/src/stories/assets/demo_index.html +7988 -7988
  252. package/src/stories/assets/iconfont.css +1377 -1377
  253. package/src/stories/assets/iconfont.json +2382 -2382
  254. package/src/stories/assets/iconfont.svg +697 -697
  255. package/src/stories/collapsible.stories.tsx +47 -47
  256. package/src/stories/drawer.stories.tsx +196 -196
  257. package/src/stories/field-checker-list-msg.stories.tsx +95 -95
  258. package/src/stories/field-checker.stories.tsx +117 -117
  259. package/src/stories/field-icon.stories.tsx +70 -70
  260. package/src/stories/field-value-checker.stories.tsx +113 -113
  261. package/src/stories/fields-design-info-table.stories.tsx +203 -203
  262. package/src/stories/fields-generating.stories.tsx +41 -41
  263. package/src/stories/fields-previewer.stories.tsx +77 -77
  264. package/src/stories/subform-fields-value-checker.stories.tsx +98 -98
  265. package/src/style.css +226 -226
  266. package/src/types.ts +8 -8
  267. package/style.css +3652 -3652
  268. package/tsconfig.json +13 -13
  269. package/vite.config.ts +44 -44
@@ -1,442 +1,442 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { useState } from 'react';
3
- import type { FieldType, IField, IFieldValueService } from '@baishuyun/types';
4
-
5
- import { FieldValueInput } from '../components/agent-helper/field-value-input';
6
-
7
- // ── Mock Service ────────────────────────────────────────────────────
8
-
9
- const mockService: IFieldValueService = {
10
- searchUsers: async (keyword) => {
11
- await new Promise((r) => setTimeout(r, 500));
12
- const users = [
13
- { id: 'user1', name: '张三', avatar: '' },
14
- { id: 'user2', name: '李四', avatar: '' },
15
- { id: 'user3', name: '王五', avatar: '' },
16
- ];
17
- return keyword
18
- ? users.filter((u) => u.name.includes(keyword))
19
- : users;
20
- },
21
- searchDepts: async (keyword) => {
22
- await new Promise((r) => setTimeout(r, 500));
23
- const depts = [
24
- { id: 'dept1', name: '技术部' },
25
- { id: 'dept2', name: '产品部' },
26
- { id: 'dept3', name: '设计部' },
27
- ];
28
- return keyword
29
- ? depts.filter((d) => d.name.includes(keyword))
30
- : depts;
31
- },
32
- searchUserGroups: async (keyword) => {
33
- await new Promise((r) => setTimeout(r, 300));
34
- return keyword ? [{ id: 'g1', name: `组-${keyword}` }] : [{ id: 'g1', name: '管理组' }, { id: 'g2', name: '普通组' }];
35
- },
36
- searchDeptGroups: async (keyword) => {
37
- await new Promise((r) => setTimeout(r, 300));
38
- return keyword ? [{ id: 'dg1', name: `部门组-${keyword}` }] : [{ id: 'dg1', name: '研发中心' }];
39
- },
40
- uploadFile: async (_file) => {
41
- await new Promise((r) => setTimeout(r, 800));
42
- return { url: 'https://example.com/file.png', name: _file.name };
43
- },
44
- fetchLinkData: async () => {
45
- await new Promise((r) => setTimeout(r, 500));
46
- return [
47
- { label: '选项A', value: 'a' },
48
- { label: '选项B', value: 'b' },
49
- { label: '选项C', value: 'c' },
50
- ];
51
- },
52
- searchAddress: async (keyword) => {
53
- await new Promise((r) => setTimeout(r, 300));
54
- const addresses = [
55
- { province: '浙江省', city: '杭州市', district: '西湖区' },
56
- { province: '浙江省', city: '杭州市', district: '余杭区' },
57
- { province: '北京市', city: '北京市', district: '朝阳区' },
58
- ];
59
- return keyword
60
- ? addresses.filter((a) => a.province.includes(keyword) || a.city.includes(keyword) || a.district.includes(keyword))
61
- : addresses;
62
- },
63
- searchLocation: async (keyword) => {
64
- await new Promise((r) => setTimeout(r, 300));
65
- return [
66
- { province: '浙江省', city: '杭州市', district: '西湖区', detail: '文三路 123 号', lnglatXY: [120.15, 30.28] as [number, number] },
67
- { province: '北京市', city: '北京市', district: '朝阳区', detail: '望京 SOHO', lnglatXY: [116.48, 39.99] as [number, number] },
68
- ].filter((l) => !keyword || l.detail.includes(keyword));
69
- },
70
- searchDistinctValues: async (_field, keyword) => {
71
- await new Promise((r) => setTimeout(r, 400));
72
- const values = [
73
- { label: '苹果', value: 'apple' },
74
- { label: '香蕉', value: 'banana' },
75
- { label: '橙子', value: 'orange' },
76
- { label: '葡萄', value: 'grape' },
77
- { label: '西瓜', value: 'watermelon' },
78
- { label: '草莓', value: 'strawberry' },
79
- ];
80
- return keyword
81
- ? values.filter((v) => v.label.includes(keyword))
82
- : values;
83
- },
84
- };
85
-
86
- const Wrapper = ({ children }: { children: React.ReactNode }) => (
87
- <div className="w-[360px] p-[16px]">{children}</div>
88
- );
89
-
90
- // ── Field factory ───────────────────────────────────────────────────
91
-
92
- function makeField(
93
- type: FieldType,
94
- overrides?: Partial<IField>,
95
- ): IField {
96
- return {
97
- label: '示例字段',
98
- widget: {
99
- type: type as never,
100
- widgetName: 'example_field',
101
- value: '',
102
- items: [
103
- { label: '选项一', value: '1' },
104
- { label: '选项二', value: '2' },
105
- { label: '选项三', value: '3' },
106
- ],
107
- ...overrides?.widget,
108
- },
109
- ...overrides,
110
- } as IField;
111
- }
112
-
113
- // ── Meta ────────────────────────────────────────────────────────────
114
-
115
- const meta: Meta<typeof FieldValueInput> = {
116
- title: 'Agent Helper/FieldValueInput',
117
- component: FieldValueInput,
118
- tags: ['autodocs'],
119
- parameters: { layout: 'centered' },
120
- decorators: [(Story) => <Wrapper><Story /></Wrapper>],
121
- };
122
-
123
- export default meta;
124
- type Story = StoryObj<typeof FieldValueInput>;
125
-
126
- // ── Basic Inputs ────────────────────────────────────────────────────
127
-
128
- export const Text: Story = {
129
- args: {
130
- field: makeField('text', { label: '名称' }),
131
- },
132
- };
133
-
134
- export const TextRequired: Story = {
135
- args: {
136
- field: makeField('text', { label: '名称', widget: { type: 'text', widgetName: 'name', value: '', allowBlank: false } }),
137
- },
138
- };
139
-
140
- export const TextWithDescription: Story = {
141
- args: {
142
- field: makeField('text', { label: '名称', description: '请输入您的姓名' }),
143
- },
144
- };
145
-
146
- export const TextDisabled: Story = {
147
- args: {
148
- field: makeField('text', { label: '名称' }),
149
- value: '不可编辑的文本',
150
- disabled: true,
151
- },
152
- };
153
-
154
- export const NumberInput: Story = {
155
- args: {
156
- field: makeField('number', { label: '数量' }),
157
- },
158
- };
159
-
160
- export const NumberWithValue: Story = {
161
- args: {
162
- field: makeField('number', { label: '数量' }),
163
- value: 42,
164
- },
165
- };
166
-
167
- export const Textarea: Story = {
168
- args: {
169
- field: makeField('textarea', { label: '备注' }),
170
- },
171
- };
172
-
173
- export const Password: Story = {
174
- args: {
175
- field: makeField('password', { label: '密码' }),
176
- },
177
- };
178
-
179
- // ── Selection Inputs ────────────────────────────────────────────────
180
-
181
- export const Combo: Story = {
182
- args: {
183
- field: makeField('combo', { label: '下拉选择' }),
184
- },
185
- };
186
-
187
- export const LinkData: Story = {
188
- args: {
189
- field: makeField('linkdata', { label: '联动数据' }),
190
- service: mockService,
191
- },
192
- };
193
-
194
- export const CheckboxGroup: Story = {
195
- args: {
196
- field: makeField('checkboxgroup', { label: '多选框组' }),
197
- },
198
- };
199
-
200
- export const Combocheck: Story = {
201
- args: {
202
- field: makeField('combocheck', { label: '下拉多选' }),
203
- },
204
- };
205
-
206
- export const RadioGroup: Story = {
207
- args: {
208
- field: makeField('radiogroup', { label: '单选组' }),
209
- },
210
- };
211
-
212
- export const DateTime: Story = {
213
- args: {
214
- field: makeField('datetime', { label: '日期时间' }),
215
- },
216
- };
217
-
218
- // ── Async Pickers ───────────────────────────────────────────────────
219
-
220
- export const UserPicker: Story = {
221
- args: {
222
- field: makeField('user', { label: '负责人' }),
223
- service: mockService,
224
- },
225
- };
226
-
227
- export const DeptPicker: Story = {
228
- args: {
229
- field: makeField('dept', { label: '所属部门' }),
230
- service: mockService,
231
- },
232
- };
233
-
234
- export const UserGroupPicker: Story = {
235
- args: {
236
- field: makeField('usergroup', { label: '用户组' }),
237
- service: mockService,
238
- },
239
- };
240
-
241
- export const DeptGroupPicker: Story = {
242
- args: {
243
- field: makeField('deptgroup', { label: '部门组' }),
244
- service: mockService,
245
- },
246
- };
247
-
248
- // ── File & Media ────────────────────────────────────────────────────
249
-
250
- export const Upload: Story = {
251
- args: {
252
- field: makeField('upload', { label: '附件' }),
253
- service: mockService,
254
- },
255
- };
256
-
257
- export const Image: Story = {
258
- args: {
259
- field: makeField('image', { label: '图片' }),
260
- service: mockService,
261
- },
262
- };
263
-
264
- // ── Address & Location (cascading province/city/district) ────────────
265
-
266
- export const Address: Story = {
267
- args: {
268
- field: makeField('address', { label: '地址' }),
269
- },
270
- };
271
-
272
- export const AddressWithValue: Story = {
273
- args: {
274
- field: makeField('address', { label: '地址' }),
275
- value: { province: '浙江省', city: '杭州市', district: '西湖区' },
276
- },
277
- };
278
-
279
- export const Location_: Story = {
280
- args: {
281
- field: makeField('location', { label: '位置' }),
282
- },
283
- };
284
-
285
- export const LocationWithValue: Story = {
286
- args: {
287
- field: makeField('location', { label: '位置' }),
288
- value: { province: '北京市', city: '北京市', district: '朝阳区' },
289
- },
290
- };
291
-
292
- // ── Display ─────────────────────────────────────────────────────────
293
-
294
- export const Separator: Story = {
295
- args: {
296
- field: makeField('separator', { label: '分割线标题' }),
297
- },
298
- };
299
-
300
- export const SerialNumber: Story = {
301
- args: {
302
- field: makeField('sn', { label: '流水号' }),
303
- },
304
- };
305
-
306
- export const Button: Story = {
307
- args: {
308
- field: makeField('button', { label: '提交' }),
309
- },
310
- };
311
-
312
- export const Subform: Story = {
313
- args: {
314
- field: makeField('subform', { label: '子表单' }),
315
- },
316
- };
317
-
318
- // ── Operator-aware: Range Inputs ─────────────────────────────────────
319
-
320
- export const RangeNumber: Story = {
321
- args: {
322
- field: makeField('number', { label: '金额' }),
323
- operator: 'range',
324
- value: { min: 10, max: 100 },
325
- },
326
- };
327
-
328
- export const RangeDateTime: Story = {
329
- args: {
330
- field: makeField('datetime', { label: '日期范围' }),
331
- operator: 'range',
332
- value: { min: '2025-01-01T00:00', max: '2025-12-31T23:59' },
333
- },
334
- };
335
-
336
- // ── Operator-aware: Text Multi-select ────────────────────────────────
337
-
338
- export const TextMultiSelectIn: Story = {
339
- args: {
340
- field: makeField('text', { label: '水果选择' }),
341
- operator: 'in',
342
- service: mockService,
343
- value: ['apple', 'banana'],
344
- },
345
- };
346
-
347
- export const TextMultiSelectNin: Story = {
348
- args: {
349
- field: makeField('text', { label: '排除项' }),
350
- operator: 'nin',
351
- service: mockService,
352
- value: ['grape'],
353
- },
354
- };
355
-
356
- export const SnMultiSelectIn: Story = {
357
- args: {
358
- field: makeField('sn', { label: '流水号选择' }),
359
- operator: 'in',
360
- service: mockService,
361
- },
362
- };
363
-
364
- // ── Operator-aware: Async Picker Multi-select ─────────────────────────
365
-
366
- export const UserPickerMultiple: Story = {
367
- args: {
368
- field: makeField('user', { label: '负责人(多选)' }),
369
- operator: 'in',
370
- service: mockService,
371
- value: ['user1', 'user2'],
372
- },
373
- };
374
-
375
- export const DeptPickerMultiple: Story = {
376
- args: {
377
- field: makeField('dept', { label: '所属部门(多选)' }),
378
- operator: 'nin',
379
- service: mockService,
380
- value: ['dept1'],
381
- },
382
- };
383
-
384
- export const UserGroupPickerMultiple: Story = {
385
- args: {
386
- field: makeField('usergroup', { label: '用户组(多选)' }),
387
- operator: 'all',
388
- service: mockService,
389
- },
390
- };
391
-
392
- export const DeptGroupPickerMultiple: Story = {
393
- args: {
394
- field: makeField('deptgroup', { label: '部门组(多选)' }),
395
- operator: 'in',
396
- service: mockService,
397
- },
398
- };
399
-
400
- // ── Operator-aware: Text single value (no operator → default TextInput) ──
401
-
402
- export const TextWithOperatorEq: Story = {
403
- args: {
404
- field: makeField('text', { label: '关键字' }),
405
- operator: 'contains',
406
- value: '搜索关键词',
407
- },
408
- };
409
-
410
- export const NumberWithOperatorGt: Story = {
411
- args: {
412
- field: makeField('number', { label: '年龄' }),
413
- operator: 'gt',
414
- value: 18,
415
- },
416
- };
417
-
418
- export const DateTimeWithOperatorEq: Story = {
419
- args: {
420
- field: makeField('datetime', { label: '开始日期' }),
421
- operator: 'gte',
422
- value: '2025-01-01T00:00',
423
- },
424
- };
425
-
426
- // ── Controlled ──────────────────────────────────────────────────────
427
-
428
- export const Controlled: Story = {
429
- args: {
430
- field: makeField('text', { label: '受控字段' }),
431
- value: '受控值',
432
- },
433
- render: (args) => {
434
- const [value, setValue] = useState('受控值');
435
- return (
436
- <div className="flex flex-col gap-4">
437
- <FieldValueInput {...args} value={value} onChange={(v) => setValue(String(v ?? ''))} />
438
- <p className="text-[12px] text-[#666]">当前值: {value || '(空)'}</p>
439
- </div>
440
- );
441
- },
442
- };
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { useState } from 'react';
3
+ import type { FieldType, IField, IFieldValueService } from '@baishuyun/types';
4
+
5
+ import { FieldValueInput } from '../components/agent-helper/field-value-input';
6
+
7
+ // ── Mock Service ────────────────────────────────────────────────────
8
+
9
+ const mockService: IFieldValueService = {
10
+ searchUsers: async (keyword) => {
11
+ await new Promise((r) => setTimeout(r, 500));
12
+ const users = [
13
+ { id: 'user1', name: '张三', avatar: '' },
14
+ { id: 'user2', name: '李四', avatar: '' },
15
+ { id: 'user3', name: '王五', avatar: '' },
16
+ ];
17
+ return keyword
18
+ ? users.filter((u) => u.name.includes(keyword))
19
+ : users;
20
+ },
21
+ searchDepts: async (keyword) => {
22
+ await new Promise((r) => setTimeout(r, 500));
23
+ const depts = [
24
+ { id: 'dept1', name: '技术部' },
25
+ { id: 'dept2', name: '产品部' },
26
+ { id: 'dept3', name: '设计部' },
27
+ ];
28
+ return keyword
29
+ ? depts.filter((d) => d.name.includes(keyword))
30
+ : depts;
31
+ },
32
+ searchUserGroups: async (keyword) => {
33
+ await new Promise((r) => setTimeout(r, 300));
34
+ return keyword ? [{ id: 'g1', name: `组-${keyword}` }] : [{ id: 'g1', name: '管理组' }, { id: 'g2', name: '普通组' }];
35
+ },
36
+ searchDeptGroups: async (keyword) => {
37
+ await new Promise((r) => setTimeout(r, 300));
38
+ return keyword ? [{ id: 'dg1', name: `部门组-${keyword}` }] : [{ id: 'dg1', name: '研发中心' }];
39
+ },
40
+ uploadFile: async (_file) => {
41
+ await new Promise((r) => setTimeout(r, 800));
42
+ return { url: 'https://example.com/file.png', name: _file.name };
43
+ },
44
+ fetchLinkData: async () => {
45
+ await new Promise((r) => setTimeout(r, 500));
46
+ return [
47
+ { label: '选项A', value: 'a' },
48
+ { label: '选项B', value: 'b' },
49
+ { label: '选项C', value: 'c' },
50
+ ];
51
+ },
52
+ searchAddress: async (keyword) => {
53
+ await new Promise((r) => setTimeout(r, 300));
54
+ const addresses = [
55
+ { province: '浙江省', city: '杭州市', district: '西湖区' },
56
+ { province: '浙江省', city: '杭州市', district: '余杭区' },
57
+ { province: '北京市', city: '北京市', district: '朝阳区' },
58
+ ];
59
+ return keyword
60
+ ? addresses.filter((a) => a.province.includes(keyword) || a.city.includes(keyword) || a.district.includes(keyword))
61
+ : addresses;
62
+ },
63
+ searchLocation: async (keyword) => {
64
+ await new Promise((r) => setTimeout(r, 300));
65
+ return [
66
+ { province: '浙江省', city: '杭州市', district: '西湖区', detail: '文三路 123 号', lnglatXY: [120.15, 30.28] as [number, number] },
67
+ { province: '北京市', city: '北京市', district: '朝阳区', detail: '望京 SOHO', lnglatXY: [116.48, 39.99] as [number, number] },
68
+ ].filter((l) => !keyword || l.detail.includes(keyword));
69
+ },
70
+ searchDistinctValues: async (_field, keyword) => {
71
+ await new Promise((r) => setTimeout(r, 400));
72
+ const values = [
73
+ { label: '苹果', value: 'apple' },
74
+ { label: '香蕉', value: 'banana' },
75
+ { label: '橙子', value: 'orange' },
76
+ { label: '葡萄', value: 'grape' },
77
+ { label: '西瓜', value: 'watermelon' },
78
+ { label: '草莓', value: 'strawberry' },
79
+ ];
80
+ return keyword
81
+ ? values.filter((v) => v.label.includes(keyword))
82
+ : values;
83
+ },
84
+ };
85
+
86
+ const Wrapper = ({ children }: { children: React.ReactNode }) => (
87
+ <div className="w-[360px] p-[16px]">{children}</div>
88
+ );
89
+
90
+ // ── Field factory ───────────────────────────────────────────────────
91
+
92
+ function makeField(
93
+ type: FieldType,
94
+ overrides?: Partial<IField>,
95
+ ): IField {
96
+ return {
97
+ label: '示例字段',
98
+ widget: {
99
+ type: type as never,
100
+ widgetName: 'example_field',
101
+ value: '',
102
+ items: [
103
+ { label: '选项一', value: '1' },
104
+ { label: '选项二', value: '2' },
105
+ { label: '选项三', value: '3' },
106
+ ],
107
+ ...overrides?.widget,
108
+ },
109
+ ...overrides,
110
+ } as IField;
111
+ }
112
+
113
+ // ── Meta ────────────────────────────────────────────────────────────
114
+
115
+ const meta: Meta<typeof FieldValueInput> = {
116
+ title: 'Agent Helper/FieldValueInput',
117
+ component: FieldValueInput,
118
+ tags: ['autodocs'],
119
+ parameters: { layout: 'centered' },
120
+ decorators: [(Story) => <Wrapper><Story /></Wrapper>],
121
+ };
122
+
123
+ export default meta;
124
+ type Story = StoryObj<typeof FieldValueInput>;
125
+
126
+ // ── Basic Inputs ────────────────────────────────────────────────────
127
+
128
+ export const Text: Story = {
129
+ args: {
130
+ field: makeField('text', { label: '名称' }),
131
+ },
132
+ };
133
+
134
+ export const TextRequired: Story = {
135
+ args: {
136
+ field: makeField('text', { label: '名称', widget: { type: 'text', widgetName: 'name', value: '', allowBlank: false } }),
137
+ },
138
+ };
139
+
140
+ export const TextWithDescription: Story = {
141
+ args: {
142
+ field: makeField('text', { label: '名称', description: '请输入您的姓名' }),
143
+ },
144
+ };
145
+
146
+ export const TextDisabled: Story = {
147
+ args: {
148
+ field: makeField('text', { label: '名称' }),
149
+ value: '不可编辑的文本',
150
+ disabled: true,
151
+ },
152
+ };
153
+
154
+ export const NumberInput: Story = {
155
+ args: {
156
+ field: makeField('number', { label: '数量' }),
157
+ },
158
+ };
159
+
160
+ export const NumberWithValue: Story = {
161
+ args: {
162
+ field: makeField('number', { label: '数量' }),
163
+ value: 42,
164
+ },
165
+ };
166
+
167
+ export const Textarea: Story = {
168
+ args: {
169
+ field: makeField('textarea', { label: '备注' }),
170
+ },
171
+ };
172
+
173
+ export const Password: Story = {
174
+ args: {
175
+ field: makeField('password', { label: '密码' }),
176
+ },
177
+ };
178
+
179
+ // ── Selection Inputs ────────────────────────────────────────────────
180
+
181
+ export const Combo: Story = {
182
+ args: {
183
+ field: makeField('combo', { label: '下拉选择' }),
184
+ },
185
+ };
186
+
187
+ export const LinkData: Story = {
188
+ args: {
189
+ field: makeField('linkdata', { label: '联动数据' }),
190
+ service: mockService,
191
+ },
192
+ };
193
+
194
+ export const CheckboxGroup: Story = {
195
+ args: {
196
+ field: makeField('checkboxgroup', { label: '多选框组' }),
197
+ },
198
+ };
199
+
200
+ export const Combocheck: Story = {
201
+ args: {
202
+ field: makeField('combocheck', { label: '下拉多选' }),
203
+ },
204
+ };
205
+
206
+ export const RadioGroup: Story = {
207
+ args: {
208
+ field: makeField('radiogroup', { label: '单选组' }),
209
+ },
210
+ };
211
+
212
+ export const DateTime: Story = {
213
+ args: {
214
+ field: makeField('datetime', { label: '日期时间' }),
215
+ },
216
+ };
217
+
218
+ // ── Async Pickers ───────────────────────────────────────────────────
219
+
220
+ export const UserPicker: Story = {
221
+ args: {
222
+ field: makeField('user', { label: '负责人' }),
223
+ service: mockService,
224
+ },
225
+ };
226
+
227
+ export const DeptPicker: Story = {
228
+ args: {
229
+ field: makeField('dept', { label: '所属部门' }),
230
+ service: mockService,
231
+ },
232
+ };
233
+
234
+ export const UserGroupPicker: Story = {
235
+ args: {
236
+ field: makeField('usergroup', { label: '用户组' }),
237
+ service: mockService,
238
+ },
239
+ };
240
+
241
+ export const DeptGroupPicker: Story = {
242
+ args: {
243
+ field: makeField('deptgroup', { label: '部门组' }),
244
+ service: mockService,
245
+ },
246
+ };
247
+
248
+ // ── File & Media ────────────────────────────────────────────────────
249
+
250
+ export const Upload: Story = {
251
+ args: {
252
+ field: makeField('upload', { label: '附件' }),
253
+ service: mockService,
254
+ },
255
+ };
256
+
257
+ export const Image: Story = {
258
+ args: {
259
+ field: makeField('image', { label: '图片' }),
260
+ service: mockService,
261
+ },
262
+ };
263
+
264
+ // ── Address & Location (cascading province/city/district) ────────────
265
+
266
+ export const Address: Story = {
267
+ args: {
268
+ field: makeField('address', { label: '地址' }),
269
+ },
270
+ };
271
+
272
+ export const AddressWithValue: Story = {
273
+ args: {
274
+ field: makeField('address', { label: '地址' }),
275
+ value: { province: '浙江省', city: '杭州市', district: '西湖区' },
276
+ },
277
+ };
278
+
279
+ export const Location_: Story = {
280
+ args: {
281
+ field: makeField('location', { label: '位置' }),
282
+ },
283
+ };
284
+
285
+ export const LocationWithValue: Story = {
286
+ args: {
287
+ field: makeField('location', { label: '位置' }),
288
+ value: { province: '北京市', city: '北京市', district: '朝阳区' },
289
+ },
290
+ };
291
+
292
+ // ── Display ─────────────────────────────────────────────────────────
293
+
294
+ export const Separator: Story = {
295
+ args: {
296
+ field: makeField('separator', { label: '分割线标题' }),
297
+ },
298
+ };
299
+
300
+ export const SerialNumber: Story = {
301
+ args: {
302
+ field: makeField('sn', { label: '流水号' }),
303
+ },
304
+ };
305
+
306
+ export const Button: Story = {
307
+ args: {
308
+ field: makeField('button', { label: '提交' }),
309
+ },
310
+ };
311
+
312
+ export const Subform: Story = {
313
+ args: {
314
+ field: makeField('subform', { label: '子表单' }),
315
+ },
316
+ };
317
+
318
+ // ── Operator-aware: Range Inputs ─────────────────────────────────────
319
+
320
+ export const RangeNumber: Story = {
321
+ args: {
322
+ field: makeField('number', { label: '金额' }),
323
+ operator: 'range',
324
+ value: { min: 10, max: 100 },
325
+ },
326
+ };
327
+
328
+ export const RangeDateTime: Story = {
329
+ args: {
330
+ field: makeField('datetime', { label: '日期范围' }),
331
+ operator: 'range',
332
+ value: { min: '2025-01-01T00:00', max: '2025-12-31T23:59' },
333
+ },
334
+ };
335
+
336
+ // ── Operator-aware: Text Multi-select ────────────────────────────────
337
+
338
+ export const TextMultiSelectIn: Story = {
339
+ args: {
340
+ field: makeField('text', { label: '水果选择' }),
341
+ operator: 'in',
342
+ service: mockService,
343
+ value: ['apple', 'banana'],
344
+ },
345
+ };
346
+
347
+ export const TextMultiSelectNin: Story = {
348
+ args: {
349
+ field: makeField('text', { label: '排除项' }),
350
+ operator: 'nin',
351
+ service: mockService,
352
+ value: ['grape'],
353
+ },
354
+ };
355
+
356
+ export const SnMultiSelectIn: Story = {
357
+ args: {
358
+ field: makeField('sn', { label: '流水号选择' }),
359
+ operator: 'in',
360
+ service: mockService,
361
+ },
362
+ };
363
+
364
+ // ── Operator-aware: Async Picker Multi-select ─────────────────────────
365
+
366
+ export const UserPickerMultiple: Story = {
367
+ args: {
368
+ field: makeField('user', { label: '负责人(多选)' }),
369
+ operator: 'in',
370
+ service: mockService,
371
+ value: ['user1', 'user2'],
372
+ },
373
+ };
374
+
375
+ export const DeptPickerMultiple: Story = {
376
+ args: {
377
+ field: makeField('dept', { label: '所属部门(多选)' }),
378
+ operator: 'nin',
379
+ service: mockService,
380
+ value: ['dept1'],
381
+ },
382
+ };
383
+
384
+ export const UserGroupPickerMultiple: Story = {
385
+ args: {
386
+ field: makeField('usergroup', { label: '用户组(多选)' }),
387
+ operator: 'all',
388
+ service: mockService,
389
+ },
390
+ };
391
+
392
+ export const DeptGroupPickerMultiple: Story = {
393
+ args: {
394
+ field: makeField('deptgroup', { label: '部门组(多选)' }),
395
+ operator: 'in',
396
+ service: mockService,
397
+ },
398
+ };
399
+
400
+ // ── Operator-aware: Text single value (no operator → default TextInput) ──
401
+
402
+ export const TextWithOperatorEq: Story = {
403
+ args: {
404
+ field: makeField('text', { label: '关键字' }),
405
+ operator: 'contains',
406
+ value: '搜索关键词',
407
+ },
408
+ };
409
+
410
+ export const NumberWithOperatorGt: Story = {
411
+ args: {
412
+ field: makeField('number', { label: '年龄' }),
413
+ operator: 'gt',
414
+ value: 18,
415
+ },
416
+ };
417
+
418
+ export const DateTimeWithOperatorEq: Story = {
419
+ args: {
420
+ field: makeField('datetime', { label: '开始日期' }),
421
+ operator: 'gte',
422
+ value: '2025-01-01T00:00',
423
+ },
424
+ };
425
+
426
+ // ── Controlled ──────────────────────────────────────────────────────
427
+
428
+ export const Controlled: Story = {
429
+ args: {
430
+ field: makeField('text', { label: '受控字段' }),
431
+ value: '受控值',
432
+ },
433
+ render: (args) => {
434
+ const [value, setValue] = useState('受控值');
435
+ return (
436
+ <div className="flex flex-col gap-4">
437
+ <FieldValueInput {...args} value={value} onChange={(v) => setValue(String(v ?? ''))} />
438
+ <p className="text-[12px] text-[#666]">当前值: {value || '(空)'}</p>
439
+ </div>
440
+ );
441
+ },
442
+ };