@uipath/apollo-wind 0.9.1 → 0.10.0-pr219.61d64eb

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 (158) hide show
  1. package/dist/components/custom/canvas.cjs +44 -0
  2. package/dist/components/custom/canvas.d.ts +14 -0
  3. package/dist/components/custom/canvas.js +10 -0
  4. package/dist/components/custom/chat-composer.cjs +105 -0
  5. package/dist/components/custom/chat-composer.d.ts +15 -0
  6. package/dist/components/custom/chat-composer.js +71 -0
  7. package/dist/components/custom/chat-first-experience.cjs +87 -0
  8. package/dist/components/custom/chat-first-experience.d.ts +24 -0
  9. package/dist/components/custom/chat-first-experience.js +53 -0
  10. package/dist/components/custom/chat-prompt-suggestions.cjs +48 -0
  11. package/dist/components/custom/chat-prompt-suggestions.d.ts +18 -0
  12. package/dist/components/custom/chat-prompt-suggestions.js +14 -0
  13. package/dist/components/custom/chat-steps-view.cjs +307 -0
  14. package/dist/components/custom/chat-steps-view.d.ts +38 -0
  15. package/dist/components/custom/chat-steps-view.js +273 -0
  16. package/dist/components/custom/flow-node.cjs +76 -0
  17. package/dist/components/custom/flow-node.d.ts +20 -0
  18. package/dist/components/custom/flow-node.js +42 -0
  19. package/dist/components/custom/flow-properties-bar.cjs +101 -0
  20. package/dist/components/custom/flow-properties-bar.d.ts +21 -0
  21. package/dist/components/custom/flow-properties-bar.js +67 -0
  22. package/dist/components/custom/flow-properties-expanded.cjs +324 -0
  23. package/dist/components/custom/flow-properties-expanded.d.ts +19 -0
  24. package/dist/components/custom/flow-properties-expanded.js +290 -0
  25. package/dist/components/custom/flow-properties-simple.cjs +357 -0
  26. package/dist/components/custom/flow-properties-simple.d.ts +62 -0
  27. package/dist/components/custom/flow-properties-simple.js +323 -0
  28. package/dist/components/custom/flow-properties.cjs +56 -0
  29. package/dist/components/custom/flow-properties.d.ts +28 -0
  30. package/dist/components/custom/flow-properties.js +22 -0
  31. package/dist/components/custom/global-header.cjs +415 -0
  32. package/dist/components/custom/global-header.d.ts +38 -0
  33. package/dist/components/custom/global-header.js +381 -0
  34. package/dist/components/custom/grid-maestro.cjs +62 -0
  35. package/dist/components/custom/grid-maestro.d.ts +19 -0
  36. package/dist/components/custom/grid-maestro.js +22 -0
  37. package/dist/components/custom/panel-delegate.cjs +280 -0
  38. package/dist/components/custom/panel-delegate.d.ts +34 -0
  39. package/dist/components/custom/panel-delegate.js +246 -0
  40. package/dist/components/custom/panel-flow.cjs +260 -0
  41. package/dist/components/custom/panel-flow.d.ts +38 -0
  42. package/dist/components/custom/panel-flow.js +223 -0
  43. package/dist/components/custom/panel-maestro.cjs +73 -0
  44. package/dist/components/custom/panel-maestro.d.ts +30 -0
  45. package/dist/components/custom/panel-maestro.js +39 -0
  46. package/dist/components/custom/toolbar-canvas.cjs +121 -0
  47. package/dist/components/custom/toolbar-canvas.d.ts +15 -0
  48. package/dist/components/custom/toolbar-canvas.js +87 -0
  49. package/dist/components/custom/toolbar-view.cjs +119 -0
  50. package/dist/components/custom/toolbar-view.d.ts +14 -0
  51. package/dist/components/custom/toolbar-view.js +85 -0
  52. package/dist/components/custom/viewport-guard.cjs +92 -0
  53. package/dist/components/custom/viewport-guard.d.ts +23 -0
  54. package/dist/components/custom/viewport-guard.js +55 -0
  55. package/dist/components/ui/button.cjs +3 -3
  56. package/dist/components/ui/button.js +3 -3
  57. package/dist/components/ui/chart.cjs +218 -0
  58. package/dist/components/ui/chart.d.ts +40 -0
  59. package/dist/components/ui/chart.js +169 -0
  60. package/dist/components/ui/data-table.cjs +14 -2
  61. package/dist/components/ui/data-table.d.ts +4 -1
  62. package/dist/components/ui/data-table.js +15 -3
  63. package/dist/components/ui/empty-state.cjs +17 -6
  64. package/dist/components/ui/empty-state.d.ts +7 -0
  65. package/dist/components/ui/empty-state.js +17 -6
  66. package/dist/components/ui/file-upload.cjs +82 -42
  67. package/dist/components/ui/file-upload.d.ts +3 -1
  68. package/dist/components/ui/file-upload.js +82 -42
  69. package/dist/components/ui/index.cjs +289 -149
  70. package/dist/components/ui/index.d.ts +2 -3
  71. package/dist/components/ui/index.js +2 -3
  72. package/dist/components/ui/tree-view.cjs +1101 -0
  73. package/dist/components/ui/tree-view.d.ts +95 -0
  74. package/dist/components/ui/tree-view.js +1067 -0
  75. package/dist/foundation/Future/colors.cjs +92 -0
  76. package/dist/foundation/Future/colors.d.ts +132 -0
  77. package/dist/foundation/Future/colors.js +43 -0
  78. package/dist/foundation/Future/radius.cjs +46 -0
  79. package/dist/foundation/Future/radius.d.ts +33 -0
  80. package/dist/foundation/Future/radius.js +12 -0
  81. package/dist/foundation/Future/responsive.cjs +49 -0
  82. package/dist/foundation/Future/responsive.d.ts +40 -0
  83. package/dist/foundation/Future/responsive.js +12 -0
  84. package/dist/foundation/Future/shadows.cjs +48 -0
  85. package/dist/foundation/Future/shadows.d.ts +29 -0
  86. package/dist/foundation/Future/shadows.js +11 -0
  87. package/dist/foundation/Future/spacing.cjs +71 -0
  88. package/dist/foundation/Future/spacing.d.ts +80 -0
  89. package/dist/foundation/Future/spacing.js +31 -0
  90. package/dist/foundation/Future/strokes.cjs +59 -0
  91. package/dist/foundation/Future/strokes.d.ts +49 -0
  92. package/dist/foundation/Future/strokes.js +19 -0
  93. package/dist/foundation/Future/types.cjs +18 -0
  94. package/dist/foundation/Future/types.d.ts +18 -0
  95. package/dist/foundation/Future/types.js +0 -0
  96. package/dist/foundation/Future/typography.cjs +79 -0
  97. package/dist/foundation/Future/typography.d.ts +86 -0
  98. package/dist/foundation/Future/typography.js +33 -0
  99. package/dist/index.cjs +125 -219
  100. package/dist/index.d.ts +2 -3
  101. package/dist/index.js +2 -4
  102. package/dist/src/foundation/Future/themes.css +371 -0
  103. package/dist/styles.css +1704 -582
  104. package/dist/tailwind.css +4 -0
  105. package/dist/templates/Admin/settings-admin.d.ts +5 -0
  106. package/dist/templates/Admin/template-admin.d.ts +105 -0
  107. package/dist/templates/Delegate/template-delegate.d.ts +26 -0
  108. package/dist/templates/EmptyErrors/error-components.d.ts +3 -0
  109. package/dist/templates/Experiments/ideas-AnimatedGradientText.d.ts +23 -0
  110. package/dist/templates/Flow/template-flow.d.ts +52 -0
  111. package/dist/templates/Maestro/template-maestro.d.ts +52 -0
  112. package/dist/templates/{vscode-example.d.ts → VisualStudio/shell.d.ts} +1 -1
  113. package/package.json +10 -1
  114. package/dist/components/ui/menubar.cjs +0 -210
  115. package/dist/components/ui/menubar.d.ts +0 -28
  116. package/dist/components/ui/menubar.js +0 -131
  117. package/dist/components/ui/navigation-menu.cjs +0 -122
  118. package/dist/components/ui/navigation-menu.d.ts +0 -12
  119. package/dist/components/ui/navigation-menu.js +0 -64
  120. package/dist/examples/admin-layout-example.cjs +0 -490
  121. package/dist/examples/admin-layout-example.d.ts +0 -92
  122. package/dist/examples/admin-layout-example.js +0 -411
  123. package/dist/examples/app-shell-example.cjs +0 -452
  124. package/dist/examples/app-shell-example.d.ts +0 -52
  125. package/dist/examples/app-shell-example.js +0 -418
  126. package/dist/examples/dashboard-example.cjs +0 -590
  127. package/dist/examples/dashboard-example.d.ts +0 -11
  128. package/dist/examples/dashboard-example.js +0 -556
  129. package/dist/examples/data-management-example.cjs +0 -584
  130. package/dist/examples/data-management-example.d.ts +0 -1
  131. package/dist/examples/data-management-example.js +0 -550
  132. package/dist/examples/flow-editor-layout-example.cjs +0 -309
  133. package/dist/examples/flow-editor-layout-example.d.ts +0 -22
  134. package/dist/examples/flow-editor-layout-example.js +0 -269
  135. package/dist/examples/flow-start-example.cjs +0 -467
  136. package/dist/examples/flow-start-example.d.ts +0 -30
  137. package/dist/examples/flow-start-example.js +0 -433
  138. package/dist/examples/form-builder-example.cjs +0 -674
  139. package/dist/examples/form-builder-example.js +0 -640
  140. package/dist/examples/new-project-example.cjs +0 -550
  141. package/dist/examples/new-project-example.d.ts +0 -30
  142. package/dist/examples/new-project-example.js +0 -516
  143. package/dist/examples/settings-example.cjs +0 -864
  144. package/dist/examples/settings-example.d.ts +0 -1
  145. package/dist/examples/settings-example.js +0 -830
  146. package/dist/examples/vscode-example.cjs +0 -340
  147. package/dist/examples/vscode-example.d.ts +0 -80
  148. package/dist/examples/vscode-example.js +0 -270
  149. package/dist/templates/admin-layout-example.d.ts +0 -92
  150. package/dist/templates/app-shell-example.d.ts +0 -52
  151. package/dist/templates/dashboard-example.d.ts +0 -11
  152. package/dist/templates/data-management-example.d.ts +0 -1
  153. package/dist/templates/flow-editor-layout-example.d.ts +0 -22
  154. package/dist/templates/flow-start-example.d.ts +0 -30
  155. package/dist/templates/form-builder-example.d.ts +0 -1
  156. package/dist/templates/new-project-example.d.ts +0 -30
  157. package/dist/templates/settings-example.d.ts +0 -1
  158. /package/dist/{examples → templates/Forms}/form-builder-example.d.ts +0 -0
