@nuralyui/file-upload 0.0.11 → 0.0.12

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 (2) hide show
  1. package/bundle.js +384 -1
  2. package/package.json +1 -1
package/bundle.js CHANGED
@@ -1 +1,384 @@
1
- import{css as i,LitElement as e,html as t}from"lit";import{property as o,state as s,customElement as r}from"lit/decorators.js";const l=i`:host{display:block;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif}.upload{width:100%}.upload-dragger{background-color:#f8f9fa;border:1px dashed #d9d9d9;border-radius:6px;box-sizing:border-box;width:100%;height:180px;text-align:center;cursor:pointer;position:relative;overflow:hidden;transition:border-color .3s;display:flex;flex-direction:column;justify-content:center;align-items:center}.upload-dragger:hover{border-color:#409eff}.upload-dragger.is-dragover{background-color:rgba(64,158,255,.06);border-color:#409eff}.upload-icon{font-size:28px;color:#c0c4cc;margin-bottom:8px}.upload-text{color:#606266;font-size:14px;text-align:center;padding:0 12px}.upload-tip{font-size:12px;color:#909399;margin-top:7px;padding:0 12px}.upload-button{padding:8px 16px;background-color:#409eff;color:#fff;border:none;border-radius:4px;cursor:pointer;font-size:14px;transition:background-color .3s}.upload-button:hover{background-color:#66b1ff}.file-list{margin-top:10px;width:100%}.file-item{display:flex;align-items:center;margin-bottom:8px;transition:all .3s;padding:8px;border-radius:4px;gap:8px;width:100%;box-sizing:border-box;min-width:0;flex-wrap:nowrap;overflow:hidden;max-width:100%}.file-item:hover{background-color:#f8f9fa}.file-name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#606266;min-width:0;max-width:100%;word-break:break-all;width:0}.file-size{color:#909399;font-size:12px;flex-shrink:0;margin-left:8px;white-space:nowrap}.file-status{display:flex;align-items:center;flex-shrink:0}.file-actions{display:flex;gap:4px;flex-shrink:0}.file-actions button{background:0 0;border:none;padding:4px;cursor:pointer;color:#909399}.file-actions button:hover{color:#409eff}.progress-bar{height:2px;width:100%;background-color:#e6e6e6;margin-top:4px;position:relative;border-radius:2px;overflow:hidden}.progress-inner{height:100%;background-color:#409eff;position:absolute;left:0;top:0;transition:width .3s ease}.progress-percentage{position:absolute;right:0;top:-18px;font-size:12px;color:#409eff}.hidden{display:none}.success{color:#67c23a}.error{color:#f56c6c}.icon-delete{color:#f56c6c}.file-preview{width:100%;margin-top:4px}.image-preview{display:block;max-width:100%;max-height:200px;border-radius:4px;object-fit:contain;cursor:zoom-in}.preview-modal{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.7);display:flex;justify-content:center;align-items:center;z-index:1000}.preview-modal img{max-width:90%;max-height:90%;object-fit:contain}.preview-close{position:absolute;top:20px;right:20px;color:#fff;font-size:30px;background:0 0;border:none;cursor:pointer}.preview-icon{padding:4px;color:#409eff;cursor:zoom-in}.file-container{width:100%;position:relative;overflow:hidden}@media (max-width:600px){.upload-dragger{height:140px;padding:12px}.upload-icon{font-size:24px}.upload-text,.upload-tip{font-size:13px}.file-item{display:grid;grid-template-columns:auto 1fr;grid-template-areas:"icon filename" "size status" "progress progress" "actions actions";gap:4px 8px;align-items:center;padding:8px;width:100%;box-sizing:border-box;overflow:hidden}.file-item>svg:first-child{grid-area:icon;align-self:start}.file-name{grid-area:filename;margin:0;padding:2px 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:0;max-width:100%;word-break:break-all;flex:1}.file-size{grid-area:size;margin:0}.file-status{grid-area:status;justify-self:end}.progress-bar{grid-area:progress;width:100%}.file-actions{grid-area:actions;margin:4px 0 0 0;justify-content:flex-end;width:100%}.upload-button{width:100%;font-size:16px}}`,n={isImageFile:i=>i.type.startsWith("image/"),formatFileSize(i){if(0===i)return"0 B";const e=Math.floor(Math.log(i)/Math.log(1024));return parseFloat((i/Math.pow(1024,e)).toFixed(2))+" "+["B","KB","MB","GB","TB"][e]},createFilePreview:i=>new Promise((e=>{const t=new FileReader;t.onload=i=>{var t;e(null===(t=i.target)||void 0===t?void 0:t.result)},t.readAsDataURL(i)}))};var a=function(i,e,t,o){for(var s,r=arguments.length,l=r<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,t):o,n=i.length-1;n>=0;n--)(s=i[n])&&(l=(r<3?s(l):r>3?s(e,t,l):s(e,t))||l);return r>3&&l&&Object.defineProperty(e,t,l),l},d=function(i,e,t,o){return new(t||(t=Promise))((function(s,r){function l(i){try{a(o.next(i))}catch(i){r(i)}}function n(i){try{a(o.throw(i))}catch(i){r(i)}}function a(i){var e;i.done?s(i.value):(e=i.value,e instanceof t?e:new t((function(i){i(e)}))).then(l,n)}a((o=o.apply(i,e||[])).next())}))};let h=class extends e{constructor(){super(...arguments),this.accept="",this.multiple=!1,this.drag=!0,this.tip="",this.limit=0,this.preview=!0,this.generatePreviewOnUpload=!1,this.fileList=[],this.isDragOver=!1,this.showDragArea=!1,this.inputElement=null,this.dragCounter=0,this.previewImage=null,this._onDocumentDragEnter=i=>{i.preventDefault(),this.dragCounter++,1===this.dragCounter&&(this.showDragArea=!0)},this._onDocumentDragLeave=i=>{i.preventDefault(),this.dragCounter--,0===this.dragCounter&&(this.showDragArea=!1,this.isDragOver=!1)},this._onDocumentDrop=i=>{i.target===this||this.contains(i.target)||(i.preventDefault(),this.dragCounter=0,this.showDragArea=!1,this.isDragOver=!1)},this._onDocumentDragOver=i=>{i.preventDefault();const e=i.composedPath().includes(this);this.isDragOver=!!e},this._onDrop=i=>{var e;i.preventDefault(),i.stopPropagation(),this.dragCounter=0,this.isDragOver=!1,this.showDragArea=!1,(null===(e=i.dataTransfer)||void 0===e?void 0:e.files)&&(this.dispatchEvent(new CustomEvent("files-changed",{detail:i.dataTransfer.files,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("file-drop",{detail:{files:i.dataTransfer.files},bubbles:!0,composed:!0})),this._handleFiles(i.dataTransfer.files))},this._onClick=()=>{var i;null===(i=this.inputElement)||void 0===i||i.click()},this._onChange=i=>{const e=i.target;e.files&&(this.dispatchEvent(new CustomEvent("files-changed",{detail:e.files,bubbles:!0,composed:!0})),this._handleFiles(e.files),e.value="")}}connectedCallback(){super.connectedCallback(),this.drag&&(document.addEventListener("dragenter",this._onDocumentDragEnter),document.addEventListener("dragleave",this._onDocumentDragLeave),document.addEventListener("drop",this._onDocumentDrop),document.addEventListener("dragover",this._onDocumentDragOver))}disconnectedCallback(){super.disconnectedCallback(),this.drag&&(document.removeEventListener("dragenter",this._onDocumentDragEnter),document.removeEventListener("dragleave",this._onDocumentDragLeave),document.removeEventListener("drop",this._onDocumentDrop),document.removeEventListener("dragover",this._onDocumentDragOver))}firstUpdated(i){var e;super.firstUpdated(i),this.inputElement=(null===(e=this.shadowRoot)||void 0===e?void 0:e.querySelector('input[type="file"]'))||null}_handleFiles(i){return d(this,void 0,void 0,(function*(){if(this.multiple&&this.limit>0&&this.fileList.length+i.length>this.limit)return void this._dispatchEvent("exceed",{files:i});if(!this.multiple&&i.length>0){const e=i[i.length-1];this.previewImage&&this.fileList.some((i=>i.url===this.previewImage))&&(this.previewImage=null);const t=[...this.fileList];for(const i of t)this._dispatchEvent("remove",{file:i});this.fileList=[];const o=n.isImageFile(e),s={name:e.name,size:n.formatFileSize(e.size),raw:e,status:"ready",percentage:0,uid:Date.now()+Math.random().toString(36).substring(2),isImage:o};return this.preview&&this.generatePreviewOnUpload&&o&&(s.url=yield n.createFilePreview(e)),this.fileList=[s],this.requestUpdate(),void this._dispatchEvent("select",{files:[s],fileList:this.fileList})}const e=[];for(const t of Array.from(i)){const i=n.isImageFile(t),o={name:t.name,size:n.formatFileSize(t.size),raw:t,status:"ready",percentage:0,uid:Date.now()+Math.random().toString(36).substring(2),isImage:i};this.preview&&this.generatePreviewOnUpload&&i&&(o.url=yield n.createFilePreview(t)),this.fileList=[...this.fileList,o],e.push(o)}this.requestUpdate(),this._dispatchEvent("select",{files:e,fileList:this.fileList})}))}updateFileStatus(i,e,t){const o=this.fileList.find((e=>e.uid===i));o&&(o.status=e,void 0!==t&&(o.percentage=t),this._updateFile(o))}_updateFile(i){this.fileList=this.fileList.map((e=>e.uid===i.uid?i:e)),this.requestUpdate()}_removeFile(i){const e=this.fileList.find((e=>e.uid===i));this.fileList=this.fileList.filter((e=>e.uid!==i)),e&&this._dispatchEvent("remove",{file:e}),this.requestUpdate()}_dispatchEvent(i,e){this.dispatchEvent(new CustomEvent(`file-${i}`,{detail:e,bubbles:!0,composed:!0}))}_showPreview(i){this.previewImage=i}_closePreview(){this.previewImage=null}render(){return t`<div class="upload" @drop="${this._onDrop}" @dragover="${i=>i.preventDefault()}"><input type="file" class="hidden" accept="${this.accept}" ?multiple="${this.multiple}" @change="${this._onChange}"> ${this.showDragArea?t`<div class="upload-dragger ${this.isDragOver?"is-dragover":""}" @click="${this._onClick}"><div class="upload-icon"><svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg></div><div class="upload-text">Drop file here or click to upload</div>${this.tip?t`<div class="upload-tip">${this.tip}</div>`:""}</div>`:t`<nr-button @click="${this._onClick}">Upload File</nr-button>${this.tip?t`<div class="upload-tip">${this.tip}</div>`:""}`}<div class="file-list">${this.fileList.map((i=>t`<div class="file-item">${i.isImage?t`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>`:t`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline></svg>`}<div class="file-name">${i.name}</div><div class="file-size">${i.size}</div><div class="file-status">${"success"===i.status?t`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#67c23a" stroke-width="2"><polyline points="20 6 9 17 4 12"></polyline></svg>`:"error"===i.status?t`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f56c6c" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>`:"uploading"===i.status?t`${i.percentage}%`:""}</div><div class="file-actions">${i.isImage&&i.url?t`<button class="preview-icon" @click="${()=>this._showPreview(i.url)}"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle></svg></button>`:""} <button @click="${()=>this._removeFile(i.uid)}"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg></button></div>${"uploading"===i.status?t`<div class="progress-bar"><div class="progress-inner" style="width:${i.percentage}"></div></div>`:""}</div>${this.preview&&i.isImage&&i.url?t`<div class="file-preview"><img class="image-preview" src="${i.url}" alt="${i.name}" @click="${()=>this._showPreview(i.url)}"></div>`:""}`))}</div>${this.previewImage?t`<div class="preview-modal" @click="${this._closePreview}"><button class="preview-close">×</button> <img src="${this.previewImage}" alt="Preview"></div>`:""}</div>`}};h.styles=l,a([o({type:String})],h.prototype,"accept",void 0),a([o({type:Boolean})],h.prototype,"multiple",void 0),a([o({type:Boolean})],h.prototype,"drag",void 0),a([o({type:String})],h.prototype,"tip",void 0),a([o({type:Number})],h.prototype,"limit",void 0),a([o({type:Boolean})],h.prototype,"preview",void 0),a([o({type:Boolean})],h.prototype,"generatePreviewOnUpload",void 0),a([s()],h.prototype,"fileList",void 0),a([s()],h.prototype,"isDragOver",void 0),a([s()],h.prototype,"showDragArea",void 0),a([s()],h.prototype,"inputElement",void 0),a([s()],h.prototype,"dragCounter",void 0),a([s()],h.prototype,"previewImage",void 0),h=a([r("nr-file-upload")],h);export{h as FileUpload};
1
+ import{css as i,LitElement as e,html as t}from"lit";import{property as o,state as s,customElement as r}from"lit/decorators.js";const n=i`
2
+ :host {
3
+ display: block;
4
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
5
+ }
6
+ .upload {
7
+ width: 100%;
8
+ }
9
+ .upload-dragger {
10
+ background-color: #f8f9fa;
11
+ border: 1px dashed #d9d9d9;
12
+ border-radius: 6px;
13
+ box-sizing: border-box;
14
+ width: 100%;
15
+ height: 180px;
16
+ text-align: center;
17
+ cursor: pointer;
18
+ position: relative;
19
+ overflow: hidden;
20
+ transition: border-color 0.3s;
21
+ display: flex;
22
+ flex-direction: column;
23
+ justify-content: center;
24
+ align-items: center;
25
+ }
26
+ .upload-dragger:hover {
27
+ border-color: #409eff;
28
+ }
29
+ .upload-dragger.is-dragover {
30
+ background-color: rgba(64, 158, 255, 0.06);
31
+ border-color: #409eff;
32
+ }
33
+ .upload-icon {
34
+ font-size: 28px;
35
+ color: #c0c4cc;
36
+ margin-bottom: 8px;
37
+ }
38
+ .upload-text {
39
+ color: #606266;
40
+ font-size: 14px;
41
+ text-align: center;
42
+ padding: 0 12px;
43
+ }
44
+ .upload-tip {
45
+ font-size: 12px;
46
+ color: #909399;
47
+ margin-top: 7px;
48
+ padding: 0 12px;
49
+ }
50
+ .upload-button {
51
+ padding: 8px 16px;
52
+ background-color: #409eff;
53
+ color: white;
54
+ border: none;
55
+ border-radius: 4px;
56
+ cursor: pointer;
57
+ font-size: 14px;
58
+ transition: background-color 0.3s;
59
+ }
60
+ .upload-button:hover {
61
+ background-color: #66b1ff;
62
+ }
63
+ .file-list {
64
+ margin-top: 10px;
65
+ width: 100%;
66
+ }
67
+ .file-item {
68
+ display: flex;
69
+ align-items: center;
70
+ margin-bottom: 8px;
71
+ transition: all 0.3s;
72
+ padding: 8px;
73
+ border-radius: 4px;
74
+ gap: 8px;
75
+ width: 100%;
76
+ box-sizing: border-box;
77
+ min-width: 0;
78
+ flex-wrap: nowrap;
79
+ overflow: hidden;
80
+ max-width: 100%;
81
+ }
82
+ .file-item:hover {
83
+ background-color: #f8f9fa;
84
+ }
85
+ .file-name {
86
+ flex: 1;
87
+ white-space: nowrap;
88
+ overflow: hidden;
89
+ text-overflow: ellipsis;
90
+ color: #606266;
91
+ min-width: 0;
92
+ max-width: 100%;
93
+ word-break: break-all;
94
+ width: 0;
95
+ }
96
+ .file-size {
97
+ color: #909399;
98
+ font-size: 12px;
99
+ flex-shrink: 0;
100
+ margin-left: 8px;
101
+ white-space: nowrap;
102
+ }
103
+ .file-status {
104
+ display: flex;
105
+ align-items: center;
106
+ flex-shrink: 0;
107
+ }
108
+ .file-actions {
109
+ display: flex;
110
+ gap: 4px;
111
+ flex-shrink: 0; /* Prevent shrinking */
112
+ }
113
+ .file-actions button {
114
+ background: none;
115
+ border: none;
116
+ padding: 4px;
117
+ cursor: pointer;
118
+ color: #909399;
119
+ }
120
+ .file-actions button:hover {
121
+ color: #409eff;
122
+ }
123
+
124
+ /* Progress bar styles - fixed to ensure full width */
125
+ .progress-bar {
126
+ height: 2px;
127
+ width: 100%;
128
+ background-color: #e6e6e6;
129
+ margin-top: 4px;
130
+ position: relative;
131
+ border-radius: 2px;
132
+ overflow: hidden;
133
+ }
134
+ .progress-inner {
135
+ height: 100%;
136
+ background-color: #409eff;
137
+ position: absolute;
138
+ left: 0;
139
+ top: 0;
140
+ transition: width 0.3s ease;
141
+ }
142
+
143
+ /* Progress percentage indicator */
144
+ .progress-percentage {
145
+ position: absolute;
146
+ right: 0;
147
+ top: -18px;
148
+ font-size: 12px;
149
+ color: #409eff;
150
+ }
151
+
152
+ .hidden {
153
+ display: none;
154
+ }
155
+ .success {
156
+ color: #67c23a;
157
+ }
158
+ .error {
159
+ color: #f56c6c;
160
+ }
161
+ .icon-delete {
162
+ color: #f56c6c;
163
+ }
164
+ .file-preview {
165
+ width: 100%;
166
+ margin-top: 4px;
167
+ }
168
+ .image-preview {
169
+ display: block;
170
+ max-width: 100%;
171
+ max-height: 200px;
172
+ border-radius: 4px;
173
+ object-fit: contain;
174
+ cursor: zoom-in;
175
+ }
176
+ .preview-modal {
177
+ position: fixed;
178
+ top: 0;
179
+ left: 0;
180
+ width: 100%;
181
+ height: 100%;
182
+ background-color: rgba(0, 0, 0, 0.7);
183
+ display: flex;
184
+ justify-content: center;
185
+ align-items: center;
186
+ z-index: 1000;
187
+ }
188
+ .preview-modal img {
189
+ max-width: 90%;
190
+ max-height: 90%;
191
+ object-fit: contain;
192
+ }
193
+ .preview-close {
194
+ position: absolute;
195
+ top: 20px;
196
+ right: 20px;
197
+ color: white;
198
+ font-size: 30px;
199
+ background: none;
200
+ border: none;
201
+ cursor: pointer;
202
+ }
203
+ .preview-icon {
204
+ padding: 4px;
205
+ color: #409eff;
206
+ cursor: zoom-in;
207
+ }
208
+
209
+ /* File item container with progress bar */
210
+ .file-container {
211
+ width: 100%;
212
+ position: relative;
213
+ overflow: hidden; /* Prevent child overflow */
214
+ }
215
+
216
+ /* Responsive styles */
217
+ @media (max-width: 600px) {
218
+ .upload-dragger {
219
+ height: 140px;
220
+ padding: 12px;
221
+ }
222
+ .upload-icon {
223
+ font-size: 24px;
224
+ }
225
+ .upload-text,
226
+ .upload-tip {
227
+ font-size: 13px;
228
+ }
229
+ .file-item {
230
+ display: grid;
231
+ grid-template-columns: auto 1fr;
232
+ grid-template-areas:
233
+ "icon filename"
234
+ "size status"
235
+ "progress progress"
236
+ "actions actions";
237
+ gap: 4px 8px;
238
+ align-items: center;
239
+ padding: 8px;
240
+ width: 100%;
241
+ box-sizing: border-box;
242
+ overflow: hidden; /* Hide content that overflows */
243
+ }
244
+ .file-item > svg:first-child {
245
+ grid-area: icon;
246
+ align-self: start;
247
+ }
248
+ .file-name {
249
+ grid-area: filename;
250
+ margin: 0;
251
+ padding: 2px 0;
252
+ white-space: nowrap;
253
+ overflow: hidden;
254
+ text-overflow: ellipsis;
255
+ width: 0; /* Force shrinking to minimum width */
256
+ max-width: 100%; /* Ensure it doesn't exceed its container */
257
+ word-break: break-all; /* Break extremely long words if necessary */
258
+ flex: 1; /* Take available space */
259
+ }
260
+ .file-size {
261
+ grid-area: size;
262
+ margin: 0;
263
+ }
264
+ .file-status {
265
+ grid-area: status;
266
+ justify-self: end;
267
+ }
268
+ .progress-bar {
269
+ grid-area: progress;
270
+ width: 100%;
271
+ }
272
+ .file-actions {
273
+ grid-area: actions;
274
+ margin: 4px 0 0 0;
275
+ justify-content: flex-end;
276
+ width: 100%;
277
+ }
278
+ .upload-button {
279
+ width: 100%;
280
+ font-size: 16px;
281
+ }
282
+ }
283
+ `,l={isImageFile:i=>i.type.startsWith("image/"),formatFileSize(i){if(0===i)return"0 B";const e=Math.floor(Math.log(i)/Math.log(1024));return parseFloat((i/Math.pow(1024,e)).toFixed(2))+" "+["B","KB","MB","GB","TB"][e]},createFilePreview:i=>new Promise((e=>{const t=new FileReader;t.onload=i=>{var t;e(null===(t=i.target)||void 0===t?void 0:t.result)},t.readAsDataURL(i)}))};var a=function(i,e,t,o){for(var s,r=arguments.length,n=r<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,t):o,l=i.length-1;l>=0;l--)(s=i[l])&&(n=(r<3?s(n):r>3?s(e,t,n):s(e,t))||n);return r>3&&n&&Object.defineProperty(e,t,n),n},d=function(i,e,t,o){return new(t||(t=Promise))((function(s,r){function n(i){try{a(o.next(i))}catch(i){r(i)}}function l(i){try{a(o.throw(i))}catch(i){r(i)}}function a(i){var e;i.done?s(i.value):(e=i.value,e instanceof t?e:new t((function(i){i(e)}))).then(n,l)}a((o=o.apply(i,e||[])).next())}))};let h=class extends e{constructor(){super(...arguments),this.accept="",this.multiple=!1,this.drag=!0,this.tip="",this.limit=0,this.preview=!0,this.generatePreviewOnUpload=!1,this.fileList=[],this.isDragOver=!1,this.showDragArea=!1,this.inputElement=null,this.dragCounter=0,this.previewImage=null,this._onDocumentDragEnter=i=>{i.preventDefault(),this.dragCounter++,1===this.dragCounter&&(this.showDragArea=!0)},this._onDocumentDragLeave=i=>{i.preventDefault(),this.dragCounter--,0===this.dragCounter&&(this.showDragArea=!1,this.isDragOver=!1)},this._onDocumentDrop=i=>{i.target===this||this.contains(i.target)||(i.preventDefault(),this.dragCounter=0,this.showDragArea=!1,this.isDragOver=!1)},this._onDocumentDragOver=i=>{i.preventDefault();const e=i.composedPath().includes(this);this.isDragOver=!!e},this._onDrop=i=>{var e;i.preventDefault(),i.stopPropagation(),this.dragCounter=0,this.isDragOver=!1,this.showDragArea=!1,(null===(e=i.dataTransfer)||void 0===e?void 0:e.files)&&(this.dispatchEvent(new CustomEvent("files-changed",{detail:i.dataTransfer.files,bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent("file-drop",{detail:{files:i.dataTransfer.files},bubbles:!0,composed:!0})),this._handleFiles(i.dataTransfer.files))},this._onClick=()=>{var i;null===(i=this.inputElement)||void 0===i||i.click()},this._onChange=i=>{const e=i.target;e.files&&(this.dispatchEvent(new CustomEvent("files-changed",{detail:e.files,bubbles:!0,composed:!0})),this._handleFiles(e.files),e.value="")}}connectedCallback(){super.connectedCallback(),this.drag&&(document.addEventListener("dragenter",this._onDocumentDragEnter),document.addEventListener("dragleave",this._onDocumentDragLeave),document.addEventListener("drop",this._onDocumentDrop),document.addEventListener("dragover",this._onDocumentDragOver))}disconnectedCallback(){super.disconnectedCallback(),this.drag&&(document.removeEventListener("dragenter",this._onDocumentDragEnter),document.removeEventListener("dragleave",this._onDocumentDragLeave),document.removeEventListener("drop",this._onDocumentDrop),document.removeEventListener("dragover",this._onDocumentDragOver))}firstUpdated(i){var e;super.firstUpdated(i),this.inputElement=(null===(e=this.shadowRoot)||void 0===e?void 0:e.querySelector('input[type="file"]'))||null}_handleFiles(i){return d(this,void 0,void 0,(function*(){if(this.multiple&&this.limit>0&&this.fileList.length+i.length>this.limit)return void this._dispatchEvent("exceed",{files:i});if(!this.multiple&&i.length>0){const e=i[i.length-1];this.previewImage&&this.fileList.some((i=>i.url===this.previewImage))&&(this.previewImage=null);const t=[...this.fileList];for(const i of t)this._dispatchEvent("remove",{file:i});this.fileList=[];const o=l.isImageFile(e),s={name:e.name,size:l.formatFileSize(e.size),raw:e,status:"ready",percentage:0,uid:Date.now()+Math.random().toString(36).substring(2),isImage:o};return this.preview&&this.generatePreviewOnUpload&&o&&(s.url=yield l.createFilePreview(e)),this.fileList=[s],this.requestUpdate(),void this._dispatchEvent("select",{files:[s],fileList:this.fileList})}const e=[];for(const t of Array.from(i)){const i=l.isImageFile(t),o={name:t.name,size:l.formatFileSize(t.size),raw:t,status:"ready",percentage:0,uid:Date.now()+Math.random().toString(36).substring(2),isImage:i};this.preview&&this.generatePreviewOnUpload&&i&&(o.url=yield l.createFilePreview(t)),this.fileList=[...this.fileList,o],e.push(o)}this.requestUpdate(),this._dispatchEvent("select",{files:e,fileList:this.fileList})}))}updateFileStatus(i,e,t){const o=this.fileList.find((e=>e.uid===i));o&&(o.status=e,void 0!==t&&(o.percentage=t),this._updateFile(o))}_updateFile(i){this.fileList=this.fileList.map((e=>e.uid===i.uid?i:e)),this.requestUpdate()}_removeFile(i){const e=this.fileList.find((e=>e.uid===i));this.fileList=this.fileList.filter((e=>e.uid!==i)),e&&this._dispatchEvent("remove",{file:e}),this.requestUpdate()}_dispatchEvent(i,e){this.dispatchEvent(new CustomEvent(`file-${i}`,{detail:e,bubbles:!0,composed:!0}))}_showPreview(i){this.previewImage=i}_closePreview(){this.previewImage=null}render(){return t`
284
+ <div class="upload" @drop=${this._onDrop} @dragover=${i=>i.preventDefault()}>
285
+ <input
286
+ type="file"
287
+ class="hidden"
288
+ accept=${this.accept}
289
+ ?multiple=${this.multiple}
290
+ @change=${this._onChange}
291
+ />
292
+
293
+ ${this.showDragArea?t`
294
+ <div
295
+ class="upload-dragger ${this.isDragOver?"is-dragover":""}"
296
+ @click=${this._onClick}
297
+ >
298
+ <div class="upload-icon">
299
+ <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
300
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
301
+ <polyline points="17 8 12 3 7 8"></polyline>
302
+ <line x1="12" y1="3" x2="12" y2="15"></line>
303
+ </svg>
304
+ </div>
305
+ <div class="upload-text">Drop file here or click to upload</div>
306
+ ${this.tip?t`<div class="upload-tip">${this.tip}</div>`:""}
307
+ </div>
308
+ `:t`
309
+ <nr-button @click=${this._onClick}>Upload File</nr-button>
310
+ ${this.tip?t`<div class="upload-tip">${this.tip}</div>`:""}
311
+ `}
312
+
313
+ <div class="file-list">
314
+ ${this.fileList.map((i=>t`
315
+ <div class="file-item">
316
+ ${i.isImage?t`
317
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
318
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
319
+ <circle cx="8.5" cy="8.5" r="1.5"></circle>
320
+ <polyline points="21 15 16 10 5 21"></polyline>
321
+ </svg>
322
+ `:t`
323
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
324
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
325
+ <polyline points="14 2 14 8 20 8"></polyline>
326
+ </svg>
327
+ `}
328
+ <div class="file-name">${i.name}</div>
329
+ <div class="file-size">${i.size}</div>
330
+ <div class="file-status">
331
+ ${"success"===i.status?t`
332
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#67c23a" stroke-width="2">
333
+ <polyline points="20 6 9 17 4 12"></polyline>
334
+ </svg>
335
+ `:"error"===i.status?t`
336
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f56c6c" stroke-width="2">
337
+ <line x1="18" y1="6" x2="6" y2="18"></line>
338
+ <line x1="6" y1="6" x2="18" y2="18"></line>
339
+ </svg>
340
+ `:"uploading"===i.status?t`${i.percentage}%`:""}
341
+ </div>
342
+ <div class="file-actions">
343
+ ${i.isImage&&i.url?t`
344
+ <button class="preview-icon" @click=${()=>this._showPreview(i.url)}>
345
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
346
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
347
+ <circle cx="12" cy="12" r="3"></circle>
348
+ </svg>
349
+ </button>
350
+ `:""}
351
+ <button @click=${()=>this._removeFile(i.uid)}>
352
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
353
+ <line x1="18" y1="6" x2="6" y2="18"></line>
354
+ <line x1="6" y1="6" x2="18" y2="18"></line>
355
+ </svg>
356
+ </button>
357
+ </div>
358
+ ${"uploading"===i.status?t`
359
+ <div class="progress-bar">
360
+ <div class="progress-inner" style="width: ${i.percentage}%"></div>
361
+ </div>
362
+ `:""}
363
+ </div>
364
+ ${this.preview&&i.isImage&&i.url?t`
365
+ <div class="file-preview">
366
+ <img
367
+ class="image-preview"
368
+ src="${i.url}"
369
+ alt="${i.name}"
370
+ @click=${()=>this._showPreview(i.url)}
371
+ />
372
+ </div>
373
+ `:""}
374
+ `))}
375
+ </div>
376
+
377
+ ${this.previewImage?t`
378
+ <div class="preview-modal" @click=${this._closePreview}>
379
+ <button class="preview-close">×</button>
380
+ <img src="${this.previewImage}" alt="Preview" />
381
+ </div>
382
+ `:""}
383
+ </div>
384
+ `}};h.styles=n,a([o({type:String})],h.prototype,"accept",void 0),a([o({type:Boolean})],h.prototype,"multiple",void 0),a([o({type:Boolean})],h.prototype,"drag",void 0),a([o({type:String})],h.prototype,"tip",void 0),a([o({type:Number})],h.prototype,"limit",void 0),a([o({type:Boolean})],h.prototype,"preview",void 0),a([o({type:Boolean})],h.prototype,"generatePreviewOnUpload",void 0),a([s()],h.prototype,"fileList",void 0),a([s()],h.prototype,"isDragOver",void 0),a([s()],h.prototype,"showDragArea",void 0),a([s()],h.prototype,"inputElement",void 0),a([s()],h.prototype,"dragCounter",void 0),a([s()],h.prototype,"previewImage",void 0),h=a([r("nr-file-upload")],h);export{h as FileUpload};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuralyui/file-upload",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",