react-native-screen-transitions 3.3.0-beta.3 → 3.3.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -31
- package/lib/commonjs/shared/animation/snap-to.js +2 -0
- package/lib/commonjs/shared/animation/snap-to.js.map +1 -1
- package/lib/commonjs/shared/components/create-transition-aware-component.js +20 -18
- package/lib/commonjs/shared/components/create-transition-aware-component.js.map +1 -1
- package/lib/commonjs/shared/components/screen-container.js +59 -6
- package/lib/commonjs/shared/components/screen-container.js.map +1 -1
- package/lib/commonjs/shared/constants.js +8 -1
- package/lib/commonjs/shared/constants.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-build-gestures.js +49 -39
- package/lib/commonjs/shared/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-screen-gesture-handlers.js +110 -61
- package/lib/commonjs/shared/hooks/gestures/use-screen-gesture-handlers.js.map +1 -1
- package/lib/commonjs/shared/hooks/gestures/use-scroll-registry.js +67 -70
- package/lib/commonjs/shared/hooks/gestures/use-scroll-registry.js.map +1 -1
- package/lib/commonjs/shared/providers/gestures.provider.js +112 -5
- package/lib/commonjs/shared/providers/gestures.provider.js.map +1 -1
- package/lib/commonjs/shared/types/ownership.types.js +71 -0
- package/lib/commonjs/shared/types/ownership.types.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/check-gesture-activation.js +72 -128
- package/lib/commonjs/shared/utils/gesture/check-gesture-activation.js.map +1 -1
- package/lib/commonjs/shared/utils/gesture/compute-claimed-directions.js +81 -0
- package/lib/commonjs/shared/utils/gesture/compute-claimed-directions.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/determine-snap-target.js +1 -1
- package/lib/commonjs/shared/utils/gesture/determine-snap-target.js.map +1 -1
- package/lib/commonjs/shared/utils/gesture/find-collapse-target.js +48 -0
- package/lib/commonjs/shared/utils/gesture/find-collapse-target.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/resolve-ownership.js +87 -0
- package/lib/commonjs/shared/utils/gesture/resolve-ownership.js.map +1 -0
- package/lib/commonjs/shared/utils/gesture/velocity.js +16 -5
- package/lib/commonjs/shared/utils/gesture/velocity.js.map +1 -1
- package/lib/module/shared/animation/snap-to.js +1 -0
- package/lib/module/shared/animation/snap-to.js.map +1 -1
- package/lib/module/shared/components/create-transition-aware-component.js +20 -18
- package/lib/module/shared/components/create-transition-aware-component.js.map +1 -1
- package/lib/module/shared/components/screen-container.js +59 -7
- package/lib/module/shared/components/screen-container.js.map +1 -1
- package/lib/module/shared/constants.js +7 -0
- package/lib/module/shared/constants.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-build-gestures.js +49 -39
- package/lib/module/shared/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-screen-gesture-handlers.js +112 -63
- package/lib/module/shared/hooks/gestures/use-screen-gesture-handlers.js.map +1 -1
- package/lib/module/shared/hooks/gestures/use-scroll-registry.js +68 -70
- package/lib/module/shared/hooks/gestures/use-scroll-registry.js.map +1 -1
- package/lib/module/shared/providers/gestures.provider.js +112 -5
- package/lib/module/shared/providers/gestures.provider.js.map +1 -1
- package/lib/module/shared/types/ownership.types.js +67 -0
- package/lib/module/shared/types/ownership.types.js.map +1 -0
- package/lib/module/shared/utils/gesture/check-gesture-activation.js +70 -126
- package/lib/module/shared/utils/gesture/check-gesture-activation.js.map +1 -1
- package/lib/module/shared/utils/gesture/compute-claimed-directions.js +77 -0
- package/lib/module/shared/utils/gesture/compute-claimed-directions.js.map +1 -0
- package/lib/module/shared/utils/gesture/determine-snap-target.js +1 -1
- package/lib/module/shared/utils/gesture/determine-snap-target.js.map +1 -1
- package/lib/module/shared/utils/gesture/find-collapse-target.js +44 -0
- package/lib/module/shared/utils/gesture/find-collapse-target.js.map +1 -0
- package/lib/module/shared/utils/gesture/resolve-ownership.js +83 -0
- package/lib/module/shared/utils/gesture/resolve-ownership.js.map +1 -0
- package/lib/module/shared/utils/gesture/velocity.js +16 -5
- package/lib/module/shared/utils/gesture/velocity.js.map +1 -1
- package/lib/typescript/shared/animation/snap-to.d.ts.map +1 -1
- package/lib/typescript/shared/components/create-transition-aware-component.d.ts.map +1 -1
- package/lib/typescript/shared/components/screen-container.d.ts.map +1 -1
- package/lib/typescript/shared/constants.d.ts +6 -0
- package/lib/typescript/shared/constants.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-build-gestures.d.ts +15 -3
- package/lib/typescript/shared/hooks/gestures/use-build-gestures.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-screen-gesture-handlers.d.ts +52 -2
- package/lib/typescript/shared/hooks/gestures/use-screen-gesture-handlers.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/gestures/use-scroll-registry.d.ts +11 -6
- package/lib/typescript/shared/hooks/gestures/use-scroll-registry.d.ts.map +1 -1
- package/lib/typescript/shared/hooks/use-backdrop-pointer-events.d.ts +1 -1
- package/lib/typescript/shared/hooks/use-backdrop-pointer-events.d.ts.map +1 -1
- package/lib/typescript/shared/providers/gestures.provider.d.ts +27 -2
- package/lib/typescript/shared/providers/gestures.provider.d.ts.map +1 -1
- package/lib/typescript/shared/types/ownership.types.d.ts +52 -0
- package/lib/typescript/shared/types/ownership.types.d.ts.map +1 -0
- package/lib/typescript/shared/types/screen.types.d.ts +22 -1
- package/lib/typescript/shared/types/screen.types.d.ts.map +1 -1
- package/lib/typescript/shared/utils/gesture/check-gesture-activation.d.ts +23 -19
- package/lib/typescript/shared/utils/gesture/check-gesture-activation.d.ts.map +1 -1
- package/lib/typescript/shared/utils/gesture/compute-claimed-directions.d.ts +23 -0
- package/lib/typescript/shared/utils/gesture/compute-claimed-directions.d.ts.map +1 -0
- package/lib/typescript/shared/utils/gesture/determine-snap-target.d.ts +5 -1
- package/lib/typescript/shared/utils/gesture/determine-snap-target.d.ts.map +1 -1
- package/lib/typescript/shared/utils/gesture/find-collapse-target.d.ts +17 -0
- package/lib/typescript/shared/utils/gesture/find-collapse-target.d.ts.map +1 -0
- package/lib/typescript/shared/utils/gesture/resolve-ownership.d.ts +36 -0
- package/lib/typescript/shared/utils/gesture/resolve-ownership.d.ts.map +1 -0
- package/lib/typescript/shared/utils/gesture/velocity.d.ts.map +1 -1
- package/package.json +121 -120
- package/src/shared/animation/snap-to.ts +1 -0
- package/src/shared/components/create-transition-aware-component.tsx +28 -25
- package/src/shared/components/screen-container.tsx +69 -7
- package/src/shared/constants.ts +7 -0
- package/src/shared/hooks/gestures/use-build-gestures.tsx +80 -44
- package/src/shared/hooks/gestures/use-screen-gesture-handlers.ts +147 -71
- package/src/shared/hooks/gestures/use-scroll-registry.tsx +94 -86
- package/src/shared/hooks/use-backdrop-pointer-events.ts +1 -1
- package/src/shared/providers/gestures.provider.tsx +166 -5
- package/src/shared/types/ownership.types.ts +77 -0
- package/src/shared/types/screen.types.ts +24 -1
- package/src/shared/utils/gesture/check-gesture-activation.ts +82 -116
- package/src/shared/utils/gesture/compute-claimed-directions.ts +93 -0
- package/src/shared/utils/gesture/determine-snap-target.ts +6 -2
- package/src/shared/utils/gesture/find-collapse-target.ts +42 -0
- package/src/shared/utils/gesture/resolve-ownership.ts +110 -0
- package/src/shared/utils/gesture/velocity.ts +16 -6
- package/src/shared/__tests__/bounds.store.test.ts +0 -394
- package/src/shared/__tests__/derivations.test.ts +0 -156
- package/src/shared/__tests__/determine-dismissal.test.ts +0 -111
- package/src/shared/__tests__/determine-snap-target.test.ts +0 -268
- package/src/shared/__tests__/geometry.test.ts +0 -130
- package/src/shared/__tests__/gesture-activation.test.ts +0 -471
- package/src/shared/__tests__/gesture.velocity.test.ts +0 -131
- package/src/shared/__tests__/history.store.test.ts +0 -550
- package/src/shared/__tests__/sync-routes-with-removed.test.ts +0 -137
- package/src/shared/__tests__/validate-snap-points.test.ts +0 -125
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { GestureDirection } from "../../types/gesture.types";
|
|
2
|
+
import { type ClaimedDirections } from "../../types/ownership.types";
|
|
3
|
+
/**
|
|
4
|
+
* Computes which directions a screen claims ownership of.
|
|
5
|
+
*
|
|
6
|
+
* A screen claims a direction when:
|
|
7
|
+
* 1. gestureEnabled is true AND
|
|
8
|
+
* 2. gestureDirection includes that direction
|
|
9
|
+
*
|
|
10
|
+
* For snap points, both directions on the axis are claimed automatically.
|
|
11
|
+
* This is because a snap point sheet handles both expand (inverse) and collapse (primary) gestures.
|
|
12
|
+
*
|
|
13
|
+
* @param gestureEnabled - Whether gestures are enabled for this screen
|
|
14
|
+
* @param gestureDirection - The gesture direction(s) configured for this screen
|
|
15
|
+
* @param hasSnapPoints - Whether this screen has snap points configured
|
|
16
|
+
* @returns The claimed directions for this screen
|
|
17
|
+
*/
|
|
18
|
+
export declare function computeClaimedDirections(gestureEnabled: boolean, gestureDirection: GestureDirection | GestureDirection[] | undefined, hasSnapPoints: boolean): ClaimedDirections;
|
|
19
|
+
/**
|
|
20
|
+
* Checks if any direction is claimed.
|
|
21
|
+
*/
|
|
22
|
+
export declare function claimsAnyDirection(claims: ClaimedDirections): boolean;
|
|
23
|
+
//# sourceMappingURL=compute-claimed-directions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute-claimed-directions.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/compute-claimed-directions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EACN,KAAK,iBAAiB,EAGtB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACvC,cAAc,EAAE,OAAO,EACvB,gBAAgB,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,GAAG,SAAS,EACnE,aAAa,EAAE,OAAO,GACpB,iBAAiB,CAsDnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAOrE"}
|
|
@@ -5,7 +5,11 @@ interface DetermineSnapTargetProps {
|
|
|
5
5
|
velocity: number;
|
|
6
6
|
/** Screen dimension along the snap axis (width or height) */
|
|
7
7
|
dimension: number;
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* How much velocity affects the snap decision.
|
|
10
|
+
* Lower values = more deliberate/iOS-like, higher values = more responsive to flicks.
|
|
11
|
+
* @default 0.1
|
|
12
|
+
*/
|
|
9
13
|
velocityFactor?: number;
|
|
10
14
|
/** Whether dismiss (progress=0) is allowed. Default true */
|
|
11
15
|
canDismiss?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"determine-snap-target.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/determine-snap-target.ts"],"names":[],"mappings":"AAAA,UAAU,wBAAwB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB
|
|
1
|
+
{"version":3,"file":"determine-snap-target.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/determine-snap-target.ts"],"names":[],"mappings":"AAAA,UAAU,wBAAwB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,yBAAyB;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EACnC,eAAe,EACf,UAAU,EACV,QAAQ,EACR,SAAS,EACT,cAAoB,EACpB,UAAiB,GACjB,EAAE,wBAAwB,GAAG,yBAAyB,CA0CtD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface FindCollapseTargetResult {
|
|
2
|
+
target: number;
|
|
3
|
+
shouldDismiss: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Finds the next lower snap point for backdrop collapse behavior.
|
|
7
|
+
*
|
|
8
|
+
* - If above min snap: returns next lower snap point
|
|
9
|
+
* - If at or below min snap: returns 0 (dismiss) if canDismiss, else stays at min
|
|
10
|
+
*
|
|
11
|
+
* @param currentProgress - Current animation progress
|
|
12
|
+
* @param snapPoints - Array of snap points
|
|
13
|
+
* @param canDismiss - Whether dismissing is allowed
|
|
14
|
+
*/
|
|
15
|
+
export declare function findCollapseTarget(currentProgress: number, snapPoints: number[], canDismiss: boolean): FindCollapseTargetResult;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=find-collapse-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-collapse-target.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/find-collapse-target.ts"],"names":[],"mappings":"AAEA,UAAU,wBAAwB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CACjC,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAAE,EACpB,UAAU,EAAE,OAAO,GACjB,wBAAwB,CAoB1B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ClaimedDirections } from "../../types/ownership.types";
|
|
2
|
+
import { type DirectionOwnership } from "../../types/ownership.types";
|
|
3
|
+
/**
|
|
4
|
+
* Minimal interface for ancestor context needed for ownership resolution.
|
|
5
|
+
* This allows the function to be used without importing the full GestureContextType.
|
|
6
|
+
*/
|
|
7
|
+
export interface AncestorClaimsContext {
|
|
8
|
+
claimedDirections: ClaimedDirections;
|
|
9
|
+
ancestorContext: AncestorClaimsContext | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Resolves ownership status for all directions relative to the current screen.
|
|
13
|
+
*
|
|
14
|
+
* For each direction:
|
|
15
|
+
* 1. If the current screen claims it → 'self' (should activate)
|
|
16
|
+
* 2. Else, walk up ancestors looking for a claim → 'ancestor' (should fail to bubble)
|
|
17
|
+
* 3. If no one claims it → 'none' (should fail, no gesture response)
|
|
18
|
+
*
|
|
19
|
+
* This is computed during render (JS thread) and the result can be safely
|
|
20
|
+
* used in worklets since it's a plain object.
|
|
21
|
+
*
|
|
22
|
+
* @param selfClaims - The directions claimed by the current screen
|
|
23
|
+
* @param ancestorContext - The ancestor context chain (can be null if no ancestors)
|
|
24
|
+
* @returns Ownership status for all four directions
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveOwnership(selfClaims: ClaimedDirections, ancestorContext: AncestorClaimsContext | null): DirectionOwnership;
|
|
27
|
+
/**
|
|
28
|
+
* Finds the nearest ancestor (or self if isCurrentOwner) that claims any direction.
|
|
29
|
+
* Used for setting up native gesture relationships.
|
|
30
|
+
*
|
|
31
|
+
* @param selfClaimsAny - Whether the current screen claims any direction
|
|
32
|
+
* @param ancestorContext - The ancestor context chain
|
|
33
|
+
* @returns The nearest context that claims a direction, or null
|
|
34
|
+
*/
|
|
35
|
+
export declare function findNearestOwner(selfClaimsAny: boolean, ancestorContext: AncestorClaimsContext | null): AncestorClaimsContext | null;
|
|
36
|
+
//# sourceMappingURL=resolve-ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-ownership.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/resolve-ownership.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAa,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAEN,KAAK,kBAAkB,EAGvB,MAAM,6BAA6B,CAAC;AAErC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACrC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,eAAe,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC9C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC/B,UAAU,EAAE,iBAAiB,EAC7B,eAAe,EAAE,qBAAqB,GAAG,IAAI,GAC3C,kBAAkB,CAYpB;AA4BD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC/B,aAAa,EAAE,OAAO,EACtB,eAAe,EAAE,qBAAqB,GAAG,IAAI,GAC3C,qBAAqB,GAAG,IAAI,CAuB9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"velocity.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/velocity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,uBAAuB,EACvB,6BAA6B,EAC7B,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"velocity.d.ts","sourceRoot":"","sources":["../../../../../src/shared/utils/gesture/velocity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,uBAAuB,EACvB,6BAA6B,EAC7B,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,UAAU,sBAAsB;IAC/B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE,uBAAuB,CAAC,6BAA6B,CAAC,CAAC;IAC9D,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,UAAU,EAAE;QACX,UAAU,EAAE,OAAO,CAAC;QACpB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,QAAQ,EAAE,OAAO,CAAC;QAClB,gBAAgB,EAAE,OAAO,CAAC;KAC1B,CAAC;CACF;AAyID,eAAO,MAAM,QAAQ;yCAjIuB,MAAM,cAAc,MAAM;wCAa3B,MAAM,aAAa,MAAM;uDAU3C,MAAM,0BACN,MAAM;+FAkB5B,sBAAsB;sDAyDL,MAAM,2BACA,MAAM,cACnB,MAAM,kBACF,MAAM;CAiCtB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,122 +1,123 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
2
|
+
"name": "react-native-screen-transitions",
|
|
3
|
+
"version": "3.3.0-beta.4",
|
|
4
|
+
"description": "Easy screen transitions for React Native and Expo",
|
|
5
|
+
"author": "Ed",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/eds2002/react-native-screen-transitions.git",
|
|
10
|
+
"directory": "packages/react-native-screen-transitions"
|
|
11
|
+
},
|
|
12
|
+
"main": "lib/commonjs/shared/index.js",
|
|
13
|
+
"module": "lib/module/shared/index.js",
|
|
14
|
+
"types": "lib/typescript/shared/index.d.ts",
|
|
15
|
+
"react-native": "src/shared/index",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"react-native": "./src/shared/index.ts",
|
|
19
|
+
"import": "./lib/module/shared/index.js",
|
|
20
|
+
"require": "./lib/commonjs/shared/index.js",
|
|
21
|
+
"types": "./lib/typescript/shared/index.d.ts"
|
|
22
|
+
},
|
|
23
|
+
"./native-stack": {
|
|
24
|
+
"react-native": "./src/native-stack/index.ts",
|
|
25
|
+
"import": "./lib/module/native-stack/index.js",
|
|
26
|
+
"require": "./lib/commonjs/native-stack/index.js",
|
|
27
|
+
"types": "./lib/typescript/native-stack/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./blank-stack": {
|
|
30
|
+
"react-native": "./src/blank-stack/index.ts",
|
|
31
|
+
"import": "./lib/module/blank-stack/index.js",
|
|
32
|
+
"require": "./lib/commonjs/blank-stack/index.js",
|
|
33
|
+
"types": "./lib/typescript/blank-stack/index.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./component-stack": {
|
|
36
|
+
"react-native": "./src/component-stack/index.ts",
|
|
37
|
+
"import": "./lib/module/component-stack/index.js",
|
|
38
|
+
"require": "./lib/commonjs/component-stack/index.js",
|
|
39
|
+
"types": "./lib/typescript/component-stack/index.d.ts"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "bob build",
|
|
44
|
+
"lint": "biome check ./src",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"prepublishOnly": "bun run build",
|
|
47
|
+
"release": "release-it",
|
|
48
|
+
"release:beta": "release-it --preRelease=beta"
|
|
49
|
+
},
|
|
50
|
+
"keywords": [
|
|
51
|
+
"react-native",
|
|
52
|
+
"transitions",
|
|
53
|
+
"animation",
|
|
54
|
+
"react-navigation",
|
|
55
|
+
"expo-router",
|
|
56
|
+
"reanimated"
|
|
57
|
+
],
|
|
58
|
+
"files": [
|
|
59
|
+
"lib",
|
|
60
|
+
"src",
|
|
61
|
+
"!src/**/__tests__",
|
|
62
|
+
"README.md",
|
|
63
|
+
"LICENSE"
|
|
64
|
+
],
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"@react-navigation/elements": ">=2.0.0",
|
|
67
|
+
"@react-navigation/native": ">=6.0.0",
|
|
68
|
+
"@react-navigation/native-stack": ">=7.0.0",
|
|
69
|
+
"@types/react": "*",
|
|
70
|
+
"@types/react-native": "*",
|
|
71
|
+
"react": "*",
|
|
72
|
+
"react-native": "*",
|
|
73
|
+
"react-native-gesture-handler": ">=2.16.1",
|
|
74
|
+
"react-native-reanimated": ">=3.16.0 || >=4.0.0-",
|
|
75
|
+
"react-native-safe-area-context": "*",
|
|
76
|
+
"react-native-screens": ">=4.4.0"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
80
|
+
"@types/react": "~19.1.10",
|
|
81
|
+
"react-native-builder-bob": "0.39.0",
|
|
82
|
+
"release-it": "^19.0.4",
|
|
83
|
+
"typescript": "catalog:"
|
|
84
|
+
},
|
|
85
|
+
"react-native-builder-bob": {
|
|
86
|
+
"source": "src",
|
|
87
|
+
"output": "lib",
|
|
88
|
+
"targets": [
|
|
89
|
+
"commonjs",
|
|
90
|
+
"module",
|
|
91
|
+
[
|
|
92
|
+
"typescript",
|
|
93
|
+
{
|
|
94
|
+
"project": "tsconfig.build.json"
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
"release-it": {
|
|
100
|
+
"git": {
|
|
101
|
+
"commitMessage": "chore: release ${version}",
|
|
102
|
+
"tagName": "v${version}",
|
|
103
|
+
"commitArgs": [
|
|
104
|
+
"-n"
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
"npm": {
|
|
108
|
+
"publish": true
|
|
109
|
+
},
|
|
110
|
+
"github": {
|
|
111
|
+
"release": true
|
|
112
|
+
},
|
|
113
|
+
"plugins": {
|
|
114
|
+
"@release-it/conventional-changelog": {
|
|
115
|
+
"preset": {
|
|
116
|
+
"name": "angular"
|
|
117
|
+
},
|
|
118
|
+
"path": "."
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
"gitHead": "888d4df9936ec0e3b8221bea7cd81115e6301693"
|
|
122
123
|
}
|
|
@@ -6,7 +6,6 @@ import { GestureDetector } from "react-native-gesture-handler";
|
|
|
6
6
|
import Animated, { runOnUI, useAnimatedRef } from "react-native-reanimated";
|
|
7
7
|
import { useAssociatedStyles } from "../hooks/animation/use-associated-style";
|
|
8
8
|
import { useScrollRegistry } from "../hooks/gestures/use-scroll-registry";
|
|
9
|
-
import { useGestureContext } from "../providers/gestures.provider";
|
|
10
9
|
import { RegisterBoundsProvider } from "../providers/register-bounds.provider";
|
|
11
10
|
import type { TransitionAwareProps } from "../types/screen.types";
|
|
12
11
|
|
|
@@ -26,33 +25,37 @@ export function createTransitionAwareComponent<P extends object>(
|
|
|
26
25
|
React.ComponentRef<typeof Wrapped>,
|
|
27
26
|
TransitionAwareProps<P>
|
|
28
27
|
>((props: any, ref) => {
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
// Determine scroll direction from the horizontal prop (standard ScrollView API)
|
|
29
|
+
const scrollDirection = props.horizontal ? "horizontal" : "vertical";
|
|
30
|
+
|
|
31
|
+
// Get scroll handlers and the gesture owner's nativeGesture for this axis
|
|
32
|
+
const { scrollHandler, onContentSizeChange, onLayout, nativeGesture } =
|
|
33
|
+
useScrollRegistry({
|
|
34
|
+
onScroll: props.onScroll,
|
|
35
|
+
onContentSizeChange: props.onContentSizeChange,
|
|
36
|
+
onLayout: props.onLayout,
|
|
37
|
+
direction: scrollDirection,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const scrollableComponent = (
|
|
41
|
+
<AnimatedComponent
|
|
42
|
+
{...(props as any)}
|
|
43
|
+
ref={ref}
|
|
44
|
+
onScroll={scrollHandler}
|
|
45
|
+
onContentSizeChange={onContentSizeChange}
|
|
46
|
+
onLayout={onLayout}
|
|
47
|
+
scrollEventThrottle={props.scrollEventThrottle || 16}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// If no gesture owner found for this axis, render without GestureDetector
|
|
52
|
+
if (!nativeGesture) {
|
|
53
|
+
return scrollableComponent;
|
|
54
|
+
}
|
|
43
55
|
|
|
44
56
|
return (
|
|
45
57
|
<GestureDetector gesture={nativeGesture}>
|
|
46
|
-
|
|
47
|
-
{...(props as any)}
|
|
48
|
-
ref={ref}
|
|
49
|
-
onScroll={scrollHandler}
|
|
50
|
-
onContentSizeChange={onContentSizeChange}
|
|
51
|
-
onLayout={onLayout}
|
|
52
|
-
onTouchStart={onTouchStart}
|
|
53
|
-
onTouchEnd={onTouchEnd}
|
|
54
|
-
scrollEventThrottle={props.scrollEventThrottle || 16}
|
|
55
|
-
/>
|
|
58
|
+
{scrollableComponent}
|
|
56
59
|
</GestureDetector>
|
|
57
60
|
);
|
|
58
61
|
});
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
/** biome-ignore-all lint/style/noNonNullAssertion: <Screen gesture is under the gesture context, so this will always exist.> */
|
|
1
2
|
import { StackActions } from "@react-navigation/native";
|
|
2
3
|
import { memo, useCallback } from "react";
|
|
3
4
|
import { Pressable, StyleSheet, View } from "react-native";
|
|
4
5
|
import { GestureDetector } from "react-native-gesture-handler";
|
|
5
|
-
import Animated, { useAnimatedStyle } from "react-native-reanimated";
|
|
6
|
+
import Animated, { runOnUI, useAnimatedStyle } from "react-native-reanimated";
|
|
7
|
+
import { DefaultSnapSpec } from "../configs/specs";
|
|
6
8
|
import { NO_STYLES } from "../constants";
|
|
7
9
|
import { useBackdropPointerEvents } from "../hooks/use-backdrop-pointer-events";
|
|
8
10
|
import { useGestureContext } from "../providers/gestures.provider";
|
|
9
11
|
import { useKeys } from "../providers/screen/keys.provider";
|
|
10
12
|
import { useScreenStyles } from "../providers/screen/styles.provider";
|
|
13
|
+
import { AnimationStore } from "../stores/animation.store";
|
|
14
|
+
import { GestureStore } from "../stores/gesture.store";
|
|
15
|
+
import { animateToProgress } from "../utils/animation/animate-to-progress";
|
|
16
|
+
import { findCollapseTarget } from "../utils/gesture/find-collapse-target";
|
|
11
17
|
|
|
12
18
|
type Props = {
|
|
13
19
|
children: React.ReactNode;
|
|
@@ -19,11 +25,67 @@ export const ScreenContainer = memo(({ children }: Props) => {
|
|
|
19
25
|
const { pointerEvents, backdropBehavior } = useBackdropPointerEvents();
|
|
20
26
|
const gestureContext = useGestureContext();
|
|
21
27
|
|
|
22
|
-
const
|
|
28
|
+
const isBackdropActive =
|
|
29
|
+
backdropBehavior === "dismiss" || backdropBehavior === "collapse";
|
|
30
|
+
|
|
31
|
+
const handleDismiss = useCallback(() => {
|
|
32
|
+
const state = current.navigation.getState();
|
|
33
|
+
current.navigation.dispatch({
|
|
34
|
+
...StackActions.pop(),
|
|
35
|
+
source: current.route.key,
|
|
36
|
+
target: state.key,
|
|
37
|
+
});
|
|
38
|
+
}, [current]);
|
|
23
39
|
|
|
24
40
|
const handleBackdropPress = useCallback(() => {
|
|
25
|
-
|
|
26
|
-
|
|
41
|
+
if (backdropBehavior === "dismiss") {
|
|
42
|
+
handleDismiss();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (backdropBehavior === "collapse") {
|
|
47
|
+
const snapPoints = current.options.snapPoints;
|
|
48
|
+
const canDismiss = current.options.gestureEnabled !== false;
|
|
49
|
+
|
|
50
|
+
// No snap points → fallback to dismiss
|
|
51
|
+
if (!snapPoints || snapPoints.length === 0) {
|
|
52
|
+
handleDismiss();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const animations = AnimationStore.getAll(current.route.key);
|
|
57
|
+
const gestures = GestureStore.getRouteGestures(current.route.key);
|
|
58
|
+
const transitionSpec = current.options.transitionSpec;
|
|
59
|
+
|
|
60
|
+
runOnUI(() => {
|
|
61
|
+
"worklet";
|
|
62
|
+
const { target, shouldDismiss } = findCollapseTarget(
|
|
63
|
+
animations.progress.value,
|
|
64
|
+
snapPoints,
|
|
65
|
+
canDismiss,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// If already dismissing, skip
|
|
69
|
+
if (gestures.isDismissing.value) return;
|
|
70
|
+
|
|
71
|
+
gestures.isDismissing.value = shouldDismiss ? 1 : 0;
|
|
72
|
+
|
|
73
|
+
const spec = shouldDismiss
|
|
74
|
+
? transitionSpec
|
|
75
|
+
: {
|
|
76
|
+
open: transitionSpec?.expand ?? DefaultSnapSpec,
|
|
77
|
+
close: transitionSpec?.collapse ?? DefaultSnapSpec,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
animateToProgress({
|
|
81
|
+
target,
|
|
82
|
+
spec,
|
|
83
|
+
animations,
|
|
84
|
+
onAnimationFinish: shouldDismiss ? handleDismiss : undefined,
|
|
85
|
+
});
|
|
86
|
+
})();
|
|
87
|
+
}
|
|
88
|
+
}, [backdropBehavior, current, handleDismiss]);
|
|
27
89
|
|
|
28
90
|
const animatedContentStyle = useAnimatedStyle(() => {
|
|
29
91
|
"worklet";
|
|
@@ -41,8 +103,8 @@ export const ScreenContainer = memo(({ children }: Props) => {
|
|
|
41
103
|
<View style={styles.container} pointerEvents={pointerEvents}>
|
|
42
104
|
<Pressable
|
|
43
105
|
style={StyleSheet.absoluteFillObject}
|
|
44
|
-
pointerEvents={
|
|
45
|
-
onPress={
|
|
106
|
+
pointerEvents={isBackdropActive ? "auto" : "none"}
|
|
107
|
+
onPress={isBackdropActive ? handleBackdropPress : undefined}
|
|
46
108
|
>
|
|
47
109
|
<Animated.View
|
|
48
110
|
style={[StyleSheet.absoluteFillObject, animatedBackdropStyle]}
|
|
@@ -51,7 +113,7 @@ export const ScreenContainer = memo(({ children }: Props) => {
|
|
|
51
113
|
<GestureDetector gesture={gestureContext!.panGesture}>
|
|
52
114
|
<Animated.View
|
|
53
115
|
style={[styles.content, animatedContentStyle]}
|
|
54
|
-
pointerEvents={
|
|
116
|
+
pointerEvents={isBackdropActive ? "box-none" : pointerEvents}
|
|
55
117
|
>
|
|
56
118
|
{children}
|
|
57
119
|
</Animated.View>
|
package/src/shared/constants.ts
CHANGED
|
@@ -93,6 +93,7 @@ export const FULLSCREEN_DIMENSIONS = (
|
|
|
93
93
|
* Default gesture config
|
|
94
94
|
*/
|
|
95
95
|
export const GESTURE_VELOCITY_IMPACT = 0.3;
|
|
96
|
+
export const SNAP_VELOCITY_IMPACT = 0.1;
|
|
96
97
|
export const DEFAULT_GESTURE_DIRECTION = "horizontal";
|
|
97
98
|
export const DEFAULT_GESTURE_DRIVES_PROGRESS = true;
|
|
98
99
|
export const DEFAULT_GESTURE_ACTIVATION_AREA: ActivationArea = "screen";
|
|
@@ -106,3 +107,9 @@ export const FALSE = 0;
|
|
|
106
107
|
* Small value for floating-point comparisons to handle animation/interpolation imprecision
|
|
107
108
|
*/
|
|
108
109
|
export const EPSILON = 1e-5;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Threshold for snapping animations to target when "close enough" (1% of range).
|
|
113
|
+
* Prevents micro-jitter/oscillation near animation endpoints.
|
|
114
|
+
*/
|
|
115
|
+
export const ANIMATION_SNAP_THRESHOLD = 0.01;
|