From bc24e50bc1d814d64f05880583cf515b03ca7086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Magrin?= Date: Mon, 21 May 2018 11:53:22 +0200 Subject: [PATCH] Change type definition for v2 --- types/react-navigation/index.d.ts | 477 +++----- types/react-navigation/v2/index.d.ts | 1086 +++++++++++++++++ .../v2/react-navigation-tests.tsx | 453 +++++++ types/react-navigation/v2/tsconfig.json | 30 + types/react-navigation/v2/tslint.json | 1 + 5 files changed, 1744 insertions(+), 303 deletions(-) create mode 100644 types/react-navigation/v2/index.d.ts create mode 100644 types/react-navigation/v2/react-navigation-tests.tsx create mode 100644 types/react-navigation/v2/tsconfig.json create mode 100644 types/react-navigation/v2/tslint.json diff --git a/types/react-navigation/index.d.ts b/types/react-navigation/index.d.ts index 641dd8463f..1233ca39e3 100644 --- a/types/react-navigation/index.d.ts +++ b/types/react-navigation/index.d.ts @@ -1,4 +1,4 @@ -// Type definitions for react-navigation 2.0.1 +// Type definitions for react-navigation 1.5 // Project: https://github.com/react-navigation/react-navigation // Definitions by: Huhuanming // mhcgrq @@ -16,12 +16,11 @@ // Armando Assuncao // Ciaran Liedeman // Edward Sammut Alessi -// Jeremy Magrin // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.6 /** - * Reference: https://github.com/react-navigation/react-navigation/tree/a37473c5e4833f48796ee6c7c9cb4a8ac49d9c06 + * Reference: https://github.com/react-navigation/react-navigation/tree/3f3ef6485c8932f49fddc3dd2c508629110bf2b6 * * NOTE: Please update the commit/link above when updating to a new Flow * react-navigation/flow/react-navigation.js reference, so we can conveniently just look at diffs on @@ -44,21 +43,15 @@ export type AnimatedValue = any; export type HeaderMode = 'float' | 'screen' | 'none'; -export interface HeaderForceInset { - horizontal?: string; - vertical?: string, - left?: string, - right?: string, - top?: string, - bottom?: string, -} - export interface HeaderProps extends NavigationSceneRendererProps { mode: HeaderMode; - router: NavigationRouter; - getScreenDetails: ( - navigationScene: NavigationScene - ) => NavigationScreenDetails; + router: NavigationRouter< + NavigationState, + NavigationStackScreenOptions + >; + getScreenDetails: (navigationScene: NavigationScene) => NavigationScreenDetails< + NavigationStackScreenOptions + >; style: StyleProp; } @@ -83,9 +76,7 @@ export interface NavigationState { routes: any[]; } -export type NavigationRoute = - | NavigationLeafRoute - | NavigationStateRoute; +export type NavigationRoute = NavigationLeafRoute | NavigationStateRoute; export interface NavigationLeafRoute { /** @@ -109,9 +100,7 @@ export interface NavigationLeafRoute { params?: Params; } -export type NavigationStateRoute< - NavigationLeafRouteParams - > = NavigationLeafRoute & NavigationState; +export type NavigationStateRoute = NavigationLeafRoute & NavigationState; export type NavigationScreenOptionsGetter = ( navigation: NavigationScreenProp>, @@ -124,10 +113,7 @@ export interface NavigationRouter { * an optional previous state. When the action is considered handled but the * state is unchanged, the output state is null. */ - getStateForAction: ( - action: NavigationAction, - lastState?: State - ) => State | null; + getStateForAction: (action: NavigationAction, lastState?: State) => (State | null); /** * Maps a URI-like string to an action. This can be mapped to a state @@ -136,14 +122,14 @@ export interface NavigationRouter { getActionForPathAndParams: ( path: string, params?: NavigationParams - ) => NavigationAction | null; + ) => (NavigationAction | null); getPathAndParamsForState: ( state: State ) => { - path: string; - params?: NavigationParams; - }; + path: string, + params?: NavigationParams, + }; getComponentForRouteName: (routeName: string) => NavigationComponent; @@ -161,8 +147,11 @@ export interface NavigationRouter { } export type NavigationScreenOption = - | T - | ((navigation: NavigationScreenProp, config: T) => T); + T + | (( + navigation: NavigationScreenProp, + config: T + ) => T); export interface NavigationScreenDetails { options: T; @@ -170,9 +159,7 @@ export interface NavigationScreenDetails { navigation: NavigationScreenProp; } -export type NavigationScreenOptions = NavigationStackScreenOptions & - NavigationTabScreenOptions & - NavigationDrawerScreenOptions; +export type NavigationScreenOptions = NavigationStackScreenOptions & NavigationTabScreenOptions & NavigationDrawerScreenOptions; export interface NavigationScreenConfigProps { navigation: NavigationScreenProp; @@ -180,34 +167,30 @@ export interface NavigationScreenConfigProps { } export type NavigationScreenConfig = - | Options - | (( - navigationOptionsContainer: NavigationScreenConfigProps & { - navigationOptions: NavigationScreenProp; - } - ) => Options); + Options + | ((navigationOptionsContainer: NavigationScreenConfigProps & { + navigationOptions: NavigationScreenProp, + }) => Options); export type NavigationComponent = - | NavigationScreenComponent - | NavigationNavigator - | any; + NavigationScreenComponent + | NavigationNavigator; export type NavigationScreenComponent< - Params = NavigationParams, - Options = {}, - Props = {} - > = React.ComponentType & Props> & { - navigationOptions?: NavigationScreenConfig; - }; + Params = NavigationParams, + Options = {}, + Props = {} +> = React.ComponentType & Props> & +{ navigationOptions?: NavigationScreenConfig }; export type NavigationNavigator< - State = NavigationState, - Options = {}, - Props = {} - > = React.ComponentType & Props> & { - router: NavigationRouter; - navigationOptions?: NavigationScreenConfig; - }; + State = NavigationState, + Options = {}, + Props = {} +> = React.ComponentType & Props> & { + router: NavigationRouter, + navigationOptions?: NavigationScreenConfig, +}; export interface NavigationParams { [key: string]: any; @@ -223,8 +206,7 @@ export interface NavigationNavigateActionPayload { key?: string; } -export interface NavigationNavigateAction - extends NavigationNavigateActionPayload { +export interface NavigationNavigateAction extends NavigationNavigateActionPayload { type: 'Navigation/NAVIGATE'; } @@ -244,8 +226,7 @@ export interface NavigationSetParamsActionPayload { params?: NavigationParams; } -export interface NavigationSetParamsAction - extends NavigationSetParamsActionPayload { +export interface NavigationSetParamsAction extends NavigationSetParamsActionPayload { type: 'Navigation/SET_PARAMS'; } @@ -290,69 +271,40 @@ export interface NavigationPopToTopActionPayload { immediate?: boolean; } -export interface NavigationPopToTopAction - extends NavigationPopToTopActionPayload { +export interface NavigationPopToTopAction extends NavigationPopToTopActionPayload { type: 'Navigation/POP_TO_TOP'; } export interface NavigationStackViewConfig { mode?: 'card' | 'modal'; headerMode?: HeaderMode; - headerTransitionPreset?: 'fade-in-place' | 'uikit'; cardStyle?: StyleProp; transitionConfig?: ( transitionProps: NavigationTransitionProps, prevTransitionProps: NavigationTransitionProps, - isModal: boolean + isModal: boolean, ) => TransitionConfig; - onTransitionStart?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps?: NavigationTransitionProps - ) => Promise | void; - onTransitionEnd?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps?: NavigationTransitionProps - ) => void; -} - -/** - * Switch Navigator - */ - -export interface NavigationSwitchRouterConfig { - initialRouteName?: string; - initialRouteParams?: NavigationParams; - paths?: NavigationPathsConfig; - navigationOptions?: NavigationScreenConfig; - order?: string[]; - backBehavior?: 'none' | 'initialRoute'; // defaults to `'none'` - resetOnBlur?: boolean; // defaults to `true` + onTransitionStart?: (transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps) => Promise | void; + onTransitionEnd?: (transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps) => void; } export interface NavigationStackScreenOptions { title?: string; - header?: - | ( - | React.ReactElement - | ((headerProps: HeaderProps) => React.ReactElement)) - | null; + header?: (React.ReactElement | ((headerProps: HeaderProps) => React.ReactElement)) | null; headerTransparent?: boolean; headerTitle?: string | React.ReactElement; headerTitleStyle?: StyleProp; headerTintColor?: string; headerLeft?: React.ReactElement; headerBackTitle?: string | null; - headerBackImage?: React.ReactElement; headerTruncatedBackTitle?: string; headerBackTitleStyle?: StyleProp; headerPressColorAndroid?: string; headerRight?: React.ReactElement; headerStyle?: StyleProp; - headerForceInset?: HeaderForceInset; headerBackground?: React.ReactNode | React.ReactType; gesturesEnabled?: boolean; gestureResponseDistance?: { vertical?: number; horizontal?: number }; - gestureDirection?: 'default' | 'inverted'; } export interface NavigationStackRouterConfig { @@ -365,7 +317,7 @@ export interface NavigationStackRouterConfig { } export type NavigationStackAction = - | NavigationInitAction + NavigationInitAction | NavigationNavigateAction | NavigationBackAction | NavigationSetParamsAction @@ -374,30 +326,25 @@ export type NavigationStackAction = | NavigationPopToTopAction; export type NavigationTabAction = - | NavigationInitAction + NavigationInitAction | NavigationNavigateAction | NavigationBackAction; export type NavigationAction = - | NavigationInitAction + NavigationInitAction | NavigationStackAction | NavigationTabAction; -export type NavigationRouteConfig = - | NavigationComponent - | ({ - navigationOptions?: NavigationScreenConfig; - path?: string; - } & NavigationScreenRouteConfig); +export type NavigationRouteConfig = NavigationComponent | ({ + navigationOptions?: NavigationScreenConfig, + path?: string, +} & NavigationScreenRouteConfig); -export type NavigationScreenRouteConfig = - | NavigationComponent - | { - screen: NavigationComponent; - } - | { - getScreen: () => NavigationComponent; - }; +export type NavigationScreenRouteConfig = NavigationComponent | { + screen: NavigationComponent, +} | { + getScreen: () => NavigationComponent, +}; export interface NavigationPathsConfig { [routeName: string]: string; @@ -413,48 +360,45 @@ export interface NavigationTabRouterConfig { backBehavior?: 'none' | 'initialRoute'; // defaults `initialRoute` } export interface TabScene { - route: NavigationRoute; - focused: boolean; - index: number; - tintColor?: string; + route: NavigationRoute; + focused: boolean; + index: number; + tintColor?: string; } export interface NavigationTabScreenOptions { title?: string; tabBarIcon?: - | React.ReactElement - | (( - options: { tintColor: string | null; focused: boolean } - ) => React.ReactElement | null); + React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)); tabBarLabel?: - | string - | React.ReactElement - | (( - options: { tintColor: string | null; focused: boolean } - ) => React.ReactElement | string | null); + string + | React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | string | null)); tabBarVisible?: boolean; - tabBarTestIDProps?: { testID?: string; accessibilityLabel?: string }; - tabBarOnPress?: ( - options: { - scene: TabScene; - jumpToIndex: (index: number) => void; - } - ) => void; + tabBarTestIDProps?: { testID?: string, accessibilityLabel?: string }; + tabBarOnPress?: (options: { + scene: TabScene, + jumpToIndex: (index: number) => void + }) => void; } export interface NavigationDrawerScreenOptions { title?: string; drawerIcon?: - | React.ReactElement - | (( - options: { tintColor: string | null; focused: boolean } - ) => React.ReactElement | null); + React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)); drawerLabel?: - | string - | React.ReactElement - | (( - options: { tintColor: string | null; focused: boolean } - ) => React.ReactElement | null); - drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open'; + string + | React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)); } export interface NavigationRouteConfigMap { @@ -469,20 +413,22 @@ export interface NavigationProp { } export type EventType = - | 'willFocus' - | 'didFocus' - | 'willBlur' - | 'didBlur' - | 'action'; +| 'willFocus' +| 'didFocus' +| 'willBlur' +| 'didBlur' +| 'action'; export interface NavigationEventPayload { type: EventType; action: NavigationAction; state: NavigationState; - lastState: NavigationState | null | undefined; + lastState: NavigationState; } -export type NavigationEventCallback = (payload: NavigationEventPayload) => void; +export type NavigationEventCallback = ( + payload: NavigationEventPayload +) => void; export interface NavigationEventSubscription { remove: () => void; @@ -492,14 +438,8 @@ export interface NavigationScreenProp { state: S; dispatch: NavigationDispatch; goBack: (routeKey?: string | null) => boolean; - dismiss: () => boolean; navigate(options: { - routeName: string | { - routeName: string; - params?: NavigationParams; - action?: NavigationNavigateAction; - key?: string; - }; + routeName: string; params?: NavigationParams; action?: NavigationAction; key?: string; @@ -507,7 +447,7 @@ export interface NavigationScreenProp { navigate( routeNameOrOptions: string, params?: NavigationParams, - action?: NavigationAction + action?: NavigationAction, ): boolean; getParam: (param: T, fallback?: P[T]) => P[T]; setParams: (newParams: P) => boolean; @@ -527,7 +467,6 @@ export interface NavigationScreenProp { ) => boolean; pop: (n?: number, params?: { immediate?: boolean }) => boolean; popToTop: (params?: { immediate?: boolean }) => boolean; - isFocused: () => boolean; } export interface NavigationNavigatorProps { @@ -619,7 +558,7 @@ export type NavigationAnimationSetter = ( lastState: NavigationState ) => void; -export type NavigationSceneRenderer = () => React.ReactElement | null; +export type NavigationSceneRenderer = () => (React.ReactElement | null); export type NavigationStyleInterpolator = ( props: NavigationSceneRendererProps @@ -628,49 +567,50 @@ export type NavigationStyleInterpolator = ( export interface LayoutEvent { nativeEvent: { layout: { - x: number; - y: number; - width: number; - height: number; - }; + x: number, + y: number, + width: number, + height: number, + }, }; } export type NavigatorType = - | 'react-navigation/STACK' - | 'react-navigation/TABS' - | 'react-navigation/DRAWER'; +| 'react-navigation/STACK' +| 'react-navigation/TABS' +| 'react-navigation/DRAWER'; -export interface NavigationContainerProps { +export function addNavigationHelpers( + navigation: { + state: S; + dispatch: (action: NavigationAction) => any; + addListener?: ( + eventName: string, + callback: NavigationEventCallback + ) => NavigationEventSubscription; + } +): NavigationScreenProp; + +export interface NavigationContainerProps { uriPrefix?: string | RegExp; onNavigationStateChange?: ( prevNavigationState: NavigationState, nextNavigationState: NavigationState, - action: NavigationAction - ) => void | null | undefined; - navigation?: NavigationScreenProp; - persistenceKey?: string | null | undefined; - renderLoadingExperimental?: React.ComponentType<{}>, - screenProps?: any; - navigationOptions?: O; + action: NavigationAction, + ) => void; style?: StyleProp; } -export interface NavigationContainerComponent - extends React.Component< +export interface NavigationContainerComponent extends React.Component< NavigationContainerProps & NavigationNavigatorProps > { dispatch: NavigationDispatch; } -export interface NavigationContainer - extends React.ComponentClass< +export interface NavigationContainer extends React.ComponentClass< NavigationContainerProps & NavigationNavigatorProps > { - new( - props: NavigationContainerProps & NavigationNavigatorProps, - context?: any - ): NavigationContainerComponent; + new(props: NavigationContainerProps & NavigationNavigatorProps, context?: any): NavigationContainerComponent; router: NavigationRouter; screenProps: { [key: string]: any }; @@ -678,43 +618,29 @@ export interface NavigationContainer state: { nav: NavigationState | null }; } -export interface StackNavigatorConfig - extends NavigationStackViewConfig, - NavigationStackRouterConfig { +export interface StackNavigatorConfig extends NavigationStackViewConfig, NavigationStackRouterConfig { containerOptions?: any; } // Return createNavigationContainer export function StackNavigator( routeConfigMap: NavigationRouteConfigMap, - stackConfig?: StackNavigatorConfig -): NavigationContainer; - -export function createStackNavigator( - routeConfigMap: NavigationRouteConfigMap, - stackConfig?: StackNavigatorConfig + stackConfig?: StackNavigatorConfig, ): NavigationContainer; export interface SwitchNavigatorConfig { initialRouteName: string; resetOnBlur?: boolean; paths?: NavigationPathsConfig; - backBehavior?: 'none' | 'intialRoute'; + backBehavior?: 'none' | 'initialRoute'; } // Return createNavigationContainer -export type _SwitchNavigatorConfig = NavigationSwitchRouterConfig; - export function SwitchNavigator( routeConfigMap: NavigationRouteConfigMap, switchConfig?: SwitchNavigatorConfig ): NavigationContainer; -export function createSwitchNavigator( - routeConfigMap: NavigationRouteConfigMap, - switchConfig?: SwitchNavigatorConfig -): NavigationContainer; - // DrawerItems export const DrawerItems: React.ReactType; @@ -729,28 +655,21 @@ export interface DrawerViewConfig { contentOptions?: any; style?: StyleProp; } -export interface DrawerNavigatorConfig - extends NavigationTabRouterConfig, - DrawerViewConfig { +export interface DrawerNavigatorConfig extends NavigationTabRouterConfig, DrawerViewConfig { containerConfig?: any; contentOptions?: { - activeTintColor?: string; - activeBackgroundColor?: string; - inactiveTintColor?: string; - inactiveBackgroundColor?: string; - style?: StyleProp; - labelStyle?: StyleProp; + activeTintColor?: string, + activeBackgroundColor?: string, + inactiveTintColor?: string, + inactiveBackgroundColor?: string, + style?: StyleProp, + labelStyle?: StyleProp, }; } export function DrawerNavigator( routeConfigMap: NavigationRouteConfigMap, - drawerConfig?: DrawerNavigatorConfig -): NavigationContainer; - -export function createDrawerNavigator( - routeConfigMap: NavigationRouteConfigMap, - drawerConfig?: DrawerNavigatorConfig + drawerConfig?: DrawerNavigatorConfig, ): NavigationContainer; /** @@ -762,23 +681,23 @@ export interface TabViewConfig { tabBarComponent?: React.ReactType; tabBarPosition?: 'top' | 'bottom'; tabBarOptions?: { - activeTintColor?: string; - allowFontScaling?: boolean; - activeBackgroundColor?: string; - inactiveTintColor?: string; - inactiveBackgroundColor?: string; - showLabel?: boolean; - style?: StyleProp; - labelStyle?: StyleProp; - iconStyle?: StyleProp; + activeTintColor?: string, + allowFontScaling?: boolean, + activeBackgroundColor?: string, + inactiveTintColor?: string, + inactiveBackgroundColor?: string, + showLabel?: boolean, + style?: StyleProp, + labelStyle?: StyleProp, + iconStyle?: StyleProp, // Top - showIcon?: boolean; - upperCaseLabel?: boolean; - pressColor?: string; - pressOpacity?: number; - scrollEnabled?: boolean; - tabStyle?: StyleProp; - indicatorStyle?: StyleProp; + showIcon?: boolean, + upperCaseLabel?: boolean, + pressColor?: string, + pressOpacity?: number, + scrollEnabled?: boolean, + tabStyle?: StyleProp, + indicatorStyle?: StyleProp, }; swipeEnabled?: boolean; animationEnabled?: boolean; @@ -786,33 +705,16 @@ export interface TabViewConfig { } // From navigators/TabNavigator.js -export interface TabNavigatorConfig - extends NavigationTabRouterConfig, - TabViewConfig { +export interface TabNavigatorConfig extends NavigationTabRouterConfig, TabViewConfig { lazy?: boolean; removeClippedSubviews?: boolean; - initialLayout?: { height: number; width: number }; + initialLayout?: { height: number, width: number }; } // From navigators/TabNavigator.js export function TabNavigator( routeConfigMap: NavigationRouteConfigMap, - drawConfig?: TabNavigatorConfig -): NavigationContainer; - -export function createTabNavigator( - routeConfigMap: NavigationRouteConfigMap, - drawConfig?: TabNavigatorConfig -): NavigationContainer; - -export function createBottomTabNavigator( - routeConfigMap: NavigationRouteConfigMap, - drawConfig?: TabNavigatorConfig -): NavigationContainer; - -export function createMaterialTopNavigator( - routeConfigMap: NavigationRouteConfigMap, - drawConfig?: TabNavigatorConfig + drawConfig?: TabNavigatorConfig, ): NavigationContainer; export interface TabBarTopProps { @@ -827,17 +729,15 @@ export interface TabBarTopProps { tabBarPosition: string; navigation: NavigationScreenProp; jumpToIndex: (index: number) => void; - getLabel: (scene: TabScene) => React.ReactNode | string; + getLabel: (scene: TabScene) => (React.ReactNode | string); getOnPress: ( previousScene: NavigationRoute, scene: TabScene - ) => ( - args: { - previousScene: NavigationRoute; - scene: TabScene; - jumpToIndex: (index: number) => void; - } - ) => void; + ) => (args: { + previousScene: NavigationRoute, + scene: TabScene, + jumpToIndex: (index: number) => void, + }) => void; renderIcon: (scene: TabScene) => React.ReactElement; labelStyle?: TextStyle; iconStyle?: ViewStyle; @@ -854,17 +754,15 @@ export interface TabBarBottomProps { position: AnimatedValue; navigation: NavigationScreenProp; jumpToIndex: (index: number) => void; - getLabel: (scene: TabScene) => React.ReactNode | string; + getLabel: (scene: TabScene) => (React.ReactNode | string); getOnPress: ( previousScene: NavigationRoute, scene: TabScene - ) => ( - args: { - previousScene: NavigationRoute; - scene: TabScene; - jumpToIndex: (index: number) => void; - } - ) => void; + ) => (args: { + previousScene: NavigationRoute, + scene: TabScene, + jumpToIndex: (index: number) => void, + }) => void; getTestIDProps: (scene: TabScene) => (scene: TabScene) => any; renderIcon: (scene: TabScene) => React.ReactNode; style?: ViewStyle; @@ -891,18 +789,12 @@ export namespace NavigationActions { const POP_TO_TOP: 'Navigation/POP_TO_TOP'; function init(options?: NavigationInitActionPayload): NavigationInitAction; - function navigate( - options: NavigationNavigateActionPayload - ): NavigationNavigateAction; + function navigate(options: NavigationNavigateActionPayload): NavigationNavigateAction; function reset(options: NavigationResetActionPayload): NavigationResetAction; function back(options?: NavigationBackActionPayload): NavigationBackAction; - function setParams( - options: NavigationSetParamsActionPayload - ): NavigationSetParamsAction; + function setParams(options: NavigationSetParamsActionPayload): NavigationSetParamsAction; function pop(options: NavigationPopActionPayload): NavigationPopAction; - function popToTop( - options: NavigationPopToTopActionPayload - ): NavigationPopToTopAction; + function popToTop(options: NavigationPopToTopActionPayload): NavigationPopToTopAction; } /** @@ -915,14 +807,8 @@ export interface TransitionerProps { prevTransitionProps?: NavigationTransitionProps ) => NavigationTransitionSpec; navigation: NavigationScreenProp; - onTransitionStart?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps?: NavigationTransitionProps - ) => Promise | void; - onTransitionEnd?: ( - transitionProps: NavigationTransitionProps, - prevTransitionProps?: NavigationTransitionProps - ) => void; + onTransitionStart?: (transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps) => Promise | void; + onTransitionEnd?: (transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps) => void; render: ( transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps @@ -940,7 +826,7 @@ export interface TransitionerState { export class Transitioner extends React.Component< TransitionerProps, TransitionerState - > { } +> { } /** * Tab Router @@ -967,23 +853,12 @@ export function StackRouter( * * @see https://github.com/react-navigation/react-navigation/blob/master/src/navigators/createNavigator.js */ -export interface NavigationDescriptor { - key: string; - state: NavigationLeafRoute | NavigationStateRoute; - navigation: NavigationScreenProp; - getComponent: () => React.ComponentType<{}>; -} - -export type NavigationView = React.ComponentType<{ - descriptors: { [key: string]: NavigationDescriptor }; -} & NavigationInjectedProps>; - export function createNavigator( - view: NavigationView, router: NavigationRouter, + routeConfigs?: NavigationRouteConfigMap, navigatorConfig?: {} | null, navigatorType?: NavigatorType -): any; +): (NavigationView: React.ComponentClass) => NavigationNavigator; /** * Create an HOC that injects the navigation and manages the navigation state @@ -1004,10 +879,7 @@ export function createNavigationContainer( * BEGIN CUSTOM CONVENIENCE INTERFACES */ -export interface NavigationScreenProps< - Params = NavigationParams, - Options = any - > { +export interface NavigationScreenProps { navigation: NavigationScreenProp, Params>; screenProps?: { [key: string]: any }; navigationOptions?: NavigationScreenConfig; @@ -1064,7 +936,6 @@ export interface SafeAreaViewProps extends ViewProps { horizontal?: SafeAreaViewForceInsetValue; vertical?: SafeAreaViewForceInsetValue; }; - children?: React.ReactNode; } export const SafeAreaView: React.ComponentClass; diff --git a/types/react-navigation/v2/index.d.ts b/types/react-navigation/v2/index.d.ts new file mode 100644 index 0000000000..36251eba5b --- /dev/null +++ b/types/react-navigation/v2/index.d.ts @@ -0,0 +1,1086 @@ +// Type definitions for react-navigation 2.0 +// Project: https://github.com/react-navigation/react-navigation +// Definitions by: Huhuanming +// mhcgrq +// fangpenlin +// petejkim +// Kyle Roach +// phanalpha +// charlesfamu +// Tim Wang +// Qibang Sun +// Sergei Butko: +// Veit Lehmann: +// Roberto Huertas: +// Steven Miller +// Armando Assuncao +// Ciaran Liedeman +// Edward Sammut Alessi +// Jérémy Magrin +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.6 + +/** + * Reference: https://github.com/react-navigation/react-navigation/tree/a37473c5e4833f48796ee6c7c9cb4a8ac49d9c06 + * + * NOTE: Please update the commit/link above when updating to a new Flow + * react-navigation/flow/react-navigation.js reference, so we can conveniently just look at diffs on + * react-navigation/flow/react-navigation.js between this latest reference point and the one you are + * using when making new updates. + */ + +import * as React from 'react'; +import { + Animated, + TextStyle, + ViewProps, + ViewStyle, + StyleProp, +} from 'react-native'; + +// @todo when we split types into common, native and web, +// we can properly change Animated.Value to its real value +export type AnimatedValue = any; + +export type HeaderMode = 'float' | 'screen' | 'none'; + +export interface HeaderForceInset { + horizontal?: string; + vertical?: string, + left?: string, + right?: string, + top?: string, + bottom?: string, +} + +export interface HeaderProps extends NavigationSceneRendererProps { + mode: HeaderMode; + router: NavigationRouter; + getScreenDetails: ( + navigationScene: NavigationScene + ) => NavigationScreenDetails; + leftInterpolator: (props: NavigationSceneRendererProps) => {}; + titleInterpolator: (props: NavigationSceneRendererProps) => {}; + rightInterpolator: (props: NavigationSceneRendererProps) => {}; + style: StyleProp; +} + +/** + * NavigationState is a tree of routes for a single navigator, where each child + * route may either be a NavigationScreenRoute or a NavigationRouterRoute. + * NavigationScreenRoute represents a leaf screen, while the + * NavigationRouterRoute represents the state of a child navigator. + * + * NOTE: NavigationState is a state tree local to a single navigator and + * its child navigators (via the routes field). + * If we're in navigator nested deep inside the app, the state will only be the + * state for that navigator. + * The state for the root navigator of our app represents the whole navigation + * state for the whole app. + */ +export interface NavigationState { + /** + * Index refers to the active child route in the routes array. + */ + index: number; + routes: NavigationRoute[]; +} + +export type NavigationRoute = + | NavigationLeafRoute + | NavigationStateRoute; + +export interface NavigationLeafRoute { + /** + * React's key used by some navigators. No need to specify these manually, + * they will be defined by the router. + */ + key: string; + /** + * For example 'Home'. + * This is used as a key in a route config when creating a navigator. + */ + routeName: string; + /** + * Path is an advanced feature used for deep linking and on the web. + */ + path?: string; + /** + * Params passed to this route when navigating to it, + * e.g. `{ car_id: 123 }` in a route that displays a car. + */ + params?: Params; +} + +export type NavigationStateRoute< + NavigationLeafRouteParams + > = NavigationLeafRoute & NavigationState; + +export type NavigationScreenOptionsGetter = ( + navigation: NavigationScreenProp>, + screenProps?: { [key: string]: any } +) => Options; + +export interface NavigationRouter { + /** + * The reducer that outputs the new navigation state for a given action, with + * an optional previous state. When the action is considered handled but the + * state is unchanged, the output state is null. + */ + getStateForAction: ( + action: NavigationAction, + lastState?: State + ) => State | null; + + /** + * Maps a URI-like string to an action. This can be mapped to a state + * using `getStateForAction`. + */ + getActionForPathAndParams: ( + path: string, + params?: NavigationParams + ) => NavigationAction | null; + + getPathAndParamsForState: ( + state: State + ) => { + path: string; + params?: NavigationParams; + }; + + getComponentForRouteName: (routeName: string) => NavigationComponent; + + getComponentForState: (state: State) => NavigationComponent; + + /** + * Gets the screen navigation options for a given screen. + * + * For example, we could get the config for the 'Foo' screen when the + * `navigation.state` is: + * + * {routeName: 'Foo', key: '123'} + */ + getScreenOptions: NavigationScreenOptionsGetter; +} + +export type NavigationScreenOption = + | T + | ((navigation: NavigationScreenProp, config: T) => T); + +export interface NavigationScreenDetails { + options: T; + state: NavigationRoute; + navigation: NavigationScreenProp; +} + +export type NavigationScreenOptions = NavigationStackScreenOptions & + NavigationTabScreenOptions & + NavigationDrawerScreenOptions; + +export interface NavigationScreenConfigProps { + navigation: NavigationScreenProp; + screenProps: { [key: string]: any }; +} + +export type NavigationScreenConfig = + | Options + | (( + navigationOptionsContainer: NavigationScreenConfigProps & { + navigationOptions: NavigationScreenProp; + } + ) => Options); + +export type NavigationComponent = + | NavigationScreenComponent + | NavigationNavigator + | any; + +export type NavigationScreenComponent< + Params = NavigationParams, + Options = {}, + Props = {} + > = React.ComponentType & Props> & { + navigationOptions?: NavigationScreenConfig; + }; + +export type NavigationNavigator< + State = NavigationState, + Options = {}, + Props = {} + > = React.ComponentType & Props> & { + router: NavigationRouter; + navigationOptions?: NavigationScreenConfig; + }; + +export interface NavigationParams { + [key: string]: any; +} + +export interface NavigationNavigateActionPayload { + routeName: string; + params?: NavigationParams; + + // The action to run inside the sub-router + action?: NavigationNavigateAction; + + key?: string; +} + +export interface NavigationNavigateAction + extends NavigationNavigateActionPayload { + type: 'Navigation/NAVIGATE'; +} + +export interface NavigationBackActionPayload { + key?: string | null; +} + +export interface NavigationBackAction extends NavigationBackActionPayload { + type: 'Navigation/BACK'; +} + +export interface NavigationSetParamsActionPayload { + // The key of the route where the params should be set + key: string; + + // The new params to merge into the existing route params + params?: NavigationParams; +} + +export interface NavigationSetParamsAction + extends NavigationSetParamsActionPayload { + type: 'Navigation/SET_PARAMS'; +} + +export interface NavigationInitActionPayload { + params?: NavigationParams; +} + +export interface NavigationInitAction extends NavigationInitActionPayload { + type: 'Navigation/INIT'; +} + +export interface NavigationResetActionPayload { + index: number; + key?: string | null; + actions: NavigationNavigateAction[]; +} + +export interface NavigationResetAction extends NavigationResetActionPayload { + type: 'Navigation/RESET'; +} + +export interface NavigationUriActionPayload { + uri: string; +} + +export interface NavigationUriAction extends NavigationUriActionPayload { + type: 'Navigation/URI'; +} + +export interface NavigationPopActionPayload { + // n: the number of routes to pop of the stack + n?: number; + immediate?: boolean; +} + +export interface NavigationPopAction extends NavigationPopActionPayload { + type: 'Navigation/POP'; +} + +export interface NavigationPopToTopActionPayload { + key?: string; + immediate?: boolean; +} + +export interface NavigationPopToTopAction + extends NavigationPopToTopActionPayload { + type: 'Navigation/POP_TO_TOP'; +} + +export interface NavigationStackViewConfig { + mode?: 'card' | 'modal'; + headerMode?: HeaderMode; + headerTransitionPreset?: 'fade-in-place' | 'uikit'; + cardStyle?: StyleProp; + transitionConfig?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps: NavigationTransitionProps, + isModal: boolean + ) => TransitionConfig; + onTransitionStart?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps?: NavigationTransitionProps + ) => Promise | void; + onTransitionEnd?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps?: NavigationTransitionProps + ) => void; +} + +/** + * Switch Navigator + */ + +export interface NavigationSwitchRouterConfig { + initialRouteName?: string; + initialRouteParams?: NavigationParams; + paths?: NavigationPathsConfig; + navigationOptions?: NavigationScreenConfig; + order?: string[]; + backBehavior?: 'none' | 'initialRoute'; // defaults to `'none'` + resetOnBlur?: boolean; // defaults to `true` +} + +export interface NavigationStackScreenOptions { + title?: string; + header?: + | ( + | React.ReactElement + | ((headerProps: HeaderProps) => React.ReactElement)) + | null; + headerTransparent?: boolean; + headerTitle?: string | React.ReactElement; + headerTitleStyle?: StyleProp; + headerTitleAllowFontScaling?: boolean; + headerTintColor?: string; + headerLeft?: React.ReactElement; + headerBackTitle?: string | null; + headerBackImage?: React.ReactElement; + headerTruncatedBackTitle?: string; + headerBackTitleStyle?: StyleProp; + headerPressColorAndroid?: string; + headerRight?: React.ReactElement; + headerStyle?: StyleProp; + headerForceInset?: HeaderForceInset; + headerBackground?: React.ReactNode | React.ReactType; + gesturesEnabled?: boolean; + gestureResponseDistance?: { vertical?: number; horizontal?: number }; + gestureDirection?: 'default' | 'inverted'; +} + +export interface NavigationStackRouterConfig { + headerTransitionPreset?: 'fade-in-place' | 'uikit'; + initialRouteName?: string; + initialRouteParams?: NavigationParams; + paths?: NavigationPathsConfig; + navigationOptions?: NavigationScreenConfig; + initialRouteKey?: string; +} + +export type NavigationStackAction = + | NavigationInitAction + | NavigationNavigateAction + | NavigationBackAction + | NavigationSetParamsAction + | NavigationResetAction + | NavigationPopAction + | NavigationPopToTopAction; + +export type NavigationTabAction = + | NavigationInitAction + | NavigationNavigateAction + | NavigationBackAction; + +export type NavigationAction = + | NavigationInitAction + | NavigationStackAction + | NavigationTabAction; + +export type NavigationRouteConfig = + | NavigationComponent + | ({ + navigationOptions?: NavigationScreenConfig; + path?: string; + } & NavigationScreenRouteConfig); + +export type NavigationScreenRouteConfig = + | NavigationComponent + | { + screen: NavigationComponent; + } + | { + getScreen: () => NavigationComponent; + }; + +export interface NavigationPathsConfig { + [routeName: string]: string; +} + +export interface NavigationTabRouterConfig { + initialRouteName?: string; + initialRouteParams?: NavigationParams; + paths?: NavigationPathsConfig; + navigationOptions?: NavigationScreenConfig; + order?: string[]; // todo: type these as the real route names rather than 'string' + + // Does the back button cause the router to switch to the initial tab + backBehavior?: 'none' | 'initialRoute'; // defaults `initialRoute` +} +export interface TabScene { + route: NavigationRoute; + focused: boolean; + index: number; + tintColor?: string; +} +export interface NavigationTabScreenOptions { + title?: string; + tabBarIcon?: + | React.ReactElement + | (( + options: { tintColor: string | null; focused: boolean } + ) => React.ReactElement | null); + tabBarLabel?: + | string + | React.ReactElement + | (( + options: { tintColor: string | null; focused: boolean } + ) => React.ReactElement | string | null); + tabBarVisible?: boolean; + tabBarTestIDProps?: { testID?: string; accessibilityLabel?: string }; + tabBarOnPress?: ( + options: { + scene: TabScene; + jumpToIndex: (index: number) => void; + } + ) => void; +} + +export interface NavigationDrawerScreenOptions { + title?: string; + drawerIcon?: + | React.ReactElement + | (( + options: { tintColor: string | null; focused: boolean } + ) => React.ReactElement | null); + drawerLabel?: + | string + | React.ReactElement + | (( + options: { tintColor: string | null; focused: boolean } + ) => React.ReactElement | null); + drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open'; +} + +export interface NavigationRouteConfigMap { + [routeName: string]: NavigationRouteConfig; +} + +export type NavigationDispatch = (action: NavigationAction) => boolean; + +export interface NavigationProp { + state: S; + dispatch: NavigationDispatch; +} + +export type EventType = + | 'willFocus' + | 'didFocus' + | 'willBlur' + | 'didBlur' + | 'action'; + +export interface NavigationEventPayload { + type: EventType; + action: NavigationAction; + state: NavigationState; + lastState: NavigationState | null | undefined; +} + +export type NavigationEventCallback = (payload: NavigationEventPayload) => void; + +export interface NavigationEventSubscription { + remove: () => void; +} + +export interface NavigationScreenProp { + state: S; + dispatch: NavigationDispatch; + goBack: (routeKey?: string | null) => boolean; + dismiss: () => boolean; + navigate(options: { + routeName: string | { + routeName: string; + params?: NavigationParams; + action?: NavigationNavigateAction; + key?: string; + }; + params?: NavigationParams; + action?: NavigationAction; + key?: string; + }): boolean; + navigate( + routeNameOrOptions: string, + params?: NavigationParams, + action?: NavigationAction + ): boolean; + openDrawer: () => any; + closeDrawer: () => any; + toggleDrawer: () => any; + getParam: (param: T, fallback?: P[T]) => P[T]; + setParams: (newParams: P) => boolean; + addListener: ( + eventName: string, + callback: NavigationEventCallback + ) => NavigationEventSubscription; + push: ( + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean; + replace: ( + routeName: string, + params?: NavigationParams, + action?: NavigationNavigateAction + ) => boolean; + pop: (n?: number, params?: { immediate?: boolean }) => boolean; + popToTop: (params?: { immediate?: boolean }) => boolean; + isFocused: () => boolean; +} + +export interface NavigationNavigatorProps { + navigation?: NavigationProp; + screenProps?: { [key: string]: any }; + navigationOptions?: O; +} + +/** + * Gestures, Animations, and Interpolators + */ + +export type NavigationGestureDirection = 'horizontal' | 'vertical'; + +export interface NavigationLayout { + height: AnimatedValue; + initHeight: number; + initWidth: number; + isMeasured: boolean; + width: AnimatedValue; +} + +export interface NavigationScene { + index: number; + isActive: boolean; + isStale: boolean; + key: string; + route: NavigationRoute; +} + +export interface NavigationTransitionProps { + // The layout of the screen container + layout: NavigationLayout; + + // The destination navigation state of the transition + navigation: NavigationScreenProp; + + // The progressive index of the transitioner's navigation state. + position: AnimatedValue; + + // The value that represents the progress of the transition when navigation + // state changes from one to another. Its numberic value will range from 0 + // to 1. + // progress.__getAnimatedValue() < 1 : transtion is happening. + // progress.__getAnimatedValue() == 1 : transtion completes. + progress: AnimatedValue; + + // All the scenes of the transitioner. + scenes: NavigationScene[]; + + // The active scene, corresponding to the route at + // `navigation.state.routes[navigation.state.index]`. When rendering + // NavigationSceneRendererPropsIndex, the scene does not refer to the active + // scene, but instead the scene that is being rendered. The index always + // is the index of the scene + scene: NavigationScene; + index: number; + + screenProps?: { [key: string]: any }; +} + +// The scene renderer props are nearly identical to the props used for rendering +// a transition. The exception is that the passed scene is not the active scene +// but is instead the scene that the renderer should render content for. +export type NavigationSceneRendererProps = NavigationTransitionProps; + +export interface NavigationTransitionSpec { + duration?: number; + // An easing function from `Easing`. + easing?: (t: number) => number; + // A timing function such as `Animated.timing`. + timing?: (value: AnimatedValue, config: any) => any; +} + +/** + * Describes a visual transition from one screen to another. + */ +export interface TransitionConfig { + // The basics properties of the animation, such as duration and easing + transitionSpec?: NavigationTransitionSpec; + // How to animate position and opacity of the screen + // based on the value generated by the transitionSpec + screenInterpolator?: (props: NavigationSceneRendererProps) => any; + // How to animate position and opacity of the header componetns + // based on the value generated by the transitionSpec + headerLeftInterpolator?: (props: NavigationSceneRendererProps) => any; + headerTitleInterpolator?: (props: NavigationSceneRendererProps) => any; + headerRightInterpolator?: (props: NavigationSceneRendererProps) => any; + // The style of the container. Useful when a scene doesn't have + // 100% opacity and the underlying container is visible. + containerStyle?: StyleProp; +} + +export type NavigationAnimationSetter = ( + position: AnimatedValue, + newState: NavigationState, + lastState: NavigationState +) => void; + +export type NavigationSceneRenderer = () => React.ReactElement | null; + +export type NavigationStyleInterpolator = ( + props: NavigationSceneRendererProps +) => ViewStyle; + +export interface LayoutEvent { + nativeEvent: { + layout: { + x: number; + y: number; + width: number; + height: number; + }; + }; +} + +export type NavigatorType = + | 'react-navigation/STACK' + | 'react-navigation/TABS' + | 'react-navigation/DRAWER'; + +export interface NavigationContainerProps { + uriPrefix?: string | RegExp; + onNavigationStateChange?: ( + prevNavigationState: NavigationState, + nextNavigationState: NavigationState, + action: NavigationAction + ) => void | null | undefined; + navigation?: NavigationScreenProp; + persistenceKey?: string | null | undefined; + renderLoadingExperimental?: React.ComponentType<{}>, + screenProps?: any; + navigationOptions?: O; + style?: StyleProp; +} + +export interface NavigationContainerComponent + extends React.Component< + NavigationContainerProps & NavigationNavigatorProps + > { + dispatch: NavigationDispatch; +} + +export interface NavigationContainer + extends React.ComponentClass< + NavigationContainerProps & NavigationNavigatorProps + > { + new( + props: NavigationContainerProps & NavigationNavigatorProps, + context?: any + ): NavigationContainerComponent; + + router: NavigationRouter; + screenProps: { [key: string]: any }; + navigationOptions: any; + state: { nav: NavigationState | null }; +} + +export interface StackNavigatorConfig + extends NavigationStackViewConfig, + NavigationStackRouterConfig { + containerOptions?: any; +} + +// Return createNavigationContainer +export function StackNavigator( + routeConfigMap: NavigationRouteConfigMap, + stackConfig?: StackNavigatorConfig +): NavigationContainer; + +export function createStackNavigator( + routeConfigMap: NavigationRouteConfigMap, + stackConfig?: StackNavigatorConfig +): NavigationContainer; + +export interface SwitchNavigatorConfig { + initialRouteName: string; + resetOnBlur?: boolean; + paths?: NavigationPathsConfig; + backBehavior?: 'none' | 'initialRoute'; +} + +// Return createNavigationContainer +export type _SwitchNavigatorConfig = NavigationSwitchRouterConfig; + +export function SwitchNavigator( + routeConfigMap: NavigationRouteConfigMap, + switchConfig?: SwitchNavigatorConfig +): NavigationContainer; + +export function createSwitchNavigator( + routeConfigMap: NavigationRouteConfigMap, + switchConfig?: SwitchNavigatorConfig +): NavigationContainer; + +// DrawerItems +export const DrawerItems: React.ReactType; + +/** + * Drawer Navigator + */ +export interface DrawerViewConfig { + drawerBackgroundColor?: string; + drawerWidth?: number; + drawerPosition?: 'left' | 'right'; + contentComponent?: React.ReactType; + contentOptions?: any; + style?: StyleProp; +} +export interface DrawerNavigatorConfig + extends NavigationTabRouterConfig, + DrawerViewConfig { + containerConfig?: any; + contentOptions?: { + activeTintColor?: string; + activeBackgroundColor?: string; + inactiveTintColor?: string; + inactiveBackgroundColor?: string; + style?: StyleProp; + labelStyle?: StyleProp; + }; +} + +export function DrawerNavigator( + routeConfigMap: NavigationRouteConfigMap, + drawerConfig?: DrawerNavigatorConfig +): NavigationContainer; + +export function createDrawerNavigator( + routeConfigMap: NavigationRouteConfigMap, + drawerConfig?: DrawerNavigatorConfig +): NavigationContainer; + +/** + * Tab Navigator + */ + +// From views/TabView/TabView.js +export interface TabViewConfig { + tabBarComponent?: React.ReactType; + tabBarPosition?: 'top' | 'bottom'; + tabBarOptions?: { + activeTintColor?: string; + allowFontScaling?: boolean; + activeBackgroundColor?: string; + inactiveTintColor?: string; + inactiveBackgroundColor?: string; + showLabel?: boolean; + style?: StyleProp; + labelStyle?: StyleProp; + iconStyle?: StyleProp; + // Top + showIcon?: boolean; + upperCaseLabel?: boolean; + pressColor?: string; + pressOpacity?: number; + scrollEnabled?: boolean; + tabStyle?: StyleProp; + indicatorStyle?: StyleProp; + }; + swipeEnabled?: boolean; + animationEnabled?: boolean; + lazy?: boolean; +} + +// From navigators/TabNavigator.js +export interface TabNavigatorConfig + extends NavigationTabRouterConfig, + TabViewConfig { + lazy?: boolean; + removeClippedSubviews?: boolean; + initialLayout?: { height: number; width: number }; +} + +// From navigators/TabNavigator.js +export function TabNavigator( + routeConfigMap: NavigationRouteConfigMap, + drawConfig?: TabNavigatorConfig +): NavigationContainer; + +export function createTabNavigator( + routeConfigMap: NavigationRouteConfigMap, + drawConfig?: TabNavigatorConfig +): NavigationContainer; + +export function createBottomTabNavigator( + routeConfigMap: NavigationRouteConfigMap, + drawConfig?: TabNavigatorConfig +): NavigationContainer; + +export function createMaterialTopNavigator( + routeConfigMap: NavigationRouteConfigMap, + drawConfig?: TabNavigatorConfig +): NavigationContainer; + +export interface TabBarTopProps { + activeTintColor: string; + inactiveTintColor: string; + indicatorStyle: StyleProp; + showIcon: boolean; + showLabel: boolean; + upperCaseLabel: boolean; + allowFontScaling: boolean; + position: AnimatedValue; + tabBarPosition: string; + navigation: NavigationScreenProp; + jumpToIndex: (index: number) => void; + getLabel: (scene: TabScene) => React.ReactNode | string; + getOnPress: ( + previousScene: NavigationRoute, + scene: TabScene + ) => ( + args: { + previousScene: NavigationRoute; + scene: TabScene; + jumpToIndex: (index: number) => void; + } + ) => void; + renderIcon: (scene: TabScene) => React.ReactElement; + labelStyle?: TextStyle; + iconStyle?: ViewStyle; +} + +export interface TabBarBottomProps { + activeTintColor: string; + activeBackgroundColor: string; + adaptive?: boolean; + inactiveTintColor: string; + inactiveBackgroundColor: string; + showLabel?: boolean; + allowFontScaling: boolean; + position: AnimatedValue; + navigation: NavigationScreenProp; + jumpToIndex: (index: number) => void; + getLabel: (scene: TabScene) => React.ReactNode | string; + getOnPress: ( + previousScene: NavigationRoute, + scene: TabScene + ) => ( + args: { + previousScene: NavigationRoute; + scene: TabScene; + jumpToIndex: (index: number) => void; + } + ) => void; + getTestIDProps: (scene: TabScene) => (scene: TabScene) => any; + renderIcon: (scene: TabScene) => React.ReactNode; + style?: ViewStyle; + animateStyle?: ViewStyle; + labelStyle?: TextStyle; + tabStyle?: ViewStyle; + showIcon?: boolean; +} + +export const TabBarTop: React.ComponentType; +export const TabBarBottom: React.ComponentType; + +/** + * NavigationActions + */ +export namespace NavigationActions { + const BACK: 'Navigation/BACK'; + const INIT: 'Navigation/INIT'; + const NAVIGATE: 'Navigation/NAVIGATE'; + const RESET: 'Navigation/RESET'; + const SET_PARAMS: 'Navigation/SET_PARAMS'; + const URI: 'Navigation/URI'; + const POP: 'Navigation/POP'; + const POP_TO_TOP: 'Navigation/POP_TO_TOP'; + + function init(options?: NavigationInitActionPayload): NavigationInitAction; + function navigate( + options: NavigationNavigateActionPayload + ): NavigationNavigateAction; + function reset(options: NavigationResetActionPayload): NavigationResetAction; + function back(options?: NavigationBackActionPayload): NavigationBackAction; + function setParams( + options: NavigationSetParamsActionPayload + ): NavigationSetParamsAction; + function pop(options: NavigationPopActionPayload): NavigationPopAction; + function popToTop( + options: NavigationPopToTopActionPayload + ): NavigationPopToTopAction; +} + +/** + * Transitioner + * @desc From react-navigation/src/views/Transitioner.js + */ +export interface TransitionerProps { + configureTransition: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps?: NavigationTransitionProps + ) => NavigationTransitionSpec; + navigation: NavigationScreenProp; + onTransitionStart?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps?: NavigationTransitionProps + ) => Promise | void; + onTransitionEnd?: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps?: NavigationTransitionProps + ) => void; + render: ( + transitionProps: NavigationTransitionProps, + prevTransitionProps?: NavigationTransitionProps + ) => any; + style?: StyleProp; +} + +export interface TransitionerState { + layout: NavigationLayout; + position: Animated.Value; + progress: Animated.Value; + scenes: NavigationScene[]; +} + +export class Transitioner extends React.Component< + TransitionerProps, + TransitionerState + > { } + +/** + * Tab Router + * + * @desc from react-navigation/src/routers/TabRouter.js + */ +export function TabRouter( + routeConfigs: NavigationRouteConfigMap, + config: NavigationTabRouterConfig +): NavigationRouter; + +/** + * Stack Router + * + * @desc from react-navigation/src/routers/StackRouter.js + */ +export function StackRouter( + routeConfigs: NavigationRouteConfigMap, + config: NavigationTabRouterConfig +): NavigationRouter; + +/** + * Create Navigator + * + * @see https://github.com/react-navigation/react-navigation/blob/master/src/navigators/createNavigator.js + */ +export interface NavigationDescriptor { + key: string; + state: NavigationLeafRoute | NavigationStateRoute; + navigation: NavigationScreenProp; + getComponent: () => React.ComponentType<{}>; +} + +export type NavigationView = React.ComponentType<{ + descriptors: { [key: string]: NavigationDescriptor }; +} & NavigationInjectedProps>; + +export function createNavigator( + view: NavigationView, + router: NavigationRouter, + navigatorConfig?: {} | null, + navigatorType?: NavigatorType +): any; + +/** + * Create an HOC that injects the navigation and manages the navigation state + * in case it's not passed from above. + * This allows to use e.g. the StackNavigator and TabNavigator as root-level + * components. + * + * @see https://github.com/react-navigation/react-navigation/blob/master/src/createNavigationContainer.js + */ +export function createNavigationContainer( + Component: NavigationNavigator +): NavigationContainer; +/** + * END MANUAL DEFINITIONS OUTSIDE OF TYPEDEFINITION.JS + */ + +/** + * BEGIN CUSTOM CONVENIENCE INTERFACES + */ + +export interface NavigationScreenProps< + Params = NavigationParams, + Options = any + > { + navigation: NavigationScreenProp, Params>; + screenProps?: { [key: string]: any }; + navigationOptions?: NavigationScreenConfig; +} + +/** + * END CUSTOM CONVENIENCE INTERFACES + */ + +/* + * Header + */ + +// src/views/HeaderBackButton.js + +export interface HeaderBackButtonProps { + onPress?: () => void; + pressColorAndroid?: string; + title?: string; + titleStyle?: StyleProp; + tintColor?: string; + truncatedTitle?: string; + width?: number; +} + +export const HeaderBackButton: React.ComponentClass; +/** + * Header Component + */ +export const Header: React.ComponentClass; + +export interface NavigationInjectedProps { + navigation: NavigationScreenProp; +} + +export function withNavigation( + Component: React.ComponentType +): React.ComponentType; + +export function withNavigationFocus( + Component: React.ComponentType +): React.ComponentType; + +/** + * SafeAreaView Component + */ +export type SafeAreaViewForceInsetValue = 'always' | 'never'; +export interface SafeAreaViewProps extends ViewProps { + forceInset?: { + top?: SafeAreaViewForceInsetValue; + bottom?: SafeAreaViewForceInsetValue; + left?: SafeAreaViewForceInsetValue; + right?: SafeAreaViewForceInsetValue; + horizontal?: SafeAreaViewForceInsetValue; + vertical?: SafeAreaViewForceInsetValue; + }; + children?: React.ReactNode; +} + +export const SafeAreaView: React.ComponentClass; diff --git a/types/react-navigation/v2/react-navigation-tests.tsx b/types/react-navigation/v2/react-navigation-tests.tsx new file mode 100644 index 0000000000..b59474bd11 --- /dev/null +++ b/types/react-navigation/v2/react-navigation-tests.tsx @@ -0,0 +1,453 @@ +import * as React from 'react'; +import { + TouchableOpacity, + View, + ViewStyle, +} from 'react-native'; +import { + createDrawerNavigator, + DrawerNavigatorConfig, + NavigationAction, + NavigationActions, + NavigationBackAction, + NavigationInitAction, + NavigationNavigateAction, + NavigationProp, + NavigationResetAction, + NavigationRouteConfigMap, + NavigationScreenProp, + NavigationScreenProps, + NavigationSetParamsAction, + NavigationStackAction, + NavigationStackScreenOptions, + NavigationTabScreenOptions, + NavigationTransitionProps, + createStackNavigator, + StackNavigatorConfig, + createSwitchNavigator, + SwitchNavigatorConfig, + TabBarTop, + createTabNavigator, + TabNavigatorConfig, + Transitioner, + HeaderBackButton, + Header, + NavigationContainer, + NavigationParams, + NavigationPopAction, + NavigationPopToTopAction, + NavigationScreenComponent, + NavigationContainerComponent, +} from 'react-navigation'; + +// Constants +const viewStyle: ViewStyle = { + flex: 1, + margin: 42, + padding: 0, + backgroundColor: "white", +}; + +const ROUTE_NAME_START_SCREEN = "StartScreen"; +const ROUTE_KEY_START_SCREEN = "StartScreen-key"; + +interface StartScreenNavigationParams { + id: number; + s: string; +} + +/** + * @desc Simple screen component class with typed component props that should + * receive the navigation prop from the AppNavigator. + */ +class StartScreen extends React.Component> { + render() { + // Implicit type checks. + const navigationStateParams: StartScreenNavigationParams | undefined = this.props.navigation.state.params; + const id = this.props.navigation.state.params && this.props.navigation.state.params.id; + const s = this.props.navigation.state.params && this.props.navigation.state.params.s; + + return ( + + + + + ); + } + private readonly navigateToNextScreen = (): void => { + const params = { + id: this.props.navigation.state.params && this.props.navigation.state.params.id, + name: this.props.navigation.state.params && this.props.navigation.state.params.s, + }; + this.props.navigation.navigate(ROUTE_NAME_NEXT_SCREEN, params); + } + private readonly navigateDifferentlyToNextScreen = (): void => { + const params = { + id: this.props.navigation.state.params && this.props.navigation.state.params.id, + name: this.props.navigation.state.params && this.props.navigation.state.params.s, + }; + this.props.navigation.navigate({routeName: ROUTE_NAME_NEXT_SCREEN, params}); + } +} + +const ROUTE_NAME_NEXT_SCREEN = "NextScreen"; + +interface NextScreenNavigationParams { + id: number; + name: string; +} + +class NextScreen extends React.Component> { + render() { + // Implicit type checks. + const navigationStateParams: NextScreenNavigationParams | undefined = this.props.navigation.state.params; + const id = this.props.navigation.state.params && this.props.navigation.state.params.id; + const name = this.props.navigation.getParam('name', 'Peter'); + + return ( + + ); + } +} + +const navigationOptions = { + headerBackTitle: null, +}; +const initialRouteParams: StartScreenNavigationParams = { + id: 1, + s: "Start", +}; +const routeConfigMap: NavigationRouteConfigMap = { + [ROUTE_NAME_START_SCREEN]: { + path: "start", + screen: StartScreen, + }, + [ROUTE_NAME_NEXT_SCREEN]: { + path: "next", + screen: NextScreen, + }, +}; +export const AppNavigator = createStackNavigator( + routeConfigMap, + { + initialRouteName: ROUTE_NAME_START_SCREEN, + initialRouteKey: ROUTE_KEY_START_SCREEN, + initialRouteParams, + navigationOptions, + }, +); + +interface StatelessScreenParams { + testID: string; +} + +const StatelessScreen: NavigationScreenComponent = (props) => + ; + +StatelessScreen.navigationOptions = { title: 'Stateless' }; + +const SimpleStackNavigator = createStackNavigator( + { + simple: { + screen: StatelessScreen, + }, + } +); + +/** + * Tab navigator. + */ + +const tabNavigatorScreenOptions: NavigationTabScreenOptions = { + title: 'title', + tabBarVisible: true, + tabBarIcon: , + tabBarLabel: 'label', + tabBarOnPress: ({scene, jumpToIndex}) => {} +}; + +const tabNavigatorConfig: TabNavigatorConfig = { + lazy: true, + tabBarComponent: TabBarTop, + tabBarOptions: { activeBackgroundColor: "blue" }, +}; + +const tabNavigatorConfigWithInitialLayout: TabNavigatorConfig = { + ...tabNavigatorConfig, + initialLayout: { height: 0, width: 100 }, +}; + +const tabNavigatorConfigWithNavigationOptions: TabNavigatorConfig = { + ...tabNavigatorConfig, + navigationOptions: { + tabBarOnPress: ({scene, jumpToIndex}) => { + jumpToIndex(scene.index); + }, + headerStyle: { + backgroundColor: 'red', + }, + }, +}; + +const BasicTabNavigator = createTabNavigator( + routeConfigMap, + tabNavigatorConfig, +); + +function renderBasicTabNavigator(): JSX.Element { + return ( + { }} + style={[viewStyle, undefined]} // Test that we are using StyleProp + /> + ); +} + +/** + * Stack navigator. + */ + +const stackNavigatorScreenOptions: NavigationStackScreenOptions = { + title: 'title', +}; + +const stackNavigatorConfig: StackNavigatorConfig = { + mode: "card", + headerMode: "screen", + navigationOptions: stackNavigatorScreenOptions, +}; + +const BasicStackNavigator = createStackNavigator( + routeConfigMap, + stackNavigatorConfig, +); + +function renderBasicStackNavigator(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); +} + +const stackNavigatorConfigWithNavigationOptionsAsFunction: StackNavigatorConfig = { + mode: "card", + headerMode: "screen", + navigationOptions: ({navigationOptions, navigation, screenProps}) => (stackNavigatorScreenOptions), +}; + +const AdvancedStackNavigator = createStackNavigator( + routeConfigMap, + stackNavigatorConfigWithNavigationOptionsAsFunction +); + +function renderAdvancedStackNavigator(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); +} + +/** + * Switch navigator. + */ + +const switchNavigatorConfig: SwitchNavigatorConfig = { + initialRouteName: 'screen', + resetOnBlur: false, + backBehavior: 'none' +}; + +const BasicSwitchNavigator = createSwitchNavigator( + routeConfigMap, + switchNavigatorConfig, +); + +function renderBasicSwitchNavigator(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); +} + +const switchNavigatorConfigWithInitialRoute: SwitchNavigatorConfig = { + initialRouteName: 'screen', + resetOnBlur: false, + backBehavior: 'initialRoute' +}; + +const SwitchNavigatorWithInitialRoute = createSwitchNavigator( + routeConfigMap, + switchNavigatorConfigWithInitialRoute, +); + +function renderSwitchNavigatorWithInitialRoute(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); +} + +/** + * Drawer navigator. + */ + +const drawerNavigatorScreenOptions: NavigationTabScreenOptions = { + title: 'title', +}; + +const drawerNavigatorConfig: DrawerNavigatorConfig = { + drawerBackgroundColor: '#777777', + contentOptions: { + activeTintColor: '#7A9B49', + inactiveTintColor: '#FFFFFF', + }, +}; + +const BasicDrawerNavigator = createDrawerNavigator( + routeConfigMap, + stackNavigatorConfig, +); + +function renderBasicDrawerNavigator(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); +} + +interface CustomTransitionerProps { + navigation: NavigationScreenProp; +} +/** + * @desc Custom transitioner component. Follows react-navigation/src/views/CardStackTransitioner.js. + */ +class CustomTransitioner extends React.Component { + render() { + return ( + { + if (prev) { + prev.position.setValue(curr.navigation.state.index); + } + }} + onTransitionEnd={(curr, prev) => { + if (prev) { + prev.position.setValue(curr.navigation.state.index); + } + }} + /> + ); + } + _render = (props: NavigationTransitionProps, prevProps: NavigationTransitionProps): React.ReactElement => { + return ( + + ); + } + _configureTransition = ( + _transitionProps: NavigationTransitionProps, + _prevTransitionProps: NavigationTransitionProps + ) => { + return {}; + } +} + +/** + * Header + */ +function renderHeaderBackButton(schema: string): JSX.Element { + switch (schema) { + case 'compact': + return ( + + ); + + default: + return ( + 'noop'} + pressColorAndroid="#ccc" + title="Press Me" + titleStyle={{ color: '#333' }} + tintColor="#2196f3" + truncatedTitle="Press" + width={85} + /> + ); + } +} + +const initAction: NavigationInitAction = NavigationActions.init({ + params: { + foo: "bar" + } +}); + +const navigateAction: NavigationNavigateAction = NavigationActions.navigate({ + routeName: "FooScreen", + params: { + foo: "bar" + }, + action: NavigationActions.navigate({ routeName: "BarScreen" }) +}); + +const resetAction: NavigationResetAction = NavigationActions.reset({ + index: 0, + key: "foo", + actions: [ + NavigationActions.navigate({ routeName: "FooScreen" }) + ] +}); + +const backAction: NavigationBackAction = NavigationActions.back({ + key: "foo" +}); + +const setParamsAction: NavigationSetParamsAction = NavigationActions.setParams({ + key: "foo", + params: { + foo: "bar" + } +}); + +const popAction: NavigationPopAction = NavigationActions.pop({ + n: 1, + immediate: true +}); + +const popToTopAction: NavigationPopToTopAction = NavigationActions.popToTop({ + key: "foo", + immediate: true +}); + +class Page1 extends React.Component { } + +const RootNavigator: NavigationContainer = createSwitchNavigator({ + default: { getScreen: () => Page1 }, +}); + +class Page2 extends React.Component { + navigatorRef: NavigationContainerComponent | null; + + componentDidMount() { + if (this.navigatorRef) { + this.navigatorRef.dispatch(NavigationActions.navigate({ routeName: 'default' })); + } + } + + render() { + return { this.navigatorRef = instance; }} />; + } +} diff --git a/types/react-navigation/v2/tsconfig.json b/types/react-navigation/v2/tsconfig.json new file mode 100644 index 0000000000..1b793c0613 --- /dev/null +++ b/types/react-navigation/v2/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "strictFunctionTypes": false, + "baseUrl": "../../", + "jsx": "react", + "typeRoots": [ + "../../" + ], + "paths": { + "react-navigation": [ + "react-navigation/v2" + ] + }, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.d.ts", + "react-navigation-tests.tsx" + ] +} diff --git a/types/react-navigation/v2/tslint.json b/types/react-navigation/v2/tslint.json new file mode 100644 index 0000000000..3db14f85ea --- /dev/null +++ b/types/react-navigation/v2/tslint.json @@ -0,0 +1 @@ +{ "extends": "dtslint/dt.json" }