Browse Source

Update custom tab bar to use TypeScript

Arnaud Vergnet 3 years ago
parent
commit
5261e85254

src/components/Tabbar/CustomTabBar.js → src/components/Tabbar/CustomTabBar.tsx View File

17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
  */
18
  */
19
 
19
 
20
-// @flow
21
-
22
 import * as React from 'react';
20
 import * as React from 'react';
23
 import {Animated} from 'react-native';
21
 import {Animated} from 'react-native';
24
 import {withTheme} from 'react-native-paper';
22
 import {withTheme} from 'react-native-paper';
26
 import {StackNavigationProp} from '@react-navigation/stack';
24
 import {StackNavigationProp} from '@react-navigation/stack';
27
 import TabIcon from './TabIcon';
25
 import TabIcon from './TabIcon';
28
 import TabHomeIcon from './TabHomeIcon';
26
 import TabHomeIcon from './TabHomeIcon';
29
-import type {CustomThemeType} from '../../managers/ThemeManager';
30
 
27
 
31
 type RouteType = {
28
 type RouteType = {
32
-  name: string,
33
-  key: string,
34
-  params: {collapsible: Collapsible},
29
+  name: string;
30
+  key: string;
31
+  params: {collapsible: Collapsible};
35
   state: {
32
   state: {
36
-    index: number,
37
-    routes: Array<RouteType>,
38
-  },
33
+    index: number;
34
+    routes: Array<RouteType>;
35
+  };
39
 };
36
 };
40
 
37
 
41
 type PropsType = {
38
 type PropsType = {
42
   state: {
39
   state: {
43
-    index: number,
44
-    routes: Array<RouteType>,
45
-  },
40
+    index: number;
41
+    routes: Array<RouteType>;
42
+  };
46
   descriptors: {
43
   descriptors: {
47
     [key: string]: {
44
     [key: string]: {
48
       options: {
45
       options: {
49
-        tabBarLabel: string,
50
-        title: string,
51
-      },
52
-    },
53
-  },
54
-  navigation: StackNavigationProp,
55
-  theme: CustomThemeType,
46
+        tabBarLabel: string;
47
+        title: string;
48
+      };
49
+    };
50
+  };
51
+  navigation: StackNavigationProp<any>;
52
+  theme: ReactNativePaper.Theme;
56
 };
53
 };
57
 
54
 
58
 type StateType = {
55
 type StateType = {
59
-  // eslint-disable-next-line flowtype/no-weak-types
60
-  translateY: any,
56
+  translateY: any;
61
 };
57
 };
62
 
58
 
