Skip to content

Android Chrome can snap backward after slow drag because fractional index is truncated and zero-duration settle skips callback #190

Description

@MartinEichinger

Hi,

I found a bug in @ncdai/react-wheel-picker 1.2.2 on Chrome for Android.

Reproduction:

  • Use a controlled wheel picker with digits 0-9
  • infinite={true}
  • optionItemHeight={40}
  • visibleCount={20}
  • dragSensitivity={4}
  • Slowly drag from 3 toward 4 until 4 is visually dominant (for example around 90% toward 4)
  • Hold for 1-2 seconds so there is effectively no release velocity
  • Release

Expected:

  • The picker should snap to 4

Actual:

  • On Android Chrome it can snap back to 3
  • On desktop Chrome I could not reproduce it in the same way

What I found while debugging:

  1. The snap logic uses truncation (X(e) | 0) instead of rounding.
    Example: if the visual position is about 3.9, truncation resolves to 3 although the wheel is already visually closer to 4.

  2. The zero-duration settle path returns too early.
    In the generated bundle, the equivalent of:

    • if (e === t || n === 0) { V(e); return; }
      means that when duration is 0, it snaps to the start position and skips the callback.
      It should snap to the target and still invoke the callback.
  3. On touch devices, velocity derived only from the last two touch samples seems fragile.
    Using the full buffered sample window gave more stable results in my local patch, although the first two items above look like the core correctness issues.

Suggested fix:

  • Round the final index instead of truncating it
  • In the zero-duration settle path, snap to target and invoke the completion callback
  • Rebuild/publish both CJS and ESM outputs, because browser builds import the ESM bundle

If helpful, I can share the exact patch I used locally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions