Skip to content

Commit a1c080a

Browse files
committed
Merge branch 'develop' into next
2 parents c5f40e6 + 331cd33 commit a1c080a

23 files changed

Lines changed: 989 additions & 99 deletions

bluebase/expo/apps/plugin-settings-app/Screens/NotFound.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { H1, View } from '@bluebase/components';
2+
23
import React from 'react';
34

45
export class NotFoundScreen extends React.Component {

src/DrawerActions.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { DrawerActionsObject, DrawerActionsProps } from '@bluebase/components';
2+
import { NavigationInjectedProps, withNavigation } from 'react-navigation';
3+
4+
import { ReactElement } from 'react';
5+
6+
/**
7+
* DrawerActions
8+
* This is a render prop component which passes the navigation actions
9+
* to the child component. It's useful when you cannot pass the navigation
10+
* actions into the component directly, or don't want to pass it in case
11+
* of a deeply nested child.
12+
*/
13+
export const DrawerActions = withNavigation(
14+
(props: DrawerActionsProps & NavigationInjectedProps) => {
15+
// (props: DrawerActionsProps & NavigationInjectedProps) => {
16+
// Extract props
17+
const {
18+
// This is passed by the consumer of this component
19+
children,
20+
// We extract this from the "withNavigation" hoc
21+
navigation,
22+
} = props;
23+
24+
const noop = () => {
25+
return;
26+
};
27+
28+
const { openDrawer = noop, closeDrawer = noop, toggleDrawer = noop } = navigation;
29+
30+
const actions: DrawerActionsObject = {
31+
closeDrawer,
32+
openDrawer,
33+
toggleDrawer,
34+
};
35+
36+
// Pass actions the object on to the children
37+
return children(actions) as ReactElement;
38+
}
39+
);

src/Navigation.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { BlueBase, BlueBaseContext, IntlConsumer, ThemeConsumer } from '@bluebase/core';
2+
3+
import { NavigationContainer } from 'react-navigation';
4+
import { NavigationProps } from '@bluebase/components';
5+
import React from 'react';
6+
import { createContainer } from './lib/index';
7+
import { createNavigator } from './helpers/createNavigator';
8+
9+
/**
10+
* Navigation
11+
* This serves as an entry point where BlueBase passes routes and navigation
12+
* configs to this component.
13+
*/
14+
export class Navigation extends React.Component<NavigationProps> {
15+
static contextType: React.Context<BlueBase> = BlueBaseContext;
16+
17+
private Router?: NavigationContainer;
18+
19+
componentWillMount() {
20+
// navigator prop from BlueBase
21+
const { navigator } = this.props;
22+
23+
// Create a React Navigation container component
24+
this.Router = createContainer(createNavigator(navigator, this.context));
25+
}
26+
27+
render() {
28+
const Router = this.Router;
29+
const { navigator, ...rest } = this.props;
30+
31+
// Render it!
32+
return Router ? (
33+
<ThemeConsumer>
34+
{({ theme }) => (
35+
<IntlConsumer>
36+
{intl => <Router screenProps={{ BB: this.context, theme, intl, ...rest }} />}
37+
</IntlConsumer>
38+
)}
39+
</ThemeConsumer>
40+
) : null;
41+
}
42+
}

src/NavigationActions.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { NavigationInjectedProps, withNavigation } from 'react-navigation';
2+
3+
import { NavigationActionsProps } from '@bluebase/components';
4+
import { ReactElement } from 'react';
5+
import { navigationToActionObject } from './helpers/navigationToActionObject';
6+
7+
/**
8+
* NavigationActions
9+
* This is a render prop component which passes the navigation actions
10+
* to the child component. It's useful when you cannot pass the navigation
11+
* actions into the component directly, or don't want to pass it in case
12+
* of a deeply nested child.
13+
*/
14+
// export const NavigationActions: React.ComponentType<any> = withNavigation((props: any) => {
15+
export const NavigationActions: React.ComponentType<NavigationActionsProps> = withNavigation(
16+
(props: NavigationActionsProps & NavigationInjectedProps) => {
17+
// Extract props
18+
const {
19+
// This is passed by the consumer of this component
20+
children,
21+
// We extract this from the "withNavigation" hoc
22+
navigation,
23+
} = props;
24+
25+
// Convert React Navigation's "navigation" prop to BlueBase's NavigationActionsObject
26+
const actions = navigationToActionObject(navigation);
27+
28+
// Pass actions the object on to the children
29+
return children(actions) as ReactElement;
30+
}
31+
);

src/__tests__/Navigation.test.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import {
2+
// SettingsScreen,
3+
Tab1Screen,
4+
Tab2Screen,
5+
} from '../../bluebase/expo/apps/plugin-settings-app/Screens';
6+
import { BlueBaseApp } from '@bluebase/core';
7+
import { Navigation } from '../Navigation';
8+
import Plugin from '../index';
9+
import React from 'react';
10+
import { mount } from 'enzyme';
11+
import { waitForElement } from 'enzyme-async-helpers';
12+
13+
const nav = {
14+
name: 'SettingsTabs',
15+
navigationOptions: {
16+
title: 'Settings Tabs',
17+
},
18+
navigator: {
19+
routes: [{
20+
exact: true,
21+
name: 'Tab1',
22+
navigationOptions: {
23+
title: 'Tab A',
24+
},
25+
path: 't1',
26+
screen: Tab1Screen,
27+
}, {
28+
exact: true,
29+
name: 'Tab2',
30+
navigationOptions: {
31+
title: 'Tab B',
32+
},
33+
path: 't2',
34+
screen: Tab2Screen,
35+
}],
36+
type: 'tab'
37+
},
38+
path: 'tabs',
39+
};
40+
41+
describe('Navigation tests', () => {
42+
it('should check props', async () => {
43+
const wrapper = mount(
44+
<BlueBaseApp plugins={[Plugin]}>
45+
<Navigation navigator={nav.navigator} styles={{ headerMode: 'none' }} />
46+
</BlueBaseApp>
47+
);
48+
await waitForElement(wrapper, Navigation);
49+
expect(wrapper.find('Navigation').prop('navigator')).toBe(nav.navigator);
50+
expect(wrapper.find('Navigation').prop('styles')).toEqual({ headerMode: 'none' });
51+
});
52+
53+
it('should check if there is no router', () => {
54+
const wrapper = mount(
55+
// <BlueBaseApp plugins={[Plugin]}>
56+
<Navigation navigator={{
57+
routes: [
58+
{} as any
59+
]
60+
} as any}/>
61+
// </BlueBaseApp>
62+
);
63+
// await waitForElement(wrapper, Navigation);
64+
expect(wrapper).toThrow('Please specify at least one route when configuring a navigator.');
65+
// expect(wrapper.find('Navigation').prop('navigator')).toBe({});
66+
});
67+
});

src/__tests__/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ test('Plugin should be correctly registered', async () => {
88
// console.log(BB);
99

1010
expect(BB.Plugins.has('@bluebase/plugin-react-navigation')).toBeTruthy();
11-
});
11+
});
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
SettingsScreen,
3+
Tab1Screen,
4+
} from '../../../bluebase/expo/apps/plugin-settings-app/Screens';
5+
import { BlueBase } from '@bluebase/core';
6+
import Plugin from '../../index';
7+
import { createNavigator } from '../createNavigator';
8+
9+
const inputRoutes = {
10+
initialRouteName: 'Home',
11+
routes: [
12+
{
13+
exact: true,
14+
name: 'Settings',
15+
navigationOptions: {},
16+
path: '/p/settings',
17+
screen: SettingsScreen,
18+
},
19+
],
20+
type: 'stack',
21+
};
22+
23+
describe('createNavigator tests', () => {
24+
it('should test if there is no navigator in routes', async () => {
25+
const BB = new BlueBase();
26+
await BB.Plugins.register(Plugin);
27+
createNavigator(inputRoutes, {} as any, BB);
28+
expect(createNavigator).toBeTruthy();
29+
});
30+
it('should test if there is no navigator in routes', async () => {
31+
const BB = new BlueBase();
32+
await BB.Plugins.register(Plugin);
33+
34+
inputRoutes.routes.push({
35+
name: 'Settings',
36+
path: '/p/settings',
37+
screen: SettingsScreen,
38+
} as any);
39+
40+
createNavigator(inputRoutes, {} as any, BB);
41+
expect(createNavigator).toBeTruthy();
42+
});
43+
44+
it('should test if there is navigator an screen in routes', () => {
45+
inputRoutes.routes.push({
46+
name: 'SettingsTabs',
47+
screen: SettingsScreen,
48+
navigator: {
49+
routes: [{
50+
name: 'Tab1',
51+
navigationOptions: {
52+
title: 'Tab A',
53+
},
54+
path: 't1',
55+
screen: Tab1Screen,
56+
}],
57+
},
58+
path: 'tabs',
59+
} as any);
60+
createNavigator(inputRoutes, {} as any, {} as any);
61+
expect(createNavigator).toBeTruthy();
62+
});
63+
64+
it('should test if there is navigator only in routes', () => {
65+
inputRoutes.routes.push({
66+
name: 'SettingsTabs',
67+
navigator: {
68+
routes: [{
69+
name: 'Tab1',
70+
navigationOptions: {
71+
title: 'Tab A',
72+
},
73+
path: 't1',
74+
screen: Tab1Screen,
75+
}],
76+
},
77+
path: 'tabs',
78+
} as any);
79+
createNavigator(inputRoutes, {} as any, {} as any);
80+
expect(createNavigator).toBeTruthy();
81+
});
82+
it('should test if there is only screen component in routes', () => {
83+
inputRoutes.routes.push({
84+
navigator: {
85+
routes: [{ screen: SettingsScreen }]
86+
}
87+
} as any);
88+
createNavigator(inputRoutes, {} as any, {} as any);
89+
expect(createNavigator).toBeTruthy();
90+
});
91+
});
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {
2+
HomeScreen,
3+
// SettingsDetailScreen,
4+
// SettingsScreen,
5+
Tab1Screen,
6+
Tab2Screen,
7+
} from '../../../bluebase/expo/apps/plugin-settings-app/Screens';
8+
import { createWrappedNavigator } from '../createWrappedNavigator';
9+
// import { navigationConverterHoc } from '../navigationConverterHoc';
10+
11+
const nav = {
12+
name: 'SettingsTabs',
13+
// TODO: test initial route here
14+
navigationOptions: {
15+
title: 'Settings Tabs',
16+
},
17+
navigator: {
18+
routes: [{
19+
exact: true,
20+
name: 'Tab1',
21+
navigationOptions: {
22+
title: 'Tab A',
23+
},
24+
path: 't1',
25+
screen: Tab1Screen,
26+
}, {
27+
exact: true,
28+
name: 'Tab2',
29+
navigationOptions: {
30+
title: 'Tab B',
31+
},
32+
path: 't2',
33+
screen: Tab2Screen,
34+
}],
35+
type: 'tab'
36+
},
37+
path: 'tabs',
38+
};
39+
40+
describe('createWrappedNavigator', () => {
41+
test('test', () => {
42+
createWrappedNavigator(nav.navigator, HomeScreen);
43+
expect(createWrappedNavigator).toBeTruthy();
44+
// jest.mock('navigationConverterHoc', () => jest.fn());
45+
// createWrappedNavigator(nav.navigator, HomeScreen).WrappedNavigator = jest.fn();
46+
// const q = jest.mock('../navigationConverterHoc', () => jest.fn());
47+
});
48+
// test('navigationConverterHoc call', () => {
49+
// // jest.mock('navigationConverterHoc', () => jest.fn());
50+
// // navigationConverterHoc = jest.fn().mockReturnValue('');
51+
// // const data = new createWrappedNavigator(nav.navigator, HomeScreen);
52+
// // expect(data.WrappedNavigator).toBeCalled();
53+
// });
54+
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
createBottomTabNavigator,
3+
createDrawerNavigator,
4+
createMaterialTopTabNavigator,
5+
createStackNavigator,
6+
createSwitchNavigator,
7+
} from '../../lib';
8+
9+
import {
10+
getNavigatorFn
11+
} from '../getNavigatorFn';
12+
13+
describe('Get Naivgator Functions Tests', () => {
14+
it('it should return createSwitchNavigator by default', () => {
15+
expect(getNavigatorFn()).toBe(createSwitchNavigator);
16+
});
17+
it('it should return createSwitchNavigator', () => {
18+
expect(getNavigatorFn('switch')).toBe(createSwitchNavigator);
19+
});
20+
it('it should return createStackNavigator on stack input', () => {
21+
expect(getNavigatorFn('stack')).toBe(createStackNavigator);
22+
});
23+
it('it should return createBottomTabNavigator', () => {
24+
expect(getNavigatorFn('bottom-tab')).toBe(createBottomTabNavigator);
25+
});
26+
it('it should return createDrawerNavigator', () => {
27+
expect(getNavigatorFn('drawer')).toBe(createDrawerNavigator);
28+
});
29+
it('it should return createMaterialTopTabnavigator', () => {
30+
expect(getNavigatorFn('tab')).toBe(createMaterialTopTabNavigator);
31+
});
32+
});

0 commit comments

Comments
 (0)