import { useImperativeHandle, useLayoutEffect, forwardRef, useEffect, useState, Fragment, useRef } from "react"; import { Platform, Animated, Easing, View } from "react-native"; import { type EmbeddedMenuButton as EmbeddedMenuButtonType } from "./components/menuButton/type"; import { type IEmbeddedMenuRef } from "./type"; import type IEmbeddedMenuProps from "./type"; import stylesheet, { useStyles } from "./stylesheet"; import MenuButton from "./components/menuButton"; import { NCoreUIKitEmbeddedMenu, NCoreUIKitTheme } from "../../core/hooks"; import type { RefForwardingComponent } from "../../types"; import { PanelLeftClose, PanelLeftOpen } from "lucide-react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import Seperator from "../seperator"; import SiteLogo from "../siteLogo"; import Button from "../button"; const Menu: RefForwardingComponent = ({ isWorkWithSafeAreaView = true, isWorkWithHeaderSpace = true, isWorkWithAnimation = true, renderHeader: RenderHeader, renderFooter: RenderFooter, isShowSiteLogo = true, close: closeAction, customLocalize, maxWidth = 300, minWidth = 75, siteLogoProps, headerSpace, customTheme, navigation, isCollapse, onClosed, onOpened, buttons, onClose, onOpen, style, id, ...props }, ref) => { const { configs, colors, spaces } = NCoreUIKitTheme.useContext(customTheme); const [ isActive, setIsActive ] = useState(false); const { headerContentContainer: headerContentContainerDynamicStyle, headerContainer: headerContainerDynamicStyle, collapseButton: collapseButtonDynamicStyle, seperator: seperatorDynamicStyle, container: containerDynamicStyle, siteLogo: siteLogoDynamicStyle } = useStyles({ isCollapse: isActive, colors, spaces }); const animatedX = useRef(new Animated.Value(!isCollapse ? minWidth : maxWidth)).current; useImperativeHandle( ref, () => ({ close, open }), [] ); useEffect(() => { if(isCollapse !== undefined && isActive !== isCollapse) setIsActive(isCollapse); }, [isCollapse]); useLayoutEffect(() => { if(isActive) { if(onOpen) onOpen({ id }); if(Platform.OS !== "web") { if(onOpened) onOpened({ id }); } else if(isWorkWithAnimation) { openAnimation(); } else { animatedX.setValue(maxWidth); if(onOpened) onOpened({ id }); } } else { if(onClose) onClose({ id }); if(isWorkWithAnimation && Platform.OS === "web") { closeAnimation(); } else { animatedX.setValue(minWidth); if(onClosed) onClosed({ id }); } } }, [ isActive ]); const open = () => { NCoreUIKitEmbeddedMenu.open({ id }); }; const close = () => { NCoreUIKitEmbeddedMenu.close({ id }); }; const openAnimation = () => { Animated.timing(animatedX, { useNativeDriver: Platform.OS !== "web", easing: Easing.linear, toValue: maxWidth, duration: 300 }).start(({ finished }) => { if(finished) { if(onOpened) onOpened({ id }); } }); }; const closeAnimation = () => { Animated.timing(animatedX, { useNativeDriver: Platform.OS !== "web", easing: Easing.linear, toValue: minWidth, duration: 300 }).start(({ finished }) => { if(finished) { if(onClosed) onClosed({ id }); } }); }; const updateMenuButtonCollabs = ({ depthMap, status }: { depthMap: Array; status: boolean; }) => { const state = NCoreUIKitEmbeddedMenu.get({ id }); if(!state) { return; } const recursivelyCatch = (item: Array, index = 0): Array => { const tIndex = depthMap[index]; return item.map((c_item, c_index) => { if(c_index !== tIndex) { return c_item; } if(index === depthMap.length - 1) { return { ...c_item, isCollapse: status }; } return { ...c_item, subButtons: recursivelyCatch(c_item.subButtons as Array, index + 1) }; }); }; const newButtons = recursivelyCatch(state.buttons); state.buttons = newButtons; NCoreUIKitEmbeddedMenu.update({ menuData: state, id: id }); }; const renderToggleCollapseForCollabsed = () => { if(isActive) { return null; } return