Skip to content

Commit

Permalink
[implement]
Browse files Browse the repository at this point in the history
1. MainFAB animation
2. Implemented basic test that tests the callback
  • Loading branch information
Juyeong-Byeon committed Aug 27, 2021
1 parent fcc5831 commit 7c1b410
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 26 deletions.
65 changes: 39 additions & 26 deletions main/FloatingActionButtonWrapper/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface FABItem {
id: string;
}

interface FloatingActionButtonsWrapperProps<ITEM extends FABItem> {
export interface FABProps<ITEM extends FABItem> {
FABList: ITEM[];
onPressFABItem: (item: ITEM | FABItem) => void;
renderMainFAB?: (isActive: boolean) => React.ReactElement;
Expand All @@ -37,7 +37,7 @@ function FloatingActionButtons<ITEM extends FABItem = FABItem>({
renderFABListItem,
size = 'large',
style,
}: FloatingActionButtonsWrapperProps<ITEM> & {
}: FABProps<ITEM> & {
theme: DoobooTheme;
}): ReactElement {
const [isActive, setFabActive] = useState(false);
Expand All @@ -52,6 +52,20 @@ function FloatingActionButtons<ITEM extends FABItem = FABItem>({
}).start();
}, [fadeAnim, isActive]);

useEffect(() => {
Animated.timing(fadeAnim.current, {
toValue: 1,
duration: 200,
easing: Easing.linear, // Easing is an additional import from react-native
useNativeDriver: true, // To make use of native driver for performance
}).start();
}, [fadeAnim]);

const spin = fadeAnim.current.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '45deg'],
});

return (
<View
style={
Expand All @@ -66,39 +80,38 @@ function FloatingActionButtons<ITEM extends FABItem = FABItem>({
style={{
opacity: fadeAnim.current,
}}>
{FABList.map((item, idx) =>
renderFABListItem ? (
{FABList.map((item, idx) => {
return (
<FABItemWrapperView key={item.icon + idx}>
{renderFABListItem(item, idx)}
</FABItemWrapperView>
) : (
<FABItemWrapperView key={item.icon + idx}>
{
{renderFABListItem ? (
renderFABListItem(item, idx)
) : (
<IconButton
testID={item.id}
size={size}
icon={<StyledIcon theme={theme} size={24} name={item.icon} />}
onPress={() => onPressFABItem(item)}
/>
}
)}
</FABItemWrapperView>
),
)}
);
})}
</Animated.View>
<FABItemWrapperView>
{renderMainFAB ? (
renderMainFAB(isActive)
) : (
<IconButton
size={size}
icon={
<StyledIcon
size={24}
name={isActive ? 'cross-light' : 'add-light'}
/>
}
onPress={() => setFabActive((prevState) => !prevState)}
/>
)}
<Animated.View
testID={'main_fab_animation_wrapper'}
style={{transform: [{rotate: spin}]}}>
{renderMainFAB ? (
renderMainFAB(isActive)
) : (
<IconButton
testID={'main_fab'}
size={size}
icon={<StyledIcon size={24} name="add-light" />}
onPress={() => setFabActive((prevState) => !prevState)}
/>
)}
</Animated.View>
</FABItemWrapperView>
</View>
);
Expand Down
46 changes: 46 additions & 0 deletions main/__tests__/FAB.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {FAB, FABItem, FABProps} from '../../main';
import {fireEvent, render, waitFor} from '@testing-library/react-native';

import {ReactElement} from 'react';
import {createComponent} from '../../test/testUtils';

const Component = (props: FABProps<FABItem>): ReactElement =>
createComponent(<FAB {...props} />);

describe('[FAB]', () => {
it('should render without crashing', () => {
const testingLib = render(
Component({
FABList: [{icon: 'bell-solid', id: 'item1'}],
size: 'large',
onPressFABItem: () => {},
}),
);

const json = testingLib.toJSON();

expect(json).toBeTruthy();
});

it('test mainFAB onPress callback', async () => {
let count = 0;
let item1: FABItem = {icon: 'bell-solid', id: 'item1'};
let resItem: FABItem;

const testingLib = render(
Component({
FABList: [item1],
size: 'large',
onPressFABItem: (item1) => {
count += 1;
resItem = item1;
},
}),
);

expect(count).toEqual(0);
fireEvent.press(testingLib.getByTestId('item1'));
expect(count).toEqual(1);
expect(resItem.id).toEqual(item1.id);
});
});

0 comments on commit 7c1b410

Please sign in to comment.