mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-10-01 15:48:23 -05:00
Fix drag n drop jank in tier list maker
This commit is contained in:
@@ -24,7 +24,7 @@ export function DraggableItem({ item }: DraggableItemProps) {
|
||||
});
|
||||
|
||||
const style = {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transform: CSS.Translate.toString(transform),
|
||||
transition,
|
||||
opacity: isDragging ? 0.3 : 1,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useDroppable } from "@dnd-kit/core";
|
||||
import {
|
||||
horizontalListSortingStrategy,
|
||||
rectSortingStrategy,
|
||||
SortableContext,
|
||||
useSortable,
|
||||
} from "@dnd-kit/sortable";
|
||||
@@ -47,9 +47,12 @@ export function TierRow({ tier }: TierRowProps) {
|
||||
|
||||
const items = getItemsInTier(tier.id);
|
||||
const { t } = useTranslation(["tier-list-maker", "common"]);
|
||||
const { setNodeRef, isOver } = useDroppable({
|
||||
const { setNodeRef, over } = useDroppable({
|
||||
id: tier.id,
|
||||
});
|
||||
const itemIds = items.map(tierListItemId);
|
||||
const isOver =
|
||||
over !== null && (over.id === tier.id || itemIds.includes(String(over.id)));
|
||||
|
||||
const combinedRef = useLockedHeightWhileDragging({
|
||||
setNodeRef,
|
||||
@@ -193,10 +196,7 @@ export function TierRow({ tier }: TierRowProps) {
|
||||
: t("tier-list-maker:dropItems")}
|
||||
</div>
|
||||
) : items.length > 0 ? (
|
||||
<SortableContext
|
||||
items={items.map(tierListItemId)}
|
||||
strategy={horizontalListSortingStrategy}
|
||||
>
|
||||
<SortableContext items={itemIds} strategy={rectSortingStrategy}>
|
||||
{items.map((item) => (
|
||||
<DraggableItem key={tierListItemId(item)} item={item} />
|
||||
))}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CollisionDetection, Modifier } from "@dnd-kit/core";
|
||||
import type { ClientRect, CollisionDetection, Modifier } from "@dnd-kit/core";
|
||||
import {
|
||||
closestCenter,
|
||||
DndContext,
|
||||
@@ -71,9 +71,30 @@ const tierAwareCollisionDetection: CollisionDetection = (args) => {
|
||||
(tierIdFromSortableId(String(container.id)) !== null) === isTierDrag,
|
||||
);
|
||||
|
||||
return isTierDrag
|
||||
? closestCenter({ ...args, droppableContainers })
|
||||
: pointerWithin({ ...args, droppableContainers });
|
||||
if (isTierDrag) return closestCenter({ ...args, droppableContainers });
|
||||
|
||||
const pointerCollisions = pointerWithin({ ...args, droppableContainers });
|
||||
|
||||
// gaps between items would otherwise resolve to the tier itself, snapping the sort preview back
|
||||
const tierZoneCollision = pointerCollisions.find((collision) =>
|
||||
String(collision.id).startsWith("tier-"),
|
||||
);
|
||||
const tierZoneRect = tierZoneCollision
|
||||
? args.droppableRects.get(tierZoneCollision.id)
|
||||
: undefined;
|
||||
if (!tierZoneCollision || !tierZoneRect) return pointerCollisions;
|
||||
|
||||
const itemsInTierZone = droppableContainers.filter((container) => {
|
||||
const rect = args.droppableRects.get(container.id);
|
||||
return (
|
||||
container.id !== tierZoneCollision.id &&
|
||||
rect !== undefined &&
|
||||
isRectCenterWithin(rect, tierZoneRect)
|
||||
);
|
||||
});
|
||||
if (itemsInTierZone.length === 0) return [tierZoneCollision];
|
||||
|
||||
return closestCenter({ ...args, droppableContainers: itemsInTierZone });
|
||||
};
|
||||
|
||||
const restrictTierDragToVerticalAxis: Modifier = (args) =>
|
||||
@@ -412,3 +433,15 @@ function ResetPopover({ handleReset }: { handleReset: () => void }) {
|
||||
</SendouPopover>
|
||||
);
|
||||
}
|
||||
|
||||
function isRectCenterWithin(rect: ClientRect, container: ClientRect) {
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
|
||||
return (
|
||||
centerX >= container.left &&
|
||||
centerX <= container.right &&
|
||||
centerY >= container.top &&
|
||||
centerY <= container.bottom
|
||||
);
|
||||
}
|
||||
|
||||
5
changelog/2026-09-22-tier-list-maker-drag-preview.md
Normal file
5
changelog/2026-09-22-tier-list-maker-drag-preview.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
navItem: tier-list-maker
|
||||
type: bug
|
||||
---
|
||||
Dragging items in tier list maker tiers with multiple rows no longer jumps around or leaves gaps in the preview
|
||||
Reference in New Issue
Block a user