Skip to content

Commit

Permalink
feat: add screenListeners prop on navigators similar to screenOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed May 25, 2021
1 parent aa77f06 commit cde44a5
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ import type {
BottomTabNavigationEventMap,
} from '../types';

type Props = DefaultNavigatorOptions<BottomTabNavigationOptions> &
type Props = DefaultNavigatorOptions<
ParamListBase,
TabNavigationState<ParamListBase>,
BottomTabNavigationOptions,
BottomTabNavigationEventMap
> &
TabRouterOptions &
BottomTabNavigationConfig;

function BottomTabNavigator({
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
sceneContainerStyle,
// @ts-expect-error: lazy is deprecated
Expand Down Expand Up @@ -85,6 +91,7 @@ function BottomTabNavigator({
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
defaultScreenOptions,
});
Expand Down
17 changes: 14 additions & 3 deletions packages/core/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,25 @@ declare global {
type Keyof<T extends {}> = Extract<keyof T, string>;

export type DefaultNavigatorOptions<
ParamList extends ParamListBase,
State extends NavigationState,
ScreenOptions extends {},
ParamList extends ParamListBase = ParamListBase
EventMap extends EventMapBase
> = 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;
/**
* Event listeners for all the screens in the navigator.
*/
screenListeners?:
| ScreenListeners<State, EventMap>
| ((props: {
route: RouteProp<ParamList>;
navigation: any;
}) => ScreenListeners<State, EventMap>);
/**
* Default options for all screens under this navigator.
*/
Expand Down Expand Up @@ -564,9 +575,9 @@ export type TypedNavigator<
Navigator: React.ComponentType<
Omit<
React.ComponentProps<Navigator>,
keyof DefaultNavigatorOptions<any, any>
keyof DefaultNavigatorOptions<any, any, any, any>
> &
DefaultNavigatorOptions<ScreenOptions, ParamList>
DefaultNavigatorOptions<ParamList, State, ScreenOptions, EventMap>
>;
/**
* Component used for grouping multiple route configuration.
Expand Down
22 changes: 18 additions & 4 deletions packages/core/src/useNavigationBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,21 @@ export default function useNavigationBuilder<
EventMap extends Record<string, any>
>(
createRouter: RouterFactory<State, any, RouterOptions>,
options: DefaultNavigatorOptions<ScreenOptions> & RouterOptions
options: DefaultNavigatorOptions<
ParamListBase,
State,
ScreenOptions,
EventMap
> &
RouterOptions
) {
const navigatorKey = useRegisterNavigator();

const route = React.useContext(NavigationRouteContext) as
| NavigatorRoute<State>
| undefined;

const { children, ...rest } = options;
const { children, screenListeners, ...rest } = options;
const { current: router } = React.useRef<Router<State, any>>(
createRouter({
...((rest as unknown) as RouterOptions),
Expand Down Expand Up @@ -487,8 +493,14 @@ export default function useNavigationBuilder<

const listeners = ([] as (((e: any) => void) | undefined)[])
.concat(
...routeNames.map((name) => {
const { listeners } = screens[name][1];
// Get an array of listeners for all screens + common listeners on navigator
...[
screenListeners,
...routeNames.map((name) => {
const { listeners } = screens[name][1];
return listeners;
}),
].map((listeners) => {
const map =
typeof listeners === 'function'
? listeners({ route: route as any, navigation })
Expand All @@ -501,6 +513,8 @@ export default function useNavigationBuilder<
: undefined;
})
)
// We don't want same listener to be called multiple times for same event
// So we remove any duplicate functions from the array
.filter((cb, i, self) => cb && self.lastIndexOf(cb) === i);

listeners.forEach((listener) => listener?.(e));
Expand Down
9 changes: 8 additions & 1 deletion packages/drawer/src/navigators/createDrawerNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ import type {
DrawerNavigationEventMap,
} from '../types';

type Props = DefaultNavigatorOptions<DrawerNavigationOptions> &
type Props = DefaultNavigatorOptions<
ParamListBase,
DrawerNavigationState<ParamListBase>,
DrawerNavigationOptions,
DrawerNavigationEventMap
> &
DrawerRouterOptions &
DrawerNavigationConfig;

Expand All @@ -26,6 +31,7 @@ function DrawerNavigator({
defaultStatus,
backBehavior,
children,
screenListeners,
screenOptions,
// @ts-expect-error: lazy is deprecated
lazy,
Expand Down Expand Up @@ -83,6 +89,7 @@ function DrawerNavigator({
defaultStatus,
backBehavior,
children,
screenListeners,
screenOptions,
defaultScreenOptions,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ import type {
MaterialBottomTabNavigationEventMap,
} from '../types';

type Props = DefaultNavigatorOptions<MaterialBottomTabNavigationOptions> &
type Props = DefaultNavigatorOptions<
ParamListBase,
TabNavigationState<ParamListBase>,
MaterialBottomTabNavigationOptions,
MaterialBottomTabNavigationEventMap
> &
TabRouterOptions &
MaterialBottomTabNavigationConfig;

function MaterialBottomTabNavigator({
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
...rest
}: Props) {
Expand All @@ -43,6 +49,7 @@ function MaterialBottomTabNavigator({
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ import type {
MaterialTopTabNavigationEventMap,
} from '../types';

type Props = DefaultNavigatorOptions<MaterialTopTabNavigationOptions> &
type Props = DefaultNavigatorOptions<
ParamListBase,
TabNavigationState<ParamListBase>,
MaterialTopTabNavigationOptions,
MaterialTopTabNavigationEventMap
> &
TabRouterOptions &
MaterialTopTabNavigationConfig;

function MaterialTopTabNavigator({
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
lazy,
tabBarOptions,
Expand Down Expand Up @@ -86,6 +92,7 @@ function MaterialTopTabNavigator({
initialRouteName,
backBehavior,
children,
screenListeners,
screenOptions,
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
createNavigatorFactory,
DefaultNavigatorOptions,
EventArg,
StackActions,
StackActionHelpers,
Expand All @@ -16,16 +15,13 @@ import NativeStackView from '../views/NativeStackView';
import type {
NativeStackNavigationOptions,
NativeStackNavigationEventMap,
NativeStackNavigationConfig,
NativeStackNavigatorProps,
} from '../types';

export type NativeStackNavigatorProps = DefaultNavigatorOptions<NativeStackNavigationOptions> &
StackRouterOptions &
NativeStackNavigationConfig;

function NativeStackNavigator({
initialRouteName,
children,
screenListeners,
screenOptions,
...rest
}: NativeStackNavigatorProps) {
Expand All @@ -38,6 +34,7 @@ function NativeStackNavigator({
>(StackRouter, {
initialRouteName,
children,
screenListeners,
screenOptions,
});

Expand Down
7 changes: 6 additions & 1 deletion packages/native-stack/src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,12 @@ export type NativeStackNavigationOptions = {
orientation?: ScreenStackHeaderConfigProps['screenOrientation'];
};

export type NativeStackNavigatorProps = DefaultNavigatorOptions<NativeStackNavigationOptions> &
export type NativeStackNavigatorProps = DefaultNavigatorOptions<
ParamListBase,
StackNavigationState<ParamListBase>,
NativeStackNavigationOptions,
NativeStackNavigationEventMap
> &
StackRouterOptions &
NativeStackNavigationConfig;

Expand Down
9 changes: 8 additions & 1 deletion packages/stack/src/navigators/createStackNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@ import type {
StackHeaderMode,
} from '../types';

type Props = DefaultNavigatorOptions<StackNavigationOptions> &
type Props = DefaultNavigatorOptions<
ParamListBase,
StackNavigationState<ParamListBase>,
StackNavigationOptions,
StackNavigationEventMap
> &
StackRouterOptions &
StackNavigationConfig;

function StackNavigator({
initialRouteName,
children,
screenListeners,
screenOptions,
...rest
}: Props) {
Expand Down Expand Up @@ -65,6 +71,7 @@ function StackNavigator({
>(StackRouter, {
initialRouteName,
children,
screenListeners,
screenOptions,
defaultScreenOptions: () => ({
presentation: mode,
Expand Down

0 comments on commit cde44a5

Please sign in to comment.