@tfdesign/b-end 1.0.4

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 (176) hide show
  1. package/AI_READ_FIRST.md +131 -0
  2. package/LICENSE +21 -0
  3. package/README.md +353 -0
  4. package/package.json +67 -0
  5. package/scripts/check-tfds-contract.mjs +334 -0
  6. package/scripts/check-tfds-integration.mjs +263 -0
  7. package/scripts/postinstall-cursor-skill.mjs +382 -0
  8. package/scripts/setup.mjs +520 -0
  9. package/skills/tfds/CHECKLIST.md +205 -0
  10. package/skills/tfds/COMMON_FAILURES.md +238 -0
  11. package/skills/tfds/DESIGN_PRINCIPLES.md +477 -0
  12. package/skills/tfds/GLOBAL_DESIGN_RULES.md +636 -0
  13. package/skills/tfds/LAYOUT_RECIPES.md +140 -0
  14. package/skills/tfds/LAYOUT_RULES.md +1355 -0
  15. package/skills/tfds/PAGE_ARCHETYPES.md +201 -0
  16. package/skills/tfds/SKILL.md +188 -0
  17. package/skills/tfds/components.index.json +7305 -0
  18. package/skills/tfds/components.summary.json +1809 -0
  19. package/src/_b_end_runtime/components/AiSuggestionShared.jsx +166 -0
  20. package/src/_b_end_runtime/components/Avatar.jsx +325 -0
  21. package/src/_b_end_runtime/components/Avatar.tokens.js +76 -0
  22. package/src/_b_end_runtime/components/AvatarGridPreview.jsx +56 -0
  23. package/src/_b_end_runtime/components/AvatarGroup.jsx +80 -0
  24. package/src/_b_end_runtime/components/AvatarGroup.tokens.js +28 -0
  25. package/src/_b_end_runtime/components/Button.jsx +144 -0
  26. package/src/_b_end_runtime/components/Button.tokens.js +90 -0
  27. package/src/_b_end_runtime/components/Card.jsx +460 -0
  28. package/src/_b_end_runtime/components/Card.tokens.js +124 -0
  29. package/src/_b_end_runtime/components/CardPreview.jsx +51 -0
  30. package/src/_b_end_runtime/components/ChatBubble.jsx +384 -0
  31. package/src/_b_end_runtime/components/ChatBubble.tokens.js +60 -0
  32. package/src/_b_end_runtime/components/ChatBubblePreview.jsx +129 -0
  33. package/src/_b_end_runtime/components/ChatInput.jsx +1399 -0
  34. package/src/_b_end_runtime/components/ChatInput.tokens.js +75 -0
  35. package/src/_b_end_runtime/components/ChatMessage.jsx +2215 -0
  36. package/src/_b_end_runtime/components/ChatMessage.tokens.js +257 -0
  37. package/src/_b_end_runtime/components/ChatMessagePreview.jsx +388 -0
  38. package/src/_b_end_runtime/components/Checkbox.jsx +317 -0
  39. package/src/_b_end_runtime/components/Checkbox.tokens.js +59 -0
  40. package/src/_b_end_runtime/components/ConversationList.jsx +1264 -0
  41. package/src/_b_end_runtime/components/ConversationList.tokens.js +135 -0
  42. package/src/_b_end_runtime/components/ConversationListPreview.jsx +108 -0
  43. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.jsx +324 -0
  44. package/src/_b_end_runtime/components/CustomerServiceWorkspaceFrame.tokens.js +69 -0
  45. package/src/_b_end_runtime/components/DatePicker.jsx +739 -0
  46. package/src/_b_end_runtime/components/DatePicker.tokens.js +99 -0
  47. package/src/_b_end_runtime/components/Empty.jsx +141 -0
  48. package/src/_b_end_runtime/components/Empty.tokens.js +40 -0
  49. package/src/_b_end_runtime/components/Form.jsx +609 -0
  50. package/src/_b_end_runtime/components/Form.tokens.js +77 -0
  51. package/src/_b_end_runtime/components/FormFieldStack.jsx +123 -0
  52. package/src/_b_end_runtime/components/FormFieldStack.tokens.js +12 -0
  53. package/src/_b_end_runtime/components/FormTitle.jsx +119 -0
  54. package/src/_b_end_runtime/components/FormTitle.tokens.js +87 -0
  55. package/src/_b_end_runtime/components/FullScreenPage.jsx +97 -0
  56. package/src/_b_end_runtime/components/FullScreenPage.tokens.js +19 -0
  57. package/src/_b_end_runtime/components/Icon.jsx +172 -0
  58. package/src/_b_end_runtime/components/Icon.tokens.js +26 -0
  59. package/src/_b_end_runtime/components/IconGridPreview.jsx +277 -0
  60. package/src/_b_end_runtime/components/InfoDisplayPanel.jsx +620 -0
  61. package/src/_b_end_runtime/components/InfoDisplayPanel.tokens.js +71 -0
  62. package/src/_b_end_runtime/components/InfoDisplayPanelPreview.jsx +133 -0
  63. package/src/_b_end_runtime/components/Input.jsx +258 -0
  64. package/src/_b_end_runtime/components/Input.tokens.js +68 -0
  65. package/src/_b_end_runtime/components/InputNumber.jsx +242 -0
  66. package/src/_b_end_runtime/components/InputNumber.tokens.js +55 -0
  67. package/src/_b_end_runtime/components/Modal.jsx +155 -0
  68. package/src/_b_end_runtime/components/Modal.tokens.js +73 -0
  69. package/src/_b_end_runtime/components/NavBar.jsx +842 -0
  70. package/src/_b_end_runtime/components/NavBar.tokens.js +97 -0
  71. package/src/_b_end_runtime/components/NavBarPreview.jsx +11 -0
  72. package/src/_b_end_runtime/components/Radio.jsx +227 -0
  73. package/src/_b_end_runtime/components/Radio.tokens.js +59 -0
  74. package/src/_b_end_runtime/components/Select.jsx +766 -0
  75. package/src/_b_end_runtime/components/Select.tokens.js +99 -0
  76. package/src/_b_end_runtime/components/Sheet.jsx +132 -0
  77. package/src/_b_end_runtime/components/Sheet.tokens.js +61 -0
  78. package/src/_b_end_runtime/components/Slider.jsx +346 -0
  79. package/src/_b_end_runtime/components/Slider.tokens.js +47 -0
  80. package/src/_b_end_runtime/components/Switch.jsx +124 -0
  81. package/src/_b_end_runtime/components/Switch.tokens.js +38 -0
  82. package/src/_b_end_runtime/components/Table.jsx +1338 -0
  83. package/src/_b_end_runtime/components/Table.tokens.js +147 -0
  84. package/src/_b_end_runtime/components/TablePreview.jsx +599 -0
  85. package/src/_b_end_runtime/components/Tabs.jsx +149 -0
  86. package/src/_b_end_runtime/components/Tabs.tokens.js +102 -0
  87. package/src/_b_end_runtime/components/Tag.jsx +199 -0
  88. package/src/_b_end_runtime/components/Tag.tokens.js +171 -0
  89. package/src/_b_end_runtime/components/TagBar.jsx +1134 -0
  90. package/src/_b_end_runtime/components/TagBar.tokens.js +75 -0
  91. package/src/_b_end_runtime/components/TagGridPreview.jsx +23 -0
  92. package/src/_b_end_runtime/components/TagInput.jsx +382 -0
  93. package/src/_b_end_runtime/components/TagInput.tokens.js +52 -0
  94. package/src/_b_end_runtime/components/TextArea.jsx +363 -0
  95. package/src/_b_end_runtime/components/TextArea.tokens.js +65 -0
  96. package/src/_b_end_runtime/components/TimePicker.jsx +444 -0
  97. package/src/_b_end_runtime/components/TimePicker.tokens.js +77 -0
  98. package/src/_b_end_runtime/components/Toast.jsx +120 -0
  99. package/src/_b_end_runtime/components/Toast.tokens.js +146 -0
  100. package/src/_b_end_runtime/components/Tooltip.jsx +282 -0
  101. package/src/_b_end_runtime/components/Tooltip.tokens.js +48 -0
  102. package/src/_b_end_runtime/components/TooltipPreview.jsx +50 -0
  103. package/src/_b_end_runtime/components/Upload.jsx +455 -0
  104. package/src/_b_end_runtime/components/Upload.tokens.js +47 -0
  105. package/src/_b_end_runtime/components/avatar-assets/avatar-default.png +0 -0
  106. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-1.png +0 -0
  107. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-2.png +0 -0
  108. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-3.png +0 -0
  109. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-4.png +0 -0
  110. package/src/_b_end_runtime/components/avatar-group-assets/avatar-group-5.png +0 -0
  111. package/src/_b_end_runtime/components/empty-assets/administrator-1.svg +40 -0
  112. package/src/_b_end_runtime/components/empty-assets/administrator-2.svg +33 -0
  113. package/src/_b_end_runtime/components/empty-assets/construction.svg +33 -0
  114. package/src/_b_end_runtime/components/empty-assets/failure.svg +49 -0
  115. package/src/_b_end_runtime/components/empty-assets/idle.svg +34 -0
  116. package/src/_b_end_runtime/components/empty-assets/no-access.svg +36 -0
  117. package/src/_b_end_runtime/components/empty-assets/no-content.svg +77 -0
  118. package/src/_b_end_runtime/components/empty-assets/no-result.svg +61 -0
  119. package/src/_b_end_runtime/components/empty-assets/not-found.svg +46 -0
  120. package/src/_b_end_runtime/components/empty-assets/success.svg +38 -0
  121. package/src/_b_end_runtime/components/file-type-assets/batch-report.png +0 -0
  122. package/src/_b_end_runtime/components/file-type-assets/catcat.svg +21 -0
  123. package/src/_b_end_runtime/components/file-type-assets/code.png +0 -0
  124. package/src/_b_end_runtime/components/file-type-assets/conversation.png +0 -0
  125. package/src/_b_end_runtime/components/file-type-assets/document.png +0 -0
  126. package/src/_b_end_runtime/components/file-type-assets/feishu-card.png +0 -0
  127. package/src/_b_end_runtime/components/file-type-assets/feishu-sheet.png +0 -0
  128. package/src/_b_end_runtime/components/file-type-assets/feishu.png +0 -0
  129. package/src/_b_end_runtime/components/file-type-assets/image.png +0 -0
  130. package/src/_b_end_runtime/components/file-type-assets/index.js +105 -0
  131. package/src/_b_end_runtime/components/file-type-assets/knowledge.png +0 -0
  132. package/src/_b_end_runtime/components/file-type-assets/pdf.png +0 -0
  133. package/src/_b_end_runtime/components/file-type-assets/pe.png +0 -0
  134. package/src/_b_end_runtime/components/file-type-assets/strategy.png +0 -0
  135. package/src/_b_end_runtime/components/file-type-assets/table.png +0 -0
  136. package/src/_b_end_runtime/components/file-type-assets/webpage.png +0 -0
  137. package/src/_b_end_runtime/components/file-type-assets/xmind.png +0 -0
  138. package/src/_b_end_runtime/components/icons/icon-data.js +12496 -0
  139. package/src/_b_end_runtime/components/nav-bar-assets/bytehi-logo-mark.svg +21 -0
  140. package/src/_b_end_runtime/components/table-assets/avatar.png +0 -0
  141. package/src/_b_end_runtime/components/table-assets/button.png +0 -0
  142. package/src/_b_end_runtime/components/table-assets/icon-chevron-down.png +0 -0
  143. package/src/_b_end_runtime/components/table-cell-assets/avatar.png +0 -0
  144. package/src/_b_end_runtime/components/table-cell-assets/button.png +0 -0
  145. package/src/_b_end_runtime/components/table-cell-assets/checkbox.png +0 -0
  146. package/src/_b_end_runtime/components/table-cell-assets/icon-chevron-right.png +0 -0
  147. package/src/_b_end_runtime/components/table-cell-assets/icon.png +0 -0
  148. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-handle.png +0 -0
  149. package/src/_b_end_runtime/components/table-cell-assets/semi-icons-tree-triangle-right.png +0 -0
  150. package/src/_b_end_runtime/components/table-cell-assets/switch.png +0 -0
  151. package/src/_b_end_runtime/components/tagShared.js +3 -0
  152. package/src/_b_end_runtime/components/team-avatar-assets/chengcheng-murphy.png +0 -0
  153. package/src/_b_end_runtime/components/team-avatar-assets/duan-ran.png +0 -0
  154. package/src/_b_end_runtime/components/team-avatar-assets/guo-zhezhi.png +0 -0
  155. package/src/_b_end_runtime/components/team-avatar-assets/li-siru.png +0 -0
  156. package/src/_b_end_runtime/components/team-avatar-assets/liu-delin.png +0 -0
  157. package/src/_b_end_runtime/components.js +3499 -0
  158. package/src/_b_end_runtime/index.js +9 -0
  159. package/src/_b_end_runtime/page-patterns/BasePageFramePattern.jsx +395 -0
  160. package/src/_b_end_runtime/page-patterns/ChatConversationPattern.jsx +989 -0
  161. package/src/_b_end_runtime/page-patterns/ChatHomePagePattern.jsx +281 -0
  162. package/src/_b_end_runtime/page-patterns/CopilotPagePattern.jsx +380 -0
  163. package/src/_b_end_runtime/page-patterns/CustomerServiceWorkspaceFramePattern.jsx +392 -0
  164. package/src/_b_end_runtime/page-patterns/IMConversationPattern.jsx +590 -0
  165. package/src/_b_end_runtime/page-patterns/McpManagementPage.jsx +237 -0
  166. package/src/_b_end_runtime/page-patterns/StrategyListPage.jsx +189 -0
  167. package/src/_b_end_runtime/page-patterns/TabTopBarListPage.jsx +594 -0
  168. package/src/_b_end_runtime/page-patterns/VariableManagementPage.jsx +87 -0
  169. package/src/_b_end_runtime/page-patterns/pageListShared.jsx +177 -0
  170. package/src/_b_end_runtime/patterns.js +428 -0
  171. package/src/_b_end_runtime/preview-registry.jsx +4719 -0
  172. package/src/_b_end_runtime/teamMembers.js +56 -0
  173. package/src/_b_end_runtime/tokens.js +500 -0
  174. package/src/index.d.ts +1073 -0
  175. package/src/index.js +52 -0
  176. package/theme.css +350 -0
