Explorar el Código

adding support for modals

talkol hace 9 años
padre
commit
00ab1a9974

+ 1
- 0
.npmignore Ver fichero

1
 example/
1
 example/
2
+example-redux/

+ 8
- 8
example/src/app.js Ver fichero

7
 Navigation.startTabBasedApp({
7
 Navigation.startTabBasedApp({
8
   tabs: [
8
   tabs: [
9
     {
9
     {
10
-      title: 'One',
10
+      label: 'One',
11
       screen: 'example.FirstTabScreen',
11
       screen: 'example.FirstTabScreen',
12
       icon: require('../img/one.png'),
12
       icon: require('../img/one.png'),
13
       selectedIcon: require('../img/one_selected.png'),
13
       selectedIcon: require('../img/one_selected.png'),
14
-      screenTitle: 'Screen One'
14
+      title: 'Screen One'
15
     },
15
     },
16
     {
16
     {
17
-      title: 'Two',
17
+      label: 'Two',
18
       screen: 'example.SecondTabScreen',
18
       screen: 'example.SecondTabScreen',
19
       icon: require('../img/two.png'),
19
       icon: require('../img/two.png'),
20
       selectedIcon: require('../img/two_selected.png'),
20
       selectedIcon: require('../img/two_selected.png'),
21
-      screenTitle: 'Screen Two'
21
+      title: 'Screen Two'
22
     },
22
     },
23
     {
23
     {
24
-      title: 'Three',
24
+      label: 'Three',
25
       screen: 'example.ThirdTabScreen',
25
       screen: 'example.ThirdTabScreen',
26
       icon: require('../img/three.png'),
26
       icon: require('../img/three.png'),
27
       selectedIcon: require('../img/three_selected.png'),
27
       selectedIcon: require('../img/three_selected.png'),
28
-      screenTitle: 'Screen Three',
28
+      title: 'Screen Three',
29
       navigatorStyle: {
29
       navigatorStyle: {
30
-        navBarBackgroundColor: '#26ade4',
31
-        navBarTextColor: '#f0f0f0',
30
+        navBarBackgroundColor: '#4dbce9',
31
+        navBarTextColor: '#f7f7f7',
32
         navBarButtonColor: '#ffffff'
32
         navBarButtonColor: '#ffffff'
33
       }
33
       }
34
     }
34
     }

+ 12
- 1
example/src/screens/FirstTabScreen.js Ver fichero

12
 // need to import every screen we push
12
 // need to import every screen we push
13
 import './PushedScreen';
13
 import './PushedScreen';
14
 import './StyledScreen';
14
 import './StyledScreen';
15
+import './ModalScreen';
15
 
16
 
16
 // instead of React.Component, we extend Screen (imported above)
17
 // instead of React.Component, we extend Screen (imported above)
17
 class FirstTabScreen extends Screen {
18
 class FirstTabScreen extends Screen {
30
           <Text style={styles.button}>Push Styled Screen</Text>
31
           <Text style={styles.button}>Push Styled Screen</Text>
31
         </TouchableOpacity>
32
         </TouchableOpacity>
32
 
33
 
34
+        <TouchableOpacity onPress={ this.onModalPress.bind(this) }>
35
+          <Text style={styles.button}>Show Modal Screen</Text>
36
+        </TouchableOpacity>
37
+
33
       </View>
38
       </View>
34
     );
39
     );
35
   }
40
   }
41
   }
46
   }
42
   onPushStyledPress() {
47
   onPushStyledPress() {
43
     this.navigator.push({
48
     this.navigator.push({
44
-      title: "More",
49
+      title: "Styled",
45
       screen: "example.StyledScreen"
50
       screen: "example.StyledScreen"
46
     });
51
     });
47
   }
52
   }
53
+  onModalPress() {
54
+    this.navigator.showModal({
55
+      title: "Modal",
56
+      screen: "example.ModalScreen"
57
+    });
58
+  }
48
 }
59
 }
49
 
60
 
