본문으로 건너뛰기

Menu

trigger를 눌렀을 때 나타나는 액션 목록입니다. 중첩된 submenu와 체크 가능한 행을 포함할 수 있고, 키보드만으로 전체를 다룰 수 있습니다.

tsx
import { Button, Menu, MenuItem, MenuSeparator, MenuSubmenu } from 'neba';

<Menu trigger={<Button>액션</Button>}>
  <MenuItem shortcut="⌘E">이름 바꾸기</MenuItem>
  <MenuSubmenu label="이동">
    <MenuItem>보관함</MenuItem>
  </MenuSubmenu>
  <MenuSeparator />
  <MenuItem color="danger">삭제</MenuItem>
</Menu>;

행은 배열이 아니라 컴포넌트로 씁니다. 행마다 다른 핸들러와 아이콘이 붙고 그중 일부가 submenu가 되기 때문입니다. 값을 고르는 목록이 필요하다면 Select를 쓰세요.

Props

Prop타입기본값설명
triggerReactElement메뉴를 여는 요소. Base UI가 연결해 줍니다. 다른 곳에서 여는 controlled 메뉴에는 필요 없습니다
openboolean열림 여부. controlled 메뉴
defaultOpenbooleanfalse처음부터 열려 있음
onOpenChange(open: boolean) => void열리거나 닫힐 때
side공통'top' | 'right' | 'bottom' | 'left''bottom'트리거의 어느 변에 걸릴지. 자리가 없으면 반대편으로 뒤집힙니다
align공통'start' | 'center' | 'end''start'그 변 위에서의 위치
sideOffsetnumber6트리거와의 거리(px)
modalbooleantrue열려 있는 동안 뒤 페이지를 가져갈지
openOnHoverbooleanfalse호버로도 열립니다. 메뉴바처럼 열린 채로 옆 메뉴로 건너가야 할 때
loopFocusbooleantrue마지막 항목에서 화살표를 누르면 처음으로 돌아갈지
disabledbooleanfalse사용 불가. 트리거가 아무것도 열지 않습니다
size공통'xs' | 'sm' | 'md' | 'lg' | 'xl''md'높이와 타입 스케일
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'의미론적 색 역할. 임의 색상값은 받지 않습니다
density공통'default' | 'compact''default'행의 여백만 바꿉니다. 메뉴는 자기 팝업 폭을 스스로 정하므로 Box보다 좁은 사다리를 씁니다
childrenReactNode행들. MenuItem, MenuGroup, MenuSeparator, MenuSubmenu 등
Prop타입기본값설명
onClick(event) => void행이 하는 일
hrefstring넘기면 진짜 a가 됩니다. 링크로 이뤄진 메뉴는 링크여야 새 탭으로 열 수 있습니다
targetstring링크가 열리는 곳. href가 없으면 무시됩니다. 이 탭이 아닌 곳으로 열면 rel에 noopener noreferrer가 더해집니다
relstring링크의 rel. 덮어쓰는 것이 아니라 합쳐집니다. nofollow를 쓴다고 새 탭의 보호가 사라지지는 않습니다
startIconReactNode라벨 앞의 내용
endIconReactNode라벨 뒤, shortcut 앞의 내용
shortcutReactNode같은 일을 하는 단축키. 행 끝에 흐리게 놓입니다. 표시만 하고 바인딩하지는 않습니다
descriptionReactNode라벨 아래 한 줄
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'이 행만 다른 색 계열로. 지우는 행에 danger. 기본값은 메뉴의 색입니다
closeOnClickbooleantrue고르면 메뉴가 닫힐지
disabledbooleanfalse사용 불가. 목록에는 남고 타이핑 검색에도 걸립니다
labelstring타이핑 검색이 맞춰 볼 문자열. 라벨이 평범한 문자열이 아닐 때
childrenReactNode라벨
Prop타입기본값설명
labelReactNode서브메뉴를 여는 행의 라벨
startIconReactNode라벨 앞의 내용
side공통'top' | 'right' | 'bottom' | 'left''right'부모 행의 어느 쪽으로 열릴지
sideOffsetnumber4부모 메뉴와의 거리(px)
disabledbooleanfalse사용 불가
childrenReactNode중첩된 행들. 그 안에 또 MenuSubmenu를 넣을 수 있고, 깊이 제한은 없습니다

ContextMenu

Prop타입기본값설명
contentReactNode행들. Menu 안에 쓰는 것과 똑같이 씁니다
children * ReactNode오른쪽 클릭이나 길게 누르기에 반응할 영역
openboolean열림 여부
defaultOpenbooleanfalse처음부터 열려 있음
onOpenChange(open: boolean) => void열리거나 닫힐 때
disabledboolean우클릭과 길게 누르기에 반응하지 않게 합니다
loopFocusbooleantrue마지막 행에서 방향키를 누르면 첫 행으로 돌아갈지
size공통'xs' | 'sm' | 'md' | 'lg' | 'xl''md'높이와 타입 스케일
color공통'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'의미론적 색 역할. 임의 색상값은 받지 않습니다
density공통'default' | 'compact''default'행의 여백만 바꿉니다

예시

href · startIcon · shortcut

href를 주면 행이 실제 <a>로 렌더링되므로 새 탭으로 열거나 주소를 복사할 수 있습니다. shortcut에는 Shortcut을 넣습니다. MenuSeparator로 행을 그룹으로 나눕니다.

깊이 제한은 없습니다. submenu의 자식도 메뉴 행이므로 그 안에 또 MenuSubmenu를 둘 수 있습니다. hover로 열리며, 열린 submenu로 포인터를 비스듬히 옮겨도 닫히지 않습니다.

체크와 라디오 행

체크 표시는 여러 개를 동시에 켜는 항목, 점은 여럿 중 하나를 고르는 항목에 씁니다. 두 경우 모두 선택 후 메뉴가 닫히지 않습니다. 행 단위로 closeOnClick을 지정할 수 있습니다.

ContextMenu

우클릭으로 열리는 메뉴입니다. content에 메뉴 행을, children에 대상 영역을 넘깁니다.

size와 density

side · align · openOnHover

sidealign은 trigger를 기준으로 팝업이 놓일 자리입니다. openOnHover는 클릭 없이 hover만으로 열리게 합니다.

접근성

  • menu / menuitem role, 방향키 roving focus, Home/End, typeahead, Escape, 바깥 클릭으로 닫기, 닫을 때 trigger로 focus 복귀가 모두 처리됩니다.
  • 삭제처럼 파괴적인 행에는 color="danger"를 주세요. 글자색과 옅은 배경, focus ring이 함께 바뀝니다.
  • 라벨이 문자열이 아니면 label에 typeahead가 매칭할 문자열을 주세요.
  • disabled 행은 목록에 남고 typeahead에도 걸립니다. 행이 사라지면 "여기서는 쓸 수 없음"이 아니라 "그런 항목이 없음"으로 읽힙니다.

Released under the MIT License