@@ -0,0 +1,455 @@
1
+ /**
2
+ * Upload — 图片上传
3
+ * @prop {string} [accept='image/*'] — 接受类型
4
+ * @prop {boolean} [multiple=true] — 是否多选
5
+ * @prop {number} limit — 数量上限
6
+ * @prop {number} maxSize — 最大体积
7
+ * @prop {number} minSize — 最小体积
8
+ * @prop {boolean} [disabled=false] — 是否禁用
9
+ * @prop {Array} value — 文件列表(受控)
10
+ * @prop {Array} [defaultValue=null] — 默认列表
11
+ * @prop {function} [onChange=null] — 列表变化
12
+ * @prop {function} [onRemove=null] — 删除回调
13
+ * @prop {function} [beforeUpload=null] — 上传前校验
14
+ * @prop {function} [onSuccess=null] — 成功回调
15
+ * @prop {function} [onError=null] — 失败回调
16
+ * @prop {function} [onProgress=null] — 进度回调
17
+ */
18
+
19
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
20
+ import Button from './Button';
21
+ import Icon from './Icon';
22
+
23
+ /* ── 布局容器 ── */
24
+ const WRAP = 'relative inline-flex flex-col';
25
+ const GALLERY = 'flex flex-wrap items-start gap-[8px]';
26
+
27
+ /* ── 图片卡片 ── */
28
+ const TILE_BASE = [
29
+ 'group relative size-[96px] shrink-0 overflow-hidden',
30
+ 'rounded-md',
31
+ 'border border-solid border-border-default',
32
+ 'bg-disabled',
33
+ ].join(' ');
34
+
35
+ const TILE_IMAGE = 'size-full object-cover';
36
+
37
+ /* ── 添加卡片 ── */
38
+ const ADD_TILE = [
39
+ 'relative inline-flex size-[96px] shrink-0 items-center justify-center',
40
+ 'rounded-md',
41
+ 'border border-dashed border-border-default',
42
+ 'bg-fill text-foreground-secondary',
43
+ 'transition-colors duration-150',
44
+ 'hover:border-primary hover:bg-brand-50',
45
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1',
46
+ ].join(' ');
47
+
48
+ const ADD_TILE_DISABLED = [
49
+ 'bg-disabled text-foreground-disabled',
50
+ 'border-border-default',
51
+ 'cursor-not-allowed pointer-events-none',
52
+ ].join(' ');
53
+
54
+ /* ── 交互层 ── */
55
+ const REMOVE_BTN = [
56
+ 'absolute right-[5px] top-[5px] inline-flex size-[16px] items-center justify-center',
57
+ 'rounded-full border-none p-0',
58
+ 'bg-[rgba(0,0,0,0.55)] text-foreground-inverse',
59
+ 'shadow-[0_0_1px_rgba(0,0,0,0.32)]',
60
+ 'opacity-0 transition-opacity duration-150',
61
+ 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary',
62
+ ].join(' ');
63
+
64
+ const OVERLAY = 'absolute inset-0 bg-[rgba(0,0,0,0.3)]';
65
+
66
+ const ERROR_BADGE = [
67
+ 'absolute bottom-[5px] right-[5px] inline-flex size-[16px]',
68
+ 'items-center justify-center',
69
+ ].join(' ');
70
+
71
+ const SPINNER_RING = [
72
+ 'inline-block size-[20px] animate-spin rounded-full',
73
+ 'border-2 border-border-default border-t-primary',
74
+ ].join(' ');
75
+
76
+ function PlusIcon() {
77
+ return (
78
+ <svg viewBox="0 0 16 16" fill="none" className="size-[24px]" aria-hidden="true">
79
+ <path d="M8 3V13M3 8H13" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
80
+ </svg>
81
+ );
82
+ }
83
+
84
+ function CloseIcon() {
85
+ return (
86
+ <svg viewBox="0 0 16 16" fill="none" className="size-[12px]" aria-hidden="true">
87
+ <path d="M4 4L12 12M12 4L4 12" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
88
+ </svg>
89
+ );
90
+ }
91
+
92
+ function normalizeStatus(status) {
93
+ if (status === 'uploading') return 'uploading';
94
+ if (status === 'error' || status === 'uploadFail') return 'error';
95
+ return 'done';
96
+ }
97
+
98
+ function normalizeList(rawList) {
99
+ const list = Array.isArray(rawList) ? rawList : [];
100
+ return list.map((item, idx) => ({
101
+ ...item,
102
+ uid: String(item?.uid ?? `${idx}-${item?.name || 'image'}`),
103
+ status: normalizeStatus(item?.status),
104
+ percent: typeof item?.percent === 'number' ? item.percent : (normalizeStatus(item?.status) === 'uploading' ? 40 : 100),
105
+ }));
106
+ }
107
+
108
+ export const Upload = ({
109
+ accept = 'image/*',
110
+ multiple = true,
111
+ limit,
112
+ maxSize,
113
+ minSize,
114
+ disabled = false,
115
+ value,
116
+ defaultValue = null,
117
+ onChange,
118
+ onRemove,
119
+ beforeUpload,
120
+ onSuccess,
121
+ onError,
122
+ onProgress,
123
+ className = '',
124
+ style,
125
+ ...rest
126
+ }) => {
127
+ const isControlled = value !== undefined;
128
+ const [innerList, setInnerList] = useState(() => normalizeList(defaultValue));
129
+ const currentList = isControlled ? normalizeList(value) : innerList;
130
+ const listRef = useRef(currentList);
131
+
132
+ const inputRef = useRef(null);
133
+ const timersRef = useRef(new Map());
134
+ const blobUrlsRef = useRef(new Set());
135
+
136
+ useEffect(() => {
137
+ listRef.current = currentList;
138
+ }, [currentList]);
139
+
140
+ const clearTimer = useCallback((uid) => {
141
+ const timer = timersRef.current.get(uid);
142
+ if (timer) {
143
+ clearInterval(timer);
144
+ timersRef.current.delete(uid);
145
+ }
146
+ }, []);
147
+
148
+ const revokeBlobUrl = useCallback((url) => {
149
+ if (typeof url !== 'string') return;
150
+ if (!blobUrlsRef.current.has(url)) return;
151
+ URL.revokeObjectURL(url);
152
+ blobUrlsRef.current.delete(url);
153
+ }, []);
154
+
155
+ useEffect(() => {
156
+ return () => {
157
+ timersRef.current.forEach((timer) => clearInterval(timer));
158
+ timersRef.current.clear();
159
+ blobUrlsRef.current.forEach((url) => URL.revokeObjectURL(url));
160
+ blobUrlsRef.current.clear();
161
+ };
162
+ }, []);
163
+
164
+ useEffect(() => {
165
+ if (!isControlled) setInnerList(normalizeList(defaultValue));
166
+ }, [defaultValue, isControlled]);
167
+
168
+ const updateList = useCallback((nextList) => {
169
+ listRef.current = nextList;
170
+ if (!isControlled) setInnerList(nextList);
171
+ onChange?.(nextList);
172
+ }, [isControlled, onChange]);
173
+
174
+ const replaceByUid = useCallback((uid, updater) => {
175
+ const base = listRef.current;
176
+ const next = base.map((item) => (item.uid === uid ? updater(item) : item));
177
+ updateList(next);
178
+ return next;
179
+ }, [updateList]);
180
+
181
+ const removeItem = useCallback((target) => {
182
+ if (disabled) return;
183
+ clearTimer(target.uid);
184
+ revokeBlobUrl(target.url);
185
+ const next = listRef.current.filter((item) => item.uid !== target.uid);
186
+ updateList(next);
187
+ onRemove?.(target, next);
188
+ }, [clearTimer, disabled, onRemove, revokeBlobUrl, updateList]);
189
+
190
+ const matchesAccept = useCallback((file) => {
191
+ if (!accept) return true;
192
+ const rules = String(accept).split(',').map((s) => s.trim()).filter(Boolean);
193
+ if (rules.length === 0) return true;
194
+ return rules.some((rule) => {
195
+ if (rule === 'image/*') return file.type.startsWith('image/');
196
+ if (rule.endsWith('/*')) return file.type.startsWith(rule.slice(0, -1));
197
+ if (rule.startsWith('.')) return file.name.toLowerCase().endsWith(rule.toLowerCase());
198
+ return file.type === rule;
199
+ });
200
+ }, [accept]);
201
+
202
+ const validateFile = useCallback((file) => {
203
+ if (!matchesAccept(file)) return { ok: false, reason: 'type' };
204
+ if (typeof maxSize === 'number' && file.size > maxSize) return { ok: false, reason: 'maxSize' };
205
+ if (typeof minSize === 'number' && file.size < minSize) return { ok: false, reason: 'minSize' };
206
+ return { ok: true };
207
+ }, [matchesAccept, maxSize, minSize]);
208
+
209
+ const runBeforeUpload = useCallback(async (file) => {
210
+ if (!beforeUpload) return true;
211
+ try {
212
+ const result = await beforeUpload(file);
213
+ return result !== false;
214
+ } catch {
215
+ return false;
216
+ }
217
+ }, [beforeUpload]);
218
+
219
+ const simulateUpload = useCallback((fileItem, rawFile) => {
220
+ const uid = fileItem.uid;
221
+ const uploadingItem = { ...fileItem, status: 'uploading', percent: 0 };
222
+
223
+ clearTimer(uid);
224
+ replaceByUid(uid, (prev) => ({
225
+ ...prev,
226
+ status: 'uploading',
227
+ percent: 0,
228
+ errorReason: undefined,
229
+ }));
230
+ onProgress?.(0, uploadingItem, rawFile);
231
+
232
+ const timer = setTimeout(() => {
233
+ clearTimer(uid);
234
+ const errorItem = { ...fileItem, status: 'error', percent: 0 };
235
+ replaceByUid(uid, (prev) => ({
236
+ ...prev,
237
+ status: 'error',
238
+ percent: 0,
239
+ }));
240
+ onSuccess?.(errorItem, rawFile);
241
+ }, 5000);
242
+
243
+ timersRef.current.set(uid, timer);
244
+ }, [clearTimer, onProgress, onSuccess, replaceByUid]);
245
+
246
+ const genUid = useCallback(
247
+ () => `upload-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
248
+ []
249
+ );
250
+
251
+ const addFiles = useCallback(async (rawFiles) => {
252
+ if (disabled) return;
253
+
254
+ const selectedFiles = Array.from(rawFiles || []);
255
+ if (selectedFiles.length === 0) return;
256
+
257
+ let working = [...listRef.current];
258
+ const hasLimit = typeof limit === 'number' && Number.isFinite(limit);
259
+ const maxCount = hasLimit ? limit : Infinity;
260
+
261
+ for (const file of selectedFiles) {
262
+ if (working.length >= maxCount) break;
263
+
264
+ const uid = genUid();
265
+ const previewUrl = URL.createObjectURL(file);
266
+ blobUrlsRef.current.add(previewUrl);
267
+
268
+ const baseItem = {
269
+ uid,
270
+ name: file.name,
271
+ size: file.size,
272
+ url: previewUrl,
273
+ fileInstance: file,
274
+ status: 'uploading',
275
+ percent: 0,
276
+ };
277
+
278
+ const validation = validateFile(file);
279
+ if (!validation.ok) {
280
+ const errorItem = { ...baseItem, status: 'error', percent: 0, errorReason: validation.reason };
281
+ working = [...working, errorItem];
282
+ updateList(working);
283
+ onError?.(validation.reason, errorItem, file);
284
+ continue;
285
+ }
286
+
287
+ const allow = await runBeforeUpload(file);
288
+ if (!allow) {
289
+ const deniedItem = { ...baseItem, status: 'error', percent: 0, errorReason: 'beforeUpload' };
290
+ working = [...working, deniedItem];
291
+ updateList(working);
292
+ onError?.('beforeUpload', deniedItem, file);
293
+ continue;
294
+ }
295
+
296
+ working = [...working, baseItem];
297
+ updateList(working);
298
+ simulateUpload(baseItem, file);
299
+ }
300
+ }, [
301
+ disabled,
302
+ genUid,
303
+ limit,
304
+ onError,
305
+ runBeforeUpload,
306
+ simulateUpload,
307
+ updateList,
308
+ validateFile,
309
+ ]);
310
+
311
+ const openDialog = useCallback(() => {
312
+ if (!disabled) inputRef.current?.click();
313
+ }, [disabled]);
314
+
315
+ const retryItem = useCallback(async (fileItem) => {
316
+ if (disabled) return;
317
+ const rawFile = fileItem?.fileInstance;
318
+
319
+ if (rawFile) {
320
+ const validation = validateFile(rawFile);
321
+ if (!validation.ok) {
322
+ replaceByUid(fileItem.uid, (prev) => ({ ...prev, status: 'error', percent: 0, errorReason: validation.reason }));
323
+ onError?.(validation.reason, fileItem, rawFile);
324
+ return;
325
+ }
326
+
327
+ const allow = await runBeforeUpload(rawFile);
328
+ if (!allow) {
329
+ replaceByUid(fileItem.uid, (prev) => ({ ...prev, status: 'error', percent: 0, errorReason: 'beforeUpload' }));
330
+ onError?.('beforeUpload', fileItem, rawFile);
331
+ return;
332
+ }
333
+ }
334
+
335
+ simulateUpload({ ...fileItem, status: 'uploading', percent: 0 }, rawFile);
336
+ }, [disabled, onError, replaceByUid, runBeforeUpload, simulateUpload, validateFile]);
337
+
338
+ const handleInputChange = useCallback(async (e) => {
339
+ const files = e.target.files;
340
+ e.target.value = '';
341
+ await addFiles(files);
342
+ }, [addFiles]);
343
+
344
+ const showAddTile = !disabled
345
+ ? (typeof limit === 'number' ? currentList.length < limit : true)
346
+ : (typeof limit === 'number' ? currentList.length < limit : currentList.length === 0);
347
+
348
+ const normalizedList = useMemo(() => normalizeList(currentList), [currentList]);
349
+
350
+ return (
351
+ <div
352
+ className={[`tfds-upload`, [WRAP, disabled ? 'opacity-60' : '', className].filter(Boolean).join(' ')].filter(Boolean).join(' ')}
353
+ style={style}
354
+ {...rest}
355
+ data-tfds-component="Upload"
356
+ >
357
+ <input
358
+ ref={inputRef}
359
+ type="file"
360
+ className="hidden"
361
+ accept={accept}
362
+ multiple={multiple}
363
+ disabled={disabled}
364
+ onChange={handleInputChange}
365
+ />
366
+
367
+ <div className={GALLERY}>
368
+ {normalizedList.map((fileItem) => {
369
+ const alwaysShowRemove = Boolean(fileItem.showRemove);
370
+ const showUploading = fileItem.status === 'uploading';
371
+ const showError = fileItem.status === 'error';
372
+
373
+ return (
374
+ <div key={fileItem.uid} className={TILE_BASE}>
375
+ {fileItem.url ? (
376
+ <img src={fileItem.url} alt={fileItem.name || 'upload image'} className={TILE_IMAGE} />
377
+ ) : (
378
+ <div className="flex size-full items-center justify-center text-foreground-disabled">
379
+ <PlusIcon />
380
+ </div>
381
+ )}
382
+
383
+ {!disabled && (
384
+ <button
385
+ type="button"
386
+ className={[
387
+ REMOVE_BTN,
388
+ alwaysShowRemove ? 'opacity-100' : 'group-hover:opacity-100 focus-visible:opacity-100',
389
+ ].join(' ')}
390
+ onClick={() => removeItem(fileItem)}
391
+ aria-label="删除图片"
392
+ >
393
+ <CloseIcon />
394
+ </button>
395
+ )}
396
+
397
+ {showUploading && (
398
+ <>
399
+ <div className={OVERLAY} />
400
+ <div className="absolute inset-0 flex items-center justify-center">
401
+ <span className={SPINNER_RING} />
402
+ </div>
403
+ </>
404
+ )}
405
+
406
+ {showError && (
407
+ <>
408
+ <div className={OVERLAY} />
409
+ <div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2">
410
+ <Button
411
+ variant="outline-black"
412
+ size="sm"
413
+ radius="rounded"
414
+ iconOnly
415
+ icon={<Icon name="refresh-cw-01-stroked" size="xs" />}
416
+ onClick={(e) => {
417
+ e.stopPropagation();
418
+ retryItem(fileItem);
419
+ }}
420
+ disabled={disabled}
421
+ aria-label="重试上传"
422
+ />
423
+ </div>
424
+ <span className={ERROR_BADGE}>
425
+ <Icon
426
+ name="info-circle-stroked"
427
+ size="sm"
428
+ color="var(--color-danger)"
429
+ style={{ transform: 'rotate(180deg)' }}
430
+ />
431
+ </span>
432
+ </>
433
+ )}
434
+ </div>
435
+ );
436
+ })}
437
+
438
+ {showAddTile && (
439
+ <button
440
+ type="button"
441
+ className={[ADD_TILE, disabled ? ADD_TILE_DISABLED : ''].join(' ')}
442
+ onClick={openDialog}
443
+ aria-label="添加图片"
444
+ >
445
+ <PlusIcon />
446
+ </button>
447
+ )}
448
+ </div>
449
+ </div>
450
+ );
451
+ };
452
+
453
+ Upload.displayName = 'Upload';
454
+
455
+ export default Upload;
@@ -0,0 +1,47 @@
1
+ export const UPLOAD_TOKEN_MAP = {
2
+ 图片卡片: [
3
+ { label: '边框色', cssProp: 'border-color', token: '--color-border-default', value: '#E4E7EC', semanticRef: 'border-default' },
4
+ { label: '背景色', cssProp: 'background-color', token: '--color-disabled', value: '#F9FAFB', semanticRef: 'bg-disabled' },
5
+ { label: '圆角', cssProp: 'border-radius', token: '--radius-md', value: '8px' },
6
+ ],
7
+ 添加卡片: [
8
+ { label: '背景色', cssProp: 'background-color', token: '--color-fill', value: 'rgba(83,96,143,0.07)', semanticRef: 'fill-default' },
9
+ { label: '边框色', cssProp: 'border-color', token: '--color-border-default', value: '#E4E7EC', semanticRef: 'border-default' },
10
+ { label: '悬浮边框', cssProp: 'border-color', token: '--color-primary', value: '#56D3BC', semanticRef: 'status-primary', state: 'hover' },
11
+ { label: '悬浮背景', cssProp: 'background-color', token: '--color-brand-50', value: '#EAFAF6', semanticRef: 'status-primary.bg', state: 'hover' },
12
+ { label: '图标色', cssProp: 'color', token: '--color-foreground-secondary', value: '#475467', semanticRef: 'text-secondary' },
13
+ ],
14
+ 删除按钮: [
15
+ { label: '背景色', cssProp: 'background-color', value: 'rgba(0,0,0,0.55)' },
16
+ { label: '图标色', cssProp: 'color', token: '--color-foreground-inverse', value: '#FFFFFF', semanticRef: 'text-inverse' },
17
+ { label: '阴影', cssProp: 'box-shadow', value: '0 0 1px rgba(0,0,0,0.32)' },
18
+ { label: '常态透明', cssProp: 'opacity', value: '0' },
19
+ { label: '悬浮透明', cssProp: 'opacity', value: '1', state: 'hover' },
20
+ ],
21
+ 上传中: [
22
+ { label: '遮罩层', cssProp: 'background-color', value: 'rgba(0,0,0,0.3)' },
23
+ { label: '环底色', cssProp: 'border-color', token: '--color-blueGrey-300', value: '#E4E7EC' },
24
+ { label: '进度高亮', cssProp: 'border-top-color', token: '--color-primary', value: '#56D3BC', semanticRef: 'status-primary' },
25
+ ],
26
+ 错误态: [
27
+ { label: '遮罩层', cssProp: 'background-color', value: 'rgba(0,0,0,0.3)' },
28
+ { label: '角标颜色', cssProp: 'color', token: '--color-danger', value: '#F74331', semanticRef: 'status-danger' },
29
+ { label: '重试按钮', cssProp: '组件引用', value: 'Button outline-black sm full iconOnly' },
30
+ ],
31
+ 禁用态: [
32
+ { label: '区块透明', cssProp: 'opacity', value: '0.6' },
33
+ { label: '添加背景', cssProp: 'background-color', token: '--color-disabled', value: '#F9FAFB', semanticRef: 'bg-disabled' },
34
+ { label: '添加图标', cssProp: 'color', token: '--color-foreground-disabled', value: '#98A2B3', semanticRef: 'text-disabled' },
35
+ ],
36
+ 尺寸: [
37
+ { label: '卡片宽度', cssProp: 'width', value: '96px' },
38
+ { label: '卡片高度', cssProp: 'height', value: '96px' },
39
+ { label: '宫格间距', cssProp: 'gap', value: '8px' },
40
+ { label: '删除尺寸', cssProp: 'width / height', value: '16px' },
41
+ { label: '加号尺寸', cssProp: 'width / height', value: '24px' },
42
+ ],
43
+ 引用组件: [
44
+ { label: '重试按钮', cssProp: '—', value: 'Button outline-black sm radius=full iconOnly + Icon refresh-ccw-01-stroked' },
45
+ { label: '异常角标', cssProp: '—', value: 'Icon info-circle-stroked(180° 旋转为叹号语义)' },
46
+ ],
47
+ };
@@ -0,0 +1,40 @@
1
+ <svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M115.211 77.8922C113.11 79.9935 110.478 81.6455 107.388 82.8036C104.438 83.9089 101.136 84.5084 97.8411 84.5377C90.8715 84.5982 84.4194 82.1748 80.1349 77.8922C75.9207 73.678 73.9405 67.7942 74.5615 61.3264C75.1435 55.2571 77.9594 49.2932 82.2849 44.9677C86.4542 40.7984 92.0822 38.5878 98.136 38.7421C104.203 38.8963 109.97 41.4038 114.372 45.8074C118.773 50.209 121.283 55.9757 121.437 62.0431C121.589 68.0969 119.379 73.7269 115.211 77.8942V77.8922Z" fill="black"/>
3
+ <path d="M82.8045 45.4851C78.5962 49.6935 75.8583 55.4914 75.292 61.3967C74.6925 67.6438 76.5965 73.3167 80.6545 77.3747C84.7124 81.4327 91.061 83.8639 97.8354 83.8053C101.046 83.778 104.26 83.1941 107.131 82.1181C110.123 80.9972 112.667 79.4017 114.694 77.3747C118.719 73.3499 120.855 67.9113 120.707 62.0607C120.558 56.1827 118.125 50.5937 113.856 46.3248C109.587 42.056 103.998 39.6228 98.1205 39.4743C92.2698 39.3259 86.8312 41.4623 82.8065 45.4871M81.7695 44.4482C90.6841 35.5336 105.514 35.9085 114.891 45.2859C124.269 54.6634 124.644 69.4931 115.729 78.4078C106.814 87.3224 88.995 87.7852 79.6175 78.4078C70.2401 69.0303 72.8529 53.3628 81.7676 44.4462L81.7695 44.4482Z" fill="black"/>
4
+ <path d="M130.678 155.111L63.9852 149.337V115.818C63.9852 111.125 64.7507 106.856 66.2583 103.13C67.7327 99.4884 69.9218 96.3541 72.7632 93.8115C75.5987 91.2768 79.0883 89.3259 83.1385 88.0136C87.2472 86.6818 91.9321 86.0061 97.0641 86.0061C102.196 86.0061 107.1 86.9903 111.927 88.9314C116.577 90.8022 120.81 93.4503 124.511 96.8033C128.217 100.162 131.143 104.007 133.207 108.231C135.355 112.627 136.445 117.195 136.445 121.809V149.819L130.68 155.109L130.678 155.111Z" fill="black"/>
5
+ <path d="M97.0641 86.7383C92.0082 86.7383 87.3996 87.4023 83.365 88.7087C79.4125 89.9897 76.0107 91.8898 73.2533 94.3563C70.4959 96.8227 68.3713 99.8671 66.9399 103.404C65.4674 107.042 64.7195 111.219 64.7195 115.816V148.663L130.422 154.352L135.712 149.497V121.809C135.712 117.308 134.648 112.848 132.549 108.553C130.526 104.413 127.657 100.642 124.019 97.346C120.435 94.0965 116.159 91.4231 111.654 89.6109C106.914 87.7049 102.005 86.7383 97.0641 86.7383ZM97.0641 85.2737C118.084 85.2737 137.175 102.396 137.175 121.809V150.141L130.936 155.867L63.2529 150.007V115.816C63.2529 96.4028 76.042 85.2717 97.0641 85.2717V85.2737Z" fill="black"/>
6
+ <path d="M110.425 79.3571C106.256 83.5263 100.628 85.7369 94.5741 85.5827C88.5067 85.4284 82.74 82.921 78.3383 78.5174C73.9367 74.1157 71.4273 68.349 71.273 62.2816C71.1207 56.2278 73.3313 50.5979 77.4986 46.4305C81.6679 42.2613 87.2959 40.0507 93.3497 40.2049C99.4171 40.3592 105.184 42.8666 109.585 47.2703C113.987 51.6719 116.496 57.4386 116.651 63.506C116.803 69.5598 114.592 75.1897 110.425 79.3571Z" fill="white"/>
7
+ <path d="M76.8043 45.7383C85.8249 36.7177 100.813 37.1096 110.28 46.5762C119.746 56.0427 120.138 71.0313 111.118 80.0518C102.097 89.0723 87.1088 88.6802 77.6422 79.2139C68.1757 69.7473 67.7837 54.7589 76.8043 45.7383ZM93.3258 41.1875C87.5415 41.0408 82.1698 43.1521 78.1949 47.127C74.2201 51.1018 72.1088 56.4735 72.2555 62.2578C72.4023 68.0698 74.808 73.5984 79.0328 77.8232C83.2577 82.048 88.7864 84.4538 94.5983 84.6006C100.382 84.7472 105.754 82.6359 109.729 78.6611C113.704 74.6864 115.815 69.3144 115.669 63.5303C115.522 57.7184 113.116 52.1897 108.891 47.9648C104.666 43.74 99.1378 41.3343 93.3258 41.1875Z" fill="black" stroke="black" stroke-width="0.5"/>
8
+ <path d="M90.8114 87.9707C95.8766 87.9707 100.717 88.9421 105.487 90.8604C110.082 92.7092 114.266 95.3255 117.923 98.6387C121.585 101.957 124.47 105.752 126.505 109.915C128.621 114.247 129.691 118.74 129.691 123.273V154.69L58.2323 150.313V117.282C58.2323 112.643 58.9888 108.44 60.4686 104.782C61.8248 101.432 63.7951 98.5242 66.329 96.1221L66.8436 95.6484C69.6214 93.1654 73.0483 91.2474 77.0399 89.9541C81.0905 88.6411 85.7222 87.9707 90.8114 87.9707Z" fill="white" stroke="black"/>
9
+ <path d="M90.8111 88.2029C85.7553 88.2029 81.1466 88.8669 77.1121 90.1733C73.1596 91.4543 69.7578 93.3544 67.0004 95.8209C64.243 98.2873 62.1183 101.332 60.6869 104.868C59.2145 108.506 58.4666 112.683 58.4666 117.28V150.094L129.459 154.443V123.274C129.459 118.772 128.395 114.312 126.296 110.018C124.273 105.878 121.404 102.107 117.766 98.8106C114.183 95.5611 109.906 92.8877 105.401 91.0755C100.661 89.1695 95.7518 88.2029 90.8111 88.2029ZM90.8111 86.7383C111.831 86.7383 130.922 103.861 130.922 123.274V156L57 151.471V117.28C57 97.8674 69.789 86.7363 90.8111 86.7363V86.7383Z" fill="black"/>
10
+ <path d="M84.9657 56L84.8179 62.1015" stroke="black" stroke-width="2" stroke-linecap="round"/>
11
+ <path d="M97.9657 57L97.8179 63.1015" stroke="black" stroke-width="2" stroke-linecap="round"/>
12
+ <path d="M82 71.4994C87.5 76.9995 96.4287 76.6018 102 73.254" stroke="black" stroke-width="2" stroke-linecap="round"/>
13
+ <path d="M103.032 111.325L107.248 107.962C109.739 105.976 113.485 106.359 115.567 108.862C119.157 113.176 123.691 112.494 125.647 107.326C126.772 104.367 130.189 102.871 133.239 104.047L137.5 105C140.193 105.985 143.088 110.23 142.127 112.86L141.89 113.485C139.915 118.63 142.85 122.157 148.416 121.327L147 119C149.825 118.611 154.607 122.734 155.049 125.515L156.108 131.53C156.668 134.692 154.48 137.666 151.293 138.146C145.727 138.976 144.129 143.186 147.719 147.5C149.781 149.979 149.451 153.653 146.936 155.658L142.72 159.021C140.229 161.008 136.483 160.624 134.4 158.122C130.81 153.807 126.276 154.489 124.32 159.657C123.172 162.635 119.779 164.112 116.728 162.937L110.925 160.704C108.232 159.719 105.244 155.237 106.205 152.607L108.077 153.498C110.053 148.353 107.117 144.826 101.552 145.656L100.878 145.757C98.0539 146.146 94.3369 142.802 93.8959 140.021L93.8591 135.454C93.2999 132.291 95.4876 129.317 98.6749 128.837C104.241 128.007 105.839 123.798 102.249 119.483C100.166 116.98 100.54 113.311 103.032 111.325Z" fill="black" stroke="black" stroke-width="2.03016"/>
14
+ <path d="M101.582 109.425L105.675 106.09C108.094 104.12 111.705 104.467 113.695 106.909C117.124 111.118 121.504 110.414 123.431 105.322C124.538 102.408 127.847 100.911 130.781 102.042L136.362 104.19C138.952 105.137 140.233 108.04 139.287 110.63L139.053 111.246C137.107 116.314 139.912 119.756 145.288 118.897L145.938 118.793C148.666 118.389 151.25 120.231 151.654 122.959L152.63 128.858C153.145 131.96 151.011 134.898 147.932 135.394C142.557 136.253 140.982 140.4 144.412 144.609C146.383 147.028 146.036 150.639 143.594 152.629L139.5 155.964C137.081 157.935 133.47 157.587 131.481 155.145C128.051 150.936 123.671 151.64 121.745 156.731C120.614 159.665 117.328 161.143 114.394 160.012L108.814 157.864C106.223 156.917 104.942 154.015 105.889 151.424L106.122 150.809C108.068 145.74 105.263 142.298 99.8875 143.157L99.2372 143.261C96.5092 143.665 93.9251 141.823 93.5213 139.095L92.5454 133.196C92.0305 130.094 94.1641 127.156 97.2427 126.66C102.619 125.801 104.193 121.654 100.763 117.445C98.7736 115.003 99.1631 111.396 101.582 109.425Z" fill="url(#paint0_linear_261_3781)" stroke="black" stroke-width="2"/>
15
+ <path d="M121.5 104.5C122.333 103 125.5 98.5005 131 100" stroke="white" stroke-width="2"/>
16
+ <path d="M131.687 134.488C133.602 129.455 131.074 123.823 126.041 121.908C121.008 119.994 115.376 122.521 113.461 127.554C111.547 132.587 114.075 138.219 119.107 140.134C124.14 142.048 129.772 139.521 131.687 134.488Z" fill="white" stroke="black" stroke-width="2"/>
17
+ <path d="M64.5 86C43.3333 86 13 98.2889 13 118.359C13 122.469 13.4387 125.15 15 128.499M43.3333 151.999C39.017 150.554 30.9367 146.961 24 140.499" stroke="black" stroke-width="2" stroke-linecap="round"/>
18
+ <path d="M135 95.5C150 98 170.5 107.5 177.777 114.5M162 169C177 165.5 190 154 190 141C190 134.891 188.66 129.722 186.5 125.385M145.5 112C160.5 114.5 177.4 129.8 177 141C176.797 143.035 176.117 145.235 174.818 147.5" stroke="black" stroke-width="2" stroke-linecap="round"/>
19
+ <path d="M164.255 151.674L170.597 146.165C171.185 145.654 172.106 145.982 172.238 146.75L173.702 155.265C173.833 156.03 173.081 156.646 172.357 156.367L164.552 153.362C163.848 153.091 163.686 152.169 164.255 151.674Z" fill="#0AD5AB"/>
20
+ <path d="M49.5 78.626C43.173 79.1231 28.0153 82.4477 18 91.7695" stroke="black" stroke-width="2" stroke-linecap="round"/>
21
+ <circle cx="19.5" cy="134.5" r="3.5" stroke="black" stroke-width="2" stroke-linecap="round"/>
22
+ <path d="M142.837 75.9891C146.34 76.2353 149.405 74.0299 151.579 72.1127C151.907 71.8239 152.48 72.2127 152.36 72.6325C151.239 76.5353 152.142 79.9759 153.606 82.1521C153.79 82.4256 153.614 82.8211 153.287 82.863C150.605 83.2068 147.316 84.6827 144.39 87.3847C144.093 87.6585 143.573 87.3858 143.633 86.9867C144.135 83.6512 143.994 79.8365 142.383 76.6596C142.226 76.3506 142.492 75.9648 142.837 75.9891Z" fill="black"/>
23
+ <circle cx="182.5" cy="119.5" r="3.5" stroke="black" stroke-width="2" stroke-linecap="round"/>
24
+ <g clip-path="url(#clip0_261_3781)">
25
+ <path d="M81.2112 158.962L90.0709 148.816L77.2975 144.54L68.4379 154.687L81.2112 158.962Z" fill="#0AD5AB"/>
26
+ <path d="M91.3754 153.623L82.5158 163.77L69.7425 159.494M90.0709 148.816L81.2112 158.962L68.4379 154.687L77.2975 144.54L90.0709 148.816Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
27
+ </g>
28
+ <defs>
29
+ <linearGradient id="paint0_linear_261_3781" x1="144.853" y1="99.9755" x2="99.589" y2="151.829" gradientUnits="userSpaceOnUse">
30
+ <stop stop-color="#FFD38F"/>
31
+ <stop offset="0.306473" stop-color="#BFFFF0"/>
32
+ <stop offset="0.578125" stop-color="#6BFFC9"/>
33
+ <stop offset="0.817708" stop-color="#2EE9F3"/>
34
+ <stop offset="1" stop-color="#DAB4FF"/>
35
+ </linearGradient>
36
+ <clipPath id="clip0_261_3781">
37
+ <rect width="29.8871" height="29.8871" fill="white" transform="translate(62.223 146.051) rotate(-15.1828)"/>
38
+ </clipPath>
39
+ </defs>
40
+ </svg>
@@ -0,0 +1,33 @@
1
+ <svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M97.209 80L98.1417 80.1088L98.5925 80.2487L99.3853 80.684L100.069 81.2902L100.349 81.6477L100.769 82.4716L100.986 83.4043L101.841 91.6119H149.222L149.719 91.643L150.621 91.8762L151.429 92.327L152.113 92.9488L152.626 93.7105L152.813 94.1457L153.015 95.0784L157.352 143.578V144.107L157.305 144.604L157.181 145.086L156.994 145.537L156.481 146.361L155.766 147.014L155.346 147.278L154.896 147.48L154.414 147.62L153.559 147.713H68.1559L67.2076 147.604L66.7568 147.449L65.9485 147.014L65.2645 146.392L64.7516 145.63L64.4407 144.744L64.3629 144.262L59.0155 84.1194L59 83.6064L59.0622 83.109L59.1865 82.6271L59.3575 82.1607L59.8861 81.3524L60.228 80.9949L60.6011 80.6995L61.0208 80.4353L61.4716 80.2332L61.9535 80.0933L62.7929 80H97.209Z" fill="black" stroke="black" stroke-width="2"/>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M65.0364 67.0061L98.7374 47.5441L99.2349 47.2953L99.7478 47.1244L100.261 47.0311L100.789 47L101.302 47.0311L101.815 47.1399L102.297 47.3109L102.764 47.5285L103.199 47.8239L103.603 48.1659L103.96 48.57L104.271 49.0208L124.728 84.4629L124.977 84.9603L125.148 85.4733L125.241 85.9863L125.272 86.5148L125.241 87.0278L125.132 87.5408L124.961 88.0226L124.744 88.489L124.448 88.9398L124.106 89.3284L123.702 89.6859L123.236 89.9968L89.5505 109.459L89.0375 109.708L88.5401 109.879L88.0115 109.972L87.483 110.003L86.97 109.972L86.4726 109.863L85.9752 109.692L85.5088 109.474L85.0736 109.179L84.6694 108.837L84.3119 108.433L84.001 107.967L63.5441 72.5401L63.2953 72.0426L63.1244 71.5296L63.0311 71.0167L63 70.4881L63.0311 69.9752L63.1399 69.4622L63.3109 68.9648L63.5285 68.4984L63.8239 68.0632L64.1659 67.659L64.57 67.317L65.0364 67.0061Z" fill="black" stroke="black" stroke-width="2"/>
4
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M59.0364 69.4052L92.7374 49.9431L93.2349 49.6944L93.7323 49.5234L94.2608 49.4301L94.7893 49.399L95.3023 49.4301L95.7997 49.5389L96.2972 49.7099L96.7635 49.9276L97.1988 50.2229L97.6029 50.5649L97.9605 50.9691L98.2714 51.4199L119.226 87.7325L119.474 88.2299L119.645 88.7429L119.739 89.2558L119.77 89.7844L119.739 90.2973L119.63 90.8103L119.474 91.3077L119.241 91.7741L118.961 92.2094L118.619 92.6135L118.215 92.9555L117.749 93.2819L84.0479 112.728L83.5505 112.977L83.0375 113.148L82.5245 113.241L81.996 113.273L81.483 113.241L80.97 113.133L80.4726 112.977L80.0063 112.744L79.571 112.449L79.1668 112.107L78.8249 111.718L78.514 111.252L57.5441 74.9391L57.2953 74.4417L57.1244 73.9287L57.0311 73.4157L57 72.8872L57.0311 72.3742L57.1399 71.8612L57.3109 71.3638L57.5285 70.913L57.8239 70.4622L58.1659 70.0736L58.57 69.7161L59.0364 69.4052Z" fill="white" stroke="black" stroke-width="2"/>
5
+ <path d="M78.4998 70.0001L93.0908 61.0028" stroke="black" stroke-width="2" stroke-linecap="round"/>
6
+ <path d="M84.0028 76.0049L97.5 67.9999" stroke="black" stroke-width="2" stroke-linecap="round"/>
7
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M116.211 66.467L154.637 72.5451L155.181 72.6694L155.694 72.8559L156.145 73.1047L156.58 73.4156L156.954 73.7731L157.296 74.1773L157.56 74.6125L157.793 75.0788L157.948 75.5763L158.042 76.1048L158.057 76.6333L158.011 77.1929L151.777 116.599L151.653 117.143L151.466 117.64L151.218 118.107L150.907 118.542L150.549 118.915L150.145 119.242L149.71 119.521L149.243 119.739L148.746 119.91L148.217 120.003L147.689 120.019L147.129 119.972L108.703 113.879L108.158 113.754L107.646 113.568L107.195 113.319L106.759 113.024L106.386 112.666L106.044 112.262L105.765 111.827L105.547 111.36L105.392 110.847L105.298 110.334L105.283 109.806L105.329 109.246L111.563 69.8403L111.687 69.2962L111.874 68.7832L112.122 68.3169L112.433 67.8972L112.791 67.5241L113.195 67.1821L113.63 66.9023L114.097 66.6847L114.594 66.5292L115.123 66.436L115.651 66.4204L116.211 66.467Z" fill="black" stroke="black" stroke-width="2"/>
8
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M110.254 64.0466L148.697 70.1402L149.241 70.2645L149.738 70.4511L150.204 70.6998L150.624 71.0107L150.997 71.3682L151.339 71.7568L151.619 72.2076L151.837 72.674L151.992 73.1714L152.085 73.6844L152.116 74.2285L152.054 74.7881L145.494 116.184L145.37 116.728L145.184 117.241L144.935 117.692L144.639 118.127L144.282 118.5L143.878 118.842L143.442 119.122L142.976 119.339L142.479 119.495L141.95 119.588L141.422 119.604L140.862 119.557L102.42 113.479L101.876 113.355L101.378 113.168L100.912 112.919L100.492 112.608L100.119 112.251L99.7772 111.847L99.4974 111.412L99.2798 110.945L99.1244 110.448L99.0311 109.919L99 109.391L99.0622 108.831L105.622 67.4198L105.746 66.8758L105.933 66.3784L106.182 65.912L106.477 65.4923L106.835 65.1037L107.239 64.7772L107.674 64.4974L108.14 64.2798L108.638 64.1244L109.166 64.0311L109.695 64L110.254 64.0466Z" fill="white" stroke="black" stroke-width="2"/>
9
+ <path d="M123.538 90.5305L124.426 84.2124L130.17 85.0199" stroke="white" stroke-width="2"/>
10
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M90.1935 78.9644L91.1417 79.0732L91.577 79.2131L92.3853 79.6483L93.0537 80.2546L93.3335 80.6121L93.7688 81.436L93.9709 82.3687L94.8414 90.5763H142.222L142.719 90.6074L143.621 90.8406L144.429 91.2914L145.113 91.9131L145.626 92.6748L145.797 93.1101L146.015 94.0428L150.336 144.542L150.352 145.071L150.29 145.568L150.181 146.05L149.994 146.501L149.466 147.325L149.139 147.667L148.766 147.978L148.346 148.242L147.896 148.444L147.414 148.584L146.559 148.677H61.1559L60.1921 148.569L59.7568 148.413L58.9485 147.978L58.2645 147.356L57.7516 146.594L57.4407 145.708L57.3629 145.226L52 83.0837V82.5707L52.0622 82.0733L52.171 81.5914L52.3575 81.1251L52.5907 80.7054L52.8861 80.3167L53.228 79.9592L53.6011 79.6639L54.0208 79.3996L54.4716 79.1975L54.9535 79.0576L55.7929 78.9644H90.1935Z" fill="white" stroke="black" stroke-width="2"/>
11
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M63.0055 86.7728L62.9744 87.1458L62.8811 87.4878L62.7257 87.7987L62.2904 88.3273L61.6842 88.6692L61.3422 88.7625L60.9847 88.8091L60.2696 88.6692L59.6789 88.3273L59.2281 87.7987L59.0882 87.4878L58.995 87.1458L58.9639 86.7728L58.995 86.4152L59.0882 86.0733L59.4302 85.4826L59.9587 85.0318L60.2696 84.8919L60.6116 84.7986L60.9847 84.752L61.6842 84.8919L62.2904 85.2338L62.7257 85.7624L62.8811 86.0733L62.9744 86.4152L63.0055 86.7728Z" fill="#0AD5AB"/>
12
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M69.068 86.7728L69.0369 87.1769L68.9126 87.55L68.726 87.9075L68.4773 88.2029L68.1664 88.4672L67.8244 88.6537L67.4514 88.7625L67.0472 88.8091L66.6586 88.7625L66.2699 88.6537L65.928 88.4672L65.6171 88.2029L65.3684 87.9075L65.1818 87.55L65.0575 87.1769L65.0264 86.7728L65.0575 86.3842L65.1818 86.0111L65.3684 85.6536L65.6171 85.3582L65.928 85.0939L66.2699 84.9074L66.6586 84.7986L67.0472 84.752L67.4514 84.7986L67.8244 84.9074L68.1664 85.0939L68.4773 85.3582L68.726 85.6536L68.9126 86.0111L69.0369 86.3842L69.068 86.7728Z" fill="#0AD5AB"/>
13
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M75.1456 86.7728L75.0057 87.4878L74.6637 88.0785L74.1352 88.5293L73.8243 88.6692L73.1092 88.8091L72.7206 88.7625L72.3475 88.6537L71.99 88.4672L71.6791 88.2029L71.4304 87.9075L71.2438 87.55L71.135 87.1769L71.0884 86.7728L71.135 86.3842L71.2438 86.0111L71.4304 85.6536L71.6791 85.3582L71.99 85.0939L72.3475 84.9074L72.7206 84.7986L73.1092 84.752L73.4823 84.7986L73.8243 84.8919L74.415 85.2338L74.8658 85.7624L75.0057 86.0733L75.0989 86.4152L75.1456 86.7728Z" fill="#0AD5AB"/>
14
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M118.86 121.412L118.824 122.77L118.679 124.074L118.462 125.341L118.172 126.591L117.792 127.804L117.339 128.981L116.814 130.122L116.216 131.227L115.546 132.277L114.822 133.291L114.025 134.251L113.174 135.156L112.269 136.007L111.309 136.804L110.295 137.528L109.245 138.198L108.14 138.796L106.999 139.321L105.822 139.774L104.591 140.154L103.36 140.444L102.074 140.661L100.77 140.806L99.4301 140.842L98.0901 140.806L96.7682 140.661L95.5006 140.444L94.2693 140.154L93.0379 139.774L91.8609 139.321L90.72 138.796L89.6154 138.198L88.5652 137.528L87.5511 136.804L86.5914 136.007L85.686 135.156L84.8349 134.251L84.0381 133.291L83.3138 132.277L82.6438 131.227L82.0462 130.122L81.5211 128.981L81.0684 127.804L80.6881 126.591L80.3803 125.341L80.1811 124.074L80.0362 122.77L80 121.412L80.0362 120.072L80.1811 118.768L80.3803 117.501L80.6881 116.251L81.0684 115.038L81.5211 113.861L82.0462 112.72L82.6438 111.615L83.3138 110.547L84.0381 109.551L84.8349 108.591L85.686 107.686L86.5914 106.835L87.5511 106.038L88.5652 105.314L89.6154 104.644L90.72 104.046L91.8609 103.521L93.0379 103.068L94.2693 102.688L95.5006 102.398L96.7682 102.181L98.0901 102.036L99.4301 102L100.77 102.036L102.074 102.181L103.36 102.398L104.591 102.688L105.822 103.068L106.999 103.521L108.14 104.046L109.245 104.644L110.295 105.314L111.309 106.038L112.269 106.835L113.174 107.686L114.025 108.591L114.822 109.551L115.546 110.547L116.216 111.615L116.814 112.72L117.339 113.861L117.792 115.038L118.172 116.251L118.462 117.501L118.679 118.768L118.824 120.072L118.86 121.412Z" fill="url(#paint0_linear_261_3812)" stroke="black" stroke-width="2"/>
15
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M99.2806 112.605C99.3802 112.597 99.4802 112.597 99.5798 112.605L100.155 112.648L100.681 112.745C100.788 112.764 100.894 112.793 100.998 112.83L101.495 113.01L102.11 113.318L102.672 113.698L103.064 114.034C103.14 114.1 103.212 114.171 103.277 114.247L103.631 114.658L104.012 115.219L104.249 115.68C104.296 115.771 104.336 115.866 104.368 115.963L104.537 116.469L104.682 117.157L104.736 117.881L104.71 118.33C104.703 118.441 104.687 118.551 104.662 118.66L104.481 119.45C104.458 119.551 104.427 119.649 104.389 119.745L104.293 119.985C104.25 120.091 104.199 120.193 104.139 120.291L103.754 120.916C103.685 121.029 103.604 121.135 103.513 121.232L102.932 121.855C102.903 121.886 102.872 121.914 102.839 121.939C102.596 122.124 102.492 122.438 102.576 122.731L104.003 127.697C104.37 128.975 103.41 130.249 102.08 130.249H97.2627C95.9681 130.249 95.0147 129.038 95.3186 127.779L96.4299 123.179C96.5458 122.699 96.3649 122.196 95.9696 121.9C95.9227 121.864 95.8783 121.826 95.8368 121.784L95.4464 121.394L95.0661 120.905L94.8158 120.502C94.7654 120.421 94.721 120.336 94.6827 120.249L94.4867 119.8L94.3316 119.321C94.3022 119.23 94.2794 119.138 94.2633 119.043L94.1788 118.551L94.1371 118.037C94.1287 117.933 94.1284 117.829 94.1362 117.725L94.1788 117.157L94.3237 116.469L94.4922 115.963C94.5247 115.866 94.5646 115.771 94.6116 115.68L94.8488 115.219L95.2291 114.658L95.5832 114.247C95.6489 114.171 95.7201 114.1 95.7965 114.034L96.1888 113.698L96.7502 113.318L97.3659 113.01L97.8628 112.83C97.9659 112.793 98.072 112.764 98.1798 112.745L98.7059 112.648L99.2806 112.605Z" fill="white" stroke="black" stroke-width="2" stroke-linejoin="round"/>
16
+ <path d="M51.7197 74.1664C39.511 76.3192 16.1791 86.7035 16.7037 111.201M47 148C36 143.5 27 135 22.9709 126.462" stroke="black" stroke-width="2" stroke-linecap="round"/>
17
+ <path d="M43.6172 64C35.9015 66.7225 18.8897 75.0104 12.5684 86.3824" stroke="black" stroke-width="2" stroke-linecap="round"/>
18
+ <path d="M163 95.0002C175.5 100.5 189.892 114.138 186.352 132.542C183.139 149.251 172.067 158.441 147.973 162.066M108 162.066C118 164.5 127.424 164.074 134.924 163.552" stroke="black" stroke-width="2" stroke-linecap="round"/>
19
+ <path d="M167.241 118.978C183.05 126.954 200.671 146.381 182.418 161.94M140.541 176.722C148.901 176.299 159.527 174.604 169.49 170.065" stroke="black" stroke-width="2" stroke-linecap="round"/>
20
+ <rect x="16.6733" y="114.751" width="7" height="7" rx="2" transform="rotate(20.5354 16.6733 114.751)" stroke="black" stroke-width="2" stroke-linecap="round"/>
21
+ <circle cx="141.465" cy="162.243" r="3.5" transform="rotate(1.67485 141.465 162.243)" fill="#0AD5AB"/>
22
+ <circle cx="176.391" cy="165.265" r="3.5" transform="rotate(1.67485 176.391 165.265)" stroke="black" stroke-width="2" stroke-linecap="round"/>
23
+ <path d="M49.4226 47.3207C52.1575 45.5952 53.2782 42.3164 53.8833 39.6886C53.9813 39.2631 54.6798 39.2426 54.8316 39.6521C56.1316 43.157 58.6624 45.2445 60.9434 46.0992C61.2521 46.2149 61.341 46.6398 61.1016 46.8664C59.2723 48.5976 57.6048 51.4912 56.8579 55.1037C56.7762 55.499 56.1927 55.5827 56.0063 55.2247C54.5584 52.4435 52.3769 49.6627 49.4473 48.1354C49.14 47.9752 49.1295 47.5056 49.4226 47.3207Z" fill="black"/>
24
+ <defs>
25
+ <linearGradient id="paint0_linear_261_3812" x1="106.191" y1="97.5109" x2="91.5193" y2="139.938" gradientUnits="userSpaceOnUse">
26
+ <stop stop-color="#FFD38F"/>
27
+ <stop offset="0.306473" stop-color="#BFFFF0"/>
28
+ <stop offset="0.578125" stop-color="#6BFFC9"/>
29
+ <stop offset="0.817708" stop-color="#2EE9F3"/>
30
+ <stop offset="1" stop-color="#DAB4FF"/>
31
+ </linearGradient>
32
+ </defs>
33
+ </svg>