import { useCallback } from 'react'; import { ImageUp, Upload, X } from 'lucide-react'; import { useDropzone } from 'react-dropzone'; import { Button } from './ui/button'; import { cn } from '../lib/utils'; interface ImageInputProps { value?: string | null; onChange: (base64: string | null) => void; label?: string; description?: string; className?: string; compact?: boolean; } function readFileAsDataUrl(file: File) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (event) => { const result = event.target?.result; if (typeof result === 'string') { resolve(result); } else { reject(new Error('Unable to read image file.')); } }; reader.onerror = () => reject(reader.error ?? new Error('Unable to read image file.')); reader.readAsDataURL(file); }); } export function ImageInput({ value, onChange, label, description, className, compact = false }: ImageInputProps) { const handleDrop = useCallback( async (acceptedFiles: File[]) => { const file = acceptedFiles[0]; if (!file) return; try { const base64 = await readFileAsDataUrl(file); onChange(base64); } catch (error) { console.error('Failed to read dropped image', error); } }, [onChange], ); const { getRootProps, getInputProps, isDragAccept, isDragReject } = useDropzone({ accept: { 'image/*': [] }, maxFiles: 1, maxSize: 10 * 1024 * 1024, multiple: false, onDrop: (acceptedFiles) => { void handleDrop(acceptedFiles); }, }); return (
{label ? (

{label}

{description ?

{description}

: null}
) : null} {value ? (
Selected input
) : (
{isDragAccept ? : }

Drop an image or click to browse

PNG, JPG, or WEBP up to 10 MB.

)}
); }