summaryrefslogtreecommitdiff
path: root/components/layout
diff options
context:
space:
mode:
authorjoonhoekim <26rote@gmail.com>2025-11-13 19:37:04 +0900
committerjoonhoekim <26rote@gmail.com>2025-11-13 19:37:04 +0900
commit7517ec0b016265a6c1d35f22ba6292c498669d43 (patch)
treed1460d90e0b73d335d87c84e1e60bd43505ecaa2 /components/layout
parent1b84707d2f7abba3349fc306b539ef661a22cd45 (diff)
(김준회) 헤더 메뉴: 클릭으로 토글하는 방식으로 변경 (설계측 요청사항)
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/Header.tsx51
1 files changed, 40 insertions, 11 deletions
diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx
index c5c83e64..b3d9ee6a 100644
--- a/components/layout/Header.tsx
+++ b/components/layout/Header.tsx
@@ -3,7 +3,6 @@
import * as React from "react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
import {
DropdownMenu,
@@ -22,7 +21,7 @@ import {
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/components/ui/navigation-menu";
-import { SearchIcon, BellIcon, Menu } from "lucide-react";
+import { SearchIcon } from "lucide-react";
import { useParams, usePathname, useSearchParams } from "next/navigation";
import { cn } from "@/lib/utils";
import Image from "next/image";
@@ -34,7 +33,6 @@ import {
salesNav,
engineeringNav,
MenuSection,
- MenuItem,
mainNavVendor,
additionalNavVendor,
domainBrandingKeys
@@ -58,20 +56,29 @@ export function Header() {
const userName = session?.user?.name || "";
- const domain = session?.user?.domain || "";
const initials = userName
.split(" ")
.map((word) => word[0]?.toUpperCase())
.join("");
const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false);
+ const [openMenuKey, setOpenMenuKey] = React.useState<string>("");
const toggleMobileMenu = () => {
setIsMobileMenuOpen(!isMobileMenuOpen);
};
+ const toggleMenu = React.useCallback((menuKey: string) => {
+ setOpenMenuKey(prev => prev === menuKey ? "" : menuKey);
+ }, []);
+
+ // 페이지 이동 시 메뉴 닫기
+ React.useEffect(() => {
+ setOpenMenuKey("");
+ }, [pathname]);
+
// 도메인별 메뉴 및 브랜딩 정보 가져오기
- const getDomainConfig = (pathname: string) => {
+ const getDomainConfig = (pathname: string | null) => {
if (pathname?.includes("/partners")) {
return {
main: mainNavVendor,
@@ -175,18 +182,35 @@ export function Header() {
{/* 네비게이션 메뉴 - 도메인별 활성화된 메뉴만 표시 (번역된) */}
<div className="hidden md:block flex-1 min-w-0">
- <NavigationMenu className="relative z-50">
+ <NavigationMenu
+ className="relative z-50"
+ value={openMenuKey}
+ >
<div className="w-full overflow-x-auto pb-1">
<NavigationMenuList className="flex-nowrap w-max">
{main.map((section: MenuSection) => (
- <NavigationMenuItem key={section.titleKey}>
- <NavigationMenuTrigger className="px-2 xl:px-3 text-sm whitespace-nowrap">
+ <NavigationMenuItem key={section.titleKey} value={section.titleKey}>
+ <NavigationMenuTrigger
+ className="px-2 xl:px-3 text-sm whitespace-nowrap"
+ onClick={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ toggleMenu(section.titleKey);
+ }}
+ onPointerEnter={(e) => e.preventDefault()}
+ onPointerMove={(e) => e.preventDefault()}
+ >
{t(section.titleKey)}
</NavigationMenuTrigger>
{/* 그룹핑이 필요한 메뉴의 경우 GroupedMenuRenderer 사용 */}
{section.useGrouping ? (
- <NavigationMenuContent className="max-h-[80vh] overflow-y-auto">
+ <NavigationMenuContent
+ className="max-h-[80vh] overflow-y-auto"
+ onPointerEnter={(e) => e.preventDefault()}
+ onPointerLeave={(e) => e.preventDefault()}
+ forceMount={openMenuKey === section.titleKey ? true : undefined}
+ >
<GroupedMenuRenderer
items={section.items}
lng={lng}
@@ -195,7 +219,12 @@ export function Header() {
/>
</NavigationMenuContent>
) : (
- <NavigationMenuContent className="max-h-[70vh] overflow-y-auto">
+ <NavigationMenuContent
+ className="max-h-[70vh] overflow-y-auto"
+ onPointerEnter={(e) => e.preventDefault()}
+ onPointerLeave={(e) => e.preventDefault()}
+ forceMount={openMenuKey === section.titleKey ? true : undefined}
+ >
<ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
{section.items.map((item) => (
<ListItem
@@ -317,7 +346,7 @@ ListItem.displayName = "ListItem";
export function RouteLogger() {
const path = usePathname();
- const qs = useSearchParams().toString();
+ const qs = useSearchParams()?.toString();
React.useEffect(() => {
console.log("[URL]", path + (qs ? "?" + qs : ""));
}, [path, qs]);