ComponentsP3 본문

Command

검색 입력 + 필터된 명령 리스트(명령 팔레트 표면) — combobox + listbox를 aria-activedescendant로 연결. 검색은 label 부분 일치, 비제어(query 내부 소유).

마지막 업데이트 2026-06-11

한눈에#

⌘K로 여는 명령 팔레트 — 검색으로 명령을 좁히고 ↑/↓·Enter로 골라 실행합니다. 여러 액션을 모으는 단축 진입점입니다.

  • 새 파일 만들기
  • 프로젝트 열기
  • 문서 검색
  • 테마 전환
  • 배포 (권한 필요)
  • 설정

↑/↓로 이동(비활성 건너뜀·순환) · Enter 또는 클릭으로 선택

  • ⌘K 명령 팔레트
  • combobox + listbox
  • label 부분 일치
  • 비제어 검색

입력해 필터하고 ↑/↓로 이동 후 Enter로 선택 — 포커스는 입력에 머물고 aria-activedescendant가 활성 항목을 가리킵니다

선택 결과를 보여주기 위해 데모 래퍼가 onSelect를 받습니다 — Command 자체의 검색·탐색은 핸들러 없이도 동작합니다(비제어).

사용 시점#

검색으로 좁혀 명령을 실행하는 팔레트면 Command — 단순 검색 이동이나 고정 액션 메뉴는 다른 컴포넌트입니다.

쓴다
  • 새 파일 만들기
  • 프로젝트 열기
  • 문서 검색
  • 테마 전환
  • 배포 (권한 필요)
  • 설정

↑/↓로 이동(비활성 건너뜀·순환) · Enter 또는 클릭으로 선택

⌘K 단축 진입점에서 검색으로 명령을 좁혀 ↑/↓·Enter로 실행

대신 SearchField

결과 페이지로 이동하는 단순 검색 입력일 때

대신 DropdownMenu

검색 없이 보여주는 고정 액션 메뉴일 때

플레이그라운드#

컨트롤로 props를 조작하면 미리보기와 코드가 실시간 갱신됩니다.

  • 새 파일 만들기
  • 프로젝트 열기
  • 문서 검색
  • 테마 전환
import { Command } from '@wds/ui-web';

<Command
  items={[
    { value: 'new', label: '새 파일 만들기' },
    { value: 'open', label: '프로젝트 열기' },
    { value: 'search', label: '문서 검색' },
    { value: 'theme', label: '테마 전환' },
  ]}
/>

변형#

변형이 없습니다 — 항목 단위 disabled로 "보이지만 선택 불가" 상태를 표현합니다(키보드 탐색이 건너뛰고, 클릭·Enter가 무시됩니다). 모달 팔레트가 필요하면 Modal과 합성하세요.

크기#

단일 크기입니다 — 입력 높이 3rem, 리스트 최대 높이 20rem(초과 시 스크롤).

상태#

  • 활성 항목aria-activedescendant 대상, color.surface-hover 배경
  • 빈 결과 — 일치 항목이 없으면 리스트 대신 emptyTextrole="status"로 표시(검색어를 바꾸면 복귀)
  • Focus — 루트 :focus-withininput.border-focus 보더 + 18% 링
  • Disabled 항목color.disabled-fg 잉크 + 커서 차단

Props#

Prop타입기본값설명
itemsreadonly CommandItem[]{ value, label, disabled? } 배열 — label이 검색 대상
onSelect(value: string) => void항목 선택 콜백 (Enter 또는 클릭)
placeholderstring'검색어를 입력하세요'검색 입력 플레이스홀더
searchLabelstring'명령 검색'검색 입력·리스트의 aria-label
emptyTextstring'결과가 없습니다'빈 결과 문구 — role="status"로 보조기술에 알림
classNamestring루트(div)에 적용

접근성#

입력이 role="combobox" + aria-autocomplete="list", 리스트가 role="listbox"입니다. 포커스는 입력에 머물고 aria-activedescendant가 활성 항목 id를 가리킵니다(클릭도 mousedown을 막아 입력 포커스 유지).

동작
문자 입력label 부분 일치(대소문자 무시) 필터 — 활성 항목은 첫 활성 매치로 리셋
/ 활성 항목 순환 이동 — 비활성 항목 건너뜀
Enter활성 항목 선택 — onSelect(value) 호출(빈 결과면 무시)
  • 활성 항목은 aria-selected, 비활성 항목은 aria-disabled로 보고
  • 빈 결과는 role="status" 라이브 영역 — 필터 결과 소멸을 보조기술에 알림
  • 검색 대상은 label 텍스트 — 약어 별칭 검색은 지원하지 않습니다

토큰#

component 토큰 없이 Input의 component 토큰(input.border-focus)과 semantic을 직접 소비합니다(신설 기준 §4 미충족).

속성토큰
루트color.surface + color.border · radius.lg · shadow.sm
포커스 링input.border-focus + color.primary 18% 링 (:focus-within)
검색 입력font.size-body-1 · placeholder color.text-placeholder
검색 아이콘icon.size-md · color.text-muted
항목font.size-body-2 · hover/활성 color.surface-hover · pressed color.surface-pressed
비활성 항목color.disabled-fg
빈 결과color.text-muted · 패딩 space.8
모션duration.fast + ease.standard