@vaadin/upload 23.3.0-alpha5 → 24.0.0-alpha2
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 +9 -9
- package/src/vaadin-upload-file-list.js +111 -0
- package/src/vaadin-upload-file.js +119 -69
- package/src/vaadin-upload-icon.js +37 -0
- package/src/vaadin-upload.d.ts +6 -8
- package/src/vaadin-upload.js +123 -52
- package/theme/lumo/vaadin-upload-styles.js +16 -18
- package/theme/material/vaadin-upload-styles.js +19 -26
- package/web-types.json +182 -10
- package/web-types.lit.json +58 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/upload",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "24.0.0-alpha2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -36,16 +36,16 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@polymer/polymer": "^3.0.0",
|
|
39
|
-
"@vaadin/button": "
|
|
40
|
-
"@vaadin/component-base": "
|
|
41
|
-
"@vaadin/progress-bar": "
|
|
42
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
43
|
-
"@vaadin/vaadin-material-styles": "
|
|
44
|
-
"@vaadin/vaadin-themable-mixin": "
|
|
39
|
+
"@vaadin/button": "24.0.0-alpha2",
|
|
40
|
+
"@vaadin/component-base": "24.0.0-alpha2",
|
|
41
|
+
"@vaadin/progress-bar": "24.0.0-alpha2",
|
|
42
|
+
"@vaadin/vaadin-lumo-styles": "24.0.0-alpha2",
|
|
43
|
+
"@vaadin/vaadin-material-styles": "24.0.0-alpha2",
|
|
44
|
+
"@vaadin/vaadin-themable-mixin": "24.0.0-alpha2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@esm-bundle/chai": "^4.3.4",
|
|
48
|
-
"@vaadin/form-layout": "
|
|
48
|
+
"@vaadin/form-layout": "24.0.0-alpha2",
|
|
49
49
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
50
50
|
"sinon": "^13.0.2"
|
|
51
51
|
},
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"web-types.json",
|
|
54
54
|
"web-types.lit.json"
|
|
55
55
|
],
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "0c16c01a6807e629a84f5a982793afecc1a7ced0"
|
|
57
57
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2016 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import './vaadin-upload-file.js';
|
|
7
|
+
import { html as legacyHtml, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
8
|
+
import { html, render } from 'lit';
|
|
9
|
+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* An element used internally by `<vaadin-upload>`. Not intended to be used separately.
|
|
13
|
+
*
|
|
14
|
+
* @extends HTMLElement
|
|
15
|
+
* @mixes FocusMixin
|
|
16
|
+
* @private
|
|
17
|
+
*/
|
|
18
|
+
class UploadFileList extends ThemableMixin(PolymerElement) {
|
|
19
|
+
static get is() {
|
|
20
|
+
return 'vaadin-upload-file-list';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static get template() {
|
|
24
|
+
return legacyHtml`
|
|
25
|
+
<style>
|
|
26
|
+
:host {
|
|
27
|
+
display: block;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
:host([hidden]) {
|
|
31
|
+
display: none !important;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
[part='list'] {
|
|
35
|
+
padding: 0;
|
|
36
|
+
margin: 0;
|
|
37
|
+
list-style-type: none;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
40
|
+
<ul part="list">
|
|
41
|
+
<slot></slot>
|
|
42
|
+
</ul>
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static get properties() {
|
|
47
|
+
return {
|
|
48
|
+
/**
|
|
49
|
+
* The array of files being processed, or already uploaded.
|
|
50
|
+
*/
|
|
51
|
+
items: {
|
|
52
|
+
type: Array,
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The object used to localize upload files.
|
|
57
|
+
*/
|
|
58
|
+
i18n: {
|
|
59
|
+
type: Object,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static get observers() {
|
|
65
|
+
return ['__updateItems(items, i18n)'];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @private */
|
|
69
|
+
__updateItems(items, i18n) {
|
|
70
|
+
if (items && i18n) {
|
|
71
|
+
this.requestContentUpdate();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Requests an update for the `vaadin-upload-file` elements.
|
|
77
|
+
*
|
|
78
|
+
* It is not guaranteed that the update happens immediately (synchronously) after it is requested.
|
|
79
|
+
*/
|
|
80
|
+
requestContentUpdate() {
|
|
81
|
+
const { items, i18n } = this;
|
|
82
|
+
|
|
83
|
+
render(
|
|
84
|
+
html`
|
|
85
|
+
${items.map(
|
|
86
|
+
(file) => html`
|
|
87
|
+
<li>
|
|
88
|
+
<vaadin-upload-file
|
|
89
|
+
.file="${file}"
|
|
90
|
+
.complete="${file.complete}"
|
|
91
|
+
.errorMessage="${file.error}"
|
|
92
|
+
.fileName="${file.name}"
|
|
93
|
+
.held="${file.held}"
|
|
94
|
+
.indeterminate="${file.indeterminate}"
|
|
95
|
+
.progress="${file.progress}"
|
|
96
|
+
.status="${file.status}"
|
|
97
|
+
.uploading="${file.uploading}"
|
|
98
|
+
.i18n="${i18n}"
|
|
99
|
+
></vaadin-upload-file>
|
|
100
|
+
</li>
|
|
101
|
+
`,
|
|
102
|
+
)}
|
|
103
|
+
`,
|
|
104
|
+
this,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
customElements.define(UploadFileList.is, UploadFileList);
|
|
110
|
+
|
|
111
|
+
export { UploadFileList };
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import '@vaadin/progress-bar/src/vaadin-progress-bar.js';
|
|
7
7
|
import './vaadin-upload-icons.js';
|
|
8
8
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
9
|
+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
9
10
|
import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
|
|
11
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
10
12
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -30,7 +32,6 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
30
32
|
* `start-button` | Start file upload button
|
|
31
33
|
* `retry-button` | Retry file upload button
|
|
32
34
|
* `remove-button` | Remove file button
|
|
33
|
-
* `progress` | Progress bar
|
|
34
35
|
*
|
|
35
36
|
* The following state attributes are available for styling:
|
|
36
37
|
*
|
|
@@ -46,10 +47,11 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
46
47
|
* See [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.
|
|
47
48
|
*
|
|
48
49
|
* @extends HTMLElement
|
|
50
|
+
* @mixes ControllerMixin
|
|
49
51
|
* @mixes FocusMixin
|
|
50
52
|
* @mixes ThemableMixin
|
|
51
53
|
*/
|
|
52
|
-
class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
54
|
+
class UploadFile extends FocusMixin(ThemableMixin(ControllerMixin(PolymerElement))) {
|
|
53
55
|
static get template() {
|
|
54
56
|
return html`
|
|
55
57
|
<style>
|
|
@@ -71,17 +73,22 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
71
73
|
border: none;
|
|
72
74
|
box-shadow: none;
|
|
73
75
|
}
|
|
76
|
+
|
|
77
|
+
:host([complete]) ::slotted([slot='progress']),
|
|
78
|
+
:host([error]) ::slotted([slot='progress']) {
|
|
79
|
+
display: none !important;
|
|
80
|
+
}
|
|
74
81
|
</style>
|
|
75
82
|
|
|
76
83
|
<div part="row">
|
|
77
84
|
<div part="info">
|
|
78
|
-
<div part="done-icon" hidden$="[[!
|
|
79
|
-
<div part="warning-icon" hidden$="[[!
|
|
85
|
+
<div part="done-icon" hidden$="[[!complete]]" aria-hidden="true"></div>
|
|
86
|
+
<div part="warning-icon" hidden$="[[!errorMessage]]" aria-hidden="true"></div>
|
|
80
87
|
|
|
81
88
|
<div part="meta">
|
|
82
|
-
<div part="name" id="name">[[
|
|
83
|
-
<div part="status" hidden$="[[!
|
|
84
|
-
<div part="error" id="error" hidden$="[[!
|
|
89
|
+
<div part="name" id="name">[[fileName]]</div>
|
|
90
|
+
<div part="status" hidden$="[[!status]]" id="status">[[status]]</div>
|
|
91
|
+
<div part="error" id="error" hidden$="[[!errorMessage]]">[[errorMessage]]</div>
|
|
85
92
|
</div>
|
|
86
93
|
</div>
|
|
87
94
|
<div part="commands">
|
|
@@ -90,7 +97,7 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
90
97
|
part="start-button"
|
|
91
98
|
file-event="file-start"
|
|
92
99
|
on-click="_fireFileEvent"
|
|
93
|
-
hidden$="[[!
|
|
100
|
+
hidden$="[[!held]]"
|
|
94
101
|
aria-label$="[[i18n.file.start]]"
|
|
95
102
|
aria-describedby="name"
|
|
96
103
|
></button>
|
|
@@ -99,7 +106,7 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
99
106
|
part="retry-button"
|
|
100
107
|
file-event="file-retry"
|
|
101
108
|
on-click="_fireFileEvent"
|
|
102
|
-
hidden$="[[!
|
|
109
|
+
hidden$="[[!errorMessage]]"
|
|
103
110
|
aria-label$="[[i18n.file.retry]]"
|
|
104
111
|
aria-describedby="name"
|
|
105
112
|
></button>
|
|
@@ -114,15 +121,7 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
114
121
|
</div>
|
|
115
122
|
</div>
|
|
116
123
|
|
|
117
|
-
<
|
|
118
|
-
part="progress"
|
|
119
|
-
id="progress"
|
|
120
|
-
value$="[[_formatProgressValue(file.progress)]]"
|
|
121
|
-
error$="[[file.error]]"
|
|
122
|
-
indeterminate$="[[file.indeterminate]]"
|
|
123
|
-
uploading$="[[file.uploading]]"
|
|
124
|
-
complete$="[[file.complete]]"
|
|
125
|
-
></vaadin-progress-bar>
|
|
124
|
+
<slot name="progress"></slot>
|
|
126
125
|
`;
|
|
127
126
|
}
|
|
128
127
|
|
|
@@ -132,9 +131,75 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
132
131
|
|
|
133
132
|
static get properties() {
|
|
134
133
|
return {
|
|
135
|
-
|
|
134
|
+
/**
|
|
135
|
+
* True if uploading is completed, false otherwise.
|
|
136
|
+
*/
|
|
137
|
+
complete: {
|
|
138
|
+
type: Boolean,
|
|
139
|
+
value: false,
|
|
140
|
+
reflectToAttribute: true,
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Error message returned by the server, if any.
|
|
145
|
+
*/
|
|
146
|
+
errorMessage: {
|
|
147
|
+
type: String,
|
|
148
|
+
value: '',
|
|
149
|
+
observer: '_errorMessageChanged',
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* The object representing a file.
|
|
154
|
+
*/
|
|
155
|
+
file: {
|
|
156
|
+
type: Object,
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Name of the uploading file.
|
|
161
|
+
*/
|
|
162
|
+
fileName: {
|
|
163
|
+
type: String,
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* True if uploading is not started, false otherwise.
|
|
168
|
+
*/
|
|
169
|
+
held: {
|
|
170
|
+
type: Boolean,
|
|
171
|
+
value: false,
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* True if remaining time is unknown, false otherwise.
|
|
176
|
+
*/
|
|
177
|
+
indeterminate: {
|
|
178
|
+
type: Boolean,
|
|
179
|
+
value: false,
|
|
180
|
+
reflectToAttribute: true,
|
|
181
|
+
},
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The object used to localize this component.
|
|
185
|
+
*/
|
|
186
|
+
i18n: {
|
|
187
|
+
type: Object,
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Number representing the uploading progress.
|
|
192
|
+
*/
|
|
193
|
+
progress: {
|
|
194
|
+
type: Number,
|
|
195
|
+
},
|
|
136
196
|
|
|
137
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Uploading status.
|
|
199
|
+
*/
|
|
200
|
+
status: {
|
|
201
|
+
type: String,
|
|
202
|
+
},
|
|
138
203
|
|
|
139
204
|
/**
|
|
140
205
|
* Indicates whether the element can be focused and where it participates in sequential keyboard navigation.
|
|
@@ -145,23 +210,42 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
145
210
|
value: 0,
|
|
146
211
|
reflectToAttribute: true,
|
|
147
212
|
},
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* True if uploading is in progress, false otherwise.
|
|
216
|
+
*/
|
|
217
|
+
uploading: {
|
|
218
|
+
type: Boolean,
|
|
219
|
+
value: false,
|
|
220
|
+
reflectToAttribute: true,
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
/** @private */
|
|
224
|
+
_progress: {
|
|
225
|
+
type: Object,
|
|
226
|
+
},
|
|
148
227
|
};
|
|
149
228
|
}
|
|
150
229
|
|
|
151
230
|
static get observers() {
|
|
152
|
-
return [
|
|
153
|
-
'_fileAborted(file.abort)',
|
|
154
|
-
'_toggleHostAttribute(file.error, "error")',
|
|
155
|
-
'_toggleHostAttribute(file.indeterminate, "indeterminate")',
|
|
156
|
-
'_toggleHostAttribute(file.uploading, "uploading")',
|
|
157
|
-
'_toggleHostAttribute(file.complete, "complete")',
|
|
158
|
-
];
|
|
231
|
+
return ['__updateProgress(_progress, progress, indeterminate)'];
|
|
159
232
|
}
|
|
160
233
|
|
|
161
234
|
/** @protected */
|
|
162
235
|
ready() {
|
|
163
236
|
super.ready();
|
|
164
237
|
|
|
238
|
+
this.addController(
|
|
239
|
+
new SlotController(
|
|
240
|
+
this,
|
|
241
|
+
'progress',
|
|
242
|
+
() => document.createElement('vaadin-progress-bar'),
|
|
243
|
+
(_, progress) => {
|
|
244
|
+
this._progress = progress;
|
|
245
|
+
},
|
|
246
|
+
),
|
|
247
|
+
);
|
|
248
|
+
|
|
165
249
|
// Handle moving focus to the button on Tab.
|
|
166
250
|
this.shadowRoot.addEventListener('focusin', (e) => {
|
|
167
251
|
const target = e.composedPath()[0];
|
|
@@ -191,26 +275,16 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
191
275
|
}
|
|
192
276
|
|
|
193
277
|
/** @private */
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
this._remove();
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/** @private */
|
|
201
|
-
_remove() {
|
|
202
|
-
this.dispatchEvent(
|
|
203
|
-
new CustomEvent('file-remove', {
|
|
204
|
-
detail: { file: this.file },
|
|
205
|
-
bubbles: true,
|
|
206
|
-
composed: true,
|
|
207
|
-
}),
|
|
208
|
-
);
|
|
278
|
+
_errorMessageChanged(errorMessage) {
|
|
279
|
+
this.toggleAttribute('error', Boolean(errorMessage));
|
|
209
280
|
}
|
|
210
281
|
|
|
211
282
|
/** @private */
|
|
212
|
-
|
|
213
|
-
|
|
283
|
+
__updateProgress(progress, value, indeterminate) {
|
|
284
|
+
if (progress) {
|
|
285
|
+
progress.value = isNaN(value) ? 0 : value / 100;
|
|
286
|
+
progress.indeterminate = indeterminate;
|
|
287
|
+
}
|
|
214
288
|
}
|
|
215
289
|
|
|
216
290
|
/** @private */
|
|
@@ -225,19 +299,6 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
225
299
|
);
|
|
226
300
|
}
|
|
227
301
|
|
|
228
|
-
/** @private */
|
|
229
|
-
_toggleHostAttribute(value, attributeName) {
|
|
230
|
-
const shouldHave = Boolean(value);
|
|
231
|
-
const has = this.hasAttribute(attributeName);
|
|
232
|
-
if (has !== shouldHave) {
|
|
233
|
-
if (shouldHave) {
|
|
234
|
-
this.setAttribute(attributeName, '');
|
|
235
|
-
} else {
|
|
236
|
-
this.removeAttribute(attributeName);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
302
|
/**
|
|
242
303
|
* Fired when the retry button is pressed. It is listened by `vaadin-upload`
|
|
243
304
|
* which will start a new upload process of this file.
|
|
@@ -258,23 +319,12 @@ class UploadFile extends FocusMixin(ThemableMixin(PolymerElement)) {
|
|
|
258
319
|
|
|
259
320
|
/**
|
|
260
321
|
* Fired when abort button is pressed. It is listened by `vaadin-upload` which
|
|
261
|
-
* will abort the upload in progress,
|
|
262
|
-
* to allow the animation to hide the element to be run.
|
|
322
|
+
* will abort the upload in progress, and then remove the file from the list.
|
|
263
323
|
*
|
|
264
324
|
* @event file-abort
|
|
265
325
|
* @param {Object} detail
|
|
266
326
|
* @param {Object} detail.file file to abort upload of
|
|
267
327
|
*/
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* Fired after the animation to hide the element has finished. It is listened
|
|
271
|
-
* by `vaadin-upload` which will actually remove the file from the upload
|
|
272
|
-
* file list.
|
|
273
|
-
*
|
|
274
|
-
* @event file-remove
|
|
275
|
-
* @param {Object} detail
|
|
276
|
-
* @param {Object} detail.file file to remove from the upload of
|
|
277
|
-
*/
|
|
278
328
|
}
|
|
279
329
|
|
|
280
330
|
customElements.define(UploadFile.is, UploadFile);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2016 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
7
|
+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An element used internally by `<vaadin-upload>`. Not intended to be used separately.
|
|
11
|
+
*
|
|
12
|
+
* @extends HTMLElement
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
class UploadIcon extends ThemableMixin(PolymerElement) {
|
|
16
|
+
static get is() {
|
|
17
|
+
return 'vaadin-upload-icon';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static get template() {
|
|
21
|
+
return html`
|
|
22
|
+
<style>
|
|
23
|
+
:host {
|
|
24
|
+
display: inline-block;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:host([hidden]) {
|
|
28
|
+
display: none !important;
|
|
29
|
+
}
|
|
30
|
+
</style>
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
customElements.define(UploadIcon.is, UploadIcon);
|
|
36
|
+
|
|
37
|
+
export { UploadIcon };
|
package/src/vaadin-upload.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2016 - 2022 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
6
7
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
7
8
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
8
9
|
|
|
@@ -180,13 +181,10 @@ export interface UploadEventMap extends HTMLElementEventMap, UploadCustomEventMa
|
|
|
180
181
|
*
|
|
181
182
|
* The following shadow DOM parts are available for styling:
|
|
182
183
|
*
|
|
183
|
-
* Part name
|
|
184
|
-
*
|
|
185
|
-
* `primary-buttons`
|
|
186
|
-
* `
|
|
187
|
-
* `drop-label` | Label for drop indicator
|
|
188
|
-
* `drop-label-icon` | Icon for drop indicator
|
|
189
|
-
* `file-list` | File list container
|
|
184
|
+
* Part name | Description
|
|
185
|
+
* -------------------|-------------------------------------
|
|
186
|
+
* `primary-buttons` | Upload container
|
|
187
|
+
* `drop-label` | Element wrapping drop label and icon
|
|
190
188
|
*
|
|
191
189
|
* The following state attributes are available for styling:
|
|
192
190
|
*
|
|
@@ -212,7 +210,7 @@ export interface UploadEventMap extends HTMLElementEventMap, UploadCustomEventMa
|
|
|
212
210
|
* @fires {CustomEvent} upload-retry - Fired when retry upload is requested.
|
|
213
211
|
* @fires {CustomEvent} upload-abort - Fired when upload abort is requested.
|
|
214
212
|
*/
|
|
215
|
-
declare class Upload extends ThemableMixin(ElementMixin(HTMLElement)) {
|
|
213
|
+
declare class Upload extends ThemableMixin(ElementMixin(ControllerMixin(HTMLElement))) {
|
|
216
214
|
/**
|
|
217
215
|
* Define whether the element supports dropping files on it for uploading.
|
|
218
216
|
* By default it's enabled in desktop and disabled in touch devices
|
package/src/vaadin-upload.js
CHANGED
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import '@polymer/polymer/lib/elements/dom-repeat.js';
|
|
7
7
|
import '@vaadin/button/src/vaadin-button.js';
|
|
8
|
+
import './vaadin-upload-icon.js';
|
|
8
9
|
import './vaadin-upload-icons.js';
|
|
9
|
-
import './vaadin-upload-file.js';
|
|
10
|
+
import './vaadin-upload-file-list.js';
|
|
10
11
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
11
12
|
import { announce } from '@vaadin/component-base/src/a11y-announcer.js';
|
|
12
13
|
import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
|
|
14
|
+
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
13
15
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
16
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
14
17
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
15
18
|
|
|
16
19
|
/**
|
|
@@ -26,13 +29,10 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
26
29
|
*
|
|
27
30
|
* The following shadow DOM parts are available for styling:
|
|
28
31
|
*
|
|
29
|
-
* Part name
|
|
30
|
-
*
|
|
31
|
-
* `primary-buttons`
|
|
32
|
-
* `
|
|
33
|
-
* `drop-label` | Label for drop indicator
|
|
34
|
-
* `drop-label-icon` | Icon for drop indicator
|
|
35
|
-
* `file-list` | File list container
|
|
32
|
+
* Part name | Description
|
|
33
|
+
* -------------------|-------------------------------------
|
|
34
|
+
* `primary-buttons` | Upload container
|
|
35
|
+
* `drop-label` | Element wrapping drop label and icon
|
|
36
36
|
*
|
|
37
37
|
* The following state attributes are available for styling:
|
|
38
38
|
*
|
|
@@ -59,10 +59,11 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
|
|
|
59
59
|
* @fires {CustomEvent} upload-abort - Fired when upload abort is requested.
|
|
60
60
|
*
|
|
61
61
|
* @extends HTMLElement
|
|
62
|
+
* @mixes ControllerMixin
|
|
62
63
|
* @mixes ThemableMixin
|
|
63
64
|
* @mixes ElementMixin
|
|
64
65
|
*/
|
|
65
|
-
class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
66
|
+
class Upload extends ElementMixin(ThemableMixin(ControllerMixin(PolymerElement))) {
|
|
66
67
|
static get template() {
|
|
67
68
|
return html`
|
|
68
69
|
<style>
|
|
@@ -79,38 +80,16 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
79
80
|
[hidden] {
|
|
80
81
|
display: none !important;
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
-
[part='file-list'] {
|
|
84
|
-
padding: 0;
|
|
85
|
-
margin: 0;
|
|
86
|
-
list-style-type: none;
|
|
87
|
-
}
|
|
88
83
|
</style>
|
|
89
84
|
|
|
90
85
|
<div part="primary-buttons">
|
|
91
|
-
<
|
|
92
|
-
<slot name="add-button">
|
|
93
|
-
<vaadin-button part="upload-button" id="addButton" disabled="[[maxFilesReached]]">
|
|
94
|
-
[[_i18nPlural(maxFiles, i18n.addFiles, i18n.addFiles.*)]]
|
|
95
|
-
</vaadin-button>
|
|
96
|
-
</slot>
|
|
97
|
-
</div>
|
|
86
|
+
<slot name="add-button"></slot>
|
|
98
87
|
<div part="drop-label" hidden$="[[nodrop]]" id="dropLabelContainer" aria-hidden="true">
|
|
99
|
-
<slot name="drop-label-icon">
|
|
100
|
-
|
|
101
|
-
</slot>
|
|
102
|
-
<slot name="drop-label" id="dropLabel"> [[_i18nPlural(maxFiles, i18n.dropFiles, i18n.dropFiles.*)]]</slot>
|
|
88
|
+
<slot name="drop-label-icon"></slot>
|
|
89
|
+
<slot name="drop-label"></slot>
|
|
103
90
|
</div>
|
|
104
91
|
</div>
|
|
105
|
-
<slot name="file-list">
|
|
106
|
-
<ul id="fileList" part="file-list">
|
|
107
|
-
<template is="dom-repeat" items="[[files]]" as="file">
|
|
108
|
-
<li>
|
|
109
|
-
<vaadin-upload-file file="[[file]]" i18n="[[i18n]]"></vaadin-upload-file>
|
|
110
|
-
</li>
|
|
111
|
-
</template>
|
|
112
|
-
</ul>
|
|
113
|
-
</slot>
|
|
92
|
+
<slot name="file-list"></slot>
|
|
114
93
|
<slot></slot>
|
|
115
94
|
<input
|
|
116
95
|
type="file"
|
|
@@ -429,9 +408,37 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
429
408
|
};
|
|
430
409
|
},
|
|
431
410
|
},
|
|
411
|
+
|
|
412
|
+
/** @private */
|
|
413
|
+
_addButton: {
|
|
414
|
+
type: Object,
|
|
415
|
+
},
|
|
416
|
+
|
|
417
|
+
/** @private */
|
|
418
|
+
_dropLabel: {
|
|
419
|
+
type: Object,
|
|
420
|
+
},
|
|
421
|
+
|
|
422
|
+
/** @private */
|
|
423
|
+
_fileList: {
|
|
424
|
+
type: Object,
|
|
425
|
+
},
|
|
426
|
+
|
|
427
|
+
/** @private */
|
|
428
|
+
_files: {
|
|
429
|
+
type: Array,
|
|
430
|
+
},
|
|
432
431
|
};
|
|
433
432
|
}
|
|
434
433
|
|
|
434
|
+
static get observers() {
|
|
435
|
+
return [
|
|
436
|
+
'__updateAddButton(_addButton, maxFiles, i18n, maxFilesReached)',
|
|
437
|
+
'__updateDropLabel(_dropLabel, maxFiles, i18n)',
|
|
438
|
+
'__updateFileList(_fileList, files, i18n)',
|
|
439
|
+
];
|
|
440
|
+
}
|
|
441
|
+
|
|
435
442
|
/** @protected */
|
|
436
443
|
ready() {
|
|
437
444
|
super.ready();
|
|
@@ -440,12 +447,52 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
440
447
|
this.addEventListener('drop', this._onDrop.bind(this));
|
|
441
448
|
this.addEventListener('file-retry', this._onFileRetry.bind(this));
|
|
442
449
|
this.addEventListener('file-abort', this._onFileAbort.bind(this));
|
|
443
|
-
this.addEventListener('file-remove', this._onFileRemove.bind(this));
|
|
444
450
|
this.addEventListener('file-start', this._onFileStart.bind(this));
|
|
445
451
|
this.addEventListener('file-reject', this._onFileReject.bind(this));
|
|
446
452
|
this.addEventListener('upload-start', this._onUploadStart.bind(this));
|
|
447
453
|
this.addEventListener('upload-success', this._onUploadSuccess.bind(this));
|
|
448
454
|
this.addEventListener('upload-error', this._onUploadError.bind(this));
|
|
455
|
+
|
|
456
|
+
this.addController(
|
|
457
|
+
new SlotController(
|
|
458
|
+
this,
|
|
459
|
+
'add-button',
|
|
460
|
+
() => document.createElement('vaadin-button'),
|
|
461
|
+
(_, button) => {
|
|
462
|
+
button.addEventListener('touchend', (e) => {
|
|
463
|
+
this._onAddFilesTouchEnd(e);
|
|
464
|
+
});
|
|
465
|
+
button.addEventListener('click', (e) => {
|
|
466
|
+
this._onAddFilesClick(e);
|
|
467
|
+
});
|
|
468
|
+
this._addButton = button;
|
|
469
|
+
},
|
|
470
|
+
),
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
this.addController(
|
|
474
|
+
new SlotController(
|
|
475
|
+
this,
|
|
476
|
+
'drop-label',
|
|
477
|
+
() => document.createElement('span'),
|
|
478
|
+
(_, label) => {
|
|
479
|
+
this._dropLabel = label;
|
|
480
|
+
},
|
|
481
|
+
),
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
this.addController(
|
|
485
|
+
new SlotController(
|
|
486
|
+
this,
|
|
487
|
+
'file-list',
|
|
488
|
+
() => document.createElement('vaadin-upload-file-list'),
|
|
489
|
+
(_, list) => {
|
|
490
|
+
this._fileList = list;
|
|
491
|
+
},
|
|
492
|
+
),
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
this.addController(new SlotController(this, 'drop-label-icon', () => document.createElement('vaadin-upload-icon')));
|
|
449
496
|
}
|
|
450
497
|
|
|
451
498
|
/** @private */
|
|
@@ -509,6 +556,29 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
509
556
|
return maxFiles >= 0 && numFiles >= maxFiles;
|
|
510
557
|
}
|
|
511
558
|
|
|
559
|
+
/** @private */
|
|
560
|
+
__updateAddButton(addButton, maxFiles, i18n, maxFilesReached) {
|
|
561
|
+
if (addButton) {
|
|
562
|
+
addButton.disabled = maxFilesReached;
|
|
563
|
+
addButton.textContent = this._i18nPlural(maxFiles, i18n.addFiles);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/** @private */
|
|
568
|
+
__updateDropLabel(dropLabel, maxFiles, i18n) {
|
|
569
|
+
if (dropLabel) {
|
|
570
|
+
dropLabel.textContent = this._i18nPlural(maxFiles, i18n.dropFiles);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** @private */
|
|
575
|
+
__updateFileList(list, files, i18n) {
|
|
576
|
+
if (list) {
|
|
577
|
+
list.items = [...files];
|
|
578
|
+
list.i18n = i18n;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
512
582
|
/** @private */
|
|
513
583
|
_onDragover(event) {
|
|
514
584
|
event.preventDefault();
|
|
@@ -615,7 +685,7 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
615
685
|
this._setStatus(file, total, loaded, elapsed);
|
|
616
686
|
stalledId = setTimeout(() => {
|
|
617
687
|
file.status = this.i18n.uploading.status.stalled;
|
|
618
|
-
this.
|
|
688
|
+
this._renderFileList();
|
|
619
689
|
}, 2000);
|
|
620
690
|
} else {
|
|
621
691
|
file.loadedStr = file.totalStr;
|
|
@@ -623,7 +693,7 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
623
693
|
}
|
|
624
694
|
}
|
|
625
695
|
|
|
626
|
-
this.
|
|
696
|
+
this._renderFileList();
|
|
627
697
|
this.dispatchEvent(new CustomEvent('upload-progress', { detail: { file, xhr } }));
|
|
628
698
|
};
|
|
629
699
|
|
|
@@ -633,7 +703,6 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
633
703
|
clearTimeout(stalledId);
|
|
634
704
|
file.indeterminate = file.uploading = false;
|
|
635
705
|
if (file.abort) {
|
|
636
|
-
this._notifyFileChanges(file);
|
|
637
706
|
return;
|
|
638
707
|
}
|
|
639
708
|
file.status = '';
|
|
@@ -663,7 +732,7 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
663
732
|
detail: { file, xhr },
|
|
664
733
|
}),
|
|
665
734
|
);
|
|
666
|
-
this.
|
|
735
|
+
this._renderFileList();
|
|
667
736
|
}
|
|
668
737
|
};
|
|
669
738
|
|
|
@@ -697,7 +766,7 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
697
766
|
detail: { file, xhr },
|
|
698
767
|
}),
|
|
699
768
|
);
|
|
700
|
-
this.
|
|
769
|
+
this._renderFileList();
|
|
701
770
|
};
|
|
702
771
|
|
|
703
772
|
// Custom listener could modify the xhr just before sending it
|
|
@@ -739,16 +808,15 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
739
808
|
if (file.xhr) {
|
|
740
809
|
file.xhr.abort();
|
|
741
810
|
}
|
|
742
|
-
this.
|
|
811
|
+
this._removeFile(file);
|
|
743
812
|
}
|
|
744
813
|
}
|
|
745
814
|
|
|
746
815
|
/** @private */
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
});
|
|
816
|
+
_renderFileList() {
|
|
817
|
+
if (this._fileList) {
|
|
818
|
+
this._fileList.requestContentUpdate();
|
|
819
|
+
}
|
|
752
820
|
}
|
|
753
821
|
|
|
754
822
|
/** @private */
|
|
@@ -810,6 +878,14 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
810
878
|
_removeFile(file) {
|
|
811
879
|
if (this.files.indexOf(file) > -1) {
|
|
812
880
|
this.files = this.files.filter((i) => i !== file);
|
|
881
|
+
|
|
882
|
+
this.dispatchEvent(
|
|
883
|
+
new CustomEvent('file-remove', {
|
|
884
|
+
detail: { file },
|
|
885
|
+
bubbles: true,
|
|
886
|
+
composed: true,
|
|
887
|
+
}),
|
|
888
|
+
);
|
|
813
889
|
}
|
|
814
890
|
}
|
|
815
891
|
|
|
@@ -851,11 +927,6 @@ class Upload extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
851
927
|
this._abortFileUpload(event.detail.file);
|
|
852
928
|
}
|
|
853
929
|
|
|
854
|
-
/** @private */
|
|
855
|
-
_onFileRemove(event) {
|
|
856
|
-
this._removeFile(event.detail.file);
|
|
857
|
-
}
|
|
858
|
-
|
|
859
930
|
/** @private */
|
|
860
931
|
_onFileReject(event) {
|
|
861
932
|
announce(`${event.detail.file.name}: ${event.detail.file.error}`, { mode: 'alert' });
|
|
@@ -24,11 +24,6 @@ registerStyles(
|
|
|
24
24
|
transition: background-color 0.6s, border-color 0.6s;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
[part='primary-buttons'] > * {
|
|
28
|
-
display: inline-block;
|
|
29
|
-
white-space: nowrap;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
27
|
[part='drop-label'] {
|
|
33
28
|
display: inline-block;
|
|
34
29
|
white-space: normal;
|
|
@@ -50,24 +45,32 @@ registerStyles(
|
|
|
50
45
|
:host([max-files-reached]) [part='drop-label'] {
|
|
51
46
|
color: var(--lumo-disabled-text-color);
|
|
52
47
|
}
|
|
48
|
+
`,
|
|
49
|
+
{ moduleId: 'lumo-upload' },
|
|
50
|
+
);
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
[part='drop-label-icon']::before {
|
|
52
|
+
registerStyles(
|
|
53
|
+
'vaadin-upload-icon',
|
|
54
|
+
css`
|
|
55
|
+
:host::before {
|
|
59
56
|
content: var(--lumo-icons-upload);
|
|
60
57
|
font-family: lumo-icons;
|
|
61
58
|
font-size: var(--lumo-icon-size-m);
|
|
62
59
|
line-height: 1;
|
|
63
60
|
vertical-align: -0.25em;
|
|
64
61
|
}
|
|
62
|
+
`,
|
|
63
|
+
{ moduleId: 'lumo-upload-icon' },
|
|
64
|
+
);
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
registerStyles(
|
|
67
|
+
'vaadin-upload-file-list',
|
|
68
|
+
css`
|
|
69
|
+
::slotted(li:not(:first-of-type)) {
|
|
67
70
|
border-top: 1px solid var(--lumo-contrast-10pct);
|
|
68
71
|
}
|
|
69
72
|
`,
|
|
70
|
-
{ moduleId: 'lumo-upload' },
|
|
73
|
+
{ moduleId: 'lumo-upload-file-list' },
|
|
71
74
|
);
|
|
72
75
|
|
|
73
76
|
const uploadFile = css`
|
|
@@ -172,16 +175,11 @@ const uploadFile = css`
|
|
|
172
175
|
color: var(--lumo-error-text-color);
|
|
173
176
|
}
|
|
174
177
|
|
|
175
|
-
[
|
|
178
|
+
::slotted([slot='progress']) {
|
|
176
179
|
width: auto;
|
|
177
180
|
margin-left: calc(var(--lumo-icon-size-m) + var(--lumo-space-xs));
|
|
178
181
|
margin-right: calc(var(--lumo-icon-size-m) + var(--lumo-space-xs));
|
|
179
182
|
}
|
|
180
|
-
|
|
181
|
-
[part='progress'][complete],
|
|
182
|
-
[part='progress'][error] {
|
|
183
|
-
display: none;
|
|
184
|
-
}
|
|
185
183
|
`;
|
|
186
184
|
|
|
187
185
|
registerStyles('vaadin-upload-file', [fieldButton, uploadFile], { moduleId: 'lumo-upload-file' });
|
|
@@ -23,14 +23,7 @@ registerStyles(
|
|
|
23
23
|
align-items: baseline;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
[part='primary-buttons'] > * {
|
|
28
|
-
display: block;
|
|
29
|
-
flex-grow: 1;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
[part='upload-button'] {
|
|
33
|
-
display: block;
|
|
26
|
+
::slotted([slot='add-button']) {
|
|
34
27
|
margin: 0 -8px;
|
|
35
28
|
}
|
|
36
29
|
|
|
@@ -56,18 +49,6 @@ registerStyles(
|
|
|
56
49
|
color: var(--material-disabled-text-color);
|
|
57
50
|
}
|
|
58
51
|
|
|
59
|
-
[part='drop-label-icon'] {
|
|
60
|
-
display: inline-block;
|
|
61
|
-
margin-right: 8px;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
[part='drop-label-icon']::before {
|
|
65
|
-
content: var(--material-icons-upload);
|
|
66
|
-
font-family: material-icons;
|
|
67
|
-
font-size: var(--material-icon-font-size);
|
|
68
|
-
line-height: 1;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
52
|
/* Ripple */
|
|
72
53
|
|
|
73
54
|
:host::before {
|
|
@@ -96,6 +77,23 @@ registerStyles(
|
|
|
96
77
|
{ moduleId: 'material-upload' },
|
|
97
78
|
);
|
|
98
79
|
|
|
80
|
+
registerStyles(
|
|
81
|
+
'vaadin-upload-icon',
|
|
82
|
+
css`
|
|
83
|
+
:host {
|
|
84
|
+
margin-right: 8px;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
:host::before {
|
|
88
|
+
content: var(--material-icons-upload);
|
|
89
|
+
font-family: material-icons;
|
|
90
|
+
font-size: var(--material-icon-font-size);
|
|
91
|
+
line-height: 1;
|
|
92
|
+
}
|
|
93
|
+
`,
|
|
94
|
+
{ moduleId: 'material-upload-icon' },
|
|
95
|
+
);
|
|
96
|
+
|
|
99
97
|
registerStyles(
|
|
100
98
|
'vaadin-upload-file',
|
|
101
99
|
css`
|
|
@@ -237,15 +235,10 @@ registerStyles(
|
|
|
237
235
|
color: var(--material-error-text-color);
|
|
238
236
|
}
|
|
239
237
|
|
|
240
|
-
[
|
|
238
|
+
::slotted([slot='progress']) {
|
|
241
239
|
width: auto;
|
|
242
240
|
margin-left: 28px;
|
|
243
241
|
}
|
|
244
|
-
|
|
245
|
-
[part='progress'][complete],
|
|
246
|
-
[part='progress'][error] {
|
|
247
|
-
display: none;
|
|
248
|
-
}
|
|
249
242
|
`,
|
|
250
243
|
{ moduleId: 'material-upload-file' },
|
|
251
244
|
);
|
package/web-types.json
CHANGED
|
@@ -1,15 +1,103 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/upload",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "24.0.0-alpha2",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
8
8
|
"elements": [
|
|
9
9
|
{
|
|
10
10
|
"name": "vaadin-upload-file",
|
|
11
|
-
"description": "`<vaadin-upload-file>` element represents a file in the file list of `<vaadin-upload>`.\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------\n`row` | File container\n`info` | Container for file status icon, file name, status and error messages\n`done-icon` | File done status icon\n`warning-icon` | File warning status icon\n`meta` | Container for file name, status and error messages\n`name` | File name\n`error` | Error message, shown when error happens\n`status` | Status message\n`commands` | Container for file command buttons\n`start-button` | Start file upload button\n`retry-button` | Retry file upload button\n`remove-button` | Remove file button\n
|
|
11
|
+
"description": "`<vaadin-upload-file>` element represents a file in the file list of `<vaadin-upload>`.\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------\n`row` | File container\n`info` | Container for file status icon, file name, status and error messages\n`done-icon` | File done status icon\n`warning-icon` | File warning status icon\n`meta` | Container for file name, status and error messages\n`name` | File name\n`error` | Error message, shown when error happens\n`status` | Status message\n`commands` | Container for file command buttons\n`start-button` | Start file upload button\n`retry-button` | Retry file upload button\n`remove-button` | Remove file button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-----------------|-------------\n`focus-ring` | Set when the element is focused using the keyboard.\n`focused` | Set when the element is focused.\n`error` | An error has happened during uploading.\n`indeterminate` | Uploading is in progress, but the progress value is unknown.\n`uploading` | Uploading is in progress.\n`complete` | Uploading has finished successfully.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
|
|
12
12
|
"attributes": [
|
|
13
|
+
{
|
|
14
|
+
"name": "complete",
|
|
15
|
+
"description": "True if uploading is completed, false otherwise.",
|
|
16
|
+
"value": {
|
|
17
|
+
"type": [
|
|
18
|
+
"boolean",
|
|
19
|
+
"null",
|
|
20
|
+
"undefined"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "error-message",
|
|
26
|
+
"description": "Error message returned by the server, if any.",
|
|
27
|
+
"value": {
|
|
28
|
+
"type": [
|
|
29
|
+
"string",
|
|
30
|
+
"null",
|
|
31
|
+
"undefined"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "file-name",
|
|
37
|
+
"description": "Name of the uploading file.",
|
|
38
|
+
"value": {
|
|
39
|
+
"type": [
|
|
40
|
+
"string",
|
|
41
|
+
"null",
|
|
42
|
+
"undefined"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "held",
|
|
48
|
+
"description": "True if uploading is not started, false otherwise.",
|
|
49
|
+
"value": {
|
|
50
|
+
"type": [
|
|
51
|
+
"boolean",
|
|
52
|
+
"null",
|
|
53
|
+
"undefined"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "indeterminate",
|
|
59
|
+
"description": "True if remaining time is unknown, false otherwise.",
|
|
60
|
+
"value": {
|
|
61
|
+
"type": [
|
|
62
|
+
"boolean",
|
|
63
|
+
"null",
|
|
64
|
+
"undefined"
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"name": "progress",
|
|
70
|
+
"description": "Number representing the uploading progress.",
|
|
71
|
+
"value": {
|
|
72
|
+
"type": [
|
|
73
|
+
"number",
|
|
74
|
+
"null",
|
|
75
|
+
"undefined"
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "status",
|
|
81
|
+
"description": "Uploading status.",
|
|
82
|
+
"value": {
|
|
83
|
+
"type": [
|
|
84
|
+
"string",
|
|
85
|
+
"null",
|
|
86
|
+
"undefined"
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "uploading",
|
|
92
|
+
"description": "True if uploading is in progress, false otherwise.",
|
|
93
|
+
"value": {
|
|
94
|
+
"type": [
|
|
95
|
+
"boolean",
|
|
96
|
+
"null",
|
|
97
|
+
"undefined"
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
},
|
|
13
101
|
{
|
|
14
102
|
"name": "theme",
|
|
15
103
|
"description": "The theme variants to apply to the component.",
|
|
@@ -24,9 +112,31 @@
|
|
|
24
112
|
],
|
|
25
113
|
"js": {
|
|
26
114
|
"properties": [
|
|
115
|
+
{
|
|
116
|
+
"name": "complete",
|
|
117
|
+
"description": "True if uploading is completed, false otherwise.",
|
|
118
|
+
"value": {
|
|
119
|
+
"type": [
|
|
120
|
+
"boolean",
|
|
121
|
+
"null",
|
|
122
|
+
"undefined"
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "errorMessage",
|
|
128
|
+
"description": "Error message returned by the server, if any.",
|
|
129
|
+
"value": {
|
|
130
|
+
"type": [
|
|
131
|
+
"string",
|
|
132
|
+
"null",
|
|
133
|
+
"undefined"
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
},
|
|
27
137
|
{
|
|
28
138
|
"name": "file",
|
|
29
|
-
"description": "",
|
|
139
|
+
"description": "The object representing a file.",
|
|
30
140
|
"value": {
|
|
31
141
|
"type": [
|
|
32
142
|
"Object",
|
|
@@ -35,9 +145,42 @@
|
|
|
35
145
|
]
|
|
36
146
|
}
|
|
37
147
|
},
|
|
148
|
+
{
|
|
149
|
+
"name": "fileName",
|
|
150
|
+
"description": "Name of the uploading file.",
|
|
151
|
+
"value": {
|
|
152
|
+
"type": [
|
|
153
|
+
"string",
|
|
154
|
+
"null",
|
|
155
|
+
"undefined"
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"name": "held",
|
|
161
|
+
"description": "True if uploading is not started, false otherwise.",
|
|
162
|
+
"value": {
|
|
163
|
+
"type": [
|
|
164
|
+
"boolean",
|
|
165
|
+
"null",
|
|
166
|
+
"undefined"
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "indeterminate",
|
|
172
|
+
"description": "True if remaining time is unknown, false otherwise.",
|
|
173
|
+
"value": {
|
|
174
|
+
"type": [
|
|
175
|
+
"boolean",
|
|
176
|
+
"null",
|
|
177
|
+
"undefined"
|
|
178
|
+
]
|
|
179
|
+
}
|
|
180
|
+
},
|
|
38
181
|
{
|
|
39
182
|
"name": "i18n",
|
|
40
|
-
"description": "",
|
|
183
|
+
"description": "The object used to localize this component.",
|
|
41
184
|
"value": {
|
|
42
185
|
"type": [
|
|
43
186
|
"Object",
|
|
@@ -45,16 +188,45 @@
|
|
|
45
188
|
"undefined"
|
|
46
189
|
]
|
|
47
190
|
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "progress",
|
|
194
|
+
"description": "Number representing the uploading progress.",
|
|
195
|
+
"value": {
|
|
196
|
+
"type": [
|
|
197
|
+
"number",
|
|
198
|
+
"null",
|
|
199
|
+
"undefined"
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"name": "status",
|
|
205
|
+
"description": "Uploading status.",
|
|
206
|
+
"value": {
|
|
207
|
+
"type": [
|
|
208
|
+
"string",
|
|
209
|
+
"null",
|
|
210
|
+
"undefined"
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"name": "uploading",
|
|
216
|
+
"description": "True if uploading is in progress, false otherwise.",
|
|
217
|
+
"value": {
|
|
218
|
+
"type": [
|
|
219
|
+
"boolean",
|
|
220
|
+
"null",
|
|
221
|
+
"undefined"
|
|
222
|
+
]
|
|
223
|
+
}
|
|
48
224
|
}
|
|
49
225
|
],
|
|
50
226
|
"events": [
|
|
51
227
|
{
|
|
52
228
|
"name": "file-abort",
|
|
53
|
-
"description": "Fired when abort button is pressed. It is listened by `vaadin-upload` which\nwill abort the upload in progress,
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"name": "file-remove",
|
|
57
|
-
"description": "Fired after the animation to hide the element has finished. It is listened\nby `vaadin-upload` which will actually remove the file from the upload\nfile list."
|
|
229
|
+
"description": "Fired when abort button is pressed. It is listened by `vaadin-upload` which\nwill abort the upload in progress, and then remove the file from the list."
|
|
58
230
|
},
|
|
59
231
|
{
|
|
60
232
|
"name": "file-retry",
|
|
@@ -69,7 +241,7 @@
|
|
|
69
241
|
},
|
|
70
242
|
{
|
|
71
243
|
"name": "vaadin-upload",
|
|
72
|
-
"description": "`<vaadin-upload>` is a Web Component for uploading multiple files with drag and drop support.\n\nExample:\n\n```\n<vaadin-upload></vaadin-upload>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name
|
|
244
|
+
"description": "`<vaadin-upload>` is a Web Component for uploading multiple files with drag and drop support.\n\nExample:\n\n```\n<vaadin-upload></vaadin-upload>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-------------------|-------------------------------------\n`primary-buttons` | Upload container\n`drop-label` | Element wrapping drop label and icon\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n---|---|---\n`nodrop` | Set when drag and drop is disabled (e. g., on touch devices) | `:host`\n`dragover` | A file is being dragged over the element | `:host`\n`dragover-valid` | A dragged file is valid with `maxFiles` and `accept` criteria | `:host`\n`max-files-reached` | The maximum number of files that the user is allowed to add to the upload has been reached | `:host`\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
|
|
73
245
|
"attributes": [
|
|
74
246
|
{
|
|
75
247
|
"name": "nodrop",
|
package/web-types.lit.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/web-types",
|
|
3
3
|
"name": "@vaadin/upload",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "24.0.0-alpha2",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"framework": "lit",
|
|
7
7
|
"framework-config": {
|
|
@@ -16,33 +16,82 @@
|
|
|
16
16
|
"elements": [
|
|
17
17
|
{
|
|
18
18
|
"name": "vaadin-upload-file",
|
|
19
|
-
"description": "`<vaadin-upload-file>` element represents a file in the file list of `<vaadin-upload>`.\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------\n`row` | File container\n`info` | Container for file status icon, file name, status and error messages\n`done-icon` | File done status icon\n`warning-icon` | File warning status icon\n`meta` | Container for file name, status and error messages\n`name` | File name\n`error` | Error message, shown when error happens\n`status` | Status message\n`commands` | Container for file command buttons\n`start-button` | Start file upload button\n`retry-button` | Retry file upload button\n`remove-button` | Remove file button\n
|
|
19
|
+
"description": "`<vaadin-upload-file>` element represents a file in the file list of `<vaadin-upload>`.\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------\n`row` | File container\n`info` | Container for file status icon, file name, status and error messages\n`done-icon` | File done status icon\n`warning-icon` | File warning status icon\n`meta` | Container for file name, status and error messages\n`name` | File name\n`error` | Error message, shown when error happens\n`status` | Status message\n`commands` | Container for file command buttons\n`start-button` | Start file upload button\n`retry-button` | Retry file upload button\n`remove-button` | Remove file button\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n-----------------|-------------\n`focus-ring` | Set when the element is focused using the keyboard.\n`focused` | Set when the element is focused.\n`error` | An error has happened during uploading.\n`indeterminate` | Uploading is in progress, but the progress value is unknown.\n`uploading` | Uploading is in progress.\n`complete` | Uploading has finished successfully.\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
|
|
20
20
|
"extension": true,
|
|
21
21
|
"attributes": [
|
|
22
|
+
{
|
|
23
|
+
"name": "?complete",
|
|
24
|
+
"description": "True if uploading is completed, false otherwise.",
|
|
25
|
+
"value": {
|
|
26
|
+
"kind": "expression"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "?held",
|
|
31
|
+
"description": "True if uploading is not started, false otherwise.",
|
|
32
|
+
"value": {
|
|
33
|
+
"kind": "expression"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "?indeterminate",
|
|
38
|
+
"description": "True if remaining time is unknown, false otherwise.",
|
|
39
|
+
"value": {
|
|
40
|
+
"kind": "expression"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "?uploading",
|
|
45
|
+
"description": "True if uploading is in progress, false otherwise.",
|
|
46
|
+
"value": {
|
|
47
|
+
"kind": "expression"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": ".errorMessage",
|
|
52
|
+
"description": "Error message returned by the server, if any.",
|
|
53
|
+
"value": {
|
|
54
|
+
"kind": "expression"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
22
57
|
{
|
|
23
58
|
"name": ".file",
|
|
24
|
-
"description": "",
|
|
59
|
+
"description": "The object representing a file.",
|
|
60
|
+
"value": {
|
|
61
|
+
"kind": "expression"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": ".fileName",
|
|
66
|
+
"description": "Name of the uploading file.",
|
|
25
67
|
"value": {
|
|
26
68
|
"kind": "expression"
|
|
27
69
|
}
|
|
28
70
|
},
|
|
29
71
|
{
|
|
30
72
|
"name": ".i18n",
|
|
31
|
-
"description": "",
|
|
73
|
+
"description": "The object used to localize this component.",
|
|
32
74
|
"value": {
|
|
33
75
|
"kind": "expression"
|
|
34
76
|
}
|
|
35
77
|
},
|
|
36
78
|
{
|
|
37
|
-
"name": "
|
|
38
|
-
"description": "
|
|
79
|
+
"name": ".progress",
|
|
80
|
+
"description": "Number representing the uploading progress.",
|
|
39
81
|
"value": {
|
|
40
82
|
"kind": "expression"
|
|
41
83
|
}
|
|
42
84
|
},
|
|
43
85
|
{
|
|
44
|
-
"name": "
|
|
45
|
-
"description": "
|
|
86
|
+
"name": ".status",
|
|
87
|
+
"description": "Uploading status.",
|
|
88
|
+
"value": {
|
|
89
|
+
"kind": "expression"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "@file-abort",
|
|
94
|
+
"description": "Fired when abort button is pressed. It is listened by `vaadin-upload` which\nwill abort the upload in progress, and then remove the file from the list.",
|
|
46
95
|
"value": {
|
|
47
96
|
"kind": "expression"
|
|
48
97
|
}
|
|
@@ -65,7 +114,7 @@
|
|
|
65
114
|
},
|
|
66
115
|
{
|
|
67
116
|
"name": "vaadin-upload",
|
|
68
|
-
"description": "`<vaadin-upload>` is a Web Component for uploading multiple files with drag and drop support.\n\nExample:\n\n```\n<vaadin-upload></vaadin-upload>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name
|
|
117
|
+
"description": "`<vaadin-upload>` is a Web Component for uploading multiple files with drag and drop support.\n\nExample:\n\n```\n<vaadin-upload></vaadin-upload>\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-------------------|-------------------------------------\n`primary-buttons` | Upload container\n`drop-label` | Element wrapping drop label and icon\n\nThe following state attributes are available for styling:\n\nAttribute | Description | Part name\n---|---|---\n`nodrop` | Set when drag and drop is disabled (e. g., on touch devices) | `:host`\n`dragover` | A file is being dragged over the element | `:host`\n`dragover-valid` | A dragged file is valid with `maxFiles` and `accept` criteria | `:host`\n`max-files-reached` | The maximum number of files that the user is allowed to add to the upload has been reached | `:host`\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
|
|
69
118
|
"extension": true,
|
|
70
119
|
"attributes": [
|
|
71
120
|
{
|