NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #2061 most downloaded on npm
dnd kit – a lightweight React library for building performant and accessible drag and drop experiences
Last release 2 years ago
no release in 18 months
Ships unpredictably
gaps range from 9 days to 13 months
Nearly every release is documented
notes for 41 of 41 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
140 releases · first in 2021
One column per quarter.
### Patch Changes - #650 `2439aae` Thanks @clauderic! - - Fixed React warning in development when unmounting a component that uses the useDraggable ho
2439aae Thanks @clauderic! - - Fixed React warning in development when unmounting a component that uses the useDraggable hook by ensuring that the ResizeObserver is disconnected in a cleanup effect.Nothing published for this version
### Patch Changes - #646 `b3b185d` Thanks @lukesmurray! - Export DraggableAttributes interface for consumers to use when interfacing with useDraggable
b3b185d Thanks @lukesmurray! - Export DraggableAttributes interface for consumers to use when interfacing with useDraggable hook.Nothing published for this version
### Patch Changes - #573 `cee1d88` Thanks @clauderic! - Only use ResizeObserver in useDroppable and if it is available in the execution environment.
cee1d88 Thanks @clauderic! - Only use ResizeObserver in useDroppable and <DragOverlay> if it is available in the execution environment.Nothing published for this version
This is a breaking change that requires all collision detection strategies to be updated to return an array of Collision rather than a single UniqueId…
#558 f3ad20d Thanks @clauderic! - Refactor of the CollisionDetection interface to return an array of Collisions:
+export interface Collision {
+ id: UniqueIdentifier;
+ data?: Record<string, any>;
+}
export type CollisionDetection = (args: {
active: Active;
collisionRect: ClientRect;
droppableContainers: DroppableContainer[];
pointerCoordinates: Coordinates | null;
-}) => UniqueIdentifier;
+}) => Collision[];
This is a breaking change that requires all collision detection strategies to be updated to return an array of Collision rather than a single UniqueIdentifier
The over property remains a single UniqueIdentifier, and is set to the first item in returned in the collisions array.
Consumers can also access the collisions property which can be used to implement use-cases such as combining droppables in user-land.
The onDragMove, onDragOver and onDragEnd callbacks are also updated to receive the collisions array property.
Built-in collision detections such as rectIntersection, closestCenter, closestCorners and pointerWithin adhere to the CollisionDescriptor interface, which extends the Collision interface:
export interface CollisionDescriptor extends Collision {
data: {
droppableContainer: DroppableContainer;
value: number;
[key: string]: any;
};
}
Consumers can also access the array of collisions in components wrapped by <DndContext> via the useDndContext() hook:
import {useDndContext} from '@dnd-kit/core';
function MyComponent() {
const {collisions} = useDndContext();
}
#561 02edd26 Thanks @clauderic! - Droppable containers now observe the node they are attached to via setNodeRef using ResizeObserver while dragging.
This behaviour can be configured using the newly introduced resizeObserverConfig property.
interface ResizeObserverConfig {
/** Whether the ResizeObserver should be disabled entirely */
disabled?: boolean;
/** Resize events may affect the layout and position of other droppable containers.
* Specify an array of `UniqueIdentifier` of droppable containers that should also be re-measured
* when this droppable container resizes. Specifying an empty array re-measures all droppable containers.
*/
updateMeasurementsFor?: UniqueIdentifier[];
/** Represents the debounce timeout between when resize events are observed and when elements are re-measured */
timeout?: number;
}
By default, only the current droppable is scheduled to be re-measured when a resize event is observed. However, this may not be suitable for all use-cases. When an element resizes, it can affect the layout and position of other elements, such that it may be necessary to re-measure other droppable nodes in response to that single resize event. The recomputeIds property can be used to specify which droppable ids should be re-measured in response to resize events being observed.
For example, the useSortable preset re-computes the measurements of all sortable elements after the element that resizes, so long as they are within the same SortableContext as the element that resizes, since it's highly likely that their layout will also shift.
Specifying an empty array for recomputeIds forces all droppable containers to be re-measured.
For consumers that were relyings on the internals of DndContext using useDndContext(), the willRecomputeLayouts property has been renamed to measuringScheduled, and the recomputeLayouts method has been renamed to measureDroppableContainers, and now optionally accepts an array of droppable UniqueIdentifier that should be scheduled to be re-measured.
#518 6310227 Thanks @clauderic! - Major internal refactor of measuring and collision detection.
Previously, all collision detection algorithms were relative to the top and left points of the document. While this approach worked in most situations, it broke down in a number of different use-cases, such as fixed position droppable containers and trying to drag between containers that had different scroll positions.
This new approach changes the frame of comparison to be relative to the viewport. This is a major breaking change, and will need to be released under a new major version bump.
@dnd-kit now ignores only the transforms applied to the draggable / droppable node itself, but considers all the transforms applied to its ancestors. This should provide the right balance of flexibility for most consumers.
ViewRect, LayoutRect to just a single concept of ClientRect.
ClientRect interface no longer holds the offsetTop and offsetLeft properties. For most use-cases, you can replace offsetTop with top and offsetLeft with left.@dnd-kit/core package with getClientRect:
getBoundingClientRectgetViewRectgetLayoutRectgetViewportLayoutRecttranslatedRect from the SensorContext interface. Replace usage with collisionRect.activeNodeClientRect on the DndContext interface. Replace with activeNodeRect.#569 e7ac3d4 Thanks @clauderic! - Separated context into public and internal context providers. Certain properties that used to be available on the public DndContextDescriptor interface have been moved to the internal context provider and are no longer exposed to consumers:
interface DndContextDescriptor {
- dispatch: React.Dispatch<Actions>;
- activators: SyntheticListeners;
- ariaDescribedById: {
- draggable: UniqueIdentifier;
- };
}
Having two distinct context providers will allow to keep certain internals such as dispatch hidden from consumers.
It also serves as an optimization until context selectors are implemented in React, properties that change often, such as the droppable containers and droppable rects, the transform value and array of collisions should be stored on a different context provider to limit un-necessary re-renders in useDraggable, useDroppable and useSortable.
The <InternalContext.Provider> is also reset to its default values within <DragOverlay>. This paves the way towards being able to seamlessly use components that use hooks such as useDraggable and useDroppable as children of <DragOverlay> without causing interference or namespace collisions.
Consumers can still make calls to useDndContext() to get the active or over properties if they wish to re-render the component rendered within DragOverlay in response to user interaction, since those use the PublicContext
c6c67cb Thanks @avgrad! - - Added pointer coordinates to collision detection
pointerWithin collision algorithmNothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
For example, checking if an element is an instance of an HTMLElement is normally done like so:
#509 1c6369e Thanks @clauderic! - Helpers have been updated to support rendering in foreign window contexts (via ReactDOM.render or ReactDOM.createPortal).
For example, checking if an element is an instance of an HTMLElement is normally done like so:
if (element instanceof HTMLElement)
However, when rendering in a different window, this can return false even if the element is indeed an HTMLElement, because this code is equivalent to:
if (element instanceof window.HTMLElement)
And in this case, the window of the element is different from the main execution context window, because we are rendering via a portal into another window.
This can be solved by finding the local window of the element:
const elementWindow = element.ownerDocument.defaultView;
if (element instanceof elementWindow.HTMLElement)
Updated dependencies [1c6369e]:
Nothing published for this version
Nothing published for this version
### Patch Changes - #504 `d973cc6` Thanks @clauderic! - Sensors that extend the AbstractPointerSensor now prevent HTML Drag and Drop API events from b
d973cc6 Thanks @clauderic! - Sensors that extend the AbstractPointerSensor now prevent HTML Drag and Drop API events from being triggered while the sensor is activated.Nothing published for this version
### Patch Changes - #479 `5ec3310` Thanks @mdrobny! - fix: bind handleCancel handler in AbstractPointerSensor to current execution context (this).
Nothing published for this version
Also fixed issues with collision detection:
#337 05d6a78 Thanks @clauderic! - React updates in non-synthetic event handlers are now batched to reduce re-renders and prepare for React 18.
Also fixed issues with collision detection:
#427 f96cb5d Thanks @clauderic! - - Using transform-agnostic measurements for the DragOverlay node.
overlayNode property to dragOverlay on the DndContextDescriptor interface.#372 dbc9601 Thanks @clauderic! - Refactored DroppableContainers type from Record<UniqueIdentifier, DroppableContainer to a custom instance that extends the Map constructor and adds a few other methods such as toArray(), getEnabled() and getNodeFor(id).
A unique key property was also added to the DraggableNode and DroppableContainer interfaces. This prevents potential race conditions in the mount and cleanup effects of useDraggable and useDroppable. It's possible for the clean-up effect to run after another React component using useDraggable or useDroppable mounts, which causes the newly mounted element to accidentally be un-registered.
#379 8d70540 Thanks @clauderic! - The layoutMeasuring prop of DndContext has been renamed to measuring.
The options that could previously be passed to the layoutMeasuring prop now need to be passed as:
<DndContext
- layoutMeasuring={options}
+ measuring={{
+ droppable: options
+ }}
The LayoutMeasuring type has been renamed to MeasuringConfiguration. The LayoutMeasuringStrategy and LayoutMeasuringFrequency enums have also been renamed to MeasuringStrategy and MeasuringFrequency.
This refactor allows consumers to configure how to measure both droppable and draggable nodes. By default, @dnd-kit ignores transforms when measuring draggable nodes. This beahviour can now be configured:
import {
DndContext,
getBoundingClientRect,
MeasuringConfiguration,
} from '@dnd-kit/core';
const measuringConfig: MeasuringConfiguration = {
draggable: {
measure: getBoundingClientRect,
},
};
function App() {
return <DndContext measuring={measuringConfig} />;
}
#350 a13dbb6 Thanks @wmain! - Breaking change: The CollisionDetection interface has been refactored. It now receives an object that contains the active draggable node, along with the collisionRect and an array of droppableContainers.
If you've built custom collision detection algorithms, you'll need to update them. Refer to this PR for examples of how to refactor collision detection functions to the new CollisionDetection interface.
The sortableKeyboardCoordinates method has also been updated since it relies on the closestCorners collision detection algorithm. If you were using collision detection strategies in a custom sortableKeyboardCoordinates method, you'll need to update those as well.
#334 13be602 Thanks @trentmwillis! - Now passing activatorEvent as an argument to modifiers
#376 aede2cc Thanks @clauderic! - Mouse, Pointer, Touch sensors now cancel dragging on visibility change and window resize. The Keyboard sensor already cancelled dragging on window resize. It now also cancels dragging on visibility change.
#399 a32a4c5 Thanks @supersebh! - Added support for tolerance in DistanceConstrain. As soon as the tolerance is exceeded, the drag operation will be aborted, unless it has already started (because distance criteria was met).
Example usage:
// Require the pointer be moved by 10 pixels vertically to initiate drag operation
// Abort if the pointer is moved by more than 5 pixels horizontally.
{
distance: {y: 10},
tolerance: {x: 5},
}
Be careful not to pick conflicting settings for distance and tolerance if used together. For example, picking a tolerance that is lower than the distance in the same axis would result in the activation constraint never being met.
#408 dea715c Thanks @wmain! - The collision rect is now completely based on the position of the DragOverlay when it is used. Previously, only the width and height properties of the DragOverlay were used for the collision rect, while the top, left, bottom and right properties were derived from the active node rect. This new approach is more aligned with developers would expect, but could cause issues for consumers that were relying on the previous (incorrect) behavior.
#433 c447880 Thanks @clauderic! - Fix unwanted animations when items in sortable context change
#415 2ba6dfe Thanks @cantrellnm! - Prevent getScrollableAncestors from continuing to search if a fixed position node is found.
#377 422d083 Thanks @clauderic! - Pointer, Mouse and Touch sensors now stop propagation of click events once activation constraints are met.
#375 c4b21b4 Thanks @clauderic! - Prevent context menu from opening when pointer sensor is active
5a41340 Thanks @clauderic! - Pointer, Mouse and Touch sensors now prevent selection changes and clear any existing selection ranges once activation constraints are met.
e2ee0dc Thanks @clauderic! - Reset the over internal state of <DndContext /> on drop.
1fe9b5c Thanks @clauderic! - Sensors may now specify a static setup method that will be invoked when <DndContext> mounts. The setup method may optionally also return a teardown function that will be invoked when the <DndContext> associated with that sensor unmounts.
#430 46ec5e4 Thanks @clauderic! - Fix duplicate scroll ancestor detection. In some scenarios, an element could be added twice to the list of detected scrollable ancestors, resulting in invalid offsets.
#371 7006464 Thanks @clauderic! - fix: do not wrap consumer-defined handlers in batchedUpdates
1fe9b5c Thanks @clauderic! - The TouchSensor attempts to prevent the default browser behavior of scrolling the page by calling event.preventDefault() in the touchmove event listener. This wasn't working in iOS Safari due to a bug with dynamically attached touchmove event listeners. Adding a non-passive, non-capture touchmove event listener before dynamically attaching other touchmove event listeners solves the issue.
Updated dependencies [0e628bc, 13be602, 1f5ca27]:
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →