Skip to content

Commit

Permalink
[implement] : FAB
Browse files Browse the repository at this point in the history
1. Implemented the basic functions of the FAB
	* Can use IconButton that is a default button component of FAB by passing the icon types and callbacks.
	* Can replace the default button component of FAB by passing renderButton function
	* Can set absolute position of FAB
	* Can replace buttons by active Props

	Rendering conditions:
		if(active===false)render DefaultFAB
		if(active===true)render ActiveFAB and ActionButtons

**Animation is not implemented**
**Need more implementation**
  • Loading branch information
Juyeong-Byeon committed Aug 14, 2021
1 parent 4e93cc7 commit f72bbc3
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 32 deletions.
133 changes: 101 additions & 32 deletions main/FloatingActionButtonWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,121 @@
import {DoobooTheme, light, withTheme} from '../theme';
import React, {FC} from 'react';
import {DoobooTheme, withTheme} from '../theme';
import {Icon, IconName} from '../Icon';
import React, {FC, useMemo} from 'react';

import {ViewStyle} from 'react-native';
import {Animated} from 'react-native';
import {IconButton} from '../IconButton';
import styled from '@emotion/native';

const FixedPositionWrapperView = styled.View`
position: fixed;
top: ${(props: ViewStyle) => props.top};
bottom: ${(props: ViewStyle) => props.bottom};
left: ${(props: ViewStyle) => props.left};
right: ${(props: ViewStyle) => props.bottom};
const AbsolutePositionWrapperView = styled.View`
position: absolute;
`;

const ExpendWrapperView = styled.View``;
export const StyledIcon = styled(Icon)`
color: ${({theme}) => theme.textContrast};
`;

const FABItemWrapperView = styled.View`
position: relative;
margin: 10px;
`;

export type FABItem = {
icon: IconName;
onPress: () => void;
};

interface FloatingActionButtonWrapperProps {
interface FloatingActionButtonsWrapperProps {
active: boolean;
DefaultMainActionButton: React.ReactElement;
ActiveMainActionButton: React.ReactElement;
ActionButtons: Array<React.ReactElement>;
DefaultFAB: FABItem;
ActiveFAB: FABItem;
FABList: FABItem[];
renderDefaultFAB?: (item: FABItem) => React.ReactElement;
renderActiveFAB?: (item: FABItem) => React.ReactElement;
renderFABListItem?: (item: FABItem, idx: number) => React.ReactElement;
zIndex?: number;
top?: number;
bottom?: number;
left?: number;
right?: number;
buttonSize: 'large' | 'small';
}

const FloatingActionButtonWrapper: FC<
FloatingActionButtonWrapperProps & {theme: DoobooTheme}
const FloatingActionButtons: FC<
FloatingActionButtonsWrapperProps & {theme: DoobooTheme}
> = ({
theme,
active,
DefaultMainActionButton,
ActiveMainActionButton,
ActionButtons,
top,
bottom,
left,
right,
DefaultFAB,
ActiveFAB,
FABList,
renderDefaultFAB,
renderActiveFAB,
renderFABListItem,
zIndex = 0,
top = 'auto',
bottom = 'auto',
left = 'auto',
right = 'auto',
}) => {
const defaultFAB: React.ReactElement = useMemo(
() =>
renderDefaultFAB ? (
renderDefaultFAB(DefaultFAB)
) : (
<IconButton
icon={<StyledIcon size={24} name={DefaultFAB.icon} />}
onPress={DefaultFAB.onPress}
/>
),
[renderDefaultFAB, DefaultFAB],
);

const activeFAB: React.ReactElement = useMemo(
() =>
renderActiveFAB ? (
renderActiveFAB(ActiveFAB)
) : (
<IconButton
icon={<StyledIcon size={24} name={ActiveFAB.icon} />}
onPress={ActiveFAB.onPress}
/>
),
[renderActiveFAB, ActiveFAB],
);

return (
<FixedPositionWrapperView style={{top, bottom, left, right}}>
{active ? ActiveMainActionButton : DefaultMainActionButton}
<ExpendWrapperView>
{ActionButtons.map((ActionButton) => ActionButton)}
</ExpendWrapperView>
</FixedPositionWrapperView>
<AbsolutePositionWrapperView
style={{
top,
bottom,
left,
right,
zIndex,
}}>
<Animated.View>
{active &&
FABList.map((item, idx) =>
renderFABListItem ? (
<FABItemWrapperView key={item.icon + idx}>
{renderFABListItem(item, idx)}
</FABItemWrapperView>
) : (
<FABItemWrapperView key={item.icon + idx}>
{
<IconButton
icon={
<StyledIcon theme={theme} size={24} name={item.icon} />
}
onPress={item.onPress}
/>
}
</FABItemWrapperView>
),
)}
</Animated.View>
<FABItemWrapperView>{active ? defaultFAB : activeFAB}</FABItemWrapperView>
</AbsolutePositionWrapperView>
);
};

FloatingActionButtonWrapper.defaultProps = {theme: light};

export const IconButton = withTheme(FloatingActionButtonWrapper);
export const FAB = withTheme(FloatingActionButtons);
1 change: 1 addition & 0 deletions main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './Accordion';
export * from './StatusBarBrightness';
export * from './SwitchToggle';
export * from './theme';
export * from './FloatingActionButtonWrapper';

0 comments on commit f72bbc3

Please sign in to comment.