Skip to content

Commit

Permalink
Improve StatusBar/Header Behavior (react-navigation#2669)
Browse files Browse the repository at this point in the history
* Track orientation change

* Add tests for withOrientation

* Better variable naming
  • Loading branch information
spencercarli authored Sep 29, 2017
1 parent c4541f4 commit a8556b0
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 10 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"react": "16.0.0-alpha.12",
"react-native": "^0.48.4",
"react-native-vector-icons": "^4.2.0",
"react-test-renderer": "^15.6.1"
"react-test-renderer": "^16.0.0"
},
"jest": {
"notify": true,
Expand Down
1 change: 1 addition & 0 deletions src/TypeDefinition.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ export type HeaderProps = {
NavigationStackScreenOptions
>,
style: ViewStyleProp,
isLandscape?: boolean,
};

/**
Expand Down
18 changes: 14 additions & 4 deletions src/views/Header/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Animated, Platform, StyleSheet, View } from 'react-native';
import HeaderTitle from './HeaderTitle';
import HeaderBackButton from './HeaderBackButton';
import HeaderStyleInterpolator from './HeaderStyleInterpolator';
import withOrientation from '../withOrientation';

import type {
NavigationScene,
Expand Down Expand Up @@ -281,14 +282,25 @@ class Header extends React.PureComponent<void, HeaderProps, HeaderState> {
screenProps,
progress,
style,
isLandscape,
...rest
} = this.props;

const { options } = this.props.getScreenDetails(scene);
const headerStyle = options.headerStyle;
const landscapeAwareStatusBarHeight = isLandscape ? 0 : STATUSBAR_HEIGHT;
const containerStyles = [
styles.container,
{
paddingTop: landscapeAwareStatusBarHeight,
height: APPBAR_HEIGHT + landscapeAwareStatusBarHeight,
},
headerStyle,
style,
];

return (
<Animated.View {...rest} style={[styles.container, headerStyle, style]}>
<Animated.View {...rest} style={containerStyles}>
<View style={styles.appBar}>{appBar}</View>
</Animated.View>
);
Expand All @@ -315,9 +327,7 @@ if (Platform.OS === 'ios') {

const styles = StyleSheet.create({
container: {
paddingTop: STATUSBAR_HEIGHT,
backgroundColor: Platform.OS === 'ios' ? '#F7F7F7' : '#FFF',
height: STATUSBAR_HEIGHT + APPBAR_HEIGHT,
...platformContainerStyles,
},
appBar: {
Expand Down Expand Up @@ -353,4 +363,4 @@ const styles = StyleSheet.create({
},
});

export default Header;
export default withOrientation(Header);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`it adds isLandscape to props 1`] = `
<View
isLandscape={false}
/>
`;
15 changes: 15 additions & 0 deletions src/views/__tests__/withOrientation-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { View } from 'react-native';
import renderer from 'react-test-renderer';
import withOrientation, { isOrientationLandscape } from '../withOrientation';

test('it adds isLandscape to props', () => {
const WrappedComponent = withOrientation(View);
const rendered = renderer.create(<WrappedComponent />).toJSON();
expect(rendered).toMatchSnapshot();
});

test('calculates orientation correctly', () => {
const isLandscape = isOrientationLandscape({ width: 10, height: 1 });
expect(isLandscape).toBeTruthy();
});
55 changes: 55 additions & 0 deletions src/views/withOrientation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// @flow

import React from 'react';
import { Dimensions } from 'react-native';
import hoistNonReactStatic from 'hoist-non-react-statics';

type WindowDimensions = {
width: number,
height: number,
};

type InjectedProps = {
isLandscape: boolean,
};

type State = {
isLandscape: boolean,
};

export const isOrientationLandscape = ({
width,
height,
}: WindowDimensions): boolean => width > height;

export default function<T: *>(WrappedComponent: ReactClass<T & InjectedProps>) {
class withOrientation extends React.Component<void, T, State> {
state: State;

constructor() {
super();

const isLandscape = isOrientationLandscape(Dimensions.get('window'));
this.state = { isLandscape };
}

componentDidMount() {
Dimensions.addEventListener('change', this.handleOrientationChange);
}

componentWillUnmount() {
Dimensions.removeEventListener('change', this.handleOrientationChange);
}

handleOrientationChange = ({ window }: { window: WindowDimensions }) => {
const isLandscape = isOrientationLandscape(window);
this.setState({ isLandscape });
};

render() {
return <WrappedComponent {...this.props} {...this.state} />;
}
}

return hoistNonReactStatic(withOrientation, WrappedComponent);
}
22 changes: 17 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2287,6 +2287,18 @@ [email protected]:
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"

fbjs@^0.8.16:
version "0.8.16"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
dependencies:
core-js "^1.0.0"
isomorphic-fetch "^2.1.1"
loose-envify "^1.0.0"
object-assign "^4.1.0"
promise "^7.1.1"
setimmediate "^1.0.5"
ua-parser-js "^0.7.9"

fbjs@^0.8.9:
version "0.8.15"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.15.tgz#4f0695fdfcc16c37c0b07facec8cb4c4091685b9"
Expand Down Expand Up @@ -4587,12 +4599,12 @@ react-proxy@^1.1.7:
lodash "^4.6.1"
react-deep-force-update "^1.0.0"

react-test-renderer@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.6.1.tgz#026f4a5bb5552661fd2cc4bbcd0d4bc8a35ebf7e"
react-test-renderer@^16.0.0:
version "16.0.0"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.0.0.tgz#9fe7b8308f2f71f29fc356d4102086f131c9cb15"
dependencies:
fbjs "^0.8.9"
object-assign "^4.1.0"
fbjs "^0.8.16"
object-assign "^4.1.1"

react-timer-mixin@^0.13.2:
version "0.13.3"
Expand Down

0 comments on commit a8556b0

Please sign in to comment.