Anonymous
So fügen Sie eine reibungslose CSS -Animation für diese Drag & Drop My TODO -Liste hinzu
Post
by Anonymous » 17 Aug 2025, 18:46
Hier ist mein React -Komponentencode. Es handelt sich um eine Todo -List -Komponente, die Zustand für das Statusverwaltung hinzufügen. Element hinzufügen. (mit Animation). /> [*] Auf Drag & Drop -Ereignisse < /li>
Element löschen < /li>
Auf Element hinzufügen < /li>
< /ol>
Code: Select all
import React, { useState, useRef, useEffect } from 'react';
import { useTodoStore } from '@/store/toDoList';
import styles from './TodoList.module.css';
export const TodoList: React.FC = () => {
const [text, setText] = useState('');
const [draggedId, setDraggedId] = useState(null);
const [dragOverId, setDragOverId] = useState(null);
const [isAdding, setIsAdding] = useState(false);
const [removingId, setRemovingId] = useState(null);
const { todos, addTodo, toggleTodo, removeTodo, reorderTodos } =
useTodoStore();
const dragRef = useRef(null);
const handleAdd = () => {
if (text.trim()) {
setIsAdding(true);
addTodo(text);
setText('');
// Reset animation state after animation completes
setTimeout(() => setIsAdding(false), 300);
}
};
const handleKeyPress = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
handleAdd();
}
};
const handleDragStart = (e: React.DragEvent, id: string) => {
setDraggedId(id);
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', id);
// Add dragging class to the dragged element
if (dragRef.current) {
dragRef.current.style.opacity = '0.5';
}
};
const handleDragOver = (e: React.DragEvent, id: string) => {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
setDragOverId(id);
};
const handleDragLeave = (e: React.DragEvent) => {
e.preventDefault();
setDragOverId(null);
};
const handleDrop = (e: React.DragEvent, targetId: string) => {
e.preventDefault();
const draggedId = e.dataTransfer.getData('text/html');
if (draggedId && draggedId !== targetId) {
const fromIndex = todos.findIndex((todo) => todo.id === draggedId);
const toIndex = todos.findIndex((todo) => todo.id === targetId);
if (fromIndex !== -1 && toIndex !== -1) {
reorderTodos(fromIndex, toIndex);
}
}
setDraggedId(null);
setDragOverId(null);
// Reset dragging styles
if (dragRef.current) {
dragRef.current.style.opacity = '1';
}
};
const handleDragEnd = () => {
setDraggedId(null);
setDragOverId(null);
// Reset dragging styles
if (dragRef.current) {
dragRef.current.style.opacity = '1';
}
};
const handleRemove = (id: string) => {
setRemovingId(id);
// Delay the actual removal to allow for animation
setTimeout(() => {
removeTodo(id);
setRemovingId(null);
}, 300);
};
return (
My Todo List
setText(e.target.value)}
onKeyPress={handleKeyPress}
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
Add
[list]
{todos.map((todo, index) => (
handleDragStart(e, todo.id)}
onDragOver={(e) => handleDragOver(e, todo.id)}
onDragLeave={handleDragLeave}
onDrop={(e) => handleDrop(e, todo.id)}
onDragEnd={handleDragEnd}
ref={draggedId === todo.id ? dragRef : null}
className={`
${styles.todoItem}
${draggedId === todo.id ? styles.dragging : ''}
${dragOverId === todo.id && draggedId !== todo.id ? styles.dragOver : ''}
${removingId === todo.id ? styles.removing : ''}
${isAdding && index === todos.length - 1 ? styles.adding : ''}
`}
>
toggleTodo(todo.id)}
>
{todo.text}
handleRemove(todo.id)}
className={styles.deleteButton}
aria-label="Delete todo"
>
))}
[/list]
{todos.length === 0 && (
No todos yet. Add one above!
)}
);
};
export default TodoList;
1755449181
Anonymous
Hier ist mein React -Komponentencode. Es handelt sich um eine Todo -List -Komponente, die Zustand für das Statusverwaltung hinzufügen. Element hinzufügen. (mit Animation). /> [*] Auf Drag & Drop -Ereignisse < /li> Element löschen < /li> Auf Element hinzufügen < /li> < /ol> [code]import React, { useState, useRef, useEffect } from 'react'; import { useTodoStore } from '@/store/toDoList'; import styles from './TodoList.module.css'; export const TodoList: React.FC = () => { const [text, setText] = useState(''); const [draggedId, setDraggedId] = useState(null); const [dragOverId, setDragOverId] = useState(null); const [isAdding, setIsAdding] = useState(false); const [removingId, setRemovingId] = useState(null); const { todos, addTodo, toggleTodo, removeTodo, reorderTodos } = useTodoStore(); const dragRef = useRef(null); const handleAdd = () => { if (text.trim()) { setIsAdding(true); addTodo(text); setText(''); // Reset animation state after animation completes setTimeout(() => setIsAdding(false), 300); } }; const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === 'Enter') { handleAdd(); } }; const handleDragStart = (e: React.DragEvent, id: string) => { setDraggedId(id); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/html', id); // Add dragging class to the dragged element if (dragRef.current) { dragRef.current.style.opacity = '0.5'; } }; const handleDragOver = (e: React.DragEvent, id: string) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; setDragOverId(id); }; const handleDragLeave = (e: React.DragEvent) => { e.preventDefault(); setDragOverId(null); }; const handleDrop = (e: React.DragEvent, targetId: string) => { e.preventDefault(); const draggedId = e.dataTransfer.getData('text/html'); if (draggedId && draggedId !== targetId) { const fromIndex = todos.findIndex((todo) => todo.id === draggedId); const toIndex = todos.findIndex((todo) => todo.id === targetId); if (fromIndex !== -1 && toIndex !== -1) { reorderTodos(fromIndex, toIndex); } } setDraggedId(null); setDragOverId(null); // Reset dragging styles if (dragRef.current) { dragRef.current.style.opacity = '1'; } }; const handleDragEnd = () => { setDraggedId(null); setDragOverId(null); // Reset dragging styles if (dragRef.current) { dragRef.current.style.opacity = '1'; } }; const handleRemove = (id: string) => { setRemovingId(id); // Delay the actual removal to allow for animation setTimeout(() => { removeTodo(id); setRemovingId(null); }, 300); }; return ( My Todo List setText(e.target.value)} onKeyPress={handleKeyPress} className="flex-1 px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" /> Add [list] {todos.map((todo, index) => ( handleDragStart(e, todo.id)} onDragOver={(e) => handleDragOver(e, todo.id)} onDragLeave={handleDragLeave} onDrop={(e) => handleDrop(e, todo.id)} onDragEnd={handleDragEnd} ref={draggedId === todo.id ? dragRef : null} className={` ${styles.todoItem} ${draggedId === todo.id ? styles.dragging : ''} ${dragOverId === todo.id && draggedId !== todo.id ? styles.dragOver : ''} ${removingId === todo.id ? styles.removing : ''} ${isAdding && index === todos.length - 1 ? styles.adding : ''} `} > toggleTodo(todo.id)} > {todo.text} handleRemove(todo.id)} className={styles.deleteButton} aria-label="Delete todo" > ))} [/list] {todos.length === 0 && ( No todos yet. Add one above! )} ); }; export default TodoList; [/code]