diff --git a/packages/common/components/src/ui/lnb/index.tsx b/packages/common/components/src/ui/lnb/index.tsx index 744ddcfd1..eac98faaa 100644 --- a/packages/common/components/src/ui/lnb/index.tsx +++ b/packages/common/components/src/ui/lnb/index.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect, useRef } from "react"; import { useQuery } from "@tanstack/react-query"; import { ChevronRight } from "lucide-react"; import { getConfig } from "@common/config"; @@ -38,12 +38,47 @@ export function LNB({ }); const [openMenuIds, setOpenMenuIds] = useState([]); + const userClosedMenusRef = useRef(new Set()); + const prevPathRef = useRef(currentPath); function isPathMatched(path: string) { if (!path) return false; return currentPath?.startsWith(path); } + useEffect(() => { + if (!menuList || !currentPath) return; + + const matchedMenuIds: number[] = []; + + const findMatchedMenus = (items: MenuItem[]) => { + items.forEach((item) => { + if (isPathMatched(item.urlPath)) { + const parentIds = getParentIds(item.menuCd)(menuList); + matchedMenuIds.push(...parentIds, item.menuCd); + } + + if (item.children) { + findMatchedMenus(item.children); + } + }); + }; + + findMatchedMenus(menuList); + + if (matchedMenuIds.length > 0) { + const filteredIds = matchedMenuIds.filter( + (id) => !userClosedMenusRef.current.has(id), + ); + setOpenMenuIds((prev) => [...new Set([...prev, ...filteredIds])]); + } + + if (prevPathRef.current !== currentPath) { + setOpenMenuIds(matchedMenuIds); + prevPathRef.current = currentPath; + } + }, [menuList, currentPath]); + function MenuItem({ item }: { item: MenuItem }) { const isMatched = isPathMatched(item.urlPath); @@ -74,20 +109,20 @@ export function LNB({ } function MenuGroup({ item }: { item: MenuItem }) { - const hasMatchedChild = item.children?.some((child) => - isPathMatched(child.urlPath), - ); - - const isOpen = openMenuIds.includes(item.menuCd) || hasMatchedChild; + const isOpen = openMenuIds.includes(item.menuCd); const handleOpenChange = (open: boolean) => { if (open) { + // 열 때는 부모들도 함께 열기 if (!openMenuIds.includes(item.menuCd)) { const parentIds = getParentIds(item.menuCd)(menuList ?? []); - setOpenMenuIds([...parentIds, item.menuCd]); + setOpenMenuIds((prev) => [...prev, ...parentIds, item.menuCd]); } + userClosedMenusRef.current.delete(item.menuCd); } else { + // 닫을 때는 현재 메뉴만 닫기 setOpenMenuIds((prev) => prev.filter((id) => id !== item.menuCd)); + userClosedMenusRef.current.add(item.menuCd); } };