From 282cfe538bbc2fb5ec2a872228c510318fcb19fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Czaj=C4=99cki?= Date: Sat, 6 Jul 2019 12:41:34 +0200 Subject: [PATCH] feat: allow specifying style interpolators in navigationOptions (#155) --- packages/stack/src/types.tsx | 31 ++++++------ packages/stack/src/views/Stack/Stack.tsx | 53 ++++++++++++-------- packages/stack/src/views/Stack/StackItem.tsx | 22 +++----- packages/stack/src/views/Stack/StackView.tsx | 19 +------ 4 files changed, 56 insertions(+), 69 deletions(-) diff --git a/packages/stack/src/types.tsx b/packages/stack/src/types.tsx index 256cc7e9..c7716cf3 100644 --- a/packages/stack/src/types.tsx +++ b/packages/stack/src/types.tsx @@ -93,23 +93,24 @@ export type HeaderProps = { styleInterpolator: HeaderStyleInterpolator; }; -export type NavigationStackOptions = HeaderOptions & { - title?: string; - header?: null | ((props: HeaderProps) => React.ReactNode); - cardShadowEnabled?: boolean; - cardOverlayEnabled?: boolean; - cardTransparent?: boolean; - cardStyle?: StyleProp; - animationEnabled?: boolean; - gesturesEnabled?: boolean; - gestureResponseDistance?: { - vertical?: number; - horizontal?: number; +export type NavigationStackOptions = HeaderOptions & + Partial & { + title?: string; + header?: null | ((props: HeaderProps) => React.ReactNode); + cardShadowEnabled?: boolean; + cardOverlayEnabled?: boolean; + cardTransparent?: boolean; + cardStyle?: StyleProp; + animationEnabled?: boolean; + gesturesEnabled?: boolean; + gestureResponseDistance?: { + vertical?: number; + horizontal?: number; + }; + disableKeyboardHandling?: boolean; }; - disableKeyboardHandling?: boolean; -}; -export type NavigationConfig = TransitionPreset & { +export type NavigationConfig = { mode: 'card' | 'modal'; headerMode: HeaderMode; }; diff --git a/packages/stack/src/views/Stack/Stack.tsx b/packages/stack/src/views/Stack/Stack.tsx index 1f4a12ac..0bbfbcd3 100755 --- a/packages/stack/src/views/Stack/Stack.tsx +++ b/packages/stack/src/views/Stack/Stack.tsx @@ -11,14 +11,15 @@ import { ScreenContainer, NativeScreen } from 'react-native-screens'; import { getDefaultHeaderHeight } from '../Header/HeaderSegment'; import { Props as HeaderContainerProps } from '../Header/HeaderContainer'; import StackItem from './StackItem'; +import { + DefaultTransition, + ModalSlideFromBottomIOS, +} from '../../TransitionConfigs/TransitionPresets'; +import { forNoAnimation } from '../../TransitionConfigs/HeaderStyleInterpolators'; import { Route, Layout, - TransitionSpec, - CardStyleInterpolator, - HeaderStyleInterpolator, HeaderMode, - GestureDirection, SceneDescriptor, NavigationProp, HeaderScene, @@ -29,6 +30,7 @@ type ProgressValues = { }; type Props = { + mode: 'card' | 'modal'; navigation: NavigationProp; descriptors: { [key: string]: SceneDescriptor }; routes: Route[]; @@ -42,7 +44,6 @@ type Props = { renderHeader: (props: HeaderContainerProps) => React.ReactNode; renderScene: (props: { route: Route }) => React.ReactNode; headerMode: HeaderMode; - direction: GestureDirection; onTransitionStart?: ( curr: { index: number }, prev: { index: number } @@ -50,12 +51,6 @@ type Props = { onGestureBegin?: () => void; onGestureCanceled?: () => void; onGestureEnd?: () => void; - transitionSpec: { - open: TransitionSpec; - close: TransitionSpec; - }; - cardStyleInterpolator: CardStyleInterpolator; - headerStyleInterpolator: HeaderStyleInterpolator; }; type State = { @@ -187,6 +182,7 @@ export default class Stack extends React.Component { render() { const { + mode, descriptors, navigation, routes, @@ -199,18 +195,28 @@ export default class Stack extends React.Component { renderHeader, renderScene, headerMode, - direction, onTransitionStart, onGestureBegin, onGestureCanceled, onGestureEnd, - transitionSpec, - cardStyleInterpolator, - headerStyleInterpolator, } = this.props; const { scenes, layout, progress, floaingHeaderHeight } = this.state; + const focusedRoute = navigation.state.routes[navigation.state.index]; + const focusedOptions = descriptors[focusedRoute.key].options; + + let defaultTransitionPreset = + mode === 'modal' && Platform.OS === 'ios' + ? ModalSlideFromBottomIOS + : DefaultTransition; + + if (headerMode === 'screen') { + defaultTransitionPreset = { + ...defaultTransitionPreset, + headerStyleInterpolator: forNoAnimation, + }; + } return ( @@ -242,6 +248,10 @@ export default class Stack extends React.Component { cardOverlayEnabled, cardStyle, gestureResponseDistance, + direction = defaultTransitionPreset.direction, + transitionSpec = defaultTransitionPreset.transitionSpec, + cardStyleInterpolator = defaultTransitionPreset.cardStyleInterpolator, + headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator, } = descriptor.options; return ( @@ -261,7 +271,6 @@ export default class Stack extends React.Component { scene={scene} previousScene={scenes[index - 1]} navigation={navigation} - direction={direction} cardTransparent={cardTransparent} cardOverlayEnabled={cardOverlayEnabled} cardShadowEnabled={cardShadowEnabled} @@ -271,9 +280,6 @@ export default class Stack extends React.Component { onGestureCanceled={onGestureCanceled} onGestureEnd={onGestureEnd} gestureResponseDistance={gestureResponseDistance} - transitionSpec={transitionSpec} - headerStyleInterpolator={headerStyleInterpolator} - cardStyleInterpolator={cardStyleInterpolator} floaingHeaderHeight={floaingHeaderHeight} hasCustomHeader={header === null} getPreviousRoute={getPreviousRoute} @@ -285,6 +291,10 @@ export default class Stack extends React.Component { onCloseRoute={onCloseRoute} onTransitionStart={onTransitionStart} onGoBack={onGoBack} + direction={direction} + transitionSpec={transitionSpec} + cardStyleInterpolator={cardStyleInterpolator} + headerStyleInterpolator={headerStyleInterpolator} /> ); @@ -298,7 +308,10 @@ export default class Stack extends React.Component { navigation, getPreviousRoute, onLayout: this.handleFloatingHeaderLayout, - styleInterpolator: headerStyleInterpolator, + styleInterpolator: + focusedOptions.headerStyleInterpolator !== undefined + ? focusedOptions.headerStyleInterpolator + : defaultTransitionPreset.headerStyleInterpolator, style: [styles.header, styles.floating], }) : null} diff --git a/packages/stack/src/views/Stack/StackItem.tsx b/packages/stack/src/views/Stack/StackItem.tsx index 0781d383..af3cced0 100644 --- a/packages/stack/src/views/Stack/StackItem.tsx +++ b/packages/stack/src/views/Stack/StackItem.tsx @@ -6,16 +6,13 @@ import Card from './Card'; import { Route, HeaderScene, - GestureDirection, Layout, - TransitionSpec, - CardStyleInterpolator, HeaderMode, NavigationProp, - HeaderStyleInterpolator, + TransitionPreset, } from '../../types'; -type Props = { +type Props = TransitionPreset & { index: number; active: boolean; focused: boolean; @@ -30,7 +27,6 @@ type Props = { cardShadowEnabled?: boolean; cardStyle?: StyleProp; gesturesEnabled?: boolean; - direction: GestureDirection; getPreviousRoute: (props: { route: Route }) => Route | undefined; renderHeader: (props: HeaderContainerProps) => React.ReactNode; renderScene: (props: { route: Route }) => React.ReactNode; @@ -48,12 +44,6 @@ type Props = { vertical?: number; horizontal?: number; }; - transitionSpec: { - open: TransitionSpec; - close: TransitionSpec; - }; - headerStyleInterpolator: HeaderStyleInterpolator; - cardStyleInterpolator: CardStyleInterpolator; headerMode: HeaderMode; headerTransparent?: boolean; floaingHeaderHeight: number; @@ -87,7 +77,6 @@ export default class StackItem extends React.PureComponent { navigation, scene, previousScene, - direction, cardTransparent, cardOverlayEnabled, cardShadowEnabled, @@ -97,9 +86,6 @@ export default class StackItem extends React.PureComponent { onGestureCanceled, onGestureEnd, gestureResponseDistance, - transitionSpec, - headerStyleInterpolator, - cardStyleInterpolator, floaingHeaderHeight, hasCustomHeader, getPreviousRoute, @@ -107,6 +93,10 @@ export default class StackItem extends React.PureComponent { headerTransparent, renderHeader, renderScene, + direction, + transitionSpec, + cardStyleInterpolator, + headerStyleInterpolator, } = this.props; return ( diff --git a/packages/stack/src/views/Stack/StackView.tsx b/packages/stack/src/views/Stack/StackView.tsx index 5b5143bc..928ecee7 100644 --- a/packages/stack/src/views/Stack/StackView.tsx +++ b/packages/stack/src/views/Stack/StackView.tsx @@ -5,11 +5,6 @@ import Stack from './Stack'; import HeaderContainer, { Props as HeaderContainerProps, } from '../Header/HeaderContainer'; -import { - DefaultTransition, - ModalSlideFromBottomIOS, -} from '../../TransitionConfigs/TransitionPresets'; -import { forNoAnimation } from '../../TransitionConfigs/HeaderStyleInterpolators'; import { NavigationProp, SceneDescriptor, @@ -283,20 +278,9 @@ class StackView extends React.Component { const headerMode = mode !== 'modal' && Platform.OS === 'ios' ? 'float' : 'screen'; - let transitionPreset = - mode === 'modal' && Platform.OS === 'ios' - ? ModalSlideFromBottomIOS - : DefaultTransition; - - if (headerMode === 'screen') { - transitionPreset = { - ...transitionPreset, - headerStyleInterpolator: forNoAnimation, - }; - } - return ( { headerMode={headerMode} navigation={navigation} descriptors={descriptors} - {...transitionPreset} {...config} /> );