@agentscope-ai/design 1.0.26-beta.1768906295632 → 1.0.26

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.
@@ -6,8 +6,8 @@
6
6
  | 属性名 | 描述 | 类型 | 默认值 |
7
7
  |--------|--------|--------|--------|
8
8
  | language | 语言 | string \| string[] | (必填) |
9
- | value | 值 | string | (必填) |
9
+ | value | 值 | string | |
10
10
  | className | 类名 | string | |
11
11
  | theme | 主题 | 'dark' \| 'light' | |
12
12
  | readOnly | 只读 | boolean | |
13
- | onChange | | (value: string) => void | |
13
+ | onChange | | (value?: string) => void | |
@@ -0,0 +1,28 @@
1
+
2
+
3
+ <DemoTitle title="FileIcon" desc="用于展示不同文件类型的图标,也可通过 FileCard 展示文件信息。">
4
+ #### API
5
+
6
+ ##### FileIcon Props
7
+
8
+ | 属性名 | 描述 | 类型 | 默认值 |
9
+ |--------|--------|--------|--------|
10
+ | src | | string | |
11
+ | image | | string | |
12
+ | type | | string | (必填) |
13
+ | size | | number | |
14
+ | style | | React.CSSProperties | |
15
+
16
+
17
+ ##### FileCard Props
18
+
19
+ | 属性名 | 描述 | 类型 | 默认值 |
20
+ |--------|--------|--------|--------|
21
+ | iconSize | | number | |
22
+ | src | | string | |
23
+ | type | | string | (必填) |
24
+ | name | | string | (必填) |
25
+ | desc | | string | |
26
+ | size | | number | |
27
+ | width | | React.CSSProperties['width'] | |
28
+ | children | | React.ReactNode | |
@@ -1,5 +1,26 @@
1
1
 
2
2
 
3
+ ### 1.0.25
4
+ `2025-01-07`
5
+
6
+ ##### Fixed
7
+
8
+ - 修复 Tooltip 弹出框内部样式优先级问题
9
+
10
+ ### 1.0.24
11
+ `2025-01-04`
12
+
13
+ ##### Changed
14
+
15
+ - Video 组件添加 enableFullscreen 参数,支持全屏播放
16
+
17
+ ### 1.0.22
18
+ `2025-12-29`
19
+
20
+ ##### Changed
21
+
22
+ - Carbon 主题修改 `colorTextOnPrimary` 颜色变量为 '#ffffff'
23
+
3
24
  ### 1.0.21
4
25
  `2025-12-25`
5
26
 
@@ -0,0 +1,150 @@
1
+
2
+
3
+ # Icon Library
4
+
5
+
6
+
7
+ ```tsx
8
+ import React, { useMemo, useState } from 'react';
9
+ import * as SparkIcons from '@agentscope-ai/icons';
10
+ import { Input, Radio, message, copy } from '@agentscope-ai/design';
11
+
12
+ /**
13
+ * Icons Library
14
+ * - 自动枚举并展示 @agentscope-ai/icons 的全部导出图标
15
+ * - 支持搜索、点击复制
16
+ */
17
+
18
+ interface IconItem {
19
+ /** 图标导出名称 */
20
+ name: string;
21
+ /** 图标 React 组件 */
22
+ Icon: React.ComponentType<any>;
23
+ }
24
+
25
+ type CopyMode = 'name' | 'import' | 'jsx';
26
+
27
+ const GRID_STYLE: React.CSSProperties = {
28
+ display: 'grid',
29
+ gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
30
+ gap: 12,
31
+ };
32
+
33
+ const CARD_STYLE: React.CSSProperties = {
34
+ padding: 12,
35
+ borderRadius: 8,
36
+ cursor: 'pointer',
37
+ border: '1px solid var(--sps-color-border-secondary)',
38
+ background: 'var(--sps-color-bg-base)',
39
+ };
40
+
41
+ const NAME_STYLE: React.CSSProperties = {
42
+ marginTop: 8,
43
+ fontSize: 12,
44
+ lineHeight: '16px',
45
+ color: 'var(--sps-color-text-tertiary)',
46
+ overflow: 'hidden',
47
+ textOverflow: 'ellipsis',
48
+ whiteSpace: 'nowrap',
49
+ width: '100%',
50
+ fontFamily:
51
+ 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
52
+ };
53
+
54
+ export default function IconLibrary() {
55
+ const [keyword, setKeyword] = useState<string>('');
56
+ const [copyMode, setCopyMode] = useState<CopyMode>('name');
57
+
58
+ const allIcons = useMemo<IconItem[]>(() => {
59
+ return Object.entries(SparkIcons)
60
+ .filter(([name, Icon]) => {
61
+ if (!name.startsWith('Spark')) return false;
62
+ return typeof Icon === 'function';
63
+ })
64
+ .map(([name, Icon]) => ({
65
+ name,
66
+ Icon: Icon as React.ComponentType<any>,
67
+ }))
68
+ .sort((a, b) => a.name.localeCompare(b.name));
69
+ }, []);
70
+
71
+ const filteredIcons = useMemo<IconItem[]>(() => {
72
+ const q = keyword.trim().toLowerCase();
73
+ if (!q) return allIcons;
74
+ return allIcons.filter((item) => item.name.toLowerCase().includes(q));
75
+ }, [allIcons, keyword]);
76
+
77
+ const handleCopy = (item: IconItem) => {
78
+ let text = item.name;
79
+ if (copyMode === 'import') {
80
+ text = `import { ${item.name} } from '@agentscope-ai/icons';`;
81
+ }
82
+ if (copyMode === 'jsx') {
83
+ text = `<${item.name} style={{ fontSize: 24 }} />`;
84
+ }
85
+
86
+ copy(text);
87
+ message.success('已复制');
88
+ };
89
+
90
+ return (
91
+ <div style={{ padding: 16 }}>
92
+ <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
93
+ <Input
94
+ placeholder="搜索图标(按导出名)"
95
+ value={keyword}
96
+ onChange={(e) => setKeyword((e?.target as any)?.value || '')}
97
+ style={{ maxWidth: 360 }}
98
+ allowClear
99
+ />
100
+ <Radio.Group
101
+ value={copyMode}
102
+ onChange={(e) => setCopyMode(e.target.value)}
103
+ optionType="button"
104
+ buttonStyle="solid"
105
+ options={[
106
+ { label: '复制名称', value: 'name' },
107
+ { label: '复制 import', value: 'import' },
108
+ { label: '复制 JSX', value: 'jsx' },
109
+ ]}
110
+ />
111
+ <div style={{ color: 'var(--sps-color-text-tertiary)', fontSize: 12 }}>
112
+ 共 {filteredIcons.length} 个
113
+ </div>
114
+ </div>
115
+
116
+ <div style={{ marginTop: 16, ...GRID_STYLE }}>
117
+ {filteredIcons.map((item) => {
118
+ const Icon = item.Icon;
119
+ return (
120
+ <div
121
+ key={item.name}
122
+ style={CARD_STYLE}
123
+ onClick={() => handleCopy(item)}
124
+ >
125
+ <div
126
+ style={{
127
+ width: 48,
128
+ height: 48,
129
+ display: 'flex',
130
+ alignItems: 'center',
131
+ justifyContent: 'center',
132
+ }}
133
+ >
134
+ <Icon style={{ fontSize: 24 }} />
135
+ </div>
136
+ <div style={NAME_STYLE} title={item.name}>
137
+ {item.name}
138
+ </div>
139
+ </div>
140
+ );
141
+ })}
142
+ </div>
143
+ </div>
144
+ );
145
+ }
146
+
147
+
148
+ ```
149
+
150
+ 查看全部图标
@@ -383,7 +383,7 @@
383
383
 
384
384
  "colorTextWhite": "#ffffff",
385
385
  "colorTextBlack": "#000000",
386
- "colorTextOnPrimary": "#000000",
386
+ "colorTextOnPrimary": "#ffffff",
387
387
  "colorFillDisable": "#898989",
388
388
  "colorPurple": "#615CED",
389
389
  "colorPurpleHover": "#8383F0",
@@ -6,9 +6,8 @@
6
6
 
7
7
  为了让 Cursor 和 Claude Code 等工具理解 Spark Design,我们支持 LLMs.txt 文件,使 Spark Design 的文档可供大型语言模型使用。
