使用 React、Tailwind CSS 和 Dnd-kit 实现拖放来排列/排序项目

PHPz
发布: 2024-07-25 08:23:12
原创
355 人浏览过

Implementing Drag and Drop to Arrange/Sort Items with React, Tailwind CSS, and Dnd-kit

Introduction

Vous êtes-vous déjà demandé comment des applications comme Trello ou Asana gèrent leurs interfaces intuitives par glisser-déposer ? Imaginez que vous ayez une application dans laquelle les utilisateurs doivent trier facilement leurs éléments. Sans une fonction glisser-déposer fluide, cette tâche peut devenir fastidieuse et frustrante. Dans cet article de blog, nous explorerons comment implémenter une fonctionnalité de glisser-déposer dynamique à l'aide de React, Tailwind CSS et Dnd-kit pour créer une expérience utilisateur transparente pour organiser et trier les éléments.

Problème du monde réel

Dans le monde réel, les applications nécessitent souvent que les utilisateurs réorganisent les éléments en fonction de la priorité, du statut ou d'autres critères. Par exemple, un utilisateur peut avoir besoin de réorganiser rapidement ses idées lors d'une séance de brainstorming. Sans une fonctionnalité de glisser-déposer efficace, ce processus pourrait impliquer des étapes fastidieuses telles que la modification manuelle de la position des éléments ou l'utilisation de boutons de déplacement vers le haut/vers le bas inefficaces. Notre objectif est de fournir une solution qui simplifie ce processus, le rendant plus intuitif et efficace pour les utilisateurs.

Cas d'utilisation

Considérons un cas d'utilisation d'un outil de brainstorming où les utilisateurs peuvent organiser leurs idées. Les utilisateurs doivent pouvoir :

  • Ajoutez de nouvelles idées à une liste.

  • Triez et hiérarchisez ces idées en les faisant glisser et en les déposant dans l'ordre souhaité.

  • Déplacez les idées entre différentes catégories (par exemple, nouvelles idées par rapport aux anciennes idées).

Pour y parvenir, nous allons créer une application React en utilisant Vite pour la configuration du projet, Tailwind CSS pour le style et Dnd-kit pour la fonctionnalité glisser-déposer. Cette configuration nous permettra de créer une interface conviviale qui améliore la productivité et l'expérience utilisateur.

Mise en place du projet

  • Initialiser le projet Vite

npm create vite@latest my-drag-drop-app --template réagir
cd mon-application-glisser-déposer
installation npm

  • Installer les dépendances requises :

npm install tailwindcss dnd-kit réagir-chaud-toast réagir-icônes

  • Configurer Tailwind CSS :

npx tailwindcss init

  • Mettre à jour tailwind.config.js :
module.exports = { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, ], plugins: [], }
登录后复制
  • Ajoutez des directives Tailwind à index.css :
@tailwind base; @tailwind components; @tailwind utilities;
登录后复制

Implémentation du glisser-déposer

App.jsx

Le fichier App.jsx est le composant principal qui configure la présentation globale de l'application et gère l'état global.

Résumé

  • Composant principal pour gérer l'état global de l'application.

  • Utilise useState pour gérer les données et les mises à jour du projet.

  • Incorpore les composants Header et DragDropArrange pour l'interface utilisateur et les fonctionnalités.

  • Comprend le grille-pain de React-Hot-Toast pour les notifications.

Fonctions clés :

  • Gestion de l'état :Gère l'état des données du projet.

  • Gérer les nouvelles données :Fonction permettant d'ajouter de nouvelles données à l'état des données du projet.

  • Mise en page :Configure la mise en page, y compris l'en-tête, le contenu principal et les notifications.

import React, { useState } from 'react'; import { Toaster } from 'react-hot-toast'; import Header from './screens/Navigation/Header'; import DragDropArrange from './screens/DDA/DragDropArrange'; import projectDataJson from "./Data/data.json" function App() { const [projectData, setProjectData] = useState(projectDataJson) function handleNewData(data){ const tempData = projectData.newIdea; const maxNumber = (Math.random() * 100) * 1000; tempData.push({_id: maxNumber, idea: data}); setProjectData({...data, newIdea: tempData}) } return ( 
); } export default App;
登录后复制

En-tête.jsx

