@adamosuiteservices/ui 2.17.1 → 2.18.1

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.
@@ -4,6 +4,8 @@
4
4
 
5
5
  File upload component with **drag & drop** functionality, extension and size validation, preview of selected files, and visual drag area. Supports both single file and multiple file upload. Ideal for forms that require file uploads with immediate user feedback.
6
6
 
7
+ > **Looking for server integration?** Check out [FileUploadV2](file-upload-v2.md) which includes automatic ID generation and metadata support for server-side file tracking.
8
+
7
9
  ## Features
8
10
 
9
11
  - ✅ Drag & drop with visual feedback
@@ -86,6 +88,58 @@ State of the currently selected file. Use `null` when there is no file.
86
88
  onFileSelect?: (file: File | null) => void
87
89
  ```
88
90
 
91
+ Callback invoked when the user selects or removes a file. Receives the new file or `null` when removed.
92
+
93
+ #### onFileAdd
94
+
95
+ ```tsx
96
+ onFileAdd?: (file: File) => void
97
+ ```
98
+
99
+ Callback invoked when a new file is added (via drag & drop or file selection). Receives the added file. This fires in addition to `onFileSelect`.
100
+
101
+ **Use case**: Track file additions for logging, analytics, or triggering immediate upload.
102
+
103
+ **Example**:
104
+
105
+ ```tsx
106
+ const handleFileAdd = (file: File) => {
107
+ console.log("File added:", file.name);
108
+ // Optionally start upload immediately
109
+ uploadFile(file);
110
+ };
111
+
112
+ <FileUpload
113
+ selectedFile={file}
114
+ onFileSelect={setFile}
115
+ onFileAdd={handleFileAdd}
116
+ />;
117
+ ```
118
+
119
+ #### onFileRemove
120
+
121
+ ```tsx
122
+ onFileRemove?: (file: File) => void
123
+ ```
124
+
125
+ Callback invoked when a file is removed. Receives the removed file. This fires in addition to `onFileSelect`.
126
+
127
+ **Use case**: Track file removals, call API to delete from server, or update analytics.
128
+
129
+ **Example**:
130
+
131
+ ```tsx
132
+ const handleFileRemove = (file: File) => {
133
+ console.log("File removed:", file.name);
134
+ };
135
+
136
+ <FileUpload
137
+ selectedFile={file}
138
+ onFileSelect={setFile}
139
+ onFileRemove={handleFileRemove}
140
+ />;
141
+ ```
142
+
89
143
  ### Common props
90
144
 
91
145
  #### acceptedExtensions
@@ -289,6 +343,64 @@ onFilesSelect?: (files: File[]) => void
289
343
 
290
344
  Callback invoked when the user selects, adds, or removes files.
291
345
 
346
+ #### onFilesAdd
347
+
348
+ ```tsx
349
+ onFilesAdd?: (files: File[]) => void
350
+ ```
351
+
352
+ Callback invoked when new files are added (via drag & drop or file selection). Receives the array of added files. This fires in addition to `onFilesSelect`.
353
+
354
+ **Use case**: Track file additions, start batch upload, or update UI state.
355
+
356
+ **Example**:
357
+
358
+ ```tsx
359
+ const handleFilesAdd = (files: File[]) => {
360
+ console.log(
361
+ `${files.length} file(s) added:`,
362
+ files.map((f) => f.name),
363
+ );
364
+ // Start batch upload
365
+ files.forEach(uploadFile);
366
+ };
367
+
368
+ <FileUpload
369
+ selectedFiles={files}
370
+ onFilesSelect={setFiles}
371
+ onFilesAdd={handleFilesAdd}
372
+ multiple
373
+ />;
374
+ ```
375
+
376
+ #### onFilesRemove
377
+
378
+ ```tsx
379
+ onFilesRemove?: (files: File[]) => void
380
+ ```
381
+
382
+ Callback invoked when files are removed (individually or via "Clear all"). Receives the array of removed files. This fires in addition to `onFilesSelect`.
383
+
384
+ **Use case**: Track file removals, call API to delete from server, or clean up resources.
385
+
386
+ **Example**:
387
+
388
+ ```tsx
389
+ const handleFilesRemove = (files: File[]) => {
390
+ console.log(
391
+ `${files.length} file(s) removed:`,
392
+ files.map((f) => f.name),
393
+ );
394
+ };
395
+
396
+ <FileUpload
397
+ selectedFiles={files}
398
+ onFilesSelect={setFiles}
399
+ onFilesRemove={handleFilesRemove}
400
+ multiple
401
+ />;
402
+ ```
403
+
292
404
  #### multiple
293
405
 
294
406
  ```tsx
