Tips & Tricks

Como implementar Drag and Drop con Claude Code

Aprenda a implementar drag and drop usando Claude Code. Incluye ejemplos practicos de codigo y guia paso a paso.

Patrones de implementacion de Drag & Drop

El drag and drop es una funcionalidad importante para lograr interfaces intuitivas. Se utiliza en muchos escenarios como reordenamiento de listas, tableros kanban y carga de archivos. Con Claude Code, puede implementar drag and drop accesible y robusto de manera eficiente.

Implementacion basica con custom hook

> Crea un custom hook de React usando la API HTML Drag and Drop.
> Que soporte el reordenamiento de listas.
import { useState, useCallback, DragEvent } from 'react';

function useSortable<T extends { id: string }>(initialItems: T[]) {
  const [items, setItems] = useState(initialItems);
  const [draggedId, setDraggedId] = useState<string | null>(null);

  const handleDragStart = useCallback((e: DragEvent, id: string) => {
    setDraggedId(id);
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', id);
  }, []);

  const handleDragOver = useCallback((e: DragEvent, targetId: string) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';

    if (draggedId === null || draggedId === targetId) return;

    setItems((prev) => {
      const dragIndex = prev.findIndex((item) => item.id === draggedId);
      const targetIndex = prev.findIndex((item) => item.id === targetId);
      const newItems = [...prev];
      const [removed] = newItems.splice(dragIndex, 1);
      newItems.splice(targetIndex, 0, removed);
      return newItems;
    });
  }, [draggedId]);

  const handleDragEnd = useCallback(() => {
    setDraggedId(null);
  }, []);

  return { items, draggedId, handleDragStart, handleDragOver, handleDragEnd, setItems };
}

Componente de lista ordenable

function SortableList({ initialTasks }: { initialTasks: Task[] }) {
  const { items, draggedId, handleDragStart, handleDragOver, handleDragEnd } =
    useSortable(initialTasks);

  return (
    <ul role="listbox" aria-label="Lista de tareas (reordenable)">
      {items.map((task) => (
        <li
          key={task.id}
          draggable
          role="option"
          aria-grabbed={draggedId === task.id}
          onDragStart={(e) => handleDragStart(e, task.id)}
          onDragOver={(e) => handleDragOver(e, task.id)}
          onDragEnd={handleDragEnd}
          className={`p-3 mb-2 rounded border cursor-grab ${
            draggedId === task.id ? 'opacity-50 border-blue-400' : 'border-gray-200'
          }`}
        >
          <span>{task.title}</span>
        </li>
      ))}
    </ul>
  );
}

Zona de carga de archivos

> Crea un componente para subir archivos mediante drag and drop.
> Con vista previa y validacion.
function FileDropZone({ onFiles, accept, maxSize = 5 * 1024 * 1024 }: DropZoneProps) {
  const [isDragging, setIsDragging] = useState(false);
  const [errors, setErrors] = useState<string[]>([]);

  const validateFiles = (files: File[]): File[] => {
    const errs: string[] = [];
    const valid = files.filter((file) => {
      if (accept && !accept.includes(file.type)) {
        errs.push(`${file.name}: formato de archivo no soportado`);
        return false;
      }
      if (file.size > maxSize) {
        errs.push(`${file.name}: el tamano del archivo excede el limite`);
        return false;
      }
      return true;
    });
    setErrors(errs);
    return valid;
  };

  const handleDrop = (e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    setIsDragging(false);
    const files = Array.from(e.dataTransfer.files);
    const valid = validateFiles(files);
    if (valid.length > 0) onFiles(valid);
  };

  return (
    <div
      onDragOver={(e) => { e.preventDefault(); setIsDragging(true); }}
      onDragLeave={() => setIsDragging(false)}
      onDrop={handleDrop}
      className={`border-2 border-dashed rounded-lg p-8 text-center transition-colors ${
        isDragging ? 'border-blue-500 bg-blue-50' : 'border-gray-300'
      }`}
    >
      <p>Suelte archivos aqui, o haga clic para seleccionar</p>
      {errors.map((err, i) => (
        <p key={i} className="text-red-500 text-sm mt-1">{err}</p>
      ))}
    </div>
  );
}

Soporte de operacion por teclado

Para accesibilidad, habilitamos la operacion tambien mediante teclado.

const handleKeyDown = (e: React.KeyboardEvent, index: number) => {
  if (e.key === ' ' || e.key === 'Enter') {
    e.preventDefault();
    toggleGrabbed(index);
  }
  if (e.key === 'ArrowUp' && isGrabbed) {
    e.preventDefault();
    moveItem(index, index - 1);
  }
  if (e.key === 'ArrowDown' && isGrabbed) {
    e.preventDefault();
    moveItem(index, index + 1);
  }
};

Resumen

Con Claude Code, puede construir eficientemente diversas implementaciones de drag and drop, desde el reordenamiento de listas hasta la carga de archivos. Para mas detalles sobre carga de archivos, consulte Implementacion de carga de archivos. Para accesibilidad, consulte la guia de accesibilidad.

Para las especificaciones de la API HTML Drag and Drop, consulte MDN Web Docs.

#Claude Code #drag and drop #React #UI #interaction