Skip to content

Commit

Permalink
[IMPROVE] migrate the ActionSheet component
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexAlexandre committed Jul 15, 2021
1 parent 99b6c3d commit 802c7b2
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,11 @@ import React, {
useCallback,
isValidElement
} from 'react';
import PropTypes from 'prop-types';
import { Keyboard, Text } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { TapGestureHandler, State } from 'react-native-gesture-handler';
import ScrollBottomSheet from 'react-native-scroll-bottom-sheet';
import Animated, {
Extrapolate,
interpolate,
Value,
Easing
} from 'react-native-reanimated';
import Animated, { Extrapolate, interpolate, Value, Easing} from 'react-native-reanimated';
import * as Haptics from 'expo-haptics';
import { useBackHandler } from '@react-native-community/hooks';

Expand All @@ -29,9 +23,16 @@ import styles, { ITEM_HEIGHT } from './styles';
import { isTablet, isIOS } from '../../utils/deviceInfo';
import * as List from '../List';
import I18n from '../../i18n';
import { useOrientation, useDimensions } from '../../dimensions';
import { useOrientation, useDimensions, IDimensionsContextProps } from '../../dimensions';

const getItemLayout = (data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index });
type TActionSheetData = {
options: any;
headerHeight?: number;
hasCancel?: boolean;
customHeader: any;
}

const getItemLayout = (data: any, index: number) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index });

const HANDLE_HEIGHT = isIOS ? 40 : 56;
const MAX_SNAP_HEIGHT = 16;
Expand All @@ -45,17 +46,17 @@ const ANIMATION_CONFIG = {
easing: Easing.bezier(0.645, 0.045, 0.355, 1.0)
};

const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
const bottomSheetRef = useRef();
const [data, setData] = useState({});
const ActionSheet = React.memo(forwardRef(({ children, theme }: {children: JSX.Element; theme: string}, ref) => {
const bottomSheetRef: any = useRef();
const [data, setData] = useState<TActionSheetData>({} as TActionSheetData);
const [isVisible, setVisible] = useState(false);
const { height } = useDimensions();
const { height }: Partial<IDimensionsContextProps> = useDimensions();
const { isLandscape } = useOrientation();
const insets = useSafeAreaInsets();

const maxSnap = Math.max(
(
height
height!
// Items height
- (ITEM_HEIGHT * (data?.options?.length || 0))
// Handle height
Expand All @@ -77,7 +78,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
* we'll provide more one snap
* that point 50% of the whole screen
*/
const snaps = (height - maxSnap > height * 0.6) && !isLandscape ? [maxSnap, height * 0.5, height] : [maxSnap, height];
const snaps: any = (height! - maxSnap > height! * 0.6) && !isLandscape ? [maxSnap, height! * 0.5, height] : [maxSnap, height];
const openedSnapIndex = snaps.length > 2 ? 1 : 0;
const closedSnapIndex = snaps.length - 1;

Expand All @@ -87,12 +88,12 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
bottomSheetRef.current?.snapTo(closedSnapIndex);
};

const show = (options) => {
const show = (options: any) => {
setData(options);
toggleVisible();
};

const onBackdropPressed = ({ nativeEvent }) => {
const onBackdropPressed = ({ nativeEvent }: any) => {
if (nativeEvent.oldState === State.ACTIVE) {
hide();
}
Expand Down Expand Up @@ -128,7 +129,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
<Handle theme={theme} />
{isValidElement(data?.customHeader) ? data.customHeader : null}
</>
));
), [theme, data]);

const renderFooter = useCallback(() => (data?.hasCancel ? (
<Button
Expand All @@ -140,9 +141,9 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
{I18n.t('Cancel')}
</Text>
</Button>
) : null));
) : null), [theme, data, hide()]);

const renderItem = useCallback(({ item }) => <Item item={item} hide={hide} theme={theme} />);
const renderItem = useCallback(({ item }) => <Item item={item} hide={hide} theme={theme} />, []);

const animatedPosition = React.useRef(new Value(0));
const opacity = interpolate(animatedPosition.current, {
Expand All @@ -168,7 +169,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
]}
/>
</TapGestureHandler>
<ScrollBottomSheet
<ScrollBottomSheet<any>
testID='action-sheet'
ref={bottomSheetRef}
componentType='FlatList'
Expand Down Expand Up @@ -200,9 +201,5 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
</>
);
}));
ActionSheet.propTypes = {
children: PropTypes.node,
theme: PropTypes.string
};

export default ActionSheet;
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import { View } from 'react-native';

import styles from './styles';
import { themes } from '../../constants/colors';

export const Handle = React.memo(({ theme }) => (
export const Handle = React.memo(({ theme }: {theme: string}) => (
<View style={[styles.handle, { backgroundColor: themes[theme].focusedBackground }]} testID='action-sheet-handle'>
<View style={[styles.handleIndicator, { backgroundColor: themes[theme].auxiliaryText }]} />
</View>
));
Handle.propTypes = {
theme: PropTypes.string
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, View } from 'react-native';

import { themes } from '../../constants/colors';
import { CustomIcon } from '../../lib/Icons';
import styles from './styles';
import { Button } from './Button';
import styles from './styles';

interface IActionSheetItem {
item: {
title: string;
icon: string;
danger: boolean;
testID: string;
onPress(): void;
right: Function;
};
theme: string
hide(): void;
}

export const Item = React.memo(({ item, hide, theme }) => {
export const Item = React.memo(({ item, hide, theme }: IActionSheetItem) => {
const onPress = () => {
hide();
item?.onPress();
Expand Down Expand Up @@ -37,15 +49,3 @@ export const Item = React.memo(({ item, hide, theme }) => {
</Button>
);
});
Item.propTypes = {
item: PropTypes.shape({
title: PropTypes.string,
icon: PropTypes.string,
danger: PropTypes.bool,
onPress: PropTypes.func,
right: PropTypes.func,
testID: PropTypes.string
}),
hide: PropTypes.func,
theme: PropTypes.string
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ export const useActionSheet = () => useContext(context);

const { Provider, Consumer } = context;

export const withActionSheet = Component => forwardRef((props, ref) => (
export const withActionSheet = (Component: any) => forwardRef((props, ref) => (
<Consumer>
{contexts => <Component {...props} {...contexts} ref={ref} />}
</Consumer>
));

export const ActionSheetProvider = React.memo(({ children }) => {
const ref = useRef();
const ref: any = useRef();
const { theme } = useTheme();

const getContext = () => ({
showActionSheet: (options) => {
showActionSheet: (options: any) => {
ref.current?.showActionSheet(options);
},
hideActionSheet: () => {
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions app/dimensions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';
import { Dimensions } from 'react-native';
import hoistNonReactStatics from 'hoist-non-react-statics';

interface IDimensionsContextProps {
export interface IDimensionsContextProps {
width: number;
height: number;
height?: number;
scale: number;
fontScale: number;
setDimensions: ({ width, height, scale, fontScale }: { width: number; height: number; scale: number; fontScale: number; }) => void;
Expand Down

0 comments on commit 802c7b2

Please sign in to comment.