@baishuyun/ai-design 2.1.0-alpha.4 → 2.1.3

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 (72) hide show
  1. package/.storybook/preview.ts +2 -0
  2. package/CHANGELOG.md +197 -28
  3. package/package.json +11 -11
  4. package/scripts/post-build.cjs +32 -0
  5. package/src/components/agent-drawer.tsx +119 -0
  6. package/src/components/agent-helper/agent-entry-card/index.tsx +3 -8
  7. package/src/components/agent-helper/agent-helper-card/index.tsx +3 -3
  8. package/src/components/agent-helper/app-select/index.tsx +119 -84
  9. package/src/components/agent-helper/condition-input/index.tsx +18 -21
  10. package/src/components/agent-helper/condition-item/index.tsx +1 -0
  11. package/src/components/agent-helper/field-edit-preference-select/index.tsx +31 -4
  12. package/src/components/agent-helper/field-value-input/dept-select.tsx +447 -0
  13. package/src/components/agent-helper/field-value-input/index.tsx +3 -2
  14. package/src/components/agent-helper/field-value-input/picker-inputs.tsx +20 -18
  15. package/src/components/agent-helper/form-select/index.tsx +12 -25
  16. package/src/components/agent-helper/relational-operator-select/index.tsx +37 -23
  17. package/src/components/agent-helper/table/index.tsx +6 -2
  18. package/src/components/agent-helper/team-wide-form-select/data-adapter.ts +109 -0
  19. package/src/components/agent-helper/team-wide-form-select/index.tsx +289 -0
  20. package/src/components/agent-helper/team-wide-form-select/tree-panel.tsx +180 -0
  21. package/src/components/agent-helper/team-wide-form-select/types.ts +36 -0
  22. package/src/components/agent-helper/team-wide-form-select/use-form-tree.ts +108 -0
  23. package/src/components/agent-helper/trigger-select/index.tsx +1 -1
  24. package/src/components/agent-select.tsx +115 -35
  25. package/src/components/bot-avatar-name.tsx +1 -1
  26. package/src/components/bs-entry-select/build-tree.ts +0 -6
  27. package/src/components/bs-entry-select/entry-item.tsx +7 -11
  28. package/src/components/bs-entry-select/other-app-section.tsx +2 -4
  29. package/src/components/bs-entry-select/scroll-slider.tsx +6 -11
  30. package/src/components/bs-icons.tsx +752 -206
  31. package/src/components/card.tsx +55 -10
  32. package/src/components/circle-checker.tsx +18 -3
  33. package/src/components/collapsible-txt-msg.tsx +18 -13
  34. package/src/components/fake-bot-msg.tsx +18 -7
  35. package/src/components/field-checker-list-msg.tsx +4 -3
  36. package/src/components/fields-design-info-table.tsx +9 -26
  37. package/src/components/fields-portal.tsx +2 -2
  38. package/src/components/fields-previewer.tsx +1 -0
  39. package/src/components/font-icon.tsx +20 -9
  40. package/src/components/form-info-editor.tsx +21 -6
  41. package/src/components/legacy-slot.tsx +11 -16
  42. package/src/components/memoized-markdown.tsx +32 -19
  43. package/src/components/message-content.tsx +7 -3
  44. package/src/components/output-config-editor.tsx +39 -25
  45. package/src/components/primary-confirm-btn.tsx +6 -1
  46. package/src/components/scroll-to-bottom-btn.tsx +3 -2
  47. package/src/components/shadow-content.tsx +19 -0
  48. package/src/components/shadow-portal.tsx +23 -0
  49. package/src/components/ui/dialog.tsx +4 -1
  50. package/src/components/ui/drawer.tsx +3 -1
  51. package/src/components/ui/enhanced-drawer.tsx +134 -0
  52. package/src/components/ui/popover.tsx +3 -2
  53. package/src/components/ui/select.tsx +3 -2
  54. package/src/components/ui/tooltip.tsx +3 -2
  55. package/src/components/user-txt-msg-bubble.tsx +41 -19
  56. package/src/components/warning-msg.tsx +29 -12
  57. package/src/const/shadow.ts +17 -0
  58. package/src/const/ui.ts +2 -2
  59. package/src/hooks/use-column-appear.ts +1 -1
  60. package/src/hooks/use-portal-container.ts +6 -3
  61. package/src/hooks/use-shadow-boundary.ts +67 -0
  62. package/src/hooks/use-shadow.ts +24 -7
  63. package/src/index.ts +21 -0
  64. package/src/stories/AppSelect.stories.tsx +44 -0
  65. package/src/stories/FieldValueInput.stories.tsx +6 -3
  66. package/src/stories/FormSelect.stories.tsx +40 -0
  67. package/src/stories/IconfontPicker.stories.tsx +106 -0
  68. package/src/stories/RelationalOperatorSelect.stories.tsx +27 -0
  69. package/src/stories/TeamWideFormSelect.stories.tsx +362 -0
  70. package/src/stories/UserTextMsgBubble.stories.ts +28 -0
  71. package/src/style.css +30 -1
  72. package/style.css +172 -130