59
+type validRoutes = 'proxiwash' | 'services' | 'planning' | 'planex';
60
+
63
 const TAB_ICONS = {
61
 const TAB_ICONS = {
64
   proxiwash: 'tshirt-crew',
62
   proxiwash: 'tshirt-crew',
65
   services: 'account-circle',
63
   services: 'account-circle',
70
 class CustomTabBar extends React.Component<PropsType, StateType> {
68
 class CustomTabBar extends React.Component<PropsType, StateType> {
71
   static TAB_BAR_HEIGHT = 48;
69
   static TAB_BAR_HEIGHT = 48;
72
 
70
 
73
-  constructor() {
74
-    super();
71
+  constructor(props: PropsType) {
72
+    super(props);
75
     this.state = {
73
     this.state = {
76
       translateY: new Animated.Value(0),
74
       translateY: new Animated.Value(0),
77
     };
75
     };
86
    */
84
    */
87
   onItemPress(route: RouteType, currentIndex: number, destIndex: number) {
85
   onItemPress(route: RouteType, currentIndex: number, destIndex: number) {
88
     const {navigation} = this.props;
86
     const {navigation} = this.props;
89
-    const event = navigation.emit({
90
-      type: 'tabPress',
91
-      target: route.key,
92
-      canPreventDefault: true,
93
-    });
94
-    if (currentIndex !== destIndex && !event.defaultPrevented)
87
+    if (currentIndex !== destIndex) {
95
       navigation.navigate(route.name);
88
       navigation.navigate(route.name);
89
+    }
96
   }
90
   }
97
 
91
 
98
   /**
92
   /**
102
    */
96
    */
103
   onItemLongPress(route: RouteType) {
97
   onItemLongPress(route: RouteType) {
104
     const {navigation} = this.props;
98
     const {navigation} = this.props;
105
-    const event = navigation.emit({
106
-      type: 'tabLongPress',
107
-      target: route.key,
108
-      canPreventDefault: true,
109
-    });
110
-    if (route.name === 'home' && !event.defaultPrevented)
99
+    if (route.name === 'home') {
111
       navigation.navigate('game-start');
100
       navigation.navigate('game-start');
101
+    }
112
   }
102
   }
113
 
103
 
114
   /**
104
   /**
126
    * @param focused
116
    * @param focused
127
    * @returns {null}
117
    * @returns {null}
128
    */
118
    */
129
-  getTabBarIcon = (route: RouteType, focused: boolean): React.Node => {
130
-    let icon = TAB_ICONS[route.name];
119
+  getTabBarIcon = (route: RouteType, focused: boolean) => {
120
+    let icon = TAB_ICONS[route.name as validRoutes];
131
     icon = focused ? icon : `${icon}-outline`;
121
     icon = focused ? icon : `${icon}-outline`;
132
-    if (route.name !== 'home') return icon;
133
-    return null;
122
+    if (route.name !== 'home') {
123
+      return icon;
124
+    }
125
+    return '';
134
   };
126
   };
135
 
127
 
136
   /**
128
   /**
141
    * @param index The index of the current route
133
    * @param index The index of the current route
142
    * @returns {*}
134
    * @returns {*}
143
    */
135
    */
144
-  getRenderIcon = (route: RouteType, index: number): React.Node => {
136
+  getRenderIcon = (route: RouteType, index: number) => {
145
     const {props} = this;
137
     const {props} = this;
146
     const {state} = props;
138
     const {state} = props;
147
     const {options} = props.descriptors[route.key];
139
     const {options} = props.descriptors[route.key];
148
     let label;
140
     let label;
149
-    if (options.tabBarLabel != null) label = options.tabBarLabel;
150
-    else if (options.title != null) label = options.title;
151
-    else label = route.name;
141
+    if (options.tabBarLabel != null) {
142
+      label = options.tabBarLabel;
143
+    } else if (options.title != null) {
144
+      label = options.title;
145
+    } else {
146
+      label = route.name;
147
+    }
152
 
148
 
153
     const onPress = () => {
149
     const onPress = () => {
154
       this.onItemPress(route, state.index, index);
150
       this.onItemPress(route, state.index, index);
186
     );
182
     );
187
   };
183
   };
188
 
184
 
189
-  getIcons(): React.Node {
185
+  getIcons() {
190
     const {props} = this;
186
     const {props} = this;
191
     return props.state.routes.map(this.getRenderIcon);
187
     return props.state.routes.map(this.getRenderIcon);
192
   }
188
   }
209
     }
205
     }
210
   };
206
   };
211
 
207
 
212
-  render(): React.Node {
208
+  render() {
213
     const {props, state} = this;
209
     const {props, state} = this;
214
     props.navigation.addListener('state', this.onRouteChange);
210
     props.navigation.addListener('state', this.onRouteChange);
215
     const icons = this.getIcons();
211
     const icons = this.getIcons();
216
     return (
212
     return (
217
-      // $FlowFixMe
218
       <Animated.View
213
       <Animated.View
219
-        useNativeDriver
220
         style={{
214
         style={{
221
           flexDirection: 'row',
215
           flexDirection: 'row',
222
           height: CustomTabBar.TAB_BAR_HEIGHT,
216
           height: CustomTabBar.TAB_BAR_HEIGHT,

src/components/Tabbar/TabHomeIcon.js → src/components/Tabbar/TabHomeIcon.tsx View File

17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
  */
18
  */
19
 
19
 
20
-// @flow
21
-
22
 import * as React from 'react';
20
 import * as React from 'react';
23
 import {Image, View} from 'react-native';
21
 import {Image, View} from 'react-native';
24
 import {FAB} from 'react-native-paper';
22
 import {FAB} from 'react-native-paper';
25
 import * as Animatable from 'react-native-animatable';
23
 import * as Animatable from 'react-native-animatable';
26
-import FOCUSED_ICON from '../../../assets/tab-icon.png';
27
-import UNFOCUSED_ICON from '../../../assets/tab-icon-outline.png';
24
+const FOCUSED_ICON = require('../../../assets/tab-icon.png');
25
+const UNFOCUSED_ICON = require('../../../assets/tab-icon-outline.png');
28
 
26
 
29
 type PropsType = {
27
 type PropsType = {
30
-  focused: boolean,
31
-  onPress: () => void,
32
-  onLongPress: () => void,
33
-  tabBarHeight: number,
28
+  focused: boolean;
29
+  onPress: () => void;
30
+  onLongPress: () => void;
31
+  tabBarHeight: number;
34
 };
32
 };
35
 
33
 
36
 const AnimatedFAB = Animatable.createAnimatableComponent(FAB);
34
 const AnimatedFAB = Animatable.createAnimatableComponent(FAB);
44
     Animatable.initializeRegistryWithDefinitions({
42
     Animatable.initializeRegistryWithDefinitions({
45
       fabFocusIn: {
43
       fabFocusIn: {
46
         '0': {
44
         '0': {
45
+          // @ts-ignore
47
           scale: 1,
46
           scale: 1,
48
           translateY: 0,
47
           translateY: 0,
49
         },
48
         },
58
       },
57
       },
59
       fabFocusOut: {
58
       fabFocusOut: {
60
         '0': {
59
         '0': {
60
+          // @ts-ignore
61
           scale: 1.1,
61
           scale: 1.1,
62
           translateY: -6,
62
           translateY: -6,
63
         },
63
         },
74
     return nextProps.focused !== focused;
74
     return nextProps.focused !== focused;
75
   }
75
   }
76
 
76
 
77
-  getIconRender = ({
78
-    size,
79
-    color,
80
-  }: {
81
-    size: number,
82
-    color: string,
83
-  }): React.Node => {
77
+  getIconRender = ({size, color}: {size: number; color: string}) => {
84
     const {focused} = this.props;
78
     const {focused} = this.props;
85
     return (
79
     return (
86
       <Image
80
       <Image
94
     );
88
     );
95
   };
89
   };
96
 
90
 
97
-  render(): React.Node {
91
+  render() {
98
     const {props} = this;
92
     const {props} = this;
99
     return (
93
     return (
100
       <View
94
       <View

src/components/Tabbar/TabIcon.js → src/components/Tabbar/TabIcon.tsx View File

17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18
  */
18
  */
19
 
19
 
20
-// @flow
21
-
22
 import * as React from 'react';
20
 import * as React from 'react';
23
 import {View} from 'react-native';
21
 import {View} from 'react-native';
24
 import {TouchableRipple, withTheme} from 'react-native-paper';
22
 import {TouchableRipple, withTheme} from 'react-native-paper';
25
-import type {MaterialCommunityIconsGlyphs} from 'react-native-vector-icons/MaterialCommunityIcons';
26
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
23
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
27
 import * as Animatable from 'react-native-animatable';
24
 import * as Animatable from 'react-native-animatable';
28
-import type {CustomThemeType} from '../../managers/ThemeManager';
29
 
25
 
30
 type PropsType = {
26
 type PropsType = {
31
-  focused: boolean,
32
-  color: string,
33
-  label: string,
34
-  icon: MaterialCommunityIconsGlyphs,
35
-  onPress: () => void,
36
-  onLongPress: () => void,
37
-  theme: CustomThemeType,
38
-  extraData: null | boolean | number | string,
27
+  focused: boolean;
28
+  color: string;
29
+  label: string;
30
+  icon: string;
31
+  onPress: () => void;
32
+  onLongPress: () => void;
33
+  theme: ReactNativePaper.Theme;
34
+  extraData: null | boolean | number | string;
39
 };
35
 };
40
 
36
 
41
 /**
37
 /**
49
     Animatable.initializeRegistryWithDefinitions({
45
     Animatable.initializeRegistryWithDefinitions({
50
       focusIn: {
46
       focusIn: {
51
         '0': {
47
         '0': {
48
+          // @ts-ignore
52
           scale: 1,
49
           scale: 1,
53
           translateY: 0,
50
           translateY: 0,
54
         },
51
         },
63
       },
60
       },
64
       focusOut: {
61
       focusOut: {
65
         '0': {
62
         '0': {
63
+          // @ts-ignore
66
           scale: 1.2,
64
           scale: 1.2,
67
           translateY: 6,
65
           translateY: 6,
68
         },
66
         },
88
     );
86
     );
89
   }
87
   }
90
 
88
 
91
-  render(): React.Node {
89
+  render() {
92
     const {props} = this;
90
     const {props} = this;
93
     return (
91
     return (
94
       <TouchableRipple
92
       <TouchableRipple
99
         style={{
97
         style={{
100
           flex: 1,
98
           flex: 1,
101
           justifyContent: 'center',
99
           justifyContent: 'center',
102
-          borderRadius: 10
100
+          borderRadius: 10,
103
         }}>
101
         }}>
104
         <View>
102
         <View>
105
           <Animatable.View
103
           <Animatable.View

Loading…
Cancel
Save