mirror of
https://github.com/status-im/react-navigation.git
synced 2025-02-24 09:08:15 +00:00
Add <NavigationEvents/> component (#4188)
* add NavigationEvents * expose TabsWithNavigationEvents in lib entrypoints * Add NavigationEvents example in playground * Add NavigationEvents example in playground * Add NavigationEvents tests * Add NavigationEvents Flow declarations * remove useless NavigationEvents constructor * NavigationEvents => make tests more readable by avoiding beforeEach callback * fix flow test error by adding <any, any> to React.Component
This commit is contained in:
parent
4e384f8057
commit
1951a3ac46
@ -36,6 +36,7 @@ import StackWithTranslucentHeader from './StackWithTranslucentHeader';
|
|||||||
import SimpleTabs from './SimpleTabs';
|
import SimpleTabs from './SimpleTabs';
|
||||||
import SwitchWithStacks from './SwitchWithStacks';
|
import SwitchWithStacks from './SwitchWithStacks';
|
||||||
import TabsWithNavigationFocus from './TabsWithNavigationFocus';
|
import TabsWithNavigationFocus from './TabsWithNavigationFocus';
|
||||||
|
import TabsWithNavigationEvents from './TabsWithNavigationEvents';
|
||||||
import KeyboardHandlingExample from './KeyboardHandlingExample';
|
import KeyboardHandlingExample from './KeyboardHandlingExample';
|
||||||
|
|
||||||
const ExampleInfo = {
|
const ExampleInfo = {
|
||||||
@ -126,6 +127,11 @@ const ExampleInfo = {
|
|||||||
name: 'withNavigationFocus',
|
name: 'withNavigationFocus',
|
||||||
description: 'Receive the focus prop to know when a screen is focused',
|
description: 'Receive the focus prop to know when a screen is focused',
|
||||||
},
|
},
|
||||||
|
TabsWithNavigationEvents: {
|
||||||
|
name: 'NavigationEvents',
|
||||||
|
description:
|
||||||
|
'Declarative NavigationEvents component to subscribe to navigation events',
|
||||||
|
},
|
||||||
KeyboardHandlingExample: {
|
KeyboardHandlingExample: {
|
||||||
name: 'Keyboard Handling Example',
|
name: 'Keyboard Handling Example',
|
||||||
description:
|
description:
|
||||||
@ -166,6 +172,7 @@ const ExampleRoutes = {
|
|||||||
path: 'settings',
|
path: 'settings',
|
||||||
},
|
},
|
||||||
TabsWithNavigationFocus,
|
TabsWithNavigationFocus,
|
||||||
|
TabsWithNavigationEvents,
|
||||||
KeyboardHandlingExample,
|
KeyboardHandlingExample,
|
||||||
// This is commented out because it's rarely useful
|
// This is commented out because it's rarely useful
|
||||||
// InactiveStack,
|
// InactiveStack,
|
||||||
|
127
examples/NavigationPlayground/js/TabsWithNavigationEvents.js
Normal file
127
examples/NavigationPlayground/js/TabsWithNavigationEvents.js
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/**
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { FlatList, SafeAreaView, StatusBar, Text, View } from 'react-native';
|
||||||
|
import { NavigationEvents } from 'react-navigation';
|
||||||
|
import { createMaterialBottomTabNavigator } from 'react-navigation-material-bottom-tabs';
|
||||||
|
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||||
|
|
||||||
|
const Event = ({ event }) => (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
borderColor: 'grey',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 3,
|
||||||
|
padding: 5,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text>{event.type}</Text>
|
||||||
|
<Text>
|
||||||
|
{event.action.type.replace('Navigation/', '')}
|
||||||
|
{event.action.routeName ? '=>' + event.action.routeName : ''}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
const createTabScreen = (name, icon, focusedIcon) => {
|
||||||
|
class TabScreen extends React.Component<any, any> {
|
||||||
|
static navigationOptions = {
|
||||||
|
tabBarLabel: name,
|
||||||
|
tabBarIcon: ({ tintColor, focused }) => (
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name={focused ? focusedIcon : icon}
|
||||||
|
size={26}
|
||||||
|
style={{ color: focused ? tintColor : '#ccc' }}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
state = { eventLog: [] };
|
||||||
|
|
||||||
|
append = navigationEvent => {
|
||||||
|
this.setState(({ eventLog }) => ({
|
||||||
|
eventLog: eventLog.concat(navigationEvent),
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<SafeAreaView
|
||||||
|
forceInset={{ horizontal: 'always', top: 'always' }}
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
margin: 10,
|
||||||
|
marginTop: 30,
|
||||||
|
fontSize: 30,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Events for tab {name}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<View style={{ flex: 1, width: '100%', marginTop: 10 }}>
|
||||||
|
<FlatList
|
||||||
|
data={this.state.eventLog}
|
||||||
|
keyExtractor={item => `${this.state.eventLog.indexOf(item)}`}
|
||||||
|
renderItem={({ item }) => (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
marginVertical: 5,
|
||||||
|
marginHorizontal: 10,
|
||||||
|
backgroundColor: '#e4e4e4',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Event event={item} />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<NavigationEvents
|
||||||
|
onWillFocus={this.append}
|
||||||
|
onDidFocus={this.append}
|
||||||
|
onWillBlur={this.append}
|
||||||
|
onDidBlur={this.append}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatusBar barStyle="default" />
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TabScreen;
|
||||||
|
};
|
||||||
|
|
||||||
|
const TabsWithNavigationEvents = createMaterialBottomTabNavigator(
|
||||||
|
{
|
||||||
|
One: {
|
||||||
|
screen: createTabScreen('One', 'numeric-1-box-outline', 'numeric-1-box'),
|
||||||
|
},
|
||||||
|
Two: {
|
||||||
|
screen: createTabScreen('Two', 'numeric-2-box-outline', 'numeric-2-box'),
|
||||||
|
},
|
||||||
|
Three: {
|
||||||
|
screen: createTabScreen(
|
||||||
|
'Three',
|
||||||
|
'numeric-3-box-outline',
|
||||||
|
'numeric-3-box'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
shifting: false,
|
||||||
|
activeTintColor: '#F44336',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default TabsWithNavigationEvents;
|
15
flow/react-navigation.js
vendored
15
flow/react-navigation.js
vendored
@ -557,6 +557,21 @@ declare module 'react-navigation' {
|
|||||||
navigationOptions?: O,
|
navigationOptions?: O,
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NavigationEvents component
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare type _NavigationEventsProps = {
|
||||||
|
navigation?: NavigationScreenProp<NavigationState>,
|
||||||
|
onWillFocus?: NavigationEventCallback,
|
||||||
|
onDidFocus?: NavigationEventCallback,
|
||||||
|
onWillBlur?: NavigationEventCallback,
|
||||||
|
onDidBlur?: NavigationEventCallback,
|
||||||
|
};
|
||||||
|
declare export var NavigationEvents: React$ComponentType<
|
||||||
|
_NavigationEventsProps
|
||||||
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigation container
|
* Navigation container
|
||||||
*/
|
*/
|
||||||
|
5
src/react-navigation.js
vendored
5
src/react-navigation.js
vendored
@ -156,6 +156,11 @@ module.exports = {
|
|||||||
return require('./views/SwitchView/SwitchView').default;
|
return require('./views/SwitchView/SwitchView').default;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// NavigationEvents
|
||||||
|
get NavigationEvents() {
|
||||||
|
return require('./views/NavigationEvents').default;
|
||||||
|
},
|
||||||
|
|
||||||
// HOCs
|
// HOCs
|
||||||
get withNavigation() {
|
get withNavigation() {
|
||||||
return require('./views/withNavigation').default;
|
return require('./views/withNavigation').default;
|
||||||
|
@ -42,6 +42,11 @@ module.exports = {
|
|||||||
return require('./routers/SwitchRouter').default;
|
return require('./routers/SwitchRouter').default;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// NavigationEvents
|
||||||
|
get NavigationEvents() {
|
||||||
|
return require('./views/NavigationEvents').default;
|
||||||
|
},
|
||||||
|
|
||||||
// HOCs
|
// HOCs
|
||||||
get withNavigation() {
|
get withNavigation() {
|
||||||
return require('./views/withNavigation').default;
|
return require('./views/withNavigation').default;
|
||||||
|
57
src/views/NavigationEvents.js
Normal file
57
src/views/NavigationEvents.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import withNavigation from './withNavigation';
|
||||||
|
|
||||||
|
const EventNameToPropName = {
|
||||||
|
willFocus: 'onWillFocus',
|
||||||
|
didFocus: 'onDidFocus',
|
||||||
|
willBlur: 'onWillBlur',
|
||||||
|
didBlur: 'onDidBlur',
|
||||||
|
};
|
||||||
|
|
||||||
|
const EventNames = Object.keys(EventNameToPropName);
|
||||||
|
|
||||||
|
class NavigationEvents extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
this.subscriptions = {};
|
||||||
|
EventNames.forEach(this.addListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
EventNames.forEach(eventName => {
|
||||||
|
const listenerHasChanged =
|
||||||
|
this.props[EventNameToPropName[eventName]] !==
|
||||||
|
prevProps[EventNameToPropName[eventName]];
|
||||||
|
if (listenerHasChanged) {
|
||||||
|
this.removeListener(eventName);
|
||||||
|
this.addListener(eventName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
EventNames.forEach(this.removeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
addListener = eventName => {
|
||||||
|
const listener = this.props[EventNameToPropName[eventName]];
|
||||||
|
if (listener) {
|
||||||
|
this.subscriptions[eventName] = this.props.navigation.addListener(
|
||||||
|
eventName,
|
||||||
|
listener
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
removeListener = eventName => {
|
||||||
|
if (this.subscriptions[eventName]) {
|
||||||
|
this.subscriptions[eventName].remove();
|
||||||
|
this.subscriptions[eventName] = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withNavigation(NavigationEvents);
|
241
src/views/__tests__/NavigationEvents-test.js
Normal file
241
src/views/__tests__/NavigationEvents-test.js
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
import renderer from 'react-test-renderer';
|
||||||
|
import NavigationEvents from '../NavigationEvents';
|
||||||
|
import { NavigationProvider } from '../NavigationContext';
|
||||||
|
|
||||||
|
const createListener = () => payload => {};
|
||||||
|
|
||||||
|
// An easy way to create the 4 listeners prop
|
||||||
|
const createEventListenersProp = () => ({
|
||||||
|
onWillFocus: createListener(),
|
||||||
|
onDidFocus: createListener(),
|
||||||
|
onWillBlur: createListener(),
|
||||||
|
onDidBlur: createListener(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const createNavigationAndHelpers = () => {
|
||||||
|
// A little API to spy on subscription remove calls that are performed during the tests
|
||||||
|
const removeCallsAPI = (() => {
|
||||||
|
let removeCalls = [];
|
||||||
|
return {
|
||||||
|
reset: () => {
|
||||||
|
removeCalls = [];
|
||||||
|
},
|
||||||
|
add: (name, handler) => {
|
||||||
|
removeCalls.push({ name, handler });
|
||||||
|
},
|
||||||
|
checkRemoveCalled: count => {
|
||||||
|
expect(removeCalls.length).toBe(count);
|
||||||
|
},
|
||||||
|
checkRemoveCalledWith: (name, handler) => {
|
||||||
|
expect(removeCalls).toContainEqual({ name, handler });
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
const navigation = {
|
||||||
|
addListener: jest.fn((name, handler) => {
|
||||||
|
return {
|
||||||
|
remove: () => removeCallsAPI.add(name, handler),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkAddListenerCalled = count => {
|
||||||
|
expect(navigation.addListener).toHaveBeenCalledTimes(count);
|
||||||
|
};
|
||||||
|
const checkAddListenerCalledWith = (eventName, handler) => {
|
||||||
|
expect(navigation.addListener).toHaveBeenCalledWith(eventName, handler);
|
||||||
|
};
|
||||||
|
const checkRemoveCalled = count => {
|
||||||
|
removeCallsAPI.checkRemoveCalled(count);
|
||||||
|
};
|
||||||
|
const checkRemoveCalledWith = (eventName, handler) => {
|
||||||
|
removeCallsAPI.checkRemoveCalledWith(eventName, handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
navigation,
|
||||||
|
removeCallsAPI,
|
||||||
|
checkAddListenerCalled,
|
||||||
|
checkAddListenerCalledWith,
|
||||||
|
checkRemoveCalled,
|
||||||
|
checkRemoveCalledWith,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// We test 2 distinct ways to provide the navigation to the NavigationEvents (prop/context)
|
||||||
|
const NavigationEventsTestComp = ({
|
||||||
|
withContext = true,
|
||||||
|
navigation,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
if (withContext) {
|
||||||
|
return (
|
||||||
|
<NavigationProvider value={navigation}>
|
||||||
|
<NavigationEvents {...props} />
|
||||||
|
</NavigationProvider>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <NavigationEvents navigation={navigation} {...props} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('NavigationEvents', () => {
|
||||||
|
it('add all listeners with navigation prop', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
checkAddListenerCalled,
|
||||||
|
checkAddListenerCalledWith,
|
||||||
|
} = createNavigationAndHelpers();
|
||||||
|
const eventListenerProps = createEventListenersProp();
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
withContext={false}
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
checkAddListenerCalled(4);
|
||||||
|
checkAddListenerCalledWith('willBlur', eventListenerProps.onWillBlur);
|
||||||
|
checkAddListenerCalledWith('willFocus', eventListenerProps.onWillFocus);
|
||||||
|
checkAddListenerCalledWith('didBlur', eventListenerProps.onDidBlur);
|
||||||
|
checkAddListenerCalledWith('didFocus', eventListenerProps.onDidFocus);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add all listeners with navigation context', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
checkAddListenerCalled,
|
||||||
|
checkAddListenerCalledWith,
|
||||||
|
} = createNavigationAndHelpers();
|
||||||
|
const eventListenerProps = createEventListenersProp();
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
withContext={true}
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
checkAddListenerCalled(4);
|
||||||
|
checkAddListenerCalledWith('willBlur', eventListenerProps.onWillBlur);
|
||||||
|
checkAddListenerCalledWith('willFocus', eventListenerProps.onWillFocus);
|
||||||
|
checkAddListenerCalledWith('didBlur', eventListenerProps.onDidBlur);
|
||||||
|
checkAddListenerCalledWith('didFocus', eventListenerProps.onDidFocus);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('remove all listeners on unmount', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
checkRemoveCalled,
|
||||||
|
checkRemoveCalledWith,
|
||||||
|
} = createNavigationAndHelpers();
|
||||||
|
const eventListenerProps = createEventListenersProp();
|
||||||
|
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
checkRemoveCalled(0);
|
||||||
|
component.unmount();
|
||||||
|
checkRemoveCalled(4);
|
||||||
|
checkRemoveCalledWith('willBlur', eventListenerProps.onWillBlur);
|
||||||
|
checkRemoveCalledWith('willFocus', eventListenerProps.onWillFocus);
|
||||||
|
checkRemoveCalledWith('didBlur', eventListenerProps.onDidBlur);
|
||||||
|
checkRemoveCalledWith('didFocus', eventListenerProps.onDidFocus);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add a single listener', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
checkAddListenerCalled,
|
||||||
|
checkAddListenerCalledWith,
|
||||||
|
} = createNavigationAndHelpers();
|
||||||
|
const listener = createListener();
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEventsTestComp navigation={navigation} onDidFocus={listener} />
|
||||||
|
);
|
||||||
|
checkAddListenerCalled(1);
|
||||||
|
checkAddListenerCalledWith('didFocus', listener);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('do not attempt to add/remove stable listeners on update', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
checkAddListenerCalled,
|
||||||
|
checkAddListenerCalledWith,
|
||||||
|
} = createNavigationAndHelpers();
|
||||||
|
const eventListenerProps = createEventListenersProp();
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
component.update(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
component.update(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
checkAddListenerCalled(4);
|
||||||
|
checkAddListenerCalledWith('willBlur', eventListenerProps.onWillBlur);
|
||||||
|
checkAddListenerCalledWith('willFocus', eventListenerProps.onWillFocus);
|
||||||
|
checkAddListenerCalledWith('didBlur', eventListenerProps.onDidBlur);
|
||||||
|
checkAddListenerCalledWith('didFocus', eventListenerProps.onDidFocus);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('add, remove and replace (remove+add) listeners on complex updates', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
checkAddListenerCalled,
|
||||||
|
checkAddListenerCalledWith,
|
||||||
|
checkRemoveCalled,
|
||||||
|
checkRemoveCalledWith,
|
||||||
|
} = createNavigationAndHelpers();
|
||||||
|
const eventListenerProps = createEventListenersProp();
|
||||||
|
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
navigation={navigation}
|
||||||
|
{...eventListenerProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
checkAddListenerCalled(4);
|
||||||
|
checkAddListenerCalledWith('willBlur', eventListenerProps.onWillBlur);
|
||||||
|
checkAddListenerCalledWith('willFocus', eventListenerProps.onWillFocus);
|
||||||
|
checkAddListenerCalledWith('didBlur', eventListenerProps.onDidBlur);
|
||||||
|
checkAddListenerCalledWith('didFocus', eventListenerProps.onDidFocus);
|
||||||
|
checkRemoveCalled(0);
|
||||||
|
|
||||||
|
const onWillFocus2 = createListener();
|
||||||
|
const onDidFocus2 = createListener();
|
||||||
|
|
||||||
|
component.update(
|
||||||
|
<NavigationEventsTestComp
|
||||||
|
navigation={navigation}
|
||||||
|
onWillBlur={eventListenerProps.onWillBlur}
|
||||||
|
onDidBlur={undefined}
|
||||||
|
onWillFocus={onWillFocus2}
|
||||||
|
onDidFocus={onDidFocus2}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
checkAddListenerCalled(6);
|
||||||
|
checkAddListenerCalledWith('willFocus', onWillFocus2);
|
||||||
|
checkAddListenerCalledWith('didFocus', onDidFocus2);
|
||||||
|
checkRemoveCalled(3);
|
||||||
|
checkRemoveCalledWith('didBlur', eventListenerProps.onDidBlur);
|
||||||
|
checkRemoveCalledWith('willFocus', eventListenerProps.onWillFocus);
|
||||||
|
checkRemoveCalledWith('didFocus', eventListenerProps.onDidFocus);
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user