Hone logo
Hone
Problems

Interactive List Reordering with React Drag and Drop

This challenge focuses on building a fundamental drag-and-drop interface in React using TypeScript. You will implement a system that allows users to reorder items within a list by dragging and dropping them. This is a common UI pattern found in many web applications, from task management tools to content editors.

Problem Description

Your task is to create a React component that renders a list of draggable items. Users should be able to click and hold an item, drag it to a new position within the list, and release it to update the list's order.

Key Requirements:

  1. Draggable Items: Each item in the list must be draggable.
  2. Droppable Area: The list itself should act as a droppable area, allowing items to be placed within it.
  3. Reordering Logic: When an item is dropped, the underlying data (the order of items) must be updated, and the UI should reflect the new order.
  4. Visual Feedback: Provide visual cues to the user during the drag operation, such as a visual indicator of the item being dragged and a highlight of where it will be dropped.
  5. TypeScript Integration: The entire solution should be implemented using TypeScript, ensuring type safety.

Expected Behavior:

  • A user clicks on an item.
  • The item visually lifts from its original position and can be moved around.
  • As the item hovers over different positions in the list, a visual indicator (e.g., a placeholder or a border) should show where the item will be dropped.
  • When the user releases the mouse button, the item settles into its new position, and the list order is updated accordingly.
  • The component should gracefully handle edge cases like dragging an item to its original position.

Examples

Example 1: Basic Reordering

Input Data:

const initialItems = [
  { id: '1', text: 'Item A' },
  { id: '2', text: 'Item B' },
  { id: '3', text: 'Item C' },
];

Scenario: The user drags "Item B" and drops it between "Item C" and the end of the list.

Expected UI State After Drag and Drop: The list should visually update to:

  1. Item A
  2. Item C
  3. Item B

Explanation: The original order [A, B, C] is changed to [A, C, B] by moving the item with id: '2' to the third position.

Example 2: Dragging to the Top

Input Data:

const initialItems = [
  { id: 'a', text: 'Task 1' },
  { id: 'b', text: 'Task 2' },
  { id: 'c', text: 'Task 3' },
];

Scenario: The user drags "Task 3" and drops it at the very beginning of the list.

Expected UI State After Drag and Drop: The list should visually update to:

  1. Task 3
  2. Task 1
  3. Task 2

Explanation: The original order [Task 1, Task 2, Task 3] is changed to [Task 3, Task 1, Task 2] by moving the item with id: 'c' to the first position.

Example 3: Dragging to the Same Position

Input Data:

const initialItems = [
  { id: 'x', text: 'First' },
  { id: 'y', text: 'Second' },
];

Scenario: The user clicks on "Second", drags it slightly, and then drops it back onto its original position.

Expected UI State After Drag and Drop: The list should remain visually unchanged:

  1. First
  2. Second

Explanation: When an item is dropped onto its original position, the order of the list should not change, and the UI should reflect no modification.

Constraints

  • The list will contain at least one item.
  • Each item will have a unique id property.
  • The solution should be performant enough to handle lists of up to 100 items without noticeable lag during dragging.
  • You are allowed to use a third-party drag-and-drop library (e.g., react-beautiful-dnd, react-dnd), but you must integrate it correctly with TypeScript. Alternatively, you can implement a custom drag-and-drop solution using native browser APIs.

Notes

  • Consider how to manage the state of the list items (order and content).
  • Think about the different events involved in a drag-and-drop operation (e.g., onDragStart, onDragOver, onDrop).
  • Visual feedback is crucial for a good user experience. How will you indicate which item is being dragged and where it can be dropped?
  • Ensure your solution is accessible to users who may not be able to use a mouse.
Loading editor...
typescript