Minor Changes
-
#1909
87bf1e6Thanks @clauderic! - Addaccelerationandthresholdoptions to theAutoScrollerplugin.accelerationcontrols the base scroll speed multiplier (default:25).thresholdcontrols the percentage of container dimensions that defines the scroll activation zone (default:0.2). Accepts a single number for both axes or{ x, y }for per-axis control. Setting an axis to0disables auto-scrolling on that axis.
AutoScroller.configure({ acceleration: 15, threshold: {x: 0, y: 0.3}, });
-
#1966
521f760Thanks @lixiaoyan! - Sortablepluginsnow acceptsCustomizable<Plugins>, allowing a function that receives the default plugins to extend them rather than replace them.This prevents accidentally losing the default Sortable plugins (
SortableKeyboardPlugin,OptimisticSortingPlugin) when adding per-entity plugin configuration such asFeedback.configure().// Extend defaults useSortable({ id: 'item', index: 0, plugins: (defaults) => [ ...defaults, Feedback.configure({feedback: 'clone'}), ], }); // Replace defaults (same behavior as before) useSortable({ id: 'item', index: 0, plugins: [MyPlugin], });
-
#1938
c001272Thanks @clauderic! - TheDropAnimationFunctioncontext now includessource, providing access to the draggable entity for conditional animation logic.Feedback.configure({ dropAnimation: async (context) => { if (context.source.type === 'service-draggable') return; // custom animation... }, });
-
#1923
cde61e4Thanks @clauderic! - Batch entity identity changes to prevent collision oscillation during virtualized sorting.When entities swap ids (e.g. as
react-windowrecycles DOM nodes during a drag), multiple registry updates could fire in an interleaved order, causing the collision detector to momentarily see stale or duplicate entries and oscillate between targets.Entity
idchanges are now deferred to a microtask and flushed atomically in a singlebatch(), ensuring:- The collision notifier skips detection while id changes are pending
- The registry cleans up ghost registrations (stale keys left behind after an id swap)
-
#2001
78af13bThanks @lixiaoyan! - Support a callback form for thefeedbackoption in theFeedbackplugin, allowing the feedback type to be chosen dynamically based on the source and manager context (e.g. activator type).Feedback.configure({ feedback: (source, manager) => { return isKeyboardEvent(manager.dragOperation.activatorEvent) ? 'clone' : 'default'; }, });
-
#1908
1328af8Thanks @clauderic! - AddkeyboardTransitionoption to theFeedbackplugin for customizing or disabling the CSS transition applied when moving elements via keyboard.By default, keyboard-driven moves animate with
250ms cubic-bezier(0.25, 1, 0.5, 1). You can now customize thedurationandeasing, or set the option tonullto disable the transition entirely.Feedback.configure({ keyboardTransition: {duration: 150, easing: 'ease-out'}, });
-
#1919
bfff7deThanks @clauderic! - The Feedback plugin now supports full CSStransformproperty for compatibility with libraries like react-window v2 that position elements via transforms. Transform-related CSS transitions are filtered out to prevent conflicts with Feedback-managed properties. The ResizeObserver computes shapes from CSS values rather than re-measuring the element, avoiding mid-transition measurement errors. Sortable'sanimate()cancels CSS transitions on transform-related properties before measuring to ensure correct FLIP deltas. -
#1915
9b24dffThanks @clauderic! - Redesign event type system to follow the DOM EventMap pattern. IntroducesDragDropEventMapfor event object types andDragDropEventHandlersfor event handler signatures, replacing the ambiguously namedDragDropEvents. Event type aliases (CollisionEvent,DragStartEvent, etc.) now derive directly fromDragDropEventMaprather than usingParameters<>extraction.Migration guide
DragDropEventshas been split into two types:DragDropEventMap— maps event names to event object types (likeWindowEventMap)DragDropEventHandlers— maps event names to(event, manager) => voidhandler signatures
- If you were importing
DragDropEventsto type event objects, useDragDropEventMapinstead:// Before type MyEvent = Parameters<DragDropEvents<D, P, M>['dragend']>[0]; // After type MyEvent = DragDropEventMap<D, P, M>['dragend'];
- If you were importing
DragDropEventsto type event handlers, useDragDropEventHandlersinstead:// Before const handler: DragDropEvents<D, P, M>['dragend'] = (event, manager) => {}; // After const handler: DragDropEventHandlers<D, P, M>['dragend'] = ( event, manager ) => {};
- The
DragDropEventsre-export from@dnd-kit/reactand@dnd-kit/solidhas been removed. ImportDragDropEventMaporDragDropEventHandlersfrom@dnd-kit/abstractdirectly if needed. - Convenience aliases (
CollisionEvent,DragStartEvent,DragEndEvent, etc.) are unchanged and continue to work as before.
-
#1938
e69387dThanks @clauderic! - Added per-entity plugin configuration and movedfeedbackfrom the Draggable entity to the Feedback plugin.Draggable entities now accept a
pluginsproperty for per-entity plugin configuration, using the existingPlugin.configure()pattern. Plugins can read per-entity options viasource.pluginConfig(PluginClass).The
feedbackproperty ('default' | 'move' | 'clone' | 'none') has been moved from the Draggable entity toFeedbackOptions. Drop animation can also now be configured per-draggable.Plugins listed in an entity's
pluginsarray are auto-registered on the manager if not already present. The Sortable class now uses this generic mechanism instead of its own custom registration logic.Migration guide
The
feedbackproperty has been moved from the draggable/sortable hook input to per-entity Feedback plugin configuration.Before:
import {FeedbackType} from '@dnd-kit/dom'; useDraggable({id: 'item', feedback: 'clone'}); useSortable({id: 'item', index: 0, feedback: 'clone'});
After:
import {Feedback} from '@dnd-kit/dom'; useDraggable({ id: 'item', plugins: [Feedback.configure({feedback: 'clone'})], }); useSortable({ id: 'item', index: 0, plugins: (defaults) => [ ...defaults, Feedback.configure({feedback: 'clone'}), ], });
Drop animation can now be configured per-draggable:
useDraggable({ id: 'item', plugins: [Feedback.configure({feedback: 'clone', dropAnimation: null})], });
-
#1905
11ff2ebThanks @clauderic! - RenamedStyleSheetManagertoStyleInjectorand centralized CSPnonceconfiguration.The
StyleInjectorplugin now accepts anonceoption that is applied to all injected<style>elements. Thenonceoptions have been removed from theCursor,PreventSelection, andFeedbackplugin options.Before:
const manager = new DragDropManager({ plugins: (defaults) => [ ...defaults, Cursor.configure({nonce: 'abc123'}), PreventSelection.configure({nonce: 'abc123'}), ], });
After:
const manager = new DragDropManager({ plugins: (defaults) => [ ...defaults, StyleInjector.configure({nonce: 'abc123'}), ], });
The
CursorandPreventSelectionplugins now route their style injection through theStyleInjector, so all injected styles respect the centralizednonceconfiguration. -
#1916
7489265Thanks @clauderic! - RewritescrollIntoViewIfNeededwith manual offset calculations for correct behavior in nested scroll containers. ThecenterIfNeededboolean parameter has been replaced with an options object acceptingblockandinlineproperties ('center','nearest', or'none').
Patch Changes
-
#1918
4bc7e71Thanks @clauderic! - Animation resolution now uses last-wins semantics matching CSS composite order.getFinalKeyframereturns the last matching keyframe across all running animations instead of short-circuiting on the first match.getProjectedTransformcollects the latest value per CSS property (transform,translate,scale) rather than accumulating transforms additively. -
#1948
532ae9bThanks @clauderic! - Fix Feedback plugin placeholder not repositioning when siblings are moved around a stationary source element.When a VDOM framework (e.g., Preact, Vue) reorders sibling elements during a drag operation, the source element and placeholder may remain in the DOM but no longer be adjacent. The existing
documentMutationObserveronly handled cases where the source or placeholder itself was re-added to the DOM. This adds a fallback adjacency check after processing all mutation entries, ensuring the placeholder stays next to the source element regardless of how siblings are rearranged. -
#1968
267c97cThanks @clauderic! - Fix clone feedback placeholder dropping inline SVG children during mutation sync.The element mutation observer used
innerHTMLto sync child changes from the dragged element to its placeholder. This text-based serialization loses SVG namespace information, causing inline SVG elements (e.g. icon components) to be stripped from the placeholder. The placeholder then measures with incorrect dimensions, producing a misaligned drop animation.Replaced
innerHTMLwithreplaceChildren(...element.cloneNode(true).childNodes), which performs a namespace-aware deep clone. -
#1987
462e435Thanks @clauderic! - fix: resolve DTS build errors with TypeScript 5.9 on Node 20Add explicit return type annotations to avoid
[dispose]serialization failures during declaration emit, and fixuseRefreadonly errors for React 19 type compatibility. -
#1971
8fc1962Thanks @clauderic! - Added LICENSE file to all published packages. -
#1983
88d5ef9Thanks @clauderic! - Fixed memory leak inListenersclass where thebindcleanup function did not remove entries from the internalentriesset, causing detached DOM nodes to be retained in memory. -
#1934
688e00fThanks @clauderic! - FixedsetPointerCaptureerror on touch devices caused by stale pointer activation.When a touch was released during the activation delay and followed by a quick re-touch, the pending delay timer from the first touch could fire with a stale
pointerId, causingsetPointerCaptureto throw. ThePointerSensornow properly aborts the activation controller during cleanup to cancel pending delay timers, and defensively handlessetPointerCapturefailures. -
#1953
cdaebffThanks @ImBaedin! - Fix sortable type narrowing soisSortable(event.operation.source)narrows to a sortable draggable with access toinitialIndex, and re-export the drag event type aliases from@dnd-kit/vue. -
#1946
5a2ed80Thanks @mattersj! - recalculate AutoScroller options in the effect to avoid stale data -
Updated dependencies [
cde61e4,a5935e0,462e435,9b24dff,8fc1962,8115a57,e69387d,4e35963]:- @dnd-kit/abstract@0.4.0
- @dnd-kit/collision@0.4.0
- @dnd-kit/geometry@0.4.0
- @dnd-kit/state@0.4.0