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' import { ProfileItem, type ProfileItemProps } from './profile-item'
const SORT_TRANSITION = 'transform 160ms cubic-bezier(0.2, 0, 0, 1)'
type SortableProfileItemProps = Omit< type SortableProfileItemProps = Omit<
ProfileItemProps, ProfileItemProps,
'dragHandleRef' | 'dragHandleAttributes' | 'dragHandleListeners' 'dragHandleRef' | 'dragHandleAttributes' | 'dragHandleListeners'
@@ -18,24 +20,33 @@ export const SortableProfileItem = ({
const { const {
attributes, attributes,
listeners, listeners,
setActivatorNodeRef,
setNodeRef, setNodeRef,
transform, transform,
transition, isSorting,
isDragging, isDragging,
} = useSortable({ id }) isOver,
} = useSortable({ id, transition: null })
const isDiagonalMove =
transform !== null && transform.x !== 0 && transform.y !== 0
return ( return (
<Box <Box
ref={setNodeRef}
sx={{ sx={{
position: 'relative', position: 'relative',
transform: CSS.Transform.toString(transform), transform: CSS.Translate.toString(transform),
transition, transition:
isSorting && !isDragging && isOver && !isDiagonalMove
? SORT_TRANSITION
: undefined,
zIndex: isDragging ? 'calc(infinity)' : undefined, zIndex: isDragging ? 'calc(infinity)' : undefined,
}} }}
> >
<ProfileItem <ProfileItem
{...profileItemProps} {...profileItemProps}
dragHandleRef={setNodeRef} dragHandleRef={setActivatorNodeRef}
dragHandleAttributes={attributes} dragHandleAttributes={attributes}
dragHandleListeners={listeners} dragHandleListeners={listeners}
/> />
+8 -1
View File
@@ -1,9 +1,11 @@
import { import {
closestCenter, closestCenter,
type CollisionDetection,
DndContext, DndContext,
type DragEndEvent, type DragEndEvent,
DragOverlay, DragOverlay,
KeyboardSensor, KeyboardSensor,
pointerWithin,
PointerSensor, PointerSensor,
useSensor, useSensor,
useSensors, useSensors,
@@ -77,6 +79,11 @@ import { debugLog } from '@/utils/debug'
const PROFILE_UPDATE_WORKER_LIMIT = 8 const PROFILE_UPDATE_WORKER_LIMIT = 8
const PROFILE_SWITCH_LOADING_DELAY = 400 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. // Equivalent to rectSortingStrategy without copying the full rect array for every item.
const profileRectSortingStrategy: SortingStrategy = ({ const profileRectSortingStrategy: SortingStrategy = ({
rects, rects,
@@ -928,7 +935,7 @@ const ProfilePage = () => {
<DndContext <DndContext
sensors={sensors} sensors={sensors}
collisionDetection={closestCenter} collisionDetection={profileCollisionDetection}
onDragEnd={onDragEnd} onDragEnd={onDragEnd}
> >
<Box <Box