# GNB (Pattern) > **SINGLE NAVIGATION MODE.** 독립 GNB / LNB / Dashboard Mode는 함께 사용하지 않는다. 2026-10-08 확정: GNB ONLY는 기존 LNB 부품을 재사용하는 내부 Sidebar를 포함할 수 있다(§15). [공통 정책](../guidelines/navigation-single-mode.md)이 이전 조합 기록보다 우선한다. 현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6.10 Pattern 계층, §6.11 Layout 단계 기준)를 따른다. ```text Layout visual reference: 외부 ui_viz Reference (ZIP 미포함) (Patterns/GNB, Variant B Top-header) Implementation: current @hm-design/ui primitives / patterns ``` ## 1. 상태 | 항목 | 내용 | |---|---| | 구현 상태 | 구현 완료 (2026-10-03 ui-viz 시각 재정합) | | 기반 | HM primitives 조합 (새 dependency 없음) | | 대표 Story | `Patterns/Layout/GNB` → `GNB` (verification: Default, Navigation Menu Open, User Menu Open, Long Labels, With Logo, Utilities, Mobile, Mobile Menu Open) | | 이력 | 첫 구현은 밝은 surface 64px였다. Layout은 ui-viz 시각 우선이라는 결정(지침 §6.11)으로 green 70px로 재정합했다 | | 보류 | §13 | ## 2. 목적 / 사용 범위 서비스 전역 상단 바(브랜드, 주 메뉴, 사용자). 새 Navigation/Menu primitive가 아니라 기존 primitive의 조합이다. 메뉴 데이터는 소비자가 children으로 그린다. | | 역할 | |---|---| | GNB | 전역 영역·서비스 이동 | | LNB | 현재 영역 내부의 세부 navigation (`lnb.md`) | | Dashboard | 별도의 Dashboard Navigation Mode. GNB와 결합하지 않는다 | ui-viz에서 GNB(Variant B, top-header)와 LNB(Variant A, sidebar)는 서로 대체하는 별개 Layout이다. 독립 Navigation Mode의 혼합은 금지한다. GNB ONLY의 내부 Sidebar에서 LNB 구현 부품을 재사용하는 것은 별도 LNB Mode 추가가 아니다(§15). ## 3. 구성 요소 | export | 역할 | |---|---| | `GNB` | `
` 바. `sticky` prop | | `GNBBrand` | 브랜드 링크(``, `asChild` 가능). 로고(`img`/`svg`, 있을 때만) + ``(`` eyebrow, `` 이름) | | `GNBNav` | 주 메뉴 영역(desktop 전용). 안에 `NavigationMenu viewport={false}` | | `GNBUtilities` | 오른쪽 영역 | | `GNBUser` | 사용자 trigger(Avatar + 이름/역할, 글자는 mobile에서 숨김). `DropdownMenuTrigger asChild`로 사용 | | `GNBMobileMenu` / `GNBMobileLink` / `GNBMobileGroup` | mobile 햄버거 + Sheet + 링크/그룹 | 검색·알림은 컴포넌트가 아니다. ghost Button + Tooltip + Badge + Popover(+Command) 조합을 `GNBUtilities`에 둔다(Story `Utilities`). ## 4. 구조 ```tsx …… 한맥 업무 시스템프로젝트 대시보드 대시보드 프로젝트
  • …
