78 lines
2.5 KiB
Svelte
78 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
type Props = {
|
|
onFilesSelected: (files: File[]) => void;
|
|
class?: string;
|
|
};
|
|
|
|
let { onFilesSelected, class: className = "" }: Props = $props();
|
|
|
|
let fileInput: HTMLInputElement | null = null;
|
|
let isDragging = $state(false);
|
|
|
|
const processFiles = (files: FileList | null | undefined) => {
|
|
if (!files) return;
|
|
|
|
const filtered = Array.from(files).filter((file) => {
|
|
const name = file.name.toLowerCase();
|
|
return (
|
|
name.endsWith('.zip') ||
|
|
file.type === 'application/zip' ||
|
|
file.type === 'application/x-zip-compressed'
|
|
);
|
|
});
|
|
|
|
if (filtered.length > 0) {
|
|
onFilesSelected(filtered);
|
|
}
|
|
};
|
|
|
|
const openFileDialog = () => fileInput?.click();
|
|
|
|
const handleFileSelection = (event: Event) => {
|
|
const input = event.currentTarget as HTMLInputElement;
|
|
processFiles(input.files);
|
|
input.value = ''; // Reset so same file can be uploaded twice
|
|
};
|
|
|
|
const handleDragOver = (event: DragEvent) => {
|
|
event.preventDefault();
|
|
isDragging = true;
|
|
};
|
|
|
|
const handleDragLeave = (event: DragEvent) => {
|
|
event.preventDefault();
|
|
isDragging = false;
|
|
};
|
|
|
|
const handleDrop = (event: DragEvent) => {
|
|
event.preventDefault();
|
|
isDragging = false;
|
|
processFiles(event.dataTransfer?.files);
|
|
};
|
|
</script>
|
|
|
|
<input
|
|
bind:this={fileInput}
|
|
class="hidden"
|
|
type="file"
|
|
accept=".zip,application/zip,application/x-zip-compressed"
|
|
multiple
|
|
onchange={handleFileSelection}
|
|
/>
|
|
|
|
<button
|
|
type="button"
|
|
class="flex min-h-[calc(-180px+100vh)] w-full grow cursor-pointer flex-col justify-center border-0 bg-transparent p-0 text-center text-inherit appearance-none focus:outline-none transition-colors rounded-2xl {isDragging ? 'bg-gray-100 border-2 border-dashed border-primary-500' : ''} {className}"
|
|
aria-label="ZIP-Dateien hinzufügen"
|
|
onclick={openFileDialog}
|
|
ondragover={handleDragOver}
|
|
ondragleave={handleDragLeave}
|
|
ondrop={handleDrop}
|
|
>
|
|
<div class="flex flex-row items-baseline justify-center gap-2">
|
|
<!-- Changed h1 to span for better semantic HTML inside a button -->
|
|
<span class="text-[20px] font-bold text-primary-900">Dateien hinzufügen</span>
|
|
<span class="text-[20px] font-extrabold text-primary-900">+</span>
|
|
</div>
|
|
</button>
|