react-native-gesture-handler
Version:
Declarative API exposing native platform touch and gesture system to React Native
137 lines (122 loc) • 3.73 kB
text/typescript
import { Insets } from 'react-native';
import {
HoverGestureHandlerEventPayload,
LongPressGestureHandlerEventPayload,
} from '../../handlers/GestureHandlerEventPayload';
import {
TouchData,
GestureStateChangeEvent,
GestureTouchEvent,
} from '../../handlers/gestureHandlerCommon';
import { InnerPressableEvent, PressableEvent } from './PressableProps';
const numberAsInset = (value: number): Insets => ({
left: value,
right: value,
top: value,
bottom: value,
});
const addInsets = (a: Insets, b: Insets): Insets => ({
left: (a.left ?? 0) + (b.left ?? 0),
right: (a.right ?? 0) + (b.right ?? 0),
top: (a.top ?? 0) + (b.top ?? 0),
bottom: (a.bottom ?? 0) + (b.bottom ?? 0),
});
const touchDataToPressEvent = (
data: TouchData,
timestamp: number,
targetId: number
): InnerPressableEvent => ({
identifier: data.id,
locationX: data.x,
locationY: data.y,
pageX: data.absoluteX,
pageY: data.absoluteY,
target: targetId,
timestamp: timestamp,
touches: [], // Always empty - legacy compatibility
changedTouches: [], // Always empty - legacy compatibility
});
const gestureToPressEvent = (
event: GestureStateChangeEvent<
HoverGestureHandlerEventPayload | LongPressGestureHandlerEventPayload
>,
timestamp: number,
targetId: number
): InnerPressableEvent => ({
identifier: event.handlerTag,
locationX: event.x,
locationY: event.y,
pageX: event.absoluteX,
pageY: event.absoluteY,
target: targetId,
timestamp: timestamp,
touches: [], // Always empty - legacy compatibility
changedTouches: [], // Always empty - legacy compatibility
});
const isTouchWithinInset = (
dimensions: { width: number; height: number },
inset: Insets,
touch?: TouchData
) =>
(touch?.x ?? 0) < (inset.right ?? 0) + dimensions.width &&
(touch?.y ?? 0) < (inset.bottom ?? 0) + dimensions.height &&
(touch?.x ?? 0) > -(inset.left ?? 0) &&
(touch?.y ?? 0) > -(inset.top ?? 0);
const gestureToPressableEvent = (
event: GestureStateChangeEvent<
HoverGestureHandlerEventPayload | LongPressGestureHandlerEventPayload
>
): PressableEvent => {
const timestamp = Date.now();
// As far as I can see, there isn't a conventional way of getting targetId with the data we get
const targetId = 0;
const pressEvent = gestureToPressEvent(event, timestamp, targetId);
return {
nativeEvent: {
touches: [pressEvent],
changedTouches: [pressEvent],
identifier: pressEvent.identifier,
locationX: event.x,
locationY: event.y,
pageX: event.absoluteX,
pageY: event.absoluteY,
target: targetId,
timestamp: timestamp,
force: undefined,
},
};
};
const gestureTouchToPressableEvent = (
event: GestureTouchEvent
): PressableEvent => {
const timestamp = Date.now();
// As far as I can see, there isn't a conventional way of getting targetId with the data we get
const targetId = 0;
const touchesList = event.allTouches.map((touch: TouchData) =>
touchDataToPressEvent(touch, timestamp, targetId)
);
const changedTouchesList = event.changedTouches.map((touch: TouchData) =>
touchDataToPressEvent(touch, timestamp, targetId)
);
return {
nativeEvent: {
touches: touchesList,
changedTouches: changedTouchesList,
identifier: event.handlerTag,
locationX: event.allTouches.at(0)?.x ?? -1,
locationY: event.allTouches.at(0)?.y ?? -1,
pageX: event.allTouches.at(0)?.absoluteX ?? -1,
pageY: event.allTouches.at(0)?.absoluteY ?? -1,
target: targetId,
timestamp: timestamp,
force: undefined,
},
};
};
export {
numberAsInset,
addInsets,
isTouchWithinInset,
gestureToPressableEvent,
gestureTouchToPressableEvent,
};