@dev-codergautam/drag-and-drop-uploader 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/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@dev-codergautam/drag-and-drop-uploader",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight drag-and-drop file uploader with previews.",
5
+ "main": "src/index.js",
6
+ "type": "module",
7
+ "files": [
8
+ "src"
9
+ ],
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "keywords": [
14
+ "upload",
15
+ "drag-drop",
16
+ "preview",
17
+ "vanilla-js"
18
+ ],
19
+ "author": "Your Name",
20
+ "license": "MIT"
21
+ }
package/readme.md ADDED
@@ -0,0 +1,123 @@
1
+ A good `README.md` is the "front door" of your project. It needs to tell developers exactly what the package does, how to install it, and—most importantly—how to get it running in 60 seconds.
2
+
3
+ Here is a professional, well-structured `README.md` tailored for your **@dev-codergautam/drag-dropuploader** package.
4
+
5
+ ---
6
+
7
+ # @dev-codergautam/drag-dropuploader
8
+
9
+ A lightweight, zero-dependency Vanilla JavaScript library for creating beautiful drag-and-drop file upload zones with real-time image previews.
10
+
11
+ ## 🚀 Features
12
+
13
+ * **Drag & Drop Support**: Seamlessly handle file drops.
14
+ * **Clipboard Integration**: Supports pasting images directly from the clipboard.
15
+ * **Live Previews**: Automatically generates and displays thumbnails for images.
16
+ * **State Management**: Easily retrieve the current list of files for form submission.
17
+ * **Customizable**: Filter by file types and hook into update events.
18
+
19
+ ---
20
+
21
+ ## 📦 Installation
22
+
23
+ Install the package via NPM:
24
+
25
+ ```bash
26
+ npm install @dev-codergautam/drag-dropuploader
27
+
28
+ ```
29
+
30
+ ---
31
+
32
+ ## 🛠 Usage
33
+
34
+ ### 1. Vanilla JavaScript
35
+
36
+ First, create a container in your HTML:
37
+
38
+ ```html
39
+ <div id="my-uploader"></div>
40
+
41
+ ```
42
+
43
+ Then, initialize the uploader in your JavaScript file:
44
+
45
+ ```javascript
46
+ import SimpleUploader from '@dev-codergautam/drag-dropuploader';
47
+ import '@dev-codergautam/drag-dropuploader/src/styles.css';
48
+
49
+ const uploader = new SimpleUploader('#my-uploader', {
50
+ allowedTypes: ['image/jpeg', 'image/png'],
51
+ onFilesUpdate: (files) => {
52
+ console.log("Files updated:", files);
53
+ }
54
+ });
55
+
56
+ // To get the files when submitting a form:
57
+ const files = uploader.getFiles();
58
+
59
+ ```
60
+
61
+ ### 2. React (Vite) Implementation
62
+
63
+ Since this is a DOM-based library, use the `useEffect` hook to initialize it.
64
+
65
+ ```jsx
66
+ import { useEffect } from 'react';
67
+ import SimpleUploader from '@dev-codergautam/drag-dropuploader';
68
+ import '@dev-codergautam/drag-dropuploader/src/styles.css';
69
+
70
+ export default function UploaderComponent() {
71
+ useEffect(() => {
72
+ const uploader = new SimpleUploader('#uploader-container', {
73
+ onFilesUpdate: (files) => console.log(files)
74
+ });
75
+ }, []);
76
+
77
+ return <div id="uploader-container"></div>;
78
+ }
79
+
80
+ ```
81
+
82
+ ---
83
+
84
+ ## ⚙️ Configuration Options
85
+
86
+ | Option | Type | Default | Description |
87
+ | --- | --- | --- | --- |
88
+ | `allowedTypes` | `Array` | `['image/']` | Array of MIME types or prefixes to allow. |
89
+ | `onFilesUpdate` | `Function` | `null` | Callback function triggered whenever files are added or removed. |
90
+
91
+ ---
92
+
93
+ ## 📖 API Methods
94
+
95
+ | Method | Description |
96
+ | --- | --- |
97
+ | `.getFiles()` | Returns an `Array` of the currently selected `File` objects. |
98
+ | `.removeFile(file)` | Removes a specific file object from the internal state and updates the UI. |
99
+
100
+ ---
101
+
102
+ ## 🎨 Custom Styling
103
+
104
+ The package comes with default styles, but you can override them in your own CSS. Key classes include:
105
+
106
+ * `.upload-container`: The main dropzone area.
107
+ * `.drag-over`: Applied to the container when a file is being hovered over it.
108
+ * `.image-preview-wrapper`: The wrapper for each individual image thumbnail.
109
+ * `.remove-icon`: The "X" button used to delete a preview.
110
+
111
+ ---
112
+
113
+ ## 📄 License
114
+
115
+ MIT © [dev-codergautam](https://www.google.com/search?q=https://github.com/dev-codergautam)
116
+
117
+ ---
118
+
119
+ ### Pro-Tip for your GitHub:
120
+
121
+ Include a **GIF** or a **screenshot** at the top of the README! Developers love seeing the UI in action before they install a package.
122
+
123
+ **Would you like me to help you write a `.gitignore` file so you don't accidentally upload your `node_modules` to GitHub?**
package/src/index.js ADDED
@@ -0,0 +1,110 @@
1
+ export default class SimpleUploader {
2
+ constructor(containerSelector, options = {}) {
3
+ this.container = document.querySelector(containerSelector);
4
+ this.options = {
5
+ allowedTypes: options.allowedTypes || ["image/"],
6
+ onFilesUpdate: options.onFilesUpdate || null,
7
+ ...options,
8
+ };
9
+
10
+ this.selectedFiles = [];
11
+ this.init();
12
+ }
13
+
14
+ init() {
15
+ this.renderBaseHTML();
16
+ this.setupEventListeners();
17
+ }
18
+
19
+ renderBaseHTML() {
20
+ this.container.classList.add("upload-container");
21
+ this.container.innerHTML = `
22
+ <p id="prompt-text">Drag & drop files, paste, or <b>click to browse</b></p>
23
+ <input type="file" id="file-input" multiple hidden />
24
+ <div id="preview-container"></div>
25
+ `;
26
+
27
+ this.promptText = this.container.querySelector("#prompt-text");
28
+ this.fileInput = this.container.querySelector("#file-input");
29
+ this.previewContainer = this.container.querySelector("#preview-container");
30
+ }
31
+
32
+ setupEventListeners() {
33
+ // Click to browse
34
+ this.promptText.addEventListener("click", () => this.fileInput.click());
35
+
36
+ this.fileInput.addEventListener("change", (e) => {
37
+ this.handleFiles(e.target.files);
38
+ e.target.value = "";
39
+ });
40
+
41
+ // Drag and Drop
42
+ ["dragenter", "dragover", "dragleave", "drop"].forEach((name) => {
43
+ this.container.addEventListener(name, (e) => {
44
+ e.preventDefault();
45
+ e.stopPropagation();
46
+ });
47
+ });
48
+
49
+ this.container.addEventListener("dragover", () => this.container.classList.add("drag-over"));
50
+ this.container.addEventListener("dragleave", () => this.container.classList.remove("drag-over"));
51
+ this.container.addEventListener("drop", (e) => {
52
+ this.container.classList.remove("drag-over");
53
+ this.handleFiles(e.dataTransfer.files);
54
+ });
55
+
56
+ // Paste
57
+ window.addEventListener("paste", (e) => {
58
+ const items = e.clipboardData.items;
59
+ const files = [];
60
+ for (let i = 0; i < items.length; i++) {
61
+ if (items[i].kind === "file") files.push(items[i].getAsFile());
62
+ }
63
+ if (files.length > 0) this.handleFiles(files);
64
+ });
65
+ }
66
+
67
+ handleFiles(files) {
68
+ const fileArray = Array.from(files).filter(file =>
69
+ this.options.allowedTypes.some(type => file.type.startsWith(type))
70
+ );
71
+
72
+ this.selectedFiles.push(...fileArray);
73
+ this.renderPreviews();
74
+
75
+ if (this.options.onFilesUpdate) {
76
+ this.options.onFilesUpdate(this.selectedFiles);
77
+ }
78
+ }
79
+
80
+ removeFile(fileToRemove) {
81
+ this.selectedFiles = this.selectedFiles.filter(f => f !== fileToRemove);
82
+ this.renderPreviews();
83
+ if (this.options.onFilesUpdate) {
84
+ this.options.onFilesUpdate(this.selectedFiles);
85
+ }
86
+ }
87
+
88
+ renderPreviews() {
89
+ this.previewContainer.innerHTML = "";
90
+ this.selectedFiles.forEach((file) => {
91
+ const reader = new FileReader();
92
+ reader.readAsDataURL(file);
93
+ reader.onloadend = () => {
94
+ const wrapper = document.createElement("div");
95
+ wrapper.className = "image-preview-wrapper";
96
+ wrapper.innerHTML = `
97
+ <img src="${reader.result}" alt="${file.name}">
98
+ <span class="remove-icon">&times;</span>
99
+ `;
100
+ wrapper.querySelector(".remove-icon").onclick = () => this.removeFile(file);
101
+ this.previewContainer.appendChild(wrapper);
102
+ };
103
+ });
104
+ }
105
+
106
+ // Helper to get current files from outside
107
+ getFiles() {
108
+ return this.selectedFiles;
109
+ }
110
+ }
package/src/styles.css ADDED
@@ -0,0 +1,71 @@
1
+ .upload-container {
2
+ width: 100%;
3
+ max-width: 500px;
4
+ min-height: 200px;
5
+ border: 2px dashed #ccc;
6
+ border-radius: 10px;
7
+ display: flex;
8
+ flex-direction: column;
9
+ align-items: center;
10
+ justify-content: center;
11
+ transition:
12
+ background 0.3s,
13
+ border-color 0.3s;
14
+ padding: 20px;
15
+ font-family: sans-serif;
16
+ position: relative; /* Context for children elements */
17
+ }
18
+
19
+ /* Make only the prompt text clickable, not the whole container */
20
+ #prompt-text {
21
+ cursor: pointer;
22
+ margin: 0;
23
+ }
24
+
25
+ .upload-container.drag-over {
26
+ background: #f0f8ff;
27
+ border-color: #007bff;
28
+ }
29
+
30
+ #preview-container {
31
+ display: flex;
32
+ flex-wrap: wrap;
33
+ justify-content: center;
34
+ margin-top: 20px;
35
+ }
36
+
37
+ /* Styling for the wrapper of each preview */
38
+ .image-preview-wrapper {
39
+ position: relative; /* Context for remove-icon positioning */
40
+ margin: 5px;
41
+ width: 80px;
42
+ height: 80px;
43
+ }
44
+
45
+ .image-preview-wrapper img {
46
+ width: 100%;
47
+ height: 100%;
48
+ object-fit: cover;
49
+ border-radius: 5px;
50
+ }
51
+
52
+ /* The style for the cross icon */
53
+ .remove-icon {
54
+ position: absolute;
55
+ top: -8px; /* Slightly offset from the corner */
56
+ right: -8px;
57
+ cursor: pointer;
58
+ background: rgba(0, 0, 0, 0.6);
59
+ color: white;
60
+ padding: 3px 6px;
61
+ border-radius: 50%;
62
+ font-size: 14px;
63
+ font-weight: bold;
64
+ line-height: 1;
65
+ z-index: 10; /* Ensure it sits on top of everything */
66
+ transition: background 0.2s;
67
+ }
68
+
69
+ .remove-icon:hover {
70
+ background: rgba(255, 0, 0, 0.8); /* Turns red on hover */
71
+ }