Components - sidebar

comment

aria-controls 속성은 고유한 ID 값을 참조해야 하는데, 해당 페이지는 동일한 ID를 여러 곳에서 사용하고 있어 중복 문제로 정상 동작하지 않음.

  • 단일 메뉴: nav__item--single 클래스를 사용하며, <a> 태그로 링크 구성
  • 서브메뉴가 있는 메뉴: <button> 태그를 사용하고, aria-controls="submenu-id" 속성으로 서브메뉴 ID 참조. .nav__submenu에는 고유한 id 속성 필수
  • 상태 클래스: is-open (서브메뉴 열림), is-current (현재 페이지 대메뉴), is-collapsed (사이드바 접힘 상태 제어)
  • 현재 페이지 표시: 대메뉴에 is-current 클래스 추가, 서브메뉴의 현재 페이지 링크에는 <a> 태그에 aria-current="page" 속성 추가
  • 사이드바 토글 버튼: js-sidebar-toggle 클래스 필수, aria-expandedaria-label 속성 필수. 클릭 시 사이드바 토글 및 aria-expanded 속성 자동 관리, sidebaris-collapsed 클래스 추가/제거
  • 네비게이션 서브메뉴 토글: .nav__link[aria-controls] 클릭 시 해당 서브메뉴 열기/닫기
  • 자동 상태 관리: 사이드바 접을 때 열려있는 모든 서브메뉴 자동 닫기 및 ARIA 속성 초기화, 펼칠 때는 이전에 열려있던 서브메뉴 상태 자동 복원
  • 외부 클릭 처리: 접힌 상태(is-collapsed)에서 네비게이션 외부 클릭 시 열려있는 모든 서브메뉴 자동 닫기
  • ARIA 속성 자동 관리: aria-expanded, hidden 속성 자동 업데이트로 접근성 향상
  • JavaScript 초기화: initSidebars() 함수를 호출하여 사이드바 토글 기능 활성화. 페이지 로드 시 자동으로 초기화되거나 수동으로 호출 가능
default
HTML 구조
<aside class="app-sidebar">
  <div class="sidebar">
    <div class="sidebar__header">
      <div class="app-brand">
        <span class="app-brand__logo" title="SOOP"></span>
        <span class="app-brand__text">Ads Center</span>
      </div>
      <button type="button" class="sidebar__fold-button js-sidebar-toggle" aria-expanded="true" aria-label="사이드바 접기">
        <span class="visually-hidden">사이드바 접기</span>
      </button>
    </div>

    <nav class="sidebar__nav" aria-label="메인 메뉴">
      <ul class="nav">
        <!-- 단일메뉴 -->
        <li class="nav__item nav__item--single nav__item--dashboard">
          <a href="#" class="nav__link">
            <span class="nav__icon"></span>
            <span class="nav__text">대시보드</span>
          </a>
        </li>

        <!-- 서브메뉴가 있는 메뉴 -->
        <li class="nav__item nav__item--campaign is-open">
          <button type="button" class="nav__link" aria-expanded="true" aria-controls="submenu-campaign">
            <span class="nav__icon"></span>
            <span class="nav__text">캠페인</span>
          </button>
          <ul class="nav__submenu" id="submenu-campaign">
            <li class="nav__subitem"><a href="#" class="nav__sublink">캠페인 관리</a></li>
            <li class="nav__subitem"><a href="#" class="nav__sublink">타겟 관리</a></li>
          </ul>
        </li>
        <!-- ... 기타 메뉴 항목들 ... -->
      </ul>
    </nav>
  </div>
</aside>
현재 페이지 표시
HTML 구조
<aside class="app-sidebar">
  <div class="sidebar">
    <div class="sidebar__header">
      <div class="app-brand">
        <span class="app-brand__logo" title="SOOP"></span>
        <span class="app-brand__text">Ads Center</span>
      </div>
      <button type="button" class="sidebar__fold-button js-sidebar-toggle" aria-expanded="true" aria-label="사이드바 접기">
        <span class="visually-hidden">사이드바 접기</span>
      </button>
    </div>

    <nav class="sidebar__nav" aria-label="메인 메뉴">
      <ul class="nav">
        <!-- 단일메뉴 -->
        <li class="nav__item nav__item--single nav__item--dashboard">
          <a href="#" class="nav__link">
            <span class="nav__icon"></span>
            <span class="nav__text">대시보드</span>
          </a>
        </li>

        <!-- 서브메뉴가 있는 메뉴 (현재 페이지: .is-current, aria-current="page") -->
        <li class="nav__item nav__item--campaign is-open is-current">
          <button type="button" class="nav__link" aria-expanded="true" aria-controls="submenu-campaign">
            <span class="nav__icon"></span>
            <span class="nav__text">캠페인</span>
          </button>
          <ul class="nav__submenu" id="submenu-campaign">
            <li class="nav__subitem"><a href="#" class="nav__sublink" aria-current="page">캠페인 관리</a></li>
            <li class="nav__subitem"><a href="#" class="nav__sublink">타겟 관리</a></li>
          </ul>
        </li>
        <!-- ... 기타 메뉴 항목들 ... -->
      </ul>
    </nav>
  </div>
</aside>