@eslamdevui/ui 3.3.2-beta.2 → 3.3.2-beta.3
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/.nuxt/ui/file-upload.ts +8 -37
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -2
- package/dist/runtime/components/FileUpload.vue +34 -262
- package/dist/runtime/components/FileUpload.vue.d.ts +10 -208
- package/dist/shared/{ui.DdcmBFzX.mjs → ui.CgUuvRXi.mjs} +8 -35
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +10 -11
package/.nuxt/ui/file-upload.ts
CHANGED
|
@@ -50,13 +50,7 @@ export default {
|
|
|
50
50
|
"fileWrapper": "flex flex-col min-w-0",
|
|
51
51
|
"fileName": "text-default truncate",
|
|
52
52
|
"fileSize": "text-muted truncate",
|
|
53
|
-
"
|
|
54
|
-
"fileProgressText": "text-xs text-muted whitespace-nowrap",
|
|
55
|
-
"fileError": "text-xs text-red-500 mt-1",
|
|
56
|
-
"fileActions": "flex items-center gap-1",
|
|
57
|
-
"fileTrailingButton": "",
|
|
58
|
-
"fileUploadButton": "",
|
|
59
|
-
"fileCancelButton": ""
|
|
53
|
+
"fileTrailingButton": ""
|
|
60
54
|
},
|
|
61
55
|
"variants": {
|
|
62
56
|
"color": {
|
|
@@ -110,15 +104,12 @@ export default {
|
|
|
110
104
|
"root": "gap-2 items-start",
|
|
111
105
|
"files": "flex flex-col w-full gap-2",
|
|
112
106
|
"file": "min-w-0 flex items-center border border-default rounded-md w-full",
|
|
113
|
-
"
|
|
107
|
+
"fileTrailingButton": "ms-auto"
|
|
114
108
|
},
|
|
115
109
|
"grid": {
|
|
116
110
|
"fileWrapper": "hidden",
|
|
117
111
|
"fileLeadingAvatar": "size-full rounded-lg",
|
|
118
|
-
"
|
|
119
|
-
"fileTrailingButton": "p-0 rounded-full border-2 border-bg",
|
|
120
|
-
"fileUploadButton": "p-0 rounded-full border-2 border-bg",
|
|
121
|
-
"fileCancelButton": "p-0 rounded-full border-2 border-bg"
|
|
112
|
+
"fileTrailingButton": "absolute -top-1.5 -end-1.5 p-0 rounded-full border-2 border-bg"
|
|
122
113
|
}
|
|
123
114
|
},
|
|
124
115
|
"position": {
|
|
@@ -139,9 +130,6 @@ export default {
|
|
|
139
130
|
},
|
|
140
131
|
"disabled": {
|
|
141
132
|
"true": "cursor-not-allowed opacity-75"
|
|
142
|
-
},
|
|
143
|
-
"showProgress": {
|
|
144
|
-
"true": ""
|
|
145
133
|
}
|
|
146
134
|
},
|
|
147
135
|
"compoundVariants": [
|
|
@@ -212,35 +200,35 @@ export default {
|
|
|
212
200
|
"size": "xs" as typeof size[number],
|
|
213
201
|
"layout": "list" as typeof layout[number],
|
|
214
202
|
"class": {
|
|
215
|
-
"
|
|
203
|
+
"fileTrailingButton": "-me-1"
|
|
216
204
|
}
|
|
217
205
|
},
|
|
218
206
|
{
|
|
219
207
|
"size": "sm" as typeof size[number],
|
|
220
208
|
"layout": "list" as typeof layout[number],
|
|
221
209
|
"class": {
|
|
222
|
-
"
|
|
210
|
+
"fileTrailingButton": "-me-1.5"
|
|
223
211
|
}
|
|
224
212
|
},
|
|
225
213
|
{
|
|
226
214
|
"size": "md" as typeof size[number],
|
|
227
215
|
"layout": "list" as typeof layout[number],
|
|
228
216
|
"class": {
|
|
229
|
-
"
|
|
217
|
+
"fileTrailingButton": "-me-1.5"
|
|
230
218
|
}
|
|
231
219
|
},
|
|
232
220
|
{
|
|
233
221
|
"size": "lg" as typeof size[number],
|
|
234
222
|
"layout": "list" as typeof layout[number],
|
|
235
223
|
"class": {
|
|
236
|
-
"
|
|
224
|
+
"fileTrailingButton": "-me-2"
|
|
237
225
|
}
|
|
238
226
|
},
|
|
239
227
|
{
|
|
240
228
|
"size": "xl" as typeof size[number],
|
|
241
229
|
"layout": "list" as typeof layout[number],
|
|
242
230
|
"class": {
|
|
243
|
-
"
|
|
231
|
+
"fileTrailingButton": "-me-2"
|
|
244
232
|
}
|
|
245
233
|
},
|
|
246
234
|
{
|
|
@@ -297,23 +285,6 @@ export default {
|
|
|
297
285
|
"interactive": true,
|
|
298
286
|
"disabled": false,
|
|
299
287
|
"class": "hover:bg-elevated/25"
|
|
300
|
-
},
|
|
301
|
-
{
|
|
302
|
-
"showProgress": true,
|
|
303
|
-
"layout": "list" as typeof layout[number],
|
|
304
|
-
"class": {
|
|
305
|
-
"fileWrapper": "flex-col",
|
|
306
|
-
"fileProgress": "w-full"
|
|
307
|
-
}
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
"showProgress": true,
|
|
311
|
-
"layout": "grid" as typeof layout[number],
|
|
312
|
-
"class": {
|
|
313
|
-
"fileWrapper": "absolute inset-0 bg-black/50 flex flex-col items-center justify-center rounded-lg",
|
|
314
|
-
"fileProgress": "w-3/4",
|
|
315
|
-
"fileProgressText": "text-white font-medium"
|
|
316
|
-
}
|
|
317
288
|
}
|
|
318
289
|
],
|
|
319
290
|
"defaultVariants": {
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, hasNuxtModule, addComponentsDir, addImportsDir, installModule } from '@nuxt/kit';
|
|
2
2
|
import { defu } from 'defu';
|
|
3
|
-
import { d as defaultOptions, r as resolveColors, a as getDefaultUiConfig, b as addTemplates } from './shared/ui.
|
|
3
|
+
import { d as defaultOptions, r as resolveColors, a as getDefaultUiConfig, b as addTemplates } from './shared/ui.CgUuvRXi.mjs';
|
|
4
4
|
import '../dist/runtime/utils/index.js';
|
|
5
5
|
import 'node:url';
|
|
6
6
|
import 'scule';
|
|
@@ -8,7 +8,7 @@ import 'tailwindcss/colors';
|
|
|
8
8
|
import 'knitwork';
|
|
9
9
|
|
|
10
10
|
const name = "@eslamdevui/ui";
|
|
11
|
-
const version = "3.3.2-beta.
|
|
11
|
+
const version = "3.3.2-beta.3";
|
|
12
12
|
|
|
13
13
|
function generateProseComponentMap(components) {
|
|
14
14
|
return components.reduce((map, component) => {
|
|
@@ -3,7 +3,7 @@ import theme from "#build/ui/file-upload";
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<script setup>
|
|
6
|
-
import { computed, watch
|
|
6
|
+
import { computed, watch } from "vue";
|
|
7
7
|
import { Primitive } from "reka-ui";
|
|
8
8
|
import { createReusableTemplate } from "@vueuse/core";
|
|
9
9
|
import { useAppConfig } from "#imports";
|
|
@@ -13,7 +13,6 @@ import { tv } from "../utils/tv";
|
|
|
13
13
|
import UAvatar from "./Avatar.vue";
|
|
14
14
|
import UButton from "./Button.vue";
|
|
15
15
|
import UIcon from "./Icon.vue";
|
|
16
|
-
import UProgress from "./Progress.vue";
|
|
17
16
|
defineOptions({ inheritAttrs: false });
|
|
18
17
|
const props = defineProps({
|
|
19
18
|
as: { type: null, required: false },
|
|
@@ -38,28 +37,20 @@ const props = defineProps({
|
|
|
38
37
|
fileIcon: { type: String, required: false },
|
|
39
38
|
fileDelete: { type: [Boolean, Object], required: false },
|
|
40
39
|
fileDeleteIcon: { type: String, required: false },
|
|
41
|
-
showProgress: { type: Boolean, required: false, default: false },
|
|
42
|
-
allowCancel: { type: Boolean, required: false, default: true },
|
|
43
|
-
uploadFn: { type: Function, required: false },
|
|
44
|
-
autoUpload: { type: Boolean, required: false, default: false },
|
|
45
|
-
uploadTimeout: { type: Number, required: false, default: 3e4 },
|
|
46
|
-
maxConcurrentUploads: { type: Number, required: false, default: 3 },
|
|
47
40
|
class: { type: null, required: false },
|
|
48
41
|
ui: { type: null, required: false }
|
|
49
42
|
});
|
|
50
|
-
const emits = defineEmits(["update:modelValue", "change"
|
|
43
|
+
const emits = defineEmits(["update:modelValue", "change"]);
|
|
51
44
|
const slots = defineSlots();
|
|
52
45
|
const modelValue = defineModel({ type: null });
|
|
53
46
|
const appConfig = useAppConfig();
|
|
54
|
-
const activeUploads = ref(0);
|
|
55
|
-
const uploadQueue = ref([]);
|
|
56
47
|
const [DefineFilesTemplate, ReuseFilesTemplate] = createReusableTemplate();
|
|
57
48
|
const { isDragging, open, inputRef, dropzoneRef } = useFileUpload({
|
|
58
49
|
accept: props.accept,
|
|
59
50
|
reset: props.reset,
|
|
60
51
|
multiple: props.multiple,
|
|
61
52
|
dropzone: props.dropzone,
|
|
62
|
-
onUpdate
|
|
53
|
+
onUpdate
|
|
63
54
|
});
|
|
64
55
|
const { emitFormInput, emitFormChange, id, name, disabled, ariaAttrs } = useFormField(props);
|
|
65
56
|
const variant = computed(() => props.multiple ? "area" : props.variant);
|
|
@@ -73,9 +64,6 @@ const position = computed(() => {
|
|
|
73
64
|
}
|
|
74
65
|
return props.position;
|
|
75
66
|
});
|
|
76
|
-
const shouldShowProgress = computed(() => {
|
|
77
|
-
return props.showProgress || props.autoUpload;
|
|
78
|
-
});
|
|
79
67
|
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.fileUpload || {} })({
|
|
80
68
|
dropzone: props.dropzone,
|
|
81
69
|
interactive: props.interactive,
|
|
@@ -86,8 +74,7 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.fileUpload ||
|
|
|
86
74
|
position: position.value,
|
|
87
75
|
multiple: props.multiple,
|
|
88
76
|
highlight: props.highlight,
|
|
89
|
-
disabled: props.disabled
|
|
90
|
-
showProgress: shouldShowProgress.value
|
|
77
|
+
disabled: props.disabled
|
|
91
78
|
}));
|
|
92
79
|
function createObjectUrl(file) {
|
|
93
80
|
return URL.createObjectURL(file);
|
|
@@ -103,265 +90,77 @@ function formatFileSize(bytes) {
|
|
|
103
90
|
const formattedSize = i === 0 ? size.toString() : size.toFixed(0);
|
|
104
91
|
return `${formattedSize}${sizes[i]}`;
|
|
105
92
|
}
|
|
106
|
-
function
|
|
107
|
-
return {
|
|
108
|
-
file,
|
|
109
|
-
progress: 0,
|
|
110
|
-
uploading: false,
|
|
111
|
-
error: void 0,
|
|
112
|
-
abortController: void 0
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
async function onFileUpdate(files, reset = false) {
|
|
116
|
-
const fileUploads = files.map(createFileUploadObject);
|
|
93
|
+
function onUpdate(files, reset = false) {
|
|
117
94
|
if (props.multiple) {
|
|
118
95
|
if (reset) {
|
|
119
|
-
modelValue.value =
|
|
96
|
+
modelValue.value = files;
|
|
120
97
|
} else {
|
|
121
98
|
const existingFiles = modelValue.value || [];
|
|
122
|
-
modelValue.value = [...existingFiles, ...
|
|
99
|
+
modelValue.value = [...existingFiles, ...files || []];
|
|
123
100
|
}
|
|
124
101
|
} else {
|
|
125
|
-
modelValue.value =
|
|
102
|
+
modelValue.value = files?.[0];
|
|
126
103
|
}
|
|
127
104
|
const event = new Event("change", { target: { value: modelValue.value } });
|
|
128
105
|
emits("change", event);
|
|
129
106
|
emitFormChange();
|
|
130
107
|
emitFormInput();
|
|
131
|
-
if (props.autoUpload && props.uploadFn) {
|
|
132
|
-
await nextTick();
|
|
133
|
-
const newFiles = props.multiple ? fileUploads : fileUploads[0] ? [fileUploads[0]] : [];
|
|
134
|
-
for (let i = 0; i < newFiles.length; i++) {
|
|
135
|
-
const actualIndex = props.multiple && !reset ? (modelValue.value?.length || 0) - newFiles.length + i : i;
|
|
136
|
-
if (props.multiple) {
|
|
137
|
-
if (newFiles[i]) {
|
|
138
|
-
queueUpload(actualIndex, newFiles[i]);
|
|
139
|
-
}
|
|
140
|
-
} else {
|
|
141
|
-
uploadFile(actualIndex);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
function queueUpload(index, fileUpload) {
|
|
147
|
-
if (!props.multiple) {
|
|
148
|
-
uploadFile(index);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (activeUploads.value < props.maxConcurrentUploads) {
|
|
152
|
-
uploadFile(index);
|
|
153
|
-
} else {
|
|
154
|
-
uploadQueue.value.push({ index, fileUpload });
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function processUploadQueue() {
|
|
158
|
-
while (uploadQueue.value.length > 0 && activeUploads.value < props.maxConcurrentUploads) {
|
|
159
|
-
const queueItem = uploadQueue.value.shift();
|
|
160
|
-
if (queueItem) {
|
|
161
|
-
uploadFile(queueItem.index);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
108
|
}
|
|
165
109
|
function removeFile(index) {
|
|
166
110
|
if (!modelValue.value) {
|
|
167
111
|
return;
|
|
168
112
|
}
|
|
169
113
|
if (!props.multiple || index === void 0) {
|
|
170
|
-
|
|
171
|
-
if (singleFile.abortController) {
|
|
172
|
-
singleFile.abortController.abort();
|
|
173
|
-
}
|
|
174
|
-
onFileUpdate([], true);
|
|
114
|
+
onUpdate([], true);
|
|
175
115
|
return;
|
|
176
116
|
}
|
|
177
117
|
const files = [...modelValue.value];
|
|
178
|
-
const file = files[index];
|
|
179
|
-
if (file?.abortController) {
|
|
180
|
-
file.abortController.abort();
|
|
181
|
-
}
|
|
182
|
-
uploadQueue.value = uploadQueue.value.filter((item) => item.index !== index);
|
|
183
118
|
files.splice(index, 1);
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
async function uploadFile(index) {
|
|
187
|
-
if (!props.uploadFn || !modelValue.value) return;
|
|
188
|
-
const files = props.multiple ? modelValue.value : [modelValue.value];
|
|
189
|
-
const fileUpload = files[index];
|
|
190
|
-
if (!fileUpload || fileUpload.uploading) return;
|
|
191
|
-
activeUploads.value++;
|
|
192
|
-
const abortController = new AbortController();
|
|
193
|
-
fileUpload.abortController = abortController;
|
|
194
|
-
fileUpload.uploading = true;
|
|
195
|
-
fileUpload.progress = 0;
|
|
196
|
-
fileUpload.error = void 0;
|
|
197
|
-
emits("upload:start", fileUpload, index);
|
|
198
|
-
const timeoutId = setTimeout(() => {
|
|
199
|
-
if (!abortController.signal.aborted) {
|
|
200
|
-
abortController.abort();
|
|
201
|
-
}
|
|
202
|
-
}, props.uploadTimeout);
|
|
203
|
-
try {
|
|
204
|
-
const result = await props.uploadFn(
|
|
205
|
-
fileUpload.file,
|
|
206
|
-
(progress) => {
|
|
207
|
-
fileUpload.progress = Math.min(100, Math.max(0, progress));
|
|
208
|
-
emits("upload:progress", fileUpload, fileUpload.progress, index);
|
|
209
|
-
},
|
|
210
|
-
abortController.signal
|
|
211
|
-
);
|
|
212
|
-
clearTimeout(timeoutId);
|
|
213
|
-
fileUpload.uploading = false;
|
|
214
|
-
fileUpload.progress = 100;
|
|
215
|
-
emits("upload:success", fileUpload, result, index);
|
|
216
|
-
} catch (error) {
|
|
217
|
-
clearTimeout(timeoutId);
|
|
218
|
-
fileUpload.uploading = false;
|
|
219
|
-
if (abortController.signal.aborted) {
|
|
220
|
-
emits("upload:cancel", fileUpload, index);
|
|
221
|
-
} else {
|
|
222
|
-
fileUpload.error = error instanceof Error ? error.message : "Upload failed";
|
|
223
|
-
emits("upload:error", fileUpload, fileUpload.error, index);
|
|
224
|
-
}
|
|
225
|
-
} finally {
|
|
226
|
-
fileUpload.abortController = void 0;
|
|
227
|
-
activeUploads.value--;
|
|
228
|
-
if (props.multiple) {
|
|
229
|
-
processUploadQueue();
|
|
230
|
-
}
|
|
231
|
-
if (props.multiple && activeUploads.value === 0 && uploadQueue.value.length === 0) {
|
|
232
|
-
emits("upload:complete", files);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
function cancelUpload(index) {
|
|
237
|
-
if (!modelValue.value) return;
|
|
238
|
-
const files = props.multiple ? modelValue.value : [modelValue.value];
|
|
239
|
-
const fileUpload = files[index];
|
|
240
|
-
if (fileUpload?.abortController) {
|
|
241
|
-
fileUpload.abortController.abort();
|
|
242
|
-
}
|
|
243
|
-
uploadQueue.value = uploadQueue.value.filter((item) => item.index !== index);
|
|
244
|
-
}
|
|
245
|
-
function shouldShowFileProgress(fileUpload) {
|
|
246
|
-
return shouldShowProgress.value && (fileUpload.uploading || (fileUpload.progress ?? 0) > 0 || !!fileUpload.error);
|
|
119
|
+
onUpdate(files, true);
|
|
247
120
|
}
|
|
248
121
|
watch(modelValue, (newValue) => {
|
|
249
122
|
const hasModelReset = !Array.isArray(newValue) || !newValue.length;
|
|
250
123
|
if (hasModelReset && inputRef.value) {
|
|
251
124
|
inputRef.value.value = "";
|
|
252
|
-
uploadQueue.value = [];
|
|
253
|
-
activeUploads.value = 0;
|
|
254
125
|
}
|
|
255
126
|
});
|
|
256
127
|
defineExpose({
|
|
257
128
|
inputRef,
|
|
258
|
-
dropzoneRef
|
|
259
|
-
uploadFile,
|
|
260
|
-
cancelUpload,
|
|
261
|
-
activeUploads: readonly(activeUploads),
|
|
262
|
-
uploadQueue: readonly(uploadQueue)
|
|
129
|
+
dropzoneRef
|
|
263
130
|
});
|
|
264
131
|
</script>
|
|
265
132
|
|
|
266
133
|
<template>
|
|
267
134
|
<DefineFilesTemplate>
|
|
268
135
|
<template v-if="modelValue && (Array.isArray(modelValue) ? modelValue.length : true)">
|
|
269
|
-
<slot
|
|
270
|
-
name="files-top"
|
|
271
|
-
:files="modelValue"
|
|
272
|
-
:open="open"
|
|
273
|
-
:remove-file="removeFile"
|
|
274
|
-
:upload-file="uploadFile"
|
|
275
|
-
:cancel-upload="cancelUpload"
|
|
276
|
-
/>
|
|
136
|
+
<slot name="files-top" :files="modelValue" :open="open" :remove-file="removeFile" />
|
|
277
137
|
|
|
278
138
|
<div :class="ui.files({ class: props.ui?.files })">
|
|
279
139
|
<slot name="files" :files="modelValue">
|
|
280
|
-
<div
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
>
|
|
285
|
-
<slot name="file" :file-upload="fileUpload" :index="index">
|
|
286
|
-
<slot name="file-leading" :file-upload="fileUpload" :index="index">
|
|
287
|
-
<UAvatar
|
|
288
|
-
:src="createObjectUrl(fileUpload.file)"
|
|
289
|
-
:icon="fileIcon || appConfig.ui.icons.file"
|
|
290
|
-
:size="props.size"
|
|
291
|
-
:class="ui.fileLeadingAvatar({ class: props.ui?.fileLeadingAvatar })"
|
|
292
|
-
/>
|
|
140
|
+
<div v-for="(file, index) in Array.isArray(modelValue) ? modelValue : [modelValue]" :key="file.name" :class="ui.file({ class: props.ui?.file })">
|
|
141
|
+
<slot name="file" :file="file" :index="index">
|
|
142
|
+
<slot name="file-leading" :file="file" :index="index">
|
|
143
|
+
<UAvatar :src="createObjectUrl(file)" :icon="fileIcon || appConfig.ui.icons.file" :size="props.size" :class="ui.fileLeadingAvatar({ class: props.ui?.fileLeadingAvatar })" />
|
|
293
144
|
</slot>
|
|
294
145
|
|
|
295
146
|
<div :class="ui.fileWrapper({ class: props.ui?.fileWrapper })">
|
|
296
147
|
<span :class="ui.fileName({ class: props.ui?.fileName })">
|
|
297
|
-
<slot name="file-name" :file
|
|
298
|
-
{{
|
|
148
|
+
<slot name="file-name" :file="file" :index="index">
|
|
149
|
+
{{ file.name }}
|
|
299
150
|
</slot>
|
|
300
151
|
</span>
|
|
301
152
|
|
|
302
153
|
<span :class="ui.fileSize({ class: props.ui?.fileSize })">
|
|
303
|
-
<slot name="file-size" :file
|
|
304
|
-
{{ formatFileSize(
|
|
154
|
+
<slot name="file-size" :file="file" :index="index">
|
|
155
|
+
{{ formatFileSize(file.size) }}
|
|
305
156
|
</slot>
|
|
306
157
|
</span>
|
|
307
|
-
|
|
308
|
-
<!-- Progress bar - Now shows automatically when autoUpload is true -->
|
|
309
|
-
<div
|
|
310
|
-
v-if="shouldShowFileProgress(fileUpload)"
|
|
311
|
-
:class="ui.fileProgress({ class: props.ui?.fileProgress })"
|
|
312
|
-
>
|
|
313
|
-
<slot name="file-progress" :file-upload="fileUpload" :index="index">
|
|
314
|
-
<UProgress
|
|
315
|
-
:model-value="fileUpload.progress || 0"
|
|
316
|
-
:color="fileUpload.error ? 'error' : color"
|
|
317
|
-
:size="size === 'xs' ? 'xs' : 'sm'"
|
|
318
|
-
/>
|
|
319
|
-
<span :class="ui.fileProgressText({ class: props.ui?.fileProgressText })">
|
|
320
|
-
{{ Math.round(fileUpload.progress || 0) }}%
|
|
321
|
-
</span>
|
|
322
|
-
</slot>
|
|
323
|
-
</div>
|
|
324
|
-
|
|
325
|
-
<!-- Error message -->
|
|
326
|
-
<div v-if="fileUpload.error" :class="ui.fileError({ class: props.ui?.fileError })">
|
|
327
|
-
{{ fileUpload.error }}
|
|
328
|
-
</div>
|
|
329
|
-
|
|
330
|
-
<!-- Upload status indicator -->
|
|
331
|
-
<div v-if="autoUpload && fileUpload.uploading" class="text-xs text-gray-500 mt-1">
|
|
332
|
-
Uploading...
|
|
333
|
-
</div>
|
|
334
158
|
</div>
|
|
335
159
|
|
|
336
|
-
<slot name="file-trailing" :file
|
|
337
|
-
<
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
v-if="uploadFn && !autoUpload && !fileUpload.uploading && !(fileUpload.progress ?? 0)"
|
|
341
|
-
color="primary"
|
|
342
|
-
variant="ghost"
|
|
343
|
-
:size="layout === 'grid' ? 'xs' : size"
|
|
344
|
-
:trailing-icon="appConfig.ui.icons.upload || 'i-lucide-upload'"
|
|
345
|
-
:class="ui.fileUploadButton({ class: props.ui?.fileUploadButton })"
|
|
346
|
-
@click.stop.prevent="uploadFile(index)"
|
|
347
|
-
/>
|
|
348
|
-
|
|
349
|
-
<!-- Cancel button (during upload) -->
|
|
350
|
-
<UButton
|
|
351
|
-
v-if="allowCancel && fileUpload.uploading"
|
|
352
|
-
color="neutral"
|
|
353
|
-
variant="ghost"
|
|
354
|
-
:size="layout === 'grid' ? 'xs' : size"
|
|
355
|
-
:trailing-icon="appConfig.ui.icons.close || 'i-lucide-x'"
|
|
356
|
-
:class="ui.fileCancelButton({ class: props.ui?.fileCancelButton })"
|
|
357
|
-
@click.stop.prevent="cancelUpload(index)"
|
|
358
|
-
/>
|
|
359
|
-
|
|
360
|
-
<!-- Delete button -->
|
|
361
|
-
<UButton
|
|
362
|
-
v-if="!fileUpload.uploading"
|
|
363
|
-
color="neutral"
|
|
364
|
-
v-bind="{
|
|
160
|
+
<slot name="file-trailing" :file="file" :index="index">
|
|
161
|
+
<UButton
|
|
162
|
+
color="neutral"
|
|
163
|
+
v-bind="{
|
|
365
164
|
...layout === 'grid' ? {
|
|
366
165
|
variant: 'solid',
|
|
367
166
|
size: 'xs'
|
|
@@ -371,30 +170,22 @@ defineExpose({
|
|
|
371
170
|
},
|
|
372
171
|
...typeof fileDelete === 'object' ? fileDelete : void 0
|
|
373
172
|
}"
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
</div>
|
|
173
|
+
:trailing-icon="fileDeleteIcon || appConfig.ui.icons.close"
|
|
174
|
+
:class="ui.fileTrailingButton({ class: props.ui?.fileTrailingButton })"
|
|
175
|
+
@click.stop.prevent="removeFile(index)"
|
|
176
|
+
/>
|
|
379
177
|
</slot>
|
|
380
178
|
</slot>
|
|
381
179
|
</div>
|
|
382
180
|
</slot>
|
|
383
181
|
</div>
|
|
384
182
|
|
|
385
|
-
<slot
|
|
386
|
-
name="files-bottom"
|
|
387
|
-
:files="modelValue"
|
|
388
|
-
:open="open"
|
|
389
|
-
:remove-file="removeFile"
|
|
390
|
-
:upload-file="uploadFile"
|
|
391
|
-
:cancel-upload="cancelUpload"
|
|
392
|
-
/>
|
|
183
|
+
<slot name="files-bottom" :files="modelValue" :open="open" :remove-file="removeFile" />
|
|
393
184
|
</template>
|
|
394
185
|
</DefineFilesTemplate>
|
|
395
186
|
|
|
396
187
|
<Primitive :as="as" :class="ui.root({ class: [props.ui?.root, props.class] })">
|
|
397
|
-
<slot :open="open" :remove-file="removeFile"
|
|
188
|
+
<slot :open="open" :remove-file="removeFile">
|
|
398
189
|
<component
|
|
399
190
|
:is="variant === 'button' ? 'button' : 'div'"
|
|
400
191
|
ref="dropzoneRef"
|
|
@@ -406,22 +197,10 @@ defineExpose({
|
|
|
406
197
|
>
|
|
407
198
|
<ReuseFilesTemplate v-if="position === 'inside'" />
|
|
408
199
|
|
|
409
|
-
<div
|
|
410
|
-
v-if="position === 'inside' ? multiple ? !modelValue?.length : !modelValue : true"
|
|
411
|
-
:class="ui.wrapper({ class: props.ui?.wrapper })"
|
|
412
|
-
>
|
|
200
|
+
<div v-if="position === 'inside' ? multiple ? !modelValue?.length : !modelValue : true" :class="ui.wrapper({ class: props.ui?.wrapper })">
|
|
413
201
|
<slot name="leading">
|
|
414
|
-
<UIcon
|
|
415
|
-
|
|
416
|
-
:name="icon || appConfig.ui.icons.upload"
|
|
417
|
-
:class="ui.icon({ class: props.ui?.icon })"
|
|
418
|
-
/>
|
|
419
|
-
<UAvatar
|
|
420
|
-
v-else
|
|
421
|
-
:icon="icon || appConfig.ui.icons.upload"
|
|
422
|
-
:size="props.size"
|
|
423
|
-
:class="ui.avatar({ class: props.ui?.avatar })"
|
|
424
|
-
/>
|
|
202
|
+
<UIcon v-if="variant === 'button'" :name="icon || appConfig.ui.icons.upload" :class="ui.icon({ class: props.ui?.icon })" />
|
|
203
|
+
<UAvatar v-else :icon="icon || appConfig.ui.icons.upload" :size="props.size" :class="ui.avatar({ class: props.ui?.avatar })" />
|
|
425
204
|
</slot>
|
|
426
205
|
|
|
427
206
|
<template v-if="variant !== 'button'">
|
|
@@ -437,14 +216,7 @@ defineExpose({
|
|
|
437
216
|
</div>
|
|
438
217
|
|
|
439
218
|
<div v-if="!!slots.actions" :class="ui.actions({ class: props.ui?.actions })">
|
|
440
|
-
<slot
|
|
441
|
-
name="actions"
|
|
442
|
-
:files="modelValue"
|
|
443
|
-
:open="open"
|
|
444
|
-
:remove-file="removeFile"
|
|
445
|
-
:upload-file="uploadFile"
|
|
446
|
-
:cancel-upload="cancelUpload"
|
|
447
|
-
/>
|
|
219
|
+
<slot name="actions" :files="modelValue" :open="open" :remove-file="removeFile" />
|
|
448
220
|
</div>
|
|
449
221
|
</template>
|
|
450
222
|
</div>
|
|
@@ -4,13 +4,6 @@ import theme from '#build/ui/file-upload';
|
|
|
4
4
|
import type { ButtonProps } from '../types';
|
|
5
5
|
import type { ComponentConfig } from '../types/utils';
|
|
6
6
|
type FileUpload = ComponentConfig<typeof theme, AppConfig, 'fileUpload'>;
|
|
7
|
-
export interface FileUploadFile {
|
|
8
|
-
file: File;
|
|
9
|
-
progress?: number;
|
|
10
|
-
uploading?: boolean;
|
|
11
|
-
error?: string;
|
|
12
|
-
abortController?: AbortController;
|
|
13
|
-
}
|
|
14
7
|
export interface FileUploadProps<M extends boolean = false> {
|
|
15
8
|
/**
|
|
16
9
|
* The element or component this component should render as.
|
|
@@ -96,55 +89,18 @@ export interface FileUploadProps<M extends boolean = false> {
|
|
|
96
89
|
* @IconifyIcon
|
|
97
90
|
*/
|
|
98
91
|
fileDeleteIcon?: string;
|
|
99
|
-
/**
|
|
100
|
-
* Enable upload progress tracking
|
|
101
|
-
* @defaultValue false
|
|
102
|
-
*/
|
|
103
|
-
showProgress?: boolean;
|
|
104
|
-
/**
|
|
105
|
-
* Allow cancelling uploads in progress
|
|
106
|
-
* @defaultValue true
|
|
107
|
-
*/
|
|
108
|
-
allowCancel?: boolean;
|
|
109
|
-
/**
|
|
110
|
-
* Upload function that returns a promise with progress callback
|
|
111
|
-
*/
|
|
112
|
-
uploadFn?: (file: File, onProgress: (progress: number) => void, signal?: AbortSignal) => Promise<any>;
|
|
113
|
-
/**
|
|
114
|
-
* Auto-start upload when files are selected
|
|
115
|
-
* @defaultValue false
|
|
116
|
-
*/
|
|
117
|
-
autoUpload?: boolean;
|
|
118
|
-
/**
|
|
119
|
-
* Upload timeout in milliseconds
|
|
120
|
-
* @defaultValue 30000
|
|
121
|
-
*/
|
|
122
|
-
uploadTimeout?: number;
|
|
123
|
-
/**
|
|
124
|
-
* Max concurrent uploads when multiple is true
|
|
125
|
-
* @defaultValue 3
|
|
126
|
-
*/
|
|
127
|
-
maxConcurrentUploads?: number;
|
|
128
92
|
class?: any;
|
|
129
93
|
ui?: FileUpload['slots'];
|
|
130
94
|
}
|
|
131
95
|
export interface FileUploadEmits<M extends boolean = false> {
|
|
132
|
-
'update:modelValue': [payload: M extends true ?
|
|
96
|
+
'update:modelValue': [payload: M extends true ? File[] : File | null];
|
|
133
97
|
'change': [event: Event];
|
|
134
|
-
'upload:start': [file: FileUploadFile, index: number];
|
|
135
|
-
'upload:progress': [file: FileUploadFile, progress: number, index: number];
|
|
136
|
-
'upload:success': [file: FileUploadFile, result: any, index: number];
|
|
137
|
-
'upload:error': [file: FileUploadFile, error: string, index: number];
|
|
138
|
-
'upload:cancel': [file: FileUploadFile, index: number];
|
|
139
|
-
'upload:complete': [files: FileUploadFile[]];
|
|
140
98
|
}
|
|
141
|
-
type FileUploadFiles<M> = (M extends true ?
|
|
99
|
+
type FileUploadFiles<M> = (M extends true ? File[] : File) | null;
|
|
142
100
|
export interface FileUploadSlots<M extends boolean = false> {
|
|
143
101
|
'default'(props: {
|
|
144
102
|
open: UseFileDialogReturn['open'];
|
|
145
103
|
removeFile: (index?: number) => void;
|
|
146
|
-
uploadFile: (index: number) => void;
|
|
147
|
-
cancelUpload: (index: number) => void;
|
|
148
104
|
}): any;
|
|
149
105
|
'leading'(props?: {}): any;
|
|
150
106
|
'label'(props?: {}): any;
|
|
@@ -153,8 +109,6 @@ export interface FileUploadSlots<M extends boolean = false> {
|
|
|
153
109
|
files?: FileUploadFiles<M>;
|
|
154
110
|
open: UseFileDialogReturn['open'];
|
|
155
111
|
removeFile: (index?: number) => void;
|
|
156
|
-
uploadFile: (index: number) => void;
|
|
157
|
-
cancelUpload: (index: number) => void;
|
|
158
112
|
}): any;
|
|
159
113
|
'files'(props: {
|
|
160
114
|
files?: FileUploadFiles<M>;
|
|
@@ -163,38 +117,30 @@ export interface FileUploadSlots<M extends boolean = false> {
|
|
|
163
117
|
files?: FileUploadFiles<M>;
|
|
164
118
|
open: UseFileDialogReturn['open'];
|
|
165
119
|
removeFile: (index?: number) => void;
|
|
166
|
-
uploadFile: (index: number) => void;
|
|
167
|
-
cancelUpload: (index: number) => void;
|
|
168
120
|
}): any;
|
|
169
121
|
'files-bottom'(props: {
|
|
170
122
|
files?: FileUploadFiles<M>;
|
|
171
123
|
open: UseFileDialogReturn['open'];
|
|
172
124
|
removeFile: (index?: number) => void;
|
|
173
|
-
uploadFile: (index: number) => void;
|
|
174
|
-
cancelUpload: (index: number) => void;
|
|
175
125
|
}): any;
|
|
176
126
|
'file'(props: {
|
|
177
|
-
|
|
127
|
+
file: File;
|
|
178
128
|
index: number;
|
|
179
129
|
}): any;
|
|
180
130
|
'file-leading'(props: {
|
|
181
|
-
|
|
131
|
+
file: File;
|
|
182
132
|
index: number;
|
|
183
133
|
}): any;
|
|
184
134
|
'file-name'(props: {
|
|
185
|
-
|
|
135
|
+
file: File;
|
|
186
136
|
index: number;
|
|
187
137
|
}): any;
|
|
188
138
|
'file-size'(props: {
|
|
189
|
-
|
|
190
|
-
index: number;
|
|
191
|
-
}): any;
|
|
192
|
-
'file-progress'(props: {
|
|
193
|
-
fileUpload: FileUploadFile;
|
|
139
|
+
file: File;
|
|
194
140
|
index: number;
|
|
195
141
|
}): any;
|
|
196
142
|
'file-trailing'(props: {
|
|
197
|
-
|
|
143
|
+
file: File;
|
|
198
144
|
index: number;
|
|
199
145
|
}): any;
|
|
200
146
|
}
|
|
@@ -202,160 +148,16 @@ declare const _default: <M extends boolean = false>(__VLS_props: NonNullable<Awa
|
|
|
202
148
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
203
149
|
readonly onChange?: ((event: Event) => any) | undefined;
|
|
204
150
|
readonly "onUpdate:modelValue"?: ((...args: unknown[]) => any) | undefined;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
readonly "onUpload:success"?: ((file: FileUploadFile, result: any, index: number) => any) | undefined;
|
|
208
|
-
readonly "onUpload:error"?: ((file: FileUploadFile, error: string, index: number) => any) | undefined;
|
|
209
|
-
readonly "onUpload:cancel"?: ((file: FileUploadFile, index: number) => any) | undefined;
|
|
210
|
-
readonly "onUpload:complete"?: ((files: FileUploadFile[]) => any) | undefined;
|
|
211
|
-
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onChange" | "onUpdate:modelValue" | "onUpload:start" | "onUpload:progress" | "onUpload:success" | "onUpload:error" | "onUpload:cancel" | "onUpload:complete"> & (FileUploadProps<M> & {
|
|
212
|
-
modelValue?: (M extends true ? FileUploadFile[] : FileUploadFile) | null;
|
|
151
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onChange" | "onUpdate:modelValue"> & (FileUploadProps<M> & {
|
|
152
|
+
modelValue?: (M extends true ? File[] : File) | null;
|
|
213
153
|
}) & Partial<{}>> & import("vue").PublicProps;
|
|
214
154
|
expose(exposed: import("vue").ShallowUnwrapRef<{
|
|
215
155
|
inputRef: import("vue").Ref<HTMLInputElement | undefined, HTMLInputElement | undefined>;
|
|
216
156
|
dropzoneRef: import("vue").Ref<HTMLDivElement | undefined, HTMLDivElement | undefined>;
|
|
217
|
-
uploadFile: (index: number) => Promise<void>;
|
|
218
|
-
cancelUpload: (index: number) => void;
|
|
219
|
-
activeUploads: Readonly<import("vue").Ref<number, number>>;
|
|
220
|
-
uploadQueue: Readonly<import("vue").Ref<readonly {
|
|
221
|
-
readonly index: number;
|
|
222
|
-
readonly fileUpload: {
|
|
223
|
-
readonly file: {
|
|
224
|
-
readonly lastModified: number;
|
|
225
|
-
readonly name: string;
|
|
226
|
-
readonly webkitRelativePath: string;
|
|
227
|
-
readonly size: number;
|
|
228
|
-
readonly type: string;
|
|
229
|
-
readonly arrayBuffer: {
|
|
230
|
-
(): Promise<ArrayBuffer>;
|
|
231
|
-
(): Promise<ArrayBuffer>;
|
|
232
|
-
};
|
|
233
|
-
readonly bytes: {
|
|
234
|
-
(): Promise<Uint8Array>;
|
|
235
|
-
(): Promise<Uint8Array>;
|
|
236
|
-
};
|
|
237
|
-
readonly slice: {
|
|
238
|
-
(start?: number, end?: number, contentType?: string): Blob;
|
|
239
|
-
(start?: number, end?: number, contentType?: string): Blob;
|
|
240
|
-
};
|
|
241
|
-
readonly stream: {
|
|
242
|
-
(): ReadableStream<Uint8Array>;
|
|
243
|
-
(): ReadableStream<Uint8Array>;
|
|
244
|
-
};
|
|
245
|
-
readonly text: {
|
|
246
|
-
(): Promise<string>;
|
|
247
|
-
(): Promise<string>;
|
|
248
|
-
};
|
|
249
|
-
};
|
|
250
|
-
readonly progress?: number | undefined;
|
|
251
|
-
readonly uploading?: boolean | undefined;
|
|
252
|
-
readonly error?: string | undefined;
|
|
253
|
-
readonly abortController?: {
|
|
254
|
-
readonly signal: {
|
|
255
|
-
readonly aborted: boolean;
|
|
256
|
-
readonly onabort: ((this: AbortSignal, ev: Event) => any) | null;
|
|
257
|
-
readonly reason: any;
|
|
258
|
-
readonly throwIfAborted: {
|
|
259
|
-
(): void;
|
|
260
|
-
(): void;
|
|
261
|
-
(): void;
|
|
262
|
-
};
|
|
263
|
-
readonly addEventListener: {
|
|
264
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
265
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
266
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
267
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
268
|
-
};
|
|
269
|
-
readonly removeEventListener: {
|
|
270
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
271
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
272
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
273
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
274
|
-
};
|
|
275
|
-
readonly dispatchEvent: {
|
|
276
|
-
(event: Event): boolean;
|
|
277
|
-
(event: Event): boolean;
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
readonly abort: {
|
|
281
|
-
(reason?: any): void;
|
|
282
|
-
(reason?: any): void;
|
|
283
|
-
(reason?: any): void;
|
|
284
|
-
};
|
|
285
|
-
} | undefined;
|
|
286
|
-
};
|
|
287
|
-
}[], readonly {
|
|
288
|
-
readonly index: number;
|
|
289
|
-
readonly fileUpload: {
|
|
290
|
-
readonly file: {
|
|
291
|
-
readonly lastModified: number;
|
|
292
|
-
readonly name: string;
|
|
293
|
-
readonly webkitRelativePath: string;
|
|
294
|
-
readonly size: number;
|
|
295
|
-
readonly type: string;
|
|
296
|
-
readonly arrayBuffer: {
|
|
297
|
-
(): Promise<ArrayBuffer>;
|
|
298
|
-
(): Promise<ArrayBuffer>;
|
|
299
|
-
};
|
|
300
|
-
readonly bytes: {
|
|
301
|
-
(): Promise<Uint8Array>;
|
|
302
|
-
(): Promise<Uint8Array>;
|
|
303
|
-
};
|
|
304
|
-
readonly slice: {
|
|
305
|
-
(start?: number, end?: number, contentType?: string): Blob;
|
|
306
|
-
(start?: number, end?: number, contentType?: string): Blob;
|
|
307
|
-
};
|
|
308
|
-
readonly stream: {
|
|
309
|
-
(): ReadableStream<Uint8Array>;
|
|
310
|
-
(): ReadableStream<Uint8Array>;
|
|
311
|
-
};
|
|
312
|
-
readonly text: {
|
|
313
|
-
(): Promise<string>;
|
|
314
|
-
(): Promise<string>;
|
|
315
|
-
};
|
|
316
|
-
};
|
|
317
|
-
readonly progress?: number | undefined;
|
|
318
|
-
readonly uploading?: boolean | undefined;
|
|
319
|
-
readonly error?: string | undefined;
|
|
320
|
-
readonly abortController?: {
|
|
321
|
-
readonly signal: {
|
|
322
|
-
readonly aborted: boolean;
|
|
323
|
-
readonly onabort: ((this: AbortSignal, ev: Event) => any) | null;
|
|
324
|
-
readonly reason: any;
|
|
325
|
-
readonly throwIfAborted: {
|
|
326
|
-
(): void;
|
|
327
|
-
(): void;
|
|
328
|
-
(): void;
|
|
329
|
-
};
|
|
330
|
-
readonly addEventListener: {
|
|
331
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
332
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
333
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
|
334
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
|
335
|
-
};
|
|
336
|
-
readonly removeEventListener: {
|
|
337
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
338
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
339
|
-
<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
340
|
-
(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
341
|
-
};
|
|
342
|
-
readonly dispatchEvent: {
|
|
343
|
-
(event: Event): boolean;
|
|
344
|
-
(event: Event): boolean;
|
|
345
|
-
};
|
|
346
|
-
};
|
|
347
|
-
readonly abort: {
|
|
348
|
-
(reason?: any): void;
|
|
349
|
-
(reason?: any): void;
|
|
350
|
-
(reason?: any): void;
|
|
351
|
-
};
|
|
352
|
-
} | undefined;
|
|
353
|
-
};
|
|
354
|
-
}[]>>;
|
|
355
157
|
}>): void;
|
|
356
158
|
attrs: any;
|
|
357
159
|
slots: FileUploadSlots<M>;
|
|
358
|
-
emit: (((evt: "change", event: Event) => void) & ((evt: "update:modelValue", payload: M extends true ?
|
|
160
|
+
emit: (((evt: "change", event: Event) => void) & ((evt: "update:modelValue", payload: M extends true ? File[] : File | null) => void)) & ((evt: "update:modelValue", value: (M extends true ? File[] : File) | null | undefined) => void);
|
|
359
161
|
}>) => import("vue").VNode & {
|
|
360
162
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
361
163
|
};
|
|
@@ -2367,13 +2367,7 @@ const fileUpload = (options) => ({
|
|
|
2367
2367
|
fileWrapper: "flex flex-col min-w-0",
|
|
2368
2368
|
fileName: "text-default truncate",
|
|
2369
2369
|
fileSize: "text-muted truncate",
|
|
2370
|
-
|
|
2371
|
-
fileProgressText: "text-xs text-muted whitespace-nowrap",
|
|
2372
|
-
fileError: "text-xs text-red-500 mt-1",
|
|
2373
|
-
fileActions: "flex items-center gap-1",
|
|
2374
|
-
fileTrailingButton: "",
|
|
2375
|
-
fileUploadButton: "",
|
|
2376
|
-
fileCancelButton: ""
|
|
2370
|
+
fileTrailingButton: ""
|
|
2377
2371
|
},
|
|
2378
2372
|
variants: {
|
|
2379
2373
|
color: {
|
|
@@ -2422,15 +2416,12 @@ const fileUpload = (options) => ({
|
|
|
2422
2416
|
root: "gap-2 items-start",
|
|
2423
2417
|
files: "flex flex-col w-full gap-2",
|
|
2424
2418
|
file: "min-w-0 flex items-center border border-default rounded-md w-full",
|
|
2425
|
-
|
|
2419
|
+
fileTrailingButton: "ms-auto"
|
|
2426
2420
|
},
|
|
2427
2421
|
grid: {
|
|
2428
2422
|
fileWrapper: "hidden",
|
|
2429
2423
|
fileLeadingAvatar: "size-full rounded-lg",
|
|
2430
|
-
|
|
2431
|
-
fileTrailingButton: "p-0 rounded-full border-2 border-bg",
|
|
2432
|
-
fileUploadButton: "p-0 rounded-full border-2 border-bg",
|
|
2433
|
-
fileCancelButton: "p-0 rounded-full border-2 border-bg"
|
|
2424
|
+
fileTrailingButton: "absolute -top-1.5 -end-1.5 p-0 rounded-full border-2 border-bg"
|
|
2434
2425
|
}
|
|
2435
2426
|
},
|
|
2436
2427
|
position: {
|
|
@@ -2451,9 +2442,6 @@ const fileUpload = (options) => ({
|
|
|
2451
2442
|
},
|
|
2452
2443
|
disabled: {
|
|
2453
2444
|
true: "cursor-not-allowed opacity-75"
|
|
2454
|
-
},
|
|
2455
|
-
showProgress: {
|
|
2456
|
-
true: ""
|
|
2457
2445
|
}
|
|
2458
2446
|
},
|
|
2459
2447
|
compoundVariants: [...(options.theme.colors || []).map((color) => ({
|
|
@@ -2474,31 +2462,31 @@ const fileUpload = (options) => ({
|
|
|
2474
2462
|
size: "xs",
|
|
2475
2463
|
layout: "list",
|
|
2476
2464
|
class: {
|
|
2477
|
-
|
|
2465
|
+
fileTrailingButton: "-me-1"
|
|
2478
2466
|
}
|
|
2479
2467
|
}, {
|
|
2480
2468
|
size: "sm",
|
|
2481
2469
|
layout: "list",
|
|
2482
2470
|
class: {
|
|
2483
|
-
|
|
2471
|
+
fileTrailingButton: "-me-1.5"
|
|
2484
2472
|
}
|
|
2485
2473
|
}, {
|
|
2486
2474
|
size: "md",
|
|
2487
2475
|
layout: "list",
|
|
2488
2476
|
class: {
|
|
2489
|
-
|
|
2477
|
+
fileTrailingButton: "-me-1.5"
|
|
2490
2478
|
}
|
|
2491
2479
|
}, {
|
|
2492
2480
|
size: "lg",
|
|
2493
2481
|
layout: "list",
|
|
2494
2482
|
class: {
|
|
2495
|
-
|
|
2483
|
+
fileTrailingButton: "-me-2"
|
|
2496
2484
|
}
|
|
2497
2485
|
}, {
|
|
2498
2486
|
size: "xl",
|
|
2499
2487
|
layout: "list",
|
|
2500
2488
|
class: {
|
|
2501
|
-
|
|
2489
|
+
fileTrailingButton: "-me-2"
|
|
2502
2490
|
}
|
|
2503
2491
|
}, {
|
|
2504
2492
|
variant: "button",
|
|
@@ -2547,21 +2535,6 @@ const fileUpload = (options) => ({
|
|
|
2547
2535
|
interactive: true,
|
|
2548
2536
|
disabled: false,
|
|
2549
2537
|
class: "hover:bg-elevated/25"
|
|
2550
|
-
}, {
|
|
2551
|
-
showProgress: true,
|
|
2552
|
-
layout: "list",
|
|
2553
|
-
class: {
|
|
2554
|
-
fileWrapper: "flex-col",
|
|
2555
|
-
fileProgress: "w-full"
|
|
2556
|
-
}
|
|
2557
|
-
}, {
|
|
2558
|
-
showProgress: true,
|
|
2559
|
-
layout: "grid",
|
|
2560
|
-
class: {
|
|
2561
|
-
fileWrapper: "absolute inset-0 bg-black/50 flex flex-col items-center justify-center rounded-lg",
|
|
2562
|
-
fileProgress: "w-3/4",
|
|
2563
|
-
fileProgressText: "text-white font-medium"
|
|
2564
|
-
}
|
|
2565
2538
|
}],
|
|
2566
2539
|
defaultVariants: {
|
|
2567
2540
|
color: "primary",
|
package/dist/unplugin.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { join, normalize } from 'pathe';
|
|
|
3
3
|
import { createUnplugin } from 'unplugin';
|
|
4
4
|
import { defu } from 'defu';
|
|
5
5
|
import tailwind from '@tailwindcss/vite';
|
|
6
|
-
import { g as getTemplates, d as defaultOptions, r as resolveColors, a as getDefaultUiConfig } from './shared/ui.
|
|
6
|
+
import { g as getTemplates, d as defaultOptions, r as resolveColors, a as getDefaultUiConfig } from './shared/ui.CgUuvRXi.mjs';
|
|
7
7
|
import { globSync } from 'tinyglobby';
|
|
8
8
|
import { genSafeVariableName } from 'knitwork';
|
|
9
9
|
import MagicString from 'magic-string';
|
package/dist/vite.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslamdevui/ui",
|
|
3
3
|
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
|
|
4
|
-
"version": "3.3.2-beta.
|
|
4
|
+
"version": "3.3.2-beta.3",
|
|
5
5
|
"packageManager": "pnpm@10.13.1",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/MohamedEslam04/ui.git"
|
|
9
9
|
},
|
|
10
|
-
"homepage": "https://ui.nuxt.com",
|
|
10
|
+
"homepage": "https://ui.nuxt.com/pro",
|
|
11
11
|
"type": "module",
|
|
12
12
|
"license": "MIT",
|
|
13
|
-
"publishConfig": {
|
|
14
|
-
"access": "public"
|
|
15
|
-
},
|
|
16
13
|
"exports": {
|
|
17
14
|
".": {
|
|
18
15
|
"types": "./dist/module.d.mts",
|
|
@@ -135,7 +132,7 @@
|
|
|
135
132
|
"colortranslator": "^5.0.0",
|
|
136
133
|
"consola": "^3.4.2",
|
|
137
134
|
"defu": "^6.1.4",
|
|
138
|
-
"dotenv": "^16.
|
|
135
|
+
"dotenv": "^16.6.1",
|
|
139
136
|
"embla-carousel-auto-height": "^8.6.0",
|
|
140
137
|
"embla-carousel-auto-scroll": "^8.6.0",
|
|
141
138
|
"embla-carousel-autoplay": "^8.6.0",
|
|
@@ -145,6 +142,7 @@
|
|
|
145
142
|
"embla-carousel-wheel-gestures": "^8.0.2",
|
|
146
143
|
"fuse.js": "^7.1.0",
|
|
147
144
|
"git-url-parse": "^16.1.0",
|
|
145
|
+
"motion-v": "^1.5.0",
|
|
148
146
|
"hookable": "^5.5.3",
|
|
149
147
|
"knitwork": "^1.2.0",
|
|
150
148
|
"magic-string": "^0.30.17",
|
|
@@ -152,26 +150,27 @@
|
|
|
152
150
|
"ofetch": "^1.4.1",
|
|
153
151
|
"ohash": "^2.0.11",
|
|
154
152
|
"pathe": "^2.0.3",
|
|
155
|
-
"pkg-types": "^2.
|
|
153
|
+
"pkg-types": "^2.2.0",
|
|
156
154
|
"reka-ui": "2.3.2",
|
|
157
155
|
"scule": "^1.3.0",
|
|
158
156
|
"tailwind-variants": "^1.0.0",
|
|
159
157
|
"tailwindcss": "^4.1.11",
|
|
160
158
|
"tinyglobby": "^0.2.14",
|
|
161
159
|
"unplugin": "^2.3.5",
|
|
162
|
-
"unplugin-auto-import": "^
|
|
163
|
-
"unplugin-vue-components": "^
|
|
160
|
+
"unplugin-auto-import": "^20.0.0",
|
|
161
|
+
"unplugin-vue-components": "^29.0.0",
|
|
164
162
|
"vaul-vue": "0.4.1",
|
|
165
|
-
"vue-component-type-helpers": "^
|
|
163
|
+
"vue-component-type-helpers": "^3.0.5"
|
|
166
164
|
},
|
|
167
165
|
"devDependencies": {
|
|
166
|
+
"@nuxt/content": "^3.6.3",
|
|
168
167
|
"@nuxt/eslint-config": "^1.6.0",
|
|
169
168
|
"@nuxt/module-builder": "^1.0.1",
|
|
170
169
|
"@nuxt/test-utils": "^3.19.2",
|
|
171
170
|
"@release-it/conventional-changelog": "^10.0.1",
|
|
172
171
|
"@vue/compiler-sfc": "3.5.17",
|
|
173
172
|
"@vue/test-utils": "^2.4.6",
|
|
174
|
-
"better-sqlite3": "^12.
|
|
173
|
+
"better-sqlite3": "^12.2.0",
|
|
175
174
|
"embla-carousel": "^8.6.0",
|
|
176
175
|
"eslint": "^9.31.0",
|
|
177
176
|
"happy-dom": "^18.0.1",
|