Skip to content

Commit

Permalink
Fix issues with DragOverlay measuring
Browse files Browse the repository at this point in the history
  • Loading branch information
Clauderic Demers committed Aug 18, 2021
1 parent 59ef705 commit de29ae1
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 74 deletions.
25 changes: 9 additions & 16 deletions packages/core/src/components/DndContext/DndContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
getEventCoordinates,
Transform,
useIsomorphicLayoutEffect,
useNodeRef,
useUniqueId,
} from '@dnd-kit/utilities';

Expand Down Expand Up @@ -61,7 +60,6 @@ import {
getViewRect,
rectIntersection,
} from '../../utilities';
import {getMeasurableNode} from '../../utilities/nodes';
import {applyModifiers, Modifiers} from '../../modifiers';
import type {Active, DataRef} from '../../store/types';
import type {
Expand All @@ -78,6 +76,7 @@ import {
screenReaderInstructions as defaultScreenReaderInstructions,
ScreenReaderInstructions,
} from '../Accessibility';
import {useDragOverlayMeasuring} from '../DragOverlay';

export interface Props {
id?: string;
Expand Down Expand Up @@ -226,13 +225,13 @@ export const DndContext = memo(function DndContext({
);
const scrollableAncestorRects = useClientRects(scrollableAncestors);

const [overlayNodeRef, setOverlayNodeRef] = useNodeRef();
const overlayNodeRect = useClientRect(
activeId ? getMeasurableNode(overlayNodeRef.current) : null
);
const overlayNode = useDragOverlayMeasuring({
disabled: activeId == null,
forceRecompute: willRecomputeLayouts,
});

// Use the rect of the drag overlay if it is mounted
const draggingNodeRect = overlayNodeRect ?? activeNodeRect;
const draggingNodeRect = overlayNode.rect ?? activeNodeRect;

// The delta between the previous and new position of the draggable node
// is only relevant when there is no drag overlay
Expand All @@ -254,7 +253,7 @@ export const DndContext = memo(function DndContext({
containerNodeRect,
draggingNodeRect,
over: sensorContext.current.over,
overlayNodeRect,
overlayNodeRect: overlayNode.rect,
scrollableAncestors,
scrollableAncestorRects,
windowRect,
Expand Down Expand Up @@ -577,11 +576,7 @@ export const DndContext = memo(function DndContext({
ariaDescribedById: {
draggable: draggableDescribedById,
},
overlayNode: {
nodeRef: overlayNodeRef,
rect: overlayNodeRect,
setRef: setOverlayNodeRef,
},
overlayNode,
containerNodeRect,
dispatch,
draggableNodes,
Expand All @@ -604,8 +599,7 @@ export const DndContext = memo(function DndContext({
activatorEvent,
activators,
containerNodeRect,
overlayNodeRect,
overlayNodeRef,
overlayNode,
dispatch,
draggableNodes,
draggableDescribedById,
Expand All @@ -615,7 +609,6 @@ export const DndContext = memo(function DndContext({
recomputeLayouts,
scrollableAncestors,
scrollableAncestorRects,
setOverlayNodeRef,
willRecomputeLayouts,
windowRect,
]);
Expand Down
17 changes: 7 additions & 10 deletions packages/core/src/components/DragOverlay/DragOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {applyModifiers, Modifiers} from '../../modifiers';
import {ActiveDraggableContext} from '../DndContext';
import {useDndContext} from '../../hooks';
import type {ViewRect} from '../../types';
import {useDerivedTransform, useDropAnimation, DropAnimation} from './hooks';
import {useDropAnimation, DropAnimation} from './hooks';

type TransitionGetter = (
activatorEvent: Event | null
Expand Down Expand Up @@ -75,20 +75,17 @@ export const DragOverlay = React.memo(
transform,
windowRect,
});
const derivedTransform = useDerivedTransform(
modifiedTransform,
activeNodeRect,
overlayNode.nodeRef.current
);
const isDragging = active !== null;
const intermediateTransform = derivedTransform ?? modifiedTransform;
const finalTransform = adjustScale
? intermediateTransform
? modifiedTransform
: {
...intermediateTransform,
...modifiedTransform,
scaleX: 1,
scaleY: 1,
};

overlayNode.transform.current = finalTransform;

const initialNodeRect = useLazyMemo<ViewRect | null>(
(previousValue) => {
if (isDragging) {
Expand Down Expand Up @@ -116,7 +113,7 @@ export const DragOverlay = React.memo(
initialNodeRect
)
: undefined,
transition: derivedTransform
transition: modifiedTransform
? undefined
: typeof transition === 'function'
? transition(activatorEvent)
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/components/DragOverlay/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export {useDerivedTransform} from './useDerivedTransform';
export {useDropAnimation, DropAnimation} from './useDropAnimation';
export {useDropAnimation} from './useDropAnimation';
export type {DropAnimation} from './useDropAnimation';
export {useDragOverlayMeasuring} from './useDragOverlayMeasuring';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {useMemo, useRef} from 'react';
import {Transform, useNodeRef} from '@dnd-kit/utilities';

import type {DndContextDescriptor} from '../../../store';
import type {ClientRect} from '../../../types';
import {useClientRect} from '../../../hooks/utilities';
import {getMeasurableNode} from '../../../utilities/nodes';

interface Arguments {
disabled: boolean;
forceRecompute: boolean;
}

export function useDragOverlayMeasuring({
disabled,
forceRecompute,
}: Arguments): DndContextDescriptor['overlayNode'] {
const transform = useRef<Transform | null>(null);
const [nodeRef, setRef] = useNodeRef();
const measuredOverlayRect = useClientRect(
disabled ? null : getMeasurableNode(nodeRef.current),
forceRecompute
);

const rect = useMemo(() => {
return measuredOverlayRect && transform.current
? add(measuredOverlayRect, transform.current)
: null;
}, [measuredOverlayRect]);

return {
nodeRef,
rect,
setRef,
transform,
};
}

function add(rect: ClientRect, transform: Transform) {
return {
...rect,
left: Math.round(rect.left - transform.x),
right: Math.round(rect.right - transform.x),
top: Math.round(rect.top - transform.y),
bottom: Math.round(rect.bottom - transform.y),
};
}
1 change: 1 addition & 0 deletions packages/core/src/components/DragOverlay/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export {DragOverlay, defaultDropAnimation} from './DragOverlay';
export type {Props} from './DragOverlay';
export {useDragOverlayMeasuring} from './hooks';
export type {DropAnimation} from './hooks';
2 changes: 1 addition & 1 deletion packages/core/src/hooks/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export type {
SyntheticListeners,
SyntheticListenerMap,
} from './useSyntheticListeners';
export {useRect, useClientRect, useClientRects} from './useRect';
export {useRect, useClientRect, useClientRects, useViewRect} from './useRect';
3 changes: 2 additions & 1 deletion packages/core/src/hooks/utilities/useRect.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {useRef} from 'react';
import {useLazyMemo} from '@dnd-kit/utilities';

import {getBoundingClientRect} from '../../utilities';
import {getBoundingClientRect, getViewRect} from '../../utilities';
import type {LayoutRect} from '../../types';

type RectFn<T, U> = (element: U) => T;

export const useViewRect = createUseRectFn(getViewRect);
export const useClientRect = createUseRectFn(getBoundingClientRect);
export const useClientRects = createUseRectsFn(getBoundingClientRect);

Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/store/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export const Context = createContext<DndContextDescriptor>({
},
rect: null,
setRef: noop,
transform: {
current: null,
},
},
scrollableAncestors: [],
scrollableAncestorRects: [],
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/store/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type {MutableRefObject} from 'react';
import type {Transform} from '@dnd-kit/utilities';

import type {
Coordinates,
Expand Down Expand Up @@ -95,6 +96,7 @@ export interface DndContextDescriptor {
overlayNode: {
nodeRef: MutableRefObject<HTMLElement | null>;
rect: ViewRect | null;
transform: MutableRefObject<Transform | null>;
setRef: (element: HTMLElement | null) => void;
};
scrollableAncestors: Element[];
Expand Down

0 comments on commit de29ae1

Please sign in to comment.