feat(DraxView): add per-axis drag activation offsets - #277
Open
cvburgess wants to merge 1 commit into
Open
Conversation
Adds dragActivationOffsetX/Y (activeOffsetX/Y) and the per-axis
dragActivationFailOffsetX/Y, so a drag can be told apart by direction
rather than by a long-press delay.
longPressDelay maps to activateAfterLongPress, which activates the pan
after its delay regardless of movement — a stationary press starts a
drag. That is a problem when the draggable view also hosts a long-press
context menu: any delay short enough to feel responsive cancels the menu,
and any delay long enough to avoid it loses the drag. There is no value
that satisfies both.
dragActivationFailOffset can't express the alternative, because it
applies the same value to failOffsetX and failOffsetY. Separating the
gestures needs 'activate on horizontal, fail on vertical', which takes
per-axis control:
longPressDelay={0}
dragActivationOffsetX={[-15, 15]}
dragActivationFailOffsetY={[-15, 15]}
A press that doesn't move leaves the context menu to open, a vertical
drag scrolls the list, and a horizontal drag starts the drag.
Fully additive: every new prop is optional, and dragActivationFailOffset
keeps its existing meaning as the symmetric shorthand — the per-axis
values only take precedence on their own axis when set. Applied to both
the RNGH v2 builder and v3 usePanGesture paths.
|
@cvburgess is attempting to deploy a commit to the Nuclear Pasta Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds four optional props —
dragActivationOffsetX/dragActivationOffsetY(mapping to gesture-handler'sactiveOffsetX/activeOffsetY) and per-axisdragActivationFailOffsetX/dragActivationFailOffsetY— so a drag can be told apart by direction rather than by a long-press delay.Happy to move this to an issue for discussion first if you'd prefer; CONTRIBUTING asks for that on non-trivial changes and I wasn't sure which side of that line this falls on.
The problem
longPressDelaymaps toactivateAfterLongPress, which activates the pan after its delay regardless of movement — so a stationary press starts a drag.That's fine in isolation, but it conflicts when the draggable view also hosts a long-press context menu. On iOS that's a
UIContextMenuInteractionat ~500ms; when the pan activates first it cancels the UIKit touches and the menu never opens. There is no value that satisfies both:We hit this shipping drag-to-reschedule in a planner app, where the same card is both a drag source and the host of a context menu carrying most of its actions. It presented as an intermittent menu, which took a while to pin down: the menu only appeared when the drag happened to fail first via
dragActivationFailOffset.dragActivationFailOffsetcan't express the alternative, because it applies one value to bothfailOffsetXandfailOffsetY. Separating the gestures needs "activate on horizontal, fail on vertical" — which requires per-axis control.The fix
When every meaningful drop is on one axis, the offsets separate the three gestures cleanly, with no timer involved:
A press that doesn't move leaves the context menu to open, a vertical drag scrolls the list, and a horizontal drag starts the drag. It also removes a footgun in the existing API: with
longPressDelay: 0, a symmetricdragActivationFailOffsetis the only rule the pan has left, so setting one prevents the drag from ever activating.Compatibility
Fully additive:
dragActivationFailOffsetkeeps its exact current meaning as the symmetric shorthand; the per-axis values take precedence only on their own axis, and only when setChanges
src/types.ts— the four newDraxViewPropssrc/DraxView.tsx— added toDRAX_PROP_KEYS(so they don't reach the underlyingReanimated.View) and forwarded touseDragGesturesrc/hooks/useDragGesture.ts— one new optional trailing argument; per-axis values resolve over the symmetric shorthandsrc/compat/types.ts,src/compat/useDraxPanGesture.ts—activeOffsetX/activeOffsetYapplied on both the RNGH v2 builder and v3usePanGesturepathsdocs-site/docs/api/components/drax-view.mdx— props table rows plus a short "Activating a drag by direction" sectionI left
CHANGELOG.mdalone sincerelease-itlooks like it's part of your release flow — glad to add an entry if you'd rather it came with the PR.Verification
yarn typecheck,yarn lint,yarn testandyarn prepareall pass, as do the lefthook pre-commit hooks.Beyond that it's been running in a production React Native app (iOS/iPad, Android, and web) via
patch-package, on RNGH 2.32 and Reanimated 4.5, across roughly a dozen simultaneous drop targets in a scrollable container. Verified by hand that the context menu and the drag now coexist on iPad, which is what motivated the change.I don't have a repro in
example/— let me know if you'd like one added and I'll put it together.