From 3cb11648d879141b9e48e113696a3102fbf4c684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Fri, 3 Oct 2025 12:47:26 +0200 Subject: [PATCH 01/19] add missing types --- .../src/v3/hooks/gestures/index.ts | 26 ++++++++++++------- .../src/v3/hooks/gestures/useFling.ts | 8 ++++++ .../src/v3/hooks/gestures/useHover.ts | 8 ++++++ .../src/v3/hooks/gestures/useLongPress.ts | 8 ++++++ .../src/v3/hooks/gestures/useManual.ts | 8 ++++++ .../src/v3/hooks/gestures/useNative.ts | 8 ++++++ .../src/v3/hooks/gestures/usePan.ts | 5 ++++ .../src/v3/hooks/gestures/usePinch.ts | 8 ++++++ .../src/v3/hooks/gestures/useRotation.ts | 8 ++++++ .../src/v3/hooks/gestures/useTap.ts | 5 ++++ 10 files changed, 83 insertions(+), 9 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts index 64e175e259..af74f1d811 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts @@ -1,26 +1,34 @@ export type { TapGestureConfig } from './useTap'; -export { useTap } from './useTap'; +export { useTap, TapGesture, TapGestureEvent } from './useTap'; export type { FlingGestureConfig } from './useFling'; -export { useFling } from './useFling'; +export { useFling, FlingGesture, FlingGestureEvent } from './useFling'; export type { LongPressGestureConfig } from './useLongPress'; -export { useLongPress } from './useLongPress'; +export { + useLongPress, + LongPressGesture, + LongPressGestureEvent, +} from './useLongPress'; export type { PinchGestureConfig } from './usePinch'; -export { usePinch } from './usePinch'; +export { usePinch, PinchGesture, PinchGestureEvent } from './usePinch'; export type { RotationGestureConfig } from './useRotation'; -export { useRotation } from './useRotation'; +export { + useRotation, + RotationGesture, + RotationGestureEvent, +} from './useRotation'; export type { HoverGestureConfig } from './useHover'; -export { useHover } from './useHover'; +export { useHover, HoverGesture, HoverGestureEvent } from './useHover'; export type { ManualGestureConfig } from './useManual'; -export { useManual } from './useManual'; +export { useManual, ManualGesture, ManualGestureEvent } from './useManual'; export type { NativeViewGestureConfig } from './useNative'; -export { useNative } from './useNative'; +export { useNative, NativeGesture, NativeGestureEvent } from './useNative'; export type { PanGestureConfig } from './usePan'; -export { usePan } from './usePan'; +export { usePan, PanGesture, PanGestureEvent } from './usePan'; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts index f1e6d2981b..4b931e1db2 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -51,3 +53,9 @@ export function useFling(config: FlingGestureConfig) { return useGesture(SingleGestureName.Fling, flingConfig); } + +export type FlingGestureEvent = GestureEvents; +export type FlingGesture = SingleGesture< + FlingHandlerData, + FlingGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts index cbcf16d4b3..85ea3bde5c 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts @@ -3,6 +3,8 @@ import { HoverEffect } from '../../../handlers/gestures/hoverGesture'; import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -44,3 +46,9 @@ export function useHover(config: HoverGestureConfig) { return useGesture(SingleGestureName.Hover, hoverConfig); } + +export type HoverGestureEvent = GestureEvents; +export type HoverGesture = SingleGesture< + HoverHandlerData, + HoverGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts index 723c9a598c..1489deee00 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -78,3 +80,9 @@ export function useLongPress(config: LongPressGestureConfig) { longPressConfig ); } + +export type LongPressGestureEvent = GestureEvents; +export type LongPressGesture = SingleGesture< + LongPressHandlerData, + LongPressGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts index 5d32f85e71..c1301af721 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -24,3 +26,9 @@ export function useManual(config: ManualGestureConfig) { return useGesture(SingleGestureName.Manual, manualConfig); } + +export type ManualGestureEvent = GestureEvents; +export type ManualGesture = SingleGesture< + ManualHandlerData, + ManualGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts index 0ed71b4d83..f2ac939e40 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -42,3 +44,9 @@ export function useNative(config: NativeViewGestureConfig) { return useGesture(SingleGestureName.Native, nativeConfig); } + +export type NativeGestureEvent = GestureEvents; +export type NativeGesture = SingleGesture< + NativeViewHandlerData, + NativeViewGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts index c79dc9cb12..2bcaf6766c 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts @@ -2,6 +2,8 @@ import { StylusData } from '../../../handlers/gestureHandlerCommon'; import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -257,3 +259,6 @@ export function usePan(config: PanGestureConfig) { panConfig ); } + +export type PanGestureEvent = GestureEvents; +export type PanGesture = SingleGesture; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts index ed61b0202c..4be2f1b785 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -30,3 +32,9 @@ export function usePinch(config: PinchGestureConfig) { return useGesture(SingleGestureName.Pinch, pinchConfig); } + +export type PinchGestureEvent = GestureEvents; +export type PinchGesture = SingleGesture< + PinchHandlerData, + PinchGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts index 542def7146..b9eed71851 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -31,3 +33,9 @@ export function useRotation(config: RotationGestureConfig) { return useGesture(SingleGestureName.Rotation, rotationConfig); } + +export type RotationGestureEvent = GestureEvents; +export type RotationGesture = SingleGesture< + RotationHandlerData, + RotationGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts index d45f8ae99e..64a9c35b55 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts @@ -1,6 +1,8 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, + GestureEvents, + SingleGesture, SingleGestureName, } from '../../types'; import { useGesture } from '../useGesture'; @@ -107,3 +109,6 @@ export function useTap(config: TapGestureConfig) { tapConfig ); } + +export type TapGestureEvent = GestureEvents; +export type TapGesture = SingleGesture; From 052bfb7202d4b06b95ebdf185f83a79bdcb4e915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Fri, 3 Oct 2025 13:19:26 +0200 Subject: [PATCH 02/19] addded type suffix --- .../src/v3/hooks/gestures/index.ts | 18 +++++++++--------- .../src/v3/hooks/gestures/useFling.ts | 2 +- .../src/v3/hooks/gestures/useHover.ts | 2 +- .../src/v3/hooks/gestures/useLongPress.ts | 2 +- .../src/v3/hooks/gestures/useManual.ts | 2 +- .../src/v3/hooks/gestures/useNative.ts | 2 +- .../src/v3/hooks/gestures/usePan.ts | 5 ++++- .../src/v3/hooks/gestures/usePinch.ts | 2 +- .../src/v3/hooks/gestures/useRotation.ts | 2 +- .../src/v3/hooks/gestures/useTap.ts | 5 ++++- 10 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts index af74f1d811..92ac9e90c5 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts @@ -1,34 +1,34 @@ export type { TapGestureConfig } from './useTap'; -export { useTap, TapGesture, TapGestureEvent } from './useTap'; +export { useTap, TapGestureType, TapGestureEvent } from './useTap'; export type { FlingGestureConfig } from './useFling'; -export { useFling, FlingGesture, FlingGestureEvent } from './useFling'; +export { useFling, FlingGestureType, FlingGestureEvent } from './useFling'; export type { LongPressGestureConfig } from './useLongPress'; export { useLongPress, - LongPressGesture, + LongPressGestureType, LongPressGestureEvent, } from './useLongPress'; export type { PinchGestureConfig } from './usePinch'; -export { usePinch, PinchGesture, PinchGestureEvent } from './usePinch'; +export { usePinch, PinchGestureType, PinchGestureEvent } from './usePinch'; export type { RotationGestureConfig } from './useRotation'; export { useRotation, - RotationGesture, + RotationGestureType, RotationGestureEvent, } from './useRotation'; export type { HoverGestureConfig } from './useHover'; -export { useHover, HoverGesture, HoverGestureEvent } from './useHover'; +export { useHover, HoverGestureType, HoverGestureEvent } from './useHover'; export type { ManualGestureConfig } from './useManual'; -export { useManual, ManualGesture, ManualGestureEvent } from './useManual'; +export { useManual, ManualGestureType, ManualGestureEvent } from './useManual'; export type { NativeViewGestureConfig } from './useNative'; -export { useNative, NativeGesture, NativeGestureEvent } from './useNative'; +export { useNative, NativeGestureType, NativeGestureEvent } from './useNative'; export type { PanGestureConfig } from './usePan'; -export { usePan, PanGesture, PanGestureEvent } from './usePan'; +export { usePan, PanGestureType, PanGestureEvent } from './usePan'; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts index 4b931e1db2..2245dd2866 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts @@ -55,7 +55,7 @@ export function useFling(config: FlingGestureConfig) { } export type FlingGestureEvent = GestureEvents; -export type FlingGesture = SingleGesture< +export type FlingGestureType = SingleGesture< FlingHandlerData, FlingGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts index 85ea3bde5c..f25332ad60 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts @@ -48,7 +48,7 @@ export function useHover(config: HoverGestureConfig) { } export type HoverGestureEvent = GestureEvents; -export type HoverGesture = SingleGesture< +export type HoverGestureType = SingleGesture< HoverHandlerData, HoverGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts index 1489deee00..8688904208 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts @@ -82,7 +82,7 @@ export function useLongPress(config: LongPressGestureConfig) { } export type LongPressGestureEvent = GestureEvents; -export type LongPressGesture = SingleGesture< +export type LongPressGestureType = SingleGesture< LongPressHandlerData, LongPressGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts index c1301af721..c97a2c6eb6 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts @@ -28,7 +28,7 @@ export function useManual(config: ManualGestureConfig) { } export type ManualGestureEvent = GestureEvents; -export type ManualGesture = SingleGesture< +export type ManualGestureType = SingleGesture< ManualHandlerData, ManualGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts index f2ac939e40..d25bdc1ece 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts @@ -46,7 +46,7 @@ export function useNative(config: NativeViewGestureConfig) { } export type NativeGestureEvent = GestureEvents; -export type NativeGesture = SingleGesture< +export type NativeGestureType = SingleGesture< NativeViewHandlerData, NativeViewGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts index 2bcaf6766c..549b975029 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts @@ -261,4 +261,7 @@ export function usePan(config: PanGestureConfig) { } export type PanGestureEvent = GestureEvents; -export type PanGesture = SingleGesture; +export type PanGestureType = SingleGesture< + PanHandlerData, + PanGestureProperties +>; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts index 4be2f1b785..655a109e63 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts @@ -34,7 +34,7 @@ export function usePinch(config: PinchGestureConfig) { } export type PinchGestureEvent = GestureEvents; -export type PinchGesture = SingleGesture< +export type PinchGestureType = SingleGesture< PinchHandlerData, PinchGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts index b9eed71851..5dcadb76d2 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts @@ -35,7 +35,7 @@ export function useRotation(config: RotationGestureConfig) { } export type RotationGestureEvent = GestureEvents; -export type RotationGesture = SingleGesture< +export type RotationGestureType = SingleGesture< RotationHandlerData, RotationGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts index 64a9c35b55..da28eae978 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts @@ -111,4 +111,7 @@ export function useTap(config: TapGestureConfig) { } export type TapGestureEvent = GestureEvents; -export type TapGesture = SingleGesture; +export type TapGestureType = SingleGesture< + TapHandlerData, + TapGestureProperties +>; From 652fe3fd98bb3dd6317dfe377b4f0bc9ce64fd52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Fri, 3 Oct 2025 13:46:37 +0200 Subject: [PATCH 03/19] exporting single and composed gesture types --- packages/react-native-gesture-handler/src/index.ts | 6 +++++- packages/react-native-gesture-handler/src/v3/types.ts | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react-native-gesture-handler/src/index.ts b/packages/react-native-gesture-handler/src/index.ts index 82392a25a7..feea452884 100644 --- a/packages/react-native-gesture-handler/src/index.ts +++ b/packages/react-native-gesture-handler/src/index.ts @@ -168,7 +168,11 @@ export { NativeDetector } from './v3/NativeDetector/NativeDetector'; export * from './v3/hooks/useGesture'; export * from './v3/hooks/relations'; -export { SingleGestureName } from './v3/types'; +export { + SingleGestureName, + SingleGestureType, + ComposedGesture as ComposedGestureType, +} from './v3/types'; export * from './v3/hooks/gestures'; diff --git a/packages/react-native-gesture-handler/src/v3/types.ts b/packages/react-native-gesture-handler/src/v3/types.ts index 110edade40..4bae732231 100644 --- a/packages/react-native-gesture-handler/src/v3/types.ts +++ b/packages/react-native-gesture-handler/src/v3/types.ts @@ -106,6 +106,8 @@ export type SingleGesture = { gestureRelations: GestureRelations; }; +export type SingleGestureType = SingleGesture; + export type ComposedGesture = { tags: number[]; type: ComposedGestureName; From 43bd77d4d1c02683ee846a8b90f84dfff591a599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Fri, 3 Oct 2025 17:09:51 +0200 Subject: [PATCH 04/19] SingleGestureType as a union --- .../react-native-gesture-handler/src/index.ts | 1 - .../src/v3/hooks/gestures/index.ts | 66 ++++++++++++++----- .../src/v3/types.ts | 2 - 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/packages/react-native-gesture-handler/src/index.ts b/packages/react-native-gesture-handler/src/index.ts index feea452884..b20eb1839a 100644 --- a/packages/react-native-gesture-handler/src/index.ts +++ b/packages/react-native-gesture-handler/src/index.ts @@ -170,7 +170,6 @@ export * from './v3/hooks/relations'; export { SingleGestureName, - SingleGestureType, ComposedGesture as ComposedGestureType, } from './v3/types'; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts index 92ac9e90c5..7a9dcc7199 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts @@ -1,34 +1,66 @@ +import { FlingGestureEvent, FlingGestureType } from './useFling'; +import { HoverGestureEvent, HoverGestureType } from './useHover'; +import { LongPressGestureEvent, LongPressGestureType } from './useLongPress'; +import { ManualGestureEvent, ManualGestureType } from './useManual'; +import { NativeGestureEvent, NativeGestureType } from './useNative'; +import { PanGestureEvent, PanGestureType } from './usePan'; +import { PinchGestureEvent, PinchGestureType } from './usePinch'; +import { RotationGestureEvent, RotationGestureType } from './useRotation'; +import { TapGestureEvent, TapGestureType } from './useTap'; + export type { TapGestureConfig } from './useTap'; -export { useTap, TapGestureType, TapGestureEvent } from './useTap'; +export type { TapGestureType, TapGestureEvent }; +export { useTap } from './useTap'; export type { FlingGestureConfig } from './useFling'; -export { useFling, FlingGestureType, FlingGestureEvent } from './useFling'; +export type { FlingGestureType, FlingGestureEvent }; +export { useFling } from './useFling'; export type { LongPressGestureConfig } from './useLongPress'; -export { - useLongPress, - LongPressGestureType, - LongPressGestureEvent, -} from './useLongPress'; +export type { LongPressGestureType, LongPressGestureEvent }; +export { useLongPress } from './useLongPress'; export type { PinchGestureConfig } from './usePinch'; -export { usePinch, PinchGestureType, PinchGestureEvent } from './usePinch'; +export type { PinchGestureType, PinchGestureEvent }; +export { usePinch } from './usePinch'; export type { RotationGestureConfig } from './useRotation'; -export { - useRotation, - RotationGestureType, - RotationGestureEvent, -} from './useRotation'; +export type { RotationGestureType, RotationGestureEvent }; +export { useRotation } from './useRotation'; export type { HoverGestureConfig } from './useHover'; -export { useHover, HoverGestureType, HoverGestureEvent } from './useHover'; +export type { HoverGestureType, HoverGestureEvent }; +export { useHover } from './useHover'; export type { ManualGestureConfig } from './useManual'; -export { useManual, ManualGestureType, ManualGestureEvent } from './useManual'; +export type { ManualGestureType, ManualGestureEvent }; +export { useManual } from './useManual'; export type { NativeViewGestureConfig } from './useNative'; -export { useNative, NativeGestureType, NativeGestureEvent } from './useNative'; +export type { NativeGestureType, NativeGestureEvent }; +export { useNative } from './useNative'; export type { PanGestureConfig } from './usePan'; -export { usePan, PanGestureType, PanGestureEvent } from './usePan'; +export type { PanGestureType, PanGestureEvent }; +export { usePan } from './usePan'; + +export type SingleGestureType = + | TapGestureType + | FlingGestureType + | LongPressGestureType + | PinchGestureType + | RotationGestureType + | HoverGestureType + | ManualGestureType + | NativeGestureType + | PanGestureType; +export type SingleGestureEvent = + | TapGestureEvent + | FlingGestureEvent + | LongPressGestureEvent + | PinchGestureEvent + | RotationGestureEvent + | HoverGestureEvent + | ManualGestureEvent + | NativeGestureEvent + | PanGestureEvent; diff --git a/packages/react-native-gesture-handler/src/v3/types.ts b/packages/react-native-gesture-handler/src/v3/types.ts index 4bae732231..110edade40 100644 --- a/packages/react-native-gesture-handler/src/v3/types.ts +++ b/packages/react-native-gesture-handler/src/v3/types.ts @@ -106,8 +106,6 @@ export type SingleGesture = { gestureRelations: GestureRelations; }; -export type SingleGestureType = SingleGesture; - export type ComposedGesture = { tags: number[]; type: ComposedGestureName; From 2b291b6dee71fcec0aa05a9c5c01f89187b08df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Fri, 3 Oct 2025 21:25:54 +0200 Subject: [PATCH 05/19] new api gets better names --- .../react-native-gesture-handler/src/index.ts | 31 +++++----- .../src/v3/hooks/gestures/index.ts | 57 ++++++++++--------- .../src/v3/hooks/gestures/useFling.ts | 2 +- .../src/v3/hooks/gestures/useHover.ts | 2 +- .../src/v3/hooks/gestures/useLongPress.ts | 2 +- .../src/v3/hooks/gestures/useManual.ts | 2 +- .../src/v3/hooks/gestures/useNative.ts | 2 +- .../src/v3/hooks/gestures/usePan.ts | 5 +- .../src/v3/hooks/gestures/usePinch.ts | 2 +- .../src/v3/hooks/gestures/useRotation.ts | 2 +- .../src/v3/hooks/gestures/useTap.ts | 5 +- 11 files changed, 52 insertions(+), 60 deletions(-) diff --git a/packages/react-native-gesture-handler/src/index.ts b/packages/react-native-gesture-handler/src/index.ts index b20eb1839a..ce93333e97 100644 --- a/packages/react-native-gesture-handler/src/index.ts +++ b/packages/react-native-gesture-handler/src/index.ts @@ -54,20 +54,20 @@ export { default as createNativeWrapper } from './handlers/createNativeWrapper'; export type { NativeViewGestureHandlerProps } from './handlers/NativeViewGestureHandler'; export { GestureDetector } from './handlers/gestures/GestureDetector'; export { GestureObjects as Gesture } from './handlers/gestures/gestureObjects'; -export type { TapGestureType as TapGesture } from './handlers/gestures/tapGesture'; -export type { PanGestureType as PanGesture } from './handlers/gestures/panGesture'; -export type { FlingGestureType as FlingGesture } from './handlers/gestures/flingGesture'; -export type { LongPressGestureType as LongPressGesture } from './handlers/gestures/longPressGesture'; -export type { PinchGestureType as PinchGesture } from './handlers/gestures/pinchGesture'; -export type { RotationGestureType as RotationGesture } from './handlers/gestures/rotationGesture'; -export type { ForceTouchGestureType as ForceTouchGesture } from './handlers/gestures/forceTouchGesture'; -export type { ManualGestureType as ManualGesture } from './handlers/gestures/manualGesture'; -export type { HoverGestureType as HoverGesture } from './handlers/gestures/hoverGesture'; +export type { TapGestureType } from './handlers/gestures/tapGesture'; +export type { PanGestureType } from './handlers/gestures/panGesture'; +export type { FlingGestureType } from './handlers/gestures/flingGesture'; +export type { LongPressGestureType } from './handlers/gestures/longPressGesture'; +export type { PinchGestureType } from './handlers/gestures/pinchGesture'; +export type { RotationGestureType } from './handlers/gestures/rotationGesture'; +export type { ForceTouchGestureType } from './handlers/gestures/forceTouchGesture'; +export type { ManualGestureType } from './handlers/gestures/manualGesture'; +export type { HoverGestureType } from './handlers/gestures/hoverGesture'; export type { - ComposedGestureType as ComposedGesture, - RaceGestureType as RaceGesture, - SimultaneousGestureType as SimultaneousGesture, - ExclusiveGestureType as ExclusiveGesture, + ComposedGestureType, + RaceGestureType, + SimultaneousGestureType, + ExclusiveGestureType, } from './handlers/gestures/gestureComposition'; export type { GestureStateManagerType as GestureStateManager } from './handlers/gestures/gestureStateManager'; export { NativeViewGestureHandler } from './handlers/NativeViewGestureHandler'; @@ -168,10 +168,7 @@ export { NativeDetector } from './v3/NativeDetector/NativeDetector'; export * from './v3/hooks/useGesture'; export * from './v3/hooks/relations'; -export { - SingleGestureName, - ComposedGesture as ComposedGestureType, -} from './v3/types'; +export { SingleGestureName, ComposedGesture } from './v3/types'; export * from './v3/hooks/gestures'; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts index 7a9dcc7199..411eebccef 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts @@ -1,59 +1,60 @@ -import { FlingGestureEvent, FlingGestureType } from './useFling'; -import { HoverGestureEvent, HoverGestureType } from './useHover'; -import { LongPressGestureEvent, LongPressGestureType } from './useLongPress'; -import { ManualGestureEvent, ManualGestureType } from './useManual'; -import { NativeGestureEvent, NativeGestureType } from './useNative'; -import { PanGestureEvent, PanGestureType } from './usePan'; -import { PinchGestureEvent, PinchGestureType } from './usePinch'; -import { RotationGestureEvent, RotationGestureType } from './useRotation'; -import { TapGestureEvent, TapGestureType } from './useTap'; +import { FlingGestureEvent, FlingGesture } from './useFling'; +import { HoverGestureEvent, HoverGesture } from './useHover'; +import { LongPressGestureEvent, LongPressGesture } from './useLongPress'; +import { ManualGestureEvent, ManualGesture } from './useManual'; +import { NativeGestureEvent, NativeGesture } from './useNative'; +import { PanGestureEvent, PanGesture } from './usePan'; +import { PinchGestureEvent, PinchGesture } from './usePinch'; +import { RotationGestureEvent, RotationGesture } from './useRotation'; +import { TapGestureEvent, TapGesture } from './useTap'; export type { TapGestureConfig } from './useTap'; -export type { TapGestureType, TapGestureEvent }; +export type { TapGesture, TapGestureEvent }; export { useTap } from './useTap'; export type { FlingGestureConfig } from './useFling'; -export type { FlingGestureType, FlingGestureEvent }; +export type { FlingGesture, FlingGestureEvent }; export { useFling } from './useFling'; export type { LongPressGestureConfig } from './useLongPress'; -export type { LongPressGestureType, LongPressGestureEvent }; +export type { LongPressGesture, LongPressGestureEvent }; export { useLongPress } from './useLongPress'; export type { PinchGestureConfig } from './usePinch'; -export type { PinchGestureType, PinchGestureEvent }; +export type { PinchGesture, PinchGestureEvent }; export { usePinch } from './usePinch'; export type { RotationGestureConfig } from './useRotation'; -export type { RotationGestureType, RotationGestureEvent }; +export type { RotationGesture, RotationGestureEvent }; export { useRotation } from './useRotation'; export type { HoverGestureConfig } from './useHover'; -export type { HoverGestureType, HoverGestureEvent }; +export type { HoverGesture, HoverGestureEvent }; export { useHover } from './useHover'; export type { ManualGestureConfig } from './useManual'; -export type { ManualGestureType, ManualGestureEvent }; +export type { ManualGesture, ManualGestureEvent }; export { useManual } from './useManual'; export type { NativeViewGestureConfig } from './useNative'; -export type { NativeGestureType, NativeGestureEvent }; +export type { NativeGesture, NativeGestureEvent }; export { useNative } from './useNative'; export type { PanGestureConfig } from './usePan'; -export type { PanGestureType, PanGestureEvent }; +export type { PanGesture, PanGestureEvent }; export { usePan } from './usePan'; -export type SingleGestureType = - | TapGestureType - | FlingGestureType - | LongPressGestureType - | PinchGestureType - | RotationGestureType - | HoverGestureType - | ManualGestureType - | NativeGestureType - | PanGestureType; +export type SingleGesture = + | TapGesture + | FlingGesture + | LongPressGesture + | PinchGesture + | RotationGesture + | HoverGesture + | ManualGesture + | NativeGesture + | PanGesture; + export type SingleGestureEvent = | TapGestureEvent | FlingGestureEvent diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts index 2245dd2866..4b931e1db2 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts @@ -55,7 +55,7 @@ export function useFling(config: FlingGestureConfig) { } export type FlingGestureEvent = GestureEvents; -export type FlingGestureType = SingleGesture< +export type FlingGesture = SingleGesture< FlingHandlerData, FlingGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts index f25332ad60..85ea3bde5c 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts @@ -48,7 +48,7 @@ export function useHover(config: HoverGestureConfig) { } export type HoverGestureEvent = GestureEvents; -export type HoverGestureType = SingleGesture< +export type HoverGesture = SingleGesture< HoverHandlerData, HoverGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts index 8688904208..1489deee00 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts @@ -82,7 +82,7 @@ export function useLongPress(config: LongPressGestureConfig) { } export type LongPressGestureEvent = GestureEvents; -export type LongPressGestureType = SingleGesture< +export type LongPressGesture = SingleGesture< LongPressHandlerData, LongPressGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts index c97a2c6eb6..c1301af721 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts @@ -28,7 +28,7 @@ export function useManual(config: ManualGestureConfig) { } export type ManualGestureEvent = GestureEvents; -export type ManualGestureType = SingleGesture< +export type ManualGesture = SingleGesture< ManualHandlerData, ManualGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts index d25bdc1ece..f2ac939e40 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts @@ -46,7 +46,7 @@ export function useNative(config: NativeViewGestureConfig) { } export type NativeGestureEvent = GestureEvents; -export type NativeGestureType = SingleGesture< +export type NativeGesture = SingleGesture< NativeViewHandlerData, NativeViewGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts index 549b975029..2bcaf6766c 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts @@ -261,7 +261,4 @@ export function usePan(config: PanGestureConfig) { } export type PanGestureEvent = GestureEvents; -export type PanGestureType = SingleGesture< - PanHandlerData, - PanGestureProperties ->; +export type PanGesture = SingleGesture; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts index 655a109e63..4be2f1b785 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts @@ -34,7 +34,7 @@ export function usePinch(config: PinchGestureConfig) { } export type PinchGestureEvent = GestureEvents; -export type PinchGestureType = SingleGesture< +export type PinchGesture = SingleGesture< PinchHandlerData, PinchGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts index 5dcadb76d2..b9eed71851 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts @@ -35,7 +35,7 @@ export function useRotation(config: RotationGestureConfig) { } export type RotationGestureEvent = GestureEvents; -export type RotationGestureType = SingleGesture< +export type RotationGesture = SingleGesture< RotationHandlerData, RotationGestureProperties >; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts index da28eae978..64a9c35b55 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts @@ -111,7 +111,4 @@ export function useTap(config: TapGestureConfig) { } export type TapGestureEvent = GestureEvents; -export type TapGestureType = SingleGesture< - TapHandlerData, - TapGestureProperties ->; +export type TapGesture = SingleGesture; From 704d604722fe511cadf2d5d958629069600a2ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Mon, 6 Oct 2025 10:47:57 +0200 Subject: [PATCH 06/19] import, export type --- .../react-native-gesture-handler/src/index.ts | 3 ++- .../src/v3/hooks/gestures/index.ts | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/react-native-gesture-handler/src/index.ts b/packages/react-native-gesture-handler/src/index.ts index ce93333e97..10577397e3 100644 --- a/packages/react-native-gesture-handler/src/index.ts +++ b/packages/react-native-gesture-handler/src/index.ts @@ -168,7 +168,8 @@ export { NativeDetector } from './v3/NativeDetector/NativeDetector'; export * from './v3/hooks/useGesture'; export * from './v3/hooks/relations'; -export { SingleGestureName, ComposedGesture } from './v3/types'; +export { SingleGestureName } from './v3/types'; +export type { ComposedGesture } from './v3/types'; export * from './v3/hooks/gestures'; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts index 411eebccef..c81eb55e7a 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/index.ts @@ -1,12 +1,12 @@ -import { FlingGestureEvent, FlingGesture } from './useFling'; -import { HoverGestureEvent, HoverGesture } from './useHover'; -import { LongPressGestureEvent, LongPressGesture } from './useLongPress'; -import { ManualGestureEvent, ManualGesture } from './useManual'; -import { NativeGestureEvent, NativeGesture } from './useNative'; -import { PanGestureEvent, PanGesture } from './usePan'; -import { PinchGestureEvent, PinchGesture } from './usePinch'; -import { RotationGestureEvent, RotationGesture } from './useRotation'; -import { TapGestureEvent, TapGesture } from './useTap'; +import type { FlingGestureEvent, FlingGesture } from './useFling'; +import type { HoverGestureEvent, HoverGesture } from './useHover'; +import type { LongPressGestureEvent, LongPressGesture } from './useLongPress'; +import type { ManualGestureEvent, ManualGesture } from './useManual'; +import type { NativeGestureEvent, NativeGesture } from './useNative'; +import type { PanGestureEvent, PanGesture } from './usePan'; +import type { PinchGestureEvent, PinchGesture } from './usePinch'; +import type { RotationGestureEvent, RotationGesture } from './useRotation'; +import type { TapGestureEvent, TapGesture } from './useTap'; export type { TapGestureConfig } from './useTap'; export type { TapGesture, TapGestureEvent }; From 4b3451d439d56140b3b3a4e0d497de4fe88a15c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Mon, 6 Oct 2025 10:50:26 +0200 Subject: [PATCH 07/19] update types in tests and examples --- .../src/new_api/drag_n_drop/Draggable.tsx | 8 +++--- .../src/__tests__/Events.test.tsx | 28 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/common-app/src/new_api/drag_n_drop/Draggable.tsx b/apps/common-app/src/new_api/drag_n_drop/Draggable.tsx index 81f92a4471..6159f143ad 100644 --- a/apps/common-app/src/new_api/drag_n_drop/Draggable.tsx +++ b/apps/common-app/src/new_api/drag_n_drop/Draggable.tsx @@ -4,8 +4,8 @@ import { PanGestureHandlerEventPayload, Gesture, GestureDetector, - PanGesture, - TapGesture, + PanGestureType, + TapGestureType, } from 'react-native-gesture-handler'; import Animated, { runOnJS, useAnimatedStyle } from 'react-native-reanimated'; @@ -22,8 +22,8 @@ interface DraggableProps { isActive: boolean; translation: AnimatedPostion; position: { x: number; y: number }; - dragGesture: PanGesture; - tapEndGesture: TapGesture; + dragGesture: PanGestureType; + tapEndGesture: TapGestureType; tileSize: number; rowGap: number; columnGap: number; diff --git a/packages/react-native-gesture-handler/src/__tests__/Events.test.tsx b/packages/react-native-gesture-handler/src/__tests__/Events.test.tsx index 89568044f8..043ef574c3 100644 --- a/packages/react-native-gesture-handler/src/__tests__/Events.test.tsx +++ b/packages/react-native-gesture-handler/src/__tests__/Events.test.tsx @@ -13,8 +13,8 @@ import { Gesture, GestureDetector, State, - PanGesture, - TapGesture, + PanGestureType, + TapGestureType, } from '../index'; import { useAnimatedGestureHandler } from 'react-native-reanimated'; import { fireGestureHandler, getByGestureTestId } from '../jestUtils'; @@ -300,7 +300,7 @@ describe('Using RNGH v2 gesture API', () => { ); - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { state: State.BEGAN }, { state: State.ACTIVE }, { state: State.END }, @@ -315,7 +315,7 @@ describe('Using RNGH v2 gesture API', () => { test('sends events with additional data to handlers', () => { const panHandlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { state: State.BEGAN, translationX: 0 }, { state: State.ACTIVE, translationX: 10 }, { translationX: 20 }, @@ -358,7 +358,7 @@ describe('Event list validation', () => { const panHandlers = mockedEventHandlers(); render(); expect(() => { - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { oldState: State.UNDETERMINED, state: State.BEGAN, x: 0, y: 10 }, { oldState: State.UNDETERMINED, state: State.ACTIVE, x: 1, y: 11 }, ]); @@ -372,7 +372,7 @@ describe('Event list validation', () => { (lastState) => { const panHandlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { state: State.BEGAN }, { state: State.ACTIVE }, { state: lastState }, @@ -452,7 +452,7 @@ describe('Filling event list with defaults', () => { test('fills missing ACTIVE states', () => { const panHandlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { state: State.BEGAN, x: 0, y: 10 }, { state: State.ACTIVE, x: 1, y: 11 }, { x: 2, y: 12 }, @@ -469,7 +469,7 @@ describe('Filling event list with defaults', () => { test('fills BEGIN and END events for discrete handlers', () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('tap'), [{ x: 5 }]); + fireGestureHandler(getByGestureTestId('tap'), [{ x: 5 }]); expect(handlers.begin).toHaveBeenCalledTimes(1); expect(handlers.end).toHaveBeenCalledTimes(1); }); @@ -477,7 +477,7 @@ describe('Filling event list with defaults', () => { test('with FAILED event, fills BEGIN event for discrete handlers', () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('tap'), [ + fireGestureHandler(getByGestureTestId('tap'), [ { state: State.FAILED }, ]); expect(handlers.begin).toHaveBeenCalledTimes(1); @@ -488,7 +488,7 @@ describe('Filling event list with defaults', () => { test('uses event data from first event in filled BEGIN, ACTIVE events', () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan'), [{ x: 120 }]); + fireGestureHandler(getByGestureTestId('pan'), [{ x: 120 }]); expect(handlers.begin).toHaveBeenCalledWith( expect.objectContaining({ x: 120 }) ); @@ -501,7 +501,7 @@ describe('Filling event list with defaults', () => { test('uses event data from last event in filled END events', () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { x: 120, state: State.FAILED }, ]); expect(handlers.begin).toHaveBeenCalledTimes(1); @@ -515,7 +515,7 @@ describe('Filling event list with defaults', () => { test('uses event data filled events', () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan'), [ + fireGestureHandler(getByGestureTestId('pan'), [ { x: 5, y: 15 }, { x: 6, y: 16 }, { x: 7, y: 17 }, @@ -533,7 +533,7 @@ describe('Filling event list with defaults', () => { test("fills BEGIN and END events when they're not present, for discrete handlers", () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('tap')); + fireGestureHandler(getByGestureTestId('tap')); expect(handlers.begin).toHaveBeenCalledTimes(1); expect(handlers.end).toHaveBeenCalledTimes(1); }); @@ -541,7 +541,7 @@ describe('Filling event list with defaults', () => { test("fills BEGIN, ACTIVE and END events when they're not present, for continuous handlers", () => { const handlers = mockedEventHandlers(); render(); - fireGestureHandler(getByGestureTestId('pan')); + fireGestureHandler(getByGestureTestId('pan')); expect(handlers.begin).toHaveBeenCalledTimes(1); expect(handlers.active).toHaveBeenCalledTimes(1); expect(handlers.end).toHaveBeenCalledTimes(1); From 679ab462ad6c046748245dc6248866fde7b3787a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Mon, 6 Oct 2025 11:57:37 +0200 Subject: [PATCH 08/19] export correct types --- .../src/v3/hooks/gestures/useFling.ts | 4 ++-- .../src/v3/hooks/gestures/useHover.ts | 4 ++-- .../src/v3/hooks/gestures/useLongPress.ts | 4 ++-- .../src/v3/hooks/gestures/useManual.ts | 4 ++-- .../src/v3/hooks/gestures/useNative.ts | 4 ++-- .../src/v3/hooks/gestures/usePan.ts | 4 ++-- .../src/v3/hooks/gestures/usePinch.ts | 4 ++-- .../src/v3/hooks/gestures/useRotation.ts | 4 ++-- .../src/v3/hooks/gestures/useTap.ts | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts index d2190a9c01..6f5fafc55b 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useFling.ts @@ -1,10 +1,10 @@ import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, SingleGestureName, WithSharedValue, + GestureHandlerEvent, } from '../../types'; import { useGesture } from '../useGesture'; import { cloneConfig } from '../utils'; @@ -55,7 +55,7 @@ export function useFling(config: FlingGestureConfig) { return useGesture(SingleGestureName.Fling, flingConfig); } -export type FlingGestureEvent = GestureEvents; +export type FlingGestureEvent = GestureHandlerEvent; export type FlingGesture = SingleGesture< FlingHandlerData, FlingGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts index 56d9dc0a7f..64fa3d1f0b 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useHover.ts @@ -1,9 +1,9 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { StylusData } from '../../../handlers/gestureHandlerCommon'; import { HoverEffect } from '../../../handlers/gestures/hoverGesture'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, HandlerData, SingleGestureName, @@ -67,7 +67,7 @@ export function useHover(config: HoverGestureConfig) { return useGesture(SingleGestureName.Hover, hoverConfig); } -export type HoverGestureEvent = GestureEvents; +export type HoverGestureEvent = GestureHandlerEvent; export type HoverGesture = SingleGesture< HoverHandlerData, HoverGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts index 7ad69698ff..f7a2851a8b 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useLongPress.ts @@ -1,7 +1,7 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, SingleGestureName, WithSharedValue, @@ -82,7 +82,7 @@ export function useLongPress(config: LongPressGestureConfig) { ); } -export type LongPressGestureEvent = GestureEvents; +export type LongPressGestureEvent = GestureHandlerEvent; export type LongPressGesture = SingleGesture< LongPressHandlerData, LongPressGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts index c1301af721..b4f18e2b46 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useManual.ts @@ -1,7 +1,7 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, SingleGestureName, } from '../../types'; @@ -27,7 +27,7 @@ export function useManual(config: ManualGestureConfig) { return useGesture(SingleGestureName.Manual, manualConfig); } -export type ManualGestureEvent = GestureEvents; +export type ManualGestureEvent = GestureHandlerEvent; export type ManualGesture = SingleGesture< ManualHandlerData, ManualGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts index 6588c6979c..dcec89e561 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useNative.ts @@ -1,7 +1,7 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, SingleGestureName, WithSharedValue, @@ -46,7 +46,7 @@ export function useNative(config: NativeViewGestureConfig) { return useGesture(SingleGestureName.Native, nativeConfig); } -export type NativeGestureEvent = GestureEvents; +export type NativeGestureEvent = GestureHandlerEvent; export type NativeGesture = SingleGesture< NativeViewHandlerData, NativeViewGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts index b9b864fc3a..6d8dd697d5 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePan.ts @@ -1,8 +1,8 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { StylusData } from '../../../handlers/gestureHandlerCommon'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, HandlerData, SingleGestureName, @@ -265,5 +265,5 @@ export function usePan(config: PanGestureConfig) { ); } -export type PanGestureEvent = GestureEvents; +export type PanGestureEvent = GestureHandlerEvent; export type PanGesture = SingleGesture; diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts index d27cfad191..57d24c74c8 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/usePinch.ts @@ -1,7 +1,7 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, HandlerData, SingleGestureName, @@ -47,7 +47,7 @@ export function usePinch(config: PinchGestureConfig) { return useGesture(SingleGestureName.Pinch, pinchConfig); } -export type PinchGestureEvent = GestureEvents; +export type PinchGestureEvent = GestureHandlerEvent; export type PinchGesture = SingleGesture< PinchHandlerData, PinchGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts index 9608fbbc21..8f2bc08a1b 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useRotation.ts @@ -1,7 +1,7 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, HandlerData, SingleGestureName, @@ -51,7 +51,7 @@ export function useRotation(config: RotationGestureConfig) { return useGesture(SingleGestureName.Rotation, rotationConfig); } -export type RotationGestureEvent = GestureEvents; +export type RotationGestureEvent = GestureHandlerEvent; export type RotationGesture = SingleGesture< RotationHandlerData, RotationGestureProperties diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts index acb9a33a1f..d3e34ff20b 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/useTap.ts @@ -1,7 +1,7 @@ +import { GestureHandlerEvent } from 'react-native-reanimated/lib/typescript/hook'; import { BaseGestureConfig, ExcludeInternalConfigProps, - GestureEvents, SingleGesture, SingleGestureName, WithSharedValue, @@ -111,5 +111,5 @@ export function useTap(config: TapGestureConfig) { ); } -export type TapGestureEvent = GestureEvents; +export type TapGestureEvent = GestureHandlerEvent; export type TapGesture = SingleGesture; From a5c00bc79baab790b0a34186493bfa8dd9181134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Mon, 29 Sep 2025 11:58:18 +0200 Subject: [PATCH 09/19] first examples --- apps/common-app/App.tsx | 11 ++ apps/common-app/src/v3_api/fling/fling.tsx | 60 ++++++++ apps/common-app/src/v3_api/lock/lock.tsx | 163 +++++++++++++++++++++ apps/common-app/src/v3_api/svg/svg.tsx | 68 +++++++++ 4 files changed, 302 insertions(+) create mode 100644 apps/common-app/src/v3_api/fling/fling.tsx create mode 100644 apps/common-app/src/v3_api/lock/lock.tsx create mode 100644 apps/common-app/src/v3_api/svg/svg.tsx diff --git a/apps/common-app/App.tsx b/apps/common-app/App.tsx index b2a49d60f9..d027ad2909 100644 --- a/apps/common-app/App.tsx +++ b/apps/common-app/App.tsx @@ -82,6 +82,9 @@ import ManualExample from './src/simple/manual'; import SimpleFling from './src/simple/fling'; import { Icon } from '@swmansion/icons'; +import Lock from './src/v3_api/lock/lock'; +import V3Fling from './src/v3_api/fling/fling'; +import LogicDetectorExample from './src/v3_api/svg/svg'; interface Example { name: string; @@ -98,6 +101,14 @@ const EXAMPLES: ExamplesSection[] = [ sectionTitle: 'Empty', data: [{ name: 'Empty Example', component: EmptyExample }], }, + { + sectionTitle: 'V3 api', + data: [ + { name: 'V3 Fling', component: V3Fling }, + { name: 'Svg', component: LogicDetectorExample }, + { name: 'Lock', component: Lock }, + ], + }, { sectionTitle: 'New api', data: [ diff --git a/apps/common-app/src/v3_api/fling/fling.tsx b/apps/common-app/src/v3_api/fling/fling.tsx new file mode 100644 index 0000000000..ba6c0c3e14 --- /dev/null +++ b/apps/common-app/src/v3_api/fling/fling.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { StyleSheet, View } from 'react-native'; +import { + Directions, + NativeDetector, + useFling, +} from 'react-native-gesture-handler'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, + Easing, +} from 'react-native-reanimated'; + +export default function V3Fling() { + const position = useSharedValue(0); + const beginPosition = useSharedValue(0); + + const flingGesture = useFling({ + direction: Directions.LEFT | Directions.RIGHT, + onBegin: (e) => { + 'worklet'; + beginPosition.value = e.handlerData.x; + }, + onStart: (e) => { + 'worklet'; + const direction = Math.sign(e.handlerData.x - beginPosition.value); + position.value = withTiming(position.value + direction * 50, { + duration: 300, + easing: Easing.bounce, + }); + }, + }); + + const animatedStyle = useAnimatedStyle(() => ({ + transform: [{ translateX: position.value }], + })); + + return ( + + + + + + ); +} + +const styles = StyleSheet.create({ + centerView: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + box: { + height: 120, + width: 120, + backgroundColor: '#b58df1', + marginBottom: 30, + }, +}); diff --git a/apps/common-app/src/v3_api/lock/lock.tsx b/apps/common-app/src/v3_api/lock/lock.tsx new file mode 100644 index 0000000000..9129beb2df --- /dev/null +++ b/apps/common-app/src/v3_api/lock/lock.tsx @@ -0,0 +1,163 @@ +import React, { useState } from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, + runOnJS, +} from 'react-native-reanimated'; +import { + NativeDetector, + useExclusive, + useLongPress, + usePinch, + useRotation, + useSimultaneous, + useTap, +} from 'react-native-gesture-handler'; + +export default function Lock() { + const rotation = useSharedValue(-Math.PI / 2); + const savedRotation = useSharedValue(-Math.PI / 2); + + const scale = useSharedValue(0.6); + const savedScale = useSharedValue(1); + + const [locked, setLocked] = useState(true); + const snapThreshold = 0.4; + const scaleThreshold = 0.1; + const minScale = 0.5; + const maxScale = 1; + const TWO_PI = 2 * Math.PI; + + // Tap to lock + const tap = useTap({ + onEnd: () => { + 'worklet'; + if (savedRotation.value === 0 && scale.value === maxScale) { + runOnJS(setLocked)(false); + } + }, + }); + + // Long press to cancel tap + const longPress = useLongPress({}); + + const confirm = useExclusive(longPress, tap); + + const rotationGesture = useRotation({ + onUpdate: (e) => { + 'worklet'; + rotation.value = savedRotation.value + e.handlerData.rotation; + + if (!locked) { + runOnJS(setLocked)(true); + } + }, + onEnd: () => { + 'worklet'; + + const nearestMultiple = Math.round(rotation.value / TWO_PI) * TWO_PI; + + if (Math.abs(rotation.value - nearestMultiple) < snapThreshold) { + rotation.value = withTiming(nearestMultiple, { duration: 300 }); + savedRotation.value = 0; + } else { + rotation.value = withTiming(-Math.PI / 2, { duration: 300 }); + savedRotation.value = -Math.PI / 2; + } + }, + simultaneousWithExternalGesture: confirm, + }); + + const pinchGesture = usePinch({ + onUpdate: (e) => { + 'worklet'; + const value = savedScale.value * e.handlerData.scale; + if (value < minScale || value > maxScale) { + return; + } + scale.value = value; + + if (!locked) { + runOnJS(setLocked)(true); + } + }, + onEnd: () => { + 'worklet'; + + if (Math.abs(scale.value - maxScale) < scaleThreshold) { + scale.value = withTiming(maxScale, { duration: 300 }); + } else { + scale.value = withTiming(minScale, { duration: 300 }); + } + savedScale.value = scale.value; + }, + simultaneousWithExternalGesture: confirm, + }); + + const unlockingGesture = useSimultaneous(rotationGesture, pinchGesture); + + const animatedStyle = useAnimatedStyle(() => ({ + transform: [ + { rotateZ: `${(rotation.value / Math.PI) * 180}deg` }, + { scale: scale.value }, + ], + })); + + return ( + + + + + + {locked ? '🔒' : '🔓'} + + + + + {locked ? 'Locked' : 'Unlocked!'} + + Tou unlock rotate 90 degrees clockwise, and scale to fill the square. + Then tap to confirm, longpress to cancel the tap + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + lockIcon: { + fontSize: 40, + color: '#fff', + fontWeight: 'bold', + }, + instructions: { + color: '#9CA3AF', + marginTop: 8, + textAlign: 'center', + paddingHorizontal: 16, + }, + + outerBox: { + height: 200, + width: 200, + backgroundColor: 'gray', + borderRadius: 20, + alignItems: 'center', + justifyContent: 'center', + marginBottom: 50, + }, + box: { + height: 200, + width: 200, + backgroundColor: '#b58df1', + borderRadius: 20, + alignItems: 'center', + justifyContent: 'center', + }, +}); diff --git a/apps/common-app/src/v3_api/svg/svg.tsx b/apps/common-app/src/v3_api/svg/svg.tsx new file mode 100644 index 0000000000..c93df1bce6 --- /dev/null +++ b/apps/common-app/src/v3_api/svg/svg.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import { Text, View, StyleSheet } from 'react-native'; +import { + NativeDetector, + LogicDetector, + useTap, +} from 'react-native-gesture-handler'; + +import Svg, { Circle, Rect } from 'react-native-svg'; + +export default function LogicDetectorExample() { + const circleElementTap = useTap({ + onStart: () => { + 'worklet'; + console.log('clicked circle'); + }, + }); + const rectElementTap = useTap({ + onStart: () => { + 'worklet'; + console.log('clicked parallelogram'); + }, + }); + const containerTap = useTap({ + onStart: () => { + 'worklet'; + console.log('clicked container'); + }, + }); + + return ( + + + + Overlapping SVGs with gesture detectors + + + + + + + + + + + + + + + Tapping each color should read to a different console.log output + + + + ); +} + +const styles = StyleSheet.create({ + container: { + alignItems: 'center', + justifyContent: 'center', + marginBottom: 48, + }, + header: { + fontSize: 18, + fontWeight: 'bold', + margin: 10, + }, +}); From 2d8d8f0c40ec1a61fecf32a322c8334b33f0a532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Antoni=20Kwa=C5=9Bniewski?= Date: Wed, 1 Oct 2025 14:02:21 +0200 Subject: [PATCH 10/19] calculator, hover, overlap --- apps/common-app/App.tsx | 9 +- .../src/v3_api/calculator/index.tsx | 426 ++++++++++++++++++ apps/common-app/src/v3_api/hover/index.tsx | 134 ++++++ apps/common-app/src/v3_api/overlap/index.tsx | 146 ++++++ 4 files changed, 714 insertions(+), 1 deletion(-) create mode 100644 apps/common-app/src/v3_api/calculator/index.tsx create mode 100644 apps/common-app/src/v3_api/hover/index.tsx create mode 100644 apps/common-app/src/v3_api/overlap/index.tsx diff --git a/apps/common-app/App.tsx b/apps/common-app/App.tsx index d027ad2909..fdc3d6e02a 100644 --- a/apps/common-app/App.tsx +++ b/apps/common-app/App.tsx @@ -81,10 +81,14 @@ import LongPressExample from './src/simple/longPress'; import ManualExample from './src/simple/manual'; import SimpleFling from './src/simple/fling'; -import { Icon } from '@swmansion/icons'; import Lock from './src/v3_api/lock/lock'; import V3Fling from './src/v3_api/fling/fling'; import LogicDetectorExample from './src/v3_api/svg/svg'; +import V3Hover from './src/v3_api/hover/index'; +import V3Overlap from './src/v3_api/overlap/index'; +import V3Calculator from './src/v3_api/calculator/index'; + +import { Icon } from '@swmansion/icons'; interface Example { name: string; @@ -107,6 +111,9 @@ const EXAMPLES: ExamplesSection[] = [ { name: 'V3 Fling', component: V3Fling }, { name: 'Svg', component: LogicDetectorExample }, { name: 'Lock', component: Lock }, + { name: 'V3 Hover', component: V3Hover }, + { name: 'V3 Overlap', component: V3Overlap }, + { name: 'V3 Calculator', component: V3Calculator }, ], }, { diff --git a/apps/common-app/src/v3_api/calculator/index.tsx b/apps/common-app/src/v3_api/calculator/index.tsx new file mode 100644 index 0000000000..d27fb3fbe6 --- /dev/null +++ b/apps/common-app/src/v3_api/calculator/index.tsx @@ -0,0 +1,426 @@ +import React, { Dispatch, SetStateAction, useRef, useState } from 'react'; +import { + StyleSheet, + View, + Text, + Dimensions, + LayoutChangeEvent, + LayoutRectangle, +} from 'react-native'; +import { + ScrollView, + usePan, + NativeDetector, + useTap, +} from 'react-native-gesture-handler'; +import Animated, { + useSharedValue, + useAnimatedStyle, + withTiming, + runOnJS, +} from 'react-native-reanimated'; + +const DRAG_ANIMATION_DURATION = 300; +const TAP_ANIMATION_DURATION = 100; +const OPERATIONS_TOGGLE_OFFSET = 75; +const OUTPUT_TOGGLE_OFFSET = 100; +const window = Dimensions.get('window'); + +export default function CalculatorUI() { + const outputOffset = useSharedValue(0); + const [history, setHistory] = useState(Array()); + const [expression, setExpression] = useState(''); + + function measure({ + nativeEvent: { + layout: { height }, + }, + }: LayoutChangeEvent) { + outputOffset.value = -height; + } + + return ( + + + + + ); +} + +interface OutputProps { + offset: Animated.SharedValue; + expression: string; + history: string[]; +} + +function Output({ offset, expression, history }: OutputProps) { + const layout = useRef({}); + const scrollView = useRef(null); + const drag = useSharedValue(0); + const dragOffset = useSharedValue(0); + const [opened, setOpened] = useState(false); + + function measure({ nativeEvent: { layout: newLayout } }: LayoutChangeEvent) { + layout.current = newLayout; + } + + function open() { + drag.value = withTiming(-offset.value, { + duration: DRAG_ANIMATION_DURATION, + }); + dragOffset.value = -offset.value; + + setOpened(true); + } + + function close() { + drag.value = withTiming(0, { duration: DRAG_ANIMATION_DURATION }); + dragOffset.value = 0; + + setOpened(false); + } + + const translationStyle = useAnimatedStyle(() => { + return { + transform: [{ translateY: offset.value + drag.value }], + }; + }); + + const dragGesture = usePan({ + onUpdate: (e) => { + 'worklet'; + const translatedOffset = dragOffset.value + e.handlerData.translationY; + + if (translatedOffset > -offset.value) { + drag.value = -offset.value; + } else if (translatedOffset < 0) { + drag.value = 0; + } else { + drag.value = translatedOffset; + } + }, + onEnd: (e) => { + 'worklet'; + const translatedOffset = dragOffset.value + e.handlerData.translationY; + + if (opened) { + if (translatedOffset < -offset.value - OUTPUT_TOGGLE_OFFSET) { + runOnJS(close)(); + } else { + runOnJS(open)(); + } + } else { + if (translatedOffset > OUTPUT_TOGGLE_OFFSET) { + runOnJS(open)(); + } else { + runOnJS(close)(); + } + } + }, + }); + + scrollView.current?.scrollToEnd({ animated: true }); + + return ( + + + { + if (!opened) { + ref?.scrollToEnd({ animated: false }); + } + scrollView.current = ref; + }} + enabled={opened} + contentContainerStyle={{ flexGrow: 1 }}> + + + {history.map((exp: string) => { + return ; + })} + + + + + + + + + ); +} + +interface ExpressionProps { + expression: string; +} + +function Expression({ expression }: ExpressionProps) { + return ( + + {expression} + {expression} + + ); +} + +interface InputProps { + setHistory: Dispatch>; + setExpression: Dispatch>; + measure: (e: LayoutChangeEvent) => void; + offset: Animated.SharedValue; + expression: string; +} + +function Input({ + setHistory, + setExpression, + measure, + offset, + expression, +}: InputProps) { + const translationStyle = useAnimatedStyle(() => { + return { + transform: [{ translateY: offset.value }], + }; + }); + + function append(symbol: string) { + if (symbol === '<') { + setHistory((h) => h.concat(expression)); + setExpression((_e) => ''); + } else { + setExpression((e) => e + symbol); + } + } + + return ( + + + + + ); +} + +interface NumPadProps { + append: (text: string) => void; +} + +function NumPad({ append }: NumPadProps) { + const buttons = ['7', '8', '9', '4', '5', '6', '1', '2', '3', '<', '0', '.']; + return ( + + {buttons.map((text) => { + return