fix(twenty-front): Scrolling and Dragging conflict on mobile devices (#23677)

Fixes: #23675 



https://github.com/user-attachments/assets/1f0d4f0f-0dd6-4731-8359-6da13a5e11b3



<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23677?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
Priyanshu Bartwal
2026-08-03 19:13:09 +05:30
committed by GitHub
parent 4a5c623ece
commit 22d83c75e6
3 changed files with 55 additions and 5 deletions
@@ -1,14 +1,11 @@
import { PointerActivationConstraints } from '@dnd-kit/dom';
import { KeyboardSensor, PointerSensor } from '@dnd-kit/react';
import { getDragActivationConstraints } from '@/ui/utilities/drag-and-drop/utils/getDragActivationConstraints';
import { shouldPreventDragActivation } from '@/ui/utilities/drag-and-drop/utils/shouldPreventDragActivation';
// Pointer drags only start past 8px so clicks on draggable items still register.
export const DND_KIT_SENSORS = [
PointerSensor.configure({
activationConstraints: [
new PointerActivationConstraints.Distance({ value: 8 }),
],
activationConstraints: getDragActivationConstraints,
preventActivation: shouldPreventDragActivation,
}),
KeyboardSensor,
@@ -0,0 +1,29 @@
import { PointerActivationConstraints } from '@dnd-kit/dom';
import { getDragActivationConstraints } from '@/ui/utilities/drag-and-drop/utils/getDragActivationConstraints';
const createPointerEvent = (pointerType: string) =>
({ pointerType }) as unknown as PointerEvent;
describe('getDragActivationConstraints', () => {
it('should require a press and hold when the pointer is a touch', () => {
const [constraint, ...otherConstraints] = getDragActivationConstraints(
createPointerEvent('touch'),
);
expect(constraint).toBeInstanceOf(PointerActivationConstraints.Delay);
expect(otherConstraints).toHaveLength(0);
});
it.each(['mouse', 'pen'])(
'should require a movement distance when the pointer is a %s',
(pointerType) => {
const [constraint, ...otherConstraints] = getDragActivationConstraints(
createPointerEvent(pointerType),
);
expect(constraint).toBeInstanceOf(PointerActivationConstraints.Distance);
expect(otherConstraints).toHaveLength(0);
},
);
});
@@ -0,0 +1,24 @@
import { PointerActivationConstraints } from '@dnd-kit/dom';
// Same values as dnd-kit's own touch default: a swipe has to scroll the board,
// so a drag only starts after a press and hold that stays put.
const TOUCH_ACTIVATION_DELAY_IN_MS = 250;
const TOUCH_ACTIVATION_TOLERANCE_IN_PX = 5;
// dnd-kit also delays activation for mouse and pen, which we leave out: holding
// a card still would start a drag and swallow the click that opens the record.
const POINTER_ACTIVATION_DISTANCE_IN_PX = 8;
export const getDragActivationConstraints = (event: PointerEvent) =>
event.pointerType === 'touch'
? [
new PointerActivationConstraints.Delay({
value: TOUCH_ACTIVATION_DELAY_IN_MS,
tolerance: TOUCH_ACTIVATION_TOLERANCE_IN_PX,
}),
]
: [
new PointerActivationConstraints.Distance({
value: POINTER_ACTIVATION_DISTANCE_IN_PX,
}),
];