Building a Responsive, Drag-and-Drop Image Gallery with React and Tailwind CSS 🎨

Julfikar Haidar - Oct 25 - - Dev Community

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 Used

  • React 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:

  1. 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]);
  }
};

Enter fullscreen mode Exit fullscreen mode
  1. 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;
  });
};

Enter fullscreen mode Exit fullscreen mode
  1. 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);
  }
};

Enter fullscreen mode Exit fullscreen mode
  1. 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>

Enter fullscreen mode Exit fullscreen mode

🎨 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! 🎉

. . . . .
Terabox Video Player