svelte-dnd-action
svelte-dnd-action copied to clipboard
Fixes wrongful element decoration
This fixes #596, where the wrong element in the list is decorated as a shadow element.
What happens is that the shadow element is not yet present when a decoration is triggered due to, for some still unknown reason, the splice at line 159 items.splice(shadowElIdx, 0, shadowElData);
not running.
That splice is responsible for adding to the list of items a copy with the following properties:
"id": "id:dnd-shadow-placeholder-0000",
"isDndShadowItem": true
Specifically, the ID is modified to that value and the isDndShadowItem
property is added.
When that shadow copy is missing, we have one less item in the list and when the decorateShadowEl(draggableEl)
function runs, it hits the correct index position but in that index position the wrong HTML element will be.
Immediately after, this internal routine runs again, properly adds the shadow copy, then hits the correct element. The thing is, in a healthy drag, the internal routine runs just once, in the problematic version it runs twice, first without adding the shadow copy and automatically it triggers again and properly adds the shadow copy.
Here is this quick video I first show a healthy drag, then a problematic drag:
Screencast from 12-09-2024 21:04:17.webm
This fix is inelegant because it doesn't get to the root cause of the issue, but apparently it works, it uses a side effect that I noticed, in the first, problematic internal routine run, one of the items object will have the ID as "id": "id:dnd-shadow-placeholder-0000"
, and in a healthy internal routine run, the ID of the item will be the correct ID as defined by the app, so the logic here is to check if one of the items has the shadow ID, which is indicative of a problematic run, and then not to decorate the element.
Ideally, we should figure out why the problematic run happens, so any suggestion on this is appreciated.
I had a couple ideas for fixes: 1 - Undecorate the element after a problematic run. 2 - The one suggested in this PR, which is to not decorate if the side effect is noticed.
But of course I would prefer to do 3:
3 - Eventually reach the source of this problem and not even have the problematic run.
I have tons of logs I can share that allowed me to arrive at this conclusion and solution. Example of my logs about the items, using console log stringify items, right before the decoration, showing a problematic run where this runs twice:
items right before decoration:
{
"content": "Text node",
"id": "id:dnd-shadow-placeholder-0000",
"isDndShadowItem": true
}
{
"content": "Text node",
"id": "text_dOHCW0NJRU8-mqerMESzgfGCw"
}
{
"content": "Text node",
"id": "text_xSZJVOxc9NthNP68l2rxVP93f"
}
------ Another automatic run, this time healthy ---------
items right before decoration:
{
"content": "Text node",
"id": "text_AbuZBBG2dZiHu6tICxBV3YIFN",
"isDndShadowItem": true
}
{
"content": "Text node",
"id": "text_dOHCW0NJRU8-mqerMESzgfGCw"
}
{
"content": "Text node",
"id": "text_xSZJVOxc9NthNP68l2rxVP93f"
}
Also, this bug was introduced in the version 42. Before that however, the last working version for my setup was 28.
From 29 to 41, all of them freeze when I try to drop with a "getBoudingEtc..."
error.
In my setup this change doesn't seem to interfere with anything else, but I'm not sure about the wide range of use cases out there.
If it is better to discuss or further work on this before merging I'm open to it!