Skip to content

Fix mobile tap selection double-trigger (Issue #54)#55

Merged
ysgrProgramming merged 1 commit into
mainfrom
feature/issue-54-fix-mobile-tap-selection-double-trigger
Nov 27, 2025
Merged

Fix mobile tap selection double-trigger (Issue #54)#55
ysgrProgramming merged 1 commit into
mainfrom
feature/issue-54-fix-mobile-tap-selection-double-trigger

Conversation

@ysgrProgramming

Copy link
Copy Markdown
Owner

Summary

Fixes Issue #54: On touch devices, selecting a piece causes the selection highlight to flash briefly and immediately disappear due to double-triggering from synthetic click events.

Root Cause

  • handleTouchEnd invokes handleSquareClick to emulate a tap
  • After the touch ends, the browser dispatches a synthetic click event, which also triggers handleSquareClick via the onClick handler
  • The second invocation treats it as "tap same square twice" and deselects

Solution

  • Added touchHandledRef to track when touch events are handled
  • Call event.preventDefault() in handleTouchEnd when handling taps to prevent synthetic click
  • Ignore synthetic click events in onClick handler when touchHandledRef.current is true
  • Reset the flag after 300ms (typical synthetic click delay window)

Changes

  • src/components/ChessBoard.tsx: Added touch handling flag and preventDefault logic
  • tests/components/ChessBoard.responsive.test.tsx: Added tests for selection persistence and double-tap deselection

Testing

  • ✅ All existing tests pass (233 tests)
  • ✅ New tests verify selection persists after tap without double-trigger
  • ✅ New test verifies deselection works correctly with double tap
  • ✅ Lint passes with no errors

Self-Walkthrough

Requirements Mapping

  1. Prevent synthetic click from firing after touch tap: ✅ Implemented via event.preventDefault() in handleTouchEnd
  2. Verify touch taps keep selection active: ✅ Tested via new test should maintain selection after tap without double-triggering from synthetic click
  3. Ensure desktop click/drag behavior unchanged: ✅ Verified - desktop clicks are not affected since touchHandledRef is only set for touch events
  4. Update responsive touch tests: ✅ Added tests for selection-only scenario

Code Logic

  • Touch event handling: When a tap is detected (small movement), we set touchHandledRef.current = true and call event.preventDefault() to prevent synthetic click
  • Click event handling: The onClick handler checks touchHandledRef.current and returns early if true, preventing double-trigger
  • Flag reset: The flag is reset after 300ms to allow normal click handling for subsequent interactions
  • Touch start reset: The flag is also reset on handleTouchStart to ensure clean state for each touch sequence

Closes #54

- Add touchHandledRef to track when touch events are handled
- Prevent synthetic click events from firing after touch taps
- Ignore synthetic click events in onClick handler when touch was handled
- Add tests to verify selection persists after tap without double-trigger
- Add test to verify deselection works correctly with double tap

Closes #54
@ysgrProgramming
ysgrProgramming merged commit f5921f3 into main Nov 27, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix mobile tap selection double-trigger

1 participant