Skip to content

fix(showcase): tune touch long-press so mobile drags don't trigger page scroll#97

Merged
jjeff merged 1 commit into
mainfrom
worktree-touch-drag-tuning
Jun 14, 2026
Merged

fix(showcase): tune touch long-press so mobile drags don't trigger page scroll#97
jjeff merged 1 commit into
mainfrom
worktree-touch-drag-tuning

Conversation

@jjeff

@jjeff jjeff commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Problem

Reported while testing the live demo (/demo/) on an iPhone: the page often scrolls when trying to drag an item.

Root cause

On touch, the library already gates drag start behind a long-press: delayOnTouchOnly defaults to 200ms and touchStartThreshold defaults to 5px (DragManager.ts:198-199). While that hold timer is pending, touch-action is set to manipulation (scroll allowed), and onPointerMoveBeforeDrag cancels the pending drag the instant the finger moves more than 5px (DragManager.ts:909).

So the natural "press and immediately move to drag" motion blows past 5px well before the 200ms elapses → the pending drag is cancelled → the gesture falls through to a page scroll. Note that preventDefault() on pointer events cannot suppress scrolling; only touch-action / non-passive touchmove can — so the cancel path scrolls unavoidably.

Fix

Apply a shared TOUCH config to every showcase demo:

const TOUCH = { delayOnTouchOnly: 150, touchStartThreshold: 15 };
  • Snappier arm (150ms) — the drag commits before the user has moved much.
  • Forgiving tolerance (15px) — a deliberate drag-start's finger drift no longer cancels into a scroll.
  • A fast scroll flick still covers far more than 15px in well under 150ms, so it cancels-to-scroll exactly as before. Quick swipe = scroll; press-and-hold = drag (native iOS reorder feel).

Demo-config only — no library code changed, so no impact on the e2e suite or library consumers.

Verification

  • npm run check — 0 errors.
  • vite build --config vite.config.examples.ts — demo builds clean (validates the inline module JS).
  • iOS Safari's gesture/touch-action timing can't be faithfully emulated headlessly, so final feel should be confirmed on a real device.

Follow-up worth considering

The library default of delayOnTouchOnly: 200 / touchStartThreshold: 5 is the same trap for any consumer who doesn't override it. Worth revisiting the default (and/or adding a non-passive touchmove guard for immediate-drag mode) in a separate library-level change.

🤖 Generated with Claude Code

…age scroll

On touch the library already gates drag behind a 200ms hold
(delayOnTouchOnly default) and cancels the pending drag if the finger
moves more than touchStartThreshold (default 5px) before the timer
fires. Because touch-action is 'manipulation' while the timer is
pending, a cancelled drag falls straight through to a page scroll — so
the natural "press and immediately move to drag" motion scrolled the
page on iPhone instead of dragging.

Apply a shared TOUCH config (delayOnTouchOnly: 150, touchStartThreshold:
15) to every showcase demo: the drag arms faster and tolerates the
finger drift of a deliberate drag-start, while a fast scroll flick still
exceeds 15px well under 150ms and scrolls as before.

Demo-config only; no library change.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Copilot AI review requested due to automatic review settings June 14, 2026 00:12
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts the showcase demo’s touch interaction configuration to reduce accidental page scrolling on mobile (notably iOS Safari) when users intend to drag items. It does this by introducing a shared touch-tuning options object and applying it consistently to all Sortable instances created in the showcase script.

Changes:

  • Introduces a shared TOUCH options object (delayOnTouchOnly: 150, touchStartThreshold: 15) in the demo script.
  • Applies ...TOUCH to each showcase Sortable initialization (including shared option objects like Kanban and folder/file lists).

@jjeff jjeff merged commit 193c9f0 into main Jun 14, 2026
14 checks passed
@jjeff jjeff deleted the worktree-touch-drag-tuning branch June 14, 2026 13:11
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.

2 participants