8
8
 
9
-
10
- - [index.llms.txt](https://g.alicdn.com/code/npm/@ali/agentscope-ai-design/4.7.2/docs-dist/llms/index.llms.txt):主要的 LLMs.txt 索引文件
11
- - [all.llms.txt](https://g.alicdn.com/code/npm/@ali/agentscope-ai-design/4.7.2/docs-dist/llms/all.llms.txt):Spark Design 的完整文档
9
+ - [index.llms.txt](https://unpkg.com/@agentscope-ai/design@1.0.26/llms/index.llms.txt):主要的 LLMs.txt 索引文件
10
+ - [all.llms.txt](https://unpkg.com/@agentscope-ai/design@1.0.26/llms/all.llms.txt):Spark Design 的完整文档
12
11
 
13
12
  在 Cursor 中使用 @Docs 功能将 LLMs.txt 文件包含在您的项目中。[了解更多](https://docs.cursor.com/en/context/@-symbols/@-docs)
14
13
 
@@ -0,0 +1,308 @@
1
+
2
+
3
+ # Icon Library
4
+
5
+
6
+
7
+ ```tsx
8
+ import React, { useEffect, useMemo, useState } from 'react';
9
+ import * as SparkIcons from '@agentscope-ai/icons';
10
+ import { Input, Radio, message, copy } from '@agentscope-ai/design';
11
+ import { createStyles } from 'antd-style';
12
+ import { useLocale } from 'dumi';
13
+ import { SparkSearchLine } from '@agentscope-ai/icons';
14
+ import { categorizeIcon, ICON_CATEGORIES } from './iconCategories';
15
+ import $i18n from '@/i18n';
16
+
17
+ /**
18
+ * Icons Library
19
+ * - 自动枚举并展示 @agentscope-ai/icons 的全部导出图标
20
+ * - 支持搜索、点击复制
21
+ */
22
+
23
+ interface IconItem {
24
+ /** 图标导出名称 */
25
+ name: string;
26
+ /** 图标 React 组件 */
27
+ Icon: React.ComponentType<any>;
28
+ /** 图标分类 */
29
+ category: string;
30
+ }
31
+
32
+ type CopyMode = 'name' | 'import' | 'jsx';
33
+
34
+ const useStyles = createStyles(() => ({
35
+ container: {
36
+ position: 'relative',
37
+ padding: 16,
38
+ paddingTop: 72,
39
+ },
40
+ toolbar: {
41
+ position: 'fixed',
42
+ width: '100%',
43
+ padding: '16px',
44
+ top: 0,
45
+ left: 0,
46
+ display: 'flex',
47
+ gap: 12,
48
+ alignItems: 'center',
49
+ justifyContent: 'space-between',
50
+ flexWrap: 'wrap',
51
+ background: 'var(--sps-color-bg-base)',
52
+ borderBottom: '1px solid var(--sps-color-border-secondary)',
53
+ marginBottom: '16px',
54
+ },
55
+ toolbarLeft: {
56
+ display: 'flex',
57
+ gap: 12,
58
+ alignItems: 'center',
59
+ },
60
+ toolbarRight: {
61
+ display: 'flex',
62
+ gap: 12,
63
+ alignItems: 'center',
64
+ justifyContent: 'flex-end',
65
+ flexWrap: 'wrap',
66
+ },
67
+ search: {
68
+ maxWidth: 300,
69
+ },
70
+ count: {
71
+ color: 'var(--sps-color-text-tertiary)',
72
+ fontSize: 12,
73
+ },
74
+ groups: {
75
+ marginTop: 16,
76
+ display: 'flex',
77
+ flexDirection: 'column',
78
+ gap: 24,
79
+ },
80
+ groupTitle: {
81
+ fontSize: 14,
82
+ fontWeight: 600,
83
+ color: 'var(--sps-color-text-base)',
84
+ marginBottom: 12,
85
+ },
86
+ groupCount: {
87
+ marginLeft: 8,
88
+ fontSize: 12,
89
+ fontWeight: 400,
90
+ color: 'var(--sps-color-text-tertiary)',
91
+ },
92
+ grid: {
93
+ display: 'grid',
94
+ gridTemplateColumns: 'repeat(auto-fill, minmax(140px, 1fr))',
95
+ gap: 12,
96
+ },
97
+ card: {
98
+ padding: 12,
99
+ borderRadius: 8,
100
+ cursor: 'pointer',
101
+ border: '1px solid var(--sps-color-border-secondary)',
102
+ background: 'var(--sps-color-bg-base)',
103
+ },
104
+ iconWrap: {
105
+ width: 48,
106
+ height: 48,
107
+ display: 'flex',
108
+ alignItems: 'center',
109
+ justifyContent: 'center',
110
+ },
111
+ name: {
112
+ marginTop: 8,
113
+ fontSize: 12,
114
+ lineHeight: '16px',
115
+ color: 'var(--sps-color-text-tertiary)',
116
+ overflow: 'hidden',
117
+ textOverflow: 'ellipsis',
118
+ whiteSpace: 'nowrap',
119
+ width: '100%',
120
+ fontFamily:
121
+ 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
122
+ },
123
+ }));
124
+
125
+ export default function IconLibrary() {
126
+ const { styles } = useStyles();
127
+ const locale = useLocale();
128
+ const [keyword, setKeyword] = useState<string>('');
129
+ const [copyMode, setCopyMode] = useState<CopyMode>('name');
130
+
131
+ useEffect(() => {
132
+ // 同步 dumi 站点语言到 $i18n($i18n 识别 zh-cn / en)
133
+ $i18n.updateLocale(locale.id === 'zh-CN' ? 'zh-cn' : 'en');
134
+ }, [locale.id]);
135
+
136
+ const excludedIcons = useMemo(
137
+ () =>
138
+ new Set([
139
+ 'SparkDelete01LineCopy',
140
+ 'SparkA2d2dFill',
141
+ 'SparkA3d3dFill',
142
+ 'SparkBoldLine1',
143
+ 'SparkShanguangdengweikaiqiFlashlightOffLine',
144
+ 'SparkZhinengshengchengAiGenerateLine',
145
+ 'SparkQqkongjianQzoneFill',
146
+ 'SparkAccountManagementFill',
147
+ ]),
148
+ [],
149
+ );
150
+
151
+ const allIcons = useMemo<IconItem[]>(() => {
152
+ return Object.entries(SparkIcons)
153
+ .filter(([name, Icon]) => {
154
+ if (!name.startsWith('Spark')) return false;
155
+ if (excludedIcons.has(name)) return false;
156
+ return typeof Icon === 'function';
157
+ })
158
+ .map(([name, Icon]) => ({
159
+ name,
160
+ Icon: Icon as React.ComponentType<any>,
161
+ category: categorizeIcon(name),
162
+ }))
163
+ .sort((a, b) => a.name.localeCompare(b.name));
164
+ }, [excludedIcons]);
165
+
166
+ const filteredIcons = useMemo<IconItem[]>(() => {
167
+ const q = keyword.trim().toLowerCase();
168
+ if (!q) return allIcons;
169
+ return allIcons.filter((item) => item.name.toLowerCase().includes(q));
170
+ }, [allIcons, keyword]);
171
+
172
+ const groupedIcons = useMemo<Record<string, IconItem[]>>(() => {
173
+ return filteredIcons.reduce<Record<string, IconItem[]>>((acc, icon) => {
174
+ const key = icon.category;
175
+ if (!acc[key]) acc[key] = [];
176
+ acc[key].push(icon);
177
+ return acc;
178
+ }, {});
179
+ }, [filteredIcons]);
180
+
181
+ const orderedCategories = useMemo<string[]>(() => {
182
+ const configOrder = Object.keys(ICON_CATEGORIES);
183
+ const existing = new Set(Object.keys(groupedIcons));
184
+ const ordered = configOrder.filter((k) => existing.has(k));
185
+ const rest = Object.keys(groupedIcons)
186
+ .filter((k) => !configOrder.includes(k))
187
+ .sort((a, b) => a.localeCompare(b));
188
+ return [...ordered, ...rest];
189
+ }, [groupedIcons]);
190
+
191
+ const handleCopy = (item: IconItem) => {
192
+ let text = item.name;
193
+ if (copyMode === 'import') {
194
+ text = `import { ${item.name} } from '@agentscope-ai/icons';`;
195
+ }
196
+ if (copyMode === 'jsx') {
197
+ text = `<${item.name} style={{ fontSize: 24 }} />`;
198
+ }
199
+
200
+ copy(text);
201
+ message.success(
202
+ $i18n.get({
203
+ id: 'docs.icons.IconLibrary.CopySuccess',
204
+ dm: '已复制',
205
+ }),
206
+ );
207
+ };
208
+
209
+ return (
210
+ <div className={styles.container}>
211
+ <div className={styles.toolbar}>
212
+ <div className={styles.toolbarLeft}>
213
+ <Input
214
+ placeholder={$i18n.get({
215
+ id: 'docs.icons.IconLibrary.SearchPlaceholder',
216
+ dm: '搜索图标(按导出名)',
217
+ })}
218
+ value={keyword}
219
+ onChange={(e) => setKeyword((e?.target as any)?.value || '')}
220
+ className={styles.search}
221
+ prefix={<SparkSearchLine style={{ fontSize: 16 }} />}
222
+ allowClear
223
+ />
224
+ </div>
225
+
226
+ <div className={styles.toolbarRight}>
227
+ <div className={styles.count}>
228
+ {$i18n.get(
229
+ {
230
+ id: 'docs.icons.IconLibrary.TotalCount',
231
+ dm: '共 {count} 个',
232
+ },
233
+ { count: String(filteredIcons.length) },
234
+ )}
235
+ </div>
236
+ <Radio.Group
237
+ value={copyMode}
238
+ onChange={(e) => setCopyMode(e.target.value)}
239
+ optionType="button"
240
+ buttonStyle="solid"
241
+ options={[
242
+ {
243
+ label: $i18n.get({
244
+ id: 'docs.icons.IconLibrary.CopyName',
245
+ dm: '复制名称',
246
+ }),
247
+ value: 'name',
248
+ },
249
+ {
250
+ label: $i18n.get({
251
+ id: 'docs.icons.IconLibrary.CopyImport',
252
+ dm: '复制 import',
253
+ }),
254
+ value: 'import',
255
+ },
256
+ {
257
+ label: $i18n.get({
258
+ id: 'docs.icons.IconLibrary.CopyJSX',
259
+ dm: '复制 JSX',
260
+ }),
261
+ value: 'jsx',
262
+ },
263
+ ]}
264
+ />
265
+ </div>
266
+ </div>
267
+
268
+ <div className={styles.groups}>
269
+ {orderedCategories.map((category) => {
270
+ const list = groupedIcons[category] || [];
271
+ return (
272
+ <div key={category}>
273
+ <div className={styles.groupTitle}>
274
+ {category}
275
+ <span className={styles.groupCount}>({list.length})</span>
276
+ </div>
277
+
278
+ <div className={styles.grid}>
279
+ {list.map((item) => {
280
+ const Icon = item.Icon;
281
+ return (
282
+ <div
283
+ key={item.name}
284
+ className={styles.card}
285
+ onClick={() => handleCopy(item)}
286
+ >
287
+ <div className={styles.iconWrap}>
288
+ <Icon style={{ fontSize: 24 }} />
289
+ </div>
290
+ <div className={styles.name} title={item.name}>
291
+ {item.name}
292
+ </div>
293
+ </div>
294
+ );
295
+ })}
296
+ </div>
297
+ </div>
298
+ );
299
+ })}
300
+ </div>
301
+ </div>
302
+ );
303
+ }
304
+
305
+
306
+ ```
307
+
308
+ 查看全部图标
@@ -0,0 +1,25 @@
1
+
2
+
3
+ # 使用
4
+
5
+
6
+
7
+ ```tsx
8
+ import { SparkLoadingLine } from '@agentscope-ai/icons';
9
+
10
+ export default () => {
11
+ return (
12
+ <SparkLoadingLine
13
+ className="your-class-name"
14
+ style={{ color: 'var(--sps-color-primary)' }}
15
+ spin
16
+ size={48}
17
+ />
18
+ );
19
+ };
20
+
21
+ ```
22
+
23
+ 基本用法
24
+
25
+ 访问 [Icon Library](https://sparkdesign.agentscope.io/#/resources/icons) 查看全部 Icon