50
 const styles = StyleSheet.create({
61
 const styles = StyleSheet.create({

+ 68
- 0
example/src/screens/ModalScreen.js Ver fichero

1
+import React, {
2
+  Text,
3
+  View,
4
+  ScrollView,
5
+  TouchableOpacity,
6
+  StyleSheet
7
+} from 'react-native';
8
+
9
+// important imports, the magic is here
10
+import { Navigation, Screen } from 'react-native-navigation';
11
+
12
+// need to import every screen we push
13
+import './PushedScreen';
14
+import './StyledScreen';
15
+
16
+// instead of React.Component, we extend Screen (imported above)
17
+class ModalScreen extends Screen {
18
+  constructor(props) {
19
+    super(props);
20
+  }
21
+  render() {
22
+    return (
23
+      <View style={{flex: 1, padding: 20}}>
24
+
25
+        <TouchableOpacity onPress={ this.onPushPress.bind(this) }>
26
+          <Text style={styles.button}>Push Plain Screen</Text>
27
+        </TouchableOpacity>
28
+
29
+        <TouchableOpacity onPress={ this.onPushStyledPress.bind(this) }>
30
+          <Text style={styles.button}>Push Styled Screen</Text>
31
+        </TouchableOpacity>
32
+
33
+        <TouchableOpacity onPress={ this.onClosePress.bind(this) }>
34
+          <Text style={styles.button}>Close Modal</Text>
35
+        </TouchableOpacity>
36
+
37
+      </View>
38
+    );
39
+  }
40
+  onPushPress() {
41
+    this.navigator.push({
42
+      title: "More",
43
+      screen: "example.PushedScreen"
44
+    });
45
+  }
46
+  onPushStyledPress() {
47
+    this.navigator.push({
48
+      title: "More",
49
+      screen: "example.StyledScreen"
50
+    });
51
+  }
52
+  onClosePress() {
53
+    this.navigator.dismissModal();
54
+  }
55
+}
56
+
57
+const styles = StyleSheet.create({
58
+  button: {
59
+    textAlign: 'center',
60
+    fontSize: 18,
61
+    marginBottom: 10,
62
+    marginTop:10,
63
+    color: 'blue'
64
+  }
65
+});
66
+
67
+// every screen must be registered with a unique name
68
+Navigation.registerScreen('example.ModalScreen', () => ModalScreen);

+ 2
- 2
package.json Ver fichero

18
   "author": "Tal Kol <talkol@gmail.com>",
18
   "author": "Tal Kol <talkol@gmail.com>",
19
   "license": "MIT",
19
   "license": "MIT",
20
   "peerDependencies": {
20
   "peerDependencies": {
21
-    "react-native": ">=0.16.0"
21
+    "react-native": ">=0.19.0"
22
   },
22
   },
23
   "dependencies": {
23
   "dependencies": {
24
-    "react-native-controllers": "^1.1.0"
24
+    "react-native-controllers": "^1.2.0"
25
   }
25
   }
26
 }
26
 }

+ 10
- 0
src/Navigation.js Ver fichero

17
   return generator();
17
   return generator();
18
 }
18
 }
19
 
19
 
20
+function showModal(params = {}) {
21
+  return platformSpecific.showModal(params);
22
+}
23
+
24
+function dismissModal(params = {}) {
25
+  return platformSpecific.dismissModal(params);
26
+}
27
+
20
 export default Navigation = {
28
 export default Navigation = {
21
   registerScreen,
29
   registerScreen,
22
   getRegisteredScreen,
30
   getRegisteredScreen,
31
+  showModal,
32
+  dismissModal,
23
   startTabBasedApp: platformSpecific.startTabBasedApp,
33
   startTabBasedApp: platformSpecific.startTabBasedApp,
24
   startSingleScreenApp: platformSpecific.startSingleScreenApp
34
   startSingleScreenApp: platformSpecific.startSingleScreenApp
25
 }
35
 }

+ 7
- 0
src/Screen.js Ver fichero

1
 import { Component } from 'react-native';
1
 import { Component } from 'react-native';
2
 import platformSpecific from './platformSpecific';
2
 import platformSpecific from './platformSpecific';
3
+import Navigation from './Navigation';
3
 
4
 
