Skip to content

Latest commit

 

History

History
171 lines (134 loc) · 6.02 KB

README.md

File metadata and controls

171 lines (134 loc) · 6.02 KB

My Drag and Drop List Component

Overview

This component allows me to implement a drag-and-drop interface for reordering items. It’s flexible enough to handle both single-level and nested lists. I’m using the @dnd-kit library to make dragging smooth and intuitive.

How to Use

Step 1: Setup

Make sure I have the necessary dependencies installed:

npm install @dnd-kit/core @dnd-kit/modifiers @dnd-kit/sortable @dnd-kit/utilities

Step 2: Import and Define My Items

I’ll need to import the component and create my items. Each item should have a unique ID, and if it has nested items, I’ll add a data property with its own array.

Example Implementation

Single-Level Drag and Drop

import React, { useReducer } from "react";
import DndListComponent from "./DndListComponent";

// Initial items for the list
const initialItems = [
  { id: "1", content: "Item 1" },
  { id: "2", content: "Item 2" },
  { id: "3", content: "Item 3" },
];

// Reducer function to handle item reordering
const reducer = (state, action) => {
  switch (action.type) {
    case "REORDER_ITEMS":
      return { ...state, items: action.payload };
    default:
      return state;
  }
};

// Main component
const MyComponent = () => {
  const [state, dispatch] = useReducer(reducer, { items: initialItems });

  return (
    <DndListComponent items={state.items} dispatch={dispatch}>
      {(item) => <div>{item.content}</div>} {/* Render item content */}
    </DndListComponent>
  );
};

export default MyComponent;

Nested Drag and Drop

import React, { useReducer } from "react";
import { itemsReducer } from "@/app/components/Dnd/DndReducer";
import { ItemType } from "@/app/components/Dnd/DndNestList.types";
import DndListComponent from "@/app/components/Dnd/DndNestList";

const initialItems: ItemType[] = [
  {
    id: 1,
    title: "Work Experience",
    data: [
      { id: 4, title: "Nested Item 1" },
      { id: 5, title: "Nested Item 2" },
      { id: 6, title: "Nested Item 3" },
    ],
  },
  {
    id: 2,
    title: "Education",
    data: [
      { id: 7, title: "Nested Item 4" },
      { id: 8, title: "Nested Item 5" },
      { id: 9, title: "Nested Item 6" },
    ],
  },
];

const Test = () => {
  const [items, dispatch] = useReducer(itemsReducer, initialItems);

  return (
    <DndListComponent items={items} dispatch={dispatch}>
      {(item) => (
        <div style={{ padding: 8, border: "1px solid gray" }}>
          <div>{item.title}</div>
          {item.data && (
            <DndListComponent
              items={item.data}
              dispatch={(action) => {
                const updatedItems = items.map((i) =>
                  i.id === item.id ? { ...i, data: action.payload } : i,
                );
                dispatch({ type: "REORDER_ITEMS", payload: updatedItems });
              }}
            >
              {(nestedItem) => (
                <div style={{ padding: 8, border: "1px solid gray" }}>
                  <div>{nestedItem.title}</div>
                </div>
              )}
            </DndListComponent>
          )}
        </div>
      )}
    </DndListComponent>
  );
};

export default Test;

Component Props

DndListComponentProps

Prop Type Description
items ItemType[] An array of items I want to display and reorder. Each item must have a unique id.
children (item: ItemType) => React.ReactNode A function that returns the content for each item.
dispatch React.Dispatch<ActionType> A function to update the state when items are reordered.

ItemType

Prop Type Description
id UniqueIdentifier A unique identifier for the item.
title string The title of the item.
data ItemType[] An array of nested items (if any).
[key: string]: any Any Additional properties can be included as needed.

ActionType

Prop Type Description
type "REORDER_ITEMS" The action type for reordering items.
payload ItemType[] The updated list of items after reordering.

SortableItemProps

Prop Type Description
itemId UniqueIdentifier The unique identifier for the sortable item.
content React.ReactNode The content to render for the sortable item.
activeId UniqueIdentifier,null The ID of the currently active (dragging) item.
isDragging boolean Indicates if the item is currently being dragged.
style React.CSSProperties Custom styles for the item.

Dragging Features

  • Reordering: I can drag and drop to reorder items, including nested ones.
  • Visual Feedback: The component changes opacity while dragging for a better user experience.
  • Restrictions: Dragging is limited to the vertical axis and within the parent element.

Customization

I can customize the styles of SortableItem or modify the component behavior by adjusting the props or styles.

Conclusion

This Drag and Drop List component is especially useful for managing nested lists, making it a valuable addition to my UI toolkit.