diff --git a/packages/react-native/Libraries/Components/StatusBar/StatusBar.js b/packages/react-native/Libraries/Components/StatusBar/StatusBar.js index f8a9e62c78b..e28ef24bc05 100644 --- a/packages/react-native/Libraries/Components/StatusBar/StatusBar.js +++ b/packages/react-native/Libraries/Components/StatusBar/StatusBar.js @@ -55,7 +55,7 @@ export type StatusBarAnimation = $Keys<{ ... }>; -type AndroidProps = $ReadOnly<{ +export type StatusBarPropsAndroid = $ReadOnly<{ /** * The background color of the status bar. * @platform android @@ -71,7 +71,7 @@ type AndroidProps = $ReadOnly<{ translucent?: ?boolean, }>; -type IOSProps = $ReadOnly<{ +export type StatusBarPropsIOS = $ReadOnly<{ /** * If the network activity indicator should be visible. * @@ -87,9 +87,7 @@ type IOSProps = $ReadOnly<{ showHideTransition?: ?('fade' | 'slide' | 'none'), }>; -type Props = $ReadOnly<{ - ...AndroidProps, - ...IOSProps, +type StatusBarBaseProps = $ReadOnly<{ /** * If the status bar is hidden. */ @@ -105,22 +103,28 @@ type Props = $ReadOnly<{ barStyle?: ?('default' | 'light-content' | 'dark-content'), }>; +export type StatusBarProps = $ReadOnly<{ + ...StatusBarPropsAndroid, + ...StatusBarPropsIOS, + ...StatusBarBaseProps, +}>; + type StackProps = { backgroundColor: ?{ - value: Props['backgroundColor'], + value: StatusBarProps['backgroundColor'], animated: boolean, }, barStyle: ?{ - value: Props['barStyle'], + value: StatusBarProps['barStyle'], animated: boolean, }, - translucent: Props['translucent'], + translucent: StatusBarProps['translucent'], hidden: ?{ value: boolean, animated: boolean, - transition: Props['showHideTransition'], + transition: StatusBarProps['showHideTransition'], }, - networkActivityIndicatorVisible: Props['networkActivityIndicatorVisible'], + networkActivityIndicatorVisible: StatusBarProps['networkActivityIndicatorVisible'], }; /** @@ -147,7 +151,7 @@ function mergePropsStack( * Returns an object to insert in the props stack from the props * and the transition/animation info. */ -function createStackEntry(props: Props): StackProps { +function createStackEntry(props: StatusBarProps): StackProps { const animated = props.animated ?? false; const showHideTransition = props.showHideTransition ?? 'fade'; return { @@ -220,7 +224,7 @@ function createStackEntry(props: Props): StackProps { * * `currentHeight` (Android only) The height of the status bar. */ -class StatusBar extends React.Component { +class StatusBar extends React.Component { static _propsStack: Array = []; static _defaultProps: any = createStackEntry({ @@ -309,7 +313,7 @@ class StatusBar extends React.Component { * @param color Background color. * @param animated Animate the style change. */ - static setBackgroundColor(color: string, animated?: boolean): void { + static setBackgroundColor(color: ColorValue, animated?: boolean): void { if (Platform.OS !== 'android') { console.warn('`setBackgroundColor` is only available on Android'); return; @@ -320,7 +324,7 @@ class StatusBar extends React.Component { const processedColor = processColor(color); if (processedColor == null) { console.warn( - `\`StatusBar.setBackgroundColor\`: Color ${color} parsed to null or undefined`, + `\`StatusBar.setBackgroundColor\`: Color ${String(color)} parsed to null or undefined`, ); return; } @@ -351,7 +355,7 @@ class StatusBar extends React.Component { * * @param props Object containing the StatusBar props to use in the stack entry. */ - static pushStackEntry(props: any): any { + static pushStackEntry(props: StatusBarProps): StackProps { const entry = createStackEntry(props); StatusBar._propsStack.push(entry); StatusBar._updatePropsStack(); @@ -363,7 +367,7 @@ class StatusBar extends React.Component { * * @param entry Entry returned from `pushStackEntry`. */ - static popStackEntry(entry: any) { + static popStackEntry(entry: StackProps) { const index = StatusBar._propsStack.indexOf(entry); if (index !== -1) { StatusBar._propsStack.splice(index, 1); @@ -377,7 +381,10 @@ class StatusBar extends React.Component { * @param entry Entry returned from `pushStackEntry` to replace. * @param props Object containing the StatusBar props to use in the replacement stack entry. */ - static replaceStackEntry(entry: any, props: any): any { + static replaceStackEntry( + entry: StackProps, + props: StatusBarProps, + ): StackProps { const newEntry = createStackEntry(props); const index = StatusBar._propsStack.indexOf(entry); if (index !== -1) { @@ -400,14 +407,18 @@ class StatusBar extends React.Component { componentWillUnmount() { // When a StatusBar is unmounted, remove itself from the stack and update // the native bar with the next props. - StatusBar.popStackEntry(this._stackEntry); + if (this._stackEntry != null) { + StatusBar.popStackEntry(this._stackEntry); + } } componentDidUpdate() { - this._stackEntry = StatusBar.replaceStackEntry( - this._stackEntry, - this.props, - ); + if (this._stackEntry != null) { + this._stackEntry = StatusBar.replaceStackEntry( + this._stackEntry, + this.props, + ); + } } /** 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 820f45d1aaa..1d84b370ca8 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 @@ -2131,48 +2131,54 @@ export type StatusBarAnimation = $Keys<{ slide: string, ... }>; -type AndroidProps = $ReadOnly<{ +export type StatusBarPropsAndroid = $ReadOnly<{ backgroundColor?: ?ColorValue, translucent?: ?boolean, }>; -type IOSProps = $ReadOnly<{ +export type StatusBarPropsIOS = $ReadOnly<{ networkActivityIndicatorVisible?: ?boolean, showHideTransition?: ?(\\"fade\\" | \\"slide\\" | \\"none\\"), }>; -type Props = $ReadOnly<{ - ...AndroidProps, - ...IOSProps, +type StatusBarBaseProps = $ReadOnly<{ hidden?: ?boolean, animated?: ?boolean, barStyle?: ?(\\"default\\" | \\"light-content\\" | \\"dark-content\\"), }>; +export type StatusBarProps = $ReadOnly<{ + ...StatusBarPropsAndroid, + ...StatusBarPropsIOS, + ...StatusBarBaseProps, +}>; type StackProps = { backgroundColor: ?{ - value: Props[\\"backgroundColor\\"], + value: StatusBarProps[\\"backgroundColor\\"], animated: boolean, }, barStyle: ?{ - value: Props[\\"barStyle\\"], + value: StatusBarProps[\\"barStyle\\"], animated: boolean, }, - translucent: Props[\\"translucent\\"], + translucent: StatusBarProps[\\"translucent\\"], hidden: ?{ value: boolean, animated: boolean, - transition: Props[\\"showHideTransition\\"], + transition: StatusBarProps[\\"showHideTransition\\"], }, - networkActivityIndicatorVisible: Props[\\"networkActivityIndicatorVisible\\"], + networkActivityIndicatorVisible: StatusBarProps[\\"networkActivityIndicatorVisible\\"], }; -declare class StatusBar extends React.Component { +declare class StatusBar extends React.Component { static currentHeight: ?number; static setHidden(hidden: boolean, animation?: StatusBarAnimation): void; static setBarStyle(style: StatusBarStyle, animated?: boolean): void; static setNetworkActivityIndicatorVisible(visible: boolean): void; - static setBackgroundColor(color: string, animated?: boolean): void; + static setBackgroundColor(color: ColorValue, animated?: boolean): void; static setTranslucent(translucent: boolean): void; - static pushStackEntry(props: any): any; - static popStackEntry(entry: any): void; - static replaceStackEntry(entry: any, props: any): any; + static pushStackEntry(props: StatusBarProps): StackProps; + static popStackEntry(entry: StackProps): void; + static replaceStackEntry( + entry: StackProps, + props: StatusBarProps + ): StackProps; componentDidMount(): void; componentWillUnmount(): void; componentDidUpdate(): void; diff --git a/scripts/build/build-types/buildTypes.js b/scripts/build/build-types/buildTypes.js index 391eb820a13..a9f15160627 100644 --- a/scripts/build/build-types/buildTypes.js +++ b/scripts/build/build-types/buildTypes.js @@ -71,6 +71,7 @@ const ENTRY_POINTS = [ 'packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js', 'packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js', 'packages/react-native/Libraries/Components/Switch/Switch.js', + 'packages/react-native/Libraries/Components/StatusBar/StatusBar.js', ]; /**