import type { PropsWithChildren, ReactElement } from 'react'; import * as React from 'react'; import type { DrawerLayoutAndroid as RNDrawerLayoutAndroid, DrawerLayoutAndroidProps as RNDrawerLayoutAndroidProps, FlatListProps as RNFlatListProps, ScrollViewProps as RNScrollViewProps, SwitchProps as RNSwitchProps, TextInputProps as RNTextInputProps, } from 'react-native'; import { FlatList as RNFlatList, RefreshControl as RNRefreshControl, ScrollView as RNScrollView, Switch as RNSwitch, TextInput as RNTextInput, } from 'react-native'; import createNativeWrapper from '../handlers/createNativeWrapper'; import type { NativeViewGestureHandlerProps } from '../handlers/NativeViewGestureHandler'; import { nativeViewProps } from '../handlers/NativeViewGestureHandler'; import { toArray } from '../utils'; /** * @deprecated use `RefreshControl` instead */ export const LegacyRefreshControl = createNativeWrapper(RNRefreshControl, { disallowInterruption: true, shouldCancelWhenOutside: false, }); // eslint-disable-next-line @typescript-eslint/no-redeclare export type LegacyRefreshControl = typeof LegacyRefreshControl & RNRefreshControl; const GHScrollView = createNativeWrapper>( RNScrollView, { disallowInterruption: true, shouldCancelWhenOutside: false, } ); /** * @deprecated use `ScrollView` instead */ export const LegacyScrollView = ( props: RNScrollViewProps & NativeViewGestureHandlerProps & { ref?: React.Ref | null>; } ) => { const refreshControlGestureRef = React.useRef(null); const { refreshControl, waitFor, ref, ...rest } = props; return ( | null>} waitFor={[...toArray(waitFor ?? []), refreshControlGestureRef]} // @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 } /> ); }; // 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 LegacyScrollView = typeof GHScrollView & React.ComponentRef; /** * @deprecated use `Switch` instead */ export const LegacySwitch = createNativeWrapper(RNSwitch, { shouldCancelWhenOutside: false, shouldActivateOnStart: true, disallowInterruption: true, }); // eslint-disable-next-line @typescript-eslint/no-redeclare export type LegacySwitch = typeof LegacySwitch & RNSwitch; /** * @deprecated use `RefreshControl` instead */ export const LegacyTextInput = createNativeWrapper(RNTextInput); // eslint-disable-next-line @typescript-eslint/no-redeclare export type LegacyTextInput = typeof LegacyTextInput & RNTextInput; // RN's `DrawerLayoutAndroid` export is a getter that logs a deprecation // warning on access, so resolve it on first render instead of module load. // `require` is used on purpose: `import * as RN` would read every export // eagerly under Metro's `experimentalImportSupport`. let DrawerLayoutAndroidImpl: typeof RNDrawerLayoutAndroid | undefined; const LazyDrawerLayoutAndroid = ( props: PropsWithChildren & { ref?: React.Ref | null>; } ) => { if (!DrawerLayoutAndroidImpl) { // eslint-disable-next-line @typescript-eslint/no-var-requires const { DrawerLayoutAndroid } = require('react-native') as { DrawerLayoutAndroid: typeof RNDrawerLayoutAndroid; }; DrawerLayoutAndroidImpl = DrawerLayoutAndroid; } return ; }; LazyDrawerLayoutAndroid.displayName = 'DrawerLayoutAndroid'; /** * @deprecated use `DrawerLayoutAndroid` instead */ export const LegacyDrawerLayoutAndroid: React.ComponentType< PropsWithChildren & NativeViewGestureHandlerProps & { // eslint-disable-next-line @typescript-eslint/no-explicit-any ref?: React.Ref | null>; } > = createNativeWrapper>( LazyDrawerLayoutAndroid, { disallowInterruption: true } ); // eslint-disable-next-line @typescript-eslint/no-redeclare export type LegacyDrawerLayoutAndroid = typeof LegacyDrawerLayoutAndroid & React.ComponentRef; /** * @deprecated use `FlatList` instead */ export const LegacyFlatList = ( props: PropsWithChildren< Omit, 'renderScrollComponent'> & NativeViewGestureHandlerProps & { ref?: React.Ref | null>; } > ): ReactElement | null => { 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 } /> ); }; // eslint-disable-next-line @typescript-eslint/no-redeclare export type LegacyFlatList = typeof LegacyFlatList & RNFlatList;