pic / src /components /DropZone.tsx
chriswu25's picture
Add squish app source, Dockerfile and HF config
2bc6d22
import React, { useCallback } from 'react';
import { Upload } from 'lucide-react';
import type { ImageFile } from '../types';
interface DropZoneProps {
onFilesDrop: (files: ImageFile[]) => void;
}
export function DropZone({ onFilesDrop }: DropZoneProps) {
const handleDrop = useCallback((e: React.DragEvent) => {
e.preventDefault();
const files = Array.from(e.dataTransfer.files)
.filter(file => file.type.startsWith('image/') || file.name.toLowerCase().endsWith('jxl'))
.map(file => ({
id: crypto.randomUUID(),
file,
status: 'pending' as const,
originalSize: file.size,
}));
onFilesDrop(files);
}, [onFilesDrop]);
const handleDragOver = useCallback((e: React.DragEvent) => {
e.preventDefault();
}, []);
const handleFileInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const files = Array.from(e.target.files || [])
.filter(file => file.type.startsWith('image/') || file.name.toLowerCase().endsWith('jxl'))
.map(file => ({
id: crypto.randomUUID(),
file,
status: 'pending' as const,
originalSize: file.size,
}));
onFilesDrop(files);
e.target.value = '';
}, [onFilesDrop]);
return (
<div
className="border-2 border-dashed border-gray-300 rounded-lg p-12 text-center hover:border-blue-500 transition-colors"
onDrop={handleDrop}
onDragOver={handleDragOver}
>
<input
type="file"
id="fileInput"
className="hidden"
multiple
accept="image/*,.jxl"
onChange={handleFileInput}
/>
<label
htmlFor="fileInput"
className="cursor-pointer flex flex-col items-center gap-4"
>
<Upload className="w-12 h-12 text-gray-400" />
<div>
<p className="text-lg font-medium text-gray-700">
Drop images here or click to upload
</p>
<p className="text-sm text-gray-500">
Supports JPEG, PNG, WebP, AVIF, and JXL
</p>
</div>
</label>
</div>
);
}