@v-c/upload 0.0.1

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.
@@ -0,0 +1,408 @@
1
+ import attrAccept_default from "./attrAccept.js";
2
+ import upload from "./request.js";
3
+ import traverseFileTree_default from "./traverseFileTree.js";
4
+ import uid from "./uid.js";
5
+ import { computed, createVNode, defineComponent, mergeProps, onMounted, onUnmounted, onUpdated, ref } from "vue";
6
+ import { clsx } from "@v-c/util";
7
+ import pickAttrs from "@v-c/util/dist/pickAttrs";
8
+ function noop() {}
9
+ var AjaxUploader_default = /* @__PURE__ */ defineComponent((props, { attrs, expose, slots }) => {
10
+ const uid$1 = ref(uid());
11
+ let _isMounted = false;
12
+ const reqs = {};
13
+ const fileInputRef = ref();
14
+ const cls = computed(() => {
15
+ const { prefixCls, disabled, className } = props;
16
+ return clsx({
17
+ [prefixCls]: true,
18
+ [`${prefixCls}-disabled`]: disabled,
19
+ [className]: className
20
+ });
21
+ });
22
+ const filterFile = (file, force = false) => {
23
+ const { accept, directory } = props;
24
+ let filterFn;
25
+ let acceptFormat;
26
+ if (typeof accept === "string") acceptFormat = accept;
27
+ else {
28
+ const { filter, format } = accept || {};
29
+ acceptFormat = format;
30
+ if (filter === "native") filterFn = () => true;
31
+ else filterFn = filter;
32
+ }
33
+ return (filterFn || (directory || force ? (currentFile) => attrAccept_default(currentFile, acceptFormat) : () => true))(file);
34
+ };
35
+ const onClick = (event) => {
36
+ if (!fileInputRef.value) return;
37
+ const target = event.target;
38
+ if (target && target.tagName === "BUTTON") {
39
+ fileInputRef.value.parentNode.focus();
40
+ target.blur();
41
+ }
42
+ fileInputRef.value.click();
43
+ if (props.onClick) props.onClick(event);
44
+ };
45
+ const onKeyDown = (e) => {
46
+ if (e.key === "Enter") onClick(e);
47
+ };
48
+ const post = ({ data, origin, action, parsedFile }) => {
49
+ if (!_isMounted) return;
50
+ const { onStart, customRequest, name, headers, withCredentials, method } = props;
51
+ const { uid: uid$2 } = origin;
52
+ const request = customRequest || upload;
53
+ const requestOption = {
54
+ action,
55
+ filename: name,
56
+ data,
57
+ file: parsedFile,
58
+ headers,
59
+ withCredentials,
60
+ method: method || "post",
61
+ onProgress: (e) => {
62
+ const { onProgress } = props;
63
+ onProgress?.(e, parsedFile);
64
+ },
65
+ onSuccess: (ret, xhr) => {
66
+ const { onSuccess } = props;
67
+ onSuccess?.(ret, parsedFile, xhr);
68
+ delete reqs[uid$2];
69
+ },
70
+ onError: (err, ret) => {
71
+ const { onError } = props;
72
+ onError?.(err, ret, parsedFile);
73
+ delete reqs[uid$2];
74
+ }
75
+ };
76
+ onStart?.(origin);
77
+ reqs[uid$2] = request(requestOption, { defaultRequest: upload });
78
+ };
79
+ const processFile = async (file, fileList) => {
80
+ const { beforeUpload } = props;
81
+ let transformedFile = file;
82
+ if (beforeUpload) {
83
+ try {
84
+ transformedFile = await beforeUpload(file, fileList);
85
+ } catch (e) {
86
+ transformedFile = false;
87
+ }
88
+ if (transformedFile === false) return {
89
+ origin: file,
90
+ parsedFile: null,
91
+ action: null,
92
+ data: null
93
+ };
94
+ }
95
+ const { action } = props;
96
+ let mergedAction;
97
+ if (typeof action === "function") mergedAction = await action(file);
98
+ else mergedAction = action;
99
+ const { data } = props;
100
+ let mergedData;
101
+ if (typeof data === "function") mergedData = await data(file);
102
+ else mergedData = data;
103
+ const parsedData = (typeof transformedFile === "object" || typeof transformedFile === "string") && transformedFile ? transformedFile : file;
104
+ let parsedFile;
105
+ if (parsedData instanceof File) parsedFile = parsedData;
106
+ else parsedFile = new File([parsedData], file.name, { type: file.type });
107
+ const mergedParsedFile = parsedFile;
108
+ mergedParsedFile.uid = file.uid;
109
+ return {
110
+ origin: file,
111
+ data: mergedData,
112
+ parsedFile: mergedParsedFile,
113
+ action: mergedAction
114
+ };
115
+ };
116
+ const uploadFiles = (files) => {
117
+ const originFiles = [...files];
118
+ const postFiles = originFiles.map((file) => {
119
+ file.uid = uid();
120
+ return processFile(file, originFiles);
121
+ });
122
+ Promise.all(postFiles).then((fileList) => {
123
+ const { onBatchStart } = props;
124
+ onBatchStart?.(fileList.map(({ origin, parsedFile }) => ({
125
+ file: origin,
126
+ parsedFile
127
+ })));
128
+ fileList.filter((file) => file.parsedFile !== null).forEach((file) => {
129
+ post(file);
130
+ });
131
+ });
132
+ };
133
+ const onDataTransferFiles = async (dataTransfer, existFileCallback) => {
134
+ if (!dataTransfer) return;
135
+ const { multiple, directory } = props;
136
+ const items = [...dataTransfer.items || []];
137
+ let files = [...dataTransfer.files || []];
138
+ if (files.length > 0 || items.some((item) => item.kind === "file")) existFileCallback?.();
139
+ if (directory) {
140
+ files = await traverseFileTree_default(Array.prototype.slice.call(items), (currentFile) => filterFile(currentFile));
141
+ uploadFiles(files);
142
+ } else {
143
+ let acceptFiles = [...files].filter((file) => filterFile(file, true));
144
+ if (multiple === false) acceptFiles = files.slice(0, 1);
145
+ uploadFiles(acceptFiles);
146
+ }
147
+ };
148
+ const onFileDrop = (e) => {
149
+ e.preventDefault();
150
+ if (e.type === "drop") {
151
+ const dataTransfer = e.dataTransfer;
152
+ return onDataTransferFiles(dataTransfer);
153
+ }
154
+ };
155
+ const onFileDragOver = (e) => {
156
+ e.preventDefault();
157
+ };
158
+ const reset = () => {
159
+ uid$1.value = uid();
160
+ };
161
+ const onChange = (e) => {
162
+ const { files } = e.target;
163
+ uploadFiles([...files || []].filter((file) => filterFile(file)));
164
+ reset();
165
+ };
166
+ const dirProps = computed(() => {
167
+ return props.directory ? {
168
+ directory: "directory",
169
+ webkitdirectory: "webkitdirectory"
170
+ } : {};
171
+ });
172
+ const abort = (file) => {
173
+ if (file) {
174
+ const uid$2 = file.uid ? file.uid : file;
175
+ if (reqs[uid$2] && reqs[uid$2].abort) reqs[uid$2].abort();
176
+ delete reqs[uid$2];
177
+ } else Object.keys(reqs).forEach((uid$2) => {
178
+ if (reqs[uid$2] && reqs[uid$2].abort) reqs[uid$2].abort();
179
+ delete reqs[uid$2];
180
+ });
181
+ };
182
+ const events = computed(() => {
183
+ return props.disabled ? {} : {
184
+ onClick: props.openFileDialogOnClick ? onClick : noop,
185
+ onKeyDown: props.openFileDialogOnClick ? onKeyDown : noop,
186
+ onMouseEnter: props.onMouseEnter,
187
+ onMouseLeave: props.onMouseLeave,
188
+ onDrop: onFileDrop,
189
+ onDragover: onFileDragOver,
190
+ tabIndex: props.hasControlInside ? void 0 : "0"
191
+ };
192
+ });
193
+ const onFilePaste = async (e) => {
194
+ const { pastable } = props;
195
+ if (!pastable) return;
196
+ if (e.type === "paste") {
197
+ const clipboardData = e.clipboardData;
198
+ return onDataTransferFiles(clipboardData, () => {
199
+ e.preventDefault();
200
+ });
201
+ }
202
+ };
203
+ let prevPastable;
204
+ onMounted(() => {
205
+ _isMounted = true;
206
+ if (props.pastable) document.addEventListener("paste", onFilePaste);
207
+ prevPastable = props.pastable;
208
+ });
209
+ onUpdated(() => {
210
+ const pastable = props.pastable;
211
+ if (pastable && !prevPastable) document.addEventListener("paste", onFilePaste);
212
+ else if (!pastable && prevPastable) document.removeEventListener("paste", onFilePaste);
213
+ prevPastable = pastable;
214
+ });
215
+ onUnmounted(() => {
216
+ _isMounted = false;
217
+ abort();
218
+ document.removeEventListener("paste", onFilePaste);
219
+ });
220
+ expose({ abort });
221
+ return () => {
222
+ const { component, prefixCls, className, classNames = {}, disabled, id, name, style, styles = {}, multiple, accept, capture, directory, openFileDialogOnClick, onMouseEnter, onMouseLeave, hasControlInside, ...otherProps } = {
223
+ ...props,
224
+ ...attrs
225
+ };
226
+ const acceptFormat = typeof accept === "string" ? accept : accept?.format;
227
+ return createVNode(component, mergeProps({ "class": cls.value }, events.value, {
228
+ "role": hasControlInside ? void 0 : "button",
229
+ "style": style
230
+ }), { default: () => [createVNode("input", mergeProps(pickAttrs(otherProps, {
231
+ aria: true,
232
+ data: true
233
+ }), {
234
+ "id": id,
235
+ "name": name,
236
+ "disabled": disabled,
237
+ "type": "file",
238
+ "ref": fileInputRef,
239
+ "onClick": (e) => e.stopPropagation(),
240
+ "key": uid$1.value,
241
+ "style": {
242
+ display: "none",
243
+ ...styles.input
244
+ },
245
+ "class": classNames.input
246
+ }, dirProps.value, {
247
+ "multiple": multiple,
248
+ "accept": acceptFormat,
249
+ "onChange": onChange
250
+ }, capture != null ? { capture } : {}), null), slots.default?.()] });
251
+ };
252
+ }, { props: {
253
+ name: {
254
+ type: String,
255
+ required: false,
256
+ default: void 0
257
+ },
258
+ style: {
259
+ type: Object,
260
+ required: false,
261
+ default: void 0
262
+ },
263
+ className: {
264
+ type: String,
265
+ required: false,
266
+ default: void 0
267
+ },
268
+ disabled: {
269
+ type: Boolean,
270
+ required: false,
271
+ default: void 0
272
+ },
273
+ component: {
274
+ type: [
275
+ Object,
276
+ Function,
277
+ String
278
+ ],
279
+ required: false,
280
+ default: void 0
281
+ },
282
+ action: {
283
+ type: [String, Function],
284
+ required: false,
285
+ default: void 0
286
+ },
287
+ method: {
288
+ type: String,
289
+ required: false,
290
+ default: void 0
291
+ },
292
+ directory: {
293
+ type: Boolean,
294
+ required: false,
295
+ default: void 0
296
+ },
297
+ data: {
298
+ type: [Object, Function],
299
+ required: false,
300
+ default: void 0
301
+ },
302
+ headers: {
303
+ type: Object,
304
+ required: false,
305
+ default: void 0
306
+ },
307
+ accept: {
308
+ type: [String, Object],
309
+ required: false,
310
+ default: void 0
311
+ },
312
+ multiple: {
313
+ type: Boolean,
314
+ required: false,
315
+ default: void 0
316
+ },
317
+ onBatchStart: {
318
+ type: Function,
319
+ required: false,
320
+ default: void 0
321
+ },
322
+ onStart: {
323
+ type: Function,
324
+ required: false,
325
+ default: void 0
326
+ },
327
+ onError: {
328
+ type: Function,
329
+ required: false,
330
+ default: void 0
331
+ },
332
+ onSuccess: {
333
+ type: Function,
334
+ required: false,
335
+ default: void 0
336
+ },
337
+ onProgress: {
338
+ type: Function,
339
+ required: false,
340
+ default: void 0
341
+ },
342
+ beforeUpload: {
343
+ type: Function,
344
+ required: false,
345
+ default: void 0
346
+ },
347
+ customRequest: {
348
+ type: Function,
349
+ required: false,
350
+ default: void 0
351
+ },
352
+ withCredentials: {
353
+ type: Boolean,
354
+ required: false,
355
+ default: void 0
356
+ },
357
+ openFileDialogOnClick: {
358
+ type: Boolean,
359
+ required: false,
360
+ default: void 0
361
+ },
362
+ prefixCls: {
363
+ type: String,
364
+ required: false,
365
+ default: void 0
366
+ },
367
+ id: {
368
+ type: String,
369
+ required: false,
370
+ default: void 0
371
+ },
372
+ onMouseEnter: {
373
+ type: Function,
374
+ required: false,
375
+ default: void 0
376
+ },
377
+ onMouseLeave: {
378
+ type: Function,
379
+ required: false,
380
+ default: void 0
381
+ },
382
+ onClick: {
383
+ type: Function,
384
+ required: false,
385
+ default: void 0
386
+ },
387
+ classNames: {
388
+ type: Object,
389
+ required: false,
390
+ default: void 0
391
+ },
392
+ styles: {
393
+ type: Object,
394
+ required: false,
395
+ default: void 0
396
+ },
397
+ hasControlInside: {
398
+ type: Boolean,
399
+ required: false,
400
+ default: void 0
401
+ },
402
+ pastable: {
403
+ type: Boolean,
404
+ required: false,
405
+ default: void 0
406
+ }
407
+ } });
408
+ export { AjaxUploader_default as default };
@@ -0,0 +1,196 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_rolldown_runtime = require("./_virtual/rolldown_runtime.cjs");
6
+ const require_AjaxUploader = require("./AjaxUploader.cjs");
7
+ let vue = require("vue");
8
+ function empty() {}
9
+ var defaults = {
10
+ component: "span",
11
+ prefixCls: "vc-upload",
12
+ data: {},
13
+ headers: {},
14
+ name: "file",
15
+ onStart: empty,
16
+ onError: empty,
17
+ onSuccess: empty,
18
+ multiple: false,
19
+ beforeUpload: void 0,
20
+ customRequest: void 0,
21
+ withCredentials: false,
22
+ openFileDialogOnClick: true,
23
+ hasControlInside: false
24
+ };
25
+ var Upload = /* @__PURE__ */ (0, vue.defineComponent)((props, { attrs, expose, slots }) => {
26
+ const uploaderRef = (0, vue.ref)();
27
+ const abort = (file) => {
28
+ uploaderRef.value?.abort(file);
29
+ };
30
+ expose({ abort });
31
+ const mergedProps = (0, vue.computed)(() => ({
32
+ ...defaults,
33
+ ...props
34
+ }));
35
+ return () => (0, vue.createVNode)(require_AjaxUploader.default, (0, vue.mergeProps)({ "ref": uploaderRef }, mergedProps.value, attrs), { default: () => [slots.default?.()] });
36
+ }, {
37
+ props: /* @__PURE__ */ (0, vue.mergeDefaults)({
38
+ name: {
39
+ type: String,
40
+ required: false,
41
+ default: void 0
42
+ },
43
+ style: {
44
+ type: Object,
45
+ required: false,
46
+ default: void 0
47
+ },
48
+ className: {
49
+ type: String,
50
+ required: false,
51
+ default: void 0
52
+ },
53
+ disabled: {
54
+ type: Boolean,
55
+ required: false,
56
+ default: void 0
57
+ },
58
+ component: {
59
+ type: [
60
+ Object,
61
+ Function,
62
+ String
63
+ ],
64
+ required: false,
65
+ default: void 0
66
+ },
67
+ action: {
68
+ type: [String, Function],
69
+ required: false,
70
+ default: void 0
71
+ },
72
+ method: {
73
+ type: String,
74
+ required: false,
75
+ default: void 0
76
+ },
77
+ directory: {
78
+ type: Boolean,
79
+ required: false,
80
+ default: void 0
81
+ },
82
+ data: {
83
+ type: [Object, Function],
84
+ required: false,
85
+ default: void 0
86
+ },
87
+ headers: {
88
+ type: Object,
89
+ required: false,
90
+ default: void 0
91
+ },
92
+ accept: {
93
+ type: [String, Object],
94
+ required: false,
95
+ default: void 0
96
+ },
97
+ multiple: {
98
+ type: Boolean,
99
+ required: false,
100
+ default: void 0
101
+ },
102
+ onBatchStart: {
103
+ type: Function,
104
+ required: false,
105
+ default: void 0
106
+ },
107
+ onStart: {
108
+ type: Function,
109
+ required: false,
110
+ default: void 0
111
+ },
112
+ onError: {
113
+ type: Function,
114
+ required: false,
115
+ default: void 0
116
+ },
117
+ onSuccess: {
118
+ type: Function,
119
+ required: false,
120
+ default: void 0
121
+ },
122
+ onProgress: {
123
+ type: Function,
124
+ required: false,
125
+ default: void 0
126
+ },
127
+ beforeUpload: {
128
+ type: Function,
129
+ required: false,
130
+ default: void 0
131
+ },
132
+ customRequest: {
133
+ type: Function,
134
+ required: false,
135
+ default: void 0
136
+ },
137
+ withCredentials: {
138
+ type: Boolean,
139
+ required: false,
140
+ default: void 0
141
+ },
142
+ openFileDialogOnClick: {
143
+ type: Boolean,
144
+ required: false,
145
+ default: void 0
146
+ },
147
+ prefixCls: {
148
+ type: String,
149
+ required: false,
150
+ default: void 0
151
+ },
152
+ id: {
153
+ type: String,
154
+ required: false,
155
+ default: void 0
156
+ },
157
+ onMouseEnter: {
158
+ type: Function,
159
+ required: false,
160
+ default: void 0
161
+ },
162
+ onMouseLeave: {
163
+ type: Function,
164
+ required: false,
165
+ default: void 0
166
+ },
167
+ onClick: {
168
+ type: Function,
169
+ required: false,
170
+ default: void 0
171
+ },
172
+ classNames: {
173
+ type: Object,
174
+ required: false,
175
+ default: void 0
176
+ },
177
+ styles: {
178
+ type: Object,
179
+ required: false,
180
+ default: void 0
181
+ },
182
+ hasControlInside: {
183
+ type: Boolean,
184
+ required: false,
185
+ default: void 0
186
+ },
187
+ pastable: {
188
+ type: Boolean,
189
+ required: false,
190
+ default: void 0
191
+ }
192
+ }, defaults),
193
+ name: "Upload"
194
+ });
195
+ var Upload_default = Upload;
196
+ exports.default = Upload_default;
@@ -0,0 +1,3 @@
1
+ import { UploadProps } from './interface';
2
+ declare const Upload: import('vue').DefineSetupFnComponent<UploadProps, {}, {}, UploadProps & {}, import('vue').PublicProps>;
3
+ export default Upload;