Skip to content

Commit

Permalink
Refactor file drop zone component
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardspresume committed Mar 7, 2024
1 parent 18b9c47 commit 277079d
Showing 1 changed file with 44 additions and 57 deletions.
101 changes: 44 additions & 57 deletions src/lib/components/form/FileDropZone.svelte
Original file line number Diff line number Diff line change
@@ -1,72 +1,59 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { MAX_FILE_SIZE_MB } from '$validations/imageValidationZodSchema';
import {
MAX_FILE_SIZE_MB,
imageValidationZodSchema
} from '$validations/imageValidationZodSchema';
export let chosenImageFile: File | null = null;
export let errorMessage: object | undefined = undefined;
let uploadedImageUrl: string | null = null;
function handleImageUpload(event: Event) {
const input = event.target as HTMLInputElement;
const input = event.currentTarget as HTMLInputElement | null;
if (input.files?.[0]) {
const file = input.files[0];
const imageValidationResult = imageValidationZodSchema.safeParse({ uploadedImage: file });
chosenImageFile = input?.files?.item(0) as File;
if (!imageValidationResult.success) {
const errorMessage =
imageValidationResult.error.errors[0]?.message || 'An unexpected error occurred';
toast.error(errorMessage);
// Reset input to allow re-triggering upload of the same file, enabling error message display on repeated attempts.
input.value = '';
return;
}
try {
// Revoke the old URL if it exists
uploadedImageUrl && URL.revokeObjectURL(uploadedImageUrl);
uploadedImageUrl = URL.createObjectURL(file);
// Reset caption when a new image is uploaded
} catch (e) {
toast.error('Failed to upload image. Please try again.');
}
// Revoke the old URL if it exists
if (uploadedImageUrl) {
URL.revokeObjectURL(uploadedImageUrl);
}
uploadedImageUrl = URL.createObjectURL(chosenImageFile);
}
</script>

<label
class="relative grid place-content-center justify-items-center gap-2 rounded-md border-2 border-dashed border-foreground/30 p-4 text-center text-sm transition-colors duration-300 hover:bg-accent/40"
>
<input
type="file"
accept="image/*"
name="uploadedImage"
class="absolute left-0 top-0 size-full cursor-pointer opacity-0"
data-testid="file-drop-zone-input"
on:change={handleImageUpload}
/>

{#if uploadedImageUrl}
<img
src={uploadedImageUrl}
alt="Uploaded Preview"
class="max-h-28 rounded-md border border-foreground/10 object-contain"
<fieldset class="space-y-2">
<label
class="relative grid gap-2 p-4 text-sm text-center transition-colors duration-300 border-2 border-dashed rounded-md place-content-center justify-items-center border-foreground/30 hover:bg-accent/40"
>
<input
type="file"
name="image"
accept="image/*"
on:input={handleImageUpload}
data-testId="file-drop-zone-input"
aria-invalid={errorMessage ? 'true' : undefined}
class="absolute top-0 left-0 opacity-0 cursor-pointer size-full"
/>
{:else}
<iconify-icon icon="flat-color-icons:add-image" class="text-5xl"></iconify-icon>

<p>
Upload image or drag and drop

<span class="text-sm text-muted-foreground">
(Max file size: {MAX_FILE_SIZE_MB}MB)
</span>
</p>
{#if uploadedImageUrl}
<img
src={uploadedImageUrl}
alt="Uploaded Preview"
class="object-contain border rounded-md max-h-28 border-foreground/10"
/>
{:else}
<iconify-icon icon="flat-color-icons:add-image" class="text-5xl"></iconify-icon>

<p>
Upload image or drag and drop

<span class="text-sm text-muted-foreground">
(Max file size: {MAX_FILE_SIZE_MB}MB)
</span>
</p>
{/if}
</label>

{#if errorMessage}
<p class="text-red-500">{errorMessage}</p>
{/if}
</label>
</fieldset>

0 comments on commit 277079d

Please sign in to comment.