Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,48 @@ jobs:
- name: Run unit tests
run: yarn test --maxWorkers=2 --coverage

# Enforces the `react-native-gesture-handler: ^2.0.0 || ^3.0.0` peer range.
#
# `yarn typecheck` is the load-bearing step: `src/` is `.ts`, so `skipLibCheck`
# does NOT suppress a missing Gesture Handler export there, and the imports in
# our shipped `.d.ts` are generated from those same statements. A consumer-side
# type test cannot replace this — in a `.d.ts`, an unresolved import silently
# widens to the error type instead of failing, which no type assertion can
# detect.
#
# Majors are tracked by tag rather than pinned so an upstream release that
# breaks the range surfaces here instead of in users' projects.
gesture-handler-compat:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
gesture-handler: ['2', '3']

steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Setup
uses: ./.github/actions/setup

- name: Install Gesture Handler v${{ matrix.gesture-handler }}
# Overriding the pinned devDependency necessarily mutates package.json
# and yarn.lock, which CI's default immutable install forbids.
env:
YARN_ENABLE_IMMUTABLE_INSTALLS: 'false'
run: yarn add -D react-native-gesture-handler@${{ matrix.gesture-handler }}

- name: Report resolved version
run: node -p "require('react-native-gesture-handler/package.json').version"

- name: Typecheck files
run: yarn typecheck

- name: Run unit tests
run: yarn test --maxWorkers=2

build-library:
runs-on: ubuntu-latest

Expand Down
17 changes: 12 additions & 5 deletions docs/docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,24 @@ bun add react-native-header-motion

Header Motion relies on three peer dependencies that your project must provide:

| Package | Required version |
| ------------------------------ | ---------------- |
| `react-native-reanimated` | `^4.0.0` |
| `react-native-gesture-handler` | `^2.0.0` |
| `react-native-worklets` | `>= 0.4.0` |
| Package | Required version |
| ------------------------------ | -------------------- |
| `react-native-reanimated` | `^4.0.0` |
| `react-native-gesture-handler` | `^2.0.0 \|\| ^3.0.0` |
| `react-native-worklets` | `>= 0.4.0` |

If you already have these installed, you're good to go. Otherwise, follow their respective installation guides:

