@mk-drag-and-drop/dom 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -369,14 +369,15 @@ Same-container sortable preview keeps its movement-responsive first-placement
369
369
  behavior: forward movement places after a newly active target, backward movement
370
370
  places before, and no sortable-axis movement uses the target midpoint. When a
371
371
  sortable item first enters a different DOM container, the initial side is based
372
- on the pointer position against the target midpoint on the sortable axis: above
373
- or left of midpoint places before, while below or right of midpoint places
374
- after. Rect-based targeting such as `centerToCenter` still selects the active
375
- target; cross-container initial preview side follows the pointer.
376
-
377
- `placementBoundary` is used after a preview placement already exists to control
378
- same-target reversal and hysteresis thresholds. It does not decide the initial
379
- side for cross-container sortable entry.
372
+ on the current sortable placement position against the target midpoint on the
373
+ sortable axis: above or left of midpoint places before, while below or right of
374
+ midpoint places after. Pointer-based targeting uses the pointer as that position;
375
+ rect-based targeting such as `centerToCenter` uses the overlay center.
376
+
377
+ `placementBoundary` is used after a preview placement already has an established
378
+ movement direction to control same-target reversal and hysteresis thresholds. It
379
+ does not decide the initial side for cross-container sortable entry or delay the
380
+ first movement that follows midpoint-based entry into a list.
380
381
 
381
382
  ## Modifiers
382
383
 
@@ -12,6 +12,8 @@ export type SortablePreviewPlacementState = {
12
12
  activeDropTargetId: string | null;
13
13
  placement: SortablePlacementSide | null;
14
14
  movementDirection: SortableAxisMovementDirection;
15
+ containerElement: HTMLElement | null;
16
+ pendingMidpointInitialPlacement: boolean;
15
17
  };
