From e97a9a57bc7e3c5d5e48ec50c2f2251c13fd1e8f Mon Sep 17 00:00:00 2001 From: Joshua Baker Date: Mon, 10 Apr 2017 20:34:30 -0700 Subject: [PATCH 1/2] Variable height --- README.md | 10 ++- src/ExNavigationRouter.js | 6 +- src/ExNavigationStack.js | 154 +++++++++++++++++++------------------- 3 files changed, 91 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index ed8808a..41e236d 100644 --- a/README.md +++ b/README.md @@ -278,7 +278,7 @@ Flow). ## Updating route params Sometimes you don't have all of the data that you need to set the -navigation bar title when you mount the route - for example, if you +navigation bar title or height when you mount the route - for example, if you navigate to a user profile screen by user id and need to fetch the profile data before you know what the name is. In this case, one solution is to use the `updateCurrentRouteParams` function available @@ -296,13 +296,17 @@ on `StackNavigation` navigators. + + return params.isCool ? `Hey cool person!` : `zzz`; }, ++ height(params) { ++ return params.height; ++ } } } + componentDidMount() { + setTimeout(() => { + this.props.navigator.updateCurrentRouteParams({ -+ isCool: this.props.route.params.name === 'Brent' ++ isCool: this.props.route.params.name === 'Brent', ++ height: 115 + }) + }, 1000); + } @@ -423,6 +427,8 @@ will be rendered in the title position of the `navigationBar`. will be rendered in the right position of the `navigationBar`. - `renderBackground` - a function that should return a React component that will be rendered in the background of the `navigationBar`. +- `height` - Either a number or a function that returns a number, +representing the height of the navigation bar. The function is provided with the route params as the first argument. ## TabNavigation diff --git a/src/ExNavigationRouter.js b/src/ExNavigationRouter.js index 1eb9625..0d3a535 100644 --- a/src/ExNavigationRouter.js +++ b/src/ExNavigationRouter.js @@ -134,7 +134,11 @@ export class ExNavigationRoute { }; getBarHeight = () => { - return _.get(this.config, 'navigationBar.height'); + const height = _.get(this.config, 'navigationBar.height'); + if (typeof height === 'function') { + return height(this.params, this.config); + } + return height; }; getBarBorderBottomWidth = () => { diff --git a/src/ExNavigationStack.js b/src/ExNavigationStack.js index f78e158..130ad14 100644 --- a/src/ExNavigationStack.js +++ b/src/ExNavigationStack.js @@ -11,21 +11,21 @@ import _ from 'lodash'; import invariant from 'invariant'; import cloneReferencedElement from 'react-clone-referenced-element'; import PureComponent from './utils/PureComponent'; -import { debounce } from 'core-decorators'; +import {debounce} from 'core-decorators'; import Actions from './ExNavigationActions'; import NavigationBar from './ExNavigationBar'; import NavigationItem from './ExNavigationStackItem'; -import { getBackButtonManager } from './ExNavigationBackButtonManager'; -import { createNavigatorComponent } from './ExNavigationComponents'; +import {getBackButtonManager} from './ExNavigationBackButtonManager'; +import {createNavigatorComponent} from './ExNavigationComponents'; import ExNavigatorContext from './ExNavigatorContext'; import ExNavigationAlertBar from './ExNavigationAlertBar'; import * as NavigationStyles from './ExNavigationStyles'; import SharedElementGroup from './shared-element/ExNavigationSharedElementGroup'; -const { Transitioner: NavigationTransitioner } = NavigationExperimental; +const {Transitioner: NavigationTransitioner} = NavigationExperimental; import type { NavigationSceneRendererProps, @@ -37,8 +37,8 @@ import type { ExNavigationRouter, } from './ExNavigationRouter'; import type ExNavigationContext from './ExNavigationContext'; -import type { ExNavigationConfig } from './ExNavigationTypeDefinition'; -import type { ExNavigationTabContext } from './tab/ExNavigationTab'; +import type {ExNavigationConfig} from './ExNavigationTypeDefinition'; +import type {ExNavigationTabContext} from './tab/ExNavigationTab'; const DEFAULT_ROUTE_CONFIG: ExNavigationConfig = { styles: Platform.OS === 'ios' @@ -51,10 +51,8 @@ const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? DEFAULT_STATUSBAR_HEIGHT : global.__exponent ? DEFAULT_STATUSBAR_HEIGHT : 0; -type TransitionFn = ( - transitionProps: NavigationTransitionProps, - prevTransitionProps: NavigationTransitionProps -) => void; +type TransitionFn = (transitionProps: NavigationTransitionProps, + prevTransitionProps: NavigationTransitionProps) => void; type Props = { augmentScene?: (scene: ReactElement, route: Object) => ReactElement, @@ -65,16 +63,12 @@ type Props = { navigation: ExNavigationContext, navigationState?: Object, navigatorUID: string, - onRegisterNavigatorContext: ( - navigatorUID: string, - navigatorContext: ExNavigationStackContext - ) => void, + onRegisterNavigatorContext: (navigatorUID: string, + navigatorContext: ExNavigationStackContext) => void, onUnregisterNavigatorContext: (navigatorUID: string) => void, onTransitionStart: ?TransitionFn, onTransitionEnd: ?TransitionFn, - renderScene?: ( - props: StackNavigationSceneRendererProps - ) => ?React.Element<{}>, + renderScene?: (props: StackNavigationSceneRendererProps) => ?React.Element<{}>, }; type State = { @@ -120,13 +114,11 @@ export class ExNavigationStackContext extends ExNavigatorContext { componentInstance: ExNavigationStackInstance; _getNavigatorState: any; - constructor( - navigatorUID: string, - parentNavigatorUID: string, - navigatorId: string, - navigationContext: ExNavigationContext, - componentInstance: ExNavigationStackInstance - ) { + constructor(navigatorUID: string, + parentNavigatorUID: string, + navigatorId: string, + navigationContext: ExNavigationContext, + componentInstance: ExNavigationStackInstance) { super(navigatorUID, parentNavigatorUID, navigatorId, navigationContext); this.navigatorUID = navigatorUID; this.parentNavigatorUID = parentNavigatorUID; @@ -140,11 +132,9 @@ export class ExNavigationStackContext extends ExNavigatorContext { } @debounce(500, true) - push( - route: ExNavigationRoute | string, - paramsOrOptions?: Object | TransitionOptions, - options?: TransitionOptions - ) { + push(route: ExNavigationRoute | string, + paramsOrOptions?: Object | TransitionOptions, + options?: TransitionOptions) { if (typeof route == 'string') { route = this.router.getRoute(route, paramsOrOptions); } else { @@ -160,21 +150,21 @@ export class ExNavigationStackContext extends ExNavigatorContext { ); } - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).push(route); }); } @debounce(500, true) pop(n: number = 1) { - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).pop(n); }); } @debounce(500, true) popToTop() { - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).popToTop(); }); } @@ -188,7 +178,7 @@ export class ExNavigationStackContext extends ExNavigatorContext { invariant(route !== null && route.key, 'Route is null or malformed.'); this.componentInstance._useAnimation = false; - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).replace(route); }); requestAnimationFrame(() => { @@ -225,7 +215,7 @@ export class ExNavigationStackContext extends ExNavigatorContext { immediatelyResetStack(routes: Array, index: number = 0) { this.componentInstance._useAnimation = false; - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).immediatelyResetStack(routes, index); }); @@ -235,19 +225,19 @@ export class ExNavigationStackContext extends ExNavigatorContext { } showLocalAlert = (message: string, options: mixed) => { - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).showLocalAlert(message, options); }); }; hideLocalAlert = () => { - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).hideLocalAlert(); }); }; updateCurrentRouteParams(newParams: Object) { - this.navigationContext.performAction(({ stacks }) => { + this.navigationContext.performAction(({stacks}) => { stacks(this.navigatorUID).updateCurrentRouteParams(newParams); }); } @@ -269,8 +259,10 @@ class ExNavigationStack extends PureComponent { static defaultProps = { defaultRouteConfig: DEFAULT_ROUTE_CONFIG, - onTransitionEnd: () => {}, - onTransitionStart: () => {}, + onTransitionEnd: () => { + }, + onTransitionStart: () => { + }, }; static contextTypes = { @@ -292,9 +284,9 @@ class ExNavigationStack extends PureComponent { navigator: this._getNavigatorContext(), parentNavigatorUID: this.state.navigatorUID, headerComponent: this.props.headerComponent || - this.context.headerComponent, + this.context.headerComponent, alertBarComponent: this.props.alertBarComponent || - this.context.alertBarComponent, + this.context.alertBarComponent, }; } @@ -335,8 +327,8 @@ class ExNavigationStack extends PureComponent { componentWillMount() { this._registerNavigatorContext(); - const { initialStack } = this.props; - let { initialRoute } = this.props; + const {initialStack} = this.props; + let {initialRoute} = this.props; invariant( initialRoute || initialStack, @@ -441,7 +433,7 @@ class ExNavigationStack extends PureComponent { const latestRoute = transitionProps.scenes[transitionProps.scenes.length - 1].route; const latestRouteConfig = latestRoute.config; - const { configureTransition } = latestRouteConfig.styles || {}; + const {configureTransition} = latestRouteConfig.styles || {}; if (typeof configureTransition === 'function') { return configureTransition(transitionProps, prevTransitionProps); @@ -494,14 +486,33 @@ class ExNavigationStack extends PureComponent { ); }; + _getStatusBarHeight(latestRouteConfig) { + let height = STATUSBAR_HEIGHT; + + if (latestRouteConfig.navigationBar && latestRouteConfig.navigationBar.height) { + if (typeof latestRouteConfig.navigationBar.height === 'function') { + height = latestRouteConfig.navigationBar.height(); + } else { + height = latestRouteConfig.navigationBar.height; + } + } + + if (latestRouteConfig.statusBar && latestRouteConfig.statusBar.translucent) { + height = DEFAULT_STATUSBAR_HEIGHT; + } + + return height; + } + _getNavigationBarHeight(latestRouteConfig) { let height = NavigationBar.DEFAULT_HEIGHT; - if ( - latestRouteConfig.navigationBar && latestRouteConfig.navigationBar.height - ) { - height = - latestRouteConfig.navigationBar.height + DEFAULT_STATUSBAR_HEIGHT; + if (latestRouteConfig.navigationBar && latestRouteConfig.navigationBar.height) { + if (typeof latestRouteConfig.navigationBar.height === 'function') { + height = latestRouteConfig.navigationBar.height() + DEFAULT_STATUSBAR_HEIGHT; + } else { + height = latestRouteConfig.navigationBar.height + DEFAULT_STATUSBAR_HEIGHT; + } } if ( @@ -543,7 +554,7 @@ class ExNavigationStack extends PureComponent { { ); const latestRouteConfig: ExNavigationConfig = latestRoute.config; - props = { ...props, latestRouteConfig, latestRoute }; + props = {...props, latestRouteConfig, latestRoute}; if (typeof this.props.renderOverlay === 'function') { return this.props.renderOverlay(props); @@ -587,12 +598,7 @@ class ExNavigationStack extends PureComponent { latestRouteConfig.navigationBar.visible !== false; // pass the statusBarHeight to headerComponent if statusBar is translucent - let statusBarHeight = STATUSBAR_HEIGHT; - if ( - latestRouteConfig.statusBar && latestRouteConfig.statusBar.translucent - ) { - statusBarHeight = DEFAULT_STATUSBAR_HEIGHT; - } + let statusBarHeight = this._getStatusBarHeight(latestRouteConfig); // TODO: add height here return ( @@ -633,7 +639,7 @@ class ExNavigationStack extends PureComponent { _renderBackgroundComponentForHeader = props => { //eslint-disable-line react/display-name - const { scene: { route } } = props; + const {scene: {route}} = props; const routeConfig = route.config; if ( @@ -655,7 +661,7 @@ class ExNavigationStack extends PureComponent { _renderLeftComponentForHeader = props => { //eslint-disable-line react/display-name - const { scene: { route } } = props; + const {scene: {route}} = props; const routeConfig = route.config; if ( @@ -680,7 +686,7 @@ class ExNavigationStack extends PureComponent { } if (props.scene.index > 0) { - return ; + return ; } return null; @@ -707,7 +713,7 @@ class ExNavigationStack extends PureComponent { _renderTitleComponentForHeader = props => { //eslint-disable-line react/display-name - const { scene: { route } } = props; + const {scene: {route}} = props; const routeConfig = route.config; if ( routeConfig.navigationBar && @@ -725,7 +731,7 @@ class ExNavigationStack extends PureComponent { }; _renderRightComponentForHeader = props => { - const { scene: { route } } = props; + const {scene: {route}} = props; const routeConfig = route.config; if ( @@ -761,7 +767,7 @@ class ExNavigationStack extends PureComponent { ); const latestRouteConfig = latestRoute.config; - const { sceneAnimations, gestures } = latestRouteConfig.styles || {}; + const {sceneAnimations, gestures} = latestRouteConfig.styles || {}; const scene: any = props.scene; const routeForScene = scene.route; @@ -815,15 +821,13 @@ class ExNavigationStack extends PureComponent { } if (hasCustomHeight) { - style = ([...style, { marginTop: customHeight }]: Array< - number | Object - >); + style = ([...style, {marginTop: customHeight}]: Array); } else { style = [ ...style, isTranslucent ? styles.withNavigationBarTranslucent - : { paddingTop: this._getNavigationBarHeight(routeConfig) }, + : {paddingTop: this._getNavigationBarHeight(routeConfig)}, ]; } } else { @@ -837,7 +841,7 @@ class ExNavigationStack extends PureComponent { return ( - + {cloneReferencedElement(routeElement, routeElementProps)} @@ -846,7 +850,7 @@ class ExNavigationStack extends PureComponent { }; _onTransitionStart = (transitionProps, prevTransitionProps) => { - const { route: nextRoute } = transitionProps.scene; + const {route: nextRoute} = transitionProps.scene; const nextRouteConfig = nextRoute.config; if (nextRouteConfig.styles && nextRouteConfig.styles.onTransitionStart) { @@ -857,7 +861,7 @@ class ExNavigationStack extends PureComponent { } if (prevTransitionProps) { - const { route: prevRoute } = prevTransitionProps.scene; + const {route: prevRoute} = prevTransitionProps.scene; const prevRouteConfg = prevRoute.config; if (prevRouteConfg.styles && prevRouteConfg.styles.onTransitionStart) { prevRouteConfg.styles.onTransitionStart( @@ -873,7 +877,7 @@ class ExNavigationStack extends PureComponent { }; _onTransitionEnd = (transitionProps, prevTransitionProps) => { - const { route: nextRoute } = transitionProps.scene; + const {route: nextRoute} = transitionProps.scene; const nextRouteConfig = nextRoute.config; if (nextRouteConfig.styles && nextRouteConfig.styles.onTransitionEnd) { @@ -884,7 +888,7 @@ class ExNavigationStack extends PureComponent { } if (prevTransitionProps) { - const { route: prevRoute } = prevTransitionProps.scene; + const {route: prevRoute} = prevTransitionProps.scene; const prevRouteConfg = prevRoute.config; if (prevRouteConfg.styles && prevRouteConfg.styles.onTransitionEnd) { prevRouteConfg.styles.onTransitionEnd( @@ -899,10 +903,8 @@ class ExNavigationStack extends PureComponent { } }; - _getRouteAtIndex( - scenes: Array, - index: number - ): ExNavigationRoute { + _getRouteAtIndex(scenes: Array, + index: number): ExNavigationRoute { const scene: any = scenes[index]; const latestRoute: ExNavigationRoute = scene.route; return latestRoute; From b1314e52ef0d2fe9b83c304ec8ccb3128b6e3fae Mon Sep 17 00:00:00 2001 From: Joshua Baker Date: Tue, 11 Apr 2017 13:11:02 -0700 Subject: [PATCH 2/2] Fix status bar height --- src/ExNavigationStack.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ExNavigationStack.js b/src/ExNavigationStack.js index 130ad14..5b57d14 100644 --- a/src/ExNavigationStack.js +++ b/src/ExNavigationStack.js @@ -488,19 +488,9 @@ class ExNavigationStack extends PureComponent { _getStatusBarHeight(latestRouteConfig) { let height = STATUSBAR_HEIGHT; - - if (latestRouteConfig.navigationBar && latestRouteConfig.navigationBar.height) { - if (typeof latestRouteConfig.navigationBar.height === 'function') { - height = latestRouteConfig.navigationBar.height(); - } else { - height = latestRouteConfig.navigationBar.height; - } - } - if (latestRouteConfig.statusBar && latestRouteConfig.statusBar.translucent) { height = DEFAULT_STATUSBAR_HEIGHT; } - return height; }