From 140bcf3675657a1747f8880bea1f606b6eed4046 Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Tue, 22 Sep 2020 17:43:40 +0200 Subject: [PATCH] Update animated components to use TypeScript --- ...atedAccordion.js => AnimatedAccordion.tsx} | 53 ++++++++-------- ...atedBottomBar.js => AnimatedBottomBar.tsx} | 41 +++++++------ .../{AnimatedFAB.js => AnimatedFAB.tsx} | 60 +++++++++++-------- 3 files changed, 84 insertions(+), 70 deletions(-) rename src/components/Animations/{AnimatedAccordion.js => AnimatedAccordion.tsx} (81%) rename src/components/Animations/{AnimatedBottomBar.js => AnimatedBottomBar.tsx} (88%) rename src/components/Animations/{AnimatedFAB.js => AnimatedFAB.tsx} (63%) diff --git a/src/components/Animations/AnimatedAccordion.js b/src/components/Animations/AnimatedAccordion.tsx similarity index 81% rename from src/components/Animations/AnimatedAccordion.js rename to src/components/Animations/AnimatedAccordion.tsx index e904aea..e0cb5a9 100644 --- a/src/components/Animations/AnimatedAccordion.js +++ b/src/components/Animations/AnimatedAccordion.tsx @@ -17,42 +17,37 @@ * along with Campus INSAT. If not, see . */ -// @flow - import * as React from 'react'; -import {View} from 'react-native'; +import {View, ViewStyle} from 'react-native'; import {List, withTheme} from 'react-native-paper'; import Collapsible from 'react-native-collapsible'; import * as Animatable from 'react-native-animatable'; -import type {CustomThemeType} from '../../managers/ThemeManager'; -import type {ListIconPropsType} from '../../constants/PaperStyles'; type PropsType = { - theme: CustomThemeType, - title: string, - subtitle?: string, - left?: () => React.Node, - opened?: boolean, - unmountWhenCollapsed?: boolean, - children?: React.Node, + theme: ReactNativePaper.Theme; + title: string; + subtitle?: string; + style: ViewStyle; + left?: (props: { + color: string; + style?: { + marginRight: number; + marginVertical?: number; + }; + }) => React.ReactNode; + opened?: boolean; + unmountWhenCollapsed?: boolean; + children?: React.ReactNode; }; type StateType = { - expanded: boolean, + expanded: boolean; }; const AnimatedListIcon = Animatable.createAnimatableComponent(List.Icon); class AnimatedAccordion extends React.Component { - static defaultProps = { - subtitle: '', - left: null, - opened: null, - unmountWhenCollapsed: false, - children: null, - }; - - chevronRef: {current: null | AnimatedListIcon}; + chevronRef: {current: null | (typeof AnimatedListIcon & List.Icon)}; chevronIcon: string; @@ -62,6 +57,9 @@ class AnimatedAccordion extends React.Component { constructor(props: PropsType) { super(props); + this.chevronIcon = ''; + this.animStart = ''; + this.animEnd = ''; this.state = { expanded: props.opened != null ? props.opened : false, }; @@ -71,8 +69,9 @@ class AnimatedAccordion extends React.Component { shouldComponentUpdate(nextProps: PropsType): boolean { const {state, props} = this; - if (nextProps.opened != null && nextProps.opened !== props.opened) + if (nextProps.opened != null && nextProps.opened !== props.opened) { state.expanded = nextProps.opened; + } return true; } @@ -101,17 +100,17 @@ class AnimatedAccordion extends React.Component { } }; - render(): React.Node { + render() { const {props, state} = this; const {colors} = props.theme; return ( - + ( + right={(iconProps) => ( . */ -// @flow - import * as React from 'react'; -import {StyleSheet, View} from 'react-native'; +import { + NativeScrollEvent, + NativeSyntheticEvent, + StyleSheet, + View, +} from 'react-native'; import {FAB, IconButton, Surface, withTheme} from 'react-native-paper'; import * as Animatable from 'react-native-animatable'; import {StackNavigationProp} from '@react-navigation/stack'; import AutoHideHandler from '../../utils/AutoHideHandler'; import CustomTabBar from '../Tabbar/CustomTabBar'; -import type {CustomThemeType} from '../../managers/ThemeManager'; -import type {OnScrollType} from '../../utils/AutoHideHandler'; const AnimatedFAB = Animatable.createAnimatableComponent(FAB); type PropsType = { - navigation: StackNavigationProp, - theme: CustomThemeType, - onPress: (action: string, data?: string) => void, - seekAttention: boolean, + navigation: StackNavigationProp; + theme: ReactNativePaper.Theme; + onPress: (action: string, data?: string) => void; + seekAttention: boolean; }; type StateType = { - currentMode: string, + currentMode: string; }; const DISPLAY_MODES = { @@ -78,14 +79,14 @@ const styles = StyleSheet.create({ }); class AnimatedBottomBar extends React.Component { - ref: {current: null | Animatable.View}; + ref: {current: null | (Animatable.View & View)}; hideHandler: AutoHideHandler; displayModeIcons: {[key: string]: string}; - constructor() { - super(); + constructor(props: PropsType) { + super(props); this.state = { currentMode: DISPLAY_MODES.WEEK, }; @@ -108,13 +109,17 @@ class AnimatedBottomBar extends React.Component { } onHideChange = (shouldHide: boolean) => { - if (this.ref.current != null) { - if (shouldHide) this.ref.current.fadeOutDown(500); - else this.ref.current.fadeInUp(500); + const ref = this.ref; + if (ref && ref.current && ref.current.fadeOutDown && ref.current.fadeInUp) { + if (shouldHide) { + ref.current.fadeOutDown(500); + } else { + ref.current.fadeInUp(500); + } } }; - onScroll = (event: OnScrollType) => { + onScroll = (event: NativeSyntheticEvent) => { this.hideHandler.onScroll(event); }; @@ -139,7 +144,7 @@ class AnimatedBottomBar extends React.Component { props.onPress('changeView', newMode); }; - render(): React.Node { + render() { const {props, state} = this; const buttonColor = props.theme.colors.primary; return ( diff --git a/src/components/Animations/AnimatedFAB.js b/src/components/Animations/AnimatedFAB.tsx similarity index 63% rename from src/components/Animations/AnimatedFAB.js rename to src/components/Animations/AnimatedFAB.tsx index 1578b03..a5254eb 100644 --- a/src/components/Animations/AnimatedFAB.js +++ b/src/components/Animations/AnimatedFAB.tsx @@ -17,22 +17,23 @@ * along with Campus INSAT. If not, see . */ -// @flow - import * as React from 'react'; -import {StyleSheet} from 'react-native'; +import { + NativeScrollEvent, + NativeSyntheticEvent, + StyleSheet, + View, +} from 'react-native'; import {FAB} from 'react-native-paper'; import * as Animatable from 'react-native-animatable'; import AutoHideHandler from '../../utils/AutoHideHandler'; import CustomTabBar from '../Tabbar/CustomTabBar'; type PropsType = { - icon: string, - onPress: () => void, + icon: string; + onPress: () => void; }; -const AnimatedFab = Animatable.createAnimatableComponent(FAB); - const styles = StyleSheet.create({ fab: { position: 'absolute', @@ -42,41 +43,50 @@ const styles = StyleSheet.create({ }); export default class AnimatedFAB extends React.Component { - ref: {current: null | Animatable.View}; + ref: {current: null | (Animatable.View & View)}; hideHandler: AutoHideHandler; - constructor() { - super(); + constructor(props: PropsType) { + super(props); this.ref = React.createRef(); this.hideHandler = new AutoHideHandler(false); this.hideHandler.addListener(this.onHideChange); } - onScroll = (event: SyntheticEvent) => { + onScroll = (event: NativeSyntheticEvent) => { this.hideHandler.onScroll(event); }; onHideChange = (shouldHide: boolean) => { - if (this.ref.current != null) { - if (shouldHide) this.ref.current.bounceOutDown(1000); - else this.ref.current.bounceInUp(1000); + const ref = this.ref; + if ( + ref && + ref.current && + ref.current.bounceOutDown && + ref.current.bounceInUp + ) { + if (shouldHide) { + ref.current.bounceOutDown(1000); + } else { + ref.current.bounceInUp(1000); + } } }; - render(): React.Node { + render() { const {props} = this; return ( - + + + ); } }