@agentscope-ai/design 1.0.27 → 1.0.28-beta.1769761940248

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.
@@ -1,308 +0,0 @@
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
- 查看全部图标