Skip to content

Commit

Permalink
Merge pull request Expensify#26654 from rayane-djouah/Migrate-Icon/in…
Browse files Browse the repository at this point in the history
…dex.js-to-function-component

Migrate Icon/index.js and FloatingActionButton to function component
  • Loading branch information
roryabraham authored Dec 16, 2023
2 parents 3ed43ff + 5bc120d commit 912fa3f
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 232 deletions.
31 changes: 3 additions & 28 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -777,35 +777,10 @@ PODS:
- React-Core
- RNReactNativeHapticFeedback (1.14.0):
- React-Core
- RNReanimated (3.5.4):
- DoubleConversion
- FBLazyVector
- glog
- hermes-engine
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React-callinvoker
- RNReanimated (3.6.1):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- React-Core/DevSupport
- React-Core/RCTWebSocket
- React-CoreModules
- React-cxxreact
- React-hermes
- React-jsi
- React-jsiexecutor
- React-jsinspector
- React-RCTActionSheet
- React-RCTAnimation
- React-RCTAppDelegate
- React-RCTBlob
- React-RCTImage
- React-RCTLinking
- React-RCTNetwork
- React-RCTSettings
- React-RCTText
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (3.21.0):
- React-Core
- React-RCTImage
Expand Down Expand Up @@ -1280,7 +1255,7 @@ SPEC CHECKSUMS:
rnmapbox-maps: 6f638ec002aa6e906a6f766d69cd45f968d98e64
RNPermissions: 9b086c8f05b2e2faa587fdc31f4c5ab4509728aa
RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c
RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87
RNReanimated: fdbaa9c964bbab7fac50c90862b6cc5f041679b9
RNScreens: d037903436160a4b039d32606668350d2a808806
RNSVG: d00c8f91c3cbf6d476451313a18f04d220d4f396
SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
"react-native-plaid-link-sdk": "10.8.0",
"react-native-qrcode-svg": "^6.2.0",
"react-native-quick-sqlite": "^8.0.0-beta.2",
"react-native-reanimated": "3.5.4",
"react-native-reanimated": "^3.6.1",
"react-native-render-html": "6.3.1",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.21.0",
Expand Down
132 changes: 0 additions & 132 deletions src/components/FloatingActionButton.js

This file was deleted.

49 changes: 49 additions & 0 deletions src/components/FloatingActionButton/FabPlusIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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';
import useTheme from '@hooks/useTheme';

const AnimatedPath = Animated.createAnimatedComponent(Path);

const propTypes = {
/* Current state (active or not active) of the component */
isActive: PropTypes.bool.isRequired,
};

function FabPlusIcon({isActive}) {
const theme = useTheme();
const animatedValue = useSharedValue(isActive ? 1 : 0);

useEffect(() => {
animatedValue.value = withTiming(isActive ? 1 : 0, {
duration: 340,
easing: Easing.inOut(Easing.ease),
});
}, [isActive, animatedValue]);

const animatedProps = useAnimatedProps(() => {
const fill = interpolateColor(animatedValue.value, [0, 1], [theme.textLight, theme.textDark]);

return {
fill,
};
});

return (
<Svg
width={20}
height={20}
>
<AnimatedPath
d="M12,3c0-1.1-0.9-2-2-2C8.9,1,8,1.9,8,3v5H3c-1.1,0-2,0.9-2,2c0,1.1,0.9,2,2,2h5v5c0,1.1,0.9,2,2,2c1.1,0,2-0.9,2-2v-5h5c1.1,0,2-0.9,2-2c0-1.1-0.9-2-2-2h-5V3z"
animatedProps={animatedProps}
/>
</Svg>
);
}

FabPlusIcon.propTypes = propTypes;
FabPlusIcon.displayName = 'FabPlusIcon';

export default FabPlusIcon;
85 changes: 85 additions & 0 deletions src/components/FloatingActionButton/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import PropTypes from 'prop-types';
import React, {useEffect, useRef} from 'react';
import {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';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import FabPlusIcon from './FabPlusIcon';

const AnimatedPressable = Animated.createAnimatedComponent(PressableWithFeedback);
AnimatedPressable.displayName = 'AnimatedPressable';

const propTypes = {
/* Callback to fire on request to toggle the FloatingActionButton */
onPress: PropTypes.func.isRequired,

/* Current state (active or not active) of the component */
isActive: PropTypes.bool.isRequired,

/* An accessibility label for the button */
accessibilityLabel: PropTypes.string.isRequired,

/* An accessibility role for the button */
role: PropTypes.string.isRequired,
};

const FloatingActionButton = React.forwardRef(({onPress, isActive, accessibilityLabel, role}, ref) => {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
const fabPressable = useRef(null);
const animatedValue = useSharedValue(isActive ? 1 : 0);
const buttonRef = ref;

useEffect(() => {
animatedValue.value = withTiming(isActive ? 1 : 0, {
duration: 340,
easing: Easing.inOut(Easing.ease),
});
}, [isActive, animatedValue]);

const animatedStyle = useAnimatedStyle(() => {
const backgroundColor = interpolateColor(animatedValue.value, [0, 1], [theme.success, theme.buttonDefaultBG]);

return {
transform: [{rotate: `${animatedValue.value * 135}deg`}],
backgroundColor,
borderRadius: styles.floatingActionButton.borderRadius,
};
});

return (
<Tooltip text={translate('common.new')}>
<View style={styles.floatingActionButtonContainer}>
<AnimatedPressable
ref={(el) => {
fabPressable.current = el;
if (buttonRef) {
buttonRef.current = el;
}
}}
accessibilityLabel={accessibilityLabel}
role={role}
pressDimmingValue={1}
onPress={(e) => {
// Drop focus to avoid blue focus ring.
fabPressable.current.blur();
onPress(e);
}}
onLongPress={() => {}}
style={[styles.floatingActionButton, animatedStyle]}
>
<FabPlusIcon isActive={isActive} />
</AnimatedPressable>
</View>
</Tooltip>
);
});

FloatingActionButton.propTypes = propTypes;
FloatingActionButton.displayName = 'FloatingActionButton';

export default FloatingActionButton;
Loading

0 comments on commit 912fa3f

Please sign in to comment.