@@ -32,29 +32,53 @@ const external_lucide_react_namespaceObject = require("lucide-react");
32
32
  const external_react_namespaceObject = require("react");
33
33
  const external_button_cjs_namespaceObject = require("./button.cjs");
34
34
  const index_cjs_namespaceObject = require("../../lib/index.cjs");
35
- function FileUpload({ onFilesChange, accept, multiple = false, disabled = false, maxSize, className, showPreview = false }) {
35
+ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false, maxSize, className, showPreview = false, errors }) {
36
36
  const [files, setFiles] = external_react_namespaceObject.useState([]);
37
37
  const [isDragging, setIsDragging] = external_react_namespaceObject.useState(false);
38
- const [error, setError] = external_react_namespaceObject.useState('');
38
+ const [fileErrors, setFileErrors] = external_react_namespaceObject.useState(new Map());
39
39
  const [previews, setPreviews] = external_react_namespaceObject.useState([]);
40
40
  const inputRef = external_react_namespaceObject.useRef(null);
41
- const validateFiles = (fileList)=>{
42
- setError('');
41
+ const isFileTypeAccepted = (file)=>{
42
+ if (!accept) return true;
43
+ const acceptedTypes = accept.split(',').map((type)=>type.trim().toLowerCase());
44
+ for (const acceptedType of acceptedTypes)if (acceptedType.endsWith('/*')) {
45
+ const baseType = acceptedType.slice(0, -2);
46
+ if (file.type.toLowerCase().startsWith(baseType)) return true;
47
+ } else if (acceptedType.includes('/')) {
48
+ if (file.type.toLowerCase() === acceptedType) return true;
49
+ } else if (acceptedType.startsWith('.')) {
50
+ if (file.name.toLowerCase().endsWith(acceptedType)) return true;
51
+ }
52
+ return false;
53
+ };
54
+ const validateFiles = (fileList, startIndex, existingErrors)=>{
43
55
  const validFiles = [];
56
+ const errors = multiple ? new Map(existingErrors) : new Map();
44
57
  for (const file of fileList){
58
+ const fileIndex = startIndex + validFiles.length;
59
+ if (!isFileTypeAccepted(file)) {
60
+ errors.set(fileIndex, 'File type not accepted');
61
+ validFiles.push(file);
62
+ continue;
63
+ }
45
64
  if (maxSize && file.size > maxSize) {
46
- setError(`File "${file.name}" exceeds maximum size of ${formatFileSize(maxSize)}`);
65
+ errors.set(fileIndex, `Exceeds maximum size of ${formatFileSize(maxSize)}`);
66
+ validFiles.push(file);
47
67
  continue;
48
68
  }
49
69
  const isDuplicate = files.some((existingFile)=>existingFile.name === file.name && existingFile.size === file.size);
50
70
  if (!isDuplicate) validFiles.push(file);
51
71
  }
52
- return validFiles;
72
+ return {
73
+ validFiles,
74
+ errors
75
+ };
53
76
  };
54
77
  const handleFiles = (fileList)=>{
55
78
  if (!fileList || 0 === fileList.length) return;
56
79
  const filesArray = Array.from(fileList);
57
- const validFiles = validateFiles(filesArray);
80
+ const startIndex = multiple ? files.length : 0;
81
+ const { validFiles, errors } = validateFiles(filesArray, startIndex, fileErrors);
58
82
  if (0 === validFiles.length) return;
59
83
  const newFiles = multiple ? [
60
84
  ...files,
@@ -62,6 +86,7 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
62
86
  ] : validFiles;
63
87
  setFiles(newFiles);
64
88
  onFilesChange?.(newFiles);
89
+ setFileErrors(errors);
65
90
  if (showPreview) {
66
91
  const newPreviews = [];
67
92
  validFiles.forEach((file)=>{
@@ -87,7 +112,14 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
87
112
  const newPreviews = previews.filter((_, i)=>i !== index);
88
113
  setPreviews(newPreviews);
89
114
  }
90
- setError('');
115
+ setFileErrors((prev)=>{
116
+ const updated = new Map();
117
+ prev.forEach((error, i)=>{
118
+ if (i < index) updated.set(i, error);
119
+ else if (i > index) updated.set(i - 1, error);
120
+ });
121
+ return updated;
122
+ });
91
123
  };
92
124
  const handleDragEnter = (e)=>{
93
125
  e.preventDefault();
@@ -132,7 +164,7 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
132
164
  className: (0, index_cjs_namespaceObject.cn)('w-full', className),
133
165
  children: [
134
166
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
135
- className: (0, index_cjs_namespaceObject.cn)('relative flex flex-col items-center justify-center w-full h-32 px-4 py-6 border-2 border-dashed rounded-lg cursor-pointer transition-colors', isDragging ? 'border-primary bg-primary/5' : 'border-input bg-background hover:bg-accent/50', disabled && 'opacity-50 cursor-not-allowed hover:bg-background', error && 'border-destructive'),
167
+ className: (0, index_cjs_namespaceObject.cn)('relative flex flex-col items-center justify-center w-full h-32 px-4 py-6 border-2 border-dashed rounded-lg cursor-pointer transition-colors', isDragging ? 'border-primary bg-primary/5' : 'border-input bg-background hover:bg-accent/50', disabled && 'opacity-50 cursor-not-allowed hover:bg-background'),
136
168
  onDragEnter: handleDragEnter,
137
169
  onDragOver: handleDragOver,
138
170
  onDragLeave: handleDragLeave,
@@ -175,54 +207,62 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
175
207
  })
176
208
  ]
177
209
  }),
178
- error && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
179
- className: "text-sm text-destructive mt-2",
180
- children: error
181
- }),
182
210
  files.length > 0 && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
