Reparenting
There are situations were you want to change the MuuriComponent parent of the dragging Item while a drag is occurring. Here's an example in the gif below.

The implementation of this feature in Muuri-react manages to have the following characteristics
- The component is not
unmounted / re-mounted(best performance). - Items don't have to be
configured(very easy to implement). - The internal
stateof the Item is maintained (best developer experience).
How it works ๐
There are two types of events:
- When the Item is
draggedto another MuuriComponent (but not released). - When the Item is
releasedin another MuuriComponent.
You can interact with the first event in the Item via the useGrid hook. Instead you have to interact with the second event through the MuuriComponent onSend prop.
This division allows you to have the best performance and a better user experience. In the example of the gif, you can figure out which grid the Item is on, for changing the color of the right strip, only re-rendering the Item and not all the MuuriComponents.
Rules ๐
There are a few simple rules for implementing reparenting
- The Items must have unique
keysbetween them, even if they do not share the same MuuriComponent parent. - You have to choose the MuuriComponents of which the Item can be a child by providing
group ids. - When an Item changes parent you have to sync the state with the
onSendprop.
Usage ๐
let's try to reproduce a part of the code of the example in gif, we focus on writing the onSend function later.
When an Item is dragged to another MuuriComponent as in the gif, we must update the Items state.
The MuuriComponents must re-render with their updated children, considering that the Item that has been dragged must be inserted in the new MuuriComponent of which it is now a child. Let's create the onSend method for the first MuuriComponent.
It is possible to simply insert the Item at the bottom as the last component (items.done.concat(transferredItem)), without worrying about the position in which it was dragged. To keep the code cleaner we can create a function that works for each MuuriComponent and keep it in a different file.
We can now use the method for each MuuriComponent.
Hook: useGrid ๐
The useGrid hook allow you to know which MuuriComponent the Item is on. See more here.
Exclusive drop ๐ซ
You can do some advanced stuff and control within which MuuriComponents a specific Item can be sorted and dragged into. To do that you can provide the groupId of these MuuriComponents in the dragSort prop.
In the example below you can send an Item from the first MuuriComponent to the second one, but not the opposite.
If you want to implement a more complex logic, different for each Item, you can provide a function which receives the dragged Item as its first argument and should return an array of Muuri instances. You can easily access these instances by providing ids and groupIds to the muuriMap.
Manual reparenting ๐ท
Reparenting is performed following a drag and drop. However, you can run it manually through the Muuri instance. This way group control is not enabled and you have to call onSend manually. See more about Muuri here.
Note that you can also access the grids with the muuriMap.
How is that possible? ๐คจ
You may have wondered how it is possible that, during the reparenting, the Item can be inserted among the children of the new MuuriComponent in any position (for example at the bottom), without worrying about the position in which it was dragged. This is because the order of the Item components is separated from the order of the elements in the DOM. This allows to have a very simple implementation (In addition the Muuri-react diffing algorithm is optimized for insertions at the bottom).
