Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Sunshine And March Vibes (2025 Wallpapers Edition)

      May 15, 2025

      The Case For Minimal WordPress Setups: A Contrarian View On Theme Frameworks

      May 15, 2025

      How To Fix Largest Contentful Paint Issues With Subpart Analysis

      May 15, 2025

      How To Prevent WordPress SQL Injection Attacks

      May 15, 2025

      Intel’s latest Arc graphics driver is ready for DOOM: The Dark Ages, launching for Premium Edition owners on PC today

      May 15, 2025

      NVIDIA’s drivers are causing big problems for DOOM: The Dark Ages, but some fixes are available

      May 15, 2025

      Capcom breaks all-time profit records with 10% income growth after Monster Hunter Wilds sold over 10 million copies in a month

      May 15, 2025

      Microsoft plans to lay off 3% of its workforce, reportedly targeting management cuts as it changes to fit a “dynamic marketplace”

      May 15, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      A cross-platform Markdown note-taking application

      May 15, 2025
      Recent

      A cross-platform Markdown note-taking application

      May 15, 2025

      AI Assistant Demo & Tips for Enterprise Projects

      May 15, 2025

      Celebrating Global Accessibility Awareness Day (GAAD)

      May 15, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Intel’s latest Arc graphics driver is ready for DOOM: The Dark Ages, launching for Premium Edition owners on PC today

      May 15, 2025
      Recent

      Intel’s latest Arc graphics driver is ready for DOOM: The Dark Ages, launching for Premium Edition owners on PC today

      May 15, 2025

      NVIDIA’s drivers are causing big problems for DOOM: The Dark Ages, but some fixes are available

      May 15, 2025

      Capcom breaks all-time profit records with 10% income growth after Monster Hunter Wilds sold over 10 million copies in a month

      May 15, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»How to Build a Dynamic Wardrobe App with React Drag and Drop

    How to Build a Dynamic Wardrobe App with React Drag and Drop

    May 5, 2025

    Have you ever found yourself stuck deciding what color outfit to wear? Maybe you’re mixing and matching different tops and bottoms, unsure if the colors go together. It’s a common dilemma – so common that many of us turn to friends or family for a second opinion before stepping out for a meeting or a hangout.

    But what if you’re alone and need to make that choice quickly? Imagine having an app where you can drag and drop different clothing colors on your screen, instantly visualizing your outfit. If it looks good, that’s all the validation you need – no more second-guessing your look.

    In this tutorial, we’ll build a dynamic wardrobe app using React. You’ll learn to structure components, handle drag-and-drop interactions, and craft a smooth user experience. Let’s get straight into it!

    Here’s what we’ll cover:

    • Prerequisites

    • Steps to Create a Dynamic Wardrobe using React

      • Step 1: Setting Up Your Project

      • Step 2: Setting Up States

      • Step 3: Defining Color Options

      • Step 4: Implementing Drag and Drop Functionality

      • Step 5: Building the User Interface

      • Step 6: Putting It All Together

    • Conclusion

    Prerequisites

    Before we start coding, make sure you have:

    • Basic knowledge of React.

    • A code editor of your choice.

    Steps to Create a Dynamic Wardrobe using React

    We’re going to go through how to build this project step by step, so it’s easy to follow along. By the end, you’ll understand exactly how drag and drop functionality in React works.

    Step 1: Setting Up Your Project

    First and foremost, you need to set up React and Tailwind CSS using Vite in a project. If you don’t know how to do that, check out this article and follow the steps. When you’re done, come back here, and let’s continue building.

    If you already have a React project with Tailwind CSS you want to use, that’s great too.

    Step 2: Setting Up States

    We’ll start by setting up our states. If you have no idea what states are you can read my article on states here. In this simple project, we’ll have only two states: one for the selected top color (selectedTop) and the other for the selected bottom color (selectedBottom). We’ll be setting the initial value of both states to white (with hex code of #ffffff), as shown below:

    const [selectedTop, setSelectedTop] = useState("#ffffff");
    
    const [selectedBottom, setSelectedBottom] = useState("#ffffff");
    

    Step 3: Defining Color Options

    Next, we define an array of color options for the outfits:

    const colorOptions = [
    
    "#ff0000", // Red
    
    "#0000ff", // Blue
    
    "#ffff00", // Yellow
    
    "#00ff00", // Green
    
    "#ff00ff", // Pink
    
    "#808080", // Gray
    
    "#000000", // Black
    
    "#ffffff", // White
    
    ];
    

    The colorOptions array provides a vibrant palette of colors that users can drag onto clothing items.

    Step 4: Implementing Drag and Drop Functionality

    Now, let’s create the drag and drop functionality, which is the core aspect of this project. We’ll need event handler functions to handle certain events when they are triggered by specific user interaction or browser events – in this case, dragging and dropping.

    Here are the event handlers we need to implement the drag and drop functionality:

    1. handleDragStart

    This function is triggered when the user starts dragging a color block from the color palette (typically triggered via onDragStart in JSX).

    const handleDragStart = (e, color) => {
    
    e.dataTransfer.setData("color", color);
    
    };
    

    Breaking it down:

    • const handleDragStart = (e, color) => { ... }: This function accepts two parameters – the drag event object (e) and color, a custom value representing the color associated with the color block being dragged.

    • e.dataTransfer.setData("color", color):

      • dataTransfer is a property of the drag event that holds data being dragged.

      • .setData("color", color) stores the value of color under the key “color”.

    1. handleDropOnTop

    This function is triggered when the color block is dropped onto the “top” section of your outfit interface.

    const handleDropOnTop = (e) => {
    
    e.preventDefault();
    
    const color = e.dataTransfer.getData("color");
    
    setSelectedTop(color);
    
    };
    

    Breaking it down:

    • const handleDropOnTop = (e) => { … }: This function takes a single argument e, which is the event object representing the drop action.

    • e.preventDefault(): By default, the browser won’t allow dropping an item unless you explicitly prevent the default behavior. This ensures the drop target can accept the dragged item.

    • const color = e.daaTransfer.getData(“color”): retrieves the data previously set during the drag operation using setData(“color”, color) in handleDragStart .

    • setSelectedTop(color): The color data will be used to update the selectedTop state that tracks the currently selected top clothing color. This will typically cause the UI to re-render, showing the dropped color on the “top” section of the outfit.

    1. handleDropOnBottom

    This function is triggered when the color block is dropped onto the “bottom” section of your outfit interface.

    const handleDropOnBottom = (e) => {
    
    e.preventDefault();
    
    const color = e.dataTransfer.getData("color");
    
    setSelectedBottom(color);
    
    };
    

    Breaking it down:

    • const handleDropOnBottom = (e) => { ... }: This function takes a single argument e, which is the event object representing the drop action.

    • e.preventDefault(): By default, the browser won’t allow dropping an item unless you explicitly prevent the default behavior. This ensures the drop target can accept the dragged item.

    • const color = e.dataTransfer.getData("color"): Retrieves the data previously set during the drag operation using setData("color", color) in handleDragStart.

    • setSelectedBottom(color): The color data will be used to update the selectedBottom state that tracks the currently selected top clothing color. This will typically cause the UI to re-render, showing the dropped color on the “bottom” section of the outfit.

    1. allowDrop

    This event handler function enables a drop target by preventing the browser’s default behavior, which otherwise disallows dropping elements.

    const allowDrop = (e) => {
    
    e.preventDefault();
    
    };
    

    Step 5: Building the User Interface

    Having finished the functional part of our wardrobe project, we want to build out the visual part that users can see and interact with.

    The UI will consist of two parts: a color palette on the left and an outfit preview on the right. The color palette section will include 30 color blocks while the outfit preview section will include a top and bottom, onto which selected colors can be dragged and applied to see how they look together.

    This is a visual representation of the UI we’re building out:

    449e4294-8917-470e-ad06-cf54d1809296

    Creating the Color Palette Section

    To display all the colors provided in our colorOptions array, we need to first map through the array consisting of color values and render a <div> for each color.

    Each <div>:

    • Acts as a draggable color block with fixed width and height.

    • Has a semi-circular appearance using Tailwind CSS classes and inline styling to apply the specific background color.

    • Triggers the handleDragStart function when dragging begins, passing the event and the selected color.

    • Has a unique key for React’s rendering optimization.

    • If the color is white (#ffffff), it conditionally displays the text “White” in light gray for visibility.

    This setup allows users to visually identify and drag different color options to the top or bottom of an outfit on the UI.

    return (
      <div className="flex flex-col items-center p-6 bg-gray-100 rounded-lg min-h-screen">
        <h1 className="text-3xl font-extrabold mb-8 text-indigo-700">
          Dynamic Wardrobe
        </h1>
    
        <div className="flex flex-col md:flex-row w-full gap-8">
          {/* Color palette section */}
          <div className="w-full md:w-1/3 bg-white p-6 rounded-lg shadow-md">
            <h2 className="text-xl font-semibold mb-4 text-center">
              Color Palette
            </h2>
            <p className="mb-4 text-sm text-gray-600">
              Drag colors to the outfit pieces
            </p>
            <div className="grid grid-cols-5 gap-2">
              {colorOptions.map((color) => (
                <div
                  key={color}
                  className="w-12 h-12 rounded-md shadow-sm cursor-move flex items-center justify-center"
                  style={{ backgroundColor: color, border: "1px solid #ddd" }}
                  draggable="true"
                  onDragStart={(e) => handleDragStart(e, color)}
                >
                  {color === "#ffffff" && (
                    <span className="text-xs text-gray-400">White</span>
                  )}
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    );
    

    Creating the Outfit Preview

    Finally, let’s implement the outfit preview section, which is the fun part. There are two parts to the outfit display: the top and the bottom section. Let’s look at them one after the other:

    Top Section

    This section acts as a drop target for the top clothing color. It consists of a div with an SVG that allows for color filling.

    <div
      className="w-full flex items-center justify-center"
      onDrop={handleDropOnTop}
      onDragOver={allowDrop}
    >
      {/* T-shirt */}
      <svg viewBox="0 0 24 24" width="180" height="140">
        <path
          d="M16 2H8L6 6v3h2v13h8V9h2V6l-2-4z"
          fill={selectedTop}
          stroke="#333"
          strokeWidth="0.2"
        />
      </svg>
    </div>;
    

    In this section:

    • onDrop={handleDropOnTop}: Sets the top outfit color, when a color is dropped at the top div.

    • allowDrop is called via onDragOver to enable dropping.

    • The T-shirt SVG is drawn and its fill color is controlled by selectedTop, which updates when a new color is dropped.

    Bottom Section

    This section acts as a drop target for the bottom clothing color. It consists of a div with an SVG that allows for color filling.

    <div
      className="w-full flex items-center justify-center -mt-8"
      onDrop={handleDropOnBottom}
      onDragOver={allowDrop}
    >
      <svg viewBox="0 0 200 200" width="120" height="140">
        {/* Pants */}
        <path
          d="M60,20 L140,20 L150,180 L110,180 L100,100 L90,180 L50,180 L60,20 Z"
          fill={selectedBottom}
          stroke="#333"
          strokeWidth="2"
        />
        {/* Waistband */}
        <rect x="60" y="18" width="80" height="5" fill="#444" />
        {/* Center seam */}
        <path d="M100,20 L100,100" stroke="#000" strokeWidth="1" />
      </svg>
    </div>;
    

    In this section:

    • onDrop={handleDropOnBottom}: Sets the bottom outfit color, when a color is dropped at the bottom div.

    • allowDrop is called via onDragOver to enable dropping.

    • The pant SVG is drawn and its fill color is controlled by selectedBottom, which updates when a new color is dropped.

    • Extra details like a waistband (rect) and a seam (path) add realism.

    That completes the UI section of our project.

    Step 6: Putting It All Together

    Now that you’ve learned about the integral aspects, here is the full code that will give you the entire look and functionality:

    import { useState } from "react";
    
    export default function App() {
      // State for selected colors
      const [selectedTop, setSelectedTop] = useState("#ffffff");
      const [selectedBottom, setSelectedBottom] = useState("#ffffff");
    
      // Color options for clothing
      const colorOptions = [
        "#ff0000", // Red
        "#0000ff", // Blue
        "#ffff00", // Yellow
        "#00ff00", // Green
        "#ff00ff", // Pink
        "#808080", // Gray
        "#000000", // Black
        "#ffffff", // White
        "#ffa500", // Orange
        "#800080", // Purple
        "#8B0000", // Dark Red
        "#006400", // Dark Green
        "#00008B", // Dark Blue
        "#4B0082", // Indigo
        "#228B22", // Forest Green
        "#20B2AA", // Light Sea Green
        "#87CEEB", // Sky Blue
        "#4682B4", // Steel Blue
        "#9932CC", // Dark Orchid
        "#FF1493", // Deep Pink
        "#FF4500", // Orange Red
        "#FFD700", // Gold
        "#F0E68C", // Khaki
        "#F5DEB3", // Wheat
        "#D2B48C", // Tan
        "#A0522D", // Sienna
        "#8B4513", // Saddle Brown
        "#BC8F8F", // Rosy Brown
        "#708090", // Slate Gray
        "#2F4F4F", // Dark Slate Gray
      ];
    
      // Drag and drop handlers
      const handleDragStart = (e, color) => {
        e.dataTransfer.setData("color", color);
      };
    
      const handleDropOnTop = (e) => {
        e.preventDefault();
        const color = e.dataTransfer.getData("color");
        setSelectedTop(color);
      };
    
      const handleDropOnBottom = (e) => {
        e.preventDefault();
        const color = e.dataTransfer.getData("color");
        setSelectedBottom(color);
      };
    
      const allowDrop = (e) => {
        e.preventDefault();
      };
    
      return (
        <div className="flex flex-col items-center p-6 bg-gray-100 rounded-lg min-h-screen">
          <h1 className="text-3xl font-extrabold mb-8 text-indigo-700">
            Dynamic Wardrobe
          </h1>
    
          <div className="flex flex-col md:flex-row w-full gap-8">
            {/* Color palette section */}
            <div className="w-full md:w-1/3 bg-white p-6 rounded-lg shadow-md">
              <h2 className="text-xl font-semibold mb-4 text-center">
                Color Palette
              </h2>
              <p className="mb-4 text-sm text-gray-600">
                Drag colors to the outfit pieces
              </p>
              <div className="grid grid-cols-5 gap-2">
                {colorOptions.map((color) => (
                  <div
                    key={color}
                    className="w-12 h-12 rounded-md shadow-sm cursor-move flex items-center justify-center"
                    style={{ backgroundColor: color, border: "1px solid #ddd" }}
                    draggable="true"
                    onDragStart={(e) => handleDragStart(e, color)}
                  >
                    {color === "#ffffff" && (
                      <span className="text-xs text-gray-400">White</span>
                    )}
                  </div>
                ))}
              </div>
            </div>
    
            {/* Outfit visualization section */}
            <div className="w-full md:w-2/3 bg-white p-6 rounded-lg shadow-md">
              <h2 className="text-xl font-semibold mb-4 text-center">
                Outfit Preview
              </h2>
              <div className="flex flex-col items-center">
                <div className="relative w-64 h-64">
                  {/* Outfit container - better positioning */}
                  <div className="relative w-full h-full flex flex-col items-center justify-center">
                    {/* Top Section - accepts drag and drop */}
                    <div
                      className="w-full flex items-center justify-center"
                      onDrop={handleDropOnTop}
                      onDragOver={allowDrop}
                    >
                      {/* T-shirt */}
                      <svg viewBox="0 0 24 24" width="180" height="140">
                        <path
                          d="M16 2H8L6 6v3h2v13h8V9h2V6l-2-4z"
                          fill={selectedTop}
                          stroke="#333"
                          strokeWidth="0.2"
                        />
                      </svg>
                    </div>
                    <div
                      className="w-full flex items-center justify-center -mt-8"
                      onDrop={handleDropOnBottom}
                      onDragOver={allowDrop}
                    >
                      <svg viewBox="0 0 200 200" width="120" height="140">
                        {/* Pants */}
                        <path
                          d="M60,20 L140,20 L150,180 L110,180 L100,100 L90,180 L50,180 L60,20 Z"
                          fill={selectedBottom}
                          stroke="#333"
                          strokeWidth="2"
                        />
                        {/* Waistband */}
                        <rect x="60" y="18" width="80" height="5" fill="#444" />
                        {/* Center seam */}
                        <path d="M100,20 L100,100" stroke="#000" strokeWidth="1" />
                      </svg>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    }
    

    Here’s our dynamic wardrobe in full flow:

    e840ecd6-665f-41b4-a590-02e91302cf26

    Conclusion

    This dynamic wardrobe project demonstrates the power of React’s drag and drop API combined with state management. Not only is it a fun project to build, but it also taught you important concepts like managing state in React components, implementing drag and drop functionality, creating responsive layouts with Tailwind CSS and using SVG for interactive visuals.

    If you enjoyed reading this tutorial, you could Buy Me a Coffee. You can also connect with me on LinkedIn for more programming-related posts and articles.

    See you on the next one!

    Source: freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleImprove you C++ skills by coding an audio plugin
    Next Article Bungie vaulting Destiny 2 content backfires with the latest Red War lawsuit court ruling

    Related Posts

    Security

    Nmap 7.96 Launches with Lightning-Fast DNS and 612 Scripts

    May 16, 2025
    Common Vulnerabilities and Exposures (CVEs)

    CVE-2025-4732 – TOTOLINK A3002R/A3002RU HTTP POST Request Handler Buffer Overflow

    May 16, 2025
    Leave A Reply Cancel Reply

    Continue Reading

    Cognitive load and UX Design

    Development

    Intelligent healthcare forms analysis with Amazon Bedrock

    Development

    The clever Roborock robot vac with a mechanical arm is finally available for preorder

    News & Updates

    Google Fixes Chrome Browser Password Manager Issue After 17-Hour Outage

    Development

    Highlights

    Development

    The budget laptop I recommend to everyone is 40% off, but only until tomorrow

    June 11, 2024

    The Yoga 6 is a killer convertible laptop that’s always on the budget end, but…

    GitHub Copilot adds agent mode, MCP support in latest release

    April 4, 2025

    What is Shadow AI? The Hidden Risks and Challenges in Modern Organizations

    February 18, 2025

    This AI Paper Proposes Approximation Decision Boundary ADBA: An AI Approach for Black-Box Adversarial Attacks

    June 20, 2024
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.