본문으로 건너뛰기
Dot Design System
v0.3.1

DropdownMenu

낮은 우선순위의 관련 행동을 트리거 가까이에 모읍니다.

목적

DropdownMenu는 현재 대상이나 화면에서 가능한 보조 행동을 한곳에 정리한다. 주 행동의 우선순위는 유지하면서 낮은 빈도의 기능을 필요할 때만 드러내고, 사용자가 어느 대상에 대한 행동인지 잃지 않게 한다.

선택 기준

  • 행이나 대상에 대한 여러 보조 행동을 정리할 때 사용한다.
  • 현재 화면의 주 행동을 메뉴 안에 숨기지 않는다.
  • form에서 값 하나를 선택하는 경우 Select를 사용한다.
  • 상태를 계속 전환하는 소수 control은 Button이나 Tabs처럼 바로 보이게 둔다.

구조

DropdownMenu 아래에 DropdownMenuTriggerDropdownMenuContent를 둔다. Content 안에는 일반 행동 DropdownMenuItem, 토글 선택 DropdownMenuCheckboxItem, 단일 선택 DropdownMenuRadioGroupDropdownMenuRadioItem을 사용할 수 있다. DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup으로 의미를 묶고 DropdownMenuShortcut으로 보조 단축키를 안내한다.

하위 메뉴는 DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent로 구성한다. DropdownMenuPortal은 Content가 자동 사용하므로 보통 직접 다루지 않는다.

변형과 크기

Content의 기본 최소 너비는 8rem이고 sideOffset 기본값은 4px이다. 사용 가능한 화면 높이를 넘으면 세로 scroll이 생긴다. Item, Label, SubTrigger의 inset은 check indicator가 있는 항목과 왼쪽 정렬을 맞출 때 사용한다.

별도 density나 size prop은 없다. 한 메뉴 안에서 임의의 항목 높이를 섞지 않는다.

상태와 동작

Item은 focus와 disabled 상태를 지원한다. CheckboxItem은 checked, RadioGroup은 valueonValueChange로 선택 상태를 다룬다. Sub menu는 열린 상태를 시각적으로 표시한다. 일반 Item 선택은 보통 메뉴를 닫고 행동을 실행한다.

비동기 작업은 메뉴 안에서 장시간 진행하지 않는다. 실행 직후 대상 근처나 toast에서 결과를 알려 이전 목록 맥락과 다음 행동을 연결한다.

콘텐츠

Item은 복제, 초안 다운로드보다 대상이 모호할 수 있으면 커리큘럼 복제처럼 결과를 분명히 쓴다. 파괴 행동은 마지막 group으로 분리하고 문구로 위험을 알린다. Shortcut은 실제로 지원하는 경우에만 표시한다.

접근성

Trigger가 icon-only라면 aria-label을 제공한다. 각 Item은 text label을 가져야 하며 아이콘과 색만으로 행동을 구분하지 않는다. keyboard 방향키, Enter, Escape 흐름을 방해하는 custom handler를 넣지 않는다. 중요한 행동을 hover에서만 접근 가능하게 만들지 않는다.

좁은 화면과 긴 콘텐츠

Content는 사용 가능한 높이 안에서 scroll되지만 지나치게 많은 항목은 group과 정보 구조를 다시 검토한다. 긴 문구를 작은 너비에서 억지로 한 줄로 유지하지 않는다. touch 중심 화면에서 항목이 많거나 설명이 필요하면 Sheet 기반 action list를 고려한다.

공개 API

  • DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuPortal
  • DropdownMenuGroup, DropdownMenuLabel, DropdownMenuSeparator
  • DropdownMenuItem: inset?: boolean
  • DropdownMenuCheckboxItem
  • DropdownMenuRadioGroup, DropdownMenuRadioItem
  • DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent; SubTrigger는 inset?: boolean
  • DropdownMenuShortcut

예제

사용 코드 · TSX
import {
  Button,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@classum/dot-design-system/ui';

export function CurriculumMenu() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline">더 보기</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuLabel>커리큘럼 관리</DropdownMenuLabel>
        <DropdownMenuItem>커리큘럼 복제</DropdownMenuItem>
        <DropdownMenuItem>초안 다운로드</DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem>보관함으로 이동</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

피해야 할 사용

  • 주 행동을 DropdownMenu 안에 숨기지 않는다.
  • form 값 선택을 일반 Item click으로 구현하지 않는다.
  • 한 메뉴에 깊은 Sub menu를 여러 단계 중첩하지 않는다.
  • 아이콘만 나열하고 text label을 생략하지 않는다.
  • 파괴 행동을 일반 행동 사이에 섞어 실수 가능성을 높이지 않는다.

관련 항목