@@ -277,4 +287,6 @@ export function StackNavigator(props: Props) {
);
}
-export default createNavigator(StackNavigator);
+export default createNavigator
(
+ StackNavigator
+);
diff --git a/example/TabNavigator.tsx b/example/TabNavigator.tsx
index f7afcefa..aaf6e673 100644
--- a/example/TabNavigator.tsx
+++ b/example/TabNavigator.tsx
@@ -23,6 +23,13 @@ type Action = {
payload: { name?: string; key?: string; params?: object };
};
+export type TabNavigationOptions = {
+ /**
+ * Title text for the screen.
+ */
+ title?: string;
+};
+
export type TabNavigationProp = NavigationProp<
ParamList
> & {
@@ -196,4 +203,6 @@ export function TabNavigator(props: Props) {
);
}
-export default createNavigator(TabNavigator);
+export default createNavigator(
+ TabNavigator
+);
diff --git a/example/index.tsx b/example/index.tsx
index 34f5dd62..1d5432af 100644
--- a/example/index.tsx
+++ b/example/index.tsx
@@ -149,14 +149,14 @@ function App() {
({
+ title: `Foo (${route.params ? route.params.author : ''})`,
+ })}
initialParams={{ author: 'Jane' }}
/>
-
+
+ {props => }
+
{() => (
diff --git a/src/SceneView.tsx b/src/SceneView.tsx
index f320ce29..01e29663 100644
--- a/src/SceneView.tsx
+++ b/src/SceneView.tsx
@@ -19,8 +19,13 @@ type Props = {
setState: (state: NavigationState) => void;
};
-export default function SceneView(props: Props) {
- const { screen, route, navigation: helpers, getState, setState } = props;
+export default function SceneView({
+ screen,
+ route,
+ navigation: helpers,
+ getState,
+ setState,
+}: Props) {
const { performTransaction } = React.useContext(NavigationStateContext);
const navigation = React.useMemo(
diff --git a/src/createNavigator.tsx b/src/createNavigator.tsx
index 0276f47e..152a0d5e 100644
--- a/src/createNavigator.tsx
+++ b/src/createNavigator.tsx
@@ -2,17 +2,19 @@ import * as React from 'react';
import { ParamListBase, RouteConfig, TypedNavigator } from './types';
import Screen from './Screen';
-export default function createNavigator>(
- RawNavigator: N
-) {
+export default function createNavigator<
+ Options extends object,
+ N extends React.ComponentType
+>(RawNavigator: N) {
return function Navigator(): TypedNavigator<
ParamList,
+ Options,
typeof RawNavigator
> {
return {
Navigator: RawNavigator,
Screen: Screen as React.ComponentType<
- RouteConfig
+ RouteConfig
>,
};
};
diff --git a/src/types.tsx b/src/types.tsx
index ee45155a..235526f2 100644
--- a/src/types.tsx
+++ b/src/types.tsx
@@ -232,7 +232,7 @@ export type CompositeNavigationProp<
(B extends NavigationProp ? U : never)
>;
-export type Descriptor = {
+export type Descriptor = {
/**
* Render the component associated with this route.
*/
@@ -244,18 +244,10 @@ export type Descriptor = {
options: Options;
};
-export type Options = {
- /**
- * Title text for the screen.
- */
- title?: string;
-
- [key: string]: any;
-};
-
export type RouteConfig<
ParamList extends ParamListBase = ParamListBase,
- RouteName extends keyof ParamList = string
+ RouteName extends keyof ParamList = string,
+ Options extends object = object
> = {
/**
* Route name of this screen.
@@ -265,7 +257,12 @@ export type RouteConfig<
/**
* Navigator options for this screen.
*/
- options?: Options;
+ options?:
+ | Options
+ | ((props: {
+ route: RouteProp;
+ navigation: NavigationProp;
+ }) => Options);
/**
* Initial params object for the route.
@@ -287,6 +284,7 @@ export type RouteConfig<
export type TypedNavigator<
ParamList extends ParamListBase,
+ Options extends object,
Navigator extends React.ComponentType
> = {
Navigator: React.ComponentType<
@@ -297,5 +295,5 @@ export type TypedNavigator<
initialRouteName?: keyof ParamList;
}
>;
- Screen: React.ComponentType>;
+ Screen: React.ComponentType>;
};
diff --git a/src/useDescriptors.tsx b/src/useDescriptors.tsx
index d10fedc2..74fccd6e 100644
--- a/src/useDescriptors.tsx
+++ b/src/useDescriptors.tsx
@@ -25,9 +25,7 @@ type Options = {
onRouteFocus: (key: string) => void;
};
-const EMPTY_OPTIONS = Object.freeze({});
-
-export default function useDescriptors({
+export default function useDescriptors({
state,
screens,
navigation,
@@ -73,10 +71,18 @@ export default function useDescriptors({
);
},
- options: screen.options || EMPTY_OPTIONS,
+ options: {
+ ...(typeof screen.options === 'function'
+ ? screen.options({
+ // @ts-ignore
+ route,
+ navigation,
+ })
+ : screen.options),
+ },
};
return acc;
},
- {} as { [key: string]: Descriptor }
+ {} as { [key: string]: Descriptor }
);
}
diff --git a/src/useNavigationBuilder.tsx b/src/useNavigationBuilder.tsx
index 2bbacb0e..8f6e89c0 100644
--- a/src/useNavigationBuilder.tsx
+++ b/src/useNavigationBuilder.tsx
@@ -39,7 +39,7 @@ const getRouteConfigsFromChildren = (children: React.ReactNode) =>
);
}, []);
-export default function useNavigationBuilder(
+export default function useNavigationBuilder(
router: Router,
options: Options
) {
@@ -156,7 +156,7 @@ export default function useNavigationBuilder(
actionCreators: router.actionCreators,
});
- const descriptors = useDescriptors({
+ const descriptors = useDescriptors({
state,
screens,
navigation,