@mk-drag-and-drop/dom 0.4.0 → 0.4.1
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
|
@@ -365,6 +365,17 @@ registry may narrow measured candidates to relevant sortable item, neighbor, or
|
|
|
365
365
|
container entries before the targeting algorithm runs; the algorithm still makes
|
|
366
366
|
the active-target decision from that narrowed measured list.
|
|
367
367
|
|
|
368
|
+
Same-container sortable preview keeps its movement-responsive first-placement
|
|
369
|
+
behavior: forward movement places after a newly active target, backward movement
|
|
370
|
+
places before, and no sortable-axis movement uses the target midpoint. When a
|
|
371
|
+
sortable item first enters a different DOM container, the initial side is based
|
|
372
|
+
on the target midpoint on the sortable axis: above or left of midpoint places
|
|
373
|
+
before, while below or right of midpoint places after.
|
|
374
|
+
|
|
375
|
+
`placementBoundary` is used after a preview placement already exists to control
|
|
376
|
+
same-target reversal and hysteresis thresholds. It does not decide the initial
|
|
377
|
+
side for cross-container sortable entry.
|
|
378
|
+
|
|
368
379
|
## Modifiers
|
|
369
380
|
|
|
370
381
|
Modifiers transform pointer movement before drag state updates. Built-ins:
|
|
@@ -56,6 +56,7 @@ export declare function getSortablePreviewPlacement(input: {
|
|
|
56
56
|
movement: SortablePointerMovementState | null;
|
|
57
57
|
previewPlacement: SortablePreviewPlacementState | null;
|
|
58
58
|
options: NormalizedSortableOptions;
|
|
59
|
+
useMidpointInitialPlacement?: boolean;
|
|
59
60
|
}): SortablePreviewPlacementDecision;
|
|
60
61
|
export declare function isSortablePreviewAlreadyPlaced(input: {
|
|
61
62
|
draggedElement: HTMLElement;
|
|
@@ -106,6 +106,7 @@ export function moveSortablePreview(input) {
|
|
|
106
106
|
if (!listElement) {
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
+
const useMidpointInitialPlacement = draggedElement.parentElement !== listElement;
|
|
109
110
|
if (!target.capabilities.sortable) {
|
|
110
111
|
return;
|
|
111
112
|
}
|
|
@@ -120,6 +121,7 @@ export function moveSortablePreview(input) {
|
|
|
120
121
|
movement: input.registry.activeDrag.pointerMovement,
|
|
121
122
|
previewPlacement: input.registry.activeDrag.previewPlacement,
|
|
122
123
|
options: input.options,
|
|
124
|
+
useMidpointInitialPlacement,
|
|
123
125
|
});
|
|
124
126
|
const placement = placementDecision.placement;
|
|
125
127
|
setSortablePreviewPlacementState({
|
|
@@ -165,12 +167,18 @@ export function getSortablePreviewPlacement(input) {
|
|
|
165
167
|
previousPlacement.placement === null ||
|
|
166
168
|
previousPlacement.movementDirection === "none") {
|
|
167
169
|
return {
|
|
168
|
-
placement:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
placement: input.useMidpointInitialPlacement
|
|
171
|
+
? getPlacementSideFromTargetMidpoint({
|
|
172
|
+
axis,
|
|
173
|
+
axisPosition,
|
|
174
|
+
targetRect,
|
|
175
|
+
})
|
|
176
|
+
: getOptimisticPlacement({
|
|
177
|
+
axis,
|
|
178
|
+
axisPosition,
|
|
179
|
+
currentDirection,
|
|
180
|
+
targetRect,
|
|
181
|
+
}),
|
|
174
182
|
movementDirection: currentDirection,
|
|
175
183
|
};
|
|
176
184
|
}
|
|
@@ -222,6 +230,12 @@ function getOptimisticPlacement(input) {
|
|
|
222
230
|
endRatio: neutralPlacementBoundaryRatio,
|
|
223
231
|
}));
|
|
224
232
|
}
|
|
233
|
+
function getPlacementSideFromTargetMidpoint(input) {
|
|
234
|
+
const targetStart = input.axis === "horizontal" ? input.targetRect.left : input.targetRect.top;
|
|
235
|
+
const targetSize = input.axis === "horizontal" ? input.targetRect.width : input.targetRect.height;
|
|
236
|
+
const midpoint = targetStart + targetSize / 2;
|
|
237
|
+
return input.axisPosition < midpoint ? "before" : "after";
|
|
238
|
+
}
|
|
225
239
|
function getCurrentAxisMovementDirection(input) {
|
|
226
240
|
const axisPosition = getAxisPosition(input.placementPosition, input.axis);
|
|
227
241
|
const previousAxisPosition = input.movement
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mk-drag-and-drop/dom",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
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",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"jsdom": "^24.1.3",
|
|
48
48
|
"typescript": "5.5.4",
|
|
49
49
|
"vitest": "^2.1.9",
|
|
50
|
-
"@repo/
|
|
51
|
-
"@repo/
|
|
50
|
+
"@repo/eslint-config": "0.0.0",
|
|
51
|
+
"@repo/typescript-config": "0.0.0"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
|