Skip to content

Commit 632a24a

Browse files
committed
refactor: enhance carousel swipe handling and add click capture functionality
1 parent b2eb30d commit 632a24a

2 files changed

Lines changed: 41 additions & 2 deletions

File tree

packages/headless/src/carousel/useCarousel.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export const useCarousel = withHeadless({
125125
const swipeStartTimeRef = React.useRef<number | null>(null);
126126
const swipeStartPointerRef = React.useRef<{ x: number; y: number } | null>(null);
127127
const prevSwipeAmountRef = React.useRef<number>(0);
128+
const recentSwipeRef = React.useRef<{ time: number; startX: number; startY: number; moved: boolean } | null>(null);
128129

129130
const previousPosition = React.useRef(0);
130131
const position = React.useRef(0);
@@ -475,14 +476,27 @@ export const useCarousel = withHeadless({
475476

476477
setIsSwiping(true);
477478

478-
swipeStartTimeRef.current = new Date().getTime();
479+
const time = new Date().getTime();
480+
481+
swipeStartTimeRef.current = time;
479482
swipeStartPointerRef.current = { x: event.clientX, y: event.clientY };
480483
prevSwipeAmountRef.current = getSwipeAmount();
484+
485+
recentSwipeRef.current = {
486+
time,
487+
startX: event.clientX,
488+
startY: event.clientY,
489+
moved: false
490+
};
481491
};
482492

483493
const handlePointerMove = (event: PointerEvent) => {
484494
if (!isSwiping || !swipeStartPointerRef.current || !swipeStartTimeRef.current || !carouselRef.current) return;
485495

496+
if (recentSwipeRef.current) {
497+
recentSwipeRef.current.moved = true;
498+
}
499+
486500
const delta = isVertical ? event.clientY - swipeStartPointerRef.current.y : event.clientX - swipeStartPointerRef.current.x;
487501

488502
const prevDelta = prevDeltaRef.current;
@@ -531,12 +545,36 @@ export const useCarousel = withHeadless({
531545
setIsSwiping(false);
532546
swipeStartPointerRef.current = null;
533547
swipeStartTimeRef.current = null;
548+
549+
setTimeout(() => {
550+
recentSwipeRef.current = null;
551+
}, 100);
534552
};
535553

536554
const handleClick = (event: MouseEvent) => {
537555
if (isSwiping) {
538556
event.preventDefault();
539557
event.stopPropagation();
558+
559+
return;
560+
}
561+
562+
if (recentSwipeRef.current) {
563+
const elapsed = Date.now() - recentSwipeRef.current.time;
564+
const deltaX = Math.abs(event.clientX - recentSwipeRef.current.startX);
565+
const deltaY = Math.abs(event.clientY - recentSwipeRef.current.startY);
566+
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
567+
568+
const significantMovement = recentSwipeRef.current.moved && elapsed > 150;
569+
const tooLong = elapsed > 500;
570+
const tooFar = distance > 25;
571+
572+
if (significantMovement || tooLong || tooFar) {
573+
event.preventDefault();
574+
event.stopPropagation();
575+
576+
return;
577+
}
540578
}
541579
};
542580

packages/primereact/src/carousel/content/CarouselContent.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export const CarouselContent = withComponent({
3030
onPointerDown: carousel?.handlePointerDown,
3131
onPointerMove: carousel?.handlePointerMove,
3232
onPointerUp: carousel?.handlePointerUp,
33-
onClick: carousel?.handleClick
33+
onClick: carousel?.handleClick,
34+
onClickCapture: carousel?.handleClick
3435
},
3536
carousel?.ptm('content'),
3637
ptmi('root')

0 commit comments

Comments
 (0)