Browse Source

Update animated components to use TypeScript

Arnaud Vergnet 3 years ago
parent
commit
140bcf3675

src/components/Animations/AnimatedAccordion.js → src/components/Animations/AnimatedAccordion.tsx View File

@@ -17,42 +17,37 @@
17 17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-// @flow
21
-
22 20
 import * as React from 'react';
23
-import {View} from 'react-native';
21
+import {View, ViewStyle} from 'react-native';
24 22
 import {List, withTheme} from 'react-native-paper';
25 23
 import Collapsible from 'react-native-collapsible';
26 24
 import * as Animatable from 'react-native-animatable';
27
-import type {CustomThemeType} from '../../managers/ThemeManager';
28
-import type {ListIconPropsType} from '../../constants/PaperStyles';
29 25
 
30 26
 type PropsType = {
31
-  theme: CustomThemeType,
32
-  title: string,
33
-  subtitle?: string,
34
-  left?: () => React.Node,
35
-  opened?: boolean,
36
-  unmountWhenCollapsed?: boolean,
37
-  children?: React.Node,
27
+  theme: ReactNativePaper.Theme;
28
+  title: string;
29
+  subtitle?: string;
30
+  style: ViewStyle;
31
+  left?: (props: {
32
+    color: string;
33
+    style?: {
34
+      marginRight: number;
35
+      marginVertical?: number;
36
+    };
37
+  }) => React.ReactNode;
38
+  opened?: boolean;
39
+  unmountWhenCollapsed?: boolean;
40
+  children?: React.ReactNode;
38 41
 };
39 42
 
40 43
 type StateType = {
41
-  expanded: boolean,
44
+  expanded: boolean;
42 45
 };
43 46
 
44 47
 const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon);
45 48
 
