This commit completes Phase 6 of the paint-ui implementation, adding full file import/export capabilities with drag-drop and clipboard support. **New Files:** - lib/file-utils.ts: Core file operations (open, save, export, project format) - hooks/use-file-operations.ts: React hook for file operations - hooks/use-drag-drop.ts: Drag & drop state management - hooks/use-clipboard.ts: Clipboard paste event handling - components/editor/file-menu.tsx: File menu dropdown component - components/modals/export-dialog.tsx: Export dialog with format/quality options - components/modals/new-image-dialog.tsx: New image dialog with presets - components/modals/index.ts: Modals barrel export **Updated Files:** - components/editor/editor-layout.tsx: Integrated FileMenu, drag-drop overlay, clipboard paste - components/editor/index.ts: Added file-menu export **Features:** - ✨ Create new images with dimension presets (Full HD, HD, 800x600, custom) - ✨ Open image files (PNG, JPG, WEBP) as new layers - ✨ Save/load .paint project files (JSON with base64 layer data) - ✨ Export as PNG/JPEG/WEBP with quality control - ✨ Drag & drop file upload with visual overlay - ✨ Clipboard paste support (Ctrl+V) - ✨ File type validation and error handling - ✨ DataTransfer API integration for unified file handling **Project File Format (.paint):** - JSON structure with version, dimensions, layer metadata - Base64-encoded PNG data for each layer - Preserves layer properties (opacity, blend mode, order, visibility) Build verified: ✓ Compiled successfully in 1233ms 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
36 lines
771 B
TypeScript
36 lines
771 B
TypeScript
import { useCallback, useState } from 'react';
|
|
|
|
export function useDragDrop(onDrop: (dataTransfer: DataTransfer) => void) {
|
|
const [isDragging, setIsDragging] = useState(false);
|
|
|
|
const handleDragOver = useCallback((e: React.DragEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setIsDragging(true);
|
|
}, []);
|
|
|
|
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setIsDragging(false);
|
|
}, []);
|
|
|
|
const handleDrop = useCallback(
|
|
(e: React.DragEvent) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setIsDragging(false);
|
|
|
|
onDrop(e.dataTransfer);
|
|
},
|
|
[onDrop]
|
|
);
|
|
|
|
return {
|
|
isDragging,
|
|
handleDragOver,
|
|
handleDragLeave,
|
|
handleDrop,
|
|
};
|
|
}
|