…
``` `viewport={false}`가 필수다: 2Depth 패널은 각 trigger 아래에서 content-width(`max-content`)로 열리며 짧은 패널도 trigger 폭 이상을 유지한다. trigger 중심에 정렬하고 viewport 가장자리에서는 clamp한다. 긴 라벨은 한 줄을 유지하며 최대 가용 폭을 넘으면 패널 안에서 가로 스크롤한다(공유 viewport는 메뉴 전체 아래에 중앙 정렬된다). ## 5. ui-viz 비교 (2026-10-03, 원본: `dashboard-composition.md` §19, `top-header-specimen.css/jsx`) > HISTORICAL_RECORD: 아래 표는 2026-10-03 비교 기록이다. 현재 패널 폭·정렬은 §4, Current/Open 우선순위는 §7을 따른다. | 항목 | ui-viz | 기존 HM(첫 구현) | 최종 HM | 분류 | |---|---|---|---|---| | 높이 | Header 70 (위 4 + 메뉴 면 66) | 64 | 70 (`--hm-gnb-height`) | MATCHED | | 배경 | 세로 4-stop `#1F8265/#165C47/#114838/#08241C` 0/30/65/100%, 높이 82px(70+12), 반복 없음 | 흰 surface | 같은 stop(`--hm-green-tone-1~4`), 82px 단일 gradient | MATCHED | | 콘텐츠 접점 | 12px, 콘텐츠 상단 radius 12, 뒤로 gradient 연속 | 없음 | `::after` 12px strip(`--hm-gnb-join`). 콘텐츠가 positioned·뒤에 오고 radius를 가져야 한다 | IMPLEMENTATION_CHANGE | | 로고 | 있을 때만, 가로(로고 왼쪽·이름 오른쪽), 없으면 영역·간격 없음 | 이름만 | 같음. eyebrow(11/700, `#BDDFD4`) + 이름(16/700), 1px 글자 테두리 | MATCHED | | 메뉴 위치 | grid 좌우 같은 폭 → header 전체 가운데 | brand 옆 왼쪽 | `minmax(0,1fr) auto minmax(0,1fr)` grid, 중앙 오차 0 | MATCHED | | 메뉴 항목 | 위 4·높이 66, 최소 112, padding 0 16, radius 4 4 0 0, White 700 16, 아이콘 없음, 글자 테두리 없음 | 34px text button | 같음 (Navigation Menu를 GNB 범위 안에서만 재색칠) | MATCHED | | hover | Black 10% + White | `--accent` | Black 10% + White | MATCHED | | current / selected shape | Beige(`bg.content`) + `#123328`, 위 radius 4, 아래 좌우 12px 오목 곡선, hover가 덮지 않음 | 연한 초록 면 | 같음 (`data-active`/`aria-current` + `::before/::after` radial) | MATCHED | | 열림(open) | White 면 + `#123328`, 곡선 숨김 | `--accent` | 같음 (`data-state=open`). current와 구분 | MATCHED | | 2뎁스 패널 | White, 부모 폭, 항목 56/16/16·24·700 가운데, hover·현재 Beige, 하단 radius 8, shadow `0 6px 16px .1` | 320px floating | 같음 | MATCHED | | utility | 원형 버튼·avatar 제거(2026-10-01 결정). 이름·역할만 | 검색·알림·Avatar | 기본은 이름·역할만. 검색·알림은 선택 조합(흰 ghost Button) | MATCHED / 선택 조합 | | 사용자 영역 | 이름 16/700 + 역할 12 `#BDDFD4`, 오른쪽 끝 (ui-viz는 avatar 없음) | Avatar + 글자 | HM Avatar(default 32px) + 글자 + Dropdown Menu. mobile은 Avatar만 | INTENTIONAL_CHANGE (2026-10-03 사용자 지시로 Avatar 추가) | | desktop 구조 | Brand / Menu / Profile | 같음 | 같음 | MATCHED | | mobile 구조 | 없음(≤1100px/48px은 OUT_OF_SCOPE) | 햄버거 + Sheet | 유지. breakpoint 1024px | INTENTIONAL_CHANGE (ui-viz에 기준 없음) | | 2뎁스 열기 | hover/click/ArrowDown, Escape + focus 복귀 | Radix | Radix Navigation Menu(hover delay, 키보드 model) | IMPLEMENTATION_CHANGE | ## 6. Public API - `GNB`: `header` props + `sticky`(기본 false). `data-slot="gnb"`, sticky면 `data-sticky`. - `GNBUser`: `button` props + `name`(필수), `description`, children = Avatar(default size, 이미지 실패 시 `AvatarFallback`). `aria-label` 기본 `" 사용자 메뉴"`. `data-slot`은 spread 뒤에 둬서 `DropdownMenuTrigger asChild`가 덮지 않는다. - `GNBMobileMenu`: 햄버거(`lg:hidden`)와 Sheet. `title`, `side`, `open`/`defaultOpen`/`onOpenChange`. `GNBMobileLink`는 router `preventDefault`가 있어도 닫히도록 context로 직접 닫는다(Radix Close는 prevented click을 건너뛴다). ## 7. Navigation 원칙 - 주 메뉴는 HM Navigation Menu다. `