expo-router
Version:
Expo Router is a file-based router for React Native and web applications.
161 lines (160 loc) • 8.61 kB
TypeScript
import type { createStandardNavigator, NavigatorArgs, NavigatorDescriptor } from 'standard-navigation';
import type { DefaultNavigatorOptions, DefaultRouterOptions, EventMapBase, NavigationAction, NavigationHelpers, NavigationState, ParamListBase, DescriptorRouteProp, RouteSource } from '../react-navigation/native';
import type { GoBackAction, NavigateAction } from '../react-navigation/routers/CommonActions';
import type { ScreenProps } from '../useScreens';
import type { ErrorBoundaryProps } from '../views/Try';
export type StandardNavigatorEventMapBase = Record<string, {
data: object | undefined;
canPreventDefault: boolean;
}>;
export type StandardNavigatorEmit<EventMap extends Record<string, {
data: object | undefined;
}>> = (event: {
[Event in keyof EventMap]: {
type: Event;
target?: string;
} & (undefined extends EventMap[Event]['data'] ? {
data?: EventMap[Event]['data'];
} : {
data: EventMap[Event]['data'];
});
}[keyof EventMap]) => void;
export type StandardNavigationAction = NavigateAction | GoBackAction;
export type PlaceholderDescriptorMap<NavigatorOptions extends object = object> = Record<string, {
route: DescriptorRouteProp<ParamListBase, string>;
options: NavigatorOptions;
render: () => React.ReactNode;
routeSource?: RouteSource;
}>;
export type DescribePlaceholderRoute<NavigatorOptions extends object = object> = (route: DescriptorRouteProp<ParamListBase, string>) => NonNullable<PlaceholderDescriptorMap<NavigatorOptions>[string]>;
export type StandardNavigator<NavigatorOptions extends object, EventMap extends StandardNavigatorEventMapBase, NavigatorProps extends object> = ReturnType<typeof createStandardNavigator<NavigatorOptions, EventMap, NavigatorProps>>;
export type StandardUseNavigationBuilderOptions<State extends NavigationState, NavigatorOptions extends object, EventMap extends StandardNavigatorEventMapBase> = DefaultNavigatorOptions<ParamListBase, string | undefined, State, NavigatorOptions, EventMap, any>;
export interface StandardNavigatorCreatePropsFactoryDeps<State extends NavigationState> {
state: State;
dispatch: (action: NavigationAction) => void;
dispatchSync: (action: NavigationAction) => void;
navigation: NavigationHelpers<ParamListBase>;
/** Returns whether the route with the given key is preloaded. */
isPreloaded: (key: string) => boolean;
/** Returns whether removal is prevented for the route with the given key. */
isRemovalPrevented: (key: string) => boolean;
}
/**
* Allows router-specific information to be exposed via navigator props alongside the standard
* `state` and `actions`.
*
* Receives the processed Expo Router `state` and raw `dispatch`. Both are internal and may have
* small breaking changes between releases, so prefer the `state` and `actions` passed to
* `NavigatorContent` when they suffice. When `processState` is provided, `state` is its result.
*
* @example
* ```tsx
* createProps: ({ state, dispatch }) => ({
* activeRouteKey: state.routes[state.index].key,
* preload: (name: string) => dispatch({ type: 'PRELOAD', payload: { name } }),
* })
* ```
*/
type CreatePropsFn<State extends NavigationState, CreateProps extends object> = (deps: StandardNavigatorCreatePropsFactoryDeps<State>) => CreateProps;
type CreatePropsOption<State extends NavigationState, CreateProps extends object> = [
keyof CreateProps
] extends [never] ? {
/**
* Declare injected props with the fourth type argument of `NavigatorContentProps` before
* providing this factory.
*/
createProps?: never;
} : {
createProps: CreatePropsFn<State, CreateProps>;
};
export type IntegrateWithRouterOptions<State extends NavigationState = NavigationState, CreateProps extends object = object, NavigatorOptions extends object = Record<string, any>, EventMap extends EventMapBase = EventMapBase> = CreatePropsOption<State, CreateProps> & {
/**
* Number of screens above a route that hides its content when `activityEnabled` is `true`.
* @default 1
*/
activityDefaultThreshold?: number;
/**
* Pre-processes the builder state before it is converted to standard-navigation state.
*
* @example
* ```tsx
* processState: (state) => ({
* ...state,
* routes: state.routes.filter((route) => route.params?.hidden !== true),
* })
* ```
*/
processState?: (state: State, descriptors: PlaceholderDescriptorMap<NavigatorOptions>, describe: DescribePlaceholderRoute<NavigatorOptions>) => State;
/** Creates additional descriptors before `processState` and navigator rendering. */
processDescriptors?: (descriptors: PlaceholderDescriptorMap<NavigatorOptions>, state: State, describe: DescribePlaceholderRoute<NavigatorOptions>) => PlaceholderDescriptorMap<NavigatorOptions>;
/**
* Transforms the screens declared as children of the navigator before they are rendered.
*
* @example
* ```tsx
* processScreens: (screens) =>
* screens.map((screen) => ({ ...screen, options: { ...screen.options, title: screen.name } })),
* ```
*/
processScreens?: (screens: (ScreenProps<NavigatorOptions, State, EventMap> & {
name: string;
})[]) => (ScreenProps<NavigatorOptions, State, EventMap> & {
name: string;
})[];
};
/**
* A standard-navigation descriptor extended with Expo Router route information.
*/
export interface StandardNavigatorDescriptor<NavigatorOptions extends object> extends NavigatorDescriptor<NavigatorOptions> {
/**
* Indicates whether Expo Router received the route from a layout declaration or inferred it
* from the filesystem.
*/
routeSource?: RouteSource;
}
export type StandardNavigatorContentProps<NavigatorOptions extends object, EventMap extends StandardNavigatorEventMapBase, NavigatorProps extends object> = NavigatorArgs<NavigatorOptions, EventMap> & Omit<NavigatorProps, keyof NavigatorArgs<NavigatorOptions, EventMap>>;
/**
* Lets TypeScript infer `EventMap`, `NavigatorProps`, and `CreateProps` from a `NavigatorContent`
* component.
*
* On their own these can't be inferred: `EventMap` only appears as an argument to `emitter.emit`,
* while `NavigatorProps` and `CreateProps` are combined inside an intersection and `Omit` — none
* are positions TypeScript can read a type back out of. Without these properties it gives up and
* falls back to the base shapes, rejecting components that declare specific events or extra props.
*
* The properties are phantom: they never exist at runtime and are never read. They exist only to
* put each type somewhere TypeScript will infer it from.
*/
type NavigatorContentInferenceCarrier<EventMap extends StandardNavigatorEventMapBase, NavigatorProps extends object, CreateProps extends object> = {
/** @internal */
readonly __eventMap__?: EventMap;
/** @internal */
readonly __navigatorProps__?: NavigatorProps;
/** @internal */
readonly __createProps__?: CreateProps;
};
/**
* Props for a standard navigator's `NavigatorContent` component. Annotate your content component
* with this type to declare the events it emits, so `createStandardRouterNavigator` can
* type `emitter.emit` for you.
*
* @example
* ```tsx
* // No events:
* type TabsContentProps = NavigatorContentProps<{ title?: string }>;
*
* // Typed events:
* type TabsContentProps = NavigatorContentProps<
* { title?: string },
* { tabPress: { data: undefined; canPreventDefault: true } },
* { tintColor?: string },
* { activeRouteKey: string }
* >;
* ```
*/
export type NavigatorContentProps<NavigatorOptions extends object, EventMap extends StandardNavigatorEventMapBase = Record<string, never>, NavigatorProps extends object = object, CreateProps extends object = object> = StandardNavigatorContentProps<NavigatorOptions, EventMap, NavigatorProps & CreateProps> & NavigatorContentInferenceCarrier<EventMap, NavigatorProps, CreateProps>;
export type StandardRouterNavigatorProps<State extends NavigationState, NavigatorOptions extends object, EventMap extends StandardNavigatorEventMapBase, NavigatorProps extends object, RouterOptions extends DefaultRouterOptions> = Omit<StandardUseNavigationBuilderOptions<State, NavigatorOptions, EventMap>, 'initialRouteName'> & Omit<NavigatorProps, 'initialRouteName'> & Omit<RouterOptions, 'initialRouteName'> & {
/** A component to render when an individual screen in this navigator throws an error. */
unstable_screenErrorBoundary?: React.ComponentType<ErrorBoundaryProps>;
};
export {};