diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/fling/useFling.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/fling/useFling.ts index dea7a561ff..b171b86c07 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/fling/useFling.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/fling/useFling.ts @@ -8,7 +8,7 @@ import { GestureUpdateEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig } from '../../utils'; +import { useClonedAndRemappedConfig } from '../../utils'; import type { FlingGestureNativeProperties } from './FlingProperties'; type FlingHandlerData = { @@ -39,9 +39,11 @@ export type FlingGesture = SingleGesture< >; export function useFling(config: FlingGestureConfig): FlingGesture { - const flingConfig = cloneConfig( - config - ); + const flingConfig = useClonedAndRemappedConfig< + FlingHandlerData, + FlingGestureProperties, + FlingGestureProperties + >(config); return useGesture(SingleGestureName.Fling, flingConfig); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/hover/useHover.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/hover/useHover.ts index 9713ee9c1f..a1133d8136 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/hover/useHover.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/hover/useHover.ts @@ -11,7 +11,10 @@ import { GestureUpdateEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig, getChangeEventCalculator } from '../../utils'; +import { + useClonedAndRemappedConfig, + getChangeEventCalculator, +} from '../../utils'; import { HoverGestureNativeProperties } from './HoverProperties'; type HoverHandlerData = { @@ -58,12 +61,22 @@ function diffCalculator( }; } -export function useHover(config: HoverGestureConfig): HoverGesture { - const hoverConfig = cloneConfig( - config - ); +function transformHoverProps( + config: HoverGestureConfig & HoverGestureInternalConfig +) { + config.changeEventCalculator = getChangeEventCalculator(diffCalculator); - hoverConfig.changeEventCalculator = getChangeEventCalculator(diffCalculator); + return config; +} + +const HoverPropsMapping = new Map(); + +export function useHover(config: HoverGestureConfig): HoverGesture { + const hoverConfig = useClonedAndRemappedConfig< + HoverHandlerData, + HoverGestureProperties, + HoverGestureProperties + >(config, HoverPropsMapping, transformHoverProps); return useGesture(SingleGestureName.Hover, hoverConfig); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/longPress/useLongPress.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/longPress/useLongPress.ts index 9061388ff6..dcef3f3e85 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/longPress/useLongPress.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/longPress/useLongPress.ts @@ -8,7 +8,7 @@ import { GestureUpdateEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig, remapProps } from '../../utils'; +import { useClonedAndRemappedConfig } from '../../utils'; import { LongPressGestureExternalProperties, LongPressGestureNativeProperties, @@ -56,20 +56,22 @@ const LongPressPropsMapping = new Map< ['maxDistance', 'maxDist'], ]); +function transformLongPressProps( + config: LongPressGestureConfig & LongPressGestureInternalConfig +) { + if (config.shouldCancelWhenOutside === undefined) { + config.shouldCancelWhenOutside = true; + } + + return config; +} + export function useLongPress(config: LongPressGestureConfig): LongPressGesture { - const longPressConfig = cloneConfig< + const longPressConfig = useClonedAndRemappedConfig< LongPressHandlerData, + LongPressGestureProperties, LongPressGestureInternalProperties - >(config); - - remapProps( - longPressConfig, - LongPressPropsMapping - ); - - if (longPressConfig.shouldCancelWhenOutside === undefined) { - longPressConfig.shouldCancelWhenOutside = true; - } + >(config, LongPressPropsMapping, transformLongPressProps); return useGesture( SingleGestureName.LongPress, diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/manual/useManual.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/manual/useManual.ts index 1f364cdbcf..8e09c1ee75 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/manual/useManual.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/manual/useManual.ts @@ -7,7 +7,7 @@ import { GestureUpdateEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig } from '../../utils'; +import { useClonedAndRemappedConfig } from '../../utils'; import { ManualGestureNativeProperties } from './ManualProperties'; type ManualHandlerData = Record; @@ -32,9 +32,11 @@ export type ManualGesture = SingleGesture< >; export function useManual(config: ManualGestureConfig): ManualGesture { - const manualConfig = cloneConfig( - config - ); + const manualConfig = useClonedAndRemappedConfig< + ManualHandlerData, + ManualGestureProperties, + ManualGestureProperties + >(config); return useGesture(SingleGestureName.Manual, manualConfig); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/native/useNative.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/native/useNative.ts index 6b9d5a30e6..85edd466d1 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/native/useNative.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/native/useNative.ts @@ -8,7 +8,7 @@ import { GestureUpdateEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig } from '../../utils'; +import { useClonedAndRemappedConfig } from '../../utils'; import { NativeGestureNativeProperties } from './NativeProperties'; type NativeViewHandlerData = { @@ -38,8 +38,9 @@ export type NativeGesture = SingleGesture< >; export function useNative(config: NativeViewGestureConfig): NativeGesture { - const nativeConfig = cloneConfig< + const nativeConfig = useClonedAndRemappedConfig< NativeViewHandlerData, + NativeViewGestureProperties, NativeViewGestureProperties >(config); diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/pan/usePan.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/pan/usePan.ts index 351b137222..abcdfb30c1 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/pan/usePan.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/pan/usePan.ts @@ -13,8 +13,7 @@ import { useGesture } from '../../useGesture'; import { getChangeEventCalculator, maybeUnpackValue, - remapProps, - cloneConfig, + useClonedAndRemappedConfig, } from '../../utils'; import { OffsetProps, @@ -56,7 +55,10 @@ export type PanGestureStateChangeEvent = export type PanGestureUpdateEvent = GestureUpdateEvent; -export type PanGesture = SingleGesture; +export type PanGesture = SingleGesture< + PanHandlerData, + PanGestureInternalProperties +>; const PanPropsMapping = new Map< keyof PanGestureProperties, @@ -137,15 +139,6 @@ function transformOffsetProp( delete config[propName]; } -function transformPanProps( - config: PanGestureConfig & PanGestureInternalConfig -) { - transformOffsetProp(config, 'activeOffsetY'); - transformOffsetProp(config, 'failOffsetX'); - transformOffsetProp(config, 'failOffsetY'); - transformOffsetProp(config, 'activeOffsetX'); -} - function diffCalculator( current: HandlerData, previous: HandlerData | null @@ -161,23 +154,29 @@ function diffCalculator( }; } +function transformPanProps( + config: PanGestureConfig & PanGestureInternalConfig +) { + transformOffsetProp(config, 'activeOffsetY'); + transformOffsetProp(config, 'failOffsetX'); + transformOffsetProp(config, 'failOffsetY'); + transformOffsetProp(config, 'activeOffsetX'); + + config.changeEventCalculator = getChangeEventCalculator(diffCalculator); + + return config; +} + export function usePan(config: PanGestureConfig): PanGesture { if (__DEV__) { validatePanConfig(config); } - const panConfig = cloneConfig( - config - ); - - remapProps( - panConfig, - PanPropsMapping - ); - - transformPanProps(panConfig); - - panConfig.changeEventCalculator = getChangeEventCalculator(diffCalculator); + const panConfig = useClonedAndRemappedConfig< + PanHandlerData, + PanGestureProperties, + PanGestureInternalProperties + >(config, PanPropsMapping, transformPanProps); return useGesture( SingleGestureName.Pan, diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/pinch/usePinch.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/pinch/usePinch.ts index 3b3f7b31d8..0c61f27d79 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/pinch/usePinch.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/pinch/usePinch.ts @@ -8,7 +8,10 @@ import { GestureStateChangeEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig, getChangeEventCalculator } from '../../utils'; +import { + useClonedAndRemappedConfig, + getChangeEventCalculator, +} from '../../utils'; import { PinchGestureNativeProperties } from './PinchProperties'; type PinchHandlerData = { @@ -49,10 +52,23 @@ function diffCalculator( }; } +function transformPinchProps( + config: PinchGestureConfig & PinchGestureInternalConfig +) { + config.changeEventCalculator = getChangeEventCalculator(diffCalculator); + + return config; +} + +const PinchPropsMapping = new Map(); + export function usePinch(config: PinchGestureConfig): PinchGesture { - const pinchConfig = cloneConfig( - config - ); + const pinchConfig = useClonedAndRemappedConfig< + PinchHandlerData, + PinchGestureProperties, + // no internal props, pass record as PinchGestureProperties maps everything to never + Record + >(config, PinchPropsMapping, transformPinchProps); pinchConfig.changeEventCalculator = getChangeEventCalculator(diffCalculator); diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/rotation/useRotation.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/rotation/useRotation.ts index cf45cbc0ba..a0eca988bb 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/rotation/useRotation.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/rotation/useRotation.ts @@ -8,7 +8,10 @@ import { GestureUpdateEvent, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig, getChangeEventCalculator } from '../../utils'; +import { + useClonedAndRemappedConfig, + getChangeEventCalculator, +} from '../../utils'; import { RotationGestureNativeProperties } from './RotationProperties'; type RotationHandlerData = { @@ -52,14 +55,23 @@ function diffCalculator( }; } +function transformRotationProps( + config: RotationGestureConfig & RotationGestureInternalConfig +) { + config.changeEventCalculator = getChangeEventCalculator(diffCalculator); + + return config; +} + +const RotationPropsMapping = new Map(); + export function useRotation(config: RotationGestureConfig): RotationGesture { - const rotationConfig = cloneConfig< + const rotationConfig = useClonedAndRemappedConfig< RotationHandlerData, - RotationGestureProperties - >(config); - - rotationConfig.changeEventCalculator = - getChangeEventCalculator(diffCalculator); + RotationGestureProperties, + // no internal props, pass record as RotationGestureProperties maps everything to never + Record + >(config, RotationPropsMapping, transformRotationProps); return useGesture(SingleGestureName.Rotation, rotationConfig); } diff --git a/packages/react-native-gesture-handler/src/v3/hooks/gestures/tap/useTap.ts b/packages/react-native-gesture-handler/src/v3/hooks/gestures/tap/useTap.ts index b9c4276353..e3b8a6780a 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/gestures/tap/useTap.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/gestures/tap/useTap.ts @@ -8,7 +8,7 @@ import { WithSharedValue, } from '../../../types'; import { useGesture } from '../../useGesture'; -import { cloneConfig, remapProps } from '../../utils'; +import { useClonedAndRemappedConfig } from '../../utils'; import { TapGestureExternalConfig, TapGestureNativeConfig, @@ -29,11 +29,6 @@ export type TapGestureConfig = ExcludeInternalConfigProps< BaseDiscreteGestureConfig >; -type TapGestureInternalConfig = BaseDiscreteGestureConfig< - TapHandlerData, - TapGestureInternalProperties ->; - export type TapGestureStateChangeEvent = GestureStateChangeEvent; @@ -41,7 +36,7 @@ export type TapGestureUpdateEvent = GestureUpdateEvent; export type TapGesture = DiscreteSingleGesture< TapHandlerData, - TapGestureProperties + TapGestureInternalProperties >; const TapPropsMapping = new Map< @@ -54,14 +49,11 @@ const TapPropsMapping = new Map< ]); export function useTap(config: TapGestureConfig): TapGesture { - const tapConfig = cloneConfig( - config - ); - - remapProps( - tapConfig, - TapPropsMapping - ); + const tapConfig = useClonedAndRemappedConfig< + TapHandlerData, + TapGestureProperties, + TapGestureInternalProperties + >(config, TapPropsMapping); return useGesture( SingleGestureName.Tap, diff --git a/packages/react-native-gesture-handler/src/v3/hooks/utils/configUtils.ts b/packages/react-native-gesture-handler/src/v3/hooks/utils/configUtils.ts index e94d64a59f..a86ed018fe 100644 --- a/packages/react-native-gesture-handler/src/v3/hooks/utils/configUtils.ts +++ b/packages/react-native-gesture-handler/src/v3/hooks/utils/configUtils.ts @@ -13,6 +13,7 @@ import { PropsToFilter, PropsWhiteLists, } from './propsWhiteList'; +import { useMemo } from 'react'; export function prepareConfig( config: BaseGestureConfig @@ -64,7 +65,10 @@ export function cloneConfig( return { ...config } as BaseGestureConfig; } -export function remapProps( +export function remapProps< + TConfig extends object, + TInternalConfig extends Record, +>( config: TConfig & TInternalConfig, propsMapping: Map ): TInternalConfig { @@ -82,3 +86,24 @@ export function remapProps( return config; } + +export function useClonedAndRemappedConfig< + THandlerData, + TConfig extends object, + TInternalConfig extends Record, +>( + config: ExcludeInternalConfigProps>, + propsMapping: Map = new Map(), + propsTransformer: (config: TInternalConfig) => TInternalConfig = (cfg) => cfg +): BaseGestureConfig { + return useMemo(() => { + const clonedConfig = cloneConfig(config); + + return propsTransformer( + remapProps( + clonedConfig as TConfig & TInternalConfig, + propsMapping + ) + ); + }, [config, propsMapping, propsTransformer]); +}