feat: support react-native-gesture-handler v3 - #26
Open
pawicao wants to merge 2 commits into
Open
Conversation
Widen the Gesture Handler peer range to `^2.0.0 || ^3.0.0`. No source changes were needed: every symbol this library uses is still exported from the v3 package root under the same name, and v3's `GestureDetector` accepts legacy gestures and dispatches to the legacy detector at runtime. The v3 `Legacy*` renames only touched components and gesture instance types, none of which we import. Our public type surface reaches Gesture Handler on a single line — the `GestureStateChangeEvent` / `PanGestureHandlerEventPayload` import in `types.ts` — and both are root exports in v2 and v3 with identical payload shapes. Add a `gesture-handler-compat` CI matrix over both majors. `yarn typecheck` is the step that actually enforces the range: `src/` is `.ts`, so a missing Gesture Handler export fails there even under `skipLibCheck: true`. A consumer-side type test was prototyped and dropped — in a `.d.ts` an unresolved import silently widens to the error type, which defeats every assertion, including `0 extends 1 & T` any-detection. Verified `lint`, `typecheck`, `test`, `prepare`, and the example app's typecheck against both 2.30.0 and 3.2.1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Move the pinned devDependency and the example app to 3.2.1, so local development and the example exercise the v3 code path. This matters for the example in particular: v3's `GestureDetector` routes legacy gestures to `LegacyGestureDetector` at runtime, and unit tests mock Gesture Handler entirely, so the example is the only place that branch runs for real. The `gesture-handler-compat` matrix keeps v2 covered. Its v2 leg overrides only the root devDependency, which is enough: `yarn typecheck` excludes `example` and Jest ignores `example/node_modules`, so the example's v3 pin does not leak into the v2 leg. Verified by simulating that install locally. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Purpose
This change adds support for
react-native-gesture-handlerv3. The librarycontinues to support v2. The peer range becomes
^2.0.0 || ^3.0.0.No source code changes are necessary. The reasons are below.
Why the source code does not change
The library uses five symbols from Gesture Handler:
GestureHeaderPanBoundary.tsxGestureDetectorHeaderPanBoundary.tsxGestureHandlerRootViewHeaderPanBoundary.tsxGestureStateChangeEventtypes.tsPanGestureHandlerEventPayloadtypes.tsv3 exports all five symbols from the package root. The names do not change.
The payload types keep the same shape.
v3 changes
GestureDetector. The root export is now the v3 detector. Thisdetector accepts a gesture from either API. It sends a legacy gesture to the
legacy detector:
v3 also renames part of the v2 surface to
Legacy*names. These renames applyto components and to gesture instance types. The library does not import these
items.
The library keeps the legacy gesture API. Do not migrate to the v3
usePanGesturehook. A migration makes version-conditional code necessary.How CI enforces the peer range
This change adds a
gesture-handler-compatjob. The job runs a matrix overboth majors. Each leg installs one major. Then each leg runs
yarn typecheckand
yarn test.yarn typecheckis the important step.src/holds.tsfiles.Therefore
skipLibCheckdoes not hide a missing Gesture Handler export.The shipped
.d.tsimports come from the same statements insrc/.The matrix tracks each major by tag. It does not pin a patch version. An
upstream release that breaks the range then fails in CI. Users do not find the
failure first.
A consumer type test is not possible
I built a consumer-side type test. Then I removed it. The test cannot fail
when it must fail.
An unresolved import inside a
.d.tsbecomes the TypeScript error type.TypeScript hides subsequent errors from the error type. Therefore no assertion
detects the problem. This includes
0 extends 1 & Tdetection ofany.I confirmed this behaviour. I pointed the built
types.d.tsat an export thatdoes not exist. The test still passed.
The same break in
src/types.tsgives a clear failure:For this reason,
yarn typecheckis the guarantee. The workflow file recordsthis reason. Do not add the fixture again.
skipLibCheck: falseis not possible with v3v3 ships
specs/RNGestureHandlerDetectorNativeComponent.d.ts. ItsNativePropsdoes not extend the React NativeViewPropstype. This giveserror
TS2430insidereact-native-gesture-handler.This problem is independent of Header Motion. No change in this repository can
correct it. Therefore
skipLibCheck: trueis the supported configuration. Thisvalue is also the React Native template default.
The FAQ records this limit.
Development versions
The pinned devDependency moves to 3.2.1. The example app also moves to 3.2.1.
Local development then uses the v3 code path.
The example app is important here. Unit tests replace Gesture Handler with a
mock. Therefore the tests do not run the
LegacyGestureDetectorbranch. Theexample app is the only place that runs this branch.
The v2 leg of the matrix stays correct. That leg overrides only the root
devDependency.
yarn typecheckexcludesexample. Jest ignoresexample/node_modules. I simulated this install. The root resolved v2.yarn typecheckandyarn testpassed.Verification
I ran these commands against 2.30.0, 2.32.0, and 3.2.1:
yarn lint— pass. Two warnings exist indocs/. They are not new.yarn typecheck— pass.yarn test— pass. 38 tests.yarn prepare— pass.npx tsc --noEmitinexample/— pass.Open item
No test runs v3 on a device. Please run the example app and use a pannable
header. This action exercises the
LegacyGestureDetectorbranch at runtime.🤖 Generated with Claude Code