-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix pan event firing order: ensure onPanStart fires before onPan #3525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
PR Review: Fix pan event firing orderSummaryThis PR addresses a timing issue where ✅ Code Quality & Best PracticesStrengths:
Observations:
🐛 Potential Issues1. Event Object Validity Concern if (onDrag) {
frame.postRender(() => onDrag(event, info))
}Issue: The Recommendation: Verify that 2. Test Robustness expect(startIndex).toBeLessThan(firstPanIndex)Potential Gap: The test doesn't verify that:
Recommendation: Consider adding assertions that check frame boundaries more explicitly, perhaps by capturing timestamps or frame counts. ⚡ Performance ConsiderationsFrame Scheduling Overhead: Analysis:
Verdict: Performance impact should be negligible. The consistency with existing patterns is more valuable than micro-optimizing this path. 🔒 Security ConcernsNo security issues identified. The changes don't introduce:
🧪 Test CoverageCurrent Coverage: Gaps: Recommendation: test("onDrag fires after render in drag controls", async () => {
const renderOrder: string[] = []
const Component = () => {
const ref = useRef<HTMLDivElement>(null)
return (
<motion.div
ref={ref}
drag
onDrag={() => renderOrder.push("drag")}
onUpdate={() => renderOrder.push("render")}
/>
)
}
// ... verify render happens before drag callback
})📊 Implementation ReviewPanSession Integration (packages/framer-motion/src/gestures/pan/PanSession.ts:280-285): if (!isPanStarted) {
onStart && onStart(this.lastMoveEvent, info)
this.startEvent = this.lastMoveEvent
}
onMove && onMove(this.lastMoveEvent, info)With the new However: Since both are deferred to the same ✨ Recommendations
🎯 Final VerdictAPPROVED with minor suggestions This is a well-implemented fix that:
The implementation is sound, though additional test coverage and documentation would strengthen it further. The approach of using Merge confidence: High ✅ |
The onPanStart/onDragStart events were firing after onPan/onDrag because of a timing mismatch: - onPanStart and onDragStart were deferred via frame.postRender() - onPan and onDrag were called synchronously within frame.update() Since postRender runs after update in the frame loop, this caused the move handlers to execute before the start handlers. The fix changes onPanStart/onDragStart to use frame.update() instead of frame.postRender(). This keeps the start events in the same frame phase as the move events while maintaining correct ordering, without introducing lag between input and visual update. https://claude.ai/code/session_01NUF3Mj5SSALV5gSW6AVGn6
e8c2762 to
177e11c
Compare
Pull Request ReviewThis PR addresses issue #2056 by fixing the event firing order for pan and drag gestures. The fix ensures ✅ Positive Findings1. Correct Root Cause AnalysisThe fix correctly identifies the timing issue: both 2. Appropriate SolutionChanging from
3. Good Test CoverageThe new test case at pan.test.tsx:47-79 properly validates the fix:
4. Consistent ApplicationThe fix is consistently applied to both:
|
Summary
This PR fixes the event firing order for pan gestures to ensure
onPanStartfires beforeonPan, andonPanfires beforeonPanEnd. Previously,onPancould fire in the same frame asonPanStart, violating the expected event sequence.Key Changes
onPancallback withasyncHandlerto defer its execution to the next frame, ensuring it fires afteronPanStartonDragcallback execution usingframe.postRender()to maintain consistent timing with pan events"onPanStart fires before onPan"to verify the correct event firing order during drag operationsImplementation Details
The fix leverages the existing
asyncHandlerutility andframe.postRender()mechanism to defer callback execution to the appropriate frame phase. This ensures the event sequence is:onPanStart- fires immediately when pan gesture beginsonPan- fires after the render phase (viaasyncHandler)onPanEnd- fires when the gesture endsThis maintains backward compatibility while fixing the event ordering issue that could cause state management problems in applications relying on the expected event sequence.
https://claude.ai/code/session_01NUF3Mj5SSALV5gSW6AVGn6