4
 class Navigator {
5
 class Navigator {
5
   constructor(navigatorID) {
6
   constructor(navigatorID) {
11
   pop(params = {}) {
12
   pop(params = {}) {
12
     return platformSpecific.navigatorPop(this, params);
13
     return platformSpecific.navigatorPop(this, params);
13
   }
14
   }
15
+  showModal(params = {}) {
16
+    return Navigation.showModal(params);
17
+  }
18
+  dismissModal(params = {}) {
19
+    return Navigation.dismissModal(params);
20
+  }
14
 }
21
 }
15
 
22
 
16
 export default class Screen extends Component {
23
 export default class Screen extends Component {

+ 63
- 42
src/platformSpecific.ios.js Ver fichero

1
 import utils from './utils';
1
 import utils from './utils';
2
 import Navigation from './Navigation';
2
 import Navigation from './Navigation';
3
-import Controllers from 'react-native-controllers';
3
+import Controllers, { Modal } from 'react-native-controllers';
4
 const React = Controllers.hijackReact();
4
 const React = Controllers.hijackReact();
5
 const {
5
 const {
6
   ControllerRegistry,
6
   ControllerRegistry,
14
     console.error('startTabBasedApp(params): params.tabs is required');
14
     console.error('startTabBasedApp(params): params.tabs is required');
15
     return;
15
     return;
16
   }
16
   }
17
-  const appID = utils.getRandomId();
18
-  const App = Controllers.createClass({
17
+  const controllerID = utils.getRandomId();
18
+  const Controller = Controllers.createClass({
19
     render: function() {
19
     render: function() {
20
       return (
20
       return (
21
-        <TabBarControllerIOS id={appID + '_tabs'}>
21
+        <TabBarControllerIOS id={controllerID + '_tabs'}>
22
         {
22
         {
23
           params.tabs.map(function(tab, index) {
23
           params.tabs.map(function(tab, index) {
24
-            const navigatorID = appID + '_nav' + index;
24
+            const navigatorID = controllerID + '_nav' + index;
25
             if (!tab.screen) {
25
             if (!tab.screen) {
26
               console.error('startTabBasedApp(params): every tab must include a screen property, take a look at tab#' + (index+1));
26
               console.error('startTabBasedApp(params): every tab must include a screen property, take a look at tab#' + (index+1));
27
               return;
27
               return;
28
             }
28
             }
29
-            const screenClass = Navigation.getRegisteredScreen(tab.screen);
30
-            if (!screenClass) {
31
-              console.error('Cannot create screen ' + tab.screen + '. Are you it was registered with Navigation.registerScreen?');
32
-              return;
33
-            }
34
-            const navigatorStyle = Object.assign({}, screenClass.navigatorStyle);
35
-            if (tab.navigatorStyle) {
36
-              Object.assign(navigatorStyle, tab.navigatorStyle);
37
-            }
29
+            const { navigatorStyle } = _mergeScreenSpecificSettings(tab.screen, tab);
38
             return (
30
             return (
39
-              <TabBarControllerIOS.Item {...tab}>
31
+              <TabBarControllerIOS.Item {...tab} title={tab.label}>
40
                 <NavigationControllerIOS
32
                 <NavigationControllerIOS
41
                   id={navigatorID}
33
                   id={navigatorID}
42
-                  title={tab.screenTitle}
34
+                  title={tab.title}
43
                   component={tab.screen}
35
                   component={tab.screen}
44
                   passProps={{navigatorID: navigatorID}}
36
                   passProps={{navigatorID: navigatorID}}
45
                   style={navigatorStyle}
37
                   style={navigatorStyle}
52
       );
44
       );
53
     }
45
     }
54
   });
46
   });
55
-  ControllerRegistry.registerController(appID, () => App);
56
-  ControllerRegistry.setRootController(appID);
47
+  ControllerRegistry.registerController(controllerID, () => Controller);
48
+  ControllerRegistry.setRootController(controllerID);
57
 }
49
 }
58
 
50
 
59
 function startSingleScreenApp(params) {
51
 function startSingleScreenApp(params) {
61
     console.error('startSingleScreenApp(params): params.screen is required');
53
     console.error('startSingleScreenApp(params): params.screen is required');
62
     return;
54
     return;
63
   }
55
   }
64
-  const appID = utils.getRandomId();
65
-  const App = Controllers.createClass({
56
+  const controllerID = utils.getRandomId();
57
+  const Controller = Controllers.createClass({
66
     render: function() {
58
     render: function() {
67
       const screen = params.screen;
59
       const screen = params.screen;
68
-      const navigatorID = appID + '_nav';
60
+      const navigatorID = controllerID + '_nav';
69
       if (!screen.screen) {
61
       if (!screen.screen) {
70
         console.error('startSingleScreenApp(params): screen must include a screen property');
62
         console.error('startSingleScreenApp(params): screen must include a screen property');
71
         return;
63
         return;
72
       }
64
       }
73
-      const screenClass = Navigation.getRegisteredScreen(screen.screen);
74
-      if (!screenClass) {
75
-        console.error('Cannot create screen ' + screen.screen + '. Are you it was registered with Navigation.registerScreen?');
76
-        return;
77
-      }
78
-      const navigatorStyle = Object.assign({}, screenClass.navigatorStyle);
79
-      if (screen.navigatorStyle) {
80
-        Object.assign(navigatorStyle, screen.navigatorStyle);
81
-      }
65
+      const { navigatorStyle } = _mergeScreenSpecificSettings(screen.screen, screen);
82
       return (
66
       return (
83
         <NavigationControllerIOS
67
         <NavigationControllerIOS
84
           id={navigatorID}
68
           id={navigatorID}
85
-          title={screen.screenTitle}
69
+          title={screen.title}
86
           component={screen.screen}
70
           component={screen.screen}
87
           passProps={{navigatorID: navigatorID}}
71
           passProps={{navigatorID: navigatorID}}
88
           style={navigatorStyle}
72
           style={navigatorStyle}
90
       );
74
       );
91
     }
75
     }
92
   });
76
   });
93
-  ControllerRegistry.registerController(appID, () => App);
94
-  ControllerRegistry.setRootController(appID);
77
+  ControllerRegistry.registerController(controllerID, () => Controller);
78
+  ControllerRegistry.setRootController(controllerID);
95
 }
79
 }
96
 
80
 
97
-function navigatorPush(navigator, params) {
98
-  if (!params.screen) {
99
-    console.error('Navigator.push(params): params.screen is required');
100
-    return;
101
-  }
102
-  const passProps = params.passProps || {};
103
-  const screenClass = Navigation.getRegisteredScreen(params.screen);
81
+function _mergeScreenSpecificSettings(screenID, params) {
82
+  const screenClass = Navigation.getRegisteredScreen(screenID);
104
   if (!screenClass) {
83
   if (!screenClass) {
105
-    console.error('Cannot create screen ' + params.screen + '. Are you it was registered with Navigation.registerScreen?');
84
+    console.error('Cannot create screen ' + screenID + '. Are you it was registered with Navigation.registerScreen?');
106
     return;
85
     return;
107
   }
86
   }
108
   const navigatorStyle = Object.assign({}, screenClass.navigatorStyle);
87
   const navigatorStyle = Object.assign({}, screenClass.navigatorStyle);
109
   if (params.navigatorStyle) {
88
   if (params.navigatorStyle) {
110
     Object.assign(navigatorStyle, params.navigatorStyle);
89
     Object.assign(navigatorStyle, params.navigatorStyle);
111
   }
90
   }
91
+  return { navigatorStyle };
92
+}
93
+
94
+function navigatorPush(navigator, params) {
95
+  if (!params.screen) {
96
+    console.error('Navigator.push(params): params.screen is required');
97
+    return;
98
+  }
99
+  const { navigatorStyle } = _mergeScreenSpecificSettings(params.screen, params);
100
+  const passProps = params.passProps || {};
112
   passProps.navigatorID = navigator.navigatorID;
101
   passProps.navigatorID = navigator.navigatorID;
113
   Controllers.NavigationControllerIOS(navigator.navigatorID).push({
102
   Controllers.NavigationControllerIOS(navigator.navigatorID).push({
114
     title: params.title,
103
     title: params.title,
126
   });
115
   });
127
 }
116
 }
128
 
117
 
118
+function showModal(params) {
119
+  if (!params.screen) {
120
+    console.error('showModal(params): params.screen is required');
121
+    return;
122
+  }
123
+  const { navigatorStyle } = _mergeScreenSpecificSettings(params.screen, params);
124
+  const controllerID = utils.getRandomId();
125
+  const Controller = Controllers.createClass({
126
+    render: function() {
127
+      const navigatorID = controllerID + '_nav';
128
+      const { navigatorStyle } = _mergeScreenSpecificSettings(params.screen, params);
129
+      return (
130
+        <NavigationControllerIOS
131
+          id={navigatorID}
132
+          title={params.title}
133
+          component={params.screen}
134
+          passProps={{navigatorID: navigatorID}}
135
+          style={navigatorStyle}
136
+        />
137
+      );
138
+    }
139
+  });
140
+  ControllerRegistry.registerController(controllerID, () => Controller);
141
+  Modal.showController(controllerID, params.animationType);
142
+}
143
+
144
+function dismissModal(params) {
145
+  Modal.dismissController(params.animationType);
146
+}
147
+
129
 export default platformSpecific = {
148
 export default platformSpecific = {
130
   startTabBasedApp,
149
   startTabBasedApp,
131
   startSingleScreenApp,
150
   startSingleScreenApp,
132
   navigatorPush,
151
   navigatorPush,
133
-  navigatorPop
152
+  navigatorPop,
153
+  showModal,
154
+  dismissModal
134
 }
155
 }