diff --git a/v2/pink-sb/src/lib/upload/Box.svelte b/v2/pink-sb/src/lib/upload/Box.svelte
index 7211dc582a..6b955e94fd 100644
--- a/v2/pink-sb/src/lib/upload/Box.svelte
+++ b/v2/pink-sb/src/lib/upload/Box.svelte
@@ -22,6 +22,7 @@
size?: number;
extension?: string;
error?: string;
+ progress?: number;
status?: 'failed' | 'pending' | 'success';
})[] = [];
@@ -67,75 +68,100 @@
{#each files as file}
{@const fileSize = file?.size ? humanFileSize(file.size) : false}
+ {@const hasProgress = typeof file?.progress === 'number' && file.progress > 0}
+ {@const clampedProgress = hasProgress
+ ? Math.round(Math.min(Math.max(file.progress ?? 0, 0), 100))
+ : 0}
+ {@const isError = !!file?.error || file?.status === 'failed'}
-
-
-
-
-
- {file.name}
-
- {#if fileSize}
-
-
- ({fileSize.value}
- {fileSize.unit})
-
+
+
+
+
+
+
+ {file.name}
- {/if}
+ {#if fileSize}
+
+
+ ({fileSize.value}
+ {fileSize.unit})
+
+
+ {/if}
+
-
-
- {#if file?.status === 'success'}
-
- {:else}
- {#if file?.error}
-
-
-
- {:else if file?.status === 'pending'}
-
-
+
+
+ {:else if hasProgress}
+
+ {clampedProgress}%
+
+ {:else if file?.status === 'pending'}
+
+
+
+ {/if}
+
+
{/if}
-
- {/if}
+
+ {#if hasProgress && file?.status !== 'success'}
+
+ {/if}
{/each}
@@ -171,4 +197,23 @@
flex-shrink: 1;
}
}
+
+ .upload-progress-bar {
+ height: 4px;
+ width: 100%;
+ border-radius: var(--border-radius-XS, 4px);
+ background: var(--bgcolor-neutral-secondary, hsl(0 0% 90%));
+ overflow: hidden;
+
+ &-fill {
+ height: 100%;
+ border-radius: inherit;
+ background: var(--bgcolor-accent);
+ transition: width 0.3s ease;
+ }
+
+ &.is-error &-fill {
+ background: var(--bgcolor-error, hsl(0 70% 55%));
+ }
+ }
diff --git a/v2/pink-sb/src/stories/upload/Box.stories.svelte b/v2/pink-sb/src/stories/upload/Box.stories.svelte
index 86419fb66f..70288f5844 100644
--- a/v2/pink-sb/src/stories/upload/Box.stories.svelte
+++ b/v2/pink-sb/src/stories/upload/Box.stories.svelte
@@ -28,6 +28,38 @@
status: 'pending'
}
];
+
+ let filesWithProgress = [
+ {
+ name: 'uploading-file.png',
+ extension: 'png',
+ size: 15728640,
+ status: 'pending',
+ progress: 45
+ },
+ {
+ name: 'almost-done.pdf',
+ extension: 'pdf',
+ size: 8388608,
+ status: 'pending',
+ progress: 92
+ },
+ {
+ name: 'completed-file.jpg',
+ extension: 'jpg',
+ size: 41024,
+ status: 'success',
+ progress: 100
+ },
+ {
+ name: 'failed-upload.zip',
+ extension: 'zip',
+ size: 52428800,
+ status: 'failed',
+ error: 'File exceeds size limit',
+ progress: 60
+ }
+ ];