Requirements
nav items should be draggable nav items tree should be draggable nav items should be draggable across multiple groups navigation groups also should be draggable
DND - Kit
DND-Kit is a react toolkit that ads a “drag and drop” functionality to markup elements.
There are 2 hooks:
Draggable, which allows the user to drag the element and Droppable which allows the user to drop the dragged element in.
The Draggable and Droppable hooks can only be used within a <DndContext> element.
Context provider
Everything that can be dragged or sorted should be wrapped between a <DndContext> </DndContext> component. Explained Hooks
Draggable
Used to create an element that can be dragged into a droppable element.
Droppable
Used to create an element where draggable can be dropped into.
Sortable
Sortable is a preset built on top of @dnd-kit/coreto help building sortable interfaces.
We only use the Sortable elements. Explained
The sortable preset exposes two main concepts: and the hook: The SortableContext provides information via context that is consumed by the useSortable hook. The useSortable hook is an abstraction that composes the and hooks:
DndContext Parent element of everything SortableContext > Parent “container” element where drag and drop can happen (For Bolt: Navbar, Nav_group, Page ) Droppable > All the elements where items can be dropped in. (For Bolt: Navbar, Nav_group, Page, Section, Row, Column ) Draggable > These are the items that can actually be dragged around. (For Bolt: Nav_groups, nav_items, sections, rows, columns, controls, content_blocks, component_blocks, etc....)
Note: items can be both draggable and droppable. For example: A navgroup can be draggable as it can be dragged into another navbar, but its body is droppable because nav_items can be dropped into.
If you paid close attention to the illustration above, you may also have noticed that we added a droppable zone around each sortable context. This isn't required, but will likely be the behavior most people want. If you move all sortable items from one column into the other, you will need a droppable zone for the empty column so that you may drag sortable items back into that empty column:
Bolt set up
We control the draggable environment using parameters in the block settings data.
Block settings data
sortable_context (Boolean) - > the element becomes a SortableContext element. droppable (Boolean) - > The element body is droppable. (Other items can be dropped inside) draggable (Boolean) - > The can be dragged into a droppable element.
Droppable control
With the parameters above, we have everything in place to define which what items can dragged and what items can be dropped into. Now we need to control which draggable item can be placed in which droppable item. For example: a page can not be dragged into a nav_item.
We do this with the accepts parameter in the block settings data. Each block contains the parameters, which contains an array of strings. Each string is the name of the block that it accepts.
Example: navigation_group accepts: navigation_item, button and input. This means that all these blocks can be dropped into it.
Note: accepts is not a default parameter in DND kit. It’s a custom functionality that we’ve added using the DND data in userDroppable . The data contains the our custom accepts parameter with the array of strings.
Item order
Now that we now which items can be dropped into (and contain draggable items), we need to store the order in which they appear in the droppable items.
We use the parameter items (array of string ids) for this, which is present for all blocks in the block data file. When the user updates the order of draggable items, we update the array with the new order of of the draggable ids.