diff --git a/types/react-navigation/index.d.ts b/types/react-navigation/index.d.ts index e64bfa26be..5286540963 100644 --- a/types/react-navigation/index.d.ts +++ b/types/react-navigation/index.d.ts @@ -3,35 +3,45 @@ // Definitions by: Huhuanming // mhcgrq // fangpenlin +// abrahambotros // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.3 -import * as React from 'react' +/** + * BEGIN FLOW TYPEDEFINITION.JS PORT + * Reference: https://github.com/react-community/react-navigation/tree/52a2846e77119148320bcea83b8982a8bc6acce3 + * + * NOTE: Please update the commit/link above when updating to a new Flow + * TypeDefinition.js reference, so we can conveniently just look at diffs on + * TypeDefinition.js between this latest reference point and the one you are + * using when making new updates. + */ + +import * as React from 'react'; import { Animated, + TextStyle, ViewStyle, - TextStyle -} from 'react-native' +} from 'react-native'; -export type HeaderMode = 'float' | 'screen' | 'none' +// @todo when we split types into common, native and web, +// we can properly change Animated.Value to its real value +type AnimatedValue = any; -export function addNavigationHelpers(params: any): any - -type SubViewProps = NavigationSceneRendererProps & { - onNavigateBack?: () => void, -} - -type SubViewRenderer = (subViewProps: SubViewProps) => React.ReactElement | undefined +export type HeaderMode = 'float' | 'screen' | 'none'; export type HeaderProps = NavigationSceneRendererProps & { mode: HeaderMode, - onNavigateBack?: () => void, - renderLeftComponent: SubViewRenderer, - renderRightComponent: SubViewRenderer, - renderTitleComponent: SubViewRenderer, - tintColor?: string, - router: NavigationRouter, -} + router: NavigationRouter< + NavigationState, + NavigationAction, + NavigationStackScreenOptions + >, + getScreenDetails: (navigationScene: NavigationScene) => NavigationScreenDetails< + NavigationStackScreenOptions + >, + style: Style, +}; /** * NavigationState is a tree of routes for a single navigator, where each child @@ -46,15 +56,17 @@ export type HeaderProps = NavigationSceneRendererProps & { * The state for the root navigator of our app represents the whole navigation * state for the whole app. */ -export interface NavigationState { +export type NavigationState = { /** * Index refers to the active child route in the routes array. */ index: number, - routes: any[], -} + routes: Array, +}; -export interface NavigationRoute

