import { Ionicons } from "@expo/vector-icons";
import { Link, usePathname } from "expo-router";
import React, { useEffect, useRef } from "react";
import { Animated, Pressable, StyleSheet, Text } from "react-native";
import { colors, commonStyles } from "./styles";
import { HEADER_HEIGHT, MenuItem } from "./types";
interface MobileMenuProps {
items: readonly MenuItem[];
isOpen: boolean;
onToggle: () => void;
onClose: () => void;
}
export function MobileMenu({ items, isOpen, onToggle, onClose }: MobileMenuProps) {
const pathname = usePathname();
const slideAnimation = useRef(new Animated.Value(0)).current;
const animatedHeight = slideAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, items.length * 60], // 각 메뉴 아이템당 약 60px
});
const animatedOpacity = slideAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
useEffect(() => {
Animated.timing(slideAnimation, {
toValue: isOpen ? 1 : 0,
duration: isOpen ? 250 : 200,
useNativeDriver: false,
}).start(() => {
if (!isOpen) {
// 애니메이션 완료 후 상태 동기화는 부모에서 처리
}
});
}, [isOpen, slideAnimation]);
useEffect(() => {
if (!isOpen) return;
const handleOutsideClick = () => {
onClose();
};
if (typeof document !== 'undefined') {
document.addEventListener('click', handleOutsideClick);
return () => document.removeEventListener('click', handleOutsideClick);
}
}, [isOpen, onClose]);
return (
<>
{/* 모바일 메뉴 아이콘 */}
<Pressable
style={styles.mobileMenuButton}
onPress={onToggle}
>
<Ionicons
name="menu"
size={28}
color={isOpen ? colors.primary : "black"}
/>
</Pressable>
{/* 모바일 메뉴 드롭다운 */}
<Animated.View
style={[
styles.mobileDropdown,
{
height: animatedHeight,
opacity: animatedOpacity,
}
]}
pointerEvents={isOpen ? 'auto' : 'none'}
>
{items.map((item) => (
<Link
key={item.href}
href={item.href}
onPress={onClose}
style={[
styles.mobileMenuItem,
pathname === item.href && styles.activeMobileMenuItem,
]}
>
<Text style={[
commonStyles.menuText,
pathname === item.href && commonStyles.activeMenuText,
]}>
{item.label}
</Text>
</Link>
))}
</Animated.View>
</>
);
}
const styles = StyleSheet.create({
mobileMenuButton: {
padding: 10,
},
mobileDropdown: {
position: "absolute",
top: HEADER_HEIGHT,
right: 0,
width: 300,
backgroundColor: colors.backgroundOverlay,
borderBottomWidth: 1,
borderBottomColor: colors.border,
boxShadow: "0px 2px 10px rgba(0, 0, 0, 0.1)",
overflow: "hidden",
},
mobileMenuItem: {
height: 60,
paddingVertical: 16,
paddingHorizontal: 20,
borderBottomWidth: 1,
borderBottomColor: colors.borderLight,
justifyContent: "center",
},
activeMobileMenuItem: {
backgroundColor: colors.activeBackground,
},
});