From c5424d5b02529d0b4672c64cb8229a3a6f15674e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Tue, 7 May 2024 11:16:53 +0200 Subject: [PATCH] Revert "Change `.web` files to default and add `.native` (#2835)" This reverts commit e3e0b79a3d3a622ec65a9c9509e8b5b12b01ff6e. --- src/RNGestureHandlerModule.native.ts | 5 - src/RNGestureHandlerModule.ts | 108 +----------- src/RNGestureHandlerModule.web.ts | 105 ++++++++++++ src/RNRenderer.native.ts | 3 - src/RNRenderer.ts | 6 +- src/RNRenderer.web.ts | 3 + src/components/GestureComponents.native.tsx | 148 ----------------- src/components/GestureComponents.tsx | 155 +++++++++++++++--- src/components/GestureComponents.web.tsx | 41 +++++ .../GestureHandlerButton.native.tsx | 5 - src/components/GestureHandlerButton.tsx | 9 +- src/components/GestureHandlerButton.web.tsx | 6 + src/components/GestureHandlerRootView.tsx | 6 + ...ive.tsx => GestureHandlerRootView.web.tsx} | 6 - src/getReactNativeVersion.native.ts | 11 -- src/getReactNativeVersion.ts | 10 +- src/getReactNativeVersion.web.ts | 3 + src/getShadowNodeFromRef.native.ts | 44 ----- src/getShadowNodeFromRef.ts | 45 ++++- src/getShadowNodeFromRef.web.ts | 7 + src/handlers/PressabilityDebugView.native.tsx | 2 - src/handlers/PressabilityDebugView.tsx | 6 +- src/handlers/PressabilityDebugView.web.tsx | 4 + src/handlers/customDirectEventTypes.native.ts | 2 - src/handlers/customDirectEventTypes.ts | 7 +- src/handlers/customDirectEventTypes.web.ts | 5 + src/handlers/gestures/GestureDetector.tsx | 13 +- tsconfig.json | 6 +- 28 files changed, 382 insertions(+), 389 deletions(-) delete mode 100644 src/RNGestureHandlerModule.native.ts create mode 100644 src/RNGestureHandlerModule.web.ts delete mode 100644 src/RNRenderer.native.ts create mode 100644 src/RNRenderer.web.ts delete mode 100644 src/components/GestureComponents.native.tsx create mode 100644 src/components/GestureComponents.web.tsx delete mode 100644 src/components/GestureHandlerButton.native.tsx create mode 100644 src/components/GestureHandlerButton.web.tsx rename src/components/{GestureHandlerRootView.native.tsx => GestureHandlerRootView.web.tsx} (71%) delete mode 100644 src/getReactNativeVersion.native.ts create mode 100644 src/getReactNativeVersion.web.ts delete mode 100644 src/getShadowNodeFromRef.native.ts create mode 100644 src/getShadowNodeFromRef.web.ts delete mode 100644 src/handlers/PressabilityDebugView.native.tsx create mode 100644 src/handlers/PressabilityDebugView.web.tsx delete mode 100644 src/handlers/customDirectEventTypes.native.ts create mode 100644 src/handlers/customDirectEventTypes.web.ts diff --git a/src/RNGestureHandlerModule.native.ts b/src/RNGestureHandlerModule.native.ts deleted file mode 100644 index b32050b354..0000000000 --- a/src/RNGestureHandlerModule.native.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Reexport the native module spec used by codegen. The relevant files are inluded on Android -// to ensure the compatibility with the old arch, while iOS doesn't require those at all. - -import Module from './specs/NativeRNGestureHandlerModule'; -export default Module; diff --git a/src/RNGestureHandlerModule.ts b/src/RNGestureHandlerModule.ts index bdf885f988..b32050b354 100644 --- a/src/RNGestureHandlerModule.ts +++ b/src/RNGestureHandlerModule.ts @@ -1,105 +1,5 @@ -import React from 'react'; +// Reexport the native module spec used by codegen. The relevant files are inluded on Android +// to ensure the compatibility with the old arch, while iOS doesn't require those at all. -import type { ActionType } from './ActionType'; -import { isNewWebImplementationEnabled } from './EnableNewWebImplementation'; -import { Gestures, HammerGestures } from './web/Gestures'; -import type { Config } from './web/interfaces'; -import InteractionManager from './web/tools/InteractionManager'; -import NodeManager from './web/tools/NodeManager'; -import * as HammerNodeManager from './web_hammer/NodeManager'; -import { GestureHandlerWebDelegate } from './web/tools/GestureHandlerWebDelegate'; - -export default { - handleSetJSResponder(tag: number, blockNativeResponder: boolean) { - console.warn('handleSetJSResponder: ', tag, blockNativeResponder); - }, - handleClearJSResponder() { - console.warn('handleClearJSResponder: '); - }, - createGestureHandler( - handlerName: keyof typeof Gestures, - handlerTag: number, - config: T - ) { - if (isNewWebImplementationEnabled()) { - if (!(handlerName in Gestures)) { - throw new Error( - `react-native-gesture-handler: ${handlerName} is not supported on web.` - ); - } - - const GestureClass = Gestures[handlerName]; - NodeManager.createGestureHandler( - handlerTag, - new GestureClass(new GestureHandlerWebDelegate()) - ); - InteractionManager.getInstance().configureInteractions( - NodeManager.getHandler(handlerTag), - config as unknown as Config - ); - } else { - if (!(handlerName in HammerGestures)) { - throw new Error( - `react-native-gesture-handler: ${handlerName} is not supported on web.` - ); - } - - // @ts-ignore If it doesn't exist, the error is thrown - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const GestureClass = HammerGestures[handlerName]; - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - HammerNodeManager.createGestureHandler(handlerTag, new GestureClass()); - } - - this.updateGestureHandler(handlerTag, config as unknown as Config); - }, - attachGestureHandler( - handlerTag: number, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - newView: any, - _actionType: ActionType, - propsRef: React.RefObject - ) { - if ( - !(newView instanceof HTMLElement || newView instanceof React.Component) - ) { - return; - } - - if (isNewWebImplementationEnabled()) { - //@ts-ignore Types should be HTMLElement or React.Component - NodeManager.getHandler(handlerTag).init(newView, propsRef); - } else { - //@ts-ignore Types should be HTMLElement or React.Component - HammerNodeManager.getHandler(handlerTag).setView(newView, propsRef); - } - }, - updateGestureHandler(handlerTag: number, newConfig: Config) { - if (isNewWebImplementationEnabled()) { - NodeManager.getHandler(handlerTag).updateGestureConfig(newConfig); - - InteractionManager.getInstance().configureInteractions( - NodeManager.getHandler(handlerTag), - newConfig - ); - } else { - HammerNodeManager.getHandler(handlerTag).updateGestureConfig(newConfig); - } - }, - getGestureHandlerNode(handlerTag: number) { - if (isNewWebImplementationEnabled()) { - return NodeManager.getHandler(handlerTag); - } else { - return HammerNodeManager.getHandler(handlerTag); - } - }, - dropGestureHandler(handlerTag: number) { - if (isNewWebImplementationEnabled()) { - NodeManager.dropGestureHandler(handlerTag); - } else { - HammerNodeManager.dropGestureHandler(handlerTag); - } - }, - // eslint-disable-next-line @typescript-eslint/no-empty-function - flushOperations() {}, -}; +import Module from './specs/NativeRNGestureHandlerModule'; +export default Module; diff --git a/src/RNGestureHandlerModule.web.ts b/src/RNGestureHandlerModule.web.ts new file mode 100644 index 0000000000..bdf885f988 --- /dev/null +++ b/src/RNGestureHandlerModule.web.ts @@ -0,0 +1,105 @@ +import React from 'react'; + +import type { ActionType } from './ActionType'; +import { isNewWebImplementationEnabled } from './EnableNewWebImplementation'; +import { Gestures, HammerGestures } from './web/Gestures'; +import type { Config } from './web/interfaces'; +import InteractionManager from './web/tools/InteractionManager'; +import NodeManager from './web/tools/NodeManager'; +import * as HammerNodeManager from './web_hammer/NodeManager'; +import { GestureHandlerWebDelegate } from './web/tools/GestureHandlerWebDelegate'; + +export default { + handleSetJSResponder(tag: number, blockNativeResponder: boolean) { + console.warn('handleSetJSResponder: ', tag, blockNativeResponder); + }, + handleClearJSResponder() { + console.warn('handleClearJSResponder: '); + }, + createGestureHandler( + handlerName: keyof typeof Gestures, + handlerTag: number, + config: T + ) { + if (isNewWebImplementationEnabled()) { + if (!(handlerName in Gestures)) { + throw new Error( + `react-native-gesture-handler: ${handlerName} is not supported on web.` + ); + } + + const GestureClass = Gestures[handlerName]; + NodeManager.createGestureHandler( + handlerTag, + new GestureClass(new GestureHandlerWebDelegate()) + ); + InteractionManager.getInstance().configureInteractions( + NodeManager.getHandler(handlerTag), + config as unknown as Config + ); + } else { + if (!(handlerName in HammerGestures)) { + throw new Error( + `react-native-gesture-handler: ${handlerName} is not supported on web.` + ); + } + + // @ts-ignore If it doesn't exist, the error is thrown + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const GestureClass = HammerGestures[handlerName]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + HammerNodeManager.createGestureHandler(handlerTag, new GestureClass()); + } + + this.updateGestureHandler(handlerTag, config as unknown as Config); + }, + attachGestureHandler( + handlerTag: number, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + newView: any, + _actionType: ActionType, + propsRef: React.RefObject + ) { + if ( + !(newView instanceof HTMLElement || newView instanceof React.Component) + ) { + return; + } + + if (isNewWebImplementationEnabled()) { + //@ts-ignore Types should be HTMLElement or React.Component + NodeManager.getHandler(handlerTag).init(newView, propsRef); + } else { + //@ts-ignore Types should be HTMLElement or React.Component + HammerNodeManager.getHandler(handlerTag).setView(newView, propsRef); + } + }, + updateGestureHandler(handlerTag: number, newConfig: Config) { + if (isNewWebImplementationEnabled()) { + NodeManager.getHandler(handlerTag).updateGestureConfig(newConfig); + + InteractionManager.getInstance().configureInteractions( + NodeManager.getHandler(handlerTag), + newConfig + ); + } else { + HammerNodeManager.getHandler(handlerTag).updateGestureConfig(newConfig); + } + }, + getGestureHandlerNode(handlerTag: number) { + if (isNewWebImplementationEnabled()) { + return NodeManager.getHandler(handlerTag); + } else { + return HammerNodeManager.getHandler(handlerTag); + } + }, + dropGestureHandler(handlerTag: number) { + if (isNewWebImplementationEnabled()) { + NodeManager.dropGestureHandler(handlerTag); + } else { + HammerNodeManager.dropGestureHandler(handlerTag); + } + }, + // eslint-disable-next-line @typescript-eslint/no-empty-function + flushOperations() {}, +}; diff --git a/src/RNRenderer.native.ts b/src/RNRenderer.native.ts deleted file mode 100644 index 7a585b64c0..0000000000 --- a/src/RNRenderer.native.ts +++ /dev/null @@ -1,3 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck -export { default as RNRenderer } from 'react-native/Libraries/Renderer/shims/ReactNative'; diff --git a/src/RNRenderer.ts b/src/RNRenderer.ts index d46b825958..7a585b64c0 100644 --- a/src/RNRenderer.ts +++ b/src/RNRenderer.ts @@ -1,3 +1,3 @@ -export const RNRenderer = { - findHostInstance_DEPRECATED: (_ref: any) => null, -}; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-nocheck +export { default as RNRenderer } from 'react-native/Libraries/Renderer/shims/ReactNative'; diff --git a/src/RNRenderer.web.ts b/src/RNRenderer.web.ts new file mode 100644 index 0000000000..d46b825958 --- /dev/null +++ b/src/RNRenderer.web.ts @@ -0,0 +1,3 @@ +export const RNRenderer = { + findHostInstance_DEPRECATED: (_ref: any) => null, +}; diff --git a/src/components/GestureComponents.native.tsx b/src/components/GestureComponents.native.tsx deleted file mode 100644 index 2a551b058d..0000000000 --- a/src/components/GestureComponents.native.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import * as React from 'react'; -import { - PropsWithChildren, - ForwardedRef, - RefAttributes, - ReactElement, -} from 'react'; -import { - ScrollView as RNScrollView, - ScrollViewProps as RNScrollViewProps, - Switch as RNSwitch, - SwitchProps as RNSwitchProps, - TextInput as RNTextInput, - TextInputProps as RNTextInputProps, - DrawerLayoutAndroid as RNDrawerLayoutAndroid, - DrawerLayoutAndroidProps as RNDrawerLayoutAndroidProps, - FlatList as RNFlatList, - FlatListProps as RNFlatListProps, - RefreshControl as RNRefreshControl, -} from 'react-native'; - -import createNativeWrapper from '../handlers/createNativeWrapper'; - -import { - NativeViewGestureHandlerProps, - nativeViewProps, -} from '../handlers/NativeViewGestureHandler'; - -import { toArray } from '../utils'; - -export const RefreshControl = createNativeWrapper(RNRefreshControl, { - disallowInterruption: true, - shouldCancelWhenOutside: false, -}); -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type RefreshControl = typeof RefreshControl & RNRefreshControl; - -const GHScrollView = createNativeWrapper>( - RNScrollView, - { - disallowInterruption: true, - shouldCancelWhenOutside: false, - } -); -export const ScrollView = React.forwardRef< - RNScrollView, - RNScrollViewProps & NativeViewGestureHandlerProps ->((props, ref) => { - const refreshControlGestureRef = React.useRef(null); - const { refreshControl, waitFor, ...rest } = props; - - return ( - - ); -}); -// backward type compatibility with https://github.com/software-mansion/react-native-gesture-handler/blob/db78d3ca7d48e8ba57482d3fe9b0a15aa79d9932/react-native-gesture-handler.d.ts#L440-L457 -// include methods of wrapped components by creating an intersection type with the RN component instead of duplicating them. -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type ScrollView = typeof GHScrollView & RNScrollView; - -export const Switch = createNativeWrapper(RNSwitch, { - shouldCancelWhenOutside: false, - shouldActivateOnStart: true, - disallowInterruption: true, -}); -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type Switch = typeof Switch & RNSwitch; - -export const TextInput = createNativeWrapper(RNTextInput); -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type TextInput = typeof TextInput & RNTextInput; - -export const DrawerLayoutAndroid = createNativeWrapper< - PropsWithChildren ->(RNDrawerLayoutAndroid, { disallowInterruption: true }); -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type DrawerLayoutAndroid = typeof DrawerLayoutAndroid & - RNDrawerLayoutAndroid; - -export const FlatList = React.forwardRef((props, ref) => { - const refreshControlGestureRef = React.useRef(null); - - const { waitFor, refreshControl, ...rest } = props; - - const flatListProps = {}; - const scrollViewProps = {}; - for (const [propName, value] of Object.entries(rest)) { - // https://github.com/microsoft/TypeScript/issues/26255 - if ((nativeViewProps as readonly string[]).includes(propName)) { - // @ts-ignore - this function cannot have generic type so we have to ignore this error - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - scrollViewProps[propName] = value; - } else { - // @ts-ignore - this function cannot have generic type so we have to ignore this error - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - flatListProps[propName] = value; - } - } - - return ( - // @ts-ignore - this function cannot have generic type so we have to ignore this error - ( - - )} - // @ts-ignore we don't pass `refreshing` prop as we only want to override the ref - refreshControl={ - refreshControl - ? React.cloneElement(refreshControl, { - // @ts-ignore for reasons unknown to me, `ref` doesn't exist on the type inferred by TS - ref: refreshControlGestureRef, - }) - : undefined - } - /> - ); -}) as ( - props: PropsWithChildren< - RNFlatListProps & - RefAttributes> & - NativeViewGestureHandlerProps - >, - ref: ForwardedRef> -) => ReactElement | null; -// eslint-disable-next-line @typescript-eslint/no-redeclare -export type FlatList = typeof FlatList & RNFlatList; diff --git a/src/components/GestureComponents.tsx b/src/components/GestureComponents.tsx index 6ab8ba63ef..2a551b058d 100644 --- a/src/components/GestureComponents.tsx +++ b/src/components/GestureComponents.tsx @@ -1,41 +1,148 @@ import * as React from 'react'; import { - FlatList as RNFlatList, + PropsWithChildren, + ForwardedRef, + RefAttributes, + ReactElement, +} from 'react'; +import { + ScrollView as RNScrollView, + ScrollViewProps as RNScrollViewProps, Switch as RNSwitch, + SwitchProps as RNSwitchProps, TextInput as RNTextInput, - ScrollView as RNScrollView, - FlatListProps, - View, + TextInputProps as RNTextInputProps, + DrawerLayoutAndroid as RNDrawerLayoutAndroid, + DrawerLayoutAndroidProps as RNDrawerLayoutAndroidProps, + FlatList as RNFlatList, + FlatListProps as RNFlatListProps, + RefreshControl as RNRefreshControl, } from 'react-native'; import createNativeWrapper from '../handlers/createNativeWrapper'; -export const ScrollView = createNativeWrapper(RNScrollView, { - disallowInterruption: false, +import { + NativeViewGestureHandlerProps, + nativeViewProps, +} from '../handlers/NativeViewGestureHandler'; + +import { toArray } from '../utils'; + +export const RefreshControl = createNativeWrapper(RNRefreshControl, { + disallowInterruption: true, + shouldCancelWhenOutside: false, }); +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type RefreshControl = typeof RefreshControl & RNRefreshControl; + +const GHScrollView = createNativeWrapper>( + RNScrollView, + { + disallowInterruption: true, + shouldCancelWhenOutside: false, + } +); +export const ScrollView = React.forwardRef< + RNScrollView, + RNScrollViewProps & NativeViewGestureHandlerProps +>((props, ref) => { + const refreshControlGestureRef = React.useRef(null); + const { refreshControl, waitFor, ...rest } = props; -export const Switch = createNativeWrapper(RNSwitch, { + return ( + + ); +}); +// backward type compatibility with https://github.com/software-mansion/react-native-gesture-handler/blob/db78d3ca7d48e8ba57482d3fe9b0a15aa79d9932/react-native-gesture-handler.d.ts#L440-L457 +// include methods of wrapped components by creating an intersection type with the RN component instead of duplicating them. +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type ScrollView = typeof GHScrollView & RNScrollView; + +export const Switch = createNativeWrapper(RNSwitch, { shouldCancelWhenOutside: false, shouldActivateOnStart: true, disallowInterruption: true, }); -export const TextInput = createNativeWrapper(RNTextInput); -export const DrawerLayoutAndroid = () => { - console.warn('DrawerLayoutAndroid is not supported on web!'); - return ; -}; - -// RefreshControl is implemented as a functional component, rendering a View -// NativeViewGestureHandler needs to set a ref on its child, which cannot be done -// on functional components -export const RefreshControl = createNativeWrapper(View); - -export const FlatList = React.forwardRef( - (props: FlatListProps, ref: any) => ( +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type Switch = typeof Switch & RNSwitch; + +export const TextInput = createNativeWrapper(RNTextInput); +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type TextInput = typeof TextInput & RNTextInput; + +export const DrawerLayoutAndroid = createNativeWrapper< + PropsWithChildren +>(RNDrawerLayoutAndroid, { disallowInterruption: true }); +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type DrawerLayoutAndroid = typeof DrawerLayoutAndroid & + RNDrawerLayoutAndroid; + +export const FlatList = React.forwardRef((props, ref) => { + const refreshControlGestureRef = React.useRef(null); + + const { waitFor, refreshControl, ...rest } = props; + + const flatListProps = {}; + const scrollViewProps = {}; + for (const [propName, value] of Object.entries(rest)) { + // https://github.com/microsoft/TypeScript/issues/26255 + if ((nativeViewProps as readonly string[]).includes(propName)) { + // @ts-ignore - this function cannot have generic type so we have to ignore this error + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + scrollViewProps[propName] = value; + } else { + // @ts-ignore - this function cannot have generic type so we have to ignore this error + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + flatListProps[propName] = value; + } + } + + return ( + // @ts-ignore - this function cannot have generic type so we have to ignore this error } + {...flatListProps} + renderScrollComponent={(scrollProps) => ( + + )} + // @ts-ignore we don't pass `refreshing` prop as we only want to override the ref + refreshControl={ + refreshControl + ? React.cloneElement(refreshControl, { + // @ts-ignore for reasons unknown to me, `ref` doesn't exist on the type inferred by TS + ref: refreshControlGestureRef, + }) + : undefined + } /> - ) -); + ); +}) as ( + props: PropsWithChildren< + RNFlatListProps & + RefAttributes> & + NativeViewGestureHandlerProps + >, + ref: ForwardedRef> +) => ReactElement | null; +// eslint-disable-next-line @typescript-eslint/no-redeclare +export type FlatList = typeof FlatList & RNFlatList; diff --git a/src/components/GestureComponents.web.tsx b/src/components/GestureComponents.web.tsx new file mode 100644 index 0000000000..6ab8ba63ef --- /dev/null +++ b/src/components/GestureComponents.web.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; +import { + FlatList as RNFlatList, + Switch as RNSwitch, + TextInput as RNTextInput, + ScrollView as RNScrollView, + FlatListProps, + View, +} from 'react-native'; + +import createNativeWrapper from '../handlers/createNativeWrapper'; + +export const ScrollView = createNativeWrapper(RNScrollView, { + disallowInterruption: false, +}); + +export const Switch = createNativeWrapper(RNSwitch, { + shouldCancelWhenOutside: false, + shouldActivateOnStart: true, + disallowInterruption: true, +}); +export const TextInput = createNativeWrapper(RNTextInput); +export const DrawerLayoutAndroid = () => { + console.warn('DrawerLayoutAndroid is not supported on web!'); + return ; +}; + +// RefreshControl is implemented as a functional component, rendering a View +// NativeViewGestureHandler needs to set a ref on its child, which cannot be done +// on functional components +export const RefreshControl = createNativeWrapper(View); + +export const FlatList = React.forwardRef( + (props: FlatListProps, ref: any) => ( + } + /> + ) +); diff --git a/src/components/GestureHandlerButton.native.tsx b/src/components/GestureHandlerButton.native.tsx deleted file mode 100644 index 1b85c23a30..0000000000 --- a/src/components/GestureHandlerButton.native.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { HostComponent } from 'react-native'; -import { RawButtonProps } from './GestureButtons'; -import RNGestureHandlerButtonNativeComponent from '../specs/RNGestureHandlerButtonNativeComponent'; - -export default RNGestureHandlerButtonNativeComponent as HostComponent; diff --git a/src/components/GestureHandlerButton.tsx b/src/components/GestureHandlerButton.tsx index 4126c7cb90..1b85c23a30 100644 --- a/src/components/GestureHandlerButton.tsx +++ b/src/components/GestureHandlerButton.tsx @@ -1,6 +1,5 @@ -import * as React from 'react'; -import { View } from 'react-native'; +import { HostComponent } from 'react-native'; +import { RawButtonProps } from './GestureButtons'; +import RNGestureHandlerButtonNativeComponent from '../specs/RNGestureHandlerButtonNativeComponent'; -export default React.forwardRef((props, ref) => ( - -)); +export default RNGestureHandlerButtonNativeComponent as HostComponent; diff --git a/src/components/GestureHandlerButton.web.tsx b/src/components/GestureHandlerButton.web.tsx new file mode 100644 index 0000000000..4126c7cb90 --- /dev/null +++ b/src/components/GestureHandlerButton.web.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; +import { View } from 'react-native'; + +export default React.forwardRef((props, ref) => ( + +)); diff --git a/src/components/GestureHandlerRootView.tsx b/src/components/GestureHandlerRootView.tsx index 965f29f4af..d668562599 100644 --- a/src/components/GestureHandlerRootView.tsx +++ b/src/components/GestureHandlerRootView.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { PropsWithChildren } from 'react'; import { View, ViewProps, StyleSheet } from 'react-native'; +import { maybeInitializeFabric } from '../init'; import GestureHandlerRootViewContext from '../GestureHandlerRootViewContext'; export interface GestureHandlerRootViewProps @@ -10,6 +11,11 @@ export default function GestureHandlerRootView({ style, ...rest }: GestureHandlerRootViewProps) { + // try initialize fabric on the first render, at this point we can + // reliably check if fabric is enabled (the function contains a flag + // to make sure it's called only once) + maybeInitializeFabric(); + return ( diff --git a/src/components/GestureHandlerRootView.native.tsx b/src/components/GestureHandlerRootView.web.tsx similarity index 71% rename from src/components/GestureHandlerRootView.native.tsx rename to src/components/GestureHandlerRootView.web.tsx index d668562599..965f29f4af 100644 --- a/src/components/GestureHandlerRootView.native.tsx +++ b/src/components/GestureHandlerRootView.web.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; import { PropsWithChildren } from 'react'; import { View, ViewProps, StyleSheet } from 'react-native'; -import { maybeInitializeFabric } from '../init'; import GestureHandlerRootViewContext from '../GestureHandlerRootViewContext'; export interface GestureHandlerRootViewProps @@ -11,11 +10,6 @@ export default function GestureHandlerRootView({ style, ...rest }: GestureHandlerRootViewProps) { - // try initialize fabric on the first render, at this point we can - // reliably check if fabric is enabled (the function contains a flag - // to make sure it's called only once) - maybeInitializeFabric(); - return ( diff --git a/src/getReactNativeVersion.native.ts b/src/getReactNativeVersion.native.ts deleted file mode 100644 index fd1cf9464d..0000000000 --- a/src/getReactNativeVersion.native.ts +++ /dev/null @@ -1,11 +0,0 @@ -import pack from 'react-native/package.json'; - -const [majorStr, minorStr] = pack.version.split('.'); -const REACT_NATIVE_VERSION = { - major: parseInt(majorStr, 10), - minor: parseInt(minorStr, 10), -}; - -export function getReactNativeVersion() { - return REACT_NATIVE_VERSION; -} diff --git a/src/getReactNativeVersion.ts b/src/getReactNativeVersion.ts index 6acdea8371..fd1cf9464d 100644 --- a/src/getReactNativeVersion.ts +++ b/src/getReactNativeVersion.ts @@ -1,3 +1,11 @@ +import pack from 'react-native/package.json'; + +const [majorStr, minorStr] = pack.version.split('.'); +const REACT_NATIVE_VERSION = { + major: parseInt(majorStr, 10), + minor: parseInt(minorStr, 10), +}; + export function getReactNativeVersion() { - throw new Error('getReactNativeVersion is not supported on web'); + return REACT_NATIVE_VERSION; } diff --git a/src/getReactNativeVersion.web.ts b/src/getReactNativeVersion.web.ts new file mode 100644 index 0000000000..6acdea8371 --- /dev/null +++ b/src/getReactNativeVersion.web.ts @@ -0,0 +1,3 @@ +export function getReactNativeVersion() { + throw new Error('getReactNativeVersion is not supported on web'); +} diff --git a/src/getShadowNodeFromRef.native.ts b/src/getShadowNodeFromRef.native.ts deleted file mode 100644 index f97a913faf..0000000000 --- a/src/getShadowNodeFromRef.native.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Used by GestureDetector (unsupported on web at the moment) to check whether the -// attached view may get flattened on Fabric. This implementation causes errors -// on web due to the static resolution of `require` statements by webpack breaking -// the conditional importing. Solved by making .web file. -let findHostInstance_DEPRECATED: (ref: unknown) => void; -let getInternalInstanceHandleFromPublicInstance: (ref: unknown) => { - stateNode: { node: unknown }; -}; - -export function getShadowNodeFromRef(ref: unknown) { - // load findHostInstance_DEPRECATED lazily because it may not be available before render - if (findHostInstance_DEPRECATED === undefined) { - try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - findHostInstance_DEPRECATED = - // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access - require('react-native/Libraries/Renderer/shims/ReactFabric').findHostInstance_DEPRECATED; - } catch (e) { - findHostInstance_DEPRECATED = (_ref: unknown) => null; - } - } - - // load findHostInstance_DEPRECATED lazily because it may not be available before render - if (getInternalInstanceHandleFromPublicInstance === undefined) { - try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - getInternalInstanceHandleFromPublicInstance = - // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access - require('react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance') - .getInternalInstanceHandleFromPublicInstance ?? - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return - ((ref: any) => ref._internalInstanceHandle); - } catch (e) { - getInternalInstanceHandleFromPublicInstance = (ref: any) => - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return - ref._internalInstanceHandle; - } - } - - // @ts-ignore Fabric - return getInternalInstanceHandleFromPublicInstance( - findHostInstance_DEPRECATED(ref) - ).stateNode.node; -} diff --git a/src/getShadowNodeFromRef.ts b/src/getShadowNodeFromRef.ts index af1cf978a2..f97a913faf 100644 --- a/src/getShadowNodeFromRef.ts +++ b/src/getShadowNodeFromRef.ts @@ -1,7 +1,44 @@ // Used by GestureDetector (unsupported on web at the moment) to check whether the -// attached view may get flattened on Fabric. Original implementation causes errors +// attached view may get flattened on Fabric. This implementation causes errors // on web due to the static resolution of `require` statements by webpack breaking -// the conditional importing. -export function getShadowNodeFromRef(_ref: any) { - return null; +// the conditional importing. Solved by making .web file. +let findHostInstance_DEPRECATED: (ref: unknown) => void; +let getInternalInstanceHandleFromPublicInstance: (ref: unknown) => { + stateNode: { node: unknown }; +}; + +export function getShadowNodeFromRef(ref: unknown) { + // load findHostInstance_DEPRECATED lazily because it may not be available before render + if (findHostInstance_DEPRECATED === undefined) { + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + findHostInstance_DEPRECATED = + // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access + require('react-native/Libraries/Renderer/shims/ReactFabric').findHostInstance_DEPRECATED; + } catch (e) { + findHostInstance_DEPRECATED = (_ref: unknown) => null; + } + } + + // load findHostInstance_DEPRECATED lazily because it may not be available before render + if (getInternalInstanceHandleFromPublicInstance === undefined) { + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + getInternalInstanceHandleFromPublicInstance = + // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-member-access + require('react-native/Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstance') + .getInternalInstanceHandleFromPublicInstance ?? + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return + ((ref: any) => ref._internalInstanceHandle); + } catch (e) { + getInternalInstanceHandleFromPublicInstance = (ref: any) => + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return + ref._internalInstanceHandle; + } + } + + // @ts-ignore Fabric + return getInternalInstanceHandleFromPublicInstance( + findHostInstance_DEPRECATED(ref) + ).stateNode.node; } diff --git a/src/getShadowNodeFromRef.web.ts b/src/getShadowNodeFromRef.web.ts new file mode 100644 index 0000000000..af1cf978a2 --- /dev/null +++ b/src/getShadowNodeFromRef.web.ts @@ -0,0 +1,7 @@ +// Used by GestureDetector (unsupported on web at the moment) to check whether the +// attached view may get flattened on Fabric. Original implementation causes errors +// on web due to the static resolution of `require` statements by webpack breaking +// the conditional importing. +export function getShadowNodeFromRef(_ref: any) { + return null; +} diff --git a/src/handlers/PressabilityDebugView.native.tsx b/src/handlers/PressabilityDebugView.native.tsx deleted file mode 100644 index 44f8bcdbcd..0000000000 --- a/src/handlers/PressabilityDebugView.native.tsx +++ /dev/null @@ -1,2 +0,0 @@ -// @ts-ignore it's not exported so we need to import it from path -export { PressabilityDebugView } from 'react-native/Libraries/Pressability/PressabilityDebug'; diff --git a/src/handlers/PressabilityDebugView.tsx b/src/handlers/PressabilityDebugView.tsx index 73e56c2bc4..44f8bcdbcd 100644 --- a/src/handlers/PressabilityDebugView.tsx +++ b/src/handlers/PressabilityDebugView.tsx @@ -1,4 +1,2 @@ -// PressabilityDebugView is not implemented in react-native-web -export function PressabilityDebugView() { - return null; -} +// @ts-ignore it's not exported so we need to import it from path +export { PressabilityDebugView } from 'react-native/Libraries/Pressability/PressabilityDebug'; diff --git a/src/handlers/PressabilityDebugView.web.tsx b/src/handlers/PressabilityDebugView.web.tsx new file mode 100644 index 0000000000..73e56c2bc4 --- /dev/null +++ b/src/handlers/PressabilityDebugView.web.tsx @@ -0,0 +1,4 @@ +// PressabilityDebugView is not implemented in react-native-web +export function PressabilityDebugView() { + return null; +} diff --git a/src/handlers/customDirectEventTypes.native.ts b/src/handlers/customDirectEventTypes.native.ts deleted file mode 100644 index 3848dac64c..0000000000 --- a/src/handlers/customDirectEventTypes.native.ts +++ /dev/null @@ -1,2 +0,0 @@ -// @ts-ignore - its taken straight from RN -export { customDirectEventTypes } from 'react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry'; diff --git a/src/handlers/customDirectEventTypes.ts b/src/handlers/customDirectEventTypes.ts index b7867a663b..3848dac64c 100644 --- a/src/handlers/customDirectEventTypes.ts +++ b/src/handlers/customDirectEventTypes.ts @@ -1,5 +1,2 @@ -// customDirectEventTypes doesn't exist in react-native-web, therefore importing it -// directly in createHandler.tsx would end in crash. -const customDirectEventTypes = {}; - -export { customDirectEventTypes }; +// @ts-ignore - its taken straight from RN +export { customDirectEventTypes } from 'react-native/Libraries/Renderer/shims/ReactNativeViewConfigRegistry'; diff --git a/src/handlers/customDirectEventTypes.web.ts b/src/handlers/customDirectEventTypes.web.ts new file mode 100644 index 0000000000..b7867a663b --- /dev/null +++ b/src/handlers/customDirectEventTypes.web.ts @@ -0,0 +1,5 @@ +// customDirectEventTypes doesn't exist in react-native-web, therefore importing it +// directly in createHandler.tsx would end in crash. +const customDirectEventTypes = {}; + +export { customDirectEventTypes }; diff --git a/src/handlers/gestures/GestureDetector.tsx b/src/handlers/gestures/GestureDetector.tsx index f6a582c252..45d927c230 100644 --- a/src/handlers/gestures/GestureDetector.tsx +++ b/src/handlers/gestures/GestureDetector.tsx @@ -42,6 +42,7 @@ import { isFabric, isJestEnv, tagMessage } from '../../utils'; import { getReactNativeVersion } from '../../getReactNativeVersion'; import { getShadowNodeFromRef } from '../../getShadowNodeFromRef'; import { Platform } from 'react-native'; +import type RNGestureHandlerModuleWeb from '../../RNGestureHandlerModule.web'; import { onGestureHandlerEvent } from './eventReceiver'; import { RNRenderer } from '../../RNRenderer'; import { isNewWebImplementationEnabled } from '../../EnableNewWebImplementation'; @@ -49,14 +50,6 @@ import { nativeViewGestureHandlerProps } from '../NativeViewGestureHandler'; import GestureHandlerRootViewContext from '../../GestureHandlerRootViewContext'; import { ghQueueMicrotask } from '../../ghQueueMicrotask'; -type AttachGestureHandlerWeb = ( - handlerTag: number, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - newView: any, - _actionType: ActionType, - propsRef: React.RefObject -) => void; - declare const global: { isFormsStackingContext: (node: unknown) => boolean | null; // JSI function }; @@ -227,7 +220,9 @@ function attachHandlers({ : ActionType.JS_FUNCTION_NEW_API; if (Platform.OS === 'web') { - (RNGestureHandlerModule.attachGestureHandler as AttachGestureHandlerWeb)( + ( + RNGestureHandlerModule.attachGestureHandler as typeof RNGestureHandlerModuleWeb.attachGestureHandler + )( gesture.handlerTag, viewTag, ActionType.JS_FUNCTION_OLD_API, // ignored on web diff --git a/tsconfig.json b/tsconfig.json index 7fbc758390..e3fe5c53b1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,9 +19,7 @@ "forceConsistentCasingInFileNames": true, "noImplicitUseStrict": false, "noUnusedParameters": true, - "noUnusedLocals": true, - - "moduleSuffixes": [".native", ""] + "noUnusedLocals": true }, - "include": ["src/**/*.ts", "src/**/*.tsx", "jestSetup.js"] + "include": ["src/**/*.ts", "src/**/*.tsx", "jestSetup.js"], }