Last updated
Last updated
To get started, install the sortable preset via npm
or yarn
:
If you're eager to get started right away, here's the code you'll need:
The sortable preset builds on top of the primitives exposed by @dnd-kit/core
to help building sortable interfaces.
The SortableContext
provides information via context that is consumed by the useSortable
hook.
At a high level, the application structure to implement a sortable list with a single container looks as follows:
To implement sortable list with items that can be dropped within multiple containers, the application structure is the same, but we add as many SortableContext
providers as we have containers:
In this example, we would use the onDragOver
callback of DndContext
to detect when a draggable element is moved over a different container to insert it in that new container while dragging.
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 behaviour 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:
The SortableContext
provides information via context that is consumed by the useSortable
hook, which is covered in greater detail in the next section.
It's important that the items
prop passed to SortableContext
be sorted in the same order in which the items are rendered, otherwise you may see unexpected results.
It does not expose any callback props. To know when a sortable (draggable) item is being picked or moved over another sortable (droppable) item, use the callback props of DndContext
:
In order for the SortableContext
component to function properly, make sure it is a descendant of a DndContext
provider. You may nest multiple SortableContext
components within the same parent DndContext
.
In most cases, the draggable and droppable hooks will be attached to the same node, and therefore be identical in size. They are represented as different nodes for illustration purposes above.
In addition to the attributes
, listeners
,transform
and setNodeRef
properties, which you should already be familiar with if you've used the useDraggable
hook before, you'll notice that the useSortable
hook also provides a transition
property.
The transform
property for useSortable
represents the displacement and change of scale transformation that a sortable item needs to apply to transition to its new position without needing to update the DOM order.
The sortable preset ships with a custom coordinate getter function for the keyboard sensor that moves the active draggable to the closest sortable element in a given direction within the same DndContext
.
To use it, import the sortableKeyboardCoordinates
coordinate getter function provided by @dnd-kit/sortable
, and pass it to the coordiniateGetter
option of the Keyboard sensor.
To learn more about sensors, read the in-depth documentation on sensors:
The supported use cases of the Sortable preset include vertical lists, horizontal lists, grids, and virtualized lists. Because of the wide variety of use cases supported, it would be difficult to write a single strategy to cover all of these different use cases. Instead, the sortable preset exposes a number of different strategies you can use, that are tailored to these various use cases:
rectSortingStrategy
: This is the default value, and is suitable for most use cases. This strategy does not support virtualized lists.
verticalListSortingStrategy
: This strategy is optimized for vertical lists, and supports virtualized lists.
horizontalListSortingStrategy
: This strategy is optimized for horizontal lists, and supports virtualized lists.
rectSwappingStrategy
: Use this strategy to achieve swappable functionality.
Make sure to use the sorting strategy that is the most adapted to the use case you are building for.
In this example, we'll be using the closest center algorithm:
To learn more about collision detection algorithms and when to use one over the other, read our guide on collision detection algorithms:
First, let's go ahead and render all of our sortable items:
Next, let's wire up the custom sensors for DndContext
and add a custom collision detection strategy:
In this example, we'll be building a vertical sortable list, so we will be using the verticalListSortingStrategy
sorting strategy:
Finally, we'll need to set up event handlers on the DndContext
provider in order to update the order of the items on drag end.
The <DragOverlay>
component provides a way to render a draggable overlay that is removed from the normal document flow and is positioned relative to the viewport. The drag overlay also implements drop animations.
A common pitfall when using the DragOverlay
component is rendering the same component that calls useSortable
inside the DragOverlay
. This will lead to unexpected results, since there will be an id
collision between the two components both calling useDraggable
with the same id
, since useSortable
is an abstraction on top of useDraggable
.
For most sortable lists, we recommend you use a if your sortable list is scrollable or if the contents of the scrollable list are taller than the viewport of the window. Check out the below to learn more.
The sortable preset exposes two main concepts: and the hook:
The useSortable
hook is an abstraction that composes the and hooks:
In addition to the , the Sortable preset requires its own context provider that contains the sorted array of the unique identifiers associated to each sortable item:
As outlined above, the useSortable
hook combines both the and hooks to connect elements as both draggable sources and drop targets:
If you're already familiar with the hook, the hook should look very familiar, since, it is an abstraction on top of it.
The transform
property for the useSortable
hook behaves similarly to the property of the hook for the active sortable item, when there is no being used.
The default transition is 250
milliseconds, with an easing function set to ease
, but you can customize this and pass any valid , or set the transition argument to null
to disable transitions entirely:
For more details on the useSortable
hook, read the full .
Sensors are an abstraction to manage and listen to different input methods. If you're unfamiliar with the concept of sensors, we recommend you read the first.
By default, the sensor moves the active draggable item by 25
pixels in the direction of the arrow key that was pressed. This is an arbitrary default, and can be customized using the coordinateGetter
option of the keyboard sensor.
In this example, we'll also be setting up the sensor, which is the other sensor that is enabled by default on DndContext
if none are defined. We use the useSensor
and useSensors
hooks to initialize the sensors:
If you'd like to use the and sensors instead of the sensor, simply initialize those sensors instead:
The default collision detection algorithm of DndContext
is the algorithm. While the rectangle intersection strategy is well suited for many use cases, it can be unforgiving, since it requires both the draggable and droppable bounding rectangles to come into direct contact and intersect.
For sortable lists, we recommend using a more forgiving collision detection strategy such as the or algorithms.
For most sortable lists, we recommend you use a if your sortable list is scrollable or if the contents of the scrollable list are taller than the viewport of the window.
Instead, create a presentational version of your component that you intend on rendering in the drag overlay, and another version that is sortable and renders the presentational component. There are two recommended patterns for this, either using or.
In this example, we'll use the pattern to avoid introducing wrapper nodes:
The sortable preset provides the building blocks to build sortable interfaces.