diff --git a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js index 39740a8ae593..ac218c0fd208 100644 --- a/packages/react-native/Libraries/Components/ScrollView/ScrollView.js +++ b/packages/react-native/Libraries/Components/ScrollView/ScrollView.js @@ -371,10 +371,10 @@ type AndroidProps = $ReadOnly<{| fadingEdgeLength?: ?number, |}>; -type StickyHeaderComponentType = React.AbstractComponent< - ScrollViewStickyHeaderProps, - $ReadOnly void}>, ->; +type StickyHeaderComponentType = component( + ref?: React.RefSetter<$ReadOnly void}>>, + ...ScrollViewStickyHeaderProps +); export type Props = $ReadOnly<{| ...ViewProps, diff --git a/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js b/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js index 89b438e54944..a97e82e86c04 100644 --- a/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js +++ b/packages/react-native/Libraries/Components/TextInput/InputAccessoryView.js @@ -87,7 +87,7 @@ type Props = $ReadOnly<{| backgroundColor?: ?ColorValue, |}>; -const InputAccessoryView: React.AbstractComponent = (props: Props) => { +const InputAccessoryView: React.ComponentType = (props: Props) => { const {width} = useWindowDimensions(); if (Platform.OS === 'ios') { diff --git a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js index 4b082ceec8bd..ee86dd32cc91 100644 --- a/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js +++ b/packages/react-native/Libraries/Components/TextInput/TextInput.flow.js @@ -1086,7 +1086,10 @@ type ImperativeMethods = $ReadOnly<{| * or control this param programmatically with native code. * */ -type InternalTextInput = (props: Props) => React.Node; +type InternalTextInput = component( + ref: React.RefSetter<$ReadOnly<{...HostInstance, ...ImperativeMethods}>>, + ...Props +); export type TextInputComponentStatics = $ReadOnly<{| State: $ReadOnly<{| @@ -1097,11 +1100,4 @@ export type TextInputComponentStatics = $ReadOnly<{| |}>, |}>; -export type TextInputType = React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{| - ...HostInstance, - ...ImperativeMethods, - |}>, -> & - TextInputComponentStatics; +export type TextInputType = InternalTextInput & TextInputComponentStatics; diff --git a/packages/react-native/Libraries/Lists/SectionListModern.js b/packages/react-native/Libraries/Lists/SectionListModern.js index 7f93d04f0bae..2d4318f27da9 100644 --- a/packages/react-native/Libraries/Lists/SectionListModern.js +++ b/packages/react-native/Libraries/Lists/SectionListModern.js @@ -93,7 +93,7 @@ type OptionalProps> = {| removeClippedSubviews?: boolean, |}; -export type Props = {| +export type Props> = $ReadOnly<{| ...$Diff< VirtualizedSectionListProps, { @@ -115,7 +115,7 @@ export type Props = {| >, ...RequiredProps, ...OptionalProps, -|}; +|}>; /** * A performant interface for rendering sectioned lists, supporting the most handy features: @@ -172,10 +172,10 @@ export type Props = {| * Alternatively, you can provide a custom `keyExtractor` prop. * */ -const SectionList: AbstractComponent>, any> = forwardRef< - Props>, - any, ->((props, ref) => { +const SectionList: component( + ref?: React.RefSetter, + ...Props> +) = forwardRef>, any>((props, ref) => { const propsWithDefaults = { stickySectionHeadersEnabled: Platform.OS === 'ios', ...props, diff --git a/packages/react-native/Libraries/LogBox/Data/LogBoxData.js b/packages/react-native/Libraries/LogBox/Data/LogBoxData.js index f32af9dbb39b..85b7cc7ecc72 100644 --- a/packages/react-native/Libraries/LogBox/Data/LogBoxData.js +++ b/packages/react-native/Libraries/LogBox/Data/LogBoxData.js @@ -421,7 +421,7 @@ type State = $ReadOnly<{| selectedLogIndex: number, |}>; -type SubscribedComponent = React.AbstractComponent< +type SubscribedComponent = React.ComponentType< $ReadOnly<{| logs: $ReadOnlyArray, isDisabled: boolean, @@ -431,7 +431,7 @@ type SubscribedComponent = React.AbstractComponent< export function withSubscription( WrappedComponent: SubscribedComponent, -): React.AbstractComponent<{||}> { +): React.ComponentType<{||}> { class LogBoxStateSubscription extends React.Component { static getDerivedStateFromError(): {hasError: boolean} { return {hasError: true}; diff --git a/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js b/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js index 142cccaf44bf..3ffaab83616e 100644 --- a/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js +++ b/packages/react-native/Libraries/LogBox/LogBoxInspectorContainer.js @@ -65,4 +65,4 @@ export class _LogBoxInspectorContainer extends React.Component { export default (LogBoxData.withSubscription( _LogBoxInspectorContainer, -): React.AbstractComponent<{||}>); +): React.ComponentType<{||}>); diff --git a/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js b/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js index 2013fa8b7e23..6f3a89185924 100644 --- a/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js +++ b/packages/react-native/Libraries/LogBox/LogBoxNotificationContainer.js @@ -102,4 +102,4 @@ const styles = StyleSheet.create({ export default (LogBoxData.withSubscription( _LogBoxNotificationContainer, -): React.AbstractComponent<{||}>); +): React.ComponentType<{||}>); diff --git a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js index 5637d6ae9efc..35a60c70026c 100644 --- a/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js +++ b/packages/react-native/Libraries/LogBox/UI/LogBoxInspectorHeader.js @@ -27,7 +27,7 @@ type Props = $ReadOnly<{ level: LogLevel, }>; -const LogBoxInspectorHeaderSafeArea: React.AbstractComponent = +const LogBoxInspectorHeaderSafeArea: React.ComponentType = Platform.OS === 'android' ? View : SafeAreaView; export default function LogBoxInspectorHeader(props: Props): React.Node { diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index 5f6f847568bd..cc0a0622ff6b 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -342,8 +342,7 @@ const styles = StyleSheet.create({ }, }); -const ExportedModal: React.AbstractComponent< - React.ElementConfig, -> = ModalInjection.unstable_Modal ?? Modal; +const ExportedModal: React.ComponentType> = + ModalInjection.unstable_Modal ?? Modal; module.exports = ExportedModal; diff --git a/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js b/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js index 68695660da13..fcb263653e3f 100644 --- a/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js +++ b/packages/react-native/Libraries/NativeComponent/NativeComponentRegistry.js @@ -124,7 +124,7 @@ export function get( export function getWithFallback_DEPRECATED( name: string, viewConfigProvider: () => PartialViewConfig, -): React.AbstractComponent { +): React.ComponentType { if (getRuntimeConfig == null) { // `getRuntimeConfig == null` when static view configs are disabled // If `setRuntimeConfigProvider` is not configured, use native reflection. diff --git a/packages/react-native/Libraries/ReactNative/AppContainer.js b/packages/react-native/Libraries/ReactNative/AppContainer.js index 91a51cd8f48a..afea7ca8631d 100644 --- a/packages/react-native/Libraries/ReactNative/AppContainer.js +++ b/packages/react-native/Libraries/ReactNative/AppContainer.js @@ -24,7 +24,7 @@ export type Props = $ReadOnly<{| internal_excludeInspector?: boolean, |}>; -const AppContainer: React.AbstractComponent = __DEV__ +const AppContainer: component(...Props) = __DEV__ ? require('./AppContainer-dev').default : require('./AppContainer-prod').default; diff --git a/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js b/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js index 34aaea169261..6b581185d114 100644 --- a/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js +++ b/packages/react-native/Libraries/ReactNative/getCachedComponentWithDebugName.js @@ -8,11 +8,9 @@ * @format */ -import type {AbstractComponent} from 'react'; - import * as React from 'react'; -type NoopComponent = AbstractComponent<{children: React.Node}>; +type NoopComponent = component(children: React.Node); const cache: Map< string, // displayName diff --git a/packages/react-native/Libraries/ReactNative/renderApplication.js b/packages/react-native/Libraries/ReactNative/renderApplication.js index c483082f919d..782014a52dd5 100644 --- a/packages/react-native/Libraries/ReactNative/renderApplication.js +++ b/packages/react-native/Libraries/ReactNative/renderApplication.js @@ -23,10 +23,12 @@ import * as React from 'react'; // require BackHandler so it sets the default handler that exits the app if no listeners respond import '../Utilities/BackHandler'; -type ActivityType = React.AbstractComponent<{ - mode: 'visible' | 'hidden', - children: React.Node, -}>; +type ActivityType = component( + ...{ + mode: 'visible' | 'hidden', + children: React.Node, + } +); export default function renderApplication( RootComponent: React.ComponentType, diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 13ddb0a6a944..ce5edc6a0724 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -2084,10 +2084,12 @@ type AndroidProps = $ReadOnly<{| persistentScrollbar?: ?boolean, fadingEdgeLength?: ?number, |}>; -type StickyHeaderComponentType = React.AbstractComponent< - ScrollViewStickyHeaderProps, - $ReadOnly void }>, ->; +type StickyHeaderComponentType = component( + ref?: React.RefSetter< + $ReadOnly void }>, + >, + ...ScrollViewStickyHeaderProps +); export type Props = $ReadOnly<{| ...ViewProps, ...IOSProps, @@ -2751,7 +2753,7 @@ exports[`public API should not change unintentionally Libraries/Components/TextI style?: ?ViewStyleProp, backgroundColor?: ?ColorValue, |}>; -declare const InputAccessoryView: React.AbstractComponent; +declare const InputAccessoryView: React.ComponentType; declare export default typeof InputAccessoryView; " `; @@ -3119,7 +3121,10 @@ type ImperativeMethods = $ReadOnly<{| getNativeRef: () => ?HostInstance, setSelection: (start: number, end: number) => void, |}>; -type InternalTextInput = (props: Props) => React.Node; +type InternalTextInput = component( + ref: React.RefSetter<$ReadOnly<{ ...HostInstance, ...ImperativeMethods }>>, + ...Props +); export type TextInputComponentStatics = $ReadOnly<{| State: $ReadOnly<{| currentlyFocusedInput: () => ?HostInstance, @@ -3128,14 +3133,7 @@ export type TextInputComponentStatics = $ReadOnly<{| blurTextInput: (textField: ?HostInstance) => void, |}>, |}>; -export type TextInputType = React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{| - ...HostInstance, - ...ImperativeMethods, - |}>, -> & - TextInputComponentStatics; +export type TextInputType = InternalTextInput & TextInputComponentStatics; " `; @@ -5842,7 +5840,7 @@ type OptionalProps> = {| onEndReached?: ?(info: { distanceFromEnd: number, ... }) => void, removeClippedSubviews?: boolean, |}; -export type Props = {| +export type Props> = $ReadOnly<{| ...$Diff< VirtualizedSectionListProps, { @@ -5864,8 +5862,11 @@ export type Props = {| >, ...RequiredProps, ...OptionalProps, -|}; -declare const SectionList: AbstractComponent>, any>; +|}>; +declare const SectionList: component( + ref?: React.RefSetter, + ...Props> +); declare export default typeof SectionList; " `; @@ -5979,7 +5980,7 @@ declare export function addIgnorePatterns( declare export function setDisabled(value: boolean): void; declare export function isDisabled(): boolean; declare export function observe(observer: Observer): Subscription; -type SubscribedComponent = React.AbstractComponent< +type SubscribedComponent = React.ComponentType< $ReadOnly<{| logs: $ReadOnlyArray, isDisabled: boolean, @@ -5988,7 +5989,7 @@ type SubscribedComponent = React.AbstractComponent< >; declare export function withSubscription( WrappedComponent: SubscribedComponent -): React.AbstractComponent<{||}>; +): React.ComponentType<{||}>; " `; @@ -6148,7 +6149,7 @@ declare export class _LogBoxInspectorContainer extends React.Component { _handleMinimize: $FlowFixMe; _handleSetSelectedLog: $FlowFixMe; } -declare export default React.AbstractComponent<{||}>; +declare export default React.ComponentType<{||}>; " `; @@ -6159,7 +6160,7 @@ exports[`public API should not change unintentionally Libraries/LogBox/LogBoxNot isDisabled?: ?boolean, |}>; declare export function _LogBoxNotificationContainer(props: Props): React.Node; -declare export default React.AbstractComponent<{||}>; +declare export default React.ComponentType<{||}>; " `; @@ -6441,7 +6442,7 @@ declare class Modal extends React.Component { render(): React.Node; _shouldSetResponder(): boolean; } -declare const ExportedModal: React.AbstractComponent< +declare const ExportedModal: React.ComponentType< React.ElementConfig, >; declare module.exports: ExportedModal; @@ -6485,7 +6486,7 @@ declare export function get( declare export function getWithFallback_DEPRECATED( name: string, viewConfigProvider: () => PartialViewConfig -): React.AbstractComponent; +): React.ComponentType; declare export function unstable_hasStaticViewConfig(name: string): boolean; " `; @@ -7304,7 +7305,7 @@ exports[`public API should not change unintentionally Libraries/ReactNative/AppC internal_excludeLogBox?: boolean, internal_excludeInspector?: boolean, |}>; -declare const AppContainer: React.AbstractComponent; +declare const AppContainer: component(...Props); declare module.exports: AppContainer; " `; @@ -7694,7 +7695,7 @@ exports[`public API should not change unintentionally Libraries/ReactNative/UIMa `; exports[`public API should not change unintentionally Libraries/ReactNative/getCachedComponentWithDebugName.js 1`] = ` -"type NoopComponent = AbstractComponent<{ children: React.Node }>; +"type NoopComponent = component(children: React.Node); declare export default function getCachedComponentWithDisplayName( displayName: string ): NoopComponent; diff --git a/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js b/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js index d07b41d21345..e06b2899b64e 100644 --- a/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js +++ b/packages/react-native/src/private/components/SafeAreaView_INTERNAL_DO_NOT_USE.js @@ -16,10 +16,10 @@ import UIManager from '../../../Libraries/ReactNative/UIManager'; import Platform from '../../../Libraries/Utilities/Platform'; import * as React from 'react'; -const exported: React.AbstractComponent< - ViewProps, - React.ElementRef, -> = Platform.select({ +const exported: component( + ref?: React.RefSetter>, + ...ViewProps +) = Platform.select({ ios: require('../../../src/private/specs/components/RCTSafeAreaViewNativeComponent') .default, android: UIManager.hasViewManagerConfig('RCTSafeAreaView') diff --git a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js index 8d6a51d6358a..85e21967ad68 100644 --- a/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js +++ b/packages/rn-tester/js/examples/Experimental/W3CPointerEventsExample.js @@ -103,7 +103,7 @@ function RelativeChildExample({log}: {log: string => void}) { function PointerEventScaffolding({ Example, }: { - Example: React.AbstractComponent<{log: string => void}>, + Example: component(log: (string) => void), }) { const [eventsLog, setEventsLog] = React.useState(''); const clear = () => setEventsLog(''); diff --git a/packages/rn-tester/js/examples/Touchable/TouchableExample.js b/packages/rn-tester/js/examples/Touchable/TouchableExample.js index 305981f1f59a..ca97f24a1188 100644 --- a/packages/rn-tester/js/examples/Touchable/TouchableExample.js +++ b/packages/rn-tester/js/examples/Touchable/TouchableExample.js @@ -311,7 +311,7 @@ class TouchableHitSlop extends React.Component<{...}, $FlowFixMeState> { } function TouchableNativeMethodChecker< - T: React.AbstractComponent, + T: component(ref?: React.RefSetter, ...any), >(props: {|Component: T, name: string|}): React.Node { const [status, setStatus] = useState(null); const ref = useRef>(null); @@ -558,7 +558,7 @@ const TouchableTouchSoundDisabled = () => { }; // $FlowFixMe[missing-local-annot] -function TouchableOnFocus>() { +function TouchableOnFocus, ...any)>() { const ref = useRef | {focus: Function}>(null); const [isFocused, setIsFocused] = useState(false); const [focusStatus, setFocusStatus] = useState( @@ -677,13 +677,13 @@ exports.examples = [ 'child view is fully opaque, although it can be made to work as a simple ' + 'background color change as well with the activeOpacity and ' + 'underlayColor props.': string), - render: function (): React.Node { + render(): React.Node { return ; }, }, { title: '', - render: function (): React.Node { + render(): React.Node { return ; }, }, @@ -692,7 +692,7 @@ exports.examples = [ description: ('TouchableNativeFeedback can have an AnimatedComponent as a' + 'direct child.': string), platform: 'android', - render: function (): React.Node { + render(): React.Node { const mScale = new Animated.Value(1); Animated.timing(mScale, { toValue: 0.3, @@ -718,25 +718,25 @@ exports.examples = [ }, { title: 'TouchableHighlight Underlay Visibility', - render: function (): React.Node { + render(): React.Node { return ; }, }, { title: 'Touchable Touch Sound', - render: function (): React.Node { + render(): React.Node { return ; }, }, { title: 'Touchable onFocus', - render: function (): React.Node { + render(): React.Node { return ; }, }, { title: ' with highlight', - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, }, @@ -744,7 +744,7 @@ exports.examples = [ title: 'Touchable feedback events', description: (' components accept onPress, onPressIn, ' + 'onPressOut, and onLongPress as props.': string), - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, }, @@ -753,7 +753,7 @@ exports.examples = [ description: (' components also accept delayPressIn, ' + 'delayPressOut, and delayLongPress as props. These props impact the ' + 'timing of feedback events.': string), - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, }, @@ -761,7 +761,7 @@ exports.examples = [ title: '3D Touch / Force Touch', description: 'iPhone 8 and 8 plus support 3D touch, which adds a force property to touches', - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, platform: 'ios', @@ -771,7 +771,7 @@ exports.examples = [ description: (' components accept hitSlop prop which extends the touch area ' + 'without changing the view bounds.': string), - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, }, @@ -779,7 +779,7 @@ exports.examples = [ title: 'Touchable Native Methods', description: ('Some components expose native methods like `measure`.': string), - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, }, @@ -787,7 +787,7 @@ exports.examples = [ title: 'Custom Ripple Radius (Android-only)', description: ('Ripple radius on TouchableNativeFeedback can be controlled': string), - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, }, @@ -796,7 +796,7 @@ exports.examples = [ description: (' components accept disabled prop which prevents ' + 'any interaction with component': string), - render: function (): React.MixedElement { + render(): React.MixedElement { return ; }, },