핵심 개념
키보드 패턴
Roving Tabindex, Spatial Navigation, 컴포넌트별 키보드 조작을 상세히 설명합니다.
reopt design업데이트
Roving Tabindex 상세
Roving Tabindex는 복합 위젯(Composite Widget) 내에서 단일 Tab Stop을 유지하면서 방향키로 내부 항목을 탐색하는 패턴입니다. Composite 계층이 이를 자동으로 관리합니다.
동작 원리
- 컨테이너의 모든 항목은
tabindex="-1"로 시작합니다. - 현재 활성 항목만
tabindex="0"으로 설정됩니다. - Tab 키로 컨테이너에 진입하면 활성 항목에 포커스가 갑니다.
- 방향키로 이동하면 이전 항목은
tabindex="-1", 새 항목은tabindex="0"으로 전환됩니다. - Tab 키로 컨테이너를 벗어나면 다음 Tab Stop으로 이동합니다.
tsx
// CompositeZone은 built-in roving tabindex를 활용합니다
import { CompositeZone, CompositeRow, CompositeItem } from "@reopt-ai/opt-ui";
<CompositeZone
aria-label="대시보드 그리드"
focusLoop // 마지막 항목에서 첫 항목으로 순환
focusWrap // 행 끝에서 다음 행으로 자동 이동
>
<CompositeRow>
<CompositeItem>카드 1</CompositeItem>
<CompositeItem>카드 2</CompositeItem>
</CompositeRow>
<CompositeRow>
<CompositeItem>카드 3</CompositeItem>
<CompositeItem>카드 4</CompositeItem>
</CompositeRow>
</CompositeZone>focusLoop vs focusWrap
| 속성 | 동작 | 사용 케이스 |
|---|---|---|
| focusLoop | 마지막 항목에서 화살표를 누르면 첫 항목으로 순환 | Toolbar, TabList, 사이드바 |
| focusWrap | Grid에서 행 끝에 도달하면 다음 행으로 자동 이동 | 2D Grid (DashboardGrid, 예제 목록) |
orientation 설정
CompositeZone의 orientation 속성으로 방향키 반응 축을 제어합니다.
| orientation | 반응 키 | 예시 |
|---|---|---|
| "vertical" | ↑ ↓ | 사이드바, 아코디언, 수직 메뉴 |
| "horizontal" | ← → | Toolbar, TabList, Menubar |
| 생략 (both) | ↑ ↓ ← → | Grid (DashboardGrid) |
tsx
// 수직 방향만 반응하는 사이드바
<CompositeZone orientation="vertical" focusLoop>
<CompositeItem>홈</CompositeItem>
<CompositeItem>대시보드</CompositeItem>
<CompositeItem>설정</CompositeItem>
</CompositeZone>
// 수평 방향만 반응하는 탭 목록
<TabList orientation="horizontal">
<Tab>개요</Tab>
<Tab>설정</Tab>
<Tab>로그</Tab>
</TabList>컴포넌트별 키보드 조작
| 컴포넌트 | 키보드 조작 | 특이사항 |
|---|---|---|
| CommandPalette | Cmd+K 열기, ↑↓ 항목, Enter 실행, Esc 닫기 | 타이핑으로 필터링 |
| DashboardGrid | Tab 진입, ↑↓←→ 4방향 이동, Enter 선택 | focusLoop + focusWrap |
| ContentTabs | ←→ 탭 전환, Tab 패널 진입, Home/End | 자동 활성화 |
| FaqAccordion | ↑↓ 항목, Enter/Space 토글 | 수직 Composite |
| StatusSelect | Enter 열기, ↑↓ 항목, Enter 선택, Esc 닫기 | Listbox 패턴 |
| SearchCombobox | 타이핑 필터, ↑↓ 항목, Enter 선택 | 입력 보호 (←→) |
| SettingsForm | Tab 필드 이동, Space 체크박스, ←→ 라디오 | 폼 요소 표준 |
| EnvPanel | ↑↓ 항목, Enter/Space 토글 | Disclosure 기반 |
키보드 체크리스트
새 컴포넌트를 구현할 때 확인해야 할 키보드 접근성 체크리스트입니다.
- Tab 순서가 논리적인가? (시각적 순서와 일치)
- 방향키 탐색 컨텍스트(CompositeZone)가 필요한가?
- Esc로 닫히는 요소는 포커스 복원이 되는가?
- 모든 인터랙션이 Enter/Space로 가능한가?
- 포커스 표시가 명확한가? (data-[focus-visible] 스타일)
- aria-label이 필요한 컨테이너에 부여되었는가?
전역 단축키
| 단축키 | 동작 | 구현 위치 |
|---|---|---|
| Cmd+K / Ctrl+K | 커맨드 팔레트 토글 | app/layout.tsx |
| Ctrl+Shift+F | opt-devtool overlay 토글 | app/layout.tsx |
| ↑ ↓ ← → | Spatial Navigation | spatial-nav.ts (전역) |