183
211
  className: "mt-4 space-y-2",
184
- children: files.map((file, index)=>/*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
185
- className: "flex items-center justify-between p-3 bg-accent/50 rounded-md",
212
+ children: files.map((file, index)=>{
213
+ const fileError = errors?.[file.name] ?? fileErrors.get(index);
214
+ return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
215
+ className: (0, index_cjs_namespaceObject.cn)('flex flex-col p-3 rounded-md', fileError ? 'bg-destructive/10 border border-destructive/20' : 'bg-accent/50'),
186
216
  children: [
187
217
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
188
- className: "flex items-center gap-3 flex-1 min-w-0",
218
+ className: "flex items-center justify-between",
189
219
  children: [
190
- showPreview && previews[index] && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("img", {
191
- src: previews[index],
192
- alt: file.name,
193
- className: "w-10 h-10 object-cover rounded"
194
- }),
195
220
  /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
196
- className: "flex-1 min-w-0",
221
+ className: "flex items-center gap-3 flex-1 min-w-0",
197
222
  children: [
198
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
199
- className: "text-sm font-medium truncate",
200
- children: file.name
223
+ showPreview && previews[index] && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("img", {
224
+ src: previews[index],
225
+ alt: file.name,
226
+ className: "w-10 h-10 object-cover rounded"
201
227
  }),
202
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
203
- className: "text-xs text-muted-foreground",
204
- children: formatFileSize(file.size)
228
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)("div", {
229
+ className: "flex-1 min-w-0",
230
+ children: [
231
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
232
+ className: "text-sm font-medium truncate",
233
+ children: file.name
234
+ }),
235
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
236
+ className: "text-xs text-muted-foreground",
237
+ children: formatFileSize(file.size)
238
+ })
239
+ ]
205
240
  })
206
241
  ]
242
+ }),
243
+ /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_button_cjs_namespaceObject.Button, {
244
+ variant: "ghost",
245
+ size: "icon",
246
+ className: "h-8 w-8",
247
+ "aria-label": `Remove ${file.name}`,
248
+ onClick: (e)=>{
249
+ e.stopPropagation();
250
+ removeFile(index);
251
+ },
252
+ disabled: disabled,
253
+ children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.X, {
254
+ className: "h-4 w-4"
255
+ })
207
256
  })
208
257
  ]
209
258
  }),
210
- /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_button_cjs_namespaceObject.Button, {
211
- variant: "ghost",
212
- size: "icon",
213
- className: "h-8 w-8",
214
- "aria-label": `Remove ${file.name}`,
215
- onClick: (e)=>{
216
- e.stopPropagation();
217
- removeFile(index);
218
- },
219
- disabled: disabled,
220
- children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_lucide_react_namespaceObject.X, {
221
- className: "h-4 w-4"
222
- })
259
+ fileError && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("p", {
260
+ className: "text-xs text-destructive mt-2",
261
+ children: fileError
223
262
  })
224
263
  ]
225
- }, index))
264
+ }, index);
265
+ })
226
266
  })
227
267
  ]
228
268
  });
@@ -6,5 +6,7 @@ export interface FileUploadProps {
6
6
  maxSize?: number;
7
7
  className?: string;
8
8
  showPreview?: boolean;
9
+ /** External errors keyed by filename. Use this to set errors from outside (e.g., upload failures). */
10
+ errors?: Record<string, string>;
9
11
  }
10
- export declare function FileUpload({ onFilesChange, accept, multiple, disabled, maxSize, className, showPreview, }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function FileUpload({ onFilesChange, accept, multiple, disabled, maxSize, className, showPreview, errors, }: FileUploadProps): import("react/jsx-runtime").JSX.Element;
@@ -4,29 +4,53 @@ import { Upload, X } from "lucide-react";
4
4
  import { useRef, useState } from "react";
5
5
  import { Button } from "./button.js";
6
6
  import { cn } from "../../lib/index.js";
7
- function FileUpload({ onFilesChange, accept, multiple = false, disabled = false, maxSize, className, showPreview = false }) {
7
+ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false, maxSize, className, showPreview = false, errors }) {
8
8
  const [files, setFiles] = useState([]);
9
9
  const [isDragging, setIsDragging] = useState(false);
10
- const [error, setError] = useState('');
10
+ const [fileErrors, setFileErrors] = useState(new Map());
11
11
  const [previews, setPreviews] = useState([]);
12
12
  const inputRef = useRef(null);
13
- const validateFiles = (fileList)=>{
14
- setError('');
13
+ const isFileTypeAccepted = (file)=>{
14
+ if (!accept) return true;
15
+ const acceptedTypes = accept.split(',').map((type)=>type.trim().toLowerCase());
16
+ for (const acceptedType of acceptedTypes)if (acceptedType.endsWith('/*')) {
17
+ const baseType = acceptedType.slice(0, -2);
18
+ if (file.type.toLowerCase().startsWith(baseType)) return true;
19
+ } else if (acceptedType.includes('/')) {
20
+ if (file.type.toLowerCase() === acceptedType) return true;
21
+ } else if (acceptedType.startsWith('.')) {
22
+ if (file.name.toLowerCase().endsWith(acceptedType)) return true;
23
+ }
24
+ return false;
25
+ };
26
+ const validateFiles = (fileList, startIndex, existingErrors)=>{
15
27
  const validFiles = [];
28
+ const errors = multiple ? new Map(existingErrors) : new Map();
16
29
  for (const file of fileList){
30
+ const fileIndex = startIndex + validFiles.length;
31
+ if (!isFileTypeAccepted(file)) {
32
+ errors.set(fileIndex, 'File type not accepted');
33
+ validFiles.push(file);
34
+ continue;
35
+ }
17
36
  if (maxSize && file.size > maxSize) {
18
- setError(`File "${file.name}" exceeds maximum size of ${formatFileSize(maxSize)}`);
37
+ errors.set(fileIndex, `Exceeds maximum size of ${formatFileSize(maxSize)}`);
38
+ validFiles.push(file);
19
39
  continue;
20
40
  }
21
41
  const isDuplicate = files.some((existingFile)=>existingFile.name === file.name && existingFile.size === file.size);
22
42
  if (!isDuplicate) validFiles.push(file);
23
43
  }
24
- return validFiles;
44
+ return {
45
+ validFiles,
46
+ errors
47
+ };
25
48
  };
26
49
  const handleFiles = (fileList)=>{
27
50
  if (!fileList || 0 === fileList.length) return;
28
51
  const filesArray = Array.from(fileList);
29
- const validFiles = validateFiles(filesArray);
52
+ const startIndex = multiple ? files.length : 0;
53
+ const { validFiles, errors } = validateFiles(filesArray, startIndex, fileErrors);
30
54
  if (0 === validFiles.length) return;
31
55
  const newFiles = multiple ? [
32
56
  ...files,
@@ -34,6 +58,7 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
34
58
  ] : validFiles;
35
59
  setFiles(newFiles);
36
60
  onFilesChange?.(newFiles);
61
+ setFileErrors(errors);
37
62
  if (showPreview) {
38
63
  const newPreviews = [];
39
64
  validFiles.forEach((file)=>{
@@ -59,7 +84,14 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
59
84
  const newPreviews = previews.filter((_, i)=>i !== index);
60
85
  setPreviews(newPreviews);
61
86
  }
62
- setError('');
87
+ setFileErrors((prev)=>{
88
+ const updated = new Map();
89
+ prev.forEach((error, i)=>{
90
+ if (i < index) updated.set(i, error);
91
+ else if (i > index) updated.set(i - 1, error);
92
+ });
93
+ return updated;
94
+ });
63
95
  };
64
96
  const handleDragEnter = (e)=>{
65
97
  e.preventDefault();
@@ -104,7 +136,7 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
104
136
  className: cn('w-full', className),
105
137
  children: [
106
138
  /*#__PURE__*/ jsxs("div", {
107
- className: cn('relative flex flex-col items-center justify-center w-full h-32 px-4 py-6 border-2 border-dashed rounded-lg cursor-pointer transition-colors', isDragging ? 'border-primary bg-primary/5' : 'border-input bg-background hover:bg-accent/50', disabled && 'opacity-50 cursor-not-allowed hover:bg-background', error && 'border-destructive'),
139
+ className: cn('relative flex flex-col items-center justify-center w-full h-32 px-4 py-6 border-2 border-dashed rounded-lg cursor-pointer transition-colors', isDragging ? 'border-primary bg-primary/5' : 'border-input bg-background hover:bg-accent/50', disabled && 'opacity-50 cursor-not-allowed hover:bg-background'),
108
140
  onDragEnter: handleDragEnter,
109
141
  onDragOver: handleDragOver,
110
142
  onDragLeave: handleDragLeave,
@@ -147,54 +179,62 @@ function FileUpload({ onFilesChange, accept, multiple = false, disabled = false,
147
179
  })
148
180
  ]
149
181
  }),
150
- error && /*#__PURE__*/ jsx("p", {
151
- className: "text-sm text-destructive mt-2",
152
- children: error
153
- }),
154
182
  files.length > 0 && /*#__PURE__*/ jsx("div", {
155
183
  className: "mt-4 space-y-2",
156
- children: files.map((file, index)=>/*#__PURE__*/ jsxs("div", {
157
- className: "flex items-center justify-between p-3 bg-accent/50 rounded-md",
184
+ children: files.map((file, index)=>{
185
+ const fileError = errors?.[file.name] ?? fileErrors.get(index);
186
+ return /*#__PURE__*/ jsxs("div", {
187
+ className: cn('flex flex-col p-3 rounded-md', fileError ? 'bg-destructive/10 border border-destructive/20' : 'bg-accent/50'),
158
188
  children: [
159
189
  /*#__PURE__*/ jsxs("div", {
160
- className: "flex items-center gap-3 flex-1 min-w-0",
190
+ className: "flex items-center justify-between",
161
191
  children: [
162
- showPreview && previews[index] && /*#__PURE__*/ jsx("img", {
163
- src: previews[index],
164
- alt: file.name,
165
- className: "w-10 h-10 object-cover rounded"
166
- }),
167
192
  /*#__PURE__*/ jsxs("div", {
168
- className: "flex-1 min-w-0",
193
+ className: "flex items-center gap-3 flex-1 min-w-0",
169
194
  children: [
170
- /*#__PURE__*/ jsx("p", {
171
- className: "text-sm font-medium truncate",
172
- children: file.name
195
+ showPreview && previews[index] && /*#__PURE__*/ jsx("img", {
196
+ src: previews[index],
197
+ alt: file.name,
198
+ className: "w-10 h-10 object-cover rounded"
173
199
  }),
174
- /*#__PURE__*/ jsx("p", {
175
- className: "text-xs text-muted-foreground",
176
- children: formatFileSize(file.size)
200
+ /*#__PURE__*/ jsxs("div", {
201
+ className: "flex-1 min-w-0",
202
+ children: [
203
+ /*#__PURE__*/ jsx("p", {
204
+ className: "text-sm font-medium truncate",
205
+ children: file.name
206
+ }),
207
+ /*#__PURE__*/ jsx("p", {
208
+ className: "text-xs text-muted-foreground",
209
+ children: formatFileSize(file.size)
210
+ })
211
+ ]
177
212
  })
178
213
  ]
214
+ }),
215
+ /*#__PURE__*/ jsx(Button, {
216
+ variant: "ghost",
217
+ size: "icon",
218
+ className: "h-8 w-8",
219
+ "aria-label": `Remove ${file.name}`,
220
+ onClick: (e)=>{
221
+ e.stopPropagation();
222
+ removeFile(index);
223
+ },
224
+ disabled: disabled,
225
+ children: /*#__PURE__*/ jsx(X, {
226
+ className: "h-4 w-4"
227
+ })
179
228
  })
180
229
  ]
181
230
  }),
182
- /*#__PURE__*/ jsx(Button, {
183
- variant: "ghost",
184
- size: "icon",
185
- className: "h-8 w-8",
186
- "aria-label": `Remove ${file.name}`,
187
- onClick: (e)=>{
188
- e.stopPropagation();
189
- removeFile(index);
190
- },
191
- disabled: disabled,
192
- children: /*#__PURE__*/ jsx(X, {
193
- className: "h-4 w-4"
194
- })
231
+ fileError && /*#__PURE__*/ jsx("p", {
232
+ className: "text-xs text-destructive mt-2",
233
+ children: fileError
195
234
  })
196
235
  ]
197
- }, index))
236
+ }, index);
237
+ })
198
238
  })
199
239
  ]
200
240
  });