Bonjour

Le titre n'est pas très explicite mais je vais expliquer mon souci le mieux possible.

Dans une application, j'ai un composant qui affiche plusieurs blocs de données ( ici des repas pour exemple ) et chaque bloc de repas peut être déplacé avec un drag and drop.
J'ai essayé de faire le plus simple possible avec le moins de code, n'hésitez pas à me dire s'il y a une meilleurs façon de faire ( surtout que ça peut impacter la suite ).

Je sais déjà que lorsqu'il y a des aliments dans le repas, le "glissé" est moins sympas...

Voici donc ce composant:
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import React, { useState } from "react";
import FoodList from "./FoodList";
import "../../css/mealComposition.css"
 
const Home: React.FC = () => {
 
	interface Meal {
		name: string,
		foods: Array<string>
		nbInputs: number
	}
 
	const [mealList, setMealList] = useState<Meal[]>([
		{name: "Repas 1", foods: ["banane", "tomate"]},
		{name: "Repas 2", foods: []},
		{name: "Repas 3", foods: ["pain", "viande"]},
	])
 
	const handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {
 
		const targetElement = e.target as HTMLDivElement
		setTimeout(() => targetElement.classList.add('dragging'), 0)
	}
 
	const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {
 
		const targetElement = e.target as HTMLDivElement
		const zone = document.querySelector('.mealDayContent')
		const draggedElement = document.querySelector('.dragging')
		const enterElementPositionY = targetElement.getBoundingClientRect().top
		const draggedElementPositionY = draggedElement.getBoundingClientRect().top
 
		zone.addEventListener('dragover', (e) => {
			e.preventDefault()
		})
 
		if (enterElementPositionY > draggedElementPositionY) {
			zone.insertBefore(draggedElement, targetElement.nextSibling)
		} else {
			zone.insertBefore(draggedElement, targetElement)
		}
	}
 
	const handleDragEnd = (e: React.DragEvent<HTMLDivElement>) => {
		const targetElement = e.target as HTMLDivElement
		targetElement.classList.remove('dragging')
	}
 
	const addMeal = () => {
		const newMeal = {name: `repas ${mealList.length + 1}`, foods: [], nbInputs: 0}
		const updateMealList = [...mealList, newMeal]
		setMealList(updateMealList)
	}
 
	return(
		<>
			<div className="mealDay">
				Repas de la journée: 
				<button onClick={addMeal}> + </button>
			</div>
			<div className="mealDayContent">
				{mealList.map((meal: Meal, index: number) => (
					<div 
						key={index} 
						className="meal"
						draggable="true"
						onDragStart={(e) => handleDragStart(e)}
						onDragEnter={(e) => handleDragEnter(e)}
						onDragEnd={(e) => handleDragEnd(e)}>
 
						<div className="mealName">
							{meal.name} 
						</div>
 
						<FoodList foodList={meal.foods}/>
					</div>
				))}
			</div>
		</>)
}
 
export default Home

Pour l'instant, je fais simple car j'apprends le drag and drop ( jamais fait avant encore moins avec React... !)
Il reste bien sûr à réorganiser l'objet mealList ( je me débrouillerai avec les index au moment du dragend )

Le problème, le vrai, est le suivant: mon composant Foodlist affiche une liste d'ingrédients et je voudrais pouvoir déplacer ces ingrédients
à l'intérieur d'un repas dans la foodList, mais aussi vers une foodList d'un autre repas.

Par exemple: je dois pouvoir glisser tomate dans le repas 3 ( n'importe ou dans la liste, avant le pain, après la viande ou entre les deux )

voici donc mon composant FoodList:
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React from "react";
 
interface FoodListProps {
	foodList: Array<string>
}
 
const FoodList: React.FC<FoodListProps> = ({foodList}: FoodListProps) => {
	return (
		<div className="foodList">
			{foodList.map((food: string, index: number) => (
				<div key={index} draggable="true" className="food">
					{food}
				</div>
			))}
		</div>
	)
}
 
export default FoodList

Quelles seraient les pistes ? Parce que pour le moment, le composant parent a un impact sur ce composant: ça déplace les aliments en dehors des repas !
( ce qui est tout à fait normal, vu que je n'ai rien codé! )
Je pourrais m'en sortir si j'avais tout dans un composant parent ( mapping des aliments ), mais je voudrais justement savoir comment faire dans ce cas.
De plus React, par principe, ça sert à faire des composants. Donc tout faire dans le même composant n'est pas correct.

J'ai mis un peu de CSS (pas la priorité pour l'instant):
Code css : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
input {
	display: block;
	margin-bottom: 10px;
}
 
.meal {
	border: 2px solid red;
	border-radius: 4px;
	margin: 10px;
	padding: 10px;
	cursor: move;
}
 
.mealName {
	margin-bottom: 10px;
	font-size: 25px;
}
 
.dragging {
	visibility: hidden;
}
 
.food {
	border: 1px solid black;
	border-radius: 4px;
	padding: 5px;
	margin-bottom: 4px;
}
 
.foodList {
	display: flex;
	justify-content: start;
	align-items: start;
	flex-direction: column;
}

Évidemment, une piste sans librairie, parce que je veux apprendre...

Merci d'avance.

Laurent.