컴포넌트/툴바

NavigationBar (내비게이션 바)

VanillaFront 2026. 9. 29. 23:15

 

Va.NavigationBar — 상단 내비게이션 바 컴포넌트

애플리케이션의 상단 헤더 영역을 담당하는 내비게이션 바 컴포넌트입니다. 좌측에 타이틀(또는 로고), 가운데에 메뉴 영역, 우측에 유틸 영역을 가진 3분할 구조로, 웹 애플리케이션에서 가장 표준적인 상단 바 레이아웃을 제공합니다. 내부에 menuButton, button 등을 자유롭게 배치할 수 있으며, menuAlign 속성으로 메뉴의 정렬 위치를 좌·중·우로 지정할 수 있습니다.

 


클래스 정보

  • Va.NavigationBar extends Va.Component
  • tagName: 'navigationBar'
  • isContainer: true
  • 기본 HTML: <nav> 요소 (접근성 role 자동 부여)
  • 파일: va_component.js

기본 사용법

{
    tagName: 'navigationBar',
    title: 'Title',
    appearance: 'primary',
    menuAlign: 'right',
    tags: [
        { tagName: 'menuButton', text: 'Menu1', appearance: 'primary',
          tags: [
              { tagName: 'menuItem', text: 'Menu11' },
              { tagName: 'menuItem', text: 'Menu12' }
          ]
        },
        { tagName: 'menuButton', text: 'Menu2', appearance: 'primary',
          tags: [
              { tagName: 'menuItem', text: 'Menu21' },
              { tagName: 'menuItem', text: 'Menu22' }
          ]
        },
        { tagName: 'button', text: 'Menu3', appearance: 'primary' }
    ]
}

tags 배열에 넣은 자식 컴포넌트는 기본적으로 메뉴 영역에 배치됩니다.


내부 3분할 구조

NavigationBar는 내부적으로 아래 3영역으로 구성됩니다.

영역위치역할

titleDiv 좌측 title 속성값 또는 tagPosition: 'title' 컴포넌트
menuDiv (기본 컨테이너) 가운데 tags로 넣은 메뉴/버튼 배치
rightDiv 우측 tagPosition: 'right' 컴포넌트 (알림·프로필 등 유틸)

containerPosition은 {title: 0, menu: 1, right: 2}로 정의되어 있어, 자식 컴포넌트에 tagPosition을 지정하면 해당 영역으로 이동합니다.


핸들러는 반드시 문자열 참조 (JSON 원칙)

VanillaFront는 화면 정의를 JSON으로 유지하는 철학입니다. 모든 이벤트 핸들러는 문자열로 View 메서드 이름을 지정합니다.

{ onTitleClick: 'onTitleClick', onMenuClick: 'onMenuClick' }

인라인 function 사용 금지 — JSON 직렬화/에디터/저장 불가.


주요 속성

속성타입기본값설명

title String — 좌측에 표시할 타이틀 텍스트 (HTML 허용)
appearance String — 시각 스타일 — 'primary', 'subtle', 'accent' 등
menuAlign String 'right' 메뉴 영역 정렬 — 'left', 'center', 'right'
expanded Boolean false 확장 상태 (모바일 대응)
border String — 테두리 스타일 — 'neutral' 등

주요 이벤트

이벤트콜백발생 시점

onTitleClick 'onTitleClick' 타이틀 클릭
onMenuClick 'onMenuClick' 메뉴 항목 클릭
onExpand 'onExpand' 확장 (모바일 햄버거 등)
onCollapse 'onCollapse' 축소

주요 메서드

  • expand() — 확장 상태로 전환
  • collapse() — 축소 상태로 전환

menuAlign — 메뉴 정렬 3가지

right (기본)

{ tagName: 'navigationBar', title: 'Title', menuAlign: 'right', tags: [ ... ] }

타이틀 좌측, 메뉴는 우측에 정렬. 가장 일반적인 상단 바 스타일.

center

{ tagName: 'navigationBar', title: 'Title', menuAlign: 'center', tags: [ ... ] }

타이틀 좌측, 메뉴는 정중앙. 좌우 여백이 대칭이 되어 홈페이지 스타일에 적합.

left