- [Reanimated & Worklets installation](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#installation)
- [Gesture Handler installation](https://docs.swmansion.com/react-native-gesture-handler/docs/fundamentals/installation)

:::info
Both Gesture Handler v2 and v3 are supported, and no configuration is needed to
pick between them. Header Motion uses the gesture API that v3 keeps at the
package root, and v3's `GestureDetector` transparently handles it — so the same
code runs on either major.
:::

:::caution
Make sure the version of `react-native-worklets` you install is compatible with your version of Reanimated. Check the [compatibility table](https://docs.swmansion.com/react-native-reanimated/docs/guides/compatibility) before installing.
:::
Expand Down
8 changes: 8 additions & 0 deletions docs/docs/other/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ If your header lives inside the same component tree as `HeaderMotion` (not rende

Header panning is built on Gesture Handler's pan gesture. Even if you don't use the `pannable` prop, the library imports from `react-native-gesture-handler`. Most React Native projects already have it installed.

## Does Header Motion work with Gesture Handler v3?

Yes. Both v2 and v3 are supported by the same build — there's no separate entry point, flag, or configuration to set.

Header Motion touches a deliberately small part of Gesture Handler: the `Gesture` builder, `GestureDetector`, `GestureHandlerRootView`, and the `GestureStateChangeEvent` / `PanGestureHandlerEventPayload` types. v3 still exports all of these from the package root under the same names, and its `GestureDetector` accepts gestures from either API and routes them accordingly. The v3 rename that moved parts of the v2 surface behind `Legacy*` names affected components and gesture instance types that this library doesn't use.

One consequence worth knowing if you compile with `skipLibCheck: false`: Gesture Handler v3 currently ships a native component spec whose props don't structurally extend React Native's `ViewProps`, so that setting fails inside `react-native-gesture-handler` itself, independently of Header Motion. `skipLibCheck: true` — the React Native template default — is the supported configuration.

## Can I use this with FlashList / LegendList / other custom scrollables?

Yes. Use `createHeaderMotionScrollable()` to wrap any scrollable component. For FlashList and LegendList, you can also use the built-in `ScrollablePresets` export so the recommended factory options are already filled in. See the [Custom scrollables](../guides/custom-scrollables) guide.
Expand Down
10 changes: 5 additions & 5 deletions docs/docs/other/migration-from-v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ The biggest shift is from a **prop-passing header API** to a **context-first hea

v1 requires:

| Package | Version |
| ------------------------------ | ---------- |
| `react-native-gesture-handler` | `^2.0.0` |
| `react-native-reanimated` | `^4.0.0` |
| `react-native-worklets` | `>= 0.4.0` |
| Package | Version |
| ------------------------------ | -------------------- |
| `react-native-gesture-handler` | `^2.0.0 \|\| ^3.0.0` |
| `react-native-reanimated` | `^4.0.0` |
| `react-native-worklets` | `>= 0.4.0` |

`react-native-gesture-handler` is new to the peer surface because header panning is built on it.

Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"react": "19.2.0",
"react-dom": "19.2.0",
"react-native": "0.83.2",
"react-native-gesture-handler": "2.30.0",
"react-native-gesture-handler": "3.2.1",
"react-native-pager-view": "8.0.0",
"react-native-reanimated": "4.2.1",
"react-native-safe-area-context": "~5.6.0",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"react": "19.2.0",
"react-native": "0.83.2",
"react-native-builder-bob": "^0.40.17",
"react-native-gesture-handler": "2.30.0",
"react-native-gesture-handler": "3.2.1",
"react-native-reanimated": "4.2.1",
"react-native-worklets": "0.7.2",
"release-it": "^19.0.4",
Expand All @@ -88,7 +88,7 @@
"peerDependencies": {
"react": "*",
"react-native": "*",
"react-native-gesture-handler": "^2.0.0",
"react-native-gesture-handler": "^2.0.0 || ^3.0.0",
"react-native-reanimated": "^4.0.0",
"react-native-worklets": ">=0.4.0"
},
Expand Down
44 changes: 18 additions & 26 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3355,15 +3355,6 @@ __metadata:
languageName: node
linkType: hard

"@egjs/hammerjs@npm:^2.0.17":
version: 2.0.17
resolution: "@egjs/hammerjs@npm:2.0.17"
dependencies:
"@types/hammerjs": "npm:^2.0.36"
checksum: 10c0/dbedc15a0e633f887c08394bd636faf6a3abd05726dc0909a0e01209d5860a752d9eca5e512da623aecfabe665f49f1d035de3103eb2f9022c5cea692f9cc9be
languageName: node
linkType: hard

"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1":
version: 4.9.1
resolution: "@eslint-community/eslint-utils@npm:4.9.1"
Expand Down Expand Up @@ -6645,13 +6636,6 @@ __metadata:
languageName: node
linkType: hard

"@types/hammerjs@npm:^2.0.36":
version: 2.0.46
resolution: "@types/hammerjs@npm:2.0.46"
checksum: 10c0/f3c1cb20dc2f0523f7b8c76065078544d50d8ae9b0edc1f62fed657210ed814266ff2dfa835d2c157a075991001eec3b64c88bf92e3e6e895c0db78d05711d06
languageName: node
linkType: hard

"@types/hast@npm:^3.0.0":
version: 3.0.4
resolution: "@types/hast@npm:3.0.4"
Expand Down Expand Up @@ -6853,6 +6837,15 @@ __metadata:
languageName: node
linkType: hard

"@types/react-test-renderer@npm:^19.1.0":
version: 19.1.0
resolution: "@types/react-test-renderer@npm:19.1.0"
dependencies:
"@types/react": "npm:*"
checksum: 10c0/799654e430df10aeaf267d71507fb64ec151359ead7e3774111bfd4abce7e0911dba461811195c06c22a6d17496ea92537d3185320ff4112fe29954cad1b9152
languageName: node
linkType: hard

"@types/react@npm:*, @types/react@npm:^19.1.12":
version: 19.2.14
resolution: "@types/react@npm:19.2.14"
Expand Down Expand Up @@ -12787,7 +12780,7 @@ __metadata:
languageName: node
linkType: hard

"hoist-non-react-statics@npm:^3.1.0, hoist-non-react-statics@npm:^3.3.0":
"hoist-non-react-statics@npm:^3.1.0":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
Expand Down Expand Up @@ -19290,17 +19283,16 @@ __metadata:
languageName: node
linkType: hard

"react-native-gesture-handler@npm:2.30.0":
version: 2.30.0
resolution: "react-native-gesture-handler@npm:2.30.0"
"react-native-gesture-handler@npm:3.2.1":
version: 3.2.1
resolution: "react-native-gesture-handler@npm:3.2.1"
dependencies:
"@egjs/hammerjs": "npm:^2.0.17"
hoist-non-react-statics: "npm:^3.3.0"
"@types/react-test-renderer": "npm:^19.1.0"
invariant: "npm:^2.2.4"
peerDependencies:
react: "*"
react-native: "*"
checksum: 10c0/26b94b0f97433fc6fb5b1c196ef29fce4f5a66c77fabb1bc33db91099357fbd44a5220783fcbb91d42700bcd578f2fd114314029d9e0d4674878767d9b7f5df6
checksum: 10c0/e20537d1eafe35206494eae7885ef85e7cd85185b32ccaac3d25f3e87beafa007ac79556c0af8da245db1140f6b5df35d20509d7fa56301d730de5a8abb1b90f
languageName: node
linkType: hard

Expand All @@ -19321,7 +19313,7 @@ __metadata:
react-dom: "npm:19.2.0"
react-native: "npm:0.83.2"
react-native-builder-bob: "npm:^0.40.17"
react-native-gesture-handler: "npm:2.30.0"
react-native-gesture-handler: "npm:3.2.1"
react-native-monorepo-config: "npm:^0.3.1"
react-native-pager-view: "npm:8.0.0"
react-native-reanimated: "npm:4.2.1"
Expand Down Expand Up @@ -19356,15 +19348,15 @@ __metadata:
react: "npm:19.2.0"
react-native: "npm:0.83.2"
react-native-builder-bob: "npm:^0.40.17"
react-native-gesture-handler: "npm:2.30.0"
react-native-gesture-handler: "npm:3.2.1"
react-native-reanimated: "npm:4.2.1"
react-native-worklets: "npm:0.7.2"
release-it: "npm:^19.0.4"
typescript: "npm:^5.9.2"
peerDependencies:
react: "*"
react-native: "*"
react-native-gesture-handler: ^2.0.0
react-native-gesture-handler: ^2.0.0 || ^3.0.0
react-native-reanimated: ^4.0.0
react-native-worklets: ">=0.4.0"
languageName: unknown
Expand Down
Loading