From ac57d7a4bbc04b3a23c16b302210830ce1a73c1f Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Mon, 18 Dec 2023 17:30:12 +0100 Subject: [PATCH 1/2] migrate FloatingActionButton to TypeScript --- .../{FabPlusIcon.js => FabPlusIcon.tsx} | 8 ++--- .../{index.js => index.tsx} | 34 +++++++++++-------- 2 files changed, 22 insertions(+), 20 deletions(-) rename src/components/FloatingActionButton/{FabPlusIcon.js => FabPlusIcon.tsx} (88%) rename src/components/FloatingActionButton/{index.js => index.tsx} (73%) diff --git a/src/components/FloatingActionButton/FabPlusIcon.js b/src/components/FloatingActionButton/FabPlusIcon.tsx similarity index 88% rename from src/components/FloatingActionButton/FabPlusIcon.js rename to src/components/FloatingActionButton/FabPlusIcon.tsx index 09afa00f119d..c7fd7c2f49cd 100644 --- a/src/components/FloatingActionButton/FabPlusIcon.js +++ b/src/components/FloatingActionButton/FabPlusIcon.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React, {useEffect} from 'react'; import Animated, {Easing, interpolateColor, useAnimatedProps, useSharedValue, withTiming} from 'react-native-reanimated'; import Svg, {Path} from 'react-native-svg'; @@ -6,12 +5,12 @@ import useTheme from '@hooks/useTheme'; const AnimatedPath = Animated.createAnimatedComponent(Path); -const propTypes = { +type FabPlusIconProps = { /* Current state (active or not active) of the component */ - isActive: PropTypes.bool.isRequired, + isActive: boolean; }; -function FabPlusIcon({isActive}) { +function FabPlusIcon({isActive}: FabPlusIconProps) { const theme = useTheme(); const animatedValue = useSharedValue(isActive ? 1 : 0); @@ -43,7 +42,6 @@ function FabPlusIcon({isActive}) { ); } -FabPlusIcon.propTypes = propTypes; FabPlusIcon.displayName = 'FabPlusIcon'; export default FabPlusIcon; diff --git a/src/components/FloatingActionButton/index.js b/src/components/FloatingActionButton/index.tsx similarity index 73% rename from src/components/FloatingActionButton/index.js rename to src/components/FloatingActionButton/index.tsx index d341396c44b7..1ed968f59e15 100644 --- a/src/components/FloatingActionButton/index.js +++ b/src/components/FloatingActionButton/index.tsx @@ -1,6 +1,5 @@ -import PropTypes from 'prop-types'; -import React, {useEffect, useRef} from 'react'; -import {View} from 'react-native'; +import React, {ForwardedRef, useEffect, useRef} from 'react'; +import {GestureResponderEvent, Role, View} from 'react-native'; import Animated, {Easing, interpolateColor, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import PressableWithFeedback from '@components/Pressable/PressableWithFeedback'; import Tooltip from '@components/Tooltip/PopoverAnchorTooltip'; @@ -12,25 +11,25 @@ import FabPlusIcon from './FabPlusIcon'; const AnimatedPressable = Animated.createAnimatedComponent(PressableWithFeedback); AnimatedPressable.displayName = 'AnimatedPressable'; -const propTypes = { +type FloatingActionButtonProps = { /* Callback to fire on request to toggle the FloatingActionButton */ - onPress: PropTypes.func.isRequired, + onPress: (event: GestureResponderEvent | KeyboardEvent | undefined) => void; /* Current state (active or not active) of the component */ - isActive: PropTypes.bool.isRequired, + isActive: boolean; /* An accessibility label for the button */ - accessibilityLabel: PropTypes.string.isRequired, + accessibilityLabel: string; /* An accessibility role for the button */ - role: PropTypes.string.isRequired, + role: Role; }; -const FloatingActionButton = React.forwardRef(({onPress, isActive, accessibilityLabel, role}, ref) => { +function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: FloatingActionButtonProps, ref: ForwardedRef) { const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); - const fabPressable = useRef(null); + const fabPressable = useRef(null); const animatedValue = useSharedValue(isActive ? 1 : 0); const buttonRef = ref; @@ -57,7 +56,13 @@ const FloatingActionButton = React.forwardRef(({onPress, isActive, accessibility { fabPressable.current = el; - if (buttonRef) { + if (!buttonRef) { + return; + } + if (typeof buttonRef === 'function') { + buttonRef(el); + } + if (typeof buttonRef === 'object') { buttonRef.current = el; } }} @@ -66,7 +71,7 @@ const FloatingActionButton = React.forwardRef(({onPress, isActive, accessibility pressDimmingValue={1} onPress={(e) => { // Drop focus to avoid blue focus ring. - fabPressable.current.blur(); + fabPressable.current?.blur(); onPress(e); }} onLongPress={() => {}} @@ -77,9 +82,8 @@ const FloatingActionButton = React.forwardRef(({onPress, isActive, accessibility ); -}); +} -FloatingActionButton.propTypes = propTypes; FloatingActionButton.displayName = 'FloatingActionButton'; -export default FloatingActionButton; +export default React.forwardRef(FloatingActionButton); From dfcff5e7ea389eb73f4557562a8ee59346298aab Mon Sep 17 00:00:00 2001 From: Julian Kobrynski Date: Thu, 21 Dec 2023 13:58:50 +0100 Subject: [PATCH 2/2] simplify ref assignment --- src/components/FloatingActionButton/index.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/components/FloatingActionButton/index.tsx b/src/components/FloatingActionButton/index.tsx index 1ed968f59e15..8a1ba2761d86 100644 --- a/src/components/FloatingActionButton/index.tsx +++ b/src/components/FloatingActionButton/index.tsx @@ -56,13 +56,8 @@ function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: Flo { fabPressable.current = el; - if (!buttonRef) { - return; - } - if (typeof buttonRef === 'function') { - buttonRef(el); - } - if (typeof buttonRef === 'object') { + + if (buttonRef && 'current' in buttonRef) { buttonRef.current = el; } }}