{
    tagName: 'navigationBar',
    title: 'Title',
    menuAlign: 'left',
    style: { titleDiv_width: '200px' },
    tags: [ ... ]
}

타이틀 옆에 바로 메뉴가 붙는 스타일. titleDiv_width로 타이틀 영역의 폭을 고정하면 깔끔합니다.


타이틀을 컴포넌트로 지정 — tagPosition: 'title'

title 문자열 대신 버튼·이미지 등 컴포넌트를 타이틀 영역에 배치하고 싶다면 자식에 tagPosition: 'title'을 지정합니다.

{
    tagName: 'navigationBar',
    menuAlign: 'left',
    style: { titleDiv_width: '200px' },
    tags: [
        {
            tagName: 'button',
            text: 'Title',
            appearance: 'accent',
            style: 'width:180px',
            tagPosition: 'title'   // ← titleDiv에 배치됨
        },
        { tagName: 'menuButton', text: 'Menu1', tags: [ ... ] },
        { tagName: 'menuButton', text: 'Menu2', tags: [ ... ] },
        { tagName: 'button', text: 'Menu3' }
    ]
}

로고 이미지를 넣고 싶을 때는 tagName: 'image' 컴포넌트에 tagPosition: 'title'을 지정하면 됩니다.


우측 유틸 영역 — tagPosition: 'right'

알림 아이콘, 프로필 메뉴 등 우측 고정 영역이 필요할 때 사용합니다.

{
    tagName: 'navigationBar',
    title: 'Title',
    menuAlign: 'right',
    tags: [
        // 메뉴 영역 (menuDiv)
        { tagName: 'menuButton', text: 'Menu1', tags: [ ... ] },
        { tagName: 'menuButton', text: 'Menu2', tags: [ ... ] },
        
        // 우측 유틸 (rightDiv)
        { tagName: 'button', text: '🔔', tagPosition: 'right' },
        { tagName: 'button', text: '👤', tagPosition: 'right' }
    ]
}

종합 예시 — 로고 + 메뉴 + 우측 유틸

config() {
    return {
        tagName: 'page',
        tags: [{
            tagName: 'navigationBar',
            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: 'menuButton', text: '제품', appearance: 'primary',
                    tags: [
                        { tagName: 'menuItem', text: 'Grid' },
                        { tagName: 'menuItem', text: 'Chart' },
                        { tagName: 'menuItem', text: 'Diagram' }
                    ]
                },
                {
                    tagName: 'menuButton', text: '문서', appearance: 'primary',
                    tags: [
                        { tagName: 'menuItem', text: '튜토리얼' },
                        { tagName: 'menuItem', text: 'API' }
                    ]
                },
                { tagName: 'button', text: '가격', appearance: 'primary' },
                
                // 우측 유틸
                { tagName: 'button', text: '로그인', tagPosition: 'right',
                  appearance: 'primary', onClick: 'onLogin' },
                { tagName: 'button', text: '시작하기', tagPosition: 'right',
                  appearance: 'accent', onClick: 'onStart' }
            ],
            onTitleClick: 'onLogoClick',
            onMenuClick: 'onMenuClick'
        }, {
            // 페이지 본문
            tagName: 'panel',
            style: { flex: 1 },
            tags: [ ... ]
        }]
    };
}

onLogoClick() { Va.Router.push('/'); }
onLogin()     { Va.Router.push('/login'); }
onStart()     { Va.Router.push('/start'); }

주의사항

  • 자식 컴포넌트의 기본 배치는 메뉴 영역 — 타이틀·우측으로 보내려면 tagPosition: 'title' 또는 'right' 명시
  • title 문자열은 HTML 허용 — 로고 이미지 태그도 삽입 가능 (예: title: '<img src="/logo.png"/> 제품명')
  • 모바일 대응은 반응형 컴포넌트와 조합 — 좁은 화면에서 메뉴가 잘리면 menuAlign 조정이나 별도 반응형 처리 필요
  • menuAlign 미지정 시 기본 'right' — 데모에는 meuAlign(오타) 사용 예도 있으나 menuAlign이 정확한 속성명
  • 핸들러는 문자열 참조만 — 인라인 function은 JSON 원칙 위반
  • 접근성 — <nav> 요소에 title 지정 시 aria-labelledby가 자동으로 부여됨