Skip to content

Commit ec7f324

Browse files
authored
Add missing typescript interfaces (#6203)
* Add missing typescript interfaces * Fix tsconfig * Fix ts imports * Remove NavigationListener * Add Navigation.events().registerComponentListener() * Avoid breaking changes in typescript * Export NavigationComponentProps
1 parent 728fe6a commit ec7f324

16 files changed

+134
-28
lines changed

lib/src/events/ComponentEventsObserver.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,20 @@ describe('ComponentEventsObserver', () => {
221221
expect(willUnmountFn).toHaveBeenCalledTimes(1);
222222
});
223223

224+
it(`registerComponentListener accepts listener object`, () => {
225+
const tree = renderer.create(<UnboundScreen />);
226+
const didAppearListenerFn = jest.fn();
227+
uut.registerComponentListener({
228+
componentDidAppear: didAppearListenerFn
229+
}, 'myCompId')
230+
231+
expect(tree.toJSON()).toBeDefined();
232+
expect(didAppearListenerFn).not.toHaveBeenCalled();
233+
234+
uut.notifyComponentDidAppear({ componentId: 'myCompId', componentName: 'doesnt matter', componentType: 'Component' });
235+
expect(didAppearListenerFn).toHaveBeenCalledTimes(1);
236+
});
237+
224238
it(`componentDidAppear should receive component props from store`, () => {
225239
const event = {
226240
componentId: 'myCompId',

lib/src/events/ComponentEventsObserver.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ import {
1818
} from '../interfaces/ComponentEvents';
1919
import { NativeEventsReceiver } from '../adapters/NativeEventsReceiver';
2020
import { Store } from '../components/Store';
21+
import { NavigationComponentListener } from 'react-native-navigation/interfaces/NavigationComponentListener'
2122

22-
type ReactComponentWithIndexing = React.Component<any> & Record<string, any>;
23+
type ReactComponentWithIndexing = NavigationComponentListener & Record<string, any>;
2324

2425
export class ComponentEventsObserver {
2526
private listeners: Record<string, Record<string, ReactComponentWithIndexing>> = {};
@@ -60,13 +61,21 @@ export class ComponentEventsObserver {
6061
if (!isString(computedComponentId)) {
6162
throw new Error(`bindComponent expects a component with a componentId in props or a componentId as the second argument`);
6263
}
63-
if (isNil(this.listeners[computedComponentId])) {
64-
this.listeners[computedComponentId] = {};
64+
65+
return this.registerComponentListener(component as NavigationComponentListener, computedComponentId);
66+
}
67+
68+
public registerComponentListener(listener: NavigationComponentListener, componentId: string): EventSubscription {
69+
if (!isString(componentId)) {
70+
throw new Error(`registerComponentListener expects a componentId as the second argument`);
71+
}
72+
if (isNil(this.listeners[componentId])) {
73+
this.listeners[componentId] = {};
6574
}
6675
const key = uniqueId();
67-
this.listeners[computedComponentId][key] = component;
76+
this.listeners[componentId][key] = listener;
6877

69-
return { remove: () => unset(this.listeners[computedComponentId], key) };
78+
return { remove: () => unset(this.listeners[componentId], key) };
7079
}
7180

7281
public unmounted(componentId: string) {

lib/src/events/EventsRegistry.test.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { EventsRegistry } from './EventsRegistry';
22
import { NativeEventsReceiver } from '../adapters/NativeEventsReceiver.mock';
33
import { CommandsObserver } from './CommandsObserver';
44
import { UniqueIdProvider } from '../adapters/UniqueIdProvider';
5+
import { NavigationComponent } from '../interfaces/NavigationComponent';
6+
import { NavigationComponentListener } from 'react-native-navigation/interfaces/NavigationComponentListener';
57

68
describe('EventsRegistry', () => {
79
let uut: EventsRegistry;
@@ -117,7 +119,14 @@ describe('EventsRegistry', () => {
117119
const subscription = {};
118120
mockScreenEventsRegistry.bindComponent = jest.fn();
119121
mockScreenEventsRegistry.bindComponent.mockReturnValueOnce(subscription);
120-
expect(uut.bindComponent({} as React.Component<any>)).toEqual(subscription);
122+
expect(uut.bindComponent({} as NavigationComponent<any>)).toEqual(subscription);
123+
});
124+
125+
it(`delegates registerComponentListener to ComponentObserver`, () => {
126+
const subscription = {};
127+
mockScreenEventsRegistry.registerComponentListener = jest.fn();
128+
mockScreenEventsRegistry.registerComponentListener.mockReturnValueOnce(subscription);
129+
expect(uut.registerComponentListener({} as NavigationComponentListener, 'componentId')).toEqual(subscription);
121130
});
122131

123132
it('delegates screenPopped to nativeEventsReceiver', () => {

lib/src/events/EventsRegistry.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
BottomTabLongPressedEvent,
2222
BottomTabPressedEvent
2323
} from '../interfaces/Events';
24+
import { NavigationComponentListener } from 'react-native-navigation/interfaces/NavigationComponentListener';
2425

2526
export class EventsRegistry {
2627
constructor(
@@ -134,6 +135,13 @@ export class EventsRegistry {
134135
return this.componentEventsObserver.bindComponent(component, componentId);
135136
}
136137

138+
public registerComponentListener(
139+
listener: NavigationComponentListener,
140+
componentId: string
141+
): EventSubscription {
142+
return this.componentEventsObserver.registerComponentListener(listener, componentId);
143+
}
144+
137145
public registerScreenPoppedListener(
138146
callback: (event: ScreenPoppedEvent) => void
139147
): EmitterSubscription {

lib/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ export * from './interfaces/Events';
99
export * from './interfaces/EventSubscription';
1010
export * from './interfaces/Layout';
1111
export * from './interfaces/Options';
12+
export * from './interfaces/NavigationComponent';
13+
export * from './interfaces/NavigationComponentProps';
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import {
3+
NavigationButtonPressedEvent,
4+
ModalDismissedEvent,
5+
ModalAttemptedToDismissEvent,
6+
SearchBarUpdatedEvent,
7+
SearchBarCancelPressedEvent,
8+
PreviewCompletedEvent,
9+
ScreenPoppedEvent,
10+
ComponentDidAppearEvent,
11+
ComponentDidDisappearEvent,
12+
} from './ComponentEvents';
13+
import { NavigationComponentProps } from './NavigationComponentProps';
14+
15+
export class NavigationComponent<Props = {}, State = {}, Snapshot = any>
16+
extends React.Component<Props & NavigationComponentProps, State, Snapshot> {
17+
componentDidAppear(_event: ComponentDidAppearEvent) {}
18+
componentDidDisappear(_event: ComponentDidDisappearEvent) {}
19+
navigationButtonPressed(_event: NavigationButtonPressedEvent) {}
20+
modalDismissed(_event: ModalDismissedEvent) {}
21+
modalAttemptedToDismiss(_event: ModalAttemptedToDismissEvent) {}
22+
searchBarUpdated(_event: SearchBarUpdatedEvent) {}
23+
searchBarCancelPressed(_event: SearchBarCancelPressedEvent) {}
24+
previewCompleted(_event: PreviewCompletedEvent) {}
25+
screenPopped(_event: ScreenPoppedEvent) {}
26+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {
2+
NavigationButtonPressedEvent,
3+
ModalDismissedEvent,
4+
ModalAttemptedToDismissEvent,
5+
SearchBarUpdatedEvent,
6+
SearchBarCancelPressedEvent,
7+
PreviewCompletedEvent,
8+
ScreenPoppedEvent,
9+
ComponentDidAppearEvent,
10+
ComponentDidDisappearEvent,
11+
} from './ComponentEvents';
12+
13+
export interface NavigationComponentListener {
14+
componentDidAppear? : (_event: ComponentDidAppearEvent) => void
15+
componentDidDisappear? : (_event: ComponentDidDisappearEvent) => void
16+
navigationButtonPressed? : (_event: NavigationButtonPressedEvent) => void
17+
modalDismissed? : (_event: ModalDismissedEvent) => void
18+
modalAttemptedToDismiss? : (_event: ModalAttemptedToDismissEvent) => void
19+
searchBarUpdated? : (_event: SearchBarUpdatedEvent) => void
20+
searchBarCancelPressed? : (_event: SearchBarCancelPressedEvent) => void
21+
previewCompleted? : (_event: PreviewCompletedEvent) => void
22+
screenPopped? : (_event: ScreenPoppedEvent) => void
23+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface NavigationComponentProps {
2+
componentId: string;
3+
}

playground/src/screens/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ const Screens = require('./Screens');
1111
function registerScreens() {
1212
Navigation.registerComponent(Screens.Alert, () => require('./Alert'));
1313
Navigation.registerComponent(Screens.CocktailDetailsScreen, () => require('./sharedElementTransition/CocktailDetailsScreen'));
14-
Navigation.registerComponent(Screens.CocktailsListScreen, () => require('./sharedElementTransition/CocktailsListScreen'));
15-
Navigation.registerComponent(Screens.CocktailsListMasterScreen, () => require('./splitView/CocktailsListMasterScreen'));
14+
Navigation.registerComponent(Screens.CocktailsListScreen, () => require('./sharedElementTransition/CocktailsListScreen').default);
15+
Navigation.registerComponent(Screens.CocktailsListMasterScreen, () => require('./splitView/CocktailsListMasterScreen').default);
1616
Navigation.registerComponent(Screens.EventsOverlay, () => require('./StaticLifecycleOverlay').StaticLifecycleOverlay);
1717
Navigation.registerComponent(Screens.EventsScreen, () => require('./StaticEventsScreen'));
1818
Navigation.registerComponent(Screens.ExternalComponent, () => require('./ExternalComponentScreen'));

playground/src/screens/sharedElementTransition/CocktailsListScreen.js renamed to playground/src/screens/sharedElementTransition/CocktailsListScreen.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const React = require('react');
2-
const { Component } = require('react');
2+
import { NavigationComponent } from 'react-native-navigation';
33
const CocktailsView = require('./CocktailsView')
44
const { Platform } = require('react-native');
55
const Navigation = require('../../services/Navigation');
@@ -8,7 +8,7 @@ const MULTIPLIER = 1.15
88
const LONG_DURATION = 350 * MULTIPLIER
99
const SHORT_DURATION = 190 * MULTIPLIER
1010

11-
class CocktailsListScreen extends Component {
11+
export default class CocktailsListScreen extends NavigationComponent {
1212
static options() {
1313
return {
1414
...Platform.select({
@@ -35,11 +35,11 @@ class CocktailsListScreen extends Component {
3535
);
3636
}
3737

38-
update = (item) => {
38+
update = (item: any) => {
3939
Navigation.updateProps('DETAILS_COMPONENT_ID', item);
4040
}
4141

42-
pushCocktailDetails = (item) => {
42+
pushCocktailDetails = (item: any) => {
4343
Navigation.push(
4444
this,
4545
{
@@ -94,4 +94,4 @@ class CocktailsListScreen extends Component {
9494
)
9595
}
9696
}
97-
module.exports = CocktailsListScreen;
97+

0 commit comments

Comments
 (0)