Le fichier Header.jsx sert de barre de navigation, fournissant un bouton pour ouvrir un formulaire permettant d'ajouter de nouveaux éléments.

Résumé :

  • Contient la navigation et un bouton pour ouvrir le formulaire de saisie d'élément.

  • Utilise useState pour gérer l'état de la visibilité du formulaire de saisie de l'élément.

  • Gère les interactions des utilisateurs pour l'ajout de nouveaux éléments.

Fonctions clés :

  • Bascule du formulaire d'élément :Gère la visibilité du formulaire de saisie d'élément.

  • Gérer les nouvelles données :transmet les nouvelles données d'élément au composant parent.

import React, { useState } from 'react'; import { PiNotepadFill } from "react-icons/pi"; import AddIdea from '../DDA/AddIdea'; const Header = ({handleNewData}) => { const [ideaTabOpen, setIdeaTabOpen] = useState(false) return ( <>  {ideaTabOpen && ( 
)} ) } export default Header
登录后复制

AddIdea.jsx

Le fichier AddIdea.jsx fournit le formulaire pour ajouter de nouveaux éléments, y compris les fonctionnalités de validation et de soumission.

Résumé :

  • Composant permettant d'ajouter de nouveaux éléments à la liste.

  • Utilise useState pour gérer les données de saisie du formulaire et le nombre de caractères.

  • Valide la longueur d'entrée et soumet de nouvelles données au composant parent.

Fonctions clés :

  • Gérer les modifications :Gère la saisie du formulaire et le nombre de caractères.

  • Handle Submit :Valide et soumet les données du formulaire au composant parent.