@@ -1,5 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import { expect, userEvent, waitFor, within } from 'storybook/test';
3
4
  import { FormSelect } from '../components/agent-helper/form-select';
4
5
  import type { FormSelectItem, FormSelectChangeResult } from '../components/agent-helper/form-select';
5
6
 
@@ -91,6 +92,45 @@ export const ManyItems: Story = {
91
92
  },
92
93
  };
93
94
 
95
+ export const ConstrainedHeight: Story = {
96
+ args: { items: manyFormItems, allowEmpty: true },
97
+ play: async ({ canvasElement, args }) => {
98
+ if (!args.popoverOnly) {
99
+ await userEvent.click(within(canvasElement).getByText(/^(无|测试表单 30)$/));
100
+ }
101
+ const search = await within(canvasElement.ownerDocument.body).findByRole('textbox');
102
+ await userEvent.clear(search);
103
+ const content = search.parentElement!.parentElement!;
104
+ const list = content.lastElementChild as HTMLElement;
105
+ await waitFor(() => {
106
+ expect(content.getBoundingClientRect().height).toBeLessThanOrEqual(300);
107
+ expect(content.scrollHeight).toBeLessThanOrEqual(content.clientHeight);
108
+ expect(search.parentElement!.getBoundingClientRect().height).toBe(30);
109
+ expect(within(content).getByText('无').parentElement!.getBoundingClientRect().height).toBe(34);
110
+ expect(list.scrollHeight).toBeGreaterThan(list.clientHeight);
111
+ if (!args.popoverOnly) {
112
+ const portal = content.parentElement!;
113
+ expect(parseFloat(getComputedStyle(portal).maxHeight)).toBeLessThanOrEqual(300);
114
+ expect(content.getBoundingClientRect().bottom).toBeLessThanOrEqual(portal.getBoundingClientRect().bottom);
115
+ }
116
+ });
117
+ const searchTop = search.getBoundingClientRect().top;
118
+ list.scrollTop = list.scrollHeight;
119
+ expect(list.scrollTop).toBeGreaterThan(0);
120
+ expect(search.getBoundingClientRect().top).toBe(searchTop);
121
+ await userEvent.type(search, '测试表单 30');
122
+ await userEvent.click(within(content).getByText('测试表单 30'));
123
+ if (!args.popoverOnly) {
124
+ expect(within(canvasElement).getByText('测试表单 30')).toBeVisible();
125
+ }
126
+ },
127
+ };
128
+
129
+ export const PopoverOnlyConstrainedHeight: Story = {
130
+ ...ConstrainedHeight,
131
+ args: { ...ConstrainedHeight.args, popoverOnly: true },
132
+ };
133
+
94
134
  export const Empty: Story = {
95
135
  args: {
96
136
  items: [],
@@ -0,0 +1,106 @@
1
+ import { useMemo, useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import { FontIcon } from '../components/font-icon';
4
+ import { copyTextToClipboard } from '../lib/utils';
5
+ import { ICON_UNICODE_MAP, getIconUnicode } from '@baishuyun/ai-feat-utils';
6
+
7
+ /**
8
+ * iconfont(sdk-icon 字体)图标浏览:
9
+ * 枚举 ICON_UNICODE_MAP 全部命名图标,支持搜索、点击复制图标名,
10
+ * 方便给 <FontIcon code={getIconUnicode(name)} /> 选图标。
11
+ */
12
+ const IconfontPicker = () => {
13
+ const [keyword, setKeyword] = useState('');
14
+ const [copied, setCopied] = useState<string | null>(null);
15
+
16
+ const names = useMemo(() => {
17
+ const all = Object.keys(ICON_UNICODE_MAP);
18
+ const kw = keyword.trim().toLowerCase();
19
+ return kw ? all.filter((n) => n.toLowerCase().includes(kw)) : all;
20
+ }, [keyword]);
21
+
22
+ return (
23
+ <div style={{ padding: 16, maxWidth: 960 }}>
24
+ <input
25
+ value={keyword}
26
+ onChange={(e) => setKeyword(e.target.value)}
27
+ placeholder="搜索图标名(如 image / resourcelibrary / Scan)"
28
+ style={{
29
+ width: '100%',
30
+ height: 34,
31
+ padding: '0 10px',
32
+ marginBottom: 16,
33
+ border: '1px solid #E0E0E0',
34
+ borderRadius: 4,
35
+ fontSize: 14,
36
+ outline: 'none',
37
+ boxSizing: 'border-box',
38
+ }}
39
+ />
40
+ <div
41
+ style={{
42
+ display: 'grid',
43
+ gridTemplateColumns: 'repeat(auto-fill, minmax(96px, 1fr))',
44
+ gap: 8,
45
+ }}
46
+ >
47
+ {names.map((name) => (
48
+ <button
49
+ key={name}
50
+ type="button"
51
+ title={`点击复制:${name}`}
52
+ onClick={async () => {
53
+ await copyTextToClipboard(name);
54
+ setCopied(name);
55
+ setTimeout(() => setCopied((c) => (c === name ? null : c)), 800);
56
+ }}
57
+ style={{
58
+ display: 'flex',
59
+ flexDirection: 'column',
60
+ alignItems: 'center',
61
+ gap: 6,
62
+ padding: '12px 4px',
63
+ background: copied === name ? '#F0F6FF' : '#fff',
64
+ border: `1px solid ${copied === name ? '#0265FF' : '#E0E0E0'}`,
65
+ borderRadius: 8,
66
+ cursor: 'pointer',
67
+ }}
68
+ >
69
+ <FontIcon
70
+ code={getIconUnicode(name)}
71
+ style={{ fontSize: 22, lineHeight: 1, color: '#121111' }}
72
+ />
73
+ <span
74
+ style={{
75
+ fontSize: 11,
76
+ color: '#666',
77
+ wordBreak: 'break-all',
78
+ textAlign: 'center',
79
+ lineHeight: 1.2,
80
+ }}
81
+ >
82
+ {name}
83
+ </span>
84
+ </button>
85
+ ))}
86
+ </div>
87
+ {names.length === 0 && (
88
+ <div style={{ textAlign: 'center', color: '#999', padding: 24 }}>
89
+ 未找到匹配「{keyword}」的图标
90
+ </div>
91
+ )}
92
+ </div>
93
+ );
94
+ };
95
+
96
+ const meta = {
97
+ title: 'Example/Icons/Iconfont Picker',
98
+ component: IconfontPicker,
99
+ tags: ['autodocs'],
100
+ parameters: { layout: 'fullscreen' },
101
+ } satisfies Meta<typeof IconfontPicker>;
102
+
103
+ export default meta;
104
+ type Story = StoryObj<typeof meta>;
105
+
106
+ export const Base: Story = {};
@@ -45,6 +45,33 @@ export const Disabled: Story = {
45
45
  },
46
46
  };
47
47
 
48
+ export const DeptGroupLabels: Story = {
49
+ args: {
50
+ defaultValue: 'in',
51
+ operators: ['in', 'all', 'eq', 'empty', 'not_empty'],
52
+ fieldType: 'deptgroup',
53
+ },
54
+ name: '按字段类型显示描述(部门多选)',
55
+ };
56
+
57
+ export const AddressLabels: Story = {
58
+ args: {
59
+ defaultValue: 'in',
60
+ operators: ['in', 'nin', 'empty', 'not_empty'],
61
+ fieldType: 'address',
62
+ },
63
+ name: '按字段类型显示描述(地址)',
64
+ };
65
+
66
+ export const CustomOperatorLabels: Story = {
67
+ args: {
68
+ defaultValue: 'eq',
69
+ operators: ['eq', 'neq'],
70
+ operatorLabels: { eq: '是', neq: '不是' },
71
+ },
72
+ name: '自定义文案(operatorLabels)',
73
+ };
74
+
48
75
  export const Controlled: Story = {
49
76
  render: () => {
50
77
  const [value, setValue] = useState<relationalOperator>('eq');
@@ -0,0 +1,362 @@
1
+ import { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+ import {
4
+ TeamWideFormSelect,
5
+ TeamWideFormDrawer,
6
+ } from '../components/agent-helper/team-wide-form-select';
7
+ import type { TeamWideFormSelectChangeResult } from '../components/agent-helper/team-wide-form-select/types';
8
+ import type { IAllAppsAndFormsData } from '@baishuyun/types';
9
+
10
+ // ── Mock:按 /dashboard/app/form/list 真实返回结构构造 ────────────
11
+
12
+ const CURRENT_APP_ID = 'app_current';
13
+
14
+ const mockData: IAllAppsAndFormsData = {
15
+ dock_corps: [],
16
+ dock_items: [],
17
+ items: [
18
+ {
19
+ _id: 'default',
20
+ name: '默认分组',
21
+ appcount: 2,
22
+ apps: [
23
+ {
24
+ _id: CURRENT_APP_ID,
25
+ appname: '客户管理系统',
26
+ parent: 'default',
27
+ style: { color: 3, icon: 66 },
28
+ copyable: true,
29
+ deletable: true,
30
+ editable: true,
31
+ dock: false,
32
+ isFavorite: true,
33
+ appType: 1,
34
+ appStatus: 1,
35
+ disable_export: false,
36
+ formList: {
37
+ aggregate_table: null,
38
+ etl_table: null,
39
+ dash: [
40
+ {
41
+ appId: CURRENT_APP_ID,
42
+ entryId: 'dash_1',
43
+ hasCoop: false,
44
+ icon: 60,
45
+ name: '销售报表',
46
+ type: 'dash',
47
+ },
48
+ ],
49
+ form: [
50
+ {
51
+ appId: CURRENT_APP_ID,
52
+ entryId: 'form_1',
53
+ hasCoop: true,
54
+ icon: 51,
55
+ name: '采购订单表',
56
+ type: 'form',
57
+ },
58
+ {
59
+ appId: CURRENT_APP_ID,
60
+ entryId: 'group_1',
61
+ hasCoop: true,
62
+ icon: 25,
63
+ name: '客户资料',
64
+ type: 'group',
65
+ child: [
66
+ {
67
+ appId: CURRENT_APP_ID,
68
+ entryId: 'form_2',
69
+ hasCoop: true,
70
+ icon: 53,
71
+ name: '客户信息表',
72
+ type: 'form',
73
+ },
74
+ {
75
+ appId: CURRENT_APP_ID,
76
+ entryId: 'group_1_1',
77
+ hasCoop: true,
78
+ icon: 25,
79
+ name: '客户资料分组一',
80
+ type: 'group',
81
+ child: [
82
+ {
83
+ appId: CURRENT_APP_ID,
84
+ entryId: 'form_3',
85
+ hasCoop: true,
86
+ icon: 56,
87
+ name: '供应商管理表',
88
+ type: 'form',
89
+ },
90
+ {
91
+ appId: CURRENT_APP_ID,
92
+ entryId: 'form_4',
93
+ hasCoop: true,
94
+ icon: 56,
95
+ name: '客户表单',
96
+ type: 'form',
97
+ },
98
+ ],
99
+ },
100
+ ],
101
+ },
102
+ ],
103
+ refApps: [],
104
+ },
105
+ },
106
+ {
107
+ _id: 'app_2',
108
+ appname: '应用二',
109
+ parent: 'default',
110
+ style: { color: 1, icon: 40 },
111
+ copyable: true,
112
+ deletable: true,
113
+ editable: true,
114
+ dock: false,
115
+ isFavorite: false,
116
+ appType: 1,
117
+ appStatus: 1,
118
+ disable_export: false,
119
+ formList: {
120
+ aggregate_table: null,
121
+ dash: null,
122
+ etl_table: null,
123
+ form: [
124
+ {
125
+ appId: 'app_2',
126
+ entryId: 'app2_form_1',
127
+ hasCoop: true,
128
+ icon: 0,
129
+ name: '未命名表单',
130
+ type: 'form',
131
+ },
132
+ {
133
+ appId: 'app_2',
134
+ entryId: 'app2_group_1',
135
+ hasCoop: true,
136
+ icon: 25,
137
+ name: '我的分组一',
138
+ type: 'group',
139
+ child: [
140
+ {
141
+ appId: 'app_2',
142
+ entryId: 'app2_form_2',
143
+ hasCoop: true,
144
+ icon: 58,
145
+ name: '供应商管理表',
146
+ type: 'form',
147
+ },
148
+ {
149
+ appId: 'app_2',
150
+ entryId: 'app2_group_1_1',
151
+ hasCoop: true,
152
+ icon: 25,
153
+ name: '我的分组一杠1',
154
+ type: 'group',
155
+ child: [
156
+ {
157
+ appId: 'app_2',
158
+ entryId: 'app2_form_3',
159
+ hasCoop: true,
160
+ icon: 57,
161
+ name: '客户信息',
162
+ type: 'form',
163
+ },
164
+ ],
165
+ },
166
+ ],
167
+ },
168
+ ],
169
+ refApps: [],
170
+ },
171
+ },
172
+ ],
173
+ },
174
+ {
175
+ _id: 'group_b',
176
+ name: '解决方案模板',
177
+ appcount: 2,
178
+ apps: [
179
+ {
180
+ _id: 'app_3',
181
+ appname: '宠物管理',
182
+ parent: 'group_b',
183
+ style: { color: 3, icon: 67 },
184
+ copyable: true,
185
+ deletable: true,
186
+ editable: true,
187
+ dock: false,
188
+ isFavorite: false,
189
+ appType: 1,
190
+ appStatus: 1,
191
+ disable_export: false,
192
+ formList: {
193
+ aggregate_table: null,
194
+ dash: null,
195
+ etl_table: null,
196
+ form: [
197
+ {
198
+ appId: 'app_3',
199
+ entryId: 'app3_form_1',
200
+ hasCoop: true,
201
+ icon: 0,
202
+ name: '宠物信息',
203
+ type: 'form',
204
+ },
205
+ ],
206
+ refApps: [],
207
+ },
208
+ },
209
+ {
210
+ _id: 'app_4',
211
+ appname: '空白应用(无表单)',
212
+ parent: 'group_b',
213
+ style: { color: 2, icon: 44 },
214
+ copyable: true,
215
+ deletable: true,
216
+ editable: true,
217
+ dock: false,
218
+ isFavorite: false,
219
+ appType: 1,
220
+ appStatus: 1,
221
+ disable_export: false,
222
+ },
223
+ ],
224
+ },
225
+ ],
226
+ };
227
+
228
+ // ── Meta ──────────────────────────────────────────────────────────
229
+
230
+ const meta: Meta<typeof TeamWideFormSelect> = {
231
+ title: 'Agent Helper/TeamWideFormSelect',
232
+ component: TeamWideFormSelect,
233
+ parameters: { layout: 'centered' },
234
+ args: {
235
+ data: mockData,
236
+ placeholder: '请选择表单',
237
+ },
238
+ decorators: [
239
+ (Story) => (
240
+ <div style={{ width: 320, padding: 20 }}>
241
+ <Story />
242
+ </div>
243
+ ),
244
+ ],
245
+ };
246
+
247
+ export default meta;
248
+ type Story = StoryObj<typeof meta>;
249
+
250
+ // ── 下拉模式 ──────────────────────────────────────────────────────
251
+
252
+ export const Dropdown: Story = {
253
+ name: '下拉 — 全量树',
254
+ };
255
+
256
+ export const DropdownWithCurrentApp: Story = {
257
+ name: '下拉 — 按当前应用分组',
258
+ args: { currentAppId: CURRENT_APP_ID },
259
+ };
260
+
261
+ export const DropdownSelected: Story = {
262
+ name: '下拉 — 已选中',
263
+ args: { currentAppId: CURRENT_APP_ID, defaultValue: 'form_3' },
264
+ };
265
+
266
+ export const DropdownDisabled: Story = {
267
+ name: '下拉 — 禁用',
268
+ args: { defaultValue: 'form_1', disabled: true },
269
+ };
270
+
271
+ export const DropdownEmpty: Story = {
272
+ name: '下拉 — 空数据',
273
+ args: { data: { dock_corps: [], dock_items: [], items: [] } },
274
+ };
275
+
276
+ // ── 抽屉模式 ──────────────────────────────────────────────────────
277
+
278
+ export const DrawerMode: Story = {
279
+ name: '抽屉 — 左侧滑入',
280
+ render: (args) => {
281
+ const [open, setOpen] = useState(false);
282
+ const [selected, setSelected] =
283
+ useState<TeamWideFormSelectChangeResult | null>(null);
284
+
285
+ return (
286
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
287
+ <button
288
+ type="button"
289
+ onClick={() => setOpen(true)}
290
+ style={{
291
+ height: 34,
292
+ padding: '0 12px',
293
+ border: '1px solid #E0E0E0',
294
+ borderRadius: 4,
295
+ background: '#fff',
296
+ cursor: 'pointer',
297
+ fontSize: 14,
298
+ }}
299
+ >
300
+ {selected ? selected.form.name : '切换表单'}
301
+ </button>
302
+ <TeamWideFormDrawer
303
+ data={args.data}
304
+ currentAppId={args.currentAppId}
305
+ open={open}
306
+ onOpenChange={setOpen}
307
+ value={selected?.entryId}
308
+ onChange={setSelected}
309
+ />
310
+ {selected && (
311
+ <div style={{ fontSize: 12, color: '#666', wordBreak: 'break-all' }}>
312
+ 已选择: {selected.form.name}(appId: {selected.appId}, entryId:{' '}
313
+ {selected.entryId})
314
+ </div>
315
+ )}
316
+ </div>
317
+ );
318
+ },
319
+ args: { currentAppId: CURRENT_APP_ID },
320
+ decorators: [
321
+ (Story) => (
322
+ <div style={{ padding: 20 }}>
323
+ <Story />
324
+ </div>
325
+ ),
326
+ ],
327
+ };
328
+
329
+ // ── 交互式(下拉) ────────────────────────────────────────────────
330
+
331
+ export const Interactive: Story = {
332
+ render: (args) => {
333
+ const [selected, setSelected] =
334
+ useState<TeamWideFormSelectChangeResult | null>(null);
335
+ const [useCurrentApp, setUseCurrentApp] = useState(true);
336
+
337
+ return (
338
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
339
+ <label style={{ fontSize: 13, display: 'flex', alignItems: 'center', gap: 4 }}>
340
+ <input
341
+ type="checkbox"
342
+ checked={useCurrentApp}
343
+ onChange={(e) => setUseCurrentApp(e.target.checked)}
344
+ />
345
+ 按当前应用分组展示
346
+ </label>
347
+ <TeamWideFormSelect
348
+ {...args}
349
+ currentAppId={useCurrentApp ? CURRENT_APP_ID : undefined}
350
+ value={selected?.entryId ?? ''}
351
+ onChange={setSelected}
352
+ />
353
+ <div style={{ fontSize: 12, color: '#666', wordBreak: 'break-all', maxWidth: 300 }}>
354
+ 已选择:{' '}
355
+ {selected
356
+ ? `${selected.form.name}(appId: ${selected.appId}, entryId: ${selected.entryId})`
357
+ : '无'}
358
+ </div>
359
+ </div>
360
+ );
361
+ },
362
+ };
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from "@storybook/react-vite";
2
2
 
3
3
  import { UserTextMsgBubble } from "../components/user-txt-msg-bubble";
4
4
 
5
+ const longText = "供应商信息管理表需要先填写基础资料再补充产品明细。".repeat(9);
6
+
5
7
  const meta = {
6
8
  title: "Example/Chat/UserTextMsgBubble",
7
9
  component: UserTextMsgBubble,
@@ -22,3 +24,29 @@ export const Base: Story = {
22
24
  text: "确认搭建:供应商信息管理表",
23
25
  },
24
26
  };
27
+
28
+ export const Long: Story = {
29
+ args: {
30
+ text: longText,
31
+ },
32
+ };
33
+
34
+ export const CollapseDisabled: Story = {
35
+ args: {
36
+ text: longText,
37
+ collapsible: false,
38
+ },
39
+ };
40
+
41
+ export const NoIcon: Story = {
42
+ args: {
43
+ text: longText,
44
+ icon: null,
45
+ },
46
+ };
47
+
48
+ export const WithMarkdown: Story = {
49
+ args: {
50
+ text: "请按下面格式填写:\n名称:供应商\n\n```ts\nconst name = \"供应商\";\n```",
51
+ },
52
+ };
package/src/style.css CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  @import 'tw-animate-css';
6
6
 
7
+ @plugin "@tailwindcss/typography";
8
+
7
9
  @custom-variant dark (&:is(.dark *));
8
10
 
9
11
  @theme inline {
@@ -82,7 +84,34 @@
82
84
  --color-sidebar-border: var(--sidebar-border);
83
85
  --color-sidebar-ring: var(--sidebar-ring);
84
86
 
85
- --radius: 0.625rem;
87
+ --spacing: 3.5px;
88
+ --radius: 8.75px;
89
+ --text-xs: 10.5px;
90
+ --text-xs--line-height: 14px;
91
+ --text-sm: 12.25px;
92
+ --text-sm--line-height: 17.5px;
93
+ --text-base: 14px;
94
+ --text-base--line-height: 21px;
95
+ --text-lg: 15.75px;
96
+ --text-lg--line-height: 24.5px;
97
+ --text-xl: 17.5px;
98
+ --text-xl--line-height: 24.5px;
99
+ --text-2xl: 21px;
100
+ --text-2xl--line-height: 28px;
101
+ --text-3xl: 26.25px;
102
+ --text-3xl--line-height: 31.5px;
103
+ --text-4xl: 31.5px;
104
+ --text-4xl--line-height: 35px;
105
+ --text-5xl: 42px;
106
+ --text-5xl--line-height: 1;
107
+ --text-6xl: 52.5px;
108
+ --text-6xl--line-height: 1;
109
+ --text-7xl: 63px;
110
+ --text-7xl--line-height: 1;
111
+ --text-8xl: 84px;
112
+ --text-8xl--line-height: 1;
113
+ --text-9xl: 112px;
114
+ --text-9xl--line-height: 1;
86
115
  --background: oklch(1 0 0);
87
116
  --foreground: oklch(0.129 0.042 264.695);
88
117
  --card: oklch(1 0 0);