Get startedFoundationsComponentsPatternsRules

Side Nav Items

사이드 내비 항목은 사이드 내비게이션 안에서 링크·동작·펼침·플라이아웃 메뉴와 섹션을 만들어요.

설치

pnpm dlx shadcn@latest add https://rebar.conmarket-landing.workers.dev/r/steel/side-nav-items.json

Navigation System 의 SideNavBody 안에 MenuList 를 두고 그 안에 항목을 넣어요. 모든 항목은 높이 32px(설명이 있으면 48px), 안쪽 여백 4px, 모서리 6px, 라벨은 body 크기에 medium(500) 굵기예요.

Examples

다른 페이지로 이동하는 항목은 LinkMenuItem 을 써요. 실제 <a href> 라서 새 탭 열기, 주소 복사가 그대로 돼요. 현재 페이지에는 isSelected 를 줘요. 선택 배경(background.selected)과 함께 왼쪽 가운데에 2×12px notch 가 생기고 aria-current="page" 가 붙어요.

Button menu item

같은 화면 안의 동작(사이드바 사용자 지정, 설정 열기)은 ButtonMenuItem(별칭 MenuItem)을 써요. description 을 주면 라벨 아래 작은 설명이 붙고 높이가 48px 이 돼요. isDisabled 는 누를 수 없는 상태예요. 아이콘이 없는 항목도 기본으로 24px 자리를 남겨 라벨이 나란히 정렬되는데, elemBefore={COLLAPSE_ELEM_BEFORE} 를 주면 그 자리를 없애요.

슬롯: elemAfter · actions · actionsOnHover

  • elemAfter: 라벨 뒤에 항상 보이는 요소 (개수, 배지)
  • actionsOnHover: 마우스를 올리거나 포커스했을 때만 나타나는 동작 버튼. elemAfter 가 있으면 그 자리를 대신해요.
  • actions: 항상 보이는 동작 버튼

동작 버튼은 IconButton appearance="subtle" spacing="compact" 로 만들어요. 라벨이 잘리면 마우스를 올렸을 때 오른쪽에 전체 내용을 툴팁으로 보여줘요(isContentTooltipDisabled 로 끌 수 있어요).

Expandable menu item

하위 항목을 제자리에서 펼치는 트리는 ExpandableMenuItem + ExpandableMenuItemTrigger + ExpandableMenuItemContent 로 만들어요. 단계마다 12px 씩 들여쓰지만 누를 수 있는 영역은 최상위 너비 그대로예요.

  • 접히면 >, 펼치면 v chevron 이 보여요. 아이콘을 주면 평소에는 아이콘이, 마우스를 올리거나 포커스하면 chevron 이 보여요.
  • 트리거에 href 를 주면 라벨은 프로젝트 첫 화면으로 가는 링크(선택 가능)가 되고, chevron 은 따로 누르는 작은 버튼이 돼요.
  • isDefaultExpanded(비제어) 또는 isExpanded + onExpansionToggle(제어)로 상태를 다뤄요.

Flyout menu item

누르면 항목 오른쪽에 400px 팝업을 띄우는 메뉴예요. 최근 항목, 즐겨찾기처럼 사이드 내비에 다 펼치기엔 긴 목록에 써요. 트리거 뒤에는 작은 오른쪽 chevron 이 붙어요. 팝업 안은 FlyoutHeader(제목 + 닫기 버튼) · FlyoutBody(스크롤) · FlyoutFooter(위 1px 테두리)로 구성해요.

Section · Divider

관련 항목은 MenuSection 으로 묶고 MenuSectionHeading(heading.xxsmall, text.subtlest)으로 이름을 붙여요. 묶음 사이는 Divider(<hr>, 위 1px 테두리)로 나누거나 TopLevelSpacer(12px)로 띄워요. 섹션을 MenuList 바로 안에 둘 때는 isMenuListItem 을 줘요.

Usage guidelines

어떤 항목을 쓸까

상황항목
다른 페이지로 이동LinkMenuItem
같은 화면 안의 동작 (설정 열기, 사용자 지정)ButtonMenuItem
하위 공간이 있는 프로젝트·스페이스ExpandableMenuItem (트리거에 href)
단순히 묶어 두는 폴더형 그룹ExpandableMenuItem (트리거에 href 없음)
긴 목록을 따로 띄워 보기 (최근 항목, 즐겨찾기)FlyoutMenuItem

좋은 사이드 내비

  • 한 번에 하나의 항목만 선택 상태로 둬요. 선택 상태, Breadcrumbs, 페이지 제목이 같은 위치를 가리켜야 해요.
  • 라벨은 짧은 명사로 써요(예: "백로그", "보드"). 길어지면 잘리고 툴팁으로만 보여요.
  • 아이콘은 모든 최상위 항목에 주거나 아예 주지 않아요. 섞이면 라벨 시작 위치가 흔들려 보여요.
  • 펼침은 두세 단계까지만 써요. 더 깊은 계층은 메인의 Breadcrumbs 나 Tabs 로 옮겨요.
  • 항목별 부가 동작(만들기, 더 보기)은 actionsOnHover 로 숨겨 두고, 꼭 늘 보여야 할 때만 actions 를 써요.
Do· 링크는 링크로
페이지를 바꾸는 항목은 LinkMenuItem 으로 만들어 새 탭 열기가 되게 해요.
Don't· 버튼으로 이동
ButtonMenuItem 의 onClick 안에서 페이지를 이동시키지 않아요.

Accessibility

  • MenuList 는 role="list", 각 항목은 role="listitem" 으로 감싸져요. 스크린 리더가 항목 개수와 위치를 읽어줘요.
  • 선택된 링크에는 aria-current="page" 가 붙어요.
  • 펼침 트리거에는 aria-expanded 와 aria-controls 가 붙어요. href 가 있으면 chevron 버튼이 따로 aria-expanded 를 갖고, 이름은 라벨과 같아요.
  • 플라이아웃 트리거에는 aria-haspopup="dialog", aria-expanded 가 붙고, 팝업은 role="dialog" 예요. 열리면 포커스가 팝업 안으로 들어가고 Esc 나 바깥 클릭으로 닫혀요.
  • MenuSection 은 role="group" 이고 MenuSectionHeading 으로 이름이 붙어요. 제목이 없으면 ariaLabel 을 줘요.
  • 슬롯 안의 아이콘처럼 상호작용하지 않는 요소는 클릭이 뒤의 항목으로 그대로 전달돼요. 슬롯 안의 버튼은 따로 Tab 으로 닿고, 동작 버튼에는 label 을 꼭 줘요.
  • 키보드: Tab 으로 항목 사이를 이동하고 Enter(링크), Enter·Space(버튼)로 실행해요.

Props

공통 (LinkMenuItem · ButtonMenuItem · 트리거)

Prop

Type

LinkMenuItem

Prop

Type

ButtonMenuItem (MenuItem)

Prop

Type

ExpandableMenuItem · Trigger · Content

Prop

Type

ExpandableMenuItemContent 는 하위 항목 목록(MenuList)이에요. useIsExpanded() 로 펼침 상태를 읽을 수 있어요.

FlyoutMenuItem · Trigger · Content

Prop

Type

FlyoutBody, FlyoutFooter 는 div props 를 받아요.

Prop

Type

On this page