import * as React from 'react'; import type { NavigationState, ParamListBase } from '../routers'; import type { DefaultNavigatorOptions, EventMapBase, NavigationListBase, NavigatorScreenParams, NavigatorTypeBagBase, PathConfig, RouteConfigComponent, RouteConfigProps, RouteGroupConfig } from './types'; /** * Flatten a type to remove all type alias names, unions etc. * This will show a plain object when hovering over the type. */ type FlatType = { [K in keyof T]: T[K]; } & {}; /** * keyof T doesn't work for union types. We can use distributive conditional types instead. * https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types */ type KeysOf = T extends {} ? keyof T : never; /** * We get a union type when using keyof, but we want an intersection instead. * https://stackoverflow.com/a/50375286/1665026 */ type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; type UnknownToUndefined = unknown extends T ? undefined : T; type ParamsForScreenComponent = T extends { screen: React.ComponentType<{ route: { params: infer P; }; }>; } ? P : T extends React.ComponentType<{ route: { params: infer P; }; }> ? P : undefined; type ParamsForScreen = T extends { screen: StaticNavigation; } ? NavigatorScreenParams> | undefined : T extends StaticNavigation ? NavigatorScreenParams> | undefined : UnknownToUndefined>; type ParamListForScreens = { [Key in KeysOf]: ParamsForScreen; }; type ParamListForGroups; }; }> | undefined> = Groups extends { [key: string]: { screens: StaticConfigScreens; }; } ? ParamListForScreens> : {}; type StaticRouteConfig = RouteConfigProps & RouteConfigComponent; export type StaticConfigScreens> = { [RouteName in keyof ParamList]: React.ComponentType | StaticNavigation | (Omit, 'name' | 'component' | 'getComponent' | 'children'> & { /** * Callback to determine whether the screen should be rendered or not. * This can be useful for conditional rendering of screens, * e.g. - if you want to render a different screen for logged in users. * * You can use a custom hook to use custom logic to determine the return value. * * @example * ```js * if: useIsLoggedIn * ``` */ if?: () => boolean; /** * Linking config for the screen. * This can be a string to specify the path, or an object with more options. * * @example * ```js * linking: { * path: 'profile/:id', * exact: true, * }, * ``` */ linking?: PathConfig | string; /** * Static navigation config or Component to render for the screen. */ screen: StaticNavigation | React.ComponentType; }); }; export type StaticConfigGroup> = Omit, 'screens' | 'children'> & { /** * Callback to determine whether the screens in the group should be rendered or not. * This can be useful for conditional rendering of group of screens. */ if?: () => boolean; /** * Static navigation config or Component to render for the screen. */ screens: StaticConfigScreens; }; export type StaticConfig = StaticConfigInternal; type StaticConfigInternal, Navigator extends React.ComponentType> = Omit, keyof DefaultNavigatorOptions> & DefaultNavigatorOptions, 'screens' | 'children'> & ({ /** * Screens to render in the navigator and their configuration. */ screens: StaticConfigScreens; /** * Groups of screens to render in the navigator and their configuration. */ groups?: { [key: string]: StaticConfigGroup; }; } | { /** * Screens to render in the navigator and their configuration. */ screens?: StaticConfigScreens; /** * Groups of screens to render in the navigator and their configuration. */ groups: { [key: string]: StaticConfigGroup; }; }); /** * Props for a screen component which is rendered by a static navigator. * Takes the route params as a generic argument. */ export type StaticScreenProps | undefined> = { route: { params: T; }; }; /** * Infer the param list from the static navigation config. */ export type StaticParamList; readonly groups?: { [key: string]: { screens: Record; }; }; }; }> = FlatType & ParamListForGroups>; export type StaticNavigation = { Navigator: React.ComponentType; Group: React.ComponentType; Screen: React.ComponentType; config: StaticConfig; }; /** * Create a component that renders a navigator based on the static configuration. * * @param tree Static navigation config. * @param displayName Name of the component to be displayed in React DevTools. * @returns A component which renders the navigator. */ export declare function createComponentForStaticNavigation(tree: StaticNavigation, displayName: string): React.ComponentType<{}>; type TreeForPathConfig = { config: { initialRouteName?: string; screens?: StaticConfigScreens>; groups?: { [key: string]: { screens: StaticConfigScreens>; }; }; }; }; /** * Create a path config object from a static navigation config for deep linking. * * @param tree Static navigation config. * @param options Additional options from `linking.config`. * @param auto Whether to automatically generate paths for leaf screens. * @returns Path config object to use in linking config. * * @example * ```js * const config = { * screens: { * Home: { * screens: createPathConfigForStaticNavigation(HomeTabs), * }, * }, * }; * ``` */ export declare function createPathConfigForStaticNavigation(tree: TreeForPathConfig, options?: { initialRouteName?: string; }, auto?: boolean): {} | undefined; export {}; //# sourceMappingURL=StaticNavigation.d.ts.map