Drop page / section descriptions, state notes and repeated captions from the representative Stories of 44 components, the Patterns, Center Graphic and OrgChart pages. Value readouts, spec lists and captions hide only on the representative page; hidden verification Stories keep them. Tabs Default API and the Filter Bar draft / applied counts move to the hidden DefaultApi and DraftApplied Stories; Center Overview is hidden with its direct URL kept. Story IDs are unchanged. Align the component, pattern and OrgChart docs with the pages, point the quality reference check at the DraftApplied Story, and make the P8 styles check expect no section header on the preview-only Expanded page.
7.0 KiB
Command
현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6, §7), Token 구조 원칙은 테마-토큰-가이드.md를 따른다. 이 문서는 Command 고유의 API·Token·상태·결정만 기록한다.
1. 상태와 성격
| 항목 | 내용 |
|---|---|
| 성격 | Primitive component (검색 가능한 command/list). Combobox 자체가 아니다 |
| 구현 상태 | 구현 완료 (현재 HM 규격) |
| 기준일 | 2026-10-02 |
| 기반 | shadcn/ui Command = cmdk |
| 대표 Story | Components/Search & Date/Command → All (이름 "Command") |
| 보류 | 아래 §11 |
2. 적용 근거
- 참고 근거: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Command가 없다(Search Field의 후보 목록은 다른 컴포넌트). 참고할 수치가 없었다.
- 현재 HM 규격: 아래 §3~§4. 현재 HM Semantic/Primitive로 새로 정했다. Input·Popover·Dropdown Menu Token은 참조하지 않는다(Command Input은 Command 전용 Token).
- 구현 방식: cmdk가 검색 필터링, 방향키/Home/End 이동, Enter 선택, disabled 건너뜀, 그룹, Empty, listbox/option ARIA를 소유한다. HM은 cmdk의 속성(
data-selected,data-disabled,[cmdk-group-heading])에 시각을 연결한다. - 범위: 전역 Command Palette(
CommandDialog)는 만들지 않았다(별도 고급 패턴). - 보류: §11.
3. 기본 규격 (현재 HM 규격)
| 항목 | 값 |
|---|---|
| Command | 흰 면(--hm-sem-bg-surface), 글자 --hm-sem-fg-primary, radius 4px. border·shadow 없음(Popover 등 컨테이너 안에서 쓰는 것을 전제) |
| Input | 높이 40px, padding-x 12px, 14 / 20, 아래 1px --hm-sem-stroke-input-default 구분선, 검색 아이콘 16px --hm-sem-fg-secondary, placeholder --hm-sem-fg-placeholder |
| List | 최대 높이 280px(넘치면 세로 scroll), padding 4px |
| Item | 최소 높이 36px, padding-x 12px, gap 8px, radius 2px, 14 / 20, 아이콘 16px |
| Group heading | 12 / 18 / 500, --hm-sem-fg-secondary, padding 6px 12px |
| Separator | 1px --hm-sem-stroke-input-default, List 폭 전체 |
| Shortcut | 12px, --hm-sem-fg-secondary, letter-spacing .05em |
| Empty | padding 24px 12px, 가운데, --hm-sem-fg-secondary |
4. 상태 규격
| 상태 | 값 |
|---|---|
Highlighted (data-selected="true") |
배경 Accent 45%(--hm-sem-surface-highlight), 글자 --accent-foreground. 포인터 hover와 키보드 이동이 공유 |
Disabled (data-disabled="true") |
opacity 0.6(이 컴포넌트 값, 전역 Disabled 규칙으로 승격 안 함), cursor not-allowed, 방향키 이동에서 제외 |
| Empty | 필터 결과가 없을 때 CommandEmpty 표시 |
| Focus | Input에 있음(outline-hidden). 이동은 Highlighted 면으로 표시 |
5. API
cmdk props 그대로. export: Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut.
Command:value/onValueChange(highlight),filter(사용자 정의 필터),shouldFilter,loop,label.CommandItem:value,keywords,disabled,onSelect.CommandInput: Input + 검색 아이콘 wrapper(data-slot="command-input-wrapper")를 포함한다.- 필터링은 cmdk 기본(fuzzy) 그대로이며 HM이 검색 알고리즘을 만들지 않았다.
- 접근성:
CommandInput은role="combobox",aria-expanded,aria-controls(listbox),aria-autocomplete="list";CommandList는role="listbox";CommandItem은role="option".
6. Dependency
cmdk^1.1.1 (packages/ui에 추가, shadcn Command의 기반). CENTER 패키지에는 추가하지 않았다.
7. Token
Component Mapping 위치: packages/ui/src/theme/command.css (--hm-command-*).
background, text, radius, input-*(height, padding-x, gap, font, placeholder, icon), divider-color, list-max-height|padding, item-*(height, padding-x, gap, radius, font), highlight-background|text, group-label-*, shortcut-*, empty-*, disabled-opacity. Semantic과 Primitive(--hm-warm-neutral-pale)만 참조한다. 신규 Primitive와 Semantic 없음. 이 CSS는 cmdk 내부 속성에 맞춘 일반 CSS이며 @layer를 쓰지 않는다(className으로 Command의 높이 등을 바꾸는 것은 TSX class 영역).
8. cmdk에서 유지한 항목
필터링과 정렬, 키보드(ArrowUp/Down, Home/End, Enter, disabled 건너뜀), 그룹 숨김(결과 없는 그룹), Empty, data-selected/data-disabled, listbox/option ARIA, 마우스 hover가 highlight를 옮기는 동작.
9. Storybook
- 대표 Story
All("Command"): Search + disabled item(선택 로그는 숨김Search에만 표시), Groups·icons·shortcut(CalendarIcon,UserIcon,SettingsIcon), Long list(30개, List가 scroll)를 한 페이지에 둔다. 테두리 박스는 Story 조합이다. - verification:
Search,Grouped.
10. 사용자 확정 결정
- 2026-10-02: ui-viz는 참고 자료이며 최종 기준은 현재 HM 구현과 이 문서다(작업 지시). 개별 수치에 대한 별도 결정은 없다.
11. 미확정 / 보류
- 수치(40px Input, 36px Item, 280px List 최대 높이)는 현재 HM 규격이며 디자인 확정 시 재검토.
- Command Palette(
CommandDialog, 전역 단축키 호출)는 별도 패턴으로 남겼다. - 로딩 상태(
Command.Loading), 중첩 페이지는 스타일링하지 않았다. - 선택됨(value) 표시는 Command에 없다(highlight와 다르다). Combobox가 check 아이콘으로 따로 표시한다.
- Command의 Escape는 Command 자체에서는 하는 일이 없다(Popover/Dialog 안에서는 컨테이너가 닫는다).
12. 관련 파일
packages/ui/src/components/ui/command.tsx
packages/ui/src/theme/command.css
packages/ui/package.json (dependency: cmdk)
packages/ui/src/theme.css (import)
packages/ui/src/index.ts (export)
src/components/command.stories.tsx
13. 검증 상태
npm run typecheck,npm run build: 통과(2026-10-02).- ARIA(Browser pane): Input
role=combobox·aria-expanded=true·aria-controls·aria-autocomplete=list, Listrole=listbox, Itemrole=option, disabled Item에data-disabled="true". - keyboard: 첫 항목이 처음부터 highlight, ArrowDown으로 이동(비활성 항목 건너뜀: 바나나 → 포도), Enter로 선택(
onSelect로그 갱신), 그룹 간 이동(ArrowUp 환경설정 → 프로필), End로 마지막 활성 항목(비활성결제는 제외). - 검색: 한글 "바나" 입력 시 바나나만 표시, 결과 없는 "zzz"는 Empty 문구, 입력을 지우면 전체 4개로 복귀하고 첫 항목이 highlight. Escape는 Input focus를 유지(Command 단독에서는 동작 없음).
- computed style: Input 래퍼 40px, List 최대 280px·padding 4px, Item 36px·padding
0 12px·14/20, Highlightedrgb(189,223,212), Group heading 12px/500rgb(110,103,89), Shortcut 12px. - 미확인: 긴 List의 키보드 scroll 시각, 모바일 폭(Combobox 안에서만 확인), pointer hover 시각,
CommandItem의keywords외 사용자 정의filter.