Skip to content

Commit

Permalink
chore: add seperator field and confs for menu item
Browse files Browse the repository at this point in the history
  • Loading branch information
enesozturk committed Mar 3, 2021
1 parent 1f5c32c commit ce2e099
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 43 deletions.
11 changes: 5 additions & 6 deletions example/src/screens/Playground/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@ import Icon from 'react-native-vector-icons/Feather';
interface PlaygroundProps {}

const Playground = ({}: PlaygroundProps) => {
const { theme, toggleTheme } = useAppContext();
const { theme } = useAppContext();

// [TODO]: MenuItem does not render icon
const items = useMemo(
() => [
{
isTitle: true,
text: 'Actions',
onPress: () => {
console.log('[ACTION]: Action 1');
},
onPress: () => {},
},
{
text: 'Theme Change',
Expand All @@ -33,7 +31,7 @@ const Playground = ({}: PlaygroundProps) => {
/>
),
onPress: () => {
toggleTheme();
console.log('[ACTION]: Action 1');
},
},
{
Expand All @@ -54,6 +52,7 @@ const Playground = ({}: PlaygroundProps) => {
onPress: () => {
console.log('[ACTION]: Action 3');
},
withSeperator: true,
},
{
text: 'Action 4',
Expand All @@ -63,7 +62,7 @@ const Playground = ({}: PlaygroundProps) => {
isDestructive: true,
},
],
[theme, toggleTheme]
[theme]
);

const themeStyles = useMemo(() => {
Expand Down
5 changes: 4 additions & 1 deletion src/components/holdItem/HoldItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ const HoldItemComponent = ({
const deviceOrientation = useDeviceOrientation();
const key = useMemo(() => `hold-item-${nanoid()}`, []);

const menuHeight = useMemo(() => calculateMenuHeight(items.length), [items]);
const menuHeight = useMemo(() => {
const itemsWithSeperator = items.filter(item => item.withSeperator);
return calculateMenuHeight(items.length, itemsWithSeperator.length);
}, [items]);

const activateAnimation = (ctx: any) => {
'worklet';
Expand Down
47 changes: 28 additions & 19 deletions src/components/menu/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { useMemo } from 'react';
import React, { useMemo, useCallback } from 'react';
import { TouchableOpacity, Text } from 'react-native';
import { TouchableOpacity as GHTouchableOpacity } from 'react-native-gesture-handler';
import Animated, { useAnimatedStyle } from 'react-native-reanimated';

import Seperator from './Seperator';
import styles from './styles';

import { MenuItemProps } from './types';
Expand Down Expand Up @@ -34,7 +35,10 @@ const MenuItemComponent = ({ item, isLast, theme }: MenuItemComponentProps) => {
const borderBottomColor =
theme === 'dark' ? BORDER_DARK_COLOR : BORDER_LIGHT_COLOR;

return { borderBottomColor, borderBottomWidth: isLast ? 0 : 1 };
return {
borderBottomColor,
borderBottomWidth: isLast ? 0 : 1,
};
}, [theme, isLast]);

const textColor = useMemo(() => {
Expand All @@ -49,27 +53,32 @@ const MenuItemComponent = ({ item, isLast, theme }: MenuItemComponentProps) => {
};
}, [item, theme]);

const handleOnPress = React.useCallback(() => {
if (item.onPress) item.onPress();
state.value = CONTEXT_MENU_STATE.END;
const handleOnPress = useCallback(() => {
if (!item.isTitle) {
if (item.onPress) item.onPress();
state.value = CONTEXT_MENU_STATE.END;
}
}, [state, item]);

return (
<AnimatedTouchable
onPress={handleOnPress}
activeOpacity={0.4}
style={[styles.menuItem, borderStyles]}
>
<Text
style={[
item.isTitle ? styles.menuItemTitleText : styles.menuItemText,
textColor,
]}
<>
<AnimatedTouchable
onPress={handleOnPress}
activeOpacity={!item.isTitle ? 0.4 : 1}
style={[styles.menuItem, borderStyles]}
>
{item.text}
</Text>
{!item.isSeperator && !item.isTitle && item.icon && item.icon()}
</AnimatedTouchable>
<Text
style={[
item.isTitle ? styles.menuItemTitleText : styles.menuItemText,
textColor,
]}
>
{item.text}
</Text>
{!item.withSeperator && !item.isTitle && item.icon && item.icon()}
</AnimatedTouchable>
{item.withSeperator && <Seperator theme={theme} />}
</>
);
};

Expand Down
23 changes: 17 additions & 6 deletions src/components/menu/MenuList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,27 @@ const MenuListComponent = () => {

const [itemList, setItemList] = React.useState<MenuItemProps[]>([]);

const menuHeight = useDerivedValue(
() => calculateMenuHeight(menuProps.value.items.length),
[menuProps]
);
const menuHeight = useDerivedValue(() => {
const itemsWithSeperator = menuProps.value.items.filter(
item => item.withSeperator
);
return calculateMenuHeight(
menuProps.value.items.length,
itemsWithSeperator.length
);
}, [menuProps]);
const prevList = useSharedValue<MenuItemProps[]>([]);

const messageStyles = useAnimatedStyle(() => {
const itemsWithSeperator = menuProps.value.items.filter(
item => item.withSeperator
);

const translate = menuAnimationAnchor(
menuProps.value.anchorPosition,
menuProps.value.itemWidth,
menuProps.value.items.length
menuProps.value.items.length,
itemsWithSeperator.length
);

const _leftOrRight = leftOrRight(menuProps);
Expand Down Expand Up @@ -121,7 +131,8 @@ const MenuListComponent = () => {
>
<Animated.View
style={[
{ ...StyleSheet.absoluteFillObject },
StyleSheet.absoluteFillObject,
styles.menuInnerContainer,
animatedInnerContainerStyle,
]}
>
Expand Down
24 changes: 24 additions & 0 deletions src/components/menu/Seperator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import isEqual from 'lodash.isequal';
import React, { memo, useMemo } from 'react';
import { View } from 'react-native';

import { BORDER_LIGHT_COLOR, BORDER_DARK_COLOR } from './constants';

type SeperatorProps = {
theme: 'light' | 'dark';
};

const Seperator = ({ theme }: SeperatorProps) => {
const styles = useMemo(() => {
return {
width: '100%',
height: 8,
backgroundColor:
theme === 'dark' ? BORDER_DARK_COLOR : BORDER_LIGHT_COLOR,
};
}, [theme]);

return <View style={styles} />;
};

export default memo(Seperator, isEqual);
16 changes: 10 additions & 6 deletions src/components/menu/styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { StyleSheet } from 'react-native';
import { MENU_WIDTH } from '../../constants';
import { MenuItemHeight } from '../../utils/calculations';
import styleGuide from '../../styleGuide';

const styles = StyleSheet.create({
Expand All @@ -15,21 +14,26 @@ const styles = StyleSheet.create({
width: MENU_WIDTH,
borderRadius: styleGuide.spacing * 1.5,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'flex-start',
overflow: 'hidden',
zIndex: 15,
},
menuInnerContainer: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'center',
},
menuItem: {
width: '100%',
height: MenuItemHeight(),

display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: styleGuide.spacing * 2,
paddingVertical: styleGuide.spacing * 1.25,
},
border: {
borderBottomWidth: 1,
Expand Down
2 changes: 1 addition & 1 deletion src/components/menu/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ export type MenuItemProps = {
icon?: () => React.ReactNode;
onPress: () => void;
isTitle?: boolean;
isSeperator?: boolean;
isDestructive?: boolean;
withSeperator?: boolean;
};

export type MenuListProps = {
Expand Down
16 changes: 12 additions & 4 deletions src/utils/calculations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ export const MenuItemHeight = () => {
return styleGuide.typography.callout.lineHeight + styleGuide.spacing * 2.5;
};

export const calculateMenuHeight = (itemLength: number) => {
export const calculateMenuHeight = (
itemLength: number,
seperatorCount: number
) => {
'worklet';
return MenuItemHeight() * itemLength;
return (
MenuItemHeight() * itemLength +
(itemLength - 1) +
seperatorCount * styleGuide.spacing
);
};

export type TransformOriginAnchorPosition =
Expand All @@ -22,10 +29,11 @@ export type TransformOriginAnchorPosition =
export const menuAnimationAnchor = (
anchorPoint: TransformOriginAnchorPosition,
itemWidth: number,
itemLength: number
itemLength: number,
itemsWithSeperatorLength: number
) => {
'worklet';
const MenuHeight = calculateMenuHeight(itemLength);
const MenuHeight = calculateMenuHeight(itemLength, itemsWithSeperatorLength);
const splittetAnchorName: string[] = anchorPoint.split('-');

const Center1 = itemWidth;
Expand Down

0 comments on commit ce2e099

Please sign in to comment.