46 49
 class AnimatedAccordion extends React.Component<PropsType, StateType> {
47
-  static defaultProps = {
48
-    subtitle: '',
49
-    left: null,
50
-    opened: null,
51
-    unmountWhenCollapsed: false,
52
-    children: null,
53
-  };
54
-
55
-  chevronRef: {current: null | AnimatedListIcon};
50
+  chevronRef: {current: null | (typeof AnimatedListIcon & List.Icon)};
56 51
 
57 52
   chevronIcon: string;
58 53
 
@@ -62,6 +57,9 @@ class AnimatedAccordion extends React.Component<PropsType, StateType> {
62 57
 
63 58
   constructor(props: PropsType) {
64 59
     super(props);
60
+    this.chevronIcon = '';
61
+    this.animStart = '';
62
+    this.animEnd = '';
65 63
     this.state = {
66 64
       expanded: props.opened != null ? props.opened : false,
67 65
     };
@@ -71,8 +69,9 @@ class AnimatedAccordion extends React.Component<PropsType, StateType> {
71 69
 
72 70
   shouldComponentUpdate(nextProps: PropsType): boolean {
73 71
     const {state, props} = this;
74
-    if (nextProps.opened != null && nextProps.opened !== props.opened)
72
+    if (nextProps.opened != null && nextProps.opened !== props.opened) {
75 73
       state.expanded = nextProps.opened;
74
+    }
76 75
     return true;
77 76
   }
78 77
 
@@ -101,17 +100,17 @@ class AnimatedAccordion extends React.Component<PropsType, StateType> {
101 100
     }
102 101
   };
103 102
 
104
-  render(): React.Node {
103
+  render() {
105 104
     const {props, state} = this;
106 105
     const {colors} = props.theme;
107 106
     return (
108
-      <View>
107
+      <View style={props.style}>
109 108
         <List.Item
110 109
           title={props.title}
111
-          subtitle={props.subtitle}
110
+          description={props.subtitle}
112 111
           titleStyle={state.expanded ? {color: colors.primary} : null}
113 112
           onPress={this.toggleAccordion}
114
-          right={(iconProps: ListIconPropsType): React.Node => (
113
+          right={(iconProps) => (
115 114
             <AnimatedListIcon
116 115
               ref={this.chevronRef}
117 116
               style={iconProps.style}

src/components/Animations/AnimatedBottomBar.js → src/components/Animations/AnimatedBottomBar.tsx View File

@@ -17,29 +17,30 @@
17 17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-// @flow
21
-
22 20
 import * as React from 'react';
23
-import {StyleSheet, View} from 'react-native';
21
+import {
22
+  NativeScrollEvent,
23
+  NativeSyntheticEvent,
24
+  StyleSheet,
25
+  View,
26
+} from 'react-native';
24 27
 import {FAB, IconButton, Surface, withTheme} from 'react-native-paper';
25 28
 import * as Animatable from 'react-native-animatable';
26 29
 import {StackNavigationProp} from '@react-navigation/stack';
27 30
 import AutoHideHandler from '../../utils/AutoHideHandler';
28 31
 import CustomTabBar from '../Tabbar/CustomTabBar';
29
-import type {CustomThemeType} from '../../managers/ThemeManager';
30
-import type {OnScrollType} from '../../utils/AutoHideHandler';
31 32
 
32 33
 const AnimatedFAB = Animatable.createAnimatableComponent(FAB);
33 34
 
34 35
 type PropsType = {
35
-  navigation: StackNavigationProp,
36
-  theme: CustomThemeType,
37
-  onPress: (action: string, data?: string) => void,
38
-  seekAttention: boolean,
36
+  navigation: StackNavigationProp<any>;
37
+  theme: ReactNativePaper.Theme;
38
+  onPress: (action: string, data?: string) => void;
39
+  seekAttention: boolean;
39 40
 };
40 41
 
41 42
 type StateType = {
42
-  currentMode: string,
43
+  currentMode: string;
43 44
 };
44 45
 
45 46
 const DISPLAY_MODES = {
@@ -78,14 +79,14 @@ const styles = StyleSheet.create({
78 79
 });
79 80
 
80 81
 class AnimatedBottomBar extends React.Component<PropsType, StateType> {
81
-  ref: {current: null | Animatable.View};
82
+  ref: {current: null | (Animatable.View & View)};
82 83
 
83 84
   hideHandler: AutoHideHandler;
84 85
 
85 86
   displayModeIcons: {[key: string]: string};
86 87
 
87
-  constructor() {
88
-    super();
88
+  constructor(props: PropsType) {
89
+    super(props);
89 90
     this.state = {
90 91
       currentMode: DISPLAY_MODES.WEEK,
91 92
     };
@@ -108,13 +109,17 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
108 109
   }
109 110
 
110 111
   onHideChange = (shouldHide: boolean) => {
111
-    if (this.ref.current != null) {
112
-      if (shouldHide) this.ref.current.fadeOutDown(500);
113
-      else this.ref.current.fadeInUp(500);
112
+    const ref = this.ref;
113
+    if (ref && ref.current && ref.current.fadeOutDown && ref.current.fadeInUp) {
114
+      if (shouldHide) {
115
+        ref.current.fadeOutDown(500);
116
+      } else {
117
+        ref.current.fadeInUp(500);
118
+      }
114 119
     }
115 120
   };
116 121
 
117
-  onScroll = (event: OnScrollType) => {
122
+  onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
118 123
     this.hideHandler.onScroll(event);
119 124
   };
120 125
 
@@ -139,7 +144,7 @@ class AnimatedBottomBar extends React.Component<PropsType, StateType> {
139 144
     props.onPress('changeView', newMode);
140 145
   };
141 146
 
142
-  render(): React.Node {
147
+  render() {
143 148
     const {props, state} = this;
144 149
     const buttonColor = props.theme.colors.primary;
145 150
     return (

src/components/Animations/AnimatedFAB.js → src/components/Animations/AnimatedFAB.tsx View File

@@ -17,22 +17,23 @@
17 17
  * along with Campus INSAT.  If not, see <https://www.gnu.org/licenses/>.
18 18
  */
19 19
 
20
-// @flow
21
-
22 20
 import * as React from 'react';
23
-import {StyleSheet} from 'react-native';
21
+import {
22
+  NativeScrollEvent,
23
+  NativeSyntheticEvent,
24
+  StyleSheet,
25
+  View,
26
+} from 'react-native';
24 27
 import {FAB} from 'react-native-paper';
25 28
 import * as Animatable from 'react-native-animatable';
26 29
 import AutoHideHandler from '../../utils/AutoHideHandler';
27 30
 import CustomTabBar from '../Tabbar/CustomTabBar';
28 31
 
29 32
 type PropsType = {
30
-  icon: string,
31
-  onPress: () => void,
33
+  icon: string;
34
+  onPress: () => void;
32 35
 };
33 36
 
34
-const AnimatedFab = Animatable.createAnimatableComponent(FAB);
35
-
36 37
 const styles = StyleSheet.create({
37 38
   fab: {
38 39
     position: 'absolute',
@@ -42,41 +43,50 @@ const styles = StyleSheet.create({
42 43
 });
43 44
 
44 45
 export default class AnimatedFAB extends React.Component<PropsType> {
45
-  ref: {current: null | Animatable.View};
46
+  ref: {current: null | (Animatable.View & View)};
46 47
 
47 48
   hideHandler: AutoHideHandler;
48 49
 
49
-  constructor() {
50
-    super();
50
+  constructor(props: PropsType) {
51
+    super(props);
51 52
     this.ref = React.createRef();
52 53
     this.hideHandler = new AutoHideHandler(false);
53 54
     this.hideHandler.addListener(this.onHideChange);
54 55
   }
55 56
 
56
-  onScroll = (event: SyntheticEvent<EventTarget>) => {
57
+  onScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
57 58
     this.hideHandler.onScroll(event);
58 59
   };
59 60
 
60 61
   onHideChange = (shouldHide: boolean) => {
61
-    if (this.ref.current != null) {
62
-      if (shouldHide) this.ref.current.bounceOutDown(1000);
63
-      else this.ref.current.bounceInUp(1000);
62
+    const ref = this.ref;
63
+    if (
64
+      ref &&
65
+      ref.current &&
66
+      ref.current.bounceOutDown &&
67
+      ref.current.bounceInUp
68
+    ) {
69
+      if (shouldHide) {
70
+        ref.current.bounceOutDown(1000);
71
+      } else {
72
+        ref.current.bounceInUp(1000);
73
+      }
64 74
     }
65 75
   };
66 76
 
67
-  render(): React.Node {
77
+  render() {
68 78
     const {props} = this;
69 79
     return (
70
-      <AnimatedFab
71
-        ref={this.ref}
72
-        useNativeDriver
73
-        icon={props.icon}
74
-        onPress={props.onPress}
75
-        style={{
76
-          ...styles.fab,
77
-          bottom: CustomTabBar.TAB_BAR_HEIGHT,
78
-        }}
79
-      />
80
+      <Animatable.View ref={this.ref} useNativeDriver={true}>
81
+        <FAB
82
+          icon={props.icon}
83
+          onPress={props.onPress}
84
+          style={{
85
+            ...styles.fab,
86
+            bottom: CustomTabBar.TAB_BAR_HEIGHT,
87
+          }}
88
+        />
89
+      </Animatable.View>
80 90
     );
81 91
   }
82 92
 }

Loading…
Cancel
Save