fix(profiles): stabilize drag reorder motion

Close: 7798
This commit is contained in:
Tunglies
2026-08-23 17:10:38 +08:00
parent f68f204fc2
commit 6eaf65ff0f
2 changed files with 24 additions and 6 deletions
@@ -4,6 +4,8 @@ import { Box } from '@mui/material'
import { ProfileItem, type ProfileItemProps } from './profile-item'
const SORT_TRANSITION = 'transform 160ms cubic-bezier(0.2, 0, 0, 1)'
type SortableProfileItemProps = Omit<
ProfileItemProps,
'dragHandleRef' | 'dragHandleAttributes' | 'dragHandleListeners'
@@ -18,24 +20,33 @@ export const SortableProfileItem = ({
const {
attributes,
listeners,
setActivatorNodeRef,
setNodeRef,
transform,
transition,
isSorting,
isDragging,
} = useSortable({ id })
isOver,
} = useSortable({ id, transition: null })
const isDiagonalMove =
transform !== null && transform.x !== 0 && transform.y !== 0
return (
<Box
ref={setNodeRef}
sx={{
position: 'relative',
transform: CSS.Transform.toString(transform),
transition,
transform: CSS.Translate.toString(transform),
transition:
isSorting && !isDragging && isOver && !isDiagonalMove
? SORT_TRANSITION
: undefined,
zIndex: isDragging ? 'calc(infinity)' : undefined,
}}
>
<ProfileItem
{...profileItemProps}
dragHandleRef={setNodeRef}
dragHandleRef={setActivatorNodeRef}
dragHandleAttributes={attributes}
dragHandleListeners={listeners}
/>
+8 -1
View File
@@ -1,9 +1,11 @@
import {
closestCenter,
type CollisionDetection,
DndContext,
type DragEndEvent,
DragOverlay,
KeyboardSensor,
pointerWithin,
PointerSensor,
useSensor,
useSensors,
@@ -77,6 +79,11 @@ import { debugLog } from '@/utils/debug'
const PROFILE_UPDATE_WORKER_LIMIT = 8
const PROFILE_SWITCH_LOADING_DELAY = 400
const profileCollisionDetection: CollisionDetection = (args) => {
const pointerCollisions = pointerWithin(args)
return pointerCollisions.length > 0 ? pointerCollisions : closestCenter(args)
}
// Equivalent to rectSortingStrategy without copying the full rect array for every item.
const profileRectSortingStrategy: SortingStrategy = ({
rects,
@@ -928,7 +935,7 @@ const ProfilePage = () => {
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
collisionDetection={profileCollisionDetection}
onDragEnd={onDragEnd}
>
<Box