import * as React from 'react'; import { useImperativeHandle, useRef } from 'react'; import { NativeViewGestureHandler, NativeViewGestureHandlerProps, nativeViewProps, } from './NativeViewGestureHandler'; /* * This array should consist of: * - All keys in propTypes from NativeGestureHandler * (and all keys in GestureHandlerPropTypes) * - 'onGestureHandlerEvent' * - 'onGestureHandlerStateChange' */ const NATIVE_WRAPPER_PROPS_FILTER = [ ...nativeViewProps, 'onGestureHandlerEvent', 'onGestureHandlerStateChange', ] as const; export default function createNativeWrapper

( Component: React.ComponentType

, config: Readonly = {} ) { const ComponentWrapper = React.forwardRef< React.ComponentType, P & NativeViewGestureHandlerProps >((props, ref) => { // filter out props that should be passed to gesture handler wrapper const gestureHandlerProps = Object.keys(props).reduce( (res, key) => { // TS being overly protective with it's types, see https://github.com/microsoft/TypeScript/issues/26255#issuecomment-458013731 for more info const allowedKeys: readonly string[] = NATIVE_WRAPPER_PROPS_FILTER; if (allowedKeys.includes(key)) { // @ts-ignore FIXME(TS) res[key] = props[key]; } return res; }, { ...config } // watch out not to modify config ); const _ref = useRef>(); const _gestureHandlerRef = useRef>(); useImperativeHandle( ref, // @ts-ignore TODO(TS) decide how nulls work in this context () => { const node = _gestureHandlerRef.current; // add handlerTag for relations config if (_ref.current && node) { // @ts-ignore FIXME(TS) think about createHandler return type _ref.current.handlerTag = node.handlerTag; return _ref.current; } return null; }, [_ref, _gestureHandlerRef] ); return ( ); }); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment ComponentWrapper.displayName = Component?.displayName || // @ts-ignore if render doesn't exist it will return undefined and go further Component?.render?.name || (typeof Component === 'string' && Component) || 'ComponentWrapper'; return ComponentWrapper; }