[IMPROVE] migrate the ActionSheet component

This commit is contained in:
AlexAlexandre 2021-07-15 16:47:53 -03:00
parent 99b6c3d073
commit 802c7b2b28
8 changed files with 43 additions and 50 deletions

View File

@ -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';
@ -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;
@ -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
@ -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;
@ -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();
}
@ -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
@ -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, {
@ -168,7 +169,7 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
]}
/>
</TapGestureHandler>
<ScrollBottomSheet
<ScrollBottomSheet<any>
testID='action-sheet'
ref={bottomSheetRef}
componentType='FlatList'
@ -200,9 +201,5 @@ const ActionSheet = React.memo(forwardRef(({ children, theme }, ref) => {
</>
);
}));
ActionSheet.propTypes = {
children: PropTypes.node,
theme: PropTypes.string
};
export default ActionSheet;

View File

@ -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
};

View File

@ -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';
export const Item = React.memo(({ item, hide, theme }) => {
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 }: IActionSheetItem) => {
const onPress = () => {
hide();
item?.onPress();
@ -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
};

View File

@ -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: () => {

View File

@ -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;