@vmz/ui 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/contracts/token-requirements.v0.json +58 -1
- package/package.json +5 -2
- package/presets/web-surface.v0.json +14 -12
- package/src/components/Accordion.vmz +49 -16
- package/src/components/Alert.vmz +125 -28
- package/src/components/AppShell.vmz +121 -56
- package/src/components/Autocomplete.vmz +136 -29
- package/src/components/Avatar.vmz +20 -12
- package/src/components/Badge.vmz +18 -26
- package/src/components/Breadcrumb.vmz +28 -14
- package/src/components/BulkActions.vmz +13 -8
- package/src/components/Button.vmz +68 -44
- package/src/components/Callout.vmz +128 -27
- package/src/components/Card.vmz +67 -46
- package/src/components/Checkbox.vmz +81 -5
- package/src/components/CodeBlock.vmz +59 -27
- package/src/components/Collapse.vmz +64 -11
- package/src/components/ConsoleShell.vmz +249 -69
- package/src/components/Content.vmz +15 -1
- package/src/components/DataTable.vmz +123 -23
- package/src/components/DatePicker.vmz +171 -79
- package/src/components/Descriptions.vmz +90 -0
- package/src/components/Dialog.vmz +133 -50
- package/src/components/Divider.vmz +8 -1
- package/src/components/Drawer.vmz +131 -40
- package/src/components/Dropdown.vmz +147 -49
- package/src/components/Empty.vmz +56 -14
- package/src/components/Field.vmz +78 -23
- package/src/components/FilterBar.vmz +34 -4
- package/src/components/Flex.vmz +3 -1
- package/src/components/Footer.vmz +6 -3
- package/src/components/Form.vmz +41 -0
- package/src/components/FormItem.vmz +2 -3
- package/src/components/Grid.vmz +6 -3
- package/src/components/Header.vmz +193 -6
- package/src/components/Layout.vmz +3 -1
- package/src/components/Link.vmz +20 -9
- package/src/components/List.vmz +35 -13
- package/src/components/Menu.vmz +198 -25
- package/src/components/Message.vmz +167 -0
- package/src/components/Notification.vmz +132 -37
- package/src/components/Pagination.vmz +186 -20
- package/src/components/Popconfirm.vmz +287 -0
- package/src/components/Popover.vmz +152 -34
- package/src/components/Progress.vmz +16 -5
- package/src/components/Prose.vmz +131 -32
- package/src/components/QueryForm.vmz +31 -9
- package/src/components/RadioGroup.vmz +91 -11
- package/src/components/Result.vmz +60 -27
- package/src/components/Segmented.vmz +46 -11
- package/src/components/Select.vmz +174 -87
- package/src/components/Sider.vmz +120 -7
- package/src/components/Skeleton.vmz +9 -7
- package/src/components/Space.vmz +9 -3
- package/src/components/Spinner.vmz +5 -4
- package/src/components/Steps.vmz +40 -25
- package/src/components/Switch.vmz +48 -15
- package/src/components/Table.vmz +130 -25
- package/src/components/Tabs.vmz +28 -13
- package/src/components/Tag.vmz +29 -12
- package/src/components/TextArea.vmz +32 -25
- package/src/components/Timeline.vmz +65 -30
- package/src/components/Toc.vmz +45 -29
- package/src/components/Tooltip.vmz +70 -21
- package/src/components/Tree.vmz +48 -25
- package/src/components/Typography.vmz +23 -8
- package/src/components/Upload.vmz +191 -96
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
</label>
|
|
6
6
|
<div data-vmz-upload="zone" class="vmz-ui-upload__zone">
|
|
7
7
|
<input :id="controlId" type="file" :accept="accept" :multiple="multiple" :disabled="inputDisabled" :aria-invalid="error ? 'true' : 'false'" :aria-describedby="describedBy" :data-vmz-upload-directory="directoryAttr" @change="onPick" class="vmz-ui-upload__control" />
|
|
8
|
-
<
|
|
9
|
-
|
|
8
|
+
<Icon name="action.upload" size="lg" decorative />
|
|
9
|
+
<p v-if="hint" data-vmz-upload="hint" class="vmz-ui-upload__hint">
|
|
10
|
+
{{ hint }}
|
|
10
11
|
</p>
|
|
11
12
|
</div>
|
|
12
13
|
<ul v-if="hasItems" data-vmz-upload="queue" class="vmz-ui-upload__queue">
|
|
@@ -24,7 +25,9 @@
|
|
|
24
25
|
{{ emptyText }}
|
|
25
26
|
</p>
|
|
26
27
|
<div v-if="showProgress" data-vmz-upload="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" :aria-valuenow="progress" :aria-label="progressLabel" class="vmz-ui-upload__progress">
|
|
27
|
-
<div class="vmz-ui-
|
|
28
|
+
<div class="vmz-ui-upload__track">
|
|
29
|
+
<div class="vmz-ui-upload__bar" :style="progressStyle" />
|
|
30
|
+
</div>
|
|
28
31
|
<span data-vmz-upload="pct" class="vmz-ui-upload__pct">
|
|
29
32
|
{{ progressLabel }}
|
|
30
33
|
</span>
|
|
@@ -36,11 +39,17 @@
|
|
|
36
39
|
{{ resultText }}
|
|
37
40
|
</p>
|
|
38
41
|
<div v-if="showActions" data-vmz-upload="actions" class="vmz-ui-upload__actions">
|
|
39
|
-
<button v-if="canCancel" type="button" data-vmz-upload="cancel" @click="onCancelClick" class="vmz-ui-upload__cancel">
|
|
40
|
-
|
|
42
|
+
<button v-if="canCancel" type="button" data-vmz-upload="cancel" :aria-label="cancelLabel" @click="onCancelClick" class="vmz-ui-upload__cancel">
|
|
43
|
+
<Icon name="action.close" size="sm" decorative />
|
|
44
|
+
<span v-if="cancelLabel">
|
|
45
|
+
{{ cancelLabel }}
|
|
46
|
+
</span>
|
|
41
47
|
</button>
|
|
42
|
-
<button v-if="canResume" type="button" data-vmz-upload="resume" @click="onResumeClick" class="vmz-ui-upload__resume">
|
|
43
|
-
|
|
48
|
+
<button v-if="canResume" type="button" data-vmz-upload="resume" :aria-label="resumeLabel" @click="onResumeClick" class="vmz-ui-upload__resume">
|
|
49
|
+
<Icon name="action.chevron-right" size="sm" decorative />
|
|
50
|
+
<span v-if="resumeLabel">
|
|
51
|
+
{{ resumeLabel }}
|
|
52
|
+
</span>
|
|
44
53
|
</button>
|
|
45
54
|
</div>
|
|
46
55
|
<p v-if="description" :id="descriptionId" class="vmz-ui-upload__description">
|
|
@@ -55,21 +64,49 @@
|
|
|
55
64
|
.vmz-ui-upload {
|
|
56
65
|
display: flex;
|
|
57
66
|
flex-direction: column;
|
|
58
|
-
gap:
|
|
67
|
+
gap: 6px;
|
|
68
|
+
width: 100%;
|
|
59
69
|
max-width: 28rem;
|
|
60
70
|
}
|
|
61
71
|
|
|
62
72
|
.vmz-ui-upload__label {
|
|
63
|
-
font:
|
|
73
|
+
font-size: 14px;
|
|
64
74
|
font-weight: 600;
|
|
75
|
+
line-height: 22px;
|
|
76
|
+
color: var(--vmz-text-ink);
|
|
65
77
|
}
|
|
66
78
|
|
|
67
79
|
.vmz-ui-upload__zone {
|
|
68
80
|
position: relative;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
align-items: center;
|
|
84
|
+
justify-content: center;
|
|
85
|
+
gap: 8px;
|
|
86
|
+
box-sizing: border-box;
|
|
87
|
+
min-height: 96px;
|
|
88
|
+
padding: 20px 24px;
|
|
69
89
|
border: 1px dashed var(--vmz-line-default);
|
|
70
|
-
border-radius: var(--vmz-radius-
|
|
71
|
-
background: var(--vmz-surface-
|
|
72
|
-
|
|
90
|
+
border-radius: var(--vmz-radius-lg);
|
|
91
|
+
background: var(--vmz-surface-mist);
|
|
92
|
+
text-align: center;
|
|
93
|
+
transition:
|
|
94
|
+
border-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
|
|
95
|
+
background-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.vmz-ui-upload__zone:hover {
|
|
99
|
+
border-color: var(--vmz-action-primary-background);
|
|
100
|
+
background: color-mix(
|
|
101
|
+
in srgb,
|
|
102
|
+
var(--vmz-action-primary-background) 4%,
|
|
103
|
+
var(--vmz-surface-paper)
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.vmz-ui-upload__zone:focus-within {
|
|
108
|
+
border-color: var(--vmz-action-primary-background);
|
|
109
|
+
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
73
110
|
}
|
|
74
111
|
|
|
75
112
|
.vmz-ui-upload.is-dragover .vmz-ui-upload__zone {
|
|
@@ -82,26 +119,33 @@
|
|
|
82
119
|
}
|
|
83
120
|
|
|
84
121
|
.vmz-ui-upload__control {
|
|
85
|
-
|
|
122
|
+
position: absolute;
|
|
123
|
+
inset: 0;
|
|
86
124
|
width: 100%;
|
|
87
|
-
|
|
88
|
-
|
|
125
|
+
height: 100%;
|
|
126
|
+
margin: 0;
|
|
127
|
+
padding: 0;
|
|
128
|
+
border: 0;
|
|
129
|
+
opacity: 0;
|
|
130
|
+
cursor: pointer;
|
|
89
131
|
outline: none;
|
|
90
132
|
}
|
|
91
133
|
|
|
92
|
-
.vmz-ui-upload__control:focus-visible {
|
|
93
|
-
box-shadow: 0 0 0 3px var(--vmz-focus-ring);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
134
|
.vmz-ui-upload__control:disabled {
|
|
97
|
-
opacity: 0.55;
|
|
98
135
|
cursor: not-allowed;
|
|
99
136
|
}
|
|
100
137
|
|
|
138
|
+
.vmz-ui-upload__zone .vmz-ui-icon {
|
|
139
|
+
color: var(--vmz-text-tertiary);
|
|
140
|
+
pointer-events: none;
|
|
141
|
+
}
|
|
142
|
+
|
|
101
143
|
.vmz-ui-upload__hint {
|
|
102
|
-
margin: 0
|
|
103
|
-
font-size:
|
|
144
|
+
margin: 0;
|
|
145
|
+
font-size: 14px;
|
|
146
|
+
line-height: 22px;
|
|
104
147
|
color: var(--vmz-text-steel);
|
|
148
|
+
pointer-events: none;
|
|
105
149
|
}
|
|
106
150
|
|
|
107
151
|
.vmz-ui-upload__queue {
|
|
@@ -110,22 +154,31 @@
|
|
|
110
154
|
padding: 0;
|
|
111
155
|
display: flex;
|
|
112
156
|
flex-direction: column;
|
|
113
|
-
|
|
157
|
+
border: 1px solid var(--vmz-line-subtle);
|
|
158
|
+
border-radius: var(--vmz-radius-lg);
|
|
159
|
+
background: var(--vmz-surface-paper);
|
|
160
|
+
overflow: hidden;
|
|
114
161
|
}
|
|
115
162
|
|
|
116
163
|
.vmz-ui-upload__item {
|
|
117
164
|
display: grid;
|
|
118
165
|
grid-template-columns: 1fr auto;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
166
|
+
align-items: center;
|
|
167
|
+
gap: 2px 12px;
|
|
168
|
+
min-height: 40px;
|
|
169
|
+
box-sizing: border-box;
|
|
170
|
+
padding: var(--vmz-density-compact-padding-y) var(--vmz-density-compact-padding-x);
|
|
171
|
+
border-bottom: 1px solid var(--vmz-line-subtle);
|
|
123
172
|
background: var(--vmz-surface-paper);
|
|
124
173
|
}
|
|
125
174
|
|
|
175
|
+
.vmz-ui-upload__item:last-child {
|
|
176
|
+
border-bottom: none;
|
|
177
|
+
}
|
|
178
|
+
|
|
126
179
|
.vmz-ui-upload__item-name {
|
|
127
|
-
font-
|
|
128
|
-
|
|
180
|
+
font-size: 14px;
|
|
181
|
+
line-height: 22px;
|
|
129
182
|
color: var(--vmz-text-ink);
|
|
130
183
|
overflow: hidden;
|
|
131
184
|
text-overflow: ellipsis;
|
|
@@ -133,17 +186,18 @@
|
|
|
133
186
|
}
|
|
134
187
|
|
|
135
188
|
.vmz-ui-upload__item-meta {
|
|
136
|
-
font-size:
|
|
137
|
-
|
|
189
|
+
font-size: 12px;
|
|
190
|
+
line-height: 20px;
|
|
191
|
+
color: var(--vmz-text-tertiary);
|
|
138
192
|
white-space: nowrap;
|
|
139
193
|
}
|
|
140
194
|
|
|
141
195
|
.vmz-ui-upload__item-bar {
|
|
142
196
|
grid-column: 1 / -1;
|
|
143
|
-
height:
|
|
144
|
-
border-radius:
|
|
197
|
+
height: 2px;
|
|
198
|
+
border-radius: 1px;
|
|
145
199
|
background: var(--vmz-action-primary-background);
|
|
146
|
-
min-width:
|
|
200
|
+
min-width: 2px;
|
|
147
201
|
transition: width var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
148
202
|
}
|
|
149
203
|
|
|
@@ -151,6 +205,10 @@
|
|
|
151
205
|
color: var(--vmz-status-danger-foreground);
|
|
152
206
|
}
|
|
153
207
|
|
|
208
|
+
.vmz-ui-upload[data-vmz-upload-status="error"] .vmz-ui-upload__zone {
|
|
209
|
+
border-color: var(--vmz-status-danger-accent);
|
|
210
|
+
}
|
|
211
|
+
|
|
154
212
|
/* The native file input already announces "no file chosen"; keep this node for
|
|
155
213
|
assistive tech without repeating the same line visually. */
|
|
156
214
|
.vmz-ui-upload__empty {
|
|
@@ -169,28 +227,37 @@
|
|
|
169
227
|
display: grid;
|
|
170
228
|
grid-template-columns: 1fr auto;
|
|
171
229
|
align-items: center;
|
|
172
|
-
gap:
|
|
173
|
-
padding:
|
|
230
|
+
gap: 8px;
|
|
231
|
+
padding: 4px 0;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.vmz-ui-upload__track {
|
|
235
|
+
height: 6px;
|
|
236
|
+
border-radius: 999px;
|
|
237
|
+
background: var(--vmz-surface-mist);
|
|
238
|
+
overflow: hidden;
|
|
174
239
|
}
|
|
175
240
|
|
|
176
241
|
.vmz-ui-upload__bar {
|
|
177
|
-
height:
|
|
178
|
-
border-radius:
|
|
242
|
+
height: 100%;
|
|
243
|
+
border-radius: inherit;
|
|
179
244
|
background: var(--vmz-action-primary-background);
|
|
180
|
-
min-width:
|
|
245
|
+
min-width: 2px;
|
|
181
246
|
transition: width var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
182
247
|
}
|
|
183
248
|
|
|
184
249
|
.vmz-ui-upload__pct {
|
|
185
|
-
font-
|
|
186
|
-
|
|
250
|
+
font-size: 12px;
|
|
251
|
+
line-height: 20px;
|
|
187
252
|
color: var(--vmz-text-steel);
|
|
253
|
+
font-variant-numeric: tabular-nums;
|
|
188
254
|
white-space: nowrap;
|
|
189
255
|
}
|
|
190
256
|
|
|
191
257
|
.vmz-ui-upload__status {
|
|
192
258
|
margin: 0;
|
|
193
|
-
font-size:
|
|
259
|
+
font-size: 14px;
|
|
260
|
+
line-height: 22px;
|
|
194
261
|
color: var(--vmz-text-steel);
|
|
195
262
|
}
|
|
196
263
|
|
|
@@ -206,25 +273,44 @@
|
|
|
206
273
|
.vmz-ui-upload__result {
|
|
207
274
|
margin: 0;
|
|
208
275
|
font-family: var(--vmz-font-mono);
|
|
209
|
-
font-size:
|
|
276
|
+
font-size: 12px;
|
|
277
|
+
line-height: 20px;
|
|
210
278
|
color: var(--vmz-text-ink);
|
|
211
279
|
}
|
|
212
280
|
|
|
213
281
|
.vmz-ui-upload__actions {
|
|
214
282
|
display: flex;
|
|
215
|
-
|
|
283
|
+
flex-wrap: wrap;
|
|
284
|
+
gap: 8px;
|
|
216
285
|
}
|
|
217
286
|
|
|
218
287
|
.vmz-ui-upload__cancel,
|
|
219
288
|
.vmz-ui-upload__resume {
|
|
289
|
+
display: inline-flex;
|
|
290
|
+
align-items: center;
|
|
291
|
+
justify-content: center;
|
|
292
|
+
gap: 6px;
|
|
293
|
+
min-height: var(--vmz-control-height, 32px);
|
|
294
|
+
box-sizing: border-box;
|
|
220
295
|
font: inherit;
|
|
221
|
-
|
|
296
|
+
font-size: 14px;
|
|
297
|
+
line-height: 22px;
|
|
298
|
+
padding: var(--vmz-density-control-padding-y) var(--vmz-density-control-padding-x);
|
|
222
299
|
border: 1px solid var(--vmz-line-default);
|
|
223
|
-
border-radius: var(--vmz-radius-md
|
|
300
|
+
border-radius: var(--vmz-radius-md);
|
|
224
301
|
background: var(--vmz-surface-paper);
|
|
225
302
|
color: var(--vmz-text-ink);
|
|
226
303
|
cursor: pointer;
|
|
227
304
|
outline: none;
|
|
305
|
+
transition:
|
|
306
|
+
color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing),
|
|
307
|
+
border-color var(--vmz-motion-control-duration) var(--vmz-motion-control-easing);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.vmz-ui-upload__cancel:hover,
|
|
311
|
+
.vmz-ui-upload__resume:hover {
|
|
312
|
+
border-color: var(--vmz-action-primary-background);
|
|
313
|
+
color: var(--vmz-action-primary-background);
|
|
228
314
|
}
|
|
229
315
|
|
|
230
316
|
.vmz-ui-upload__cancel:focus-visible,
|
|
@@ -239,19 +325,24 @@
|
|
|
239
325
|
|
|
240
326
|
.vmz-ui-upload__description {
|
|
241
327
|
margin: 0;
|
|
242
|
-
|
|
243
|
-
|
|
328
|
+
font-size: 14px;
|
|
329
|
+
line-height: 22px;
|
|
330
|
+
color: var(--vmz-text-tertiary);
|
|
244
331
|
}
|
|
245
332
|
|
|
246
333
|
.vmz-ui-upload__error {
|
|
247
334
|
margin: 0;
|
|
335
|
+
font-size: 14px;
|
|
336
|
+
line-height: 22px;
|
|
248
337
|
color: var(--vmz-status-danger-foreground);
|
|
249
|
-
font-size: 0.9em;
|
|
250
338
|
}
|
|
251
339
|
|
|
252
340
|
@media (prefers-reduced-motion: reduce) {
|
|
253
341
|
.vmz-ui-upload__bar,
|
|
254
|
-
.vmz-ui-upload__item-bar
|
|
342
|
+
.vmz-ui-upload__item-bar,
|
|
343
|
+
.vmz-ui-upload__zone,
|
|
344
|
+
.vmz-ui-upload__cancel,
|
|
345
|
+
.vmz-ui-upload__resume {
|
|
255
346
|
transition: none;
|
|
256
347
|
}
|
|
257
348
|
}
|
|
@@ -272,7 +363,7 @@ export default class Upload {
|
|
|
272
363
|
public description: string = "";
|
|
273
364
|
/** Form-level validation message from parent. */
|
|
274
365
|
public error: string = "";
|
|
275
|
-
public emptyText: string = "
|
|
366
|
+
public emptyText: string = "";
|
|
276
367
|
public accept: string = "";
|
|
277
368
|
public disabled: boolean = false;
|
|
278
369
|
public invalidAttr: string = "false";
|
|
@@ -310,10 +401,14 @@ export default class Upload {
|
|
|
310
401
|
public onValue: ((items: UploadValueItem[]) => void) | null = null;
|
|
311
402
|
/** Parent mirrors overall status for form fixture / submit gates. */
|
|
312
403
|
public onStatus: ((status: string) => void) | null = null;
|
|
313
|
-
public cancelLabel: string = "
|
|
314
|
-
public resumeLabel: string = "
|
|
315
|
-
/** Caller-supplied drop-zone hint; empty
|
|
404
|
+
public cancelLabel: string = "";
|
|
405
|
+
public resumeLabel: string = "";
|
|
406
|
+
/** Caller-supplied drop-zone hint; empty hides the hint line. */
|
|
316
407
|
public hint: string = "";
|
|
408
|
+
/** Localized status / diagnostic copy. Empty keys hide the status line. */
|
|
409
|
+
public messages: Record<string, string> = {};
|
|
410
|
+
/** Suffix for multi-file success (`N <readyText>`); part of the stable result text. */
|
|
411
|
+
public readyText: string = "file(s) ready";
|
|
317
412
|
// presentation (component-owned — NOT public props)
|
|
318
413
|
status: string = "idle";
|
|
319
414
|
progress: string = "0";
|
|
@@ -333,7 +428,6 @@ export default class Upload {
|
|
|
333
428
|
directoryAttr: string = "false";
|
|
334
429
|
chunkAttr: string = "0";
|
|
335
430
|
sessionAttr: string = "";
|
|
336
|
-
zoneHint: string = "Choose a file or drop it here";
|
|
337
431
|
/** @type {{ key: string, name: string, meta: string, status: string, showBar: boolean, barStyle: string }[]} */
|
|
338
432
|
queue: {
|
|
339
433
|
key: string;
|
|
@@ -374,6 +468,11 @@ export default class Upload {
|
|
|
374
468
|
this.applyDirectoryAttr();
|
|
375
469
|
this.syncChunkAttr();
|
|
376
470
|
}
|
|
471
|
+
msg(key: string) {
|
|
472
|
+
const messages = this.messages || {};
|
|
473
|
+
const value = messages[key];
|
|
474
|
+
return typeof value === "string" ? value : "";
|
|
475
|
+
}
|
|
377
476
|
onPick(ev) {
|
|
378
477
|
this.syncClearToken();
|
|
379
478
|
this.applyDirectoryAttr();
|
|
@@ -432,11 +531,6 @@ export default class Upload {
|
|
|
432
531
|
applyDirectoryAttr() {
|
|
433
532
|
this.directoryAttr = this.directory ? "true" : "false";
|
|
434
533
|
this.selectionMode = this.directory ? "directory" : this.multiple ? "multiple" : "single";
|
|
435
|
-
this.zoneHint = this.directory
|
|
436
|
-
? "Choose a folder or drop files here"
|
|
437
|
-
: this.multiple
|
|
438
|
-
? "Choose files or drop them here"
|
|
439
|
-
: "Choose a file or drop it here";
|
|
440
534
|
// Native directory picker (UA-specific).
|
|
441
535
|
const el = typeof document !== "undefined" ? document.getElementById(this.controlId) : null;
|
|
442
536
|
if (el && "webkitdirectory" in el) {
|
|
@@ -464,24 +558,24 @@ export default class Upload {
|
|
|
464
558
|
const capped =
|
|
465
559
|
this.multiple || this.directory ? files.slice(0, maxCount) : files.slice(0, 1);
|
|
466
560
|
if ((this.multiple || this.directory) && files.length > maxCount) {
|
|
467
|
-
this.failAll(
|
|
561
|
+
this.failAll(this.msg("tooMany"));
|
|
468
562
|
return;
|
|
469
563
|
}
|
|
470
564
|
const maxBytes = Number(this.maxBytes) || 0;
|
|
471
565
|
for (const f of capped) {
|
|
472
566
|
const acceptErr = acceptError(f, this.accept);
|
|
473
567
|
if (acceptErr) {
|
|
474
|
-
this.failAll(
|
|
568
|
+
this.failAll(this.msg("acceptType"));
|
|
475
569
|
return;
|
|
476
570
|
}
|
|
477
571
|
if (maxBytes > 0 && Number(f.size) > maxBytes) {
|
|
478
|
-
this.failAll(
|
|
572
|
+
this.failAll(this.msg("fileTooLarge"));
|
|
479
573
|
return;
|
|
480
574
|
}
|
|
481
575
|
}
|
|
482
576
|
const chunkSize = Math.max(0, Number(this.chunkSize) || 0);
|
|
483
577
|
if (chunkSize > 0 && capped.length !== 1) {
|
|
484
|
-
this.failAll("
|
|
578
|
+
this.failAll(this.msg("singleFileChunk"));
|
|
485
579
|
return;
|
|
486
580
|
}
|
|
487
581
|
this.cancelActive(false);
|
|
@@ -530,7 +624,7 @@ export default class Upload {
|
|
|
530
624
|
*/
|
|
531
625
|
async runClient(gen) {
|
|
532
626
|
if (gen !== this._gen) return;
|
|
533
|
-
this.setOverall("uploading", "
|
|
627
|
+
this.setOverall("uploading", this.msg("preparing"), true, false);
|
|
534
628
|
const values = [];
|
|
535
629
|
for (let i = 0; i < this._files.length; i++) {
|
|
536
630
|
if (gen !== this._gen) return;
|
|
@@ -540,7 +634,7 @@ export default class Upload {
|
|
|
540
634
|
status: "done",
|
|
541
635
|
showBar: true,
|
|
542
636
|
barStyle: `width:${pct}%`,
|
|
543
|
-
meta:
|
|
637
|
+
meta: formatBytes(file.size),
|
|
544
638
|
});
|
|
545
639
|
this.setProgress(pct);
|
|
546
640
|
values.push({
|
|
@@ -565,11 +659,11 @@ export default class Upload {
|
|
|
565
659
|
if (gen !== this._gen) return;
|
|
566
660
|
const action = String(this.action || "").trim();
|
|
567
661
|
if (!action) {
|
|
568
|
-
this.failAll("
|
|
662
|
+
this.failAll(this.msg("actionRequired"));
|
|
569
663
|
return;
|
|
570
664
|
}
|
|
571
665
|
// Sequential single-XHR for thin gate; multi-file appends all parts then one request.
|
|
572
|
-
this.setOverall("uploading", "
|
|
666
|
+
this.setOverall("uploading", this.msg("uploading"), true, true);
|
|
573
667
|
this.setProgress(0);
|
|
574
668
|
for (let i = 0; i < this.queue.length; i++) {
|
|
575
669
|
this.patchItem(i, {
|
|
@@ -610,7 +704,7 @@ export default class Upload {
|
|
|
610
704
|
}
|
|
611
705
|
const body = result.body;
|
|
612
706
|
if (!(result.status >= 200 && result.status < 300) || !body || !body.ok) {
|
|
613
|
-
this.failAll((body && body.error) ||
|
|
707
|
+
this.failAll((body && body.error) || this.msg("failed"));
|
|
614
708
|
return;
|
|
615
709
|
}
|
|
616
710
|
// Single-file shape { ok, id, bytes, name } or multi { ok, items: [...] }
|
|
@@ -648,7 +742,7 @@ export default class Upload {
|
|
|
648
742
|
status: "done",
|
|
649
743
|
showBar: true,
|
|
650
744
|
barStyle: "width:100%",
|
|
651
|
-
meta:
|
|
745
|
+
meta: formatBytes(values[i] && values[i].bytes),
|
|
652
746
|
});
|
|
653
747
|
}
|
|
654
748
|
this._values = values;
|
|
@@ -666,16 +760,16 @@ export default class Upload {
|
|
|
666
760
|
.trim()
|
|
667
761
|
.replace(/\/+$/, "");
|
|
668
762
|
if (!base) {
|
|
669
|
-
this.failAll("
|
|
763
|
+
this.failAll(this.msg("actionRequired"));
|
|
670
764
|
return;
|
|
671
765
|
}
|
|
672
766
|
const file = this._files[0];
|
|
673
767
|
if (!file) {
|
|
674
|
-
this.failAll("
|
|
768
|
+
this.failAll(this.msg("noFile"));
|
|
675
769
|
return;
|
|
676
770
|
}
|
|
677
771
|
this._activeChunkSize = chunkSize;
|
|
678
|
-
this.setOverall("uploading", this._uploadId ? "
|
|
772
|
+
this.setOverall("uploading", this._uploadId ? this.msg("resuming") : this.msg("uploading"), true, true);
|
|
679
773
|
this.canResume = false;
|
|
680
774
|
this.showActions = true;
|
|
681
775
|
this.patchItem(0, {
|
|
@@ -707,7 +801,7 @@ export default class Upload {
|
|
|
707
801
|
this.failAll(
|
|
708
802
|
(initResult.body && initResult.body.error) ||
|
|
709
803
|
initResult.error ||
|
|
710
|
-
|
|
804
|
+
this.msg("initFailed"),
|
|
711
805
|
);
|
|
712
806
|
return;
|
|
713
807
|
}
|
|
@@ -719,7 +813,7 @@ export default class Upload {
|
|
|
719
813
|
this._received = [];
|
|
720
814
|
this.syncChunkAttr();
|
|
721
815
|
if (!this._uploadId) {
|
|
722
|
-
this.failAll("
|
|
816
|
+
this.failAll(this.msg("uploadIdMissing"));
|
|
723
817
|
return;
|
|
724
818
|
}
|
|
725
819
|
} else {
|
|
@@ -743,7 +837,7 @@ export default class Upload {
|
|
|
743
837
|
this.failAll(
|
|
744
838
|
(statusResult.body && statusResult.body.error) ||
|
|
745
839
|
statusResult.error ||
|
|
746
|
-
|
|
840
|
+
this.msg("statusFailed"),
|
|
747
841
|
);
|
|
748
842
|
return;
|
|
749
843
|
}
|
|
@@ -762,7 +856,7 @@ export default class Upload {
|
|
|
762
856
|
this.setProgress(Math.round((receivedSet.size / total) * 100));
|
|
763
857
|
this.patchItem(0, {
|
|
764
858
|
barStyle: `width:${Math.round((receivedSet.size / total) * 100)}%`,
|
|
765
|
-
meta: `${receivedSet.size}/${total}
|
|
859
|
+
meta: `${receivedSet.size}/${total}`,
|
|
766
860
|
});
|
|
767
861
|
for (let index = 0; index < total; index++) {
|
|
768
862
|
if (gen !== this._gen) return;
|
|
@@ -805,7 +899,7 @@ export default class Upload {
|
|
|
805
899
|
this.failAll(
|
|
806
900
|
(result.body && result.body.error) ||
|
|
807
901
|
result.error ||
|
|
808
|
-
|
|
902
|
+
this.msg("chunkFailed"),
|
|
809
903
|
);
|
|
810
904
|
return;
|
|
811
905
|
}
|
|
@@ -819,7 +913,7 @@ export default class Upload {
|
|
|
819
913
|
this.setProgress(pct);
|
|
820
914
|
this.patchItem(0, {
|
|
821
915
|
barStyle: `width:${pct}%`,
|
|
822
|
-
meta: `${receivedSet.size}/${total}
|
|
916
|
+
meta: `${receivedSet.size}/${total}`,
|
|
823
917
|
});
|
|
824
918
|
}
|
|
825
919
|
if (gen !== this._gen) return;
|
|
@@ -843,7 +937,7 @@ export default class Upload {
|
|
|
843
937
|
this.failAll(
|
|
844
938
|
(completeResult.body && completeResult.body.error) ||
|
|
845
939
|
completeResult.error ||
|
|
846
|
-
|
|
940
|
+
this.msg("completeFailed"),
|
|
847
941
|
);
|
|
848
942
|
return;
|
|
849
943
|
}
|
|
@@ -865,7 +959,7 @@ export default class Upload {
|
|
|
865
959
|
status: "done",
|
|
866
960
|
showBar: true,
|
|
867
961
|
barStyle: "width:100%",
|
|
868
|
-
meta: `${formatBytes(values[0].bytes)}
|
|
962
|
+
meta: `${formatBytes(values[0].bytes)} (${total})`,
|
|
869
963
|
});
|
|
870
964
|
this.resetSession();
|
|
871
965
|
this._values = values;
|
|
@@ -877,10 +971,10 @@ export default class Upload {
|
|
|
877
971
|
async runObject(gen) {
|
|
878
972
|
if (gen !== this._gen) return;
|
|
879
973
|
if (typeof this.onPresign !== "function") {
|
|
880
|
-
this.failAll("
|
|
974
|
+
this.failAll(this.msg("presignRequired"));
|
|
881
975
|
return;
|
|
882
976
|
}
|
|
883
|
-
this.setOverall("uploading", "
|
|
977
|
+
this.setOverall("uploading", this.msg("uploading"), true, true);
|
|
884
978
|
const values = [];
|
|
885
979
|
for (let i = 0; i < this._files.length; i++) {
|
|
886
980
|
if (gen !== this._gen) return;
|
|
@@ -894,13 +988,13 @@ export default class Upload {
|
|
|
894
988
|
try {
|
|
895
989
|
signed = await this.onPresign(file);
|
|
896
990
|
} catch (err) {
|
|
897
|
-
this.failAll(err instanceof Error ? err.message : String(err || "
|
|
991
|
+
this.failAll(err instanceof Error ? err.message : String(err || this.msg("presignFailed")));
|
|
898
992
|
return;
|
|
899
993
|
}
|
|
900
994
|
if (gen !== this._gen) return;
|
|
901
995
|
const url = signed && signed.uploadUrl ? String(signed.uploadUrl) : "";
|
|
902
996
|
if (!url) {
|
|
903
|
-
this.failAll("
|
|
997
|
+
this.failAll(this.msg("presignUrl"));
|
|
904
998
|
return;
|
|
905
999
|
}
|
|
906
1000
|
const xhr = new XMLHttpRequest();
|
|
@@ -927,7 +1021,7 @@ export default class Upload {
|
|
|
927
1021
|
}
|
|
928
1022
|
if (result.error || !(result.status >= 200 && result.status < 300)) {
|
|
929
1023
|
this.failAll(
|
|
930
|
-
result.error ||
|
|
1024
|
+
result.error || this.msg("objectFailed"),
|
|
931
1025
|
);
|
|
932
1026
|
return;
|
|
933
1027
|
}
|
|
@@ -945,7 +1039,7 @@ export default class Upload {
|
|
|
945
1039
|
status: "done",
|
|
946
1040
|
showBar: true,
|
|
947
1041
|
barStyle: "width:100%",
|
|
948
|
-
meta:
|
|
1042
|
+
meta: formatBytes(file.size),
|
|
949
1043
|
});
|
|
950
1044
|
}
|
|
951
1045
|
this._values = values;
|
|
@@ -957,7 +1051,7 @@ export default class Upload {
|
|
|
957
1051
|
finishOk(values) {
|
|
958
1052
|
this.setProgress(100);
|
|
959
1053
|
this.status = "done";
|
|
960
|
-
this.statusText = "
|
|
1054
|
+
this.statusText = this.msg("complete");
|
|
961
1055
|
this.showProgress = true;
|
|
962
1056
|
this.canCancel = false;
|
|
963
1057
|
this.canResume = false;
|
|
@@ -975,7 +1069,7 @@ export default class Upload {
|
|
|
975
1069
|
const chunkNote = first.chunks ? ` chunks:${first.chunks}` : "";
|
|
976
1070
|
this.resultText = `${prefix}:${first.id} (${first.bytes || 0} bytes)${head}${chunkNote}`;
|
|
977
1071
|
} else {
|
|
978
|
-
this.resultText = `${values.length}
|
|
1072
|
+
this.resultText = `${values.length} ${this.readyText}`.trim();
|
|
979
1073
|
}
|
|
980
1074
|
this.emitStatus();
|
|
981
1075
|
this.emitValue(values);
|
|
@@ -986,8 +1080,9 @@ export default class Upload {
|
|
|
986
1080
|
failAll(message) {
|
|
987
1081
|
this.cancelActive(false);
|
|
988
1082
|
this.resetSession();
|
|
1083
|
+
const text = message || this.msg("failed");
|
|
989
1084
|
this.status = "error";
|
|
990
|
-
this.statusText =
|
|
1085
|
+
this.statusText = text;
|
|
991
1086
|
this.showProgress = false;
|
|
992
1087
|
this.canCancel = false;
|
|
993
1088
|
this.canResume = false;
|
|
@@ -1006,7 +1101,7 @@ export default class Upload {
|
|
|
1006
1101
|
}
|
|
1007
1102
|
markCancelled() {
|
|
1008
1103
|
this.status = "cancelled";
|
|
1009
|
-
this.statusText = "
|
|
1104
|
+
this.statusText = this.msg("cancelled");
|
|
1010
1105
|
this.showProgress = false;
|
|
1011
1106
|
this.canCancel = false;
|
|
1012
1107
|
this.canResume = false;
|
|
@@ -1020,7 +1115,7 @@ export default class Upload {
|
|
|
1020
1115
|
}
|
|
1021
1116
|
markPaused() {
|
|
1022
1117
|
this.status = "paused";
|
|
1023
|
-
this.statusText = "
|
|
1118
|
+
this.statusText = this.msg("paused");
|
|
1024
1119
|
this.showProgress = true;
|
|
1025
1120
|
this.canCancel = false;
|
|
1026
1121
|
this.canResume = !!this._uploadId;
|
|
@@ -1031,7 +1126,7 @@ export default class Upload {
|
|
|
1031
1126
|
this.syncChunkAttr();
|
|
1032
1127
|
this.patchItem(0, {
|
|
1033
1128
|
status: "paused",
|
|
1034
|
-
meta: `${this._received.length}/${this._chunkTotal || 0}
|
|
1129
|
+
meta: `${this._received.length}/${this._chunkTotal || 0}`,
|
|
1035
1130
|
});
|
|
1036
1131
|
this.emitStatus();
|
|
1037
1132
|
this.emitValue([]);
|
|
@@ -1183,7 +1278,7 @@ function acceptError(file, accept) {
|
|
|
1183
1278
|
return "";
|
|
1184
1279
|
}
|
|
1185
1280
|
}
|
|
1186
|
-
return
|
|
1281
|
+
return "accept";
|
|
1187
1282
|
}
|
|
1188
1283
|
/**
|
|
1189
1284
|
* @param {number} n
|
|
@@ -1228,7 +1323,7 @@ function xhrSend(xhr, method, url, body, onProgress, headers) {
|
|
|
1228
1323
|
aborted: false,
|
|
1229
1324
|
status: 0,
|
|
1230
1325
|
body: null,
|
|
1231
|
-
error: "
|
|
1326
|
+
error: "",
|
|
1232
1327
|
});
|
|
1233
1328
|
xhr.onload = () => {
|
|
1234
1329
|
let parsed = null;
|
|
@@ -1274,7 +1369,7 @@ function xhrSendJson(xhr, method, url, payload) {
|
|
|
1274
1369
|
aborted: false,
|
|
1275
1370
|
status: 0,
|
|
1276
1371
|
body: null,
|
|
1277
|
-
error: "
|
|
1372
|
+
error: "",
|
|
1278
1373
|
});
|
|
1279
1374
|
xhr.onload = () => {
|
|
1280
1375
|
let parsed = null;
|