16
18
  export type SortablePreviewPlacementDecision = {
17
19
  placement: SortablePlacementSide;
@@ -36,10 +38,6 @@ export declare function moveSortablePreview(input: {
36
38
  runtime: DomSortableRuntime;
37
39
  draggedDraggableId: string;
38
40
  activeDropTargetId: string | null;
39
- pointerPosition: {
40
- x: number;
41
- y: number;
42
- };
43
41
  placementPosition: {
44
42
  x: number;
45
43
  y: number;
@@ -53,10 +51,6 @@ export declare function getSortablePreviewPlacement(input: {
53
51
  x: number;
54
52
  y: number;
55
53
  };
56
- midpointPlacementPosition?: {
57
- x: number;
58
- y: number;
59
- };
60
54
  movement: SortablePointerMovementState | null;
61
55
  previewPlacement: SortablePreviewPlacementState | null;
62
56
  options: NormalizedSortableOptions;
@@ -76,10 +76,15 @@ export function moveSortablePreview(input) {
76
76
  addRegistrationContainerId(measurementIds, target);
77
77
  if (target.capabilities.container) {
78
78
  measurementIds.add(target.id);
79
+ const previousListElement = input.registry.activeDrag.previewPlacement?.containerElement ?? null;
80
+ const pendingMidpointInitialPlacement = draggedElement.parentElement !== target.element ||
81
+ (previousListElement !== null && previousListElement !== target.element);
79
82
  setSortablePreviewPlacementState({
80
83
  registry: input.registry,
81
84
  activeDropTargetId: target.id,
82
85
  placement: null,
86
+ containerElement: target.element,
87
+ pendingMidpointInitialPlacement,
83
88
  movementDirection: getCurrentAxisMovementDirection({
84
89
  placementPosition: input.placementPosition,
85
90
  movement: input.registry.activeDrag.pointerMovement,
@@ -106,9 +111,13 @@ export function moveSortablePreview(input) {
106
111
  if (!listElement) {
107
112
  return;
108
113
  }
109
- const sourceListElement = input.registry.activeDrag.snapshots.get(input.draggedDraggableId)?.parent ??
110
- draggedElement.parentElement;
111
- const useMidpointInitialPlacement = sourceListElement !== listElement;
114
+ const previousPlacement = input.registry.activeDrag.previewPlacement;
115
+ const previousListElement = previousPlacement?.containerElement ?? null;
116
+ const useMidpointInitialPlacement = draggedElement.parentElement !== listElement ||
117
+ (previousListElement !== null && previousListElement !== listElement) ||
118
+ (previousPlacement?.placement === null &&
119
+ previousPlacement.pendingMidpointInitialPlacement &&
120
+ previousListElement === listElement);
112
121
  if (!target.capabilities.sortable) {
113
122
  return;
114
123
  }
@@ -120,9 +129,6 @@ export function moveSortablePreview(input) {
120
129
  activeDropTargetId,
121
130
  targetElement,
122
131
  placementPosition: input.placementPosition,
123
- midpointPlacementPosition: useMidpointInitialPlacement
124
- ? input.pointerPosition
125
- : input.placementPosition,
126
132
  movement: input.registry.activeDrag.pointerMovement,
127
133
  previewPlacement: input.registry.activeDrag.previewPlacement,
128
134
  options: input.options,
@@ -134,6 +140,8 @@ export function moveSortablePreview(input) {
134
140
  activeDropTargetId,
135
141
  placement,
136
142
  movementDirection: placementDecision.movementDirection,
143
+ containerElement: listElement,
144
+ pendingMidpointInitialPlacement: false,
137
145
  });
138
146
  if (isSortablePreviewAlreadyPlaced({
139
147
  draggedElement,
@@ -160,7 +168,6 @@ export function moveSortablePreview(input) {
160
168
  export function getSortablePreviewPlacement(input) {
161
169
  const axis = input.options.axis;
162
170
  const axisPosition = getAxisPosition(input.placementPosition, axis);
163
- const midpointAxisPosition = getAxisPosition(input.midpointPlacementPosition ?? input.placementPosition, axis);
164
171
  const targetRect = input.targetElement.getBoundingClientRect();
165
172
  const currentDirection = getCurrentAxisMovementDirection({
166
173
  placementPosition: input.placementPosition,
@@ -172,19 +179,24 @@ export function getSortablePreviewPlacement(input) {
172
179
  previousPlacement.activeDropTargetId !== input.activeDropTargetId ||
173
180
  previousPlacement.placement === null ||
174
181
  previousPlacement.movementDirection === "none") {
182
+ if (input.useMidpointInitialPlacement) {
183
+ const placement = getPlacementSideFromTargetMidpoint({
184
+ axis,
185
+ axisPosition,
186
+ targetRect,
187
+ });
188
+ return {
189
+ placement,
190
+ movementDirection: "none",
191
+ };
192
+ }
175
193
  return {
176
- placement: input.useMidpointInitialPlacement
177
- ? getPlacementSideFromTargetMidpoint({
178
- axis,
179
- axisPosition: midpointAxisPosition,
180
- targetRect,
181
- })
182
- : getOptimisticPlacement({
183
- axis,
184
- axisPosition,
185
- currentDirection,
186
- targetRect,
187
- }),
194
+ placement: getOptimisticPlacement({
195
+ axis,
196
+ axisPosition,
197
+ currentDirection,
198
+ targetRect,
199
+ }),
188
200
  movementDirection: currentDirection,
189
201
  };
190
202
  }
@@ -219,6 +231,8 @@ function setSortablePreviewPlacementState(input) {
219
231
  activeDropTargetId: input.activeDropTargetId,
220
232
  placement: input.placement,
221
233
  movementDirection: input.movementDirection,
234
+ containerElement: input.containerElement,
235
+ pendingMidpointInitialPlacement: input.pendingMidpointInitialPlacement,
222
236
  };
223
237
  }
224
238
  function getOptimisticPlacement(input) {
@@ -34,7 +34,6 @@ export function getSortableRegistry(runtime) {
34
34
  runtime,
35
35
  draggedDraggableId: event.draggableId,
36
36
  activeDropTargetId: event.activeDropTargetId,
37
- pointerPosition: event.pointerPosition,
38
37
  placementPosition: event.placementPosition ?? event.pointerPosition,
39
38
  options: getSortableOptions(registry, event.draggableId),
40
39
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mk-drag-and-drop/dom",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Headless DOM drag-and-drop primitives for draggable, droppable, sortable, and grouped interactions.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://mkramer.dev",