react-native-gesture-handler
Version:
Declarative API exposing native platform touch and gesture system to React Native
158 lines (135 loc) • 4.38 kB
text/typescript
import type { NativeSyntheticEvent } from 'react-native';
import type { GestureTouchEvent } from '../../../handlers/gestureHandlerCommon';
import { tagMessage } from '../../../utils';
import type {
AnimatedEvent,
BaseGestureConfig,
ChangeCalculatorType,
DiffCalculatorType,
GestureEvent,
GestureHandlerEventWithHandlerData,
GestureStateChangeEventWithHandlerData,
GestureUpdateEventWithHandlerData,
} from '../../types';
function isNativeEvent<THandlerData, TExtendedHandlerData extends THandlerData>(
event: GestureHandlerEventWithHandlerData<THandlerData, TExtendedHandlerData>
): event is
| NativeSyntheticEvent<
GestureUpdateEventWithHandlerData<TExtendedHandlerData>
>
| NativeSyntheticEvent<GestureStateChangeEventWithHandlerData<THandlerData>>
| NativeSyntheticEvent<GestureTouchEvent> {
'worklet';
return 'nativeEvent' in event;
}
export function maybeExtractNativeEvent<
THandlerData,
TExtendedHandlerData extends THandlerData,
>(
event: GestureHandlerEventWithHandlerData<THandlerData, TExtendedHandlerData>
):
| GestureTouchEvent
| GestureUpdateEventWithHandlerData<TExtendedHandlerData>
| GestureStateChangeEventWithHandlerData<THandlerData> {
'worklet';
return isNativeEvent(event) ? event.nativeEvent : event;
}
export function flattenAndFilterEvent<THandlerData>(
event:
| GestureUpdateEventWithHandlerData<THandlerData>
| GestureStateChangeEventWithHandlerData<THandlerData>
): GestureEvent<THandlerData> {
'worklet';
return { handlerTag: event.handlerTag, ...event.handlerData };
}
export function isEventForHandlerWithTag<
THandlerData,
TExtendedHandlerData extends THandlerData,
>(
handlerTag: number,
event:
| GestureStateChangeEventWithHandlerData<THandlerData>
| GestureUpdateEventWithHandlerData<TExtendedHandlerData>
| GestureTouchEvent
) {
'worklet';
return event.handlerTag === handlerTag;
}
export function isNativeAnimatedEvent<THandlerData>(
callback:
| ((event: GestureEvent<THandlerData>) => void)
| AnimatedEvent
| undefined
): callback is AnimatedEvent {
'worklet';
return !!callback && '_argMapping' in callback;
}
export function checkMappingForChangeProperties(animatedEvent: AnimatedEvent) {
for (const mapping of animatedEvent._argMapping) {
if (
!mapping ||
!('nativeEvent' in mapping && 'handlerData' in mapping.nativeEvent)
) {
continue;
}
for (const key in mapping.nativeEvent.handlerData) {
if (key.startsWith('change')) {
throw new Error(
tagMessage(`${key} is not available when using Animated.Event.`)
);
}
}
}
}
export function shouldHandleTouchEvents<
TConfig,
THandlerData,
TExtendedHandlerData extends THandlerData,
>(config: BaseGestureConfig<TConfig, THandlerData, TExtendedHandlerData>) {
return (
!!config.onTouchesDown ||
!!config.onTouchesMove ||
!!config.onTouchesUp ||
!!config.onTouchesCancel
);
}
export function getChangeEventCalculator<TExtendedHandlerData>(
diffCalculator: DiffCalculatorType<TExtendedHandlerData>
): ChangeCalculatorType<TExtendedHandlerData> {
'worklet';
return (
current: GestureUpdateEventWithHandlerData<TExtendedHandlerData>,
previous?: GestureUpdateEventWithHandlerData<TExtendedHandlerData>
) => {
'worklet';
const currentEventData = current.handlerData;
const previousEventData = previous ? previous.handlerData : null;
const changePayload = diffCalculator(currentEventData, previousEventData);
current.handlerData = { ...currentEventData, ...changePayload };
return current;
};
}
export function isTouchEvent<
THandlerData,
TExtendedHandlerData extends THandlerData,
>(
event:
| GestureStateChangeEventWithHandlerData<THandlerData>
| GestureUpdateEventWithHandlerData<TExtendedHandlerData>
| GestureTouchEvent
): event is GestureTouchEvent {
'worklet';
return 'allTouches' in event;
}
export function isStateChangeEvent<
THandlerData,
TExtendedHandlerData extends THandlerData,
>(
event:
| GestureStateChangeEventWithHandlerData<THandlerData>
| GestureUpdateEventWithHandlerData<TExtendedHandlerData>
| GestureTouchEvent
): event is GestureStateChangeEventWithHandlerData<THandlerData> {
'worklet';
return 'oldState' in event && event.oldState !== undefined;
}