@vaadin/upload 25.1.0-alpha6 → 25.1.0-alpha8
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/custom-elements.json +2513 -0
- package/package.json +13 -11
- package/src/vaadin-upload-button.js +16 -10
- package/src/vaadin-upload-drop-zone.d.ts +2 -1
- package/src/vaadin-upload-drop-zone.js +55 -16
- package/src/vaadin-upload-file-list-mixin.js +20 -3
- package/src/vaadin-upload-file-list.js +1 -1
- package/src/vaadin-upload-file.js +1 -1
- package/src/vaadin-upload-icon.js +1 -1
- package/src/vaadin-upload-manager.d.ts +21 -1
- package/src/vaadin-upload-manager.js +43 -0
- package/src/vaadin-upload-mixin.d.ts +1 -0
- package/src/vaadin-upload-mixin.js +9 -1
- package/src/vaadin-upload.js +1 -1
- package/web-types.json +11 -11
- package/web-types.lit.json +4 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/upload",
|
|
3
|
-
"version": "25.1.0-
|
|
3
|
+
"version": "25.1.0-alpha8",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"src",
|
|
24
24
|
"vaadin-*.d.ts",
|
|
25
25
|
"vaadin-*.js",
|
|
26
|
+
"custom-elements.json",
|
|
26
27
|
"web-types.json",
|
|
27
28
|
"web-types.lit.json"
|
|
28
29
|
],
|
|
@@ -34,24 +35,25 @@
|
|
|
34
35
|
],
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
37
|
-
"@vaadin/a11y-base": "25.1.0-
|
|
38
|
-
"@vaadin/button": "25.1.0-
|
|
39
|
-
"@vaadin/component-base": "25.1.0-
|
|
40
|
-
"@vaadin/progress-bar": "25.1.0-
|
|
41
|
-
"@vaadin/vaadin-themable-mixin": "25.1.0-
|
|
38
|
+
"@vaadin/a11y-base": "25.1.0-alpha8",
|
|
39
|
+
"@vaadin/button": "25.1.0-alpha8",
|
|
40
|
+
"@vaadin/component-base": "25.1.0-alpha8",
|
|
41
|
+
"@vaadin/progress-bar": "25.1.0-alpha8",
|
|
42
|
+
"@vaadin/vaadin-themable-mixin": "25.1.0-alpha8",
|
|
42
43
|
"lit": "^3.0.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
|
-
"@vaadin/aura": "25.1.0-
|
|
46
|
-
"@vaadin/chai-plugins": "25.1.0-
|
|
47
|
-
"@vaadin/test-runner-commands": "25.1.0-
|
|
46
|
+
"@vaadin/aura": "25.1.0-alpha8",
|
|
47
|
+
"@vaadin/chai-plugins": "25.1.0-alpha8",
|
|
48
|
+
"@vaadin/test-runner-commands": "25.1.0-alpha8",
|
|
48
49
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
49
|
-
"@vaadin/vaadin-lumo-styles": "25.1.0-
|
|
50
|
+
"@vaadin/vaadin-lumo-styles": "25.1.0-alpha8",
|
|
50
51
|
"sinon": "^21.0.0"
|
|
51
52
|
},
|
|
53
|
+
"customElements": "custom-elements.json",
|
|
52
54
|
"web-types": [
|
|
53
55
|
"web-types.json",
|
|
54
56
|
"web-types.lit.json"
|
|
55
57
|
],
|
|
56
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "810590c9c7682a9326c9352df795b5ea4891a71f"
|
|
57
59
|
}
|
|
@@ -70,7 +70,7 @@ import { UploadManager } from './vaadin-upload-manager.js';
|
|
|
70
70
|
*
|
|
71
71
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
72
72
|
*
|
|
73
|
-
* @customElement
|
|
73
|
+
* @customElement vaadin-upload-button
|
|
74
74
|
* @extends HTMLElement
|
|
75
75
|
* @mixes ButtonMixin
|
|
76
76
|
* @mixes ElementMixin
|
|
@@ -128,7 +128,7 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
130
|
* Whether the button is disabled.
|
|
131
|
-
* Returns true if either explicitly disabled or maxFilesReached is true.
|
|
131
|
+
* Returns true if either explicitly disabled, manager is disabled, or maxFilesReached is true.
|
|
132
132
|
* @type {boolean}
|
|
133
133
|
* @override
|
|
134
134
|
*/
|
|
@@ -138,8 +138,7 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
138
138
|
|
|
139
139
|
set disabled(value) {
|
|
140
140
|
this.__explicitDisabled = Boolean(value);
|
|
141
|
-
|
|
142
|
-
super.disabled = this.__explicitDisabled || this.maxFilesReached;
|
|
141
|
+
super.disabled = this.__effectiveDisabled;
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
/** @protected */
|
|
@@ -182,6 +181,7 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
182
181
|
// Clean up manager listener to prevent memory leaks
|
|
183
182
|
if (this.manager instanceof UploadManager) {
|
|
184
183
|
this.manager.removeEventListener('max-files-reached-changed', this.__syncFromManager);
|
|
184
|
+
this.manager.removeEventListener('disabled-changed', this.__syncFromManager);
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
@@ -192,8 +192,9 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
192
192
|
// Re-attach manager listener when reconnected to DOM
|
|
193
193
|
if (this.manager instanceof UploadManager) {
|
|
194
194
|
this.manager.addEventListener('max-files-reached-changed', this.__syncFromManager);
|
|
195
|
-
this.__syncFromManager
|
|
195
|
+
this.manager.addEventListener('disabled-changed', this.__syncFromManager);
|
|
196
196
|
}
|
|
197
|
+
this.__syncFromManager();
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
/**
|
|
@@ -250,11 +251,13 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
250
251
|
// Remove listener from old manager
|
|
251
252
|
if (oldManager instanceof UploadManager) {
|
|
252
253
|
oldManager.removeEventListener('max-files-reached-changed', this.__syncFromManager);
|
|
254
|
+
oldManager.removeEventListener('disabled-changed', this.__syncFromManager);
|
|
253
255
|
}
|
|
254
256
|
|
|
255
257
|
// Add listener to new manager and sync state only when connected
|
|
256
258
|
if (this.isConnected && manager instanceof UploadManager) {
|
|
257
259
|
manager.addEventListener('max-files-reached-changed', this.__syncFromManager);
|
|
260
|
+
manager.addEventListener('disabled-changed', this.__syncFromManager);
|
|
258
261
|
this.__syncFromManager();
|
|
259
262
|
} else if (this.isConnected) {
|
|
260
263
|
// No manager - reset state
|
|
@@ -262,6 +265,13 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
262
265
|
}
|
|
263
266
|
}
|
|
264
267
|
|
|
268
|
+
/** @private */
|
|
269
|
+
get __effectiveDisabled() {
|
|
270
|
+
const noManager = !(this.manager instanceof UploadManager);
|
|
271
|
+
const managerDisabled = !noManager && this.manager.disabled;
|
|
272
|
+
return this.__explicitDisabled || noManager || managerDisabled || this.maxFilesReached;
|
|
273
|
+
}
|
|
274
|
+
|
|
265
275
|
/** @private */
|
|
266
276
|
__syncFromManager() {
|
|
267
277
|
if (this.manager instanceof UploadManager) {
|
|
@@ -270,11 +280,7 @@ class UploadButton extends ButtonMixin(ElementMixin(ThemableMixin(PolylitMixin(L
|
|
|
270
280
|
this.maxFilesReached = false;
|
|
271
281
|
}
|
|
272
282
|
|
|
273
|
-
|
|
274
|
-
const effectiveDisabled = this.__explicitDisabled || this.maxFilesReached;
|
|
275
|
-
if (super.disabled !== effectiveDisabled) {
|
|
276
|
-
super.disabled = effectiveDisabled;
|
|
277
|
-
}
|
|
283
|
+
super.disabled = this.__effectiveDisabled;
|
|
278
284
|
}
|
|
279
285
|
|
|
280
286
|
/** @override */
|
|
@@ -36,7 +36,7 @@ import type { UploadManager } from './vaadin-upload-manager.js';
|
|
|
36
36
|
* Attribute | Description
|
|
37
37
|
* -------------------|--------------------------------------------
|
|
38
38
|
* `dragover` | Set when files are being dragged over the element
|
|
39
|
-
* `disabled` | Set when the drop zone is
|
|
39
|
+
* `disabled` | Set when the drop zone is effectively disabled
|
|
40
40
|
* `max-files-reached`| Set when the manager has reached maxFiles
|
|
41
41
|
*
|
|
42
42
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
@@ -50,6 +50,7 @@ declare class UploadDropZone extends HTMLElement {
|
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Whether the drop zone is disabled.
|
|
53
|
+
* Returns true if either explicitly disabled, manager is disabled, or no manager is set.
|
|
53
54
|
*/
|
|
54
55
|
disabled: boolean;
|
|
55
56
|
|
|
@@ -42,12 +42,12 @@ import { UploadManager } from './vaadin-upload-manager.js';
|
|
|
42
42
|
* Attribute | Description
|
|
43
43
|
* -------------------|--------------------------------------------
|
|
44
44
|
* `dragover` | Set when files are being dragged over the element
|
|
45
|
-
* `disabled` | Set when the drop zone is
|
|
45
|
+
* `disabled` | Set when the drop zone is effectively disabled
|
|
46
46
|
* `max-files-reached`| Set when the manager has reached maxFiles
|
|
47
47
|
*
|
|
48
48
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
49
49
|
*
|
|
50
|
-
* @customElement
|
|
50
|
+
* @customElement vaadin-upload-drop-zone
|
|
51
51
|
* @extends HTMLElement
|
|
52
52
|
* @mixes ElementMixin
|
|
53
53
|
* @mixes ThemableMixin
|
|
@@ -80,12 +80,12 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
82
|
* Whether the drop zone is disabled.
|
|
83
|
+
* Returns true if either explicitly disabled, manager is disabled, or no manager is set.
|
|
83
84
|
* @type {boolean}
|
|
84
85
|
*/
|
|
85
86
|
disabled: {
|
|
86
87
|
type: Boolean,
|
|
87
88
|
value: false,
|
|
88
|
-
reflect: true,
|
|
89
89
|
},
|
|
90
90
|
|
|
91
91
|
/**
|
|
@@ -110,9 +110,27 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Whether the drop zone is disabled.
|
|
115
|
+
* Returns true if either explicitly disabled, manager is disabled, or no manager is set.
|
|
116
|
+
* @type {boolean}
|
|
117
|
+
* @override
|
|
118
|
+
*/
|
|
119
|
+
get disabled() {
|
|
120
|
+
return this.__effectiveDisabled;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
set disabled(value) {
|
|
124
|
+
if (this.__syncingDisabled) return;
|
|
125
|
+
this.__explicitDisabled = Boolean(value);
|
|
126
|
+
this.__syncDisabledState();
|
|
127
|
+
}
|
|
128
|
+
|
|
113
129
|
constructor() {
|
|
114
130
|
super();
|
|
131
|
+
this.__explicitDisabled = false;
|
|
115
132
|
this.__onMaxFilesReachedChanged = this.__onMaxFilesReachedChanged.bind(this);
|
|
133
|
+
this.__syncDisabledState = this.__syncDisabledState.bind(this);
|
|
116
134
|
}
|
|
117
135
|
|
|
118
136
|
/** @protected */
|
|
@@ -128,9 +146,10 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
128
146
|
disconnectedCallback() {
|
|
129
147
|
super.disconnectedCallback();
|
|
130
148
|
|
|
131
|
-
// Clean up manager
|
|
149
|
+
// Clean up manager listeners to prevent memory leaks
|
|
132
150
|
if (this.manager instanceof UploadManager) {
|
|
133
151
|
this.manager.removeEventListener('max-files-reached-changed', this.__onMaxFilesReachedChanged);
|
|
152
|
+
this.manager.removeEventListener('disabled-changed', this.__syncDisabledState);
|
|
134
153
|
}
|
|
135
154
|
}
|
|
136
155
|
|
|
@@ -138,13 +157,15 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
138
157
|
connectedCallback() {
|
|
139
158
|
super.connectedCallback();
|
|
140
159
|
|
|
141
|
-
// Re-attach manager
|
|
160
|
+
// Re-attach manager listeners when reconnected to DOM
|
|
142
161
|
if (this.manager instanceof UploadManager) {
|
|
143
162
|
this.manager.addEventListener('max-files-reached-changed', this.__onMaxFilesReachedChanged);
|
|
163
|
+
this.manager.addEventListener('disabled-changed', this.__syncDisabledState);
|
|
144
164
|
|
|
145
|
-
// Sync
|
|
165
|
+
// Sync state with current manager state
|
|
146
166
|
this.maxFilesReached = !!this.manager.maxFilesReached;
|
|
147
167
|
}
|
|
168
|
+
this.__syncDisabledState();
|
|
148
169
|
}
|
|
149
170
|
|
|
150
171
|
/** @protected */
|
|
@@ -152,14 +173,19 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
152
173
|
return html`<slot></slot>`;
|
|
153
174
|
}
|
|
154
175
|
|
|
176
|
+
/** @private */
|
|
177
|
+
get __effectiveDisabled() {
|
|
178
|
+
const noManager = !(this.manager instanceof UploadManager);
|
|
179
|
+
return this.__explicitDisabled || noManager || this.manager.disabled || this.maxFilesReached;
|
|
180
|
+
}
|
|
181
|
+
|
|
155
182
|
/** @private */
|
|
156
183
|
__onDragover(event) {
|
|
157
184
|
event.preventDefault();
|
|
158
|
-
|
|
159
|
-
if (!effectiveDisabled) {
|
|
185
|
+
if (!this.__effectiveDisabled) {
|
|
160
186
|
this.__dragover = true;
|
|
161
187
|
}
|
|
162
|
-
event.dataTransfer.dropEffect =
|
|
188
|
+
event.dataTransfer.dropEffect = this.__effectiveDisabled ? 'none' : 'copy';
|
|
163
189
|
}
|
|
164
190
|
|
|
165
191
|
/** @private */
|
|
@@ -167,7 +193,7 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
167
193
|
event.preventDefault();
|
|
168
194
|
// Only remove dragover if we're actually leaving the drop zone
|
|
169
195
|
// (not just entering a child element)
|
|
170
|
-
if (event.
|
|
196
|
+
if (event.target !== this) {
|
|
171
197
|
return;
|
|
172
198
|
}
|
|
173
199
|
this.__dragover = false;
|
|
@@ -178,9 +204,7 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
178
204
|
event.preventDefault();
|
|
179
205
|
this.__dragover = false;
|
|
180
206
|
|
|
181
|
-
|
|
182
|
-
const effectiveDisabled = this.disabled || this.maxFilesReached;
|
|
183
|
-
if (!effectiveDisabled && this.manager instanceof UploadManager) {
|
|
207
|
+
if (!this.__effectiveDisabled) {
|
|
184
208
|
const files = await getFilesFromDropEvent(event);
|
|
185
209
|
this.manager.addFiles(files);
|
|
186
210
|
}
|
|
@@ -188,25 +212,40 @@ class UploadDropZone extends ElementMixin(ThemableMixin(PolylitMixin(LumoInjecti
|
|
|
188
212
|
|
|
189
213
|
/** @private */
|
|
190
214
|
__managerChanged(manager, oldManager) {
|
|
191
|
-
// Remove
|
|
215
|
+
// Remove listeners from old manager
|
|
192
216
|
if (oldManager instanceof UploadManager) {
|
|
193
217
|
oldManager.removeEventListener('max-files-reached-changed', this.__onMaxFilesReachedChanged);
|
|
218
|
+
oldManager.removeEventListener('disabled-changed', this.__syncDisabledState);
|
|
194
219
|
}
|
|
195
220
|
|
|
196
|
-
// Add
|
|
221
|
+
// Add listeners to new manager
|
|
197
222
|
if (this.isConnected && manager instanceof UploadManager) {
|
|
198
223
|
manager.addEventListener('max-files-reached-changed', this.__onMaxFilesReachedChanged);
|
|
224
|
+
manager.addEventListener('disabled-changed', this.__syncDisabledState);
|
|
199
225
|
|
|
200
|
-
// Sync initial state
|
|
226
|
+
// Sync initial state
|
|
201
227
|
this.maxFilesReached = !!manager.maxFilesReached;
|
|
202
228
|
} else {
|
|
203
229
|
this.maxFilesReached = false;
|
|
204
230
|
}
|
|
231
|
+
|
|
232
|
+
if (this.isConnected) {
|
|
233
|
+
this.__syncDisabledState();
|
|
234
|
+
}
|
|
205
235
|
}
|
|
206
236
|
|
|
207
237
|
/** @private */
|
|
208
238
|
__onMaxFilesReachedChanged(event) {
|
|
209
239
|
this.maxFilesReached = event.detail.value;
|
|
240
|
+
this.__syncDisabledState();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** @private */
|
|
244
|
+
__syncDisabledState() {
|
|
245
|
+
if (!this.isConnected) return;
|
|
246
|
+
this.__syncingDisabled = true;
|
|
247
|
+
this.toggleAttribute('disabled', this.__effectiveDisabled);
|
|
248
|
+
this.__syncingDisabled = false;
|
|
210
249
|
}
|
|
211
250
|
}
|
|
212
251
|
|
|
@@ -34,6 +34,7 @@ const DEFAULT_I18N = {
|
|
|
34
34
|
serverUnavailable: 'Upload failed, please try again later',
|
|
35
35
|
unexpectedServerError: 'Upload failed due to server error',
|
|
36
36
|
forbidden: 'Upload forbidden',
|
|
37
|
+
fileTooLarge: 'File is too large',
|
|
37
38
|
},
|
|
38
39
|
},
|
|
39
40
|
units: {
|
|
@@ -88,6 +89,7 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
88
89
|
constructor() {
|
|
89
90
|
super();
|
|
90
91
|
this.__onManagerFilesChanged = this.__onManagerFilesChanged.bind(this);
|
|
92
|
+
this.__onManagerDisabledChanged = this.__onManagerDisabledChanged.bind(this);
|
|
91
93
|
this.__onFileRetry = this.__onFileRetry.bind(this);
|
|
92
94
|
this.__onFileAbort = this.__onFileAbort.bind(this);
|
|
93
95
|
this.__onFileStart = this.__onFileStart.bind(this);
|
|
@@ -112,6 +114,7 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
112
114
|
// Clean up manager listener to prevent memory leaks
|
|
113
115
|
if (this.manager instanceof UploadManager) {
|
|
114
116
|
this.manager.removeEventListener('files-changed', this.__onManagerFilesChanged);
|
|
117
|
+
this.manager.removeEventListener('disabled-changed', this.__onManagerDisabledChanged);
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
120
|
|
|
@@ -122,8 +125,9 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
122
125
|
// Re-attach manager listener when reconnected to DOM
|
|
123
126
|
if (this.manager instanceof UploadManager) {
|
|
124
127
|
this.manager.addEventListener('files-changed', this.__onManagerFilesChanged);
|
|
128
|
+
this.manager.addEventListener('disabled-changed', this.__onManagerDisabledChanged);
|
|
125
129
|
|
|
126
|
-
// Sync state with current manager
|
|
130
|
+
// Sync state with current manager
|
|
127
131
|
this.__syncFromManager();
|
|
128
132
|
}
|
|
129
133
|
}
|
|
@@ -133,11 +137,13 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
133
137
|
// Remove listeners from old manager
|
|
134
138
|
if (oldManager instanceof UploadManager) {
|
|
135
139
|
oldManager.removeEventListener('files-changed', this.__onManagerFilesChanged);
|
|
140
|
+
oldManager.removeEventListener('disabled-changed', this.__onManagerDisabledChanged);
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
// Add listeners to new manager only when connected
|
|
139
144
|
if (this.isConnected && manager instanceof UploadManager) {
|
|
140
145
|
manager.addEventListener('files-changed', this.__onManagerFilesChanged);
|
|
146
|
+
manager.addEventListener('disabled-changed', this.__onManagerDisabledChanged);
|
|
141
147
|
|
|
142
148
|
// Sync initial state
|
|
143
149
|
this.__syncFromManager();
|
|
@@ -152,6 +158,11 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
152
158
|
this.__syncFromManager();
|
|
153
159
|
}
|
|
154
160
|
|
|
161
|
+
/** @private */
|
|
162
|
+
__onManagerDisabledChanged() {
|
|
163
|
+
this.requestContentUpdate();
|
|
164
|
+
}
|
|
165
|
+
|
|
155
166
|
/** @private */
|
|
156
167
|
__syncFromManager() {
|
|
157
168
|
if (this.manager instanceof UploadManager) {
|
|
@@ -322,6 +333,8 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
322
333
|
/** @private */
|
|
323
334
|
requestContentUpdate() {
|
|
324
335
|
const { items, __effectiveI18n: i18n, disabled } = this;
|
|
336
|
+
const managerDisabled = this.manager instanceof UploadManager && this.manager.disabled;
|
|
337
|
+
const effectiveDisabled = disabled || managerDisabled;
|
|
325
338
|
|
|
326
339
|
render(
|
|
327
340
|
html`
|
|
@@ -329,7 +342,7 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
329
342
|
(file) => html`
|
|
330
343
|
<li>
|
|
331
344
|
<vaadin-upload-file
|
|
332
|
-
.disabled="${
|
|
345
|
+
.disabled="${effectiveDisabled}"
|
|
333
346
|
.file="${file}"
|
|
334
347
|
.complete="${file.complete}"
|
|
335
348
|
.errorMessage="${file.error}"
|
|
@@ -340,7 +353,11 @@ export const UploadFileListMixin = (superClass) =>
|
|
|
340
353
|
.status="${file.status}"
|
|
341
354
|
.uploading="${file.uploading}"
|
|
342
355
|
.i18n="${i18n}"
|
|
343
|
-
theme="${ifDefined(
|
|
356
|
+
theme="${ifDefined(
|
|
357
|
+
window.Vaadin.featureFlags.modularUpload || window.Vaadin.featureFlags.aiComponents
|
|
358
|
+
? this._theme
|
|
359
|
+
: undefined,
|
|
360
|
+
)}"
|
|
344
361
|
></vaadin-upload-file>
|
|
345
362
|
</li>
|
|
346
363
|
`,
|
|
@@ -75,7 +75,7 @@ import { UploadFileListMixin } from './vaadin-upload-file-list-mixin.js';
|
|
|
75
75
|
*
|
|
76
76
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
77
77
|
*
|
|
78
|
-
* @customElement
|
|
78
|
+
* @customElement vaadin-upload-file-list
|
|
79
79
|
* @extends HTMLElement
|
|
80
80
|
* @mixes ThemableMixin
|
|
81
81
|
* @mixes UploadFileListMixin
|
|
@@ -77,7 +77,7 @@ import { UploadFileMixin } from './vaadin-upload-file-mixin.js';
|
|
|
77
77
|
*
|
|
78
78
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
|
|
79
79
|
*
|
|
80
|
-
* @customElement
|
|
80
|
+
* @customElement vaadin-upload-file
|
|
81
81
|
* @extends HTMLElement
|
|
82
82
|
* @mixes UploadFileMixin
|
|
83
83
|
* @mixes ThemableMixin
|
|
@@ -12,7 +12,7 @@ import { uploadIconStyles } from './styles/vaadin-upload-icon-base-styles.js';
|
|
|
12
12
|
/**
|
|
13
13
|
* An element used internally by `<vaadin-upload>`. Not intended to be used separately.
|
|
14
14
|
*
|
|
15
|
-
* @customElement
|
|
15
|
+
* @customElement vaadin-upload-icon
|
|
16
16
|
* @extends HTMLElement
|
|
17
17
|
* @private
|
|
18
18
|
*/
|
|
@@ -9,7 +9,13 @@ export type UploadFormat = 'raw' | 'multipart';
|
|
|
9
9
|
|
|
10
10
|
export type FileRejectError = 'tooManyFiles' | 'fileIsTooBig' | 'incorrectFileType';
|
|
11
11
|
|
|
12
|
-
export type UploadErrorKey =
|
|
12
|
+
export type UploadErrorKey =
|
|
13
|
+
| 'timeout'
|
|
14
|
+
| 'serverUnavailable'
|
|
15
|
+
| 'unexpectedServerError'
|
|
16
|
+
| 'forbidden'
|
|
17
|
+
| 'sendFailed'
|
|
18
|
+
| 'fileTooLarge';
|
|
13
19
|
|
|
14
20
|
export interface UploadFile extends File {
|
|
15
21
|
uploadTarget: string;
|
|
@@ -125,6 +131,13 @@ export interface UploadManagerOptions {
|
|
|
125
131
|
* @default 'file'
|
|
126
132
|
*/
|
|
127
133
|
formDataName?: string;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Whether the upload manager is disabled.
|
|
137
|
+
* When true, connected components (upload-button, upload-drop-zone) will be automatically disabled.
|
|
138
|
+
* @default false
|
|
139
|
+
*/
|
|
140
|
+
disabled?: boolean;
|
|
128
141
|
}
|
|
129
142
|
|
|
130
143
|
export interface UploadManagerEventMap {
|
|
@@ -147,6 +160,7 @@ export interface UploadManagerEventMap {
|
|
|
147
160
|
'upload-abort': CustomEvent<{ file: UploadFile; xhr: XMLHttpRequest }>;
|
|
148
161
|
'files-changed': CustomEvent<{ value: UploadFile[] }>;
|
|
149
162
|
'max-files-reached-changed': CustomEvent<{ value: boolean }>;
|
|
163
|
+
'disabled-changed': CustomEvent<{ value: boolean }>;
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
/**
|
|
@@ -292,6 +306,12 @@ export class UploadManager extends EventTarget {
|
|
|
292
306
|
*/
|
|
293
307
|
readonly maxFilesReached: boolean;
|
|
294
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Whether the upload manager is disabled.
|
|
311
|
+
* When true, connected components (upload-button, upload-drop-zone) will be automatically disabled.
|
|
312
|
+
*/
|
|
313
|
+
disabled: boolean;
|
|
314
|
+
|
|
295
315
|
/**
|
|
296
316
|
* Add files to the upload list.
|
|
297
317
|
*/
|
|
@@ -4,11 +4,19 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
window.Vaadin = window.Vaadin || {};
|
|
8
|
+
window.Vaadin.featureFlags = window.Vaadin.featureFlags || {};
|
|
9
|
+
|
|
7
10
|
/**
|
|
8
11
|
* A pure JavaScript class that manages file upload state and XHR requests.
|
|
9
12
|
* It has no knowledge of UI components - components should listen to events and
|
|
10
13
|
* call methods to interact with the manager.
|
|
11
14
|
*
|
|
15
|
+
* **Note:** This class is experimental and requires the `modularUpload` or `aiComponents` feature flag to be enabled:
|
|
16
|
+
* ```javascript
|
|
17
|
+
* window.Vaadin.featureFlags.modularUpload = true;
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
12
20
|
* @example
|
|
13
21
|
* ```javascript
|
|
14
22
|
* import { UploadManager } from '@vaadin/upload';
|
|
@@ -50,6 +58,7 @@
|
|
|
50
58
|
* @fires {CustomEvent} upload-abort - Fired when abort is requested
|
|
51
59
|
* @fires {CustomEvent} files-changed - Fired when the files array changes
|
|
52
60
|
* @fires {CustomEvent} max-files-reached-changed - Fired when maxFilesReached changes
|
|
61
|
+
* @fires {CustomEvent} disabled-changed - Fired when disabled changes
|
|
53
62
|
*/
|
|
54
63
|
export class UploadManager extends EventTarget {
|
|
55
64
|
/** @type {Array<UploadFile>} */
|
|
@@ -58,6 +67,9 @@ export class UploadManager extends EventTarget {
|
|
|
58
67
|
/** @type {boolean} */
|
|
59
68
|
#maxFilesReached = false;
|
|
60
69
|
|
|
70
|
+
/** @type {boolean} */
|
|
71
|
+
#disabled = false;
|
|
72
|
+
|
|
61
73
|
/** @type {Array<UploadFile>} */
|
|
62
74
|
#uploadQueue = [];
|
|
63
75
|
|
|
@@ -91,10 +103,17 @@ export class UploadManager extends EventTarget {
|
|
|
91
103
|
* @param {string} [options.uploadFormat='raw'] - Specifies the upload format to use when sending files to the server. 'raw': Send file as raw binary data with the file's MIME type as Content-Type (default). 'multipart': Send file using multipart/form-data encoding.
|
|
92
104
|
* @param {number} [options.maxConcurrentUploads=3] - Specifies the maximum number of files that can be uploaded simultaneously. This helps prevent browser performance degradation and XHR limitations when uploading large numbers of files. Files exceeding this limit will be queued and uploaded as active uploads complete.
|
|
93
105
|
* @param {string} [options.formDataName='file'] - Specifies the 'name' property at Content-Disposition for multipart uploads. This property is ignored when uploadFormat is 'raw'.
|
|
106
|
+
* @param {boolean} [options.disabled=false] - Whether the upload manager is disabled. When true, connected components (upload-button, upload-drop-zone) will be automatically disabled.
|
|
94
107
|
*/
|
|
95
108
|
constructor(options = {}) {
|
|
96
109
|
super();
|
|
97
110
|
|
|
111
|
+
if (!window.Vaadin.featureFlags.modularUpload && !window.Vaadin.featureFlags.aiComponents) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
'UploadManager requires the modularUpload feature flag. Enable it with: window.Vaadin.featureFlags.modularUpload = true',
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
98
117
|
// Configuration properties - use setters for validation
|
|
99
118
|
this.target = options.target || '';
|
|
100
119
|
this.method = options.method || 'POST';
|
|
@@ -108,6 +127,7 @@ export class UploadManager extends EventTarget {
|
|
|
108
127
|
this.uploadFormat = options.uploadFormat || 'raw';
|
|
109
128
|
this.maxConcurrentUploads = options.maxConcurrentUploads === undefined ? 3 : options.maxConcurrentUploads;
|
|
110
129
|
this.formDataName = options.formDataName || 'file';
|
|
130
|
+
this.disabled = options.disabled === undefined ? false : options.disabled;
|
|
111
131
|
}
|
|
112
132
|
|
|
113
133
|
/**
|
|
@@ -241,6 +261,27 @@ export class UploadManager extends EventTarget {
|
|
|
241
261
|
return this.#maxFilesReached;
|
|
242
262
|
}
|
|
243
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Whether the upload manager is disabled.
|
|
266
|
+
* When true, connected components (upload-button, upload-drop-zone) will be automatically disabled.
|
|
267
|
+
* @type {boolean}
|
|
268
|
+
*/
|
|
269
|
+
get disabled() {
|
|
270
|
+
return this.#disabled;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
set disabled(value) {
|
|
274
|
+
const disabled = Boolean(value);
|
|
275
|
+
if (disabled !== this.#disabled) {
|
|
276
|
+
this.#disabled = disabled;
|
|
277
|
+
this.dispatchEvent(
|
|
278
|
+
new CustomEvent('disabled-changed', {
|
|
279
|
+
detail: { value: disabled },
|
|
280
|
+
}),
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
244
285
|
/**
|
|
245
286
|
* Add files to the upload list.
|
|
246
287
|
* @param {FileList|File[]} files - Files to add
|
|
@@ -503,6 +544,8 @@ export class UploadManager extends EventTarget {
|
|
|
503
544
|
file.errorKey = 'serverUnavailable';
|
|
504
545
|
} else if (xhr.status >= 500) {
|
|
505
546
|
file.errorKey = 'unexpectedServerError';
|
|
547
|
+
} else if (xhr.status === 413) {
|
|
548
|
+
file.errorKey = 'fileTooLarge';
|
|
506
549
|
} else if (xhr.status >= 400) {
|
|
507
550
|
file.errorKey = 'forbidden';
|
|
508
551
|
}
|
|
@@ -39,6 +39,7 @@ export const DEFAULT_I18N = {
|
|
|
39
39
|
serverUnavailable: 'Upload failed, please try again later',
|
|
40
40
|
unexpectedServerError: 'Upload failed due to server error',
|
|
41
41
|
forbidden: 'Upload forbidden',
|
|
42
|
+
fileTooLarge: 'File is too large',
|
|
42
43
|
},
|
|
43
44
|
},
|
|
44
45
|
file: {
|
|
@@ -590,7 +591,12 @@ export const UploadMixin = (superClass) =>
|
|
|
590
591
|
list.items = [...files];
|
|
591
592
|
list.i18n = effectiveI18n;
|
|
592
593
|
list.disabled = disabled;
|
|
593
|
-
if (
|
|
594
|
+
if (
|
|
595
|
+
window.Vaadin &&
|
|
596
|
+
window.Vaadin.featureFlags &&
|
|
597
|
+
(window.Vaadin.featureFlags.modularUpload || window.Vaadin.featureFlags.aiComponents) &&
|
|
598
|
+
this._theme
|
|
599
|
+
) {
|
|
594
600
|
list.setAttribute('theme', this._theme);
|
|
595
601
|
} else {
|
|
596
602
|
list.removeAttribute('theme');
|
|
@@ -790,6 +796,8 @@ export const UploadMixin = (superClass) =>
|
|
|
790
796
|
file.error = this.__effectiveI18n.uploading.error.serverUnavailable;
|
|
791
797
|
} else if (xhr.status >= 500) {
|
|
792
798
|
file.error = this.__effectiveI18n.uploading.error.unexpectedServerError;
|
|
799
|
+
} else if (xhr.status === 413) {
|
|
800
|
+
file.error = this.__effectiveI18n.uploading.error.fileTooLarge;
|
|
793
801
|
} else if (xhr.status >= 400) {
|
|
794
802
|
file.error = this.__effectiveI18n.uploading.error.forbidden;
|
|
795
803
|
}
|
package/src/vaadin-upload.js
CHANGED
|
@@ -101,7 +101,7 @@ import { UploadMixin } from './vaadin-upload-mixin.js';
|
|
|
101
101
|
* @fires {CustomEvent} upload-retry - Fired when retry upload is requested.
|
|
102
102
|
* @fires {CustomEvent} upload-abort - Fired when upload abort is requested.
|
|
103
103
|
*
|
|
104
|
-
* @customElement
|
|
104
|
+
* @customElement vaadin-upload
|
|
105
105
|
* @extends HTMLElement
|
|
106
106
|
* @mixes ThemableMixin
|
|
107
107
|
* @mixes ElementMixin
|