ultra-image-uploader 0.0.2 → 1.0.0
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.
- package/README.md +408 -55
- package/dist/components/ImageUploader.d.ts +58 -4
- package/dist/components/ImageUploader.d.ts.map +1 -0
- package/dist/components/ImageUploader.js +203 -13
- package/dist/components/ImageUploader.js.map +1 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -0
- package/dist/providers/BaseProvider.d.ts +19 -0
- package/dist/providers/BaseProvider.d.ts.map +1 -0
- package/dist/providers/BaseProvider.js +48 -0
- package/dist/providers/BaseProvider.js.map +1 -0
- package/dist/providers/CloudinaryProvider.d.ts +17 -0
- package/dist/providers/CloudinaryProvider.d.ts.map +1 -0
- package/dist/providers/CloudinaryProvider.js +123 -0
- package/dist/providers/CloudinaryProvider.js.map +1 -0
- package/dist/providers/ImgBBProvider.d.ts +13 -0
- package/dist/providers/ImgBBProvider.d.ts.map +1 -0
- package/dist/providers/ImgBBProvider.js +68 -0
- package/dist/providers/ImgBBProvider.js.map +1 -0
- package/dist/providers/index.d.ts +20 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +36 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/types/index.d.ts +67 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/imageUpload.d.ts +1 -0
- package/dist/utils/imageUpload.d.ts.map +1 -0
- package/dist/utils/imageUpload.js +1 -0
- package/dist/utils/imageUpload.js.map +1 -0
- package/dist/utils/upload.d.ts +49 -0
- package/dist/utils/upload.d.ts.map +1 -0
- package/dist/utils/upload.js +62 -0
- package/dist/utils/upload.js.map +1 -0
- package/dist/utils/validation.d.ts +11 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +125 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +51 -15
- package/src/components/ImageUploader.tsx +0 -115
- package/src/index.ts +0 -4
- package/src/utils/imageUpload.ts +0 -56
- package/tsconfig.json +0 -17
package/README.md
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
# Ultra Image Uploader
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
A modern, feature-rich React image upload component with support for multiple hosting providers.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/ultra-image-uploader)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
|
|
10
|
+
**Features** • **Multiple Providers** • **Themeable** • **TypeScript** • **Production Ready**
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
4
15
|
|
|
5
16
|
## Features
|
|
6
17
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
18
|
+
- **Multiple Provider Support** - Built-in support for ImgBB and Cloudinary
|
|
19
|
+
- **Drag & Drop** - Intuitive drag and drop interface
|
|
20
|
+
- **Upload Progress** - Real-time upload progress tracking
|
|
21
|
+
- **File Validation** - Comprehensive file type, size, and dimension validation
|
|
22
|
+
- **Theme System** - 5 built-in themes + custom theme support
|
|
23
|
+
- **Auto Upload** - Optional automatic upload on file selection
|
|
24
|
+
- **Image Preview** - Instant preview with file size display
|
|
25
|
+
- **Error Handling** - Graceful error handling with user feedback
|
|
26
|
+
- **TypeScript** - Fully typed for excellent developer experience
|
|
27
|
+
- **Customizable** - Highly customizable styling and behavior
|
|
28
|
+
- **Tree Shakeable** - Optimized bundle size
|
|
15
29
|
|
|
16
30
|
## Installation
|
|
17
31
|
|
|
@@ -32,20 +46,20 @@ import { ImageUploader } from "ultra-image-uploader";
|
|
|
32
46
|
import { useState } from "react";
|
|
33
47
|
|
|
34
48
|
function App() {
|
|
35
|
-
const [
|
|
49
|
+
const [images, setImages] = useState<File[]>([]);
|
|
36
50
|
|
|
37
51
|
return (
|
|
38
52
|
<ImageUploader
|
|
39
|
-
images={
|
|
40
|
-
setImages={
|
|
41
|
-
mode="add"
|
|
53
|
+
images={images}
|
|
54
|
+
setImages={setImages}
|
|
42
55
|
multiple={true}
|
|
56
|
+
theme="light"
|
|
43
57
|
/>
|
|
44
58
|
);
|
|
45
59
|
}
|
|
46
60
|
```
|
|
47
61
|
|
|
48
|
-
### With ImgBB
|
|
62
|
+
### With ImgBB Upload
|
|
49
63
|
|
|
50
64
|
```tsx
|
|
51
65
|
import { ImageUploader, uploadImagesToImageBB } from "ultra-image-uploader";
|
|
@@ -53,15 +67,17 @@ import { useState } from "react";
|
|
|
53
67
|
|
|
54
68
|
function ImageUploadForm() {
|
|
55
69
|
const [images, setImages] = useState<File[]>([]);
|
|
70
|
+
const [uploadedUrls, setUploadedUrls] = useState<string[]>([]);
|
|
56
71
|
const [loading, setLoading] = useState(false);
|
|
57
72
|
|
|
58
|
-
const
|
|
73
|
+
const handleUpload = async () => {
|
|
59
74
|
setLoading(true);
|
|
60
75
|
try {
|
|
61
76
|
const result = await uploadImagesToImageBB(
|
|
62
77
|
images,
|
|
63
78
|
"your-imgbb-api-key-here"
|
|
64
79
|
);
|
|
80
|
+
setUploadedUrls(result.urls);
|
|
65
81
|
console.log("Uploaded URLs:", result.urls);
|
|
66
82
|
} catch (error) {
|
|
67
83
|
console.error("Error uploading images:", error);
|
|
@@ -75,72 +91,409 @@ function ImageUploadForm() {
|
|
|
75
91
|
<ImageUploader
|
|
76
92
|
images={images}
|
|
77
93
|
setImages={setImages}
|
|
78
|
-
mode="add"
|
|
79
94
|
multiple={true}
|
|
95
|
+
theme="modern"
|
|
80
96
|
/>
|
|
81
97
|
<button
|
|
82
|
-
onClick={
|
|
98
|
+
onClick={handleUpload}
|
|
83
99
|
disabled={loading || images.length === 0}
|
|
84
|
-
className="bg-blue-500 text-white
|
|
100
|
+
className="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50"
|
|
85
101
|
>
|
|
86
|
-
{loading ? "Uploading..." : "Upload
|
|
102
|
+
{loading ? "Uploading..." : "Upload to ImgBB"}
|
|
87
103
|
</button>
|
|
104
|
+
|
|
105
|
+
{uploadedUrls.length > 0 && (
|
|
106
|
+
<div>
|
|
107
|
+
<h3>Uploaded Images:</h3>
|
|
108
|
+
{uploadedUrls.map((url) => (
|
|
109
|
+
<img key={url} src={url} alt="Uploaded" />
|
|
110
|
+
))}
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
88
113
|
</div>
|
|
89
114
|
);
|
|
90
115
|
}
|
|
91
116
|
```
|
|
92
117
|
|
|
118
|
+
### With Cloudinary
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
import { ImageUploader, uploadImagesToCloudinary } from "ultra-image-uploader";
|
|
122
|
+
import { useState } from "react";
|
|
123
|
+
|
|
124
|
+
function CloudinaryUpload() {
|
|
125
|
+
const [images, setImages] = useState<File[]>([]);
|
|
126
|
+
const [loading, setLoading] = useState(false);
|
|
127
|
+
|
|
128
|
+
const handleUpload = async () => {
|
|
129
|
+
setLoading(true);
|
|
130
|
+
try {
|
|
131
|
+
const results = await uploadImagesToCloudinary(
|
|
132
|
+
images,
|
|
133
|
+
{
|
|
134
|
+
cloudName: "your-cloud-name",
|
|
135
|
+
uploadPreset: "your-upload-preset", // for unsigned uploads
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
onProgress: (progress) => {
|
|
139
|
+
console.log(`Upload: ${progress.percentage}%`);
|
|
140
|
+
},
|
|
141
|
+
transformOptions: {
|
|
142
|
+
width: 800,
|
|
143
|
+
height: 600,
|
|
144
|
+
crop: "limit",
|
|
145
|
+
quality: 80,
|
|
146
|
+
},
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
console.log("Uploaded:", results);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error("Error:", error);
|
|
152
|
+
} finally {
|
|
153
|
+
setLoading(false);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<div>
|
|
159
|
+
<ImageUploader
|
|
160
|
+
images={images}
|
|
161
|
+
setImages={setImages}
|
|
162
|
+
multiple={true}
|
|
163
|
+
theme="dark"
|
|
164
|
+
/>
|
|
165
|
+
<button onClick={handleUpload} disabled={loading}>
|
|
166
|
+
Upload to Cloudinary
|
|
167
|
+
</button>
|
|
168
|
+
</div>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Auto Upload Mode
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
import { ImageUploader } from "ultra-image-uploader";
|
|
177
|
+
import { useState } from "react";
|
|
178
|
+
|
|
179
|
+
function AutoUploadExample() {
|
|
180
|
+
const [images, setImages] = useState<File[]>([]);
|
|
181
|
+
const [uploadedUrls, setUploadedUrls] = useState<string[]>([]);
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<ImageUploader
|
|
185
|
+
images={images}
|
|
186
|
+
setImages={setImages}
|
|
187
|
+
multiple={true}
|
|
188
|
+
autoUpload={true}
|
|
189
|
+
uploadConfig={{
|
|
190
|
+
provider: "imgbb",
|
|
191
|
+
config: { apiKey: "your-api-key" },
|
|
192
|
+
}}
|
|
193
|
+
onUploadComplete={(urls) => {
|
|
194
|
+
setUploadedUrls(urls);
|
|
195
|
+
console.log("All uploads complete!", urls);
|
|
196
|
+
}}
|
|
197
|
+
onUploadError={(error) => {
|
|
198
|
+
console.error("Upload failed:", error);
|
|
199
|
+
}}
|
|
200
|
+
theme="colorful"
|
|
201
|
+
/>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Theming
|
|
207
|
+
|
|
208
|
+
### Built-in Themes
|
|
209
|
+
|
|
210
|
+
The component comes with 5 beautiful themes:
|
|
211
|
+
|
|
212
|
+
- **`light`** - Clean and modern light theme
|
|
213
|
+
- **`dark`** - Sleek dark theme
|
|
214
|
+
- **`modern`** - Purple-themed modern design
|
|
215
|
+
- **`minimal`** - Minimalist black and white
|
|
216
|
+
- **`colorful`** - Warm amber/yellow theme
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<ImageUploader images={images} setImages={setImages} theme="dark" />
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Custom Theme
|
|
223
|
+
|
|
224
|
+
Create your own theme with full customization:
|
|
225
|
+
|
|
226
|
+
```tsx
|
|
227
|
+
import { ImageUploader, type UploaderTheme } from "ultra-image-uploader";
|
|
228
|
+
|
|
229
|
+
const customTheme: UploaderTheme = {
|
|
230
|
+
primary: "#ff6b6b",
|
|
231
|
+
primaryHover: "#ee5a5a",
|
|
232
|
+
background: "#f7f7f7",
|
|
233
|
+
border: "#ddd",
|
|
234
|
+
text: "#333",
|
|
235
|
+
textSecondary: "#666",
|
|
236
|
+
error: "#e74c3c",
|
|
237
|
+
success: "#2ecc71",
|
|
238
|
+
radius: "8px",
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
<ImageUploader
|
|
242
|
+
images={images}
|
|
243
|
+
setImages={setImages}
|
|
244
|
+
customTheme={customTheme}
|
|
245
|
+
/>
|
|
246
|
+
```
|
|
247
|
+
|
|
93
248
|
## Component Props
|
|
94
249
|
|
|
95
|
-
| Prop
|
|
96
|
-
|
|
97
|
-
| `images`
|
|
98
|
-
| `setImages`
|
|
99
|
-
| `mode`
|
|
100
|
-
| `defaultImages`
|
|
101
|
-
| `multiple`
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `uploadText`
|
|
105
|
-
| `typeText`
|
|
250
|
+
| Prop | Type | Default | Description |
|
|
251
|
+
|------|------|---------|-------------|
|
|
252
|
+
| `images` | `File[]` | **Required** | Array of selected image files |
|
|
253
|
+
| `setImages` | `(files: File[]) => void` | **Required** | Function to update images array |
|
|
254
|
+
| `mode` | `'add' \| 'update'` | `'add'` | Component operation mode |
|
|
255
|
+
| `defaultImages` | `string[]` | `[]` | Existing image URLs for update mode |
|
|
256
|
+
| `multiple` | `boolean` | `false` | Allow multiple file selection |
|
|
257
|
+
| `theme` | `ThemePreset` | `'light'` | Built-in theme to use |
|
|
258
|
+
| `customTheme` | `UploaderTheme` | `undefined` | Custom theme configuration |
|
|
259
|
+
| `uploadText` | `string` | `'Drop images here...'` | Upload area text |
|
|
260
|
+
| `typeText` | `string` | `'PNG, JPG,...'` | File type hint text |
|
|
261
|
+
| `maxSize` | `number` | `10485760` | Max file size in bytes (10MB) |
|
|
262
|
+
| `allowedTypes` | `string[]` | `['image/jpeg', ...]` | Allowed MIME types |
|
|
263
|
+
| `showFileSize` | `boolean` | `true` | Show file size on preview |
|
|
264
|
+
| `dragAndDrop` | `boolean` | `true` | Enable drag and drop |
|
|
265
|
+
| `previewWidth` | `number` | `150` | Preview image width in px |
|
|
266
|
+
| `previewHeight` | `number` | `150` | Preview image height in px |
|
|
267
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
268
|
+
| `autoUpload` | `boolean` | `false` | Auto-upload on file selection |
|
|
269
|
+
| `uploadConfig` | `{ provider, config }` | `undefined` | Upload configuration |
|
|
270
|
+
| `onUploadComplete` | `(urls: string[]) => void` | `undefined` | Callback on upload success |
|
|
271
|
+
| `onUploadError` | `(error: Error) => void` | `undefined` | Callback on upload error |
|
|
272
|
+
|
|
273
|
+
## Upload Providers
|
|
106
274
|
|
|
275
|
+
### ImgBB
|
|
107
276
|
|
|
108
|
-
|
|
277
|
+
Free image hosting with simple API:
|
|
109
278
|
|
|
110
|
-
|
|
279
|
+
```tsx
|
|
280
|
+
import { uploadImagesToImageBB } from "ultra-image-uploader";
|
|
281
|
+
|
|
282
|
+
const result = await uploadImagesToImageBB(
|
|
283
|
+
images,
|
|
284
|
+
"your-imgbb-api-key"
|
|
285
|
+
);
|
|
286
|
+
console.log(result.urls);
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
**Get API Key:** [imgbb.com/settings/api](https://imgbb.com/settings/api)
|
|
290
|
+
|
|
291
|
+
### Cloudinary
|
|
292
|
+
|
|
293
|
+
Enterprise-grade image hosting with transformations:
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
import { uploadImagesToCloudinary } from "ultra-image-uploader";
|
|
297
|
+
|
|
298
|
+
const results = await uploadImagesToCloudinary(
|
|
299
|
+
images,
|
|
300
|
+
{
|
|
301
|
+
cloudName: "your-cloud-name",
|
|
302
|
+
uploadPreset: "your-upload-preset", // optional
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
onProgress: (progress) => console.log(progress.percentage),
|
|
306
|
+
transformOptions: {
|
|
307
|
+
width: 800,
|
|
308
|
+
height: 600,
|
|
309
|
+
quality: 85,
|
|
310
|
+
crop: "limit",
|
|
311
|
+
},
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
**Get Credentials:**
|
|
317
|
+
1. Sign up at [cloudinary.com](https://cloudinary.com)
|
|
318
|
+
2. Get your cloud name from dashboard
|
|
319
|
+
3. Create an upload preset (Settings → Upload → Upload presets)
|
|
320
|
+
|
|
321
|
+
## Advanced Usage
|
|
322
|
+
|
|
323
|
+
### Custom Provider
|
|
324
|
+
|
|
325
|
+
You can create custom upload providers:
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
import { BaseImageProvider } from "ultra-image-uploader";
|
|
329
|
+
|
|
330
|
+
class CustomProvider extends BaseImageProvider {
|
|
331
|
+
name = 'custom' as const;
|
|
111
332
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
333
|
+
async upload(file: File, config: ProviderConfig) {
|
|
334
|
+
// Your upload logic here
|
|
335
|
+
return {
|
|
336
|
+
url: "https://...",
|
|
337
|
+
provider: "custom",
|
|
338
|
+
originalFile: file,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async uploadMultiple(files: File[], config: ProviderConfig) {
|
|
343
|
+
return Promise.all(files.map(f => this.upload(f, config)));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Register and use
|
|
348
|
+
import { providerRegistry } from "ultra-image-uploader";
|
|
349
|
+
providerRegistry.register(new CustomProvider());
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### File Validation
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
import {
|
|
356
|
+
validateImageFile,
|
|
357
|
+
validateFileComplete,
|
|
358
|
+
formatFileSize,
|
|
359
|
+
} from "ultra-image-uploader";
|
|
360
|
+
|
|
361
|
+
// Quick validation
|
|
362
|
+
const validation = validateImageFile(file, {
|
|
363
|
+
maxSize: 5 * 1024 * 1024, // 5MB
|
|
364
|
+
allowedTypes: ["image/jpeg", "image/png"],
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
if (!validation.valid) {
|
|
368
|
+
console.error("Errors:", validation.errors);
|
|
115
369
|
}
|
|
116
370
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
371
|
+
// Complete validation (with dimensions)
|
|
372
|
+
const completeValidation = await validateFileComplete(file, {
|
|
373
|
+
maxSize: 10 * 1024 * 1024,
|
|
374
|
+
minWidth: 800,
|
|
375
|
+
maxWidth: 4000,
|
|
376
|
+
minHeight: 600,
|
|
377
|
+
maxHeight: 3000,
|
|
378
|
+
});
|
|
121
379
|
```
|
|
122
380
|
|
|
123
|
-
|
|
381
|
+
### Transforming Cloudinary Images
|
|
124
382
|
|
|
125
|
-
|
|
383
|
+
Generate transformed URLs for existing Cloudinary images:
|
|
126
384
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
385
|
+
```tsx
|
|
386
|
+
import { CloudinaryProvider } from "ultra-image-uploader";
|
|
387
|
+
|
|
388
|
+
const transformedUrl = CloudinaryProvider.generateTransformedUrl(
|
|
389
|
+
"https://res.cloudinary.com/.../image.jpg",
|
|
390
|
+
{
|
|
391
|
+
width: 400,
|
|
392
|
+
height: 300,
|
|
393
|
+
crop: "fill",
|
|
394
|
+
quality: 80,
|
|
395
|
+
format: "webp",
|
|
396
|
+
}
|
|
397
|
+
);
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## TypeScript Support
|
|
401
|
+
|
|
402
|
+
The package is fully typed. Import types as needed:
|
|
403
|
+
|
|
404
|
+
```tsx
|
|
405
|
+
import type {
|
|
406
|
+
UploadProvider,
|
|
407
|
+
UploadResult,
|
|
408
|
+
ProviderConfig,
|
|
409
|
+
UploadOptions,
|
|
410
|
+
ImageUploaderProps,
|
|
411
|
+
UploaderTheme,
|
|
412
|
+
ValidationResult,
|
|
413
|
+
FileValidationOptions,
|
|
414
|
+
} from "ultra-image-uploader";
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## Examples
|
|
418
|
+
|
|
419
|
+
### E-commerce Product Image Upload
|
|
420
|
+
|
|
421
|
+
```tsx
|
|
422
|
+
function ProductImageUpload() {
|
|
423
|
+
const [images, setImages] = useState<File[]>([]);
|
|
424
|
+
const [existingImages, setExistingImages] = useState<string[]>([
|
|
425
|
+
"https://example.com/product1.jpg",
|
|
426
|
+
]);
|
|
427
|
+
|
|
428
|
+
return (
|
|
429
|
+
<ImageUploader
|
|
430
|
+
images={images}
|
|
431
|
+
setImages={setImages}
|
|
432
|
+
mode="update"
|
|
433
|
+
defaultImages={existingImages}
|
|
434
|
+
multiple={true}
|
|
435
|
+
maxSize={5 * 1024 * 1024} // 5MB
|
|
436
|
+
allowedTypes={["image/jpeg", "image/webp"]}
|
|
437
|
+
theme="modern"
|
|
438
|
+
previewWidth={200}
|
|
439
|
+
previewHeight={200}
|
|
440
|
+
/>
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Profile Picture Upload
|
|
446
|
+
|
|
447
|
+
```tsx
|
|
448
|
+
function ProfilePicUpload() {
|
|
449
|
+
const [avatar, setAvatar] = useState<File[]>([]);
|
|
450
|
+
|
|
451
|
+
return (
|
|
452
|
+
<ImageUploader
|
|
453
|
+
images={avatar}
|
|
454
|
+
setImages={setAvatar}
|
|
455
|
+
multiple={false}
|
|
456
|
+
maxSize={2 * 1024 * 1024} // 2MB
|
|
457
|
+
previewWidth={180}
|
|
458
|
+
previewHeight={180}
|
|
459
|
+
theme="minimal"
|
|
460
|
+
/>
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
## Migration from v0.0.x
|
|
466
|
+
|
|
467
|
+
If you're upgrading from version 0.0.x, the API is backward compatible:
|
|
468
|
+
|
|
469
|
+
```tsx
|
|
470
|
+
// Old API still works
|
|
471
|
+
import { uploadImagesToImageBB } from "ultra-image-uploader";
|
|
472
|
+
const { urls } = await uploadImagesToImageBB(images, apiKey);
|
|
473
|
+
|
|
474
|
+
// But you can now use the new provider-agnostic API
|
|
475
|
+
import { uploadImages } from "ultra-image-uploader";
|
|
476
|
+
const results = await uploadImages(images, "imgbb", { apiKey });
|
|
477
|
+
const urls = results.map(r => r.url);
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
## Browser Support
|
|
481
|
+
|
|
482
|
+
- Chrome/Edge (latest)
|
|
483
|
+
- Firefox (latest)
|
|
484
|
+
- Safari (latest)
|
|
485
|
+
- Mobile browsers
|
|
139
486
|
|
|
140
487
|
## License
|
|
141
488
|
|
|
142
489
|
MIT © Digontha Das
|
|
143
490
|
|
|
144
|
-
## Support
|
|
491
|
+
## Support & Contributing
|
|
492
|
+
|
|
493
|
+
- **Issues:** [GitHub Issues](https://github.com/digontha/ultra-image-uploader/issues)
|
|
494
|
+
- **Contributing:** Pull requests are welcome!
|
|
495
|
+
- **Discussions:** Ask questions and share ideas
|
|
496
|
+
|
|
497
|
+
---
|
|
145
498
|
|
|
146
|
-
|
|
499
|
+
Made with ❤️ by [Digontha Das](https://github.com/digontha)
|
|
@@ -1,12 +1,66 @@
|
|
|
1
|
+
import type { UploadProvider, ProviderConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Theme configuration for the uploader
|
|
4
|
+
*/
|
|
5
|
+
export interface UploaderTheme {
|
|
6
|
+
primary?: string;
|
|
7
|
+
primaryHover?: string;
|
|
8
|
+
background?: string;
|
|
9
|
+
border?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
textSecondary?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
success?: string;
|
|
14
|
+
radius?: string;
|
|
15
|
+
}
|
|
16
|
+
export type ThemePreset = 'light' | 'dark' | 'modern' | 'minimal' | 'colorful';
|
|
17
|
+
/**
|
|
18
|
+
* Props for the ImageUploader component
|
|
19
|
+
*/
|
|
1
20
|
export interface ImageUploaderProps {
|
|
21
|
+
/** Currently selected image files */
|
|
2
22
|
images: File[];
|
|
23
|
+
/** Function to update the images array */
|
|
3
24
|
setImages: (images: File[]) => void;
|
|
4
|
-
|
|
25
|
+
/** Operation mode */
|
|
26
|
+
mode?: 'add' | 'update';
|
|
27
|
+
/** Existing image URLs for update mode */
|
|
5
28
|
defaultImages?: string[];
|
|
29
|
+
/** Allow multiple file selection */
|
|
6
30
|
multiple?: boolean;
|
|
7
|
-
|
|
8
|
-
|
|
31
|
+
/** Custom CSS classes */
|
|
32
|
+
className?: string;
|
|
33
|
+
/** Upload area text */
|
|
9
34
|
uploadText?: string;
|
|
35
|
+
/** File type hint text */
|
|
10
36
|
typeText?: string;
|
|
37
|
+
/** Maximum file size in bytes */
|
|
38
|
+
maxSize?: number;
|
|
39
|
+
/** Allowed file types */
|
|
40
|
+
allowedTypes?: string[];
|
|
41
|
+
/** Theme preset */
|
|
42
|
+
theme?: ThemePreset;
|
|
43
|
+
/** Custom theme object */
|
|
44
|
+
customTheme?: UploaderTheme;
|
|
45
|
+
/** Show file size preview */
|
|
46
|
+
showFileSize?: boolean;
|
|
47
|
+
/** Enable drag and drop */
|
|
48
|
+
dragAndDrop?: boolean;
|
|
49
|
+
/** Image preview width */
|
|
50
|
+
previewWidth?: number;
|
|
51
|
+
/** Image preview height */
|
|
52
|
+
previewHeight?: number;
|
|
53
|
+
/** Callback when upload completes */
|
|
54
|
+
onUploadComplete?: (urls: string[]) => void;
|
|
55
|
+
/** Callback when upload fails */
|
|
56
|
+
onUploadError?: (error: Error) => void;
|
|
57
|
+
/** Auto upload on file selection */
|
|
58
|
+
autoUpload?: boolean;
|
|
59
|
+
/** Upload provider configuration */
|
|
60
|
+
uploadConfig?: {
|
|
61
|
+
provider: UploadProvider;
|
|
62
|
+
config: ProviderConfig;
|
|
63
|
+
};
|
|
11
64
|
}
|
|
12
|
-
export declare function ImageUploader({ images, setImages, mode, defaultImages, multiple,
|
|
65
|
+
export declare function ImageUploader({ images, setImages, mode, defaultImages, multiple, className, uploadText, typeText, maxSize, allowedTypes, theme, customTheme, showFileSize, dragAndDrop, previewWidth, previewHeight, onUploadComplete, onUploadError, autoUpload, uploadConfig, }: ImageUploaderProps): import("react/jsx-runtime").JSX.Element;
|
|
66
|
+
//# sourceMappingURL=ImageUploader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageUploader.d.ts","sourceRoot":"","sources":["../../src/components/ImageUploader.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI/D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AA4D/E;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,MAAM,EAAE,IAAI,EAAE,CAAC;IACf,0CAA0C;IAC1C,SAAS,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACpC,qBAAqB;IACrB,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACxB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,0BAA0B;IAC1B,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,6BAA6B;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC5C,iCAAiC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvC,oCAAoC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oCAAoC;IACpC,YAAY,CAAC,EAAE;QACb,QAAQ,EAAE,cAAc,CAAC;QACzB,MAAM,EAAE,cAAc,CAAC;KACxB,CAAC;CACH;AAUD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,SAAS,EACT,IAAY,EACZ,aAAkB,EAClB,QAAgB,EAChB,SAAc,EACd,UAAkD,EAClD,QAAiD,EACjD,OAA0B,EAC1B,YAAkF,EAClF,KAAe,EACf,WAAW,EACX,YAAmB,EACnB,WAAkB,EAClB,YAAkB,EAClB,aAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,UAAkB,EAClB,YAAY,GACb,EAAE,kBAAkB,2CAkVpB"}
|