Skip to content
Merged
Show file tree
Hide file tree
Changes from 106 commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
daa017c
Separate Reanimated from JS in NativeDetector
m-bert Aug 21, 2025
1e17cf8
Separate Reanimated on Android
m-bert Aug 21, 2025
08d1e2b
Separate Reanimated on iOS
m-bert Aug 21, 2025
256f707
Reorganize structure
m-bert Aug 21, 2025
19fd985
Create ceparate hooks for Reanimated
m-bert Aug 21, 2025
133319b
Add checks in useGesture
m-bert Aug 22, 2025
e50f6cc
use isAnimatedEvent
m-bert Aug 22, 2025
b3ef022
Extract handlers in separate function
m-bert Aug 22, 2025
952fbe1
Pass correct touch event callback
m-bert Aug 22, 2025
ec9eaa7
Merge branch 'next' into @mbert/extract-reanimated-handlers
m-bert Aug 22, 2025
60a56e6
Merge branch 'next' into @mbert/extract-reanimated-handlers
m-bert Aug 25, 2025
fda23cc
Fix crash when onUpdate is Animated.Event
m-bert Aug 25, 2025
e46554b
Unify lateinit
m-bert Aug 25, 2025
13f3af4
Rename EventTarget on Android
m-bert Aug 25, 2025
d7a2b1a
Rename EventTarget on iOS
m-bert Aug 25, 2025
1b04d3c
Add reset for animated and reanimated events flags
m-bert Aug 25, 2025
b8df015
Rename getter for event handlers
m-bert Aug 25, 2025
93343da
Correctly handle disableReanimated
m-bert Aug 26, 2025
d1d3efb
Unpack nativeEvent
m-bert Aug 26, 2025
03a1e64
Bring back hooks
m-bert Aug 26, 2025
cc1313a
Use old name
m-bert Aug 26, 2025
dac39cf
Disable coalescing on Android
m-bert Aug 7, 2025
51b5a86
Implement DFS for gesture relations
m-bert Aug 13, 2025
92b4a3a
Implement module method for updating relations
m-bert Aug 14, 2025
e73ee57
Add blocksHandlers array
m-bert Aug 14, 2025
432aee0
Handle Simultaneous as root
m-bert Aug 14, 2025
b09d746
Change name to enum
m-bert Aug 14, 2025
db5d261
Move DFS to other file
m-bert Aug 14, 2025
43212af
Do not traverse single gestures
m-bert Aug 18, 2025
4ec26c0
Handle external relations
m-bert Aug 18, 2025
fa599af
Use operation block
m-bert Aug 20, 2025
42fc8c2
Move flushOperations into JS
m-bert Aug 20, 2025
f62a6df
Add exports for type
m-bert Aug 20, 2025
504feae
Add composed handler
m-bert Aug 26, 2025
122613f
Merge branch 'next' into @mbert/extract-reanimated-handlers
m-bert Aug 26, 2025
246f096
Merge branch '@mbert/extract-reanimated-handlers' into @mbert/relatio…
m-bert Aug 26, 2025
e229d84
Rename dfs
m-bert Aug 26, 2025
fac31e2
Split utils
m-bert Aug 26, 2025
53ce245
Merge branch 'next' into @mbert/extract-reanimated-handlers
m-bert Sep 4, 2025
fb88c8c
Change hook eslint rule to warning
m-bert Sep 4, 2025
8e5f07e
Extract choosing handler type into function
m-bert Sep 4, 2025
feaa167
Rename event handlers
m-bert Sep 4, 2025
3f2ea8c
Improve error message
m-bert Sep 4, 2025
4022b96
Move for loop inside function
m-bert Sep 4, 2025
8d9fc49
Merge branch '@mbert/extract-reanimated-handlers' into @mbert/relatio…
m-bert Sep 4, 2025
2dc44b8
Do not drop relataions on config change
m-bert Sep 4, 2025
fab60e5
Rename method
m-bert Sep 5, 2025
31c0e8b
Merge branch '@mbert/extract-reanimated-handlers' into @mbert/relatio…
m-bert Sep 5, 2025
832ffb0
Rename files to camelCase
m-bert Sep 5, 2025
bea99ab
Merge branch 'next' into @mbert/relations-v2
m-bert Sep 5, 2025
fb8c8e3
Rename files to camelCase
m-bert Sep 5, 2025
192556e
Remove todo
m-bert Sep 5, 2025
7c7876b
Make simultaneousWithExternalGesture symmetric
m-bert Sep 5, 2025
3e2b661
Fix crash with animated
m-bert Sep 5, 2025
8cd19ff
Add todo
m-bert Sep 5, 2025
74ec173
Type config
m-bert Sep 5, 2025
5c560e8
Split types and handler data
m-bert Sep 8, 2025
619aed9
Use enums
m-bert Sep 8, 2025
b12824b
Use named type
m-bert Sep 8, 2025
4ad7f5b
Extract dfs call to utils
m-bert Sep 8, 2025
a6f1ecb
Pass composed type as argument
m-bert Sep 8, 2025
761e22a
Move function to global scope
m-bert Sep 8, 2025
648f862
Update comment
m-bert Sep 8, 2025
ce2de67
Assign instead of only push
m-bert Sep 9, 2025
ec85bb5
Add warning about the same gesture passed multiple times
m-bert Sep 9, 2025
d6abf0d
Merge branch '@mbert/relations-v2' into @mbert/properly-type-config
m-bert Sep 9, 2025
2e99481
Do not store set in variable
m-bert Sep 9, 2025
adfada7
Change warning to error
m-bert Sep 9, 2025
7ab9b3b
Use warn about multiple animated events
m-bert Sep 9, 2025
c2c88cc
Do not add repeating tags with external relations into simultaneous h…
m-bert Sep 10, 2025
4baf2cb
Do not mark gesture as simultaneous with itself
m-bert Sep 10, 2025
db2e974
Handle external simultaneous composition
m-bert Sep 11, 2025
6fe39a5
Remove todo
m-bert Sep 11, 2025
1429ecd
Update types
m-bert Sep 11, 2025
81677c7
Change dfs name
m-bert Sep 11, 2025
759d022
Prepare external relations in useGesture
m-bert Sep 11, 2025
7c001fe
Rename types
m-bert Sep 12, 2025
c3d63cc
Mark otherHandlers as possibly undefined
m-bert Sep 12, 2025
3aa7e96
Merge branch '@mbert/relations-v2' into @mbert/properly-type-config
m-bert Sep 12, 2025
d20025b
Add default parameters to Gesture type
m-bert Sep 12, 2025
100e1aa
useTap
m-bert Sep 15, 2025
944cada
Make NativeDetector generic
m-bert Sep 15, 2025
b3e37e7
Merge branch 'next' into @mbert/properly-type-config
m-bert Sep 15, 2025
df1a0f5
Merge branch '@mbert/properly-type-config' into @mbert/gesture-hooks
m-bert Sep 15, 2025
a9392eb
useFling
m-bert Sep 15, 2025
72118e7
useLongPress
m-bert Sep 15, 2025
0688821
Small tap improvements
m-bert Sep 15, 2025
d3a7c32
usePinch
m-bert Sep 15, 2025
bc3f1e5
useRotation
m-bert Sep 15, 2025
3d3198c
Change interface to type
m-bert Sep 15, 2025
2d746d3
useHover
m-bert Sep 15, 2025
ed4af90
useManual
m-bert Sep 15, 2025
7871cc6
useNative
m-bert Sep 15, 2025
28455b3
usePan
m-bert Sep 15, 2025
c21c055
Rename types
m-bert Sep 15, 2025
0bf03e1
Add common props to HandlerData
m-bert Sep 15, 2025
37f392e
Long press default behavior
m-bert Sep 15, 2025
d3ad70f
Pan props validation
m-bert Sep 15, 2025
d69d9c4
Merge branch 'next' into @mbert/properly-type-config
m-bert Sep 16, 2025
14a72f1
Merge branch '@mbert/properly-type-config' into @mbert/gesture-hooks
m-bert Sep 16, 2025
e609fe4
Merge branch 'next' into @mbert/gesture-hooks
m-bert Sep 16, 2025
60b4655
Merge branch 'next' into @mbert/gesture-hooks
m-bert Sep 16, 2025
d2ff3a4
Remove unnecexxary export keywords
m-bert Sep 16, 2025
c10d2e2
Add ts-ignore explanations in NativeDetector
m-bert Sep 16, 2025
e2ab449
Switch order in type name
m-bert Sep 16, 2025
d77bd44
Update types
m-bert Sep 16, 2025
4b406a8
Fix NativeViewGestureHandler name
m-bert Sep 16, 2025
68dd1e6
Fix types
m-bert Sep 16, 2025
7f33ffc
Merge branch 'next' into @mbert/gesture-hooks
m-bert Sep 17, 2025
78a8f1a
Change type name to only T
m-bert Sep 18, 2025
5d0ef4d
Add cloneConfig to other gestures
m-bert Sep 18, 2025
dc472e1
Rename Props to Properties
m-bert Sep 18, 2025
b496adf
Merge branch 'next' into @mbert/gesture-hooks
m-bert Sep 18, 2025
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
2 changes: 2 additions & 0 deletions packages/react-native-gesture-handler/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,6 @@ export * from './v3/hooks/relations';