{ +export type NavigationRoute = NavigationLeafRoute | NavigationStateRoute; + +export type NavigationLeafRoute = { /** * React's key used by some navigators. No need to specify these manually, * they will be defined by the router. @@ -73,236 +85,179 @@ export interface NavigationRoute

{ * Params passed to this route when navigating to it, * e.g. `{ car_id: 123 }` in a route that displays a car. */ - params: P, -} + params?: Params, +}; -export interface NavigationRouter { +export type NavigationStateRoute = NavigationLeafRoute & { + index: number, + routes: Array>, +}; + +export type NavigationScreenOptionsGetter = ( + navigation: NavigationScreenProp, Action>, + screenProps?: { [key: string]: any } +) => Options; + +export type 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?: NavigationState, - ) => NavigationState | undefined, + getStateForAction: (action: Action, lastState: (State | null)) => (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 | undefined, + getActionForPathAndParams: ( + path: string, + params?: NavigationParams + ) => (Action | null), - getPathAndParamsForState: (state: NavigationState) => { path: string, params?: NavigationParams }, + getPathAndParamsForState: ( + state: State + ) => { + path: string, + params?: NavigationParams, + }, getComponentForRouteName: (routeName: string) => NavigationComponent, - getComponentForState: (state: NavigationState) => NavigationComponent, + getComponentForState: (state: State) => NavigationComponent, /** - * Gets the screen config for a given navigation screen prop. + * Gets the screen navigation options for a given screen. * - * For example, we could get the config for a 'Foo' screen when the + * For example, we could get the config for the 'Foo' screen when the * `navigation.state` is: * * {routeName: 'Foo', key: '123'} */ - getScreenConfig: ( - navigation: NavigationScreenProp, - optionName: string, - ) => any, // todo, fix this any type to become a key of NavigationScreenConfig -} + getScreenOptions: NavigationScreenOptionsGetter, +}; -type NavigationFunc = (navigation: NavigationScreenProp, config: E) => E +export type NavigationScreenOption = + T + | (( + navigation: NavigationScreenProp, NavigationAction>, + config: T + ) => T); -export type NavigationScreenOption = T | NavigationFunc +export type Style = ViewStyle; -export interface HeaderConfig { - /** - * Title string used by the navigation bar, or a custom component - */ - title?: string | React.ReactElement; +export type NavigationScreenDetails = { + options: T, + state: NavigationRoute, + navigation: NavigationScreenProp, NavigationAction>, +}; - /** - * Whether the navigation bar is visible. - */ - visible?: boolean; - - /** - * Renders a custom right component - */ - right?: React.ReactElement, - - /** - * Renders a custom left component - */ - left?: React.ReactElement - - /** - * Style passed into navigation bar container - */ - style?: ViewStyle, - - /** - * Style passed into navigation bar title - */ - titleStyle?: TextStyle, - - // // Style of title text - // titleTextStyle?: $NavigationThunk, - // // Tint color of navigation bar contents - // tintColor?: $NavigationThunk, - // // Navigation bar height - // height?: $NavigationThunk, - // // Navigation bar translucentcy - // translucent?: $NavigationThunk, - // // Renders a custom left component - // renderLeft?: React.Element<*> | - // (navigation: NavigationProp<*>, canGoBack: boolean) => React.Element<*>, - // // Renders a custom navigation bar background - // renderBackground?: $NavigationThunk>, -} - -export interface TabBarConfig { - /** - * Icon used by the tab bar. - */ - icon?: (options: { tintColor: string, focused: boolean }) => React.ReactElement | undefined; - /** - * Label text used by the tab bar. - */ - label?: string | React.ReactElement; -} - -export interface DrawerConfig { - /** - * Icon used by the drawer. - */ - icon?: (options: { tintColor: string, focused: boolean }) => React.ReactElement | undefined; - /** - * Label text used by the drawer. - */ - label?: string; -} - -export interface CardStackConfig { - /** - * Whether you can use gestures to dismiss this screen. - * Defaults to true on iOS, false on Android. - */ - gesturesEnabled?: boolean; -} - -export interface NavigationScreenOptions { - /** - * Title is rendered by certain navigators, e.g. the tab navigator, - * or on web as the title of the browser tab. - */ - title?: NavigationScreenOption; - /** - * Options passed to the navigation bar for this screen. - */ - header?: NavigationScreenOption; - /** - * Options passed to the tab bar for this screen. - */ - tabBar?: NavigationScreenOption; - /** - * Options passed to the drawer for this screen. - */ - drawer?: NavigationScreenOption; - /** - * Options passed to the card stack for this screen. - */ - cardStack?: NavigationScreenOption; -} - -export interface NavigationScreenConfig { +export type NavigationScreenOptions = { title?: string, - header?: HeaderConfig, - tabBar?: TabBarConfig, - drawer?: DrawerConfig; -} +}; -export type NavigationComponent = NavigationScreenComponent | NavigationNavigator +export type NavigationScreenConfigProps = { + navigation: NavigationScreenProp, NavigationAction>, + screenProps: { [key: string]: any } +}; -export type NavigationScreenComponent = React.ComponentClass & { - navigationOptions?: NavigationScreenOptions, -} +export type NavigationScreenConfig = + Options + | (NavigationScreenConfigProps & + ((navigationOptionsContainer: { + navigationOptions: NavigationScreenProp< + NavigationRoute, + NavigationAction + >, + }) => Options)); -export type NavigationNavigator = React.ComponentClass & { - router?: NavigationRouter, - navigationOptions?: NavigationScreenOptions, -} +export type NavigationComponent = + NavigationScreenComponent + | NavigationNavigator; + +export type NavigationScreenComponent = React.ComponentClass & { + navigationOptions?: NavigationScreenConfig, +}; + +export type NavigationNavigator = React.ComponentClass & { + router?: NavigationRouter, + navigationOptions?: NavigationScreenConfig, +}; export interface NavigationParams { [key: string]: any, } -export interface NavigationNavigateAction { - type?: 'Navigation/NAVIGATE', +export type NavigationNavigateAction = { + type: 'Navigation/NAVIGATE', routeName: string, params?: NavigationParams, // The action to run inside the sub-router action?: NavigationNavigateAction, -} +}; -export interface NavigationBackAction { - type?: 'Navigation/BACK', - key?: string, -} +export type NavigationBackAction = { + type: 'Navigation/BACK', + key?: string | null, +}; -export interface NavigationSetParamsAction { - type?: 'Navigation/SET_PARAMS', +export type NavigationSetParamsAction = { + type: 'Navigation/SET_PARAMS', // 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 NavigationInitAction { - type?: 'Navigation/INIT', +export type NavigationInitAction = { + type: 'Navigation/INIT', params?: NavigationParams, -} +}; -export interface NavigationResetAction { - type?: 'Navigation/RESET', +export type NavigationResetAction = { + type: 'Navigation/RESET', index: number, key?: string | null, - actions: NavigationNavigateAction[], -} + actions: Array, +}; -export interface NavigationUriAction { - type?: 'Navigation/URI', +export type NavigationUriAction = { + type: 'Navigation/URI', uri: string, -} - -export interface NavigationContainerOptions { - // This is used to extract the path from the URI passed to the app for a deep link - URIPrefix?: string, -} - -export interface NavigationContainerConfig { - containerOptions?: NavigationContainerOptions, -} +}; export interface NavigationStackViewConfig { mode?: 'card' | 'modal', headerMode?: HeaderMode, - headerComponent?: React.ComponentClass, - cardStyle?: ViewStyle, + cardStyle?: Style, + transitionConfig?: () => TransitionConfig, onTransitionStart?: () => void, onTransitionEnd?: () => void, } +export type NavigationStackScreenOptions = NavigationScreenOptions & { + header?: (React.ReactElement | ((headerProps: HeaderProps) => React.ReactElement)) | null, + headerTitle?: string | React.ReactElement, + headerTitleStyle?: Style, + headerTintColor?: string, + headerLeft?: React.ReactElement, + headerBackTitle?: string, + headerTruncatedBackTitle?: string, + headerBackTitleStyle?: Style, + headerPressColorAndroid?: string, + headerRight?: React.ReactElement, + headerStyle?: Style, + gesturesEnabled?: boolean, +}; + export interface NavigationStackRouterConfig { initialRouteName?: string, initialRouteParams?: NavigationParams, paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenOptions, + navigationOptions?: NavigationScreenConfig, } export type NavigationStackAction = @@ -310,238 +265,279 @@ export type NavigationStackAction = | NavigationNavigateAction | NavigationBackAction | NavigationSetParamsAction - | NavigationResetAction + | NavigationResetAction; export type NavigationTabAction = NavigationInitAction | NavigationNavigateAction - | NavigationBackAction + | NavigationBackAction; export type NavigationAction = NavigationInitAction | NavigationStackAction - | NavigationTabAction - -export namespace NavigationActions { - function init(options?: NavigationInitAction): NavigationInitAction; - function navigate(options: NavigationNavigateAction): NavigationNavigateAction; - function reset(options: NavigationResetAction): NavigationResetAction; - function back(options?: NavigationBackAction): NavigationBackAction; - function setParams(options: NavigationSetParamsAction): NavigationSetParamsAction; -} + | NavigationTabAction; export type NavigationRouteConfig = T & { - navigationOptions?: NavigationScreenOptions, + navigationOptions?: NavigationScreenConfig, path?: string, -} +}; -export interface NavigationPathsConfig { +export type NavigationScreenRouteConfig = + { + screen: NavigationComponent, + } + | { + getScreen: () => NavigationComponent, + }; + +export type NavigationPathsConfig = { [routeName: string]: string, -} +}; export interface NavigationTabRouterConfig { initialRouteName?: string, paths?: NavigationPathsConfig, - navigationOptions?: NavigationScreenOptions, - order?: string[], // todo: type these as the real route names rather than 'string' + navigationOptions?: NavigationScreenConfig, + order?: Array, // 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 NavigationRouteConfigMap { +export type NavigationTabScreenOptions = NavigationScreenOptions & { + tabBarIcon?: + React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)), + tabBarLabel?: + string + | React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)), + tabBarVisible?: boolean, +}; + +export type NavigationDrawerScreenOptions = NavigationScreenOptions & { + drawerIcon?: + React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)), + drawerLabel?: + React.ReactElement + | ((options: { tintColor: (string | null), focused: boolean }) => (React.ReactElement< + any + > | null)), +}; + +export type NavigationRouteConfigMap = { [routeName: string]: NavigationRouteConfig, -} +}; -export type NavigationDispatch = (action: A) => boolean +export type NavigationDispatch = (action: A) => boolean; -export interface NavigationProp { +export type NavigationProp = { state: S, dispatch: NavigationDispatch, -} +}; -export type NavigationScreenProp = NavigationProp & { - goBack: (routeKey?: string | null) => boolean, - navigate: (routeName: string, params?: NavigationParams, action?: NavigationAction) => boolean, +export type NavigationScreenProp = { + state: S, + dispatch: NavigationDispatch, + goBack: (routeKey?: (string | null)) => boolean, + navigate: ( + routeName: string, + params?: NavigationParams, + action?: NavigationAction + ) => boolean, setParams: (newParams: NavigationParams) => boolean, -} +}; -export interface NavigationNavigatorProps

{ - navigation: NavigationProp, NavigationAction>, -} +export type NavigationNavigatorProps = { + navigation?: NavigationProp, + screenProps?: { [key: string]: any } + navigationOptions?: any, +}; /** * Gestures, Animations, and Interpolators */ -export type NavigationAnimatedValue = Animated.Value +export type NavigationGestureDirection = 'horizontal' | 'vertical'; -export type NavigationGestureDirection = 'horizontal' | 'vertical' - -export interface NavigationLayout { - height: NavigationAnimatedValue, +export type NavigationLayout = { + height: AnimatedValue, initHeight: number, initWidth: number, isMeasured: boolean, - width: NavigationAnimatedValue, -} + width: AnimatedValue, +}; -export interface NavigationScene { +export type NavigationScene = { index: number, isActive: boolean, isStale: boolean, key: string, - route: any, -} + route: NavigationRoute, +}; -export interface NavigationTransitionProps { - // The layout of the transitioner of the scenes. +export type NavigationTransitionProps = { + // The layout of the screen container layout: NavigationLayout, - // The navigation state of the transitioner. - navigationState: NavigationState, + // The destination navigation state of the transition + navigation: NavigationScreenProp, // The progressive index of the transitioner's navigation state. - position: NavigationAnimatedValue, + 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: NavigationAnimatedValue, + progress: AnimatedValue, // All the scenes of the transitioner. - scenes: NavigationScene[], + scenes: Array, // The active scene, corresponding to the route at - // `navigationState.routes[navigationState.index]`. When rendering + // `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, - navigation: NavigationScreenProp, - // The gesture distance for `horizontal` and `vertical` transitions - gestureResponseDistance?: 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 type NavigationSceneRendererProps = NavigationTransitionProps; -export interface NavigationPanHandlers { - onMoveShouldSetResponder: () => void, - onMoveShouldSetResponderCapture: () => void, - onResponderEnd: () => void, - onResponderGrant: () => void, - onResponderMove: () => void, - onResponderReject: () => void, - onResponderRelease: () => void, - onResponderStart: () => void, - onResponderTerminate: () => void, - onResponderTerminationRequest: () => void, - onStartShouldSetResponder: () => void, - onStartShouldSetResponderCapture: () => void, -} - -export interface NavigationTransitionSpec { +export type NavigationTransitionSpec = { duration?: number, // An easing function from `Easing`. - easing?: () => any, + easing?: (t: number) => number, // A timing function such as `Animated.timing`. - timing?: (value: NavigationAnimatedValue, config: any) => any, -} + timing?: (value: AnimatedValue, config: any) => any, +}; + +/** + * Describes a visual transition from one screen to another. + */ +export type 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, +}; export type NavigationAnimationSetter = ( - position: NavigationAnimatedValue, + position: AnimatedValue, newState: NavigationState, - lastState: NavigationState, -) => void + lastState: NavigationState +) => void; -export type NavigationSceneRenderer = ( - props: NavigationSceneRendererProps, -) => React.ReactElement +export type NavigationSceneRenderer = () => (React.ReactElement | null); export type NavigationStyleInterpolator = ( - props: NavigationSceneRendererProps, -) => ViewStyle + props: NavigationSceneRendererProps +) => Style; -export interface LayoutEvent { +export type LayoutEvent = { nativeEvent: { layout: { - x: number; - y: number; - width: number; - height: number; + x: number, + y: number, + width: number, + height: number, }, - } -} + }, +}; +/** + * END FLOW TYPEDEFINITION.JS PORT + */ + + +/** + * BEGIN MANUAL DEFINITIONS OUTSIDE OF TYPEDEFINITION.JS + */ + +// From addNavigatorHelpers.js +export function addNavigationHelpers(navigation: NavigationProp): NavigationScreenProp; + +// From createNavigationContainer.js interface NavigationContainerProps { - screenProps?: any - navigation?: NavigationProp + uriPrefix?: string | RegExp, onNavigationStateChange?: ( - preNavigationState: NavigationState, + prevNavigationState: NavigationState, nextNavigationState: NavigationState, + action: NavigationAction, ) => void, - style?: ViewStyle -} - -interface NavigationContainerState { - nav?: NavigationState + style?: ViewStyle, } export interface NavigationContainer extends React.ComponentClass< - NavigationContainerProps + NavigationContainerProps & NavigationNavigatorProps > { - router: NavigationRouter + router: NavigationRouter + screenProps: { [key: string]: any }, + navigationOptions: any, + state: { nav: NavigationState | null }, } -export type StackNavigatorConfig = - NavigationContainerConfig - & NavigationStackViewConfig - & NavigationStackRouterConfig; +export interface StackNavigatorConfig extends NavigationStackViewConfig, NavigationStackRouterConfig { + containerOptions?: any, +} // Return createNavigationContainer -export function StackNavigator( +export function StackNavigator( routeConfigMap: NavigationRouteConfigMap, stackConfig?: StackNavigatorConfig, -): NavigationContainer +): NavigationContainer; /** * Drawer Navigator */ -export interface DrawNavigatorConfig { - drawerWidth?: number, - drawerPosition?: 'left'|'right', - contentComponent?: React.ReactElement, +export interface DrawerViewConfig { + drawerWidth: number, + drawerPosition: 'left' | 'right', + contentComponent: React.ComponentClass, + contentOptions?: any, + style?: ViewStyle, +} +export interface DrawerNavigatorConfig extends NavigationTabRouterConfig, DrawerViewConfig { + containerConfig?: any, contentOptions?: { activeTintColor?: string, activeBackgroundColor?: string, inactiveTintColor?: string, inactiveBackgroundColor?: string, style?: ViewStyle, - labelStyle?: TextStyle + labelStyle?: TextStyle, } } -export function DrawerNavigator( +export function DrawerNavigator( routeConfigMap: NavigationRouteConfigMap, - drawConfig?: DrawNavigatorConfig, + drawerConfig?: DrawerNavigatorConfig, ): NavigationContainer; /** * Tab Navigator */ -export interface TabNavigatorConfig { - tabBarComponent?: React.ReactElement, - tabBarPosition?: 'top'|'bottom', - swipeEnabled?: boolean, - animationEnabled?: boolean, - lazy?: boolean, + +// From views/TabView/TabView.js +export interface TabViewConfig { + tabBarComponent?: React.ComponentClass, + tabBarPosition?: 'top' | 'bottom', tabBarOptions?: { activeTintColor?: string, activeBackgroundColor?: string, @@ -559,104 +555,83 @@ export interface TabNavigatorConfig { scrollEnabled?: boolean, tabStyle?: ViewStyle, indicatorStyle?: ViewStyle - } - initialRouteName?: string, - order?: string[], - paths?: any // TODO: better def - backBehavior?: 'initialRoute'|'none' + }, + swipeEnabled?: boolean, + animationEnabled?: boolean, + lazy?: boolean, } -export function TabNavigator( +// From navigators/TabNavigator.js +export interface TabNavigatorConfig extends NavigationTabRouterConfig, TabViewConfig { } + +// From navigators/TabNavigator.js +export function TabNavigator( routeConfigMap: NavigationRouteConfigMap, drawConfig?: TabNavigatorConfig, ): NavigationContainer; + +export const TabBarTop: React.ComponentClass; +export const TabBarBottom: React.ComponentClass; + /** - * Screen Options + * NavigationActions + * @todo Is this necessary, or can we remove? Not referenced anywhere else here, but it seems a + * recent commit or two touches these. Can anyone provide a strong use case for keeping this in? */ -export interface StackNavigatorScreenOptions { - title?: string; - headerVisible?: boolean; - headerTitle?: string|React.ReactElement; - headerBackTitle?: string; - headerTruncatedBackTitle?: string; - headerRight?: React.ReactElement; - headerLeft?: React.ReactElement; - headerStyle?: ViewStyle; - headerTitleStyle?: TextStyle; - headerTintColor?: string; - headerPressColorAndroid?: string; - gesturesEnabled?: boolean; +export namespace NavigationActions { + function init(options?: NavigationInitAction): NavigationInitAction; + function navigate(options: NavigationNavigateAction): NavigationNavigateAction; + function reset(options: NavigationResetAction): NavigationResetAction; + function back(options?: NavigationBackAction): NavigationBackAction; + function setParams(options: NavigationSetParamsAction): NavigationSetParamsAction; } -export interface TabNavigatorScreenOptions { - title?: string; - tabBarVisible?: boolean; - tabBarIcon?: React.ReactElement - | ((options: { focused: boolean, tintColor: string }) => React.ReactElement); - tabBarLabel?: string - | React.ReactElement - | ((options: { focused: boolean, tintColor: string }) => React.ReactElement); -} - -export interface DrawerNavigatorScreenOptions { - title?: string; - drawerLabel?: string - |React.ReactElement - | ((options: {focused: boolean, tintColor: string}) => React.ReactElement) - ; - drawerIcon?: React.ReactElement - | ((options: {focused: boolean, tintColor: string}) => React.ReactElement) - ; -} - -export type NavigationNavigateActionCreator = (options: NavigationNavigateAction) => boolean; -export type NavigationResetActionCreator = (options: NavigationResetAction) => boolean; -export type NavigationBackActionCreator = (options?: NavigationBackAction) => boolean; -export type NavigationSetParamsActionCreator = (options: NavigationSetParamsAction) => boolean; - -export interface NavigationComponentProps { - screenProps: any - navigation: { - dispatch: any - goBack: NavigationBackActionCreator - navigate: NavigationNavigateActionCreator - setParams: NavigationSetParamsActionCreator - state: { - key: string - routeName: string, - params: T, - }, - } -} - -export const TabBarTop: React.ReactElement; -export const TabBarBottom: React.ReactElement; - +/** + * Transitioner + * @desc From react-navigation/src/views/Transitioner.js + */ interface TransitionerProps { configureTransition: ( transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps - ) => NavigationTransitionSpec - navigation: NavigationProp - onTransitionEnd?: () => void - onTransitionStart?: () => void + ) => NavigationTransitionSpec, + navigation: NavigationScreenProp, + onTransitionEnd?: () => void, + onTransitionStart?: () => void, render: ( transitionProps: NavigationTransitionProps, prevTransitionProps?: NavigationTransitionProps ) => any - style?: ViewStyle + style?: ViewStyle, } interface TransitionerState { - layout: NavigationLayout - position: Animated.Value - progress: Animated.Value - scenes: Array + layout: NavigationLayout, + position: Animated.Value, + progress: Animated.Value, + scenes: Array, } export class Transitioner extends React.Component< TransitionerProps, TransitionerState -> { +> { } +/** + * END MANUAL DEFINITIONS OUTSIDE OF TYPEDEFINITION.JS + */ + + +/** + * BEGIN CUSTOM CONVENIENCE INTERFACES + */ + +export interface NavigationScreenProps { + navigation: NavigationScreenProp, NavigationAction>, + screenProps?: { [key: string]: any }, + navigationOptions?: NavigationScreenConfig, } + +/** + * END CUSTOM CONVENIENCE INTERFACES + */ diff --git a/types/react-navigation/react-navigation-tests.tsx b/types/react-navigation/react-navigation-tests.tsx index 738bd8c456..835e63d756 100644 --- a/types/react-navigation/react-navigation-tests.tsx +++ b/types/react-navigation/react-navigation-tests.tsx @@ -1,81 +1,221 @@ import * as React from 'react'; -import { View } from 'react-native'; +import { + TouchableOpacity, + View, + ViewStyle, +} from 'react-native'; import { addNavigationHelpers, + NavigationRouteConfigMap, + NavigationScreenProp, + NavigationScreenProps, + NavigationStackAction, + NavigationStackScreenOptions, + NavigationTabScreenOptions, StackNavigator, - TabNavigatorScreenOptions, + StackNavigatorConfig, + TabNavigator, TabNavigatorConfig, TabBarTop, - TabBarBottom, + Transitioner, NavigationProp, NavigationAction, NavigationTransitionProps, - Transitioner } from 'react-navigation'; -const Start = ( - +// Constants +const viewStyle: ViewStyle = { + flex: 1, + margin: 42, + padding: 0, + backgroundColor: "white", +}; + + +/** + * @class StartScreen @extends React.Component + * @desc Simple screen component class with typed component props that should + * receive the navigation prop from the AppNavigator. + */ +const ROUTE_NAME_START_SCREEN = "StartScreen"; +interface StartScreenNavigationParams { + id: number, + s: string, +} +interface StartScreenProps extends NavigationScreenProps { } +class StartScreen extends React.Component { + render() { + // Implicit type checks. + const navigationStateParams: StartScreenNavigationParams = this.props.navigation.state.params; + const id = this.props.navigation.state.params.id; + const s = this.props.navigation.state.params.s; + + return ( + + + + ); + } + private navigateToNextScreen = (): void => { + this.props.navigation.navigate( + ROUTE_NAME_NEXT_SCREEN, + { + id: this.props.navigation.state.params.id, + name: this.props.navigation.state.params.s, + } as NextScreenNavigationParams, + ); + + } +} + +/** + * @class NextScreen @extends React.Component + */ +const ROUTE_NAME_NEXT_SCREEN = "NextScreen"; +interface NextScreenNavigationParams { + id: number, + name: string, +} +interface NextScreenProps extends NavigationScreenProps { } +class NextScreen extends React.Component { + render() { + // Implicit type checks. + const navigationStateParams: NextScreenNavigationParams = this.props.navigation.state.params; + const id = this.props.navigation.state.params.id; + const name = this.props.navigation.state.params.name; + + return ( + + ); + } +} + +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 = StackNavigator( + routeConfigMap, + { + initialRouteName: ROUTE_NAME_START_SCREEN, + initialRouteParams, + }, ); -export const AppNavigator = StackNavigator({ - StartImage: { - path: 'startImage', - screen: Start, - }, -}, { - initialRouteName: 'StartImage', -}); - +/** + * Router. + */ const Router = (props: any) => ( - true, + state: {}, + }) + } /> ); -const tabNavigatorScreenOptions: TabNavigatorScreenOptions = { + +/** + * Tab navigator. + */ + +const tabNavigatorScreenOptions: NavigationTabScreenOptions = { title: 'title', tabBarVisible: true, tabBarIcon: , tabBarLabel: 'label', -} +}; const tabNavigatorConfig: TabNavigatorConfig = { lazy: true, tabBarComponent: TabBarTop, + tabBarOptions: tabNavigatorScreenOptions, +}; + +const BasicTabNavigator = TabNavigator( + routeConfigMap, + tabNavigatorConfig, +); + +function renderBasicTabNavigator(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); } + +/** + * Stack navigator. + */ + +const stackNavigatorScreenOptions: NavigationStackScreenOptions = { + title: 'title', +}; + +const stackNavigatorConfig: StackNavigatorConfig = { + mode: "card", + headerMode: "screen", + navigationOptions: stackNavigatorScreenOptions, +}; + +const BasicStackNavigator = StackNavigator( + routeConfigMap, + stackNavigatorConfig, +); + +function renderBasicStackNavigator(): JSX.Element { + return ( + { }} + style={viewStyle} + /> + ); +} + + +/** + * @class CustomTransitioner @extends React.Component + * @desc Custom transitioner component. Follows react-navigation/src/views/CardStackTransitioner.js. + */ interface CustomTransitionerProps { - navigation: NavigationProp + navigation: NavigationScreenProp } - -const configureTransition = ( - _transitionProps: NavigationTransitionProps, - _prevTransitionProps: NavigationTransitionProps - ) => { - return {} - } - -const renderTransitioner = (props: NavigationTransitionProps, prevProps: NavigationTransitionProps) => { - return +class CustomTransitioner extends React.Component { + render() { + return ( + { }} + onTransitionEnd={() => { }} + /> + ); + } + _render = (props: NavigationTransitionProps, prevProps: NavigationTransitionProps): React.ReactElement => { + return ( + + ); + } + _configureTransition = ( + _transitionProps: NavigationTransitionProps, + _prevTransitionProps: NavigationTransitionProps + ) => { + return {} + } } - -const CustomTransitioner = (props: CustomTransitionerProps) => { - { }} - onTransitionEnd={() => { }} - /> -} - -const BasicStackNavigation = StackNavigator({ - StartScreen: { screen: Start } -}); - - diff --git a/types/react-navigation/tsconfig.json b/types/react-navigation/tsconfig.json index e670f06667..ad15863a78 100644 --- a/types/react-navigation/tsconfig.json +++ b/types/react-navigation/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "module": "commonjs", "lib": [ - "es6" + "es6", + "dom" ], "noImplicitAny": true, "noImplicitThis": true,