@makolabs/ripple 2.3.0 → 2.4.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.
|
@@ -40,6 +40,8 @@
|
|
|
40
40
|
const dropzoneEnabled = $derived(!disabled && !dropzoneFull);
|
|
41
41
|
|
|
42
42
|
let isDragging = $state(false);
|
|
43
|
+
let truncationMessage = $state('');
|
|
44
|
+
let truncationTimer: ReturnType<typeof setTimeout> | undefined;
|
|
43
45
|
let inputRef: HTMLInputElement;
|
|
44
46
|
|
|
45
47
|
function makeId(): string {
|
|
@@ -60,6 +62,18 @@
|
|
|
60
62
|
// Multi-file mode: cap and stage
|
|
61
63
|
const room = Math.max(0, maxFiles - files.length);
|
|
62
64
|
const accepted = arr.slice(0, room);
|
|
65
|
+
const dropped = arr.length - accepted.length;
|
|
66
|
+
|
|
67
|
+
if (dropped > 0) {
|
|
68
|
+
clearTimeout(truncationTimer);
|
|
69
|
+
truncationMessage = `${dropped} file${dropped > 1 ? 's' : ''} could not be added — maximum of ${maxFiles} reached.`;
|
|
70
|
+
truncationTimer = setTimeout(() => {
|
|
71
|
+
truncationMessage = '';
|
|
72
|
+
}, 5000);
|
|
73
|
+
} else {
|
|
74
|
+
truncationMessage = '';
|
|
75
|
+
}
|
|
76
|
+
|
|
63
77
|
const toAdd: StagedFile[] = accepted.map((file) => ({
|
|
64
78
|
id: makeId(),
|
|
65
79
|
file,
|
|
@@ -70,15 +84,21 @@
|
|
|
70
84
|
|
|
71
85
|
function handleRemove(fileId: string) {
|
|
72
86
|
files = files.filter((f) => f.id !== fileId);
|
|
87
|
+
truncationMessage = '';
|
|
73
88
|
}
|
|
74
89
|
|
|
75
90
|
function handleClearAll() {
|
|
76
91
|
files = [];
|
|
92
|
+
truncationMessage = '';
|
|
77
93
|
}
|
|
78
94
|
|
|
79
95
|
const readyCount = $derived(files.filter((f) => !f.status || f.status === 'ready').length);
|
|
96
|
+
const successCount = $derived(files.filter((f) => f.status === 'success').length);
|
|
97
|
+
const errorCount = $derived(files.filter((f) => f.status === 'error').length);
|
|
98
|
+
const uploadingCount = $derived(files.filter((f) => f.status === 'uploading').length);
|
|
99
|
+
const hasUploadActivity = $derived(successCount > 0 || errorCount > 0 || uploadingCount > 0);
|
|
80
100
|
const hasAnyFile = $derived(files.length > 0);
|
|
81
|
-
const anyUploading = $derived(
|
|
101
|
+
const anyUploading = $derived(uploadingCount > 0);
|
|
82
102
|
const canUpload = $derived(readyCount > 0 && !anyUploading && !!onfiles);
|
|
83
103
|
|
|
84
104
|
function handleUploadAll() {
|
|
@@ -167,6 +187,7 @@
|
|
|
167
187
|
ondragover={handleDragOver}
|
|
168
188
|
ondrop={handleDrop}
|
|
169
189
|
for={id}
|
|
190
|
+
data-dropzone-full={dropzoneFull ? 'true' : undefined}
|
|
170
191
|
>
|
|
171
192
|
<input
|
|
172
193
|
type="file"
|
|
@@ -190,34 +211,91 @@
|
|
|
190
211
|
</div>
|
|
191
212
|
|
|
192
213
|
<div class={slots.textBlock()}>
|
|
193
|
-
{#if
|
|
214
|
+
{#if dropzoneFull}
|
|
215
|
+
<div class={slots.mainText()}>
|
|
216
|
+
<span class="text-default-500 font-medium">Maximum of {maxFiles} files reached.</span>
|
|
217
|
+
</div>
|
|
218
|
+
<div class={slots.hintText()}>Remove a file to add more.</div>
|
|
219
|
+
{:else if !uploadContent}
|
|
194
220
|
<div class={slots.mainText()}>
|
|
195
221
|
<span class="text-primary-500 font-medium">Click here</span>
|
|
196
222
|
<span class="text-default-600"> to upload your file or drag and drop.</span>
|
|
197
223
|
</div>
|
|
224
|
+
<div class={slots.hintText()}>
|
|
225
|
+
Supported Format: {allowedMimeTypes.length
|
|
226
|
+
? allowedMimeTypes.join(', ')
|
|
227
|
+
: 'SVG, JPG, PNG'}
|
|
228
|
+
{#if maxSize}
|
|
229
|
+
({formatFileSize(maxSize)} each)
|
|
230
|
+
{:else}
|
|
231
|
+
(10MB each)
|
|
232
|
+
{/if}
|
|
233
|
+
</div>
|
|
198
234
|
{:else}
|
|
199
235
|
{@render uploadContent()}
|
|
236
|
+
<div class={slots.hintText()}>
|
|
237
|
+
Supported Format: {allowedMimeTypes.length
|
|
238
|
+
? allowedMimeTypes.join(', ')
|
|
239
|
+
: 'SVG, JPG, PNG'}
|
|
240
|
+
{#if maxSize}
|
|
241
|
+
({formatFileSize(maxSize)} each)
|
|
242
|
+
{:else}
|
|
243
|
+
(10MB each)
|
|
244
|
+
{/if}
|
|
245
|
+
</div>
|
|
200
246
|
{/if}
|
|
201
|
-
|
|
202
|
-
<div class={slots.hintText()}>
|
|
203
|
-
Supported Format: {allowedMimeTypes.length
|
|
204
|
-
? allowedMimeTypes.join(', ')
|
|
205
|
-
: 'SVG, JPG, PNG'}
|
|
206
|
-
{#if maxSize}
|
|
207
|
-
({formatFileSize(maxSize)} each)
|
|
208
|
-
{:else}
|
|
209
|
-
(10MB each)
|
|
210
|
-
{/if}
|
|
211
|
-
</div>
|
|
212
247
|
</div>
|
|
213
248
|
</div>
|
|
214
249
|
</label>
|
|
215
250
|
|
|
251
|
+
{#if truncationMessage}
|
|
252
|
+
<div
|
|
253
|
+
class="text-warning-700 bg-warning-50 border-warning-200 flex items-center gap-2 rounded-lg border px-3 py-2 text-xs"
|
|
254
|
+
data-fileupload-truncation-warning=""
|
|
255
|
+
>
|
|
256
|
+
<svg
|
|
257
|
+
class="text-warning-500 size-4 shrink-0"
|
|
258
|
+
fill="none"
|
|
259
|
+
viewBox="0 0 24 24"
|
|
260
|
+
stroke="currentColor"
|
|
261
|
+
>
|
|
262
|
+
<path
|
|
263
|
+
stroke-linecap="round"
|
|
264
|
+
stroke-linejoin="round"
|
|
265
|
+
stroke-width="2"
|
|
266
|
+
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4.5c-.77-.833-2.694-.833-3.464 0L3.34 16.5c-.77.833.192 2.5 1.732 2.5z"
|
|
267
|
+
/>
|
|
268
|
+
</svg>
|
|
269
|
+
{truncationMessage}
|
|
270
|
+
</div>
|
|
271
|
+
{/if}
|
|
272
|
+
|
|
216
273
|
{#if isMulti && hasAnyFile}
|
|
217
274
|
<div class="flex flex-col gap-2">
|
|
218
275
|
<div class="flex items-center justify-between">
|
|
219
|
-
<span
|
|
220
|
-
{
|
|
276
|
+
<span
|
|
277
|
+
class={cn('text-sm font-medium', dropzoneFull ? 'text-warning-600' : 'text-default-700')}
|
|
278
|
+
>
|
|
279
|
+
{filesListLabel} ({files.length}/{maxFiles})
|
|
280
|
+
{#if dropzoneFull}
|
|
281
|
+
<span class="text-warning-500 ml-1 text-xs font-normal">— full</span>
|
|
282
|
+
{/if}
|
|
283
|
+
{#if hasUploadActivity}
|
|
284
|
+
<span class="text-default-500 ml-2 text-xs font-normal" data-fileupload-summary="">
|
|
285
|
+
—
|
|
286
|
+
{#if successCount > 0}
|
|
287
|
+
<span class="text-success-600">{successCount} uploaded</span>
|
|
288
|
+
{/if}
|
|
289
|
+
{#if errorCount > 0}
|
|
290
|
+
{#if successCount > 0},{/if}
|
|
291
|
+
<span class="text-danger-600">{errorCount} failed</span>
|
|
292
|
+
{/if}
|
|
293
|
+
{#if uploadingCount > 0}
|
|
294
|
+
{#if successCount > 0 || errorCount > 0},{/if}
|
|
295
|
+
<span class="text-primary-600">{uploadingCount} uploading</span>
|
|
296
|
+
{/if}
|
|
297
|
+
</span>
|
|
298
|
+
{/if}
|
|
221
299
|
</span>
|
|
222
300
|
<div class="flex gap-2">
|
|
223
301
|
<Button
|