NavigationMenuBar (햄버거 메뉴 바)
Va.NavigationMenuBar — 확장형 메뉴 내비게이션 바
햄버거 메뉴 버튼과 확장 가능한 메뉴 영역을 결합한 상단 내비게이션 컴포넌트입니다. 헤더 우측에 자동으로 메뉴 버튼(햄버거 아이콘)이 배치되고, 클릭하면 아래로 펼쳐지는 메뉴 팝 영역에 메뉴 항목들이 표시됩니다. 모바일 친화적인 접기/펼치기 UX가 필요한 애플리케이션이나, 메뉴 항목이 많아 상단 바에 다 배치하기 어려운 경우에 적합합니다.

클래스 정보
- Va.NavigationMenuBar extends Va.Component
- tagName: 'navigationMenuBar'
- isContainer: true
- 기본 HTML: <nav> 요소
- 파일: va_component.js
기본 사용법
{
tagName: 'navigationMenuBar',
title: 'Title',
menuAlign: 'right',
tags: [
{ tagName: 'expandButton', shape: 'square', text: 'Menu1',
tags: [
{ tagName: 'button', shape: 'square', text: 'Menu11' },
{ tagName: 'button', shape: 'square', text: 'Menu12' }
]
},
{ tagName: 'expandButton', shape: 'square', text: 'Menu2',
tags: [
{ tagName: 'button', shape: 'square', text: 'Menu21' },
{ tagName: 'button', shape: 'square', text: 'Menu22' }
]
},
{ tagName: 'button', shape: 'square', text: 'Menu3' }
]
}
차이점 요약: NavigationBar와 달리, tags로 넣은 자식은 기본적으로 접혀 있는 메뉴 팝(menuPop) 영역에 들어갑니다. 화면 우측의 햄버거 버튼을 눌러야 펼쳐집니다.
내부 구조
NavigationMenuBar는 헤더 + 메뉴 팝(pop) 두 개의 층으로 구성됩니다.
영역위치역할
| titleDiv | 헤더 좌측 | title 속성값 또는 tagPosition: 'title' 컴포넌트 |
| menuDiv | 헤더 가운데 | tagPosition: 'menu'로 지정된 컴포넌트 (헤더에 상시 노출) |
| menuButton | 헤더 우측 | 자동 생성되는 햄버거 버튼 (ico_navigation) |
| menuPop (기본 컨테이너) | 헤더 아래 | tags로 넣은 자식이 배치, expanded 시 표시 |
containerPosition은 {title: 0, menu: 1, menuPop: 2}로 정의되며, **기본 컨테이너는 menuPop**입니다.
핸들러는 반드시 문자열 참조 (JSON 원칙)
VanillaFront는 화면 정의를 JSON으로 유지하는 철학입니다. 모든 이벤트 핸들러는 문자열로 View 메서드 이름을 지정합니다.
{ onTitleClick: 'onTitleClick', onMenuClick: 'onMenuClick', onExpand: 'onExpand', onCollapse: 'onCollapse' }
인라인 function 사용 금지 — JSON 직렬화/에디터/저장 불가.
주요 속성
속성타입기본값설명
| title | String | — | 좌측에 표시할 타이틀 텍스트 |
| appearance | String | — | 시각 스타일 — 'primary', 'subtle', 'accent' 등 |
| menuAlign | String | 'right' | 헤더의 menuDiv 정렬 — 'left', 'center', 'right' |
| expanded | Boolean | false | 메뉴 팝 열림 상태 |
| border | String | — | 테두리 스타일 — 'neutral' 등 |
| menuButton | Object | — | 자동 생성되는 햄버거 버튼 옵션 오버라이드 (icon, appearance 등) |
주요 이벤트
이벤트콜백발생 시점
| onExpand | 'onExpand' | 햄버거 버튼 클릭으로 메뉴 팝이 열릴 때 |
| onCollapse | 'onCollapse' | 햄버거 버튼 재클릭으로 메뉴 팝이 닫힐 때 |
| onMenuClick | 'onMenuClick' | 햄버거 버튼 클릭 시마다 (expand/collapse와 함께) |
| onTitleClick | 'onTitleClick' | 타이틀 클릭 |
주요 메서드
- expand() — 메뉴 팝 열기
- collapse() — 메뉴 팝 닫기
menuAlign — 헤더의 menuDiv 정렬
헤더 가운데 배치되는 menuDiv 영역의 정렬을 지정합니다. NavigationBar와 동일하게 'left', 'center', 'right' 3가지를 지원합니다.
{ tagName: 'navigationMenuBar', title: 'Title', menuAlign: 'center', tags: [ ... ] }
주의: menuAlign은 헤더의 menuDiv 정렬을 결정할 뿐, 메뉴 팝 안 항목들의 배치와는 관계없습니다.
expandButton — 접었다 펼치는 아코디언 메뉴
NavigationMenuBar 안에서는 서브메뉴를 표현할 때 expandButton을 씁니다. 클릭 시 하위 항목들이 드롭다운이 아닌 인라인 아코디언 방식으로 펼쳐지므로 좁은 폭에서도 자연스럽게 동작합니다.
{
tagName: 'expandButton',
shape: 'square',
text: '제품',
tags: [
{ tagName: 'button', shape: 'square', text: 'Grid' },
{ tagName: 'button', shape: 'square', text: 'Chart' },
{ tagName: 'button', shape: 'square', text: 'Diagram' }
]
}
contentFlex: 1, textAlign: 'left' 스타일을 적용하면 좌측 정렬된 메뉴 리스트 형태가 됩니다.
타이틀·상시 노출 메뉴를 헤더에 배치 — tagPosition
기본은 자식이 menuPop(햄버거로 열리는 영역)에 들어가지만, 헤더에 항상 보여야 하는 요소는 tagPosition으로 위치를 옮깁니다.
{
tagName: 'navigationMenuBar',
menuAlign: 'left',
style: { titleDiv_width: '200px' },
tags: [
// 헤더 좌측 (titleDiv)
{
tagName: 'button',
text: 'Title',
appearance: 'accent',
style: 'width:180px',
tagPosition: 'title'
},
// 헤더 가운데 (menuDiv) — 항상 노출
{
tagName: 'button',
text: 'Another Menu',
appearance: 'primary',
tagPosition: 'menu'
},
// 이하 tagPosition 없음 → menuPop(햄버거 안)
{ tagName: 'expandButton', shape: 'square', text: 'Menu1',
tags: [ ... ] },
{ tagName: 'expandButton', shape: 'square', text: 'Menu2',
tags: [ ... ] }
]
}
tagPosition배치 영역표시 조건
| 'title' | titleDiv | 항상 |
| 'menu' | menuDiv | 항상 |
| (없음) | menuPop | 햄버거 버튼으로 열었을 때만 |
햄버거 버튼 커스터마이징 — menuButton
기본 아이콘은 ico_navigation(햄버거)이지만, menuButton 옵션으로 오버라이드할 수 있습니다.
{
tagName: 'navigationMenuBar',
title: 'Title',
menuButton: {
icon: 'ico_more', // 다른 아이콘
appearance: 'primary',
size: 'large'
},
tags: [ ... ]
}
종합 예시 — 로고 + 상시 메뉴 + 햄버거 확장
config() {
return {
tagName: 'page',
tags: [{
tagName: 'navigationMenuBar',
appearance: 'primary',
menuAlign: 'left',
border: 'neutral',
style: { titleDiv_width: '220px' },
tags: [
// 로고 (헤더 좌측 상시)
{
tagName: 'button',
text: 'VanillaFront',
appearance: 'accent',
style: 'width:200px',
tagPosition: 'title',
onClick: 'onLogoClick'
},
// 헤더 가운데 상시 메뉴
{ tagName: 'button', appearance: 'primary', text: '가격',
tagPosition: 'menu' },
{ tagName: 'button', appearance: 'primary', text: '문서',
tagPosition: 'menu' },
// 햄버거 안에 접혀 있는 메뉴들
{
tagName: 'expandButton', shape: 'square', appearance: 'primary',
text: '제품',
tags: [
{ tagName: 'button', appearance: 'primary', shape: 'square',
text: 'Grid', style: { contentFlex: 1, textAlign: 'left' } },
{ tagName: 'button', appearance: 'primary', shape: 'square',
text: 'Chart', style: { contentFlex: 1, textAlign: 'left' } },
{ tagName: 'button', appearance: 'primary', shape: 'square',
text: 'Diagram', style: { contentFlex: 1, textAlign: 'left' } }
]
},
{
tagName: 'expandButton', shape: 'square', appearance: 'primary',
text: '학습',
tags: [
{ tagName: 'button', appearance: 'primary', shape: 'square',
text: '튜토리얼', style: { contentFlex: 1, textAlign: 'left' } },
{ tagName: 'button', appearance: 'primary', shape: 'square',
text: 'API', style: { contentFlex: 1, textAlign: 'left' } }
]
},
{ tagName: 'button', appearance: 'primary', shape: 'square',
text: '커뮤니티' }
],
onTitleClick: 'onLogoClick',
onMenuClick: 'onMenuClick',
onExpand: 'onExpand',
onCollapse: 'onCollapse'
}, {
// 페이지 본문
tagName: 'panel',
style: { flex: 1 },
tags: [ ... ]
}]
};
}
NavigationBar vs NavigationMenuBar — 차이점
항목NavigationBarNavigationMenuBar
| 자식 배치 기본 위치 | 헤더 menuDiv (상시 노출) | menuPop (햄버거 안, 접혀 있음) |
| 서브메뉴 표현 | menuButton + menuItem (드롭다운) | expandButton + button (아코디언) |
| 우측 자동 요소 | 없음 | 햄버거 버튼 (자동 생성) |
| expand/collapse 이벤트 | 지원 | 지원 (실제 팝 개폐 동작) |
| 우측 유틸 영역 | tagPosition: 'right' 사용 | 별도 rightDiv 없음 |
| 적합한 상황 | 데스크톱 웹, 항상 메뉴 노출 | 모바일 친화, 메뉴 많은 경우 |
주의사항
- 기본 컨테이너는 menuPop — tags 자식은 햄버거 안에 들어감. 헤더에 상시 노출하려면 tagPosition: 'menu' 지정 필수
- 햄버거 버튼은 자동 생성 — 별도로 만들지 않아도 우측에 나타남
- 서브메뉴는 expandButton 권장 — menuButton(드롭다운)은 팝 영역 안에서 어색할 수 있음
- menuAlign은 헤더의 menuDiv 전용 — menuPop 안 항목 정렬과는 무관
- title 텍스트는 순수 텍스트(textContent) — NavigationBar와 달리 HTML 삽입 불가
- 핸들러는 문자열 참조만 — 인라인 function은 JSON 원칙 위반
- 모바일 미디어쿼리와 조합 권장 — 데스크톱에선 NavigationBar, 모바일에선 NavigationMenuBar로 교체하는 반응형 패턴이 유용
대안 비교
상황추천
| 모바일/좁은 화면, 접히는 메뉴 필요 | Va.NavigationMenuBar |
| 데스크톱 상단, 메뉴 상시 노출 | Va.NavigationBar |
| 좌측 세로 아이콘 메뉴 | Va.NavigationRail |
| 좌측 트리형 메뉴 | (프로젝트 표준 사이드 메뉴 컴포넌트) |
| 페이지 내부 액션 툴바 | Va.ActionBar / Va.TitleBar |
참고
- API 문서 페이지: https://vanillafront.com/docs.html?theme=light#main#apinavigationmenubar
- 연관: Va.NavigationBar (상시 노출형), Va.ExpandButton (아코디언 서브메뉴)