@react-navigation/core
Version:
Core utilities for building navigators
850 lines • 36.1 kB
TypeScript
import type { DefaultRouterOptions, InitialState, NavigationAction, NavigationState, ParamListBase, PartialState, Route, Router } from '@react-navigation/routers';
import type * as React from 'react';
/**
* Flatten a type to remove all type alias names, unions etc.
* This will show a plain object when hovering over the type.
*/
type FlatType<T> = {
[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> = 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> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type UnknownToUndefined<T> = unknown extends T ? undefined : T;
type ParamsForScreenComponent<T> = T extends {
screen: React.ComponentType<{
route: {
params: infer P;
};
}>;
} ? P : T extends React.ComponentType<{
route: {
params: infer P;
};
}> ? P : undefined;
type StaticNavigationConfig = {
readonly config: {
readonly screens?: Record<string, any>;
readonly groups?: {
[key: string]: {
screens: Record<string, any>;
};
};
};
};
type ParamsForScreen<T> = T extends {
screen: infer Screen;
} ? Screen extends StaticNavigationConfig ? NavigatorScreenParams<StaticParamList<Screen>> | undefined : UnknownToUndefined<ParamsForScreenComponent<T>> : T extends StaticNavigationConfig ? NavigatorScreenParams<StaticParamList<T>> | undefined : UnknownToUndefined<ParamsForScreenComponent<T>>;
type ParamListForScreens<Screens> = {
[Key in KeysOf<Screens>]: ParamsForScreen<Screens[Key]>;
};
type ParamListForGroups<Groups extends Readonly<{
[key: string]: {
screens: Record<string, any>;
};
}> | undefined> = Groups extends {
[key: string]: {
screens: Record<string, any>;
};
} ? ParamListForScreens<UnionToIntersection<Groups[keyof Groups]['screens']>> : {};
/**
* Infer the param list from the static navigation config.
*/
export type StaticParamList<T extends StaticNavigationConfig> = FlatType<ParamListForScreens<T['config']['screens']> & ParamListForGroups<T['config']['groups']>>;
type ParamListForStaticNavigator<T> = T extends StaticNavigationConfig ? StaticParamList<T> : {};
type ParamListForTypedNavigator<T> = T extends {
Screen: any;
} & PrivateValueStore<infer Value> ? Value[0] : {};
type ParamListForRootNavigator<T> = string extends keyof ParamListForTypedNavigator<T> ? ParamListForStaticNavigator<T> : ParamListForTypedNavigator<T>;
/**
* Root navigator used in the app.
* It's used for the global types in the app.
*
* Users need to use module augmentation to add their navigator type:
*
* ```ts
* // Navigator created with static or dynamic API
* const RootStack = createStackNavigator({
* // ...
* });
*
* type RootStackType = typeof RootStack;
*
* declare module '@react-navigation/core' {
* interface RootNavigator extends RootStackType {}
* }
* ```
*/
export interface RootNavigator {
}
/**
* Theme object for the navigation components.
*
* Custom properties can be added using declaration merging:
*
* ```ts
* declare module '@react-navigation/core' {
* interface Theme extends NativeTheme {
* myCustomProperty: string;
* }
* }
* ```
*/
export interface Theme {
}
type RootTheme = Theme;
declare global {
namespace ReactNavigation {
interface RootParamList extends ParamListForRootNavigator<RootNavigator> {
}
interface Theme extends RootTheme {
}
}
}
type Keyof<T extends {}> = Extract<keyof T, string>;
export type DefaultNavigatorOptions<ParamList extends ParamListBase, NavigatorID extends string | undefined, State extends NavigationState, ScreenOptions extends {}, EventMap extends EventMapBase, Navigation> = DefaultRouterOptions<Keyof<ParamList>> & {
/**
* Children React Elements to extract the route configuration from.
* Only `Screen`, `Group` and `React.Fragment` are supported as children.
*/
children: React.ReactNode;
/**
* Layout for the navigator.
* Useful for wrapping with a component with access to navigator's state and options.
*/
layout?: (props: {
state: State;
navigation: NavigationHelpers<ParamList>;
descriptors: Record<string, Descriptor<ScreenOptions, NavigationProp<ParamList, keyof ParamList, string | undefined, State, ScreenOptions, EventMap>, RouteProp<ParamList>>>;
children: React.ReactNode;
}) => React.ReactElement;
/**
* Event listeners for all the screens in the navigator.
*/
screenListeners?: ScreenListeners<State, EventMap> | ((props: {
route: RouteProp<ParamList>;
navigation: Navigation;
}) => ScreenListeners<State, EventMap>);
/**
* Default options for all screens under this navigator.
*/
screenOptions?: ScreenOptions | ((props: {
route: RouteProp<ParamList>;
navigation: Navigation;
theme: ReactNavigation.Theme;
}) => ScreenOptions);
/**
* Layout for all screens under this navigator.
*/
screenLayout?: (props: ScreenLayoutArgs<ParamList, keyof ParamList, ScreenOptions, Navigation>) => React.ReactElement;
/**
* A function returning overrides for the underlying router used by the navigator.
* The overrides will be shallow merged onto the original router.
* It receives the original router as an argument to the function.
*
* This must be a pure function and cannot reference outside dynamic variables.
*/
UNSTABLE_router?: <Action extends NavigationAction>(original: Router<State, Action>) => Partial<Router<State, Action>>;
/**
* What should happen when the available route names change.
* e.g. when different screens are rendered based on a condition.
*
* - 'firstMatch': Navigate to the first route in the new list of routes (default).
* - 'lastUnhandled': Restore the last state that was unhandled due to conditional render.
*
* Example cases where previous state might have been unhandled:
* - Opened a deep link to a screen, but a login screen was shown.
* - Navigated to a screen containing a navigator, but a different screen was shown.
* - Reset the navigator to a state with different routes not matching the current list of routes.
*
* In these cases, 'lastUnhandled' will reuse the unhandled state if present.
* If there's no unhandled state, it will fallback to 'firstMatch' behavior.
*
* Caveats:
* - Direct navigation is only handled for `NAVIGATE` actions.
* - Unhandled state is restored only if the current state becomes invalid, i.e. it doesn't contain any currently defined screens.
*/
UNSTABLE_routeNamesChangeBehavior?: 'firstMatch' | 'lastUnhandled';
} & (NavigatorID extends string ? {
/**
* Optional ID for the navigator. Can be used with `navigation.getParent(id)` to refer to a parent.
*/
id: NavigatorID;
} : {
id?: undefined;
});
export type EventMapBase = Record<string, {
data?: any;
canPreventDefault?: boolean;
}>;
export type EventMapCore<State extends NavigationState> = {
focus: {
data: undefined;
};
blur: {
data: undefined;
};
state: {
data: {
state: State;
};
};
beforeRemove: {
data: {
action: NavigationAction;
};
canPreventDefault: true;
};
};
export type EventArg<EventName, CanPreventDefault extends boolean | undefined = false, Data = undefined> = {
/**
* Type of the event (e.g. `focus`, `blur`)
*/
readonly type: EventName;
readonly target?: string;
} & (CanPreventDefault extends true ? {
/**
* Whether `event.preventDefault()` was called on this event object.
*/
readonly defaultPrevented: boolean;
/**
* Prevent the default action which happens on this event.
*/
preventDefault(): void;
} : {}) & (undefined extends Data ? {
readonly data?: Readonly<Data>;
} : {
readonly data: Readonly<Data>;
});
export type EventListenerCallback<EventMap extends EventMapBase, EventName extends keyof EventMap, EventCanPreventDefault extends boolean | undefined = EventMap[EventName]['canPreventDefault']> = (e: EventArg<EventName, undefined extends EventCanPreventDefault ? false : EventCanPreventDefault, EventMap[EventName]['data']>) => void;
export type EventConsumer<EventMap extends EventMapBase> = {
/**
* Subscribe to events from the parent navigator.
*
* @param type Type of the event (e.g. `focus`, `blur`)
* @param callback Callback listener which is executed upon receiving the event.
*/
addListener<EventName extends Keyof<EventMap>>(type: EventName, callback: EventListenerCallback<EventMap, EventName>): () => void;
removeListener<EventName extends Keyof<EventMap>>(type: EventName, callback: EventListenerCallback<EventMap, EventName>): void;
};
export type EventEmitter<EventMap extends EventMapBase> = {
/**
* Emit an event to child screens.
*
* @param options.type Type of the event (e.g. `focus`, `blur`)
* @param [options.data] Optional information regarding the event.
* @param [options.target] Key of the target route which should receive the event.
* If not specified, all routes receive the event.
*/
emit<EventName extends Keyof<EventMap>>(options: {
type: EventName;
target?: string;
} & (EventMap[EventName]['canPreventDefault'] extends true ? {
canPreventDefault: true;
} : {}) & (undefined extends EventMap[EventName]['data'] ? {
data?: EventMap[EventName]['data'];
} : {
data: EventMap[EventName]['data'];
})): EventArg<EventName, EventMap[EventName]['canPreventDefault'], EventMap[EventName]['data']>;
};
export declare class PrivateValueStore<T extends [any, any, any]> {
/**
* UGLY HACK! DO NOT USE THE TYPE!!!
*
* TypeScript requires a type to be used to be able to infer it.
* The type should exist as its own without any operations such as union.
* So we need to figure out a way to store this type in a property.
* The problem with a normal property is that it shows up in intelliSense.
* Adding private keyword works, but the annotation is stripped away in declaration.
* Turns out if we use an empty string, it doesn't show up in intelliSense.
*/
protected ''?: T;
}
type NavigationHelpersCommon<ParamList extends ParamListBase, State extends NavigationState = NavigationState> = {
/**
* Dispatch an action or an update function to the router.
* The update function will receive the current state,
*
* @param action Action object or update function.
*/
dispatch(action: NavigationAction | ((state: Readonly<State>) => NavigationAction)): void;
/**
* Navigate to a screen in the current or parent navigator.
* If we're already on the screen, update the params instead.
*
* @param screen Name of the route to navigate to.
* @param [params] Params object for the route.
* @param [options.merge] Whether to merge the params onto the route. Defaults to `false`.
* @param [options.pop] Whether to pop routes in a stack to go back to the matching route. Defaults to `false`.
*/
navigate<RouteName extends keyof ParamList>(...args: RouteName extends unknown ? undefined extends ParamList[RouteName] ? [
screen: RouteName,
params?: ParamList[RouteName],
options?: {
merge?: boolean;
pop?: boolean;
}
] : [
screen: RouteName,
params: ParamList[RouteName],
options?: {
merge?: boolean;
pop?: boolean;
}
] : never): void;
/**
* Navigate to a route in current navigation tree.
*
* @param options.name Name of the route to navigate to.
* @param [options.params] Params object for the route.
* @param [options.path] Path to associate the route with (e.g. for deep links).
* @param [options.merge] Whether to merge the params onto the route. Defaults to `false`.
* @param [options.pop] Whether to pop routes in a stack to go back to the matching route. Defaults to `false`.
*/
navigate<RouteName extends keyof ParamList>(options: RouteName extends unknown ? {
name: RouteName;
params: ParamList[RouteName];
path?: string;
merge?: boolean;
pop?: boolean;
} : never): void;
/**
* Navigate to a route in current navigation tree.
*
* @deprecated Use `navigate` instead.
*
* @param screen Name of the route to navigate to.
* @param [params] Params object for the route.
*/
navigateDeprecated<RouteName extends keyof ParamList>(...args: RouteName extends unknown ? undefined extends ParamList[RouteName] ? [screen: RouteName, params?: ParamList[RouteName]] : [screen: RouteName, params: ParamList[RouteName]] : never): void;
/**
* Navigate to a route in current navigation tree.
*
* @deprecated Use `navigate` instead.
*
* @param options Object with `name` for the route to navigate to, and a `params` object.
*/
navigateDeprecated<RouteName extends keyof ParamList>(options: RouteName extends unknown ? {
name: RouteName;
params: ParamList[RouteName];
merge?: boolean;
} : never): void;
/**
* Preloads the route in current navigation tree.
*
* @param screen Name of the route to preload.
* @param [params] Params object for the route.
*/
preload<RouteName extends keyof ParamList>(...args: RouteName extends unknown ? undefined extends ParamList[RouteName] ? [screen: RouteName, params?: ParamList[RouteName]] : [screen: RouteName, params: ParamList[RouteName]] : never): void;
/**
* Reset the navigation state to the provided state.
*
* @param state Navigation state object.
*/
reset(state: PartialState<State> | State): void;
/**
* Go back to the previous route in history.
*/
goBack(): void;
/**
* Check if the screen is focused. The method returns `true` if focused, `false` otherwise.
* Note that this method doesn't re-render screen when the focus changes. So don't use it in `render`.
* To get notified of focus changes, use `addListener('focus', cb)` and `addListener('blur', cb)`.
* To conditionally render content based on focus state, use the `useIsFocused` hook.
*/
isFocused(): boolean;
/**
* Check if dispatching back action will be handled by navigation.
* Note that this method doesn't re-render screen when the result changes. So don't use it in `render`.
*/
canGoBack(): boolean;
/**
* Returns the name of the navigator specified in the `name` prop.
* If no name is specified, returns `undefined`.
*/
getId(): string | undefined;
/**
* Returns the navigation helpers from a parent navigator based on the ID.
* If an ID is provided, the navigation helper from the parent navigator with matching ID (including current) will be returned.
* If no ID is provided, the navigation helper from the immediate parent navigator will be returned.
*
* @param id Optional ID of a parent navigator.
*/
getParent<T = NavigationHelpers<ParamListBase> | undefined>(id?: string): T;
/**
* Returns the navigator's state.
* Note that this method doesn't re-render screen when the result changes. So don't use it in `render`.
*/
getState(): State;
} & PrivateValueStore<[ParamList, unknown, unknown]>;
type NavigationHelpersRoute<ParamList extends {}, RouteName extends keyof ParamList = Keyof<ParamList>> = {
/**
* Update the param object for the route.
* The new params will be shallow merged with the old one.
*
* @param params Partial params object for the current route.
*/
setParams(params: ParamList[RouteName] extends undefined ? undefined : Partial<ParamList[RouteName]>): void;
/**
* Replace the param object for the route
*
* @param params Params object for the current route.
*/
replaceParams(params: ParamList[RouteName] extends undefined ? undefined : ParamList[RouteName]): void;
};
export type NavigationHelpers<ParamList extends ParamListBase, EventMap extends EventMapBase = {}> = NavigationHelpersCommon<ParamList> & EventEmitter<EventMap> & NavigationHelpersRoute<ParamList, keyof ParamList>;
export type NavigationContainerProps = {
/**
* Initial state object for the navigation tree.
*/
initialState?: InitialState;
/**
* Callback which is called with the latest navigation state when it changes.
*/
onStateChange?: (state: Readonly<NavigationState> | undefined) => void;
/**
* Callback which is called after the navigation tree mounts.
*/
onReady?: () => void;
/**
* Callback which is called when an action is not handled.
*/
onUnhandledAction?: (action: Readonly<NavigationAction>) => void;
/**
* Whether child navigator should handle a navigation action.
* The child navigator needs to be mounted before it can handle the action.
* Defaults to `false`.
*
* This will be removed in the next major release.
*
* @deprecated Use nested navigation API instead
*/
navigationInChildEnabled?: boolean;
/**
* Theme object for the UI elements.
*/
theme?: ReactNavigation.Theme;
/**
* Children elements to render.
*/
children: React.ReactNode;
};
export type NavigationProp<ParamList extends {}, RouteName extends keyof ParamList = Keyof<ParamList>, NavigatorID extends string | undefined = string | undefined, State extends NavigationState = NavigationState<ParamList>, ScreenOptions extends {} = {}, EventMap extends EventMapBase = {}> = Omit<NavigationHelpersCommon<ParamList, State>, 'getParent'> & {
/**
* Returns the navigation prop from a parent navigator based on the ID.
* If an ID is provided, the navigation prop from the parent navigator with matching ID (including current) will be returned.
* If no ID is provided, the navigation prop from the immediate parent navigator will be returned.
*
* @param id Optional ID of a parent navigator.
*/
getParent<T = NavigationProp<ParamListBase> | undefined>(id?: NavigatorID): T;
/**
* Update the options for the route.
* The options object will be shallow merged with default options object.
*
* @param update Options object or a callback which takes the options from navigator config and returns a new options object.
*/
setOptions(options: Partial<ScreenOptions>): void;
} & NavigationHelpersRoute<ParamList, RouteName> & EventConsumer<EventMap & EventMapCore<State>> & PrivateValueStore<[ParamList, RouteName, EventMap]>;
export type RouteProp<ParamList extends ParamListBase, RouteName extends keyof ParamList = Keyof<ParamList>> = Route<Extract<RouteName, string>, ParamList[RouteName]>;
export type CompositeNavigationProp<A extends NavigationProp<ParamListBase, string, any, any, any>, B extends NavigationHelpersCommon<ParamListBase, any>> = Omit<A & B, keyof NavigationProp<any>> & NavigationProp<
/**
* Param list from both navigation objects needs to be combined
* For example, we should be able to navigate to screens in both A and B
*/
(A extends NavigationHelpersCommon<infer T> ? T : never) & (B extends NavigationHelpersCommon<infer U> ? U : never),
/**
* The route name should refer to the route name specified in the first type
* Ideally it should work for any of them, but it's not possible to infer that way
*/
A extends NavigationProp<any, infer R> ? R : string,
/**
* ID from both navigation objects needs to be combined for `getParent`
*/
(A extends NavigationProp<any, any, infer I> ? I : never) | (B extends NavigationProp<any, any, infer J> ? J : never),
/**
* The type of state should refer to the state specified in the first type
*/
A extends NavigationProp<any, any, any, infer S> ? S : NavigationState,
/**
* Screen options should refer to the options specified in the first type
*/
A extends NavigationProp<any, any, any, any, infer O> ? O : {},
/**
* Event consumer config should refer to the config specified in the first type
* This allows typechecking `addListener`/`removeListener`
*/
A extends NavigationProp<any, any, any, any, any, infer E> ? E : {}>;
export type CompositeScreenProps<A extends {
navigation: NavigationProp<ParamListBase, string, string | undefined, any, any, any>;
route: RouteProp<ParamListBase>;
}, B extends {
navigation: NavigationHelpersCommon<any, any>;
}> = {
navigation: CompositeNavigationProp<A['navigation'], B['navigation']>;
route: A['route'];
};
export type ScreenLayoutArgs<ParamList extends ParamListBase, RouteName extends keyof ParamList, ScreenOptions extends {}, Navigation> = {
route: RouteProp<ParamList, RouteName>;
options: ScreenOptions;
navigation: Navigation;
theme: ReactNavigation.Theme;
children: React.ReactElement;
};
export type Descriptor<ScreenOptions extends {}, Navigation extends NavigationProp<any, any, any, any, any, any>, Route extends RouteProp<any, any>> = {
/**
* Render the component associated with this route.
*/
render(): React.JSX.Element;
/**
* Options for the route.
*/
options: ScreenOptions;
/**
* Route object for the screen
*/
route: Route;
/**
* Navigation object for the screen
*/
navigation: Navigation;
};
export type ScreenListeners<State extends NavigationState, EventMap extends EventMapBase> = Partial<{
[EventName in keyof (EventMap & EventMapCore<State>)]: EventListenerCallback<EventMap & EventMapCore<State>, EventName>;
}>;
type ScreenComponentType<ParamList extends ParamListBase, RouteName extends keyof ParamList> = React.ComponentType<{
route: RouteProp<ParamList, RouteName>;
navigation: any;
}> | React.ComponentType<{}>;
export type RouteConfigComponent<ParamList extends ParamListBase, RouteName extends keyof ParamList> = {
/**
* React component to render for this screen.
*/
component: ScreenComponentType<ParamList, RouteName>;
getComponent?: never;
children?: never;
} | {
/**
* Lazily get a React component to render for this screen.
*/
getComponent: () => ScreenComponentType<ParamList, RouteName>;
component?: never;
children?: never;
} | {
/**
* Render callback to render content of this screen.
*/
children: (props: {
route: RouteProp<ParamList, RouteName>;
navigation: any;
}) => React.ReactNode;
component?: never;
getComponent?: never;
};
export type RouteConfigProps<ParamList extends ParamListBase, RouteName extends keyof ParamList, State extends NavigationState, ScreenOptions extends {}, EventMap extends EventMapBase, Navigation> = {
/**
* Optional key for this screen. This doesn't need to be unique.
* If the key changes, existing screens with this name will be removed or reset.
* Useful when we have some common screens and have conditional rendering.
*/
navigationKey?: string;
/**
* Route name of this screen.
*/
name: RouteName;
/**
* Navigator options for this screen.
*/
options?: ScreenOptions | ((props: {
route: RouteProp<ParamList, RouteName>;
navigation: Navigation;
theme: ReactNavigation.Theme;
}) => ScreenOptions);
/**
* Event listeners for this screen.
*/
listeners?: ScreenListeners<State, EventMap> | ((props: {
route: RouteProp<ParamList, RouteName>;
navigation: Navigation;
}) => ScreenListeners<State, EventMap>);
/**
* Layout for this screen.
* Useful for wrapping the screen with custom containers.
* e.g. for styling, error boundaries, suspense, etc.
*/
layout?: (props: ScreenLayoutArgs<ParamList, RouteName, ScreenOptions, Navigation>) => React.ReactElement;
/**
* Function to return an unique ID for this screen.
* Receives an object with the route params.
* For a given screen name, there will always be only one screen corresponding to an ID.
* If `undefined` is returned, it acts same as no `getId` being specified.
*/
getId?: ({ params, }: {
params: Readonly<ParamList[RouteName]>;
}) => string | undefined;
/**
* Initial params object for the route.
*/
initialParams?: Partial<ParamList[RouteName]>;
};
export type RouteConfig<ParamList extends ParamListBase, RouteName extends keyof ParamList, State extends NavigationState, ScreenOptions extends {}, EventMap extends EventMapBase, Navigation> = RouteConfigProps<ParamList, RouteName, State, ScreenOptions, EventMap, Navigation> & RouteConfigComponent<ParamList, RouteName>;
export type RouteGroupConfig<ParamList extends ParamListBase, ScreenOptions extends {}, Navigation> = {
/**
* Optional key for the screens in this group.
* If the key changes, all existing screens in this group will be removed or reset.
*/
navigationKey?: string;
/**
* Navigator options for this screen.
*/
screenOptions?: ScreenOptions | ((props: {
route: RouteProp<ParamList, keyof ParamList>;
navigation: Navigation;
theme: ReactNavigation.Theme;
}) => ScreenOptions);
/**
* Layout for the screens inside the group.
* This will override the `screenLayout` of parent group or navigator.
*/
screenLayout?: ((props: ScreenLayoutArgs<ParamList, keyof ParamList, ScreenOptions, Navigation>) => React.ReactElement) | {};
/**
* Children React Elements to extract the route configuration from.
* Only `Screen`, `Group` and `React.Fragment` are supported as children.
*/
children: React.ReactNode;
};
export type NavigationContainerEventMap = {
/**
* Event that fires when the navigation container is ready to be used.
*/
ready: {
data: undefined;
};
/**
* Event that fires when the navigation state changes.
*/
state: {
data: {
/**
* The updated state object after the state change.
*/
state: NavigationState | PartialState<NavigationState> | undefined;
};
};
/**
* Event that fires when current options changes.
*/
options: {
data: {
options: object;
};
};
/**
* Event that fires when an action is dispatched.
* Only intended for debugging purposes, don't use it for app logic.
* This event will be emitted before state changes have been applied.
*/
__unsafe_action__: {
data: {
/**
* The action object that was dispatched.
*/
action: NavigationAction;
/**
* Whether the action was a no-op, i.e. resulted any state changes.
*/
noop: boolean;
/**
* Stack trace of the action, this will only be available during development.
*/
stack: string | undefined;
};
};
};
type NotUndefined<T> = T extends undefined ? never : T;
export type ParamListRoute<ParamList extends ParamListBase> = {
[RouteName in keyof ParamList]: NavigatorScreenParams<{}> extends ParamList[RouteName] ? NotUndefined<ParamList[RouteName]> extends NavigatorScreenParams<infer T> ? ParamListRoute<T> : Route<Extract<RouteName, string>, ParamList[RouteName]> : Route<Extract<RouteName, string>, ParamList[RouteName]>;
}[keyof ParamList];
type MaybeParamListRoute<ParamList extends {}> = ParamList extends ParamListBase ? ParamListRoute<ParamList> : Route<string>;
export type NavigationContainerRef<ParamList extends {}> = NavigationHelpers<ParamList> & EventConsumer<NavigationContainerEventMap> & {
/**
* Reset the navigation state of the root navigator to the provided state.
*
* @param state Navigation state object.
*/
resetRoot(state?: PartialState<NavigationState> | NavigationState): void;
/**
* Get the rehydrated navigation state of the navigation tree.
*/
getRootState(): NavigationState;
/**
* Get the currently focused navigation route.
*/
getCurrentRoute(): MaybeParamListRoute<ParamList> | undefined;
/**
* Get the currently focused route's options.
*/
getCurrentOptions(): object | undefined;
/**
* Whether the navigation container is ready to handle actions.
*/
isReady(): boolean;
/**
* Stub function for setOptions on navigation object for use with useNavigation.
*/
setOptions(): never;
/**
* Stub function for getParent on navigation object for use with useNavigation.
*/
getParent(): undefined;
};
export type NavigationContainerRefWithCurrent<ParamList extends {}> = NavigationContainerRef<ParamList> & {
current: NavigationContainerRef<ParamList> | null;
};
export type NavigationListBase<ParamList extends ParamListBase> = {
[RouteName in keyof ParamList]: unknown;
};
export type TypeBag<ParamList extends ParamListBase, NavigatorID extends string | undefined, State extends NavigationState, ScreenOptions extends {}, EventMap extends EventMapBase, NavigationList extends NavigationListBase<ParamList>, Navigator extends React.ComponentType<any>> = {
ParamList: ParamList;
NavigatorID: NavigatorID;
State: State;
ScreenOptions: ScreenOptions;
EventMap: EventMap;
NavigationList: NavigationList;
Navigator: Navigator;
};
export type NavigatorTypeBagBase = {
ParamList: {};
NavigatorID: string | undefined;
State: NavigationState;
ScreenOptions: {};
EventMap: {};
NavigationList: NavigationListBase<ParamListBase>;
Navigator: React.ComponentType<any>;
};
export type NavigatorTypeBag<ParamList extends ParamListBase, NavigatorID extends string | undefined, State extends NavigationState, ScreenOptions extends {}, EventMap extends EventMapBase, NavigationList extends NavigationListBase<ParamList>, Navigator extends React.ComponentType<any>> = {
ParamList: ParamList;
NavigatorID: NavigatorID;
State: State;
ScreenOptions: ScreenOptions;
EventMap: EventMap;
NavigationList: NavigationList;
Navigator: Navigator;
};
type TypedNavigatorComponent<Bag extends NavigatorTypeBagBase> = React.ComponentType<Omit<React.ComponentProps<TypedNavigatorInternal<Bag['ParamList'], Bag['NavigatorID'], Bag['State'], Bag['ScreenOptions'], Bag['EventMap'], Bag['NavigationList'], Bag['Navigator']>['Navigator']>, 'children'>>;
type TypedNavigatorStaticDecorated<Bag extends NavigatorTypeBagBase, Config> = TypedNavigatorInternal<Bag['ParamList'], Bag['NavigatorID'], Bag['State'], Bag['ScreenOptions'], Bag['EventMap'], Bag['NavigationList'], Bag['Navigator']> & {
getComponent: () => React.ComponentType<{}>;
config: Config;
} & PrivateValueStore<[Bag['ParamList'], Bag['NavigationList'], unknown]>;
type TypedNavigatorStatic<Bag extends NavigatorTypeBagBase, Config> = TypedNavigatorInternal<Bag['ParamList'], Bag['NavigatorID'], Bag['State'], Bag['ScreenOptions'], Bag['EventMap'], Bag['NavigationList'], Bag['Navigator']> & {
config: Config;
with: (Component: React.ComponentType<{
Navigator: TypedNavigatorComponent<Bag>;
}>) => TypedNavigatorStaticDecorated<Bag, Config>;
getComponent: () => TypedNavigatorComponent<Bag>;
} & PrivateValueStore<[Bag['ParamList'], Bag['NavigationList'], unknown]>;
export type TypedNavigator<Bag extends NavigatorTypeBagBase, Config = unknown> = (undefined extends Config ? TypedNavigatorInternal<Bag['ParamList'], Bag['NavigatorID'], Bag['State'], Bag['ScreenOptions'], Bag['EventMap'], Bag['NavigationList'], Bag['Navigator']> : TypedNavigatorStatic<Bag, Config>) & PrivateValueStore<[Bag['ParamList'], Bag['NavigationList'], unknown]>;
type TypedNavigatorInternal<ParamList extends ParamListBase, NavigatorID extends string | undefined, State extends NavigationState, ScreenOptions extends {}, EventMap extends EventMapBase, NavigationList extends NavigationListBase<ParamList>, Navigator extends React.ComponentType<any>> = {
/**
* Navigator component which manages the child screens.
*/
Navigator: React.ComponentType<Omit<React.ComponentProps<Navigator>, keyof DefaultNavigatorOptions<any, any, any, any, any, any>> & DefaultNavigatorOptions<ParamList, NavigatorID, State, ScreenOptions, EventMap, NavigationList[keyof ParamList]>>;
/**
* Component used for grouping multiple route configuration.
*/
Group: React.ComponentType<RouteGroupConfig<ParamList, ScreenOptions, NavigationList[keyof ParamList]>>;
/**
* Component used for specifying route configuration.
*/
Screen: <RouteName extends keyof ParamList>(_: RouteConfig<ParamList, RouteName, State, ScreenOptions, EventMap, NavigationList[RouteName]>) => null;
};
export type NavigatorScreenParams<ParamList extends {}> = {
screen?: never;
params?: never;
merge?: never;
initial?: never;
pop?: never;
path?: string;
state: PartialState<NavigationState> | NavigationState | undefined;
} | {
[RouteName in keyof ParamList]: undefined extends ParamList[RouteName] ? {
screen: RouteName;
params?: ParamList[RouteName];
merge?: boolean;
initial?: boolean;
path?: string;
pop?: boolean;
state?: never;
} : {
screen: RouteName;
params: ParamList[RouteName];
merge?: boolean;
initial?: boolean;
path?: string;
pop?: boolean;
state?: never;
};
}[keyof ParamList];
type PathConfigAlias = {
/**
* Path string to match against.
* e.g. `/users/:id` will match `/users/1` and extract `id` param as `1`.
*/
path: string;
/**
* Whether the path should be consider parent paths or use the exact path.
* By default, paths are relating to the path config on the parent screen.
* If `exact` is set to `true`, the parent path configuration is not used.
*/
exact?: boolean;
/**
* An object mapping the param name to a function which parses the param value.
*
* @example
* ```js
* parse: {
* id: Number,
* date: (value) => new Date(value)
* }
* ```
*/
parse?: Record<string, (value: string) => any>;
};
export type PathConfig<ParamList extends {}> = Partial<PathConfigAlias> & {
/**
* An object mapping the param name to a function which converts the param value to a string.
* By default, all params are converted to strings using `String(value)`.
*
* @example
* ```js
* stringify: {
* date: (value) => value.toISOString()
* }
* ```
*/
stringify?: Record<string, (value: any) => string>;
/**
* Additional path alias that will be matched to the same screen.
*/
alias?: (string | PathConfigAlias)[];
/**
* Path configuration for child screens.
*/
screens?: PathConfigMap<ParamList>;
/**
* Name of the initial route to use for the navigator when the path matches.
*/
initialRouteName?: keyof ParamList;
};
export type PathConfigMap<ParamList extends {}> = {
[RouteName in keyof ParamList]?: NonNullable<ParamList[RouteName]> extends NavigatorScreenParams<infer T extends {}> ? string | PathConfig<T> : string | Omit<PathConfig<{}>, 'screens' | 'initialRouteName'>;
};
export {};
//# sourceMappingURL=types.d.ts.map