In my latest project, I tackled an engaging challenge: building a dynamic image gallery in React that supports drag-and-drop functionality, image uploads, and image selection. Here's a rundown of what I did, the technical challenges I faced, and how I overcame them.
🎯 Project Goal
To create a user-friendly gallery where users can:
- Upload multiple images at once.
- Select and delete specific images.
- Drag and rearrange images dynamically.
Provide a responsive layout that adapts across various screen sizes.
🛠 Technologies UsedReact for building the user interface.
TypeScript for type safety and improved development experience.
Tailwind CSS for rapid styling.
HTML5 Drag-and-Drop API for implementing intuitive drag-and-drop functionality.
💻 Code Overview
Here's a breakdown of some of the core components and functionality that make up this gallery:
- Image Uploading I used a simple element to allow users to upload multiple images simultaneously. When images are uploaded, they are previewed in the gallery by generating a URL using URL.createObjectURL(file). The uploaded images are stored in the component state, making it easy to manage and render them dynamically.
const handleFileUpload = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
const newImages = Array.from(event.target.files).map((file, index) => ({
id: images.length + index + 1,
url: URL.createObjectURL(file),
selected: false,
}));
setImages((prev) => [...prev, ...newImages]);
}
};
- Selecting and Deleting Images Each image in the gallery has a checkbox that allows users to select it. The selected images can be deleted in bulk with a simple click. The state management for this is straightforward, with a selected property for each image to track its selection status.
const toggleSelection = (id: number) => {
setImages((prevImages) => {
const updatedImages = prevImages.map((img) =>
img.id === id ? { ...img, selected: !img.selected } : img
);
const newSelectedCount = updatedImages.filter(
(img) => img.selected
).length;
setSelectedCount(newSelectedCount);
return updatedImages;
});
};
- Drag-and-Drop Sorting Using the HTML5 Drag-and-Drop API, I implemented a simple way to rearrange images by dragging and dropping them. This makes the gallery interactive and fun to use.
const handleDragStart = (index: number) => {
setDraggedIndex(index);
};
const handleDrop = (e: React.DragEvent<HTMLDivElement>, index: number) => {
e.preventDefault();
if (draggedIndex !== null && draggedIndex !== index) {
const updatedImages = [...images];
const [movedImage] = updatedImages.splice(draggedIndex, 1);
updatedImages.splice(index, 0, movedImage);
setImages(updatedImages);
setDraggedIndex(index);
}
};
- Responsive Layout with Tailwind CSS I utilized Tailwind CSS to create a responsive grid layout for the gallery. The images adjust their sizes dynamically based on the screen size, ensuring a seamless experience across all devices.
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-2 max-h-[500px] overflow-y-auto'>
{/* Image Items Here */}
</div>
🎨 User Experience and Design
To enhance the user experience:
- I added an overlay that appears when hovering over images, showing the checkbox for selection.
- The layout adapts to screen size changes, offering a clean, organized look on any device.
- An "Add Images" button is always visible, enabling easy uploads without disrupting the current view.
📝 Key Takeaways
- State Management: Efficiently managing component state with React hooks was crucial for handling image uploads, selections, and deletions.
- Drag-and-Drop: Leveraging the native HTML5 API made implementing drag-and-drop relatively straightforward without additional dependencies.
- User Interface: Tailwind CSS proved to be an invaluable tool for quickly creating a responsive and visually appealing design.
- File Handling: Previewing images before uploading by using URL.createObjectURL is a handy trick for a better user experience
🚀 Next Steps
I plan to enhance the gallery by:
- Adding a lightbox effect to view images in larger sizes.
- Integrating a backend to save uploaded images permanently.
- Adding filters and sorting options to manage large image collections easily.
📸 Demo & Code
If you're interested in the complete code, check out my GitHub repository here. Feel free to clone, fork, and play around with it!
Live
💬 Feedback
I’d love to hear your thoughts! What do you think of this image gallery? What features would you like to see added? Feel free to leave a comment or connect with me on LinkedIn!
Thanks for reading, and happy coding! 🎉
Top comments (0)