@@ -597,6 +709,104 @@ function CustomInputPropsExample() {
597
709
  }
598
710
  ```
599
711
 
712
+ ### With callbacks for immediate upload
713
+
714
+ ```tsx
715
+ import { useState } from "react";
716
+ import { FileUpload } from "@adamosuiteservices/ui/file-upload";
717
+ import { Typography } from "@adamosuiteservices/ui/typography";
718
+
719
+ function ImmediateUploadExample() {
720
+ const [file, setFile] = useState<File | null>(null);
721
+ const [isUploading, setIsUploading] = useState(false);
722
+
723
+ const handleFileAdd = async (addedFile: File) => {
724
+ console.log("File added, starting upload:", addedFile.name);
725
+ setIsUploading(true);
726
+
727
+ try {
728
+ const formData = new FormData();
729
+ formData.append("file", addedFile);
730
+
731
+ const response = await fetch("/api/upload", {
732
+ method: "POST",
733
+ body: formData,
734
+ });
735
+
736
+ if (response.ok) {
737
+ console.log("Upload successful");
738
+ }
739
+ } catch (error) {
740
+ console.error("Upload failed:", error);
741
+ } finally {
742
+ setIsUploading(false);
743
+ }
744
+ };
745
+
746
+ const handleFileRemove = (removedFile: File) => {
747
+ console.log("File removed:", removedFile.name);
748
+ };
749
+
750
+ return (
751
+ <div className="adm:max-w-xl adm:space-y-4">
752
+ <FileUpload
753
+ selectedFile={file}
754
+ onFileSelect={setFile}
755
+ onFileAdd={handleFileAdd}
756
+ onFileRemove={handleFileRemove}
757
+ />
758
+ {isUploading && <Typography color="muted">Uploading...</Typography>}
759
+ </div>
760
+ );
761
+ }
762
+ ```
763
+
764
+ ### Multiple files with callbacks
765
+
766
+ ```tsx
767
+ import { useState } from "react";
768
+ import { FileUpload } from "@adamosuiteservices/ui/file-upload";
769
+ import { Typography } from "@adamosuiteservices/ui/typography";
770
+
771
+ function MultipleFilesWithCallbacks() {
772
+ const [files, setFiles] = useState<File[]>([]);
773
+ const [eventLog, setEventLog] = useState<string[]>([]);
774
+
775
+ const handleFilesAdd = (addedFiles: File[]) => {
776
+ const message = `Added ${addedFiles.length} file(s): ${addedFiles.map((f) => f.name).join(", ")}`;
777
+ setEventLog((prev) => [...prev, message]);
778
+ };
779
+
780
+ const handleFilesRemove = (removedFiles: File[]) => {
781
+ const message = `Removed ${removedFiles.length} file(s): ${removedFiles.map((f) => f.name).join(", ")}`;
782
+ setEventLog((prev) => [...prev, message]);
783
+ };
784
+
785
+ return (
786
+ <div className="adm:max-w-xl adm:space-y-4">
787
+ <FileUpload
788
+ selectedFiles={files}
789
+ onFilesSelect={setFiles}
790
+ onFilesAdd={handleFilesAdd}
791
+ onFilesRemove={handleFilesRemove}
792
+ multiple
793
+ />
794
+
795
+ {eventLog.length > 0 && (
796
+ <div className="adm:space-y-2">
797
+ <Typography className="adm:font-medium">Event log:</Typography>
798
+ {eventLog.map((log, index) => (
799
+ <Typography key={index} color="muted" className="adm:text-sm">
800
+ {log}
801
+ </Typography>
802
+ ))}
803
+ </div>
804
+ )}
805
+ </div>
806
+ );
807
+ }
808
+ ```
809
+
600
810
  ### Excel files (default)
601
811
 
602
812
  ````tsx
package/llm.txt CHANGED
@@ -1,11 +1,11 @@
1
1
  # Adamo UI Component Library - LLM Context
2
2
 
3
- > **CRITICAL**: This is a COMPLETE React component library with 45+ components. DO NOT create components that already exist. ALWAYS check this file first and use existing components.
3
+ > **CRITICAL**: This is a COMPLETE React component library with 46+ components. DO NOT create components that already exist. ALWAYS check this file first and use existing components.
4
4
 
5
5
  ## 🚨 MOST IMPORTANT RULES
6
6
 
7
7
  1. **NEVER create a component that already exists** - Check the component list below first
8
- - Example: ❌ DON'T create `<input type="file">` ✅ DO use `<FileUpload>`
8
+ - Example: ❌ DON'T create `<input type="file">` ✅ DO use `<FileUpload>` or `<FileUploadV2>`
9
9
 
10
10
  2. **Use individual imports** - `import { Button } from "@adamosuiteservices/ui/button";`
11
11
 
@@ -13,11 +13,11 @@
13
13
 
14
14
  4. **Users NEVER use `adm:` prefix** - Only library internals use it
15
15
 
16
- ## 📦 Available Components (45+)
16
+ ## 📦 Available Components (46+)
17
17
 
18
18
  Before creating ANY component, verify it doesn't exist here. For implementation details, props, and examples, see the linked documentation.
19
19
 
20
- ### Form Components (14)
20
+ ### Form Components (15)
21
21
  - **Button** [`docs/components/ui/button.md`] - `@adamosuiteservices/ui/button`
22
22
  - **Button Group** [`docs/components/ui/button-group.md`] - `@adamosuiteservices/ui/button-group`
23
23
  - **Input** [`docs/components/ui/input.md`] - `@adamosuiteservices/ui/input`
@@ -31,7 +31,8 @@ Before creating ANY component, verify it doesn't exist here. For implementation
31
31
  - **Field** [`docs/components/ui/field.md`] - `@adamosuiteservices/ui/field` (form wrapper with label/error)
32
32
  - **Label** [`docs/components/ui/label.md`] - `@adamosuiteservices/ui/label`
33
33
  - **Input Group** [`docs/components/ui/input-group.md`] - `@adamosuiteservices/ui/input-group`
34
- - **File Upload** [`docs/components/ui/file-upload.md`] - `@adamosuiteservices/ui/file-upload` ⚠️ USE THIS!
34
+ - **File Upload** [`docs/components/ui/file-upload.md`] - `@adamosuiteservices/ui/file-upload` ⚠️ Simple file upload
35
+ - **File Upload V2** [`docs/components/ui/file-upload-v2.md`] - `@adamosuiteservices/ui/file-upload-v2` ⚠️ With IDs for server integration
35
36
 
36
37
  ### Overlay Components (8)
37
38
  - **Dialog** [`docs/components/ui/dialog.md`] - `@adamosuiteservices/ui/dialog` (modal)
@@ -89,6 +90,8 @@ Before creating ANY component, verify it doesn't exist here. For implementation
89
90
  1. ❌ Creating components that already exist (check list above first!)
90
91
  2. ❌ Using barrel imports: `import { X } from "@adamosuiteservices/ui"`
91
92
  3. ❌ Using `adm:` prefix in user code
93
+ 5. ❌ Using FileUploadV2 for simple forms (use FileUpload instead)
94
+ 6. ❌ Using FileUpload when you need server-side file tracking (use FileUploadV2)
92
95
  4. ❌ Not consulting component documentation before implementation
93
96
 
94
97
  ## 📚 Documentation Structure
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adamosuiteservices/ui",
3
- "version": "2.17.1",
3
+ "version": "2.18.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -118,6 +118,10 @@
118
118
  "types": "./dist/components/ui/file-upload/file-upload.d.ts",
119
119
  "import": "./dist/file-upload.js"
120
120
  },
121
+ "./file-upload-v2": {
122
+ "types": "./dist/components/ui/file-upload-v2/file-upload-v2.d.ts",
123
+ "import": "./dist/file-upload-v2.js"
124
+ },
121
125
  "./hover-card": {
122
126
  "types": "./dist/components/ui/hover-card/hover-card.d.ts",
123
127
  "import": "./dist/hover-card.js"