import React, { useState } from 'react'; import toast from "react-hot-toast"; import { Helmet } from 'react-helmet'; const AddIdea = ({ handleNewData, setIdeaTabOpen }) => { const maxLengths = 100; const [formData, setFormData] = useState(); const [remainingChars, setRemainingChars] = useState(80) const handleChange = (e) => { if (e.target.value.length > maxLengths) { toast.error(`${`Input can't be more than ${maxLengths} characters`}`); } else { setFormData(e.target.value); setRemainingChars(maxLengths - e.target.value.length); } }; const handleSubmit = (e) => { e.preventDefault(); if (!formData) { toast.error(`You don't have an idea.`); return } handleNewData(formData); setIdeaTabOpen(false) }; return ( 

{remainingChars} characters remaining

Drag Drop & Arrange | New Idea
setIdeaTabOpen(false)}>
); }; export default AddIdea;
登录后复制

DragDropArrange.jsx

Le fichier DragDropArrange.jsx est responsable de la gestion de la fonctionnalité glisser-déposer et de la mise à jour de l'ordre des éléments en fonction des interactions de l'utilisateur.

Summary:

  • Main component for handling drag-and-drop functionality.

  • Uses DndContext and SortableContext from @dnd-kit/core for drag-and-drop behavior.

  • Manages state for the data array and updates the order of items based on drag events.

  • Fetches initial data from projectData and sets it to the state.

Key Functions:

  • Handle Drag End:Manages the logic for rearranging items based on drag-and-drop actions.

  • Fetch Data:Fetches initial data and sets it to the component state.

import React, { useState, useEffect } from 'react'; import { DndContext, closestCenter } from '@dnd-kit/core'; import { arrayMove, SortableContext } from '@dnd-kit/sortable'; import { Helmet } from 'react-helmet'; import Arrange from './Arrange'; import Loader from '../Navigation/Loader'; const DragDropArrange = ({projectData}) => { const [dataArray, setDataArray] = useState({ newIdea: undefined, oldIdea: undefined, updateValue: [] }); const handleDragEnd = ({ active, over }) => { if (!over) return; const { fromList, targetId } = active.data.current; const { toList, index } = over.data.current; if (fromList === toList) { const sortedItems = arrayMove(dataArray[toList], dataArray[toList].findIndex((idea) => idea._id === targetId), index); setDataArray((prev) => ({ ...prev, [toList]: sortedItems })); } else { const draggedItem = dataArray[fromList].find((idea) => idea._id === targetId); const updatedFromList = dataArray[fromList].filter((idea) => idea._id !== targetId); const updatedToList = [...dataArray[toList].slice(0, index), draggedItem, ...dataArray[toList].slice(index)]; setDataArray((prev) => ({ ...prev, [fromList]: updatedFromList, [toList]: updatedToList })); } }; const fetchData = async () => { const { newIdea, oldIdea } = projectData; setTimeout(() => { setDataArray((prev) => ({ ...prev, newIdea, oldIdea })); }, 500); }; useEffect(() => { fetchData(); }, []); return ( 
{dataArray.newIdea && dataArray.oldIdea && ( )} {!dataArray.newIdea && !dataArray.oldIdea && ( <>
Loading...
)}
Drag Drop & Arrange | Home
); }; export default DragDropArrange
登录后复制

Arrange.jsx

The Arrange.jsx file handles the arrangement of new and old ideas, displaying them in sortable contexts.

Summary:

  • Manages the arrangement of new and old ideas.
  • Uses SortableContext for sortable behavior.

  • Displays items and manages their order within each category.

Key Functions:

  • Display Items:Renders items in their respective categories.

  • Handle Sorting:Manages the sortable behavior of items.

import React from 'react'; import { SortableContext } from '@dnd-kit/sortable'; import Drag from "./Drag"; import Drop from "./Drop"; import Lottie from 'react-lottie'; import NoData from '../../Lottie/NoData.json'; const Arrange = ({ dataArray }) => { const { newIdea, oldIdea } = dataArray; const defaultOptions = { loop: true, autoplay: true, animationData: NoData, rendererSettings: { preserveAspectRatio: "xMidYMid slice" } }; return ( 

New Idea

item._id)}> {newIdea.length > 0 && ( <> {newIdea?.map((data) => ( ))} )} {newIdea.length < 1 && ( <>
)}

Old Idea

item._id)}> {oldIdea.length > 0 && ( <> {oldIdea?.map((data) => ( ))} )} {oldIdea.length < 1 && ( <>
)}
); } export default Arrange
登录后复制

Drag.jsx

The Drag.jsx file manages the draggable items, defining their behavior and style during the drag operation.

Summary:

  • Manages the behavior and style of draggable items.

  • Uses useDraggable from @dnd-kit/core for draggable behavior.

  • Defines the drag and drop interaction for items.

Key Functions:

  • useDraggable:Provides drag-and-drop functionality.

  • Style Management:Updates the style based on drag state.

import React from 'react'; import { useDraggable } from '@dnd-kit/core'; import { IoMdMove } from "react-icons/io"; const Drag = ({ data, listType }) => { const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({ id: data._id, data: { fromList: listType, targetId: data._id }, }); const style = { transform: transform ? `translate3d(${transform.x}px, ${transform.y}px, 0)` : undefined, opacity: isDragging ? 0.5 : 1, pointerEvents: isDragging ? 'none' : 'auto', }; return ( <> 

{data?.idea}

); }; export default Drag;
登录后复制

Drop.jsx

The Drop.jsx file defines the droppable areas where items can be dropped, including visual feedback during the drag operation.

Summary:

  • Manages the behavior of droppable areas.
  • Uses useDroppable from @dnd-kit/core for droppable behavior.

  • Provides visual feedback during drag-and-drop interactions.

Key Functions:

  • useDroppable:Provides droppable functionality.

  • Handle Drop:Manages drop actions and updates the state accordingly.

import React from 'react'; import { useDroppable } from '@dnd-kit/core'; const Drop= ({ index, setDragged, listType }) => { const { isOver, setNodeRef } = useDroppable({ id: `${listType}-${index}`, data: { toList: listType, index }, }); const handleDrop = (e) => { e.preventDefault(); setDragged({ toList: listType, index }); }; return ( 
e.preventDefault()} className={`w-auto h-16 rounded-lg flex items-center justify-center text-xs text-secondary_shadow ${isOver ? ` opacity-100` : `opacity-0`}`} style={{ pointerEvents: 'none' }} >
); }; export default Drop
登录后复制

Conclusion

By following this comprehensive guide, you can create a dynamic and user-friendly drag-and-drop interface for your applications. This setup not only enhances user experience but also makes managing and organizing items intuitive and efficient. The combination of React, Tailwind CSS, and Dnd-kit provides a robust foundation for building such interactive features.

Feel free to customize and extend this implementation to suit your specific needs. Happy coding!

Source Code

You can find the complete source code for this project in my GitHub repository:
Github Link

以上是使用 React、Tailwind CSS 和 Dnd-kit 实现拖放来排列/排序项目的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!