Menu
관련 작업을 필요할 때만 펼치는 목록.
- 라이브러리 전용
개요
미리보기
예시
상태
닫힘
열림
열림 · 끝 정렬
조용한 트리거
쓰임 예
공유 (ShareMenu 예)
이렇게 · 이렇게 하지 않기
- 이렇게 자주 쓰는 행동은 메뉴에 숨기지 않는다. 위험 항목은 맨 아래 구분선 뒤에 두고 결과를 이름에 쓴다(“센트럴바이에서 삭제”). 연결 해제와 삭제를 한 항목으로 합치지 않는다.
- 이렇게 위험 항목은 결과를 문장으로 쓰고(“연결 해제…”), 실행하면 ConfirmDialog를 연다. “…”는 추가 입력이 필요하다는 뜻.
- 이렇게 하지 않기 값 선택(정렬, 언어, 범위)에 메뉴를 쓰지 않는다. select·radio·listbox를 쓴다.
- 이렇게 하지 않기 연결 해제·보관·삭제처럼 차이를 설명해야 하는 행동을 메뉴 한 줄로 숨기지 않는다.
토큰과 속성
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
label | string | 작업 | 트리거 라벨이자 메뉴의 접근 이름. |
items | readonly MenuItem[] | — | 행동 항목 { id, label, icon?, disabled?, danger?, onSelect? }, 체크 항목 { kind: "checkbox", checked, onCheckedChange }, 구분선 { kind: "separator" }. 미리보기는 표본 8개. |
placement? | 'bottom-start' | 'bottom-end' | 'top-start' | bottom-start | 선호 위치. 화면 아래 공간이 모자라면 위로 뒤집고, 가로는 화면 안으로 맞춘다. |
triggerVariant? | 'secondary' | 'quiet' | secondary | 트리거 버튼 강조. 메뉴 트리거는 primary가 아니다. |
open? | boolean | false | 값이 바뀌면 그 상태로 연다/닫는다. 사용자 조작은 onOpenChange로 알린다. 카탈로그 미리보기는 정적으로 그린다. |
onOpenChange?: (open: boolean) => void | — | — | 사용자가 열거나 닫을 때(Esc, 바깥 클릭, 선택, Tab) 호출된다. |
ref | — | — | ref는 트리거 <button>으로 전달된다. |
popover="auto" | — | — | 패널은 네이티브 popover(top layer, 바깥 클릭으로 닫힘)다. 포털을 쓰지 않는다. |
| 그 밖의 속성 | — | — | id, aria-* 등 네이티브 div 속성은 바깥 래퍼로 전달된다. className·style·children은 받지 않는다. |
접근성
키보드: 트리거: Enter·Space·↓ = 열고 첫 항목, ↑ = 열고 마지막 항목. 메뉴: ↑↓ 순환, Home/End, 글자 typeahead, Enter·Space 실행, Esc 닫고 트리거로, Tab 닫고 다음 요소로.
- 트리거: aria-haspopup="menu", aria-expanded, aria-controls. 메뉴 이름은 트리거(aria-labelledby).
- disabled 항목도 초점을 받는다(aria-disabled). 그래야 존재를 알 수 있다.
- 바깥 클릭으로 닫히면 초점은 클릭한 곳에 둔다. Esc·선택이면 트리거로 돌아간다.
- 모션: base 불투명도 + 4px 이동, 퇴장 ×0.7. reduce면 이동 0.