export { SingleGestureName } from './v3/types';

export * from './v3/hooks/gestures';

initialize();
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { tagMessage } from '../../utils';
import { configureRelations } from './utils';
import { isComposedGesture } from '../hooks/utils/relationUtils';

export interface NativeDetectorProps {
export interface NativeDetectorProps<THandlerData, TConfig> {
children?: React.ReactNode;
gesture: Gesture;
gesture: Gesture<THandlerData, TConfig>;
}

const AnimatedNativeDetector =
Expand All @@ -18,7 +18,10 @@ const AnimatedNativeDetector =
const ReanimatedNativeDetector =
Reanimated?.default.createAnimatedComponent(HostGestureDetector);

export function NativeDetector({ gesture, children }: NativeDetectorProps) {
export function NativeDetector<THandlerData, TConfig>({
gesture,
children,
}: NativeDetectorProps<THandlerData, TConfig>) {
const NativeDetectorComponent = gesture.config.dispatchesAnimatedEvents
? AnimatedNativeDetector
: gesture.config.shouldUseReanimated
Expand All @@ -38,25 +41,25 @@ export function NativeDetector({ gesture, children }: NativeDetectorProps) {

return (
<NativeDetectorComponent
// @ts-ignore TODO: Fix types
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
onGestureHandlerStateChange={
gesture.gestureEvents.onGestureHandlerStateChange
}
// @ts-ignore TODO: Fix types
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
onGestureHandlerEvent={gesture.gestureEvents.onGestureHandlerEvent}
// @ts-ignore TODO: Fix types
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
onGestureHandlerTouchEvent={
gesture.gestureEvents.onGestureHandlerTouchEvent
}
// @ts-ignore TODO: Fix types
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
onGestureHandlerReanimatedStateChange={
gesture.gestureEvents.onReanimatedStateChange
}
// @ts-ignore TODO: Fix types
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
onGestureHandlerReanimatedEvent={
gesture.gestureEvents.onReanimatedUpdateEvent
}
// @ts-ignore TODO: Fix types
// @ts-ignore This is a type mismatch between RNGH types and RN Codegen types
onGestureHandlerReanimatedTouchEvent={
gesture.gestureEvents.onReanimatedTouchEvent
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ export const traverseAndConfigureRelations = (
});
};

export function configureRelations(gesture: Gesture) {
export function configureRelations<THandlerData, TConfig>(
gesture: Gesture<THandlerData, TConfig>
) {
if (isComposedGesture(gesture)) {
const simultaneousHandlers = new Set<number>(
gesture.externalSimultaneousHandlers
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export type { TapGestureConfig } from './useTap';
export { useTap } from './useTap';

export type { FlingGestureConfig } from './useFling';
export { useFling } from './useFling';

export type { LongPressGestureConfig } from './useLongPress';
export { useLongPress } from './useLongPress';

export type { PinchGestureConfig } from './usePinch';
export { usePinch } from './usePinch';

export type { RotationGestureConfig } from './useRotation';
export { useRotation } from './useRotation';

export type { HoverGestureConfig } from './useHover';
export { useHover } from './useHover';

export type { ManualGestureConfig } from './useManual';
export { useManual } from './useManual';

export type { NativeViewGestureConfig } from './useNative';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can change to NativeGestureConfig (or something else) if you prefer.

export { useNative } from './useNative';

export type { PanGestureConfig } from './usePan';
export { usePan } from './usePan';
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
BaseGestureConfig,
ExcludeInternalConfigProps,
SingleGestureName,
} from '../../types';
import { useGesture } from '../useGesture';
import { cloneConfig } from '../utils';

type FlingGestureProps = {
/**
* Expressed allowed direction of movement. It's possible to pass one or many
* directions in one parameter:
*
* ```js
* direction={Directions.RIGHT | Directions.LEFT}
* ```
*
* or
*
* ```js
* direction={Directions.DOWN}
* ```
*/
direction?: number;

/**
* Determine exact number of points required to handle the fling gesture.
*/
numberOfPointers?: number;
};

type FlingHandlerData = {
x: number;
y: number;
absoluteX: number;
absoluteY: number;
};

type FlingGestureInternalConfig = BaseGestureConfig<
FlingHandlerData,
FlingGestureProps
>;

export type FlingGestureConfig =
ExcludeInternalConfigProps<FlingGestureInternalConfig>;

export function useFling(config: FlingGestureConfig) {
const flingConfig = cloneConfig<FlingHandlerData, FlingGestureProps>(config);

return useGesture(SingleGestureName.Fling, flingConfig);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { StylusData } from '../../../handlers/gestureHandlerCommon';
import { HoverEffect } from '../../../handlers/gestures/hoverGesture';
import {
BaseGestureConfig,
ExcludeInternalConfigProps,
SingleGestureName,
} from '../../types';
import { useGesture } from '../useGesture';
import { cloneConfig } from '../utils';

type HoverGestureProps = {
/**
* Visual effect applied to the view while the view is hovered. The possible values are:
*
* - `HoverEffect.None`
* - `HoverEffect.Lift`
* - `HoverEffect.Highlight`
*
* Defaults to `HoverEffect.None`
*/
hoverEffect?: HoverEffect;
};

type HoverHandlerData = {
x: number;
y: number;
absoluteX: number;
absoluteY: number;
stylusData: StylusData;
};

type HoverGestureInternalConfig = BaseGestureConfig<
HoverHandlerData,
HoverGestureProps
>;

export type HoverGestureConfig =
ExcludeInternalConfigProps<HoverGestureInternalConfig>;

export function useHover(config: HoverGestureConfig) {
const hoverConfig = cloneConfig<HoverHandlerData, HoverGestureProps>(config);

return useGesture(SingleGestureName.Hover, hoverConfig);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
BaseGestureConfig,
ExcludeInternalConfigProps,
SingleGestureName,
} from '../../types';
import { useGesture } from '../useGesture';
import { remapProps } from '../utils';

type LongPressGestureProps = {
/**
* Minimum time, expressed in milliseconds, that a finger must remain pressed on
* the corresponding view. The default value is 500.
*/
minDuration?: number;

/**
* Maximum distance, expressed in points, that defines how far the finger is
* allowed to travel during a long press gesture. If the finger travels
* further than the defined distance and the handler hasn't yet activated, it
* will fail to recognize the gesture. The default value is 10.
*/
maxDistance?: number;

/**
* Determine exact number of points required to handle the long press gesture.
*/
numberOfPointers?: number;
};

type LongPressGestureInternalProps = {
minDurationMs?: number;
maxDist?: number;
numberOfPointers?: number;
};

type LongPressHandlerData = {
x: number;
y: number;
absoluteX: number;
absoluteY: number;
duration: number;
};

export type LongPressGestureConfig = ExcludeInternalConfigProps<
BaseGestureConfig<LongPressHandlerData, LongPressGestureProps>
>;

type LongPressGestureInternalConfig = BaseGestureConfig<
LongPressHandlerData,
LongPressGestureInternalProps
>;

const LongPressPropsMapping = new Map<
keyof LongPressGestureProps,
keyof LongPressGestureInternalProps
>([
['minDuration', 'minDurationMs'],
['maxDistance', 'maxDist'],
]);

export function useLongPress(config: LongPressGestureConfig) {
const longPressConfig = remapProps<
LongPressGestureConfig,
LongPressGestureInternalConfig
>(config, LongPressPropsMapping);

if (longPressConfig.shouldCancelWhenOutside === undefined) {
longPressConfig.shouldCancelWhenOutside = true;
}

return useGesture<LongPressHandlerData, LongPressGestureInternalProps>(
SingleGestureName.LongPress,
longPressConfig
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
BaseGestureConfig,
ExcludeInternalConfigProps,
SingleGestureName,
} from '../../types';
import { useGesture } from '../useGesture';
import { cloneConfig } from '../utils';

type ManualGestureProps = Record<string, never>;
type ManualHandlerData = Record<string, never>;

type ManualGestureInternalConfig = BaseGestureConfig<
ManualHandlerData,
ManualGestureProps
>;

export type ManualGestureConfig =
ExcludeInternalConfigProps<ManualGestureInternalConfig>;

export function useManual(config: ManualGestureConfig) {
const manualConfig = cloneConfig<ManualHandlerData, ManualGestureProps>(
config
);

return useGesture(SingleGestureName.Manual, manualConfig);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
BaseGestureConfig,
ExcludeInternalConfigProps,
SingleGestureName,
} from '../../types';
import { useGesture } from '../useGesture';
import { cloneConfig } from '../utils';

type NativeViewGestureProps = {
/**
* Android only.
*
* Determines whether the handler should check for an existing touch event on
* instantiation.
*/
shouldActivateOnStart?: boolean;

/**
* When `true`, cancels all other gesture handlers when this
* `NativeViewGestureHandler` receives an `ACTIVE` state event.
*/
disallowInterruption?: boolean;
};

type NativeViewHandlerData = {
pointerInside: boolean;
};

type NativeViewGestureInternalConfig = BaseGestureConfig<
NativeViewHandlerData,
NativeViewGestureProps
>;

export type NativeViewGestureConfig =
ExcludeInternalConfigProps<NativeViewGestureInternalConfig>;

export function useNative(config: NativeViewGestureConfig) {
const nativeConfig = cloneConfig<
NativeViewHandlerData,
NativeViewGestureProps
>(config);

return useGesture(SingleGestureName.Native, nativeConfig);
}
Loading
Loading