nuxt-ui-elements 0.1.24 → 0.1.25
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 +199 -160
- package/dist/module.d.mts +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +8 -1
- package/dist/runtime/composables/useUploader/index.d.ts +368 -0
- package/dist/runtime/composables/useUploader/index.js +274 -0
- package/dist/runtime/composables/useUploader/plugins/image-compressor.d.ts +49 -0
- package/dist/runtime/composables/useUploader/plugins/image-compressor.js +111 -0
- package/dist/runtime/composables/useUploader/plugins/index.d.ts +2 -0
- package/dist/runtime/composables/useUploader/plugins/index.js +2 -0
- package/dist/runtime/composables/useUploader/plugins/thumbnail-generator.d.ts +8 -0
- package/dist/runtime/composables/useUploader/plugins/thumbnail-generator.js +65 -0
- package/dist/runtime/composables/useUploader/types.d.ts +155 -0
- package/dist/runtime/composables/useUploader/types.js +0 -0
- package/dist/runtime/composables/useUploader/validators/allowed-file-types.d.ts +6 -0
- package/dist/runtime/composables/useUploader/validators/allowed-file-types.js +12 -0
- package/dist/runtime/composables/useUploader/validators/duplicate-file.d.ts +27 -0
- package/dist/runtime/composables/useUploader/validators/duplicate-file.js +26 -0
- package/dist/runtime/composables/useUploader/validators/index.d.ts +4 -0
- package/dist/runtime/composables/useUploader/validators/index.js +4 -0
- package/dist/runtime/composables/useUploader/validators/max-file-size.d.ts +6 -0
- package/dist/runtime/composables/useUploader/validators/max-file-size.js +12 -0
- package/dist/runtime/composables/useUploader/validators/max-files.d.ts +6 -0
- package/dist/runtime/composables/useUploader/validators/max-files.js +12 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/types/index.d.ts +1 -0
- package/dist/runtime/types/index.js +1 -0
- package/dist/types.d.mts +2 -0
- package/package.json +3 -2
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export const PluginImageCompressor = (_, pluginOptions) => {
|
|
2
|
+
const {
|
|
3
|
+
maxWidth = 1920,
|
|
4
|
+
maxHeight = 1920,
|
|
5
|
+
quality = 0.85,
|
|
6
|
+
outputFormat = "auto",
|
|
7
|
+
minSizeToCompress = 1e5,
|
|
8
|
+
// 100KB
|
|
9
|
+
preserveMetadata = true
|
|
10
|
+
} = pluginOptions;
|
|
11
|
+
return {
|
|
12
|
+
id: "image-compressor",
|
|
13
|
+
hooks: {
|
|
14
|
+
process: async (file) => {
|
|
15
|
+
if (!file.mimeType.startsWith("image/")) {
|
|
16
|
+
return file;
|
|
17
|
+
}
|
|
18
|
+
if (file.mimeType === "image/gif") {
|
|
19
|
+
return file;
|
|
20
|
+
}
|
|
21
|
+
if (file.mimeType === "image/svg+xml") {
|
|
22
|
+
return file;
|
|
23
|
+
}
|
|
24
|
+
if (file.size < minSizeToCompress) {
|
|
25
|
+
return file;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const sourceUrl = URL.createObjectURL(file.data);
|
|
29
|
+
const image = new Image();
|
|
30
|
+
image.src = sourceUrl;
|
|
31
|
+
await new Promise((resolve, reject) => {
|
|
32
|
+
image.onload = () => resolve();
|
|
33
|
+
image.onerror = () => reject(new Error("Failed to load image"));
|
|
34
|
+
});
|
|
35
|
+
const needsResize = image.width > maxWidth || image.height > maxHeight;
|
|
36
|
+
if (!needsResize && outputFormat === "auto") {
|
|
37
|
+
URL.revokeObjectURL(sourceUrl);
|
|
38
|
+
return file;
|
|
39
|
+
}
|
|
40
|
+
let targetWidth = image.width;
|
|
41
|
+
let targetHeight = image.height;
|
|
42
|
+
if (needsResize) {
|
|
43
|
+
const widthRatio = maxWidth / image.width;
|
|
44
|
+
const heightRatio = maxHeight / image.height;
|
|
45
|
+
const ratio = Math.min(widthRatio, heightRatio);
|
|
46
|
+
targetWidth = Math.round(image.width * ratio);
|
|
47
|
+
targetHeight = Math.round(image.height * ratio);
|
|
48
|
+
}
|
|
49
|
+
const canvas = document.createElement("canvas");
|
|
50
|
+
canvas.width = targetWidth;
|
|
51
|
+
canvas.height = targetHeight;
|
|
52
|
+
const ctx = canvas.getContext("2d");
|
|
53
|
+
if (!ctx) {
|
|
54
|
+
throw new Error("Could not get canvas context");
|
|
55
|
+
}
|
|
56
|
+
ctx.imageSmoothingEnabled = true;
|
|
57
|
+
ctx.imageSmoothingQuality = "high";
|
|
58
|
+
ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
|
|
59
|
+
let mimeType = file.mimeType;
|
|
60
|
+
if (outputFormat === "jpeg") {
|
|
61
|
+
mimeType = "image/jpeg";
|
|
62
|
+
} else if (outputFormat === "webp") {
|
|
63
|
+
mimeType = "image/webp";
|
|
64
|
+
} else if (outputFormat === "png") {
|
|
65
|
+
mimeType = "image/png";
|
|
66
|
+
}
|
|
67
|
+
const compressedBlob = await new Promise((resolve, reject) => {
|
|
68
|
+
canvas.toBlob(
|
|
69
|
+
(blob) => {
|
|
70
|
+
if (blob) {
|
|
71
|
+
resolve(blob);
|
|
72
|
+
} else {
|
|
73
|
+
reject(new Error("Failed to compress image"));
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
mimeType,
|
|
77
|
+
quality
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
URL.revokeObjectURL(sourceUrl);
|
|
81
|
+
if (compressedBlob.size < file.size) {
|
|
82
|
+
let newId = file.id;
|
|
83
|
+
if (outputFormat !== "auto" && outputFormat !== file.meta.extension) {
|
|
84
|
+
const extension = outputFormat === "jpeg" ? "jpg" : outputFormat;
|
|
85
|
+
newId = file.id.replace(/\.[^.]+$/, `.${extension}`);
|
|
86
|
+
}
|
|
87
|
+
file.meta.originalSize = file.size;
|
|
88
|
+
file.meta.compressionRatio = ((file.size - compressedBlob.size) / file.size * 100).toFixed(1);
|
|
89
|
+
return {
|
|
90
|
+
...file,
|
|
91
|
+
id: newId,
|
|
92
|
+
data: compressedBlob,
|
|
93
|
+
size: compressedBlob.size,
|
|
94
|
+
mimeType,
|
|
95
|
+
meta: {
|
|
96
|
+
...file.meta,
|
|
97
|
+
compressed: true,
|
|
98
|
+
originalSize: file.size,
|
|
99
|
+
compressionRatio: file.meta.compressionRatio
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return file;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.warn(`Image compression failed for ${file.name}:`, error);
|
|
106
|
+
return file;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const PluginThumbnailGenerator = (_options, pluginOptions) => {
|
|
2
|
+
return {
|
|
3
|
+
id: "thumbnail-generator",
|
|
4
|
+
hooks: {
|
|
5
|
+
process: async (file) => {
|
|
6
|
+
const { width = 100, height = 100, quality = 0.7 } = pluginOptions;
|
|
7
|
+
const sourceUrl = file.isRemote ? file.remoteUrl : URL.createObjectURL(file.data);
|
|
8
|
+
if (file.mimeType.startsWith("image/")) {
|
|
9
|
+
const image = new Image();
|
|
10
|
+
image.crossOrigin = "anonymous";
|
|
11
|
+
image.src = sourceUrl;
|
|
12
|
+
await new Promise((resolve) => {
|
|
13
|
+
image.onload = resolve;
|
|
14
|
+
});
|
|
15
|
+
const aspectRatio = image.width / image.height;
|
|
16
|
+
let targetWidth = width;
|
|
17
|
+
let targetHeight = height;
|
|
18
|
+
if (aspectRatio > 1) {
|
|
19
|
+
targetHeight = width / aspectRatio;
|
|
20
|
+
} else {
|
|
21
|
+
targetWidth = height * aspectRatio;
|
|
22
|
+
}
|
|
23
|
+
const canvas = document.createElement("canvas");
|
|
24
|
+
canvas.width = targetWidth;
|
|
25
|
+
canvas.height = targetHeight;
|
|
26
|
+
const ctx = canvas.getContext("2d");
|
|
27
|
+
if (ctx) {
|
|
28
|
+
ctx.drawImage(image, 0, 0, targetWidth, targetHeight);
|
|
29
|
+
const thumbnailPreviewUrl = canvas.toDataURL("image/jpeg", quality);
|
|
30
|
+
file.preview = thumbnailPreviewUrl;
|
|
31
|
+
}
|
|
32
|
+
} else if (file.mimeType.startsWith("video/")) {
|
|
33
|
+
const video = document.createElement("video");
|
|
34
|
+
video.src = sourceUrl;
|
|
35
|
+
video.crossOrigin = "anonymous";
|
|
36
|
+
video.currentTime = 1;
|
|
37
|
+
await new Promise((resolve) => {
|
|
38
|
+
video.onloadeddata = () => {
|
|
39
|
+
video.onseeked = resolve;
|
|
40
|
+
video.currentTime = 1;
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
const aspectRatio = video.videoWidth / video.videoHeight;
|
|
44
|
+
let targetWidth = width;
|
|
45
|
+
let targetHeight = height;
|
|
46
|
+
if (aspectRatio > 1) {
|
|
47
|
+
targetHeight = width / aspectRatio;
|
|
48
|
+
} else {
|
|
49
|
+
targetWidth = height * aspectRatio;
|
|
50
|
+
}
|
|
51
|
+
const canvas = document.createElement("canvas");
|
|
52
|
+
canvas.width = targetWidth;
|
|
53
|
+
canvas.height = targetHeight;
|
|
54
|
+
const ctx = canvas.getContext("2d");
|
|
55
|
+
if (ctx) {
|
|
56
|
+
ctx.drawImage(video, 0, 0, targetWidth, targetHeight);
|
|
57
|
+
const thumbnailPreviewUrl = canvas.toDataURL("image/jpeg", quality);
|
|
58
|
+
file.preview = thumbnailPreviewUrl;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return file;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { Emitter } from "mitt";
|
|
2
|
+
/**
|
|
3
|
+
* PUBLIC API - Types users commonly need
|
|
4
|
+
* These are exported from the main package
|
|
5
|
+
*/
|
|
6
|
+
export type FileStatus = "waiting" | "preprocessing" | "uploading" | "postprocessing" | "complete" | "error";
|
|
7
|
+
export type UploadStatus = "waiting" | "uploading";
|
|
8
|
+
export interface FileProgress {
|
|
9
|
+
percentage: number;
|
|
10
|
+
}
|
|
11
|
+
export interface FileError {
|
|
12
|
+
message: string;
|
|
13
|
+
details?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface UploadFile<TUploadResult = any> {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
size: number;
|
|
19
|
+
mimeType: string;
|
|
20
|
+
data: File | Blob;
|
|
21
|
+
status: FileStatus;
|
|
22
|
+
preview?: string;
|
|
23
|
+
progress: FileProgress;
|
|
24
|
+
error?: FileError;
|
|
25
|
+
uploadResult?: TUploadResult;
|
|
26
|
+
isRemote?: boolean;
|
|
27
|
+
remoteUrl?: string;
|
|
28
|
+
meta: Record<string, unknown>;
|
|
29
|
+
}
|
|
30
|
+
export type UploadFn<TUploadResult = any> = (file: UploadFile<TUploadResult>, onProgress: (progress: number) => void) => Promise<TUploadResult>;
|
|
31
|
+
export type GetRemoteFileFn = (fileId: string) => Promise<MinimumRemoteFileAttributes>;
|
|
32
|
+
export interface UploadOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Custom plugins to add (in addition to built-in plugins)
|
|
35
|
+
*/
|
|
36
|
+
plugins?: Plugin[];
|
|
37
|
+
/**
|
|
38
|
+
* Validate maximum number of files
|
|
39
|
+
* - false: disabled
|
|
40
|
+
* - number: enabled with limit
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
maxFiles?: false | number;
|
|
44
|
+
/**
|
|
45
|
+
* Validate maximum file size in bytes
|
|
46
|
+
* - false: disabled
|
|
47
|
+
* - number: enabled with limit
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
maxFileSize?: false | number;
|
|
51
|
+
/**
|
|
52
|
+
* Validate allowed file MIME types
|
|
53
|
+
* - false: disabled
|
|
54
|
+
* - string[]: enabled with allowed types
|
|
55
|
+
* @default false
|
|
56
|
+
*/
|
|
57
|
+
allowedFileTypes?: false | string[];
|
|
58
|
+
/**
|
|
59
|
+
* Generate thumbnail previews for images/videos
|
|
60
|
+
* - false: disabled
|
|
61
|
+
* - true: enabled with defaults
|
|
62
|
+
* - object: enabled with custom options
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
thumbnails?: false | true | ThumbnailOptions;
|
|
66
|
+
/**
|
|
67
|
+
* Compress images before upload
|
|
68
|
+
* - false: disabled
|
|
69
|
+
* - true: enabled with defaults
|
|
70
|
+
* - object: enabled with custom options
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
imageCompression?: false | true | ImageCompressionOptions;
|
|
74
|
+
/**
|
|
75
|
+
* Automatically start upload after files are added
|
|
76
|
+
* @default false
|
|
77
|
+
*/
|
|
78
|
+
autoProceed?: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface ThumbnailOptions {
|
|
81
|
+
width?: number;
|
|
82
|
+
height?: number;
|
|
83
|
+
quality?: number;
|
|
84
|
+
}
|
|
85
|
+
export interface ImageCompressionOptions {
|
|
86
|
+
maxWidth?: number;
|
|
87
|
+
maxHeight?: number;
|
|
88
|
+
quality?: number;
|
|
89
|
+
outputFormat?: "jpeg" | "webp" | "png" | "auto";
|
|
90
|
+
minSizeToCompress?: number;
|
|
91
|
+
preserveMetadata?: boolean;
|
|
92
|
+
}
|
|
93
|
+
export type UploaderEvents<TUploadResult = any> = {
|
|
94
|
+
"file:added": Readonly<UploadFile<TUploadResult>>;
|
|
95
|
+
"file:removed": Readonly<UploadFile<TUploadResult>>;
|
|
96
|
+
"file:processing": Readonly<UploadFile<TUploadResult>>;
|
|
97
|
+
"file:error": {
|
|
98
|
+
file: Readonly<UploadFile<TUploadResult>>;
|
|
99
|
+
error: FileError;
|
|
100
|
+
};
|
|
101
|
+
"upload:start": Array<Readonly<UploadFile<TUploadResult>>>;
|
|
102
|
+
"upload:complete": Array<Required<Readonly<UploadFile<TUploadResult>>>>;
|
|
103
|
+
"upload:error": FileError;
|
|
104
|
+
"upload:progress": {
|
|
105
|
+
file: Readonly<UploadFile<TUploadResult>>;
|
|
106
|
+
progress: number;
|
|
107
|
+
};
|
|
108
|
+
"files:reorder": {
|
|
109
|
+
oldIndex: number;
|
|
110
|
+
newIndex: number;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* PLUGIN API - Types for building custom plugins
|
|
115
|
+
* Only needed if users want to create custom validators/processors
|
|
116
|
+
*/
|
|
117
|
+
export type PluginContext = {
|
|
118
|
+
files: UploadFile[];
|
|
119
|
+
options: UploadOptions;
|
|
120
|
+
};
|
|
121
|
+
export type ValidationHook = (file: UploadFile, context: PluginContext) => Promise<true | UploadFile>;
|
|
122
|
+
export type ProcessingHook = (file: UploadFile, context: PluginContext) => Promise<UploadFile>;
|
|
123
|
+
export type SetupHook = (context: PluginContext) => Promise<void>;
|
|
124
|
+
export type PluginLifecycleStage = "validate" | "process" | "complete";
|
|
125
|
+
export type PluginHooks = {
|
|
126
|
+
validate?: ValidationHook;
|
|
127
|
+
process?: ProcessingHook;
|
|
128
|
+
complete?: ProcessingHook;
|
|
129
|
+
};
|
|
130
|
+
export interface Plugin {
|
|
131
|
+
id: string;
|
|
132
|
+
hooks: PluginHooks;
|
|
133
|
+
options?: UploadOptions;
|
|
134
|
+
}
|
|
135
|
+
export type PluginFn<TPluginOptions = unknown> = {
|
|
136
|
+
(context: PluginContext, pluginOptions: TPluginOptions): Plugin;
|
|
137
|
+
__pluginOptions?: TPluginOptions;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* INTERNAL TYPES - Not commonly needed by users
|
|
141
|
+
* Kept exported for edge cases but not primary API
|
|
142
|
+
*/
|
|
143
|
+
export type PreProcessor = (file: UploadFile) => Promise<UploadFile>;
|
|
144
|
+
export type Uploader = (file: Readonly<UploadFile>, emiter: Emitter<Pick<UploaderEvents, "upload:error" | "upload:progress">>) => Promise<string>;
|
|
145
|
+
export type Validator = (file: UploadFile) => Promise<boolean | FileError>;
|
|
146
|
+
export type Processor = (file: UploadFile) => Promise<File | Blob>;
|
|
147
|
+
export interface UploadBlob {
|
|
148
|
+
blobPath: string;
|
|
149
|
+
}
|
|
150
|
+
type MinimumRemoteFileAttributes = {
|
|
151
|
+
size: number;
|
|
152
|
+
mimeType: string;
|
|
153
|
+
remoteUrl: string;
|
|
154
|
+
};
|
|
155
|
+
export {};
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const ValidatorAllowedFileTypes = (_, options) => {
|
|
2
|
+
return {
|
|
3
|
+
id: "validator-allowed-file-types",
|
|
4
|
+
hooks: {
|
|
5
|
+
validate: async (file) => {
|
|
6
|
+
if (options.allowedFileTypes && options.allowedFileTypes.includes(file.mimeType) || (options.allowedFileTypes && options.allowedFileTypes.length) === 0)
|
|
7
|
+
return file;
|
|
8
|
+
throw { message: `File type ${file.mimeType} is not allowed` };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PluginFn } from "../types.js";
|
|
2
|
+
interface ValidatorDuplicateFileOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Whether to allow duplicate files
|
|
5
|
+
* @default false
|
|
6
|
+
*/
|
|
7
|
+
allowDuplicates?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Custom error message for duplicates
|
|
10
|
+
*/
|
|
11
|
+
errorMessage?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Prevents uploading duplicate files based on name, size, and last modified date.
|
|
15
|
+
* Useful for preventing accidental double-uploads in social media scheduling.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const uploader = useUpload()
|
|
20
|
+
* uploader.addPlugin(ValidatorDuplicateFile, {
|
|
21
|
+
* allowDuplicates: false,
|
|
22
|
+
* errorMessage: 'This file has already been added'
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare const ValidatorDuplicateFile: PluginFn<ValidatorDuplicateFileOptions>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const ValidatorDuplicateFile = ({ files }, options) => {
|
|
2
|
+
const { allowDuplicates = false, errorMessage = "This file has already been added" } = options;
|
|
3
|
+
return {
|
|
4
|
+
id: "validator-duplicate-file",
|
|
5
|
+
hooks: {
|
|
6
|
+
validate: async (file) => {
|
|
7
|
+
if (allowDuplicates) {
|
|
8
|
+
return file;
|
|
9
|
+
}
|
|
10
|
+
const isDuplicate = files.some((existingFile) => {
|
|
11
|
+
const sameSize = existingFile.size === file.size;
|
|
12
|
+
const sameName = existingFile.name === file.name;
|
|
13
|
+
let sameDate = true;
|
|
14
|
+
if (file.data instanceof File && existingFile.data instanceof File) {
|
|
15
|
+
sameDate = existingFile.data.lastModified === file.data.lastModified;
|
|
16
|
+
}
|
|
17
|
+
return sameSize && sameName && sameDate;
|
|
18
|
+
});
|
|
19
|
+
if (isDuplicate) {
|
|
20
|
+
throw { message: errorMessage, details: { fileName: file.name } };
|
|
21
|
+
}
|
|
22
|
+
return file;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const ValidatorMaxfileSize = (_, options) => {
|
|
2
|
+
return {
|
|
3
|
+
id: "validator-max-file-size",
|
|
4
|
+
hooks: {
|
|
5
|
+
validate: async (file) => {
|
|
6
|
+
if (options.maxFileSize && options.maxFileSize !== Infinity && file.size <= options.maxFileSize || options.maxFileSize && options.maxFileSize === Infinity)
|
|
7
|
+
return file;
|
|
8
|
+
throw { message: `File size exceeds the maximum limit of ${options.maxFileSize} bytes` };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const ValidatorMaxFiles = ({ files }, options) => {
|
|
2
|
+
return {
|
|
3
|
+
id: "validator-max-files",
|
|
4
|
+
hooks: {
|
|
5
|
+
validate: async (file) => {
|
|
6
|
+
if (options.maxFiles && options.maxFiles !== Infinity && files.length < options.maxFiles || options.maxFiles && options.maxFiles === Infinity)
|
|
7
|
+
return file;
|
|
8
|
+
throw { message: `Maximum number of files (${options.maxFiles}) exceeded` };
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types/index.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types/index.js";
|
package/dist/types.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-ui-elements",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.25",
|
|
4
4
|
"description": "A collection of beautiful, animated UI components for Nuxt applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "https://github.com/genu/nuxt-ui-elements.git",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"@internationalized/date": "^3.10.1",
|
|
29
29
|
"@nuxt/kit": "^4.2.2",
|
|
30
30
|
"@sindresorhus/slugify": "^3.0.0",
|
|
31
|
+
"mitt": "^3.0.1",
|
|
31
32
|
"plur": "^6.0.0",
|
|
32
33
|
"scule": "^1.3.0",
|
|
33
34
|
"tailwind-variants": "^3.2.2"
|
|
@@ -37,7 +38,7 @@
|
|
|
37
38
|
"@nuxt/eslint-config": "^1.12.1",
|
|
38
39
|
"@nuxt/module-builder": "^1.0.2",
|
|
39
40
|
"@nuxt/schema": "^4.2.2",
|
|
40
|
-
"@nuxt/test-utils": "^3.
|
|
41
|
+
"@nuxt/test-utils": "^3.23.0",
|
|
41
42
|
"@types/culori": "^4.0.1",
|
|
42
43
|
"@types/node": "latest",
|
|
43
44
|
"@vitest/coverage-v8": "^4.0.16",
|