reopt designreopt design
DocsExploreToolsPricingBuilder
시작하기
개요
시작하기
Next.js 설치
Private install
핵심 개념
아키텍처
컴포지션 패턴
접근성
키보드 패턴
스타일링
테마 시스템
고급 패턴
구축·운영
Skills
AI 연동
CLI (opt surface add)
의존 그래프
도구
Canvas 카탈로그
Theme Builder
Form Builder
템플릿
템플릿
릴리즈
릴리즈 노트
Oopt-ui
reopt designreopt design

AI 시대를 위한 디자인 시스템

  • 문서
  • 가격
  • 릴리즈 노트
  • GitHub
  • 서비스 약관
  • 개인정보처리방침

© 2026 reopt-ai. All rights reserved.

핵심 개념
  1. 문서
  2. /
  3. 핵심 개념
  4. /
  5. 키보드 패턴

키보드 패턴

Roving Tabindex, Spatial Navigation, 컴포넌트별 키보드 조작을 상세히 설명합니다.

reopt design · 업데이트 2026년 6월 26일

Roving Tabindex 상세

Roving Tabindex는 복합 위젯(Composite Widget) 내에서 단일 Tab Stop을 유지하면서 방향키로 내부 항목을 탐색하는 패턴입니다. Composite 계층이 이를 자동으로 관리합니다.

동작 원리

  1. 컨테이너의 모든 항목은 tabindex="-1"로 시작합니다.
  2. 현재 활성 항목만 tabindex="0"으로 설정됩니다.
  3. Tab 키로 컨테이너에 진입하면 활성 항목에 포커스가 갑니다.
  4. 방향키로 이동하면 이전 항목은 tabindex="-1", 새 항목은 tabindex="0"으로 전환됩니다.
  5. 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, 사이드바
focusWrapGrid에서 행 끝에 도달하면 다음 행으로 자동 이동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>

Spatial Navigation 상세

Spatial Navigation은 Composite 외부에서 방향키로 가장 가까운 포커스 가능 요소로 이동하는 시스템입니다.

거리 점수 계산

각 방향의 후보에 대해 점수를 계산하고, 가장 낮은 점수의 요소로 이동합니다.

ts
// 점수 계산 공식
score = distance + (alignment_offset * penalty)

// distance: 두 요소 중심 간 직선 거리
// alignment_offset: 이동 방향의 수직축 오프셋
// penalty: 정렬 페널티 계수 (기본 0.5)

// 예시: 오른쪽으로 이동할 때
// - 완벽히 정렬된 요소 (Y축 차이 0): score = 100 + 0 = 100
// - 약간 어긋난 요소 (Y축 차이 50): score = 100 + 25 = 125
// → 정렬된 요소가 선택됨

우선순위

  1. Composite 계열이 먼저 처리 (defaultPrevented)
  2. 입력 필드 보호 방향은 건너뜀
  3. Trapped Context(Dialog, Menu) 내부는 건너뜀
  4. 위 조건을 통과하면 Spatial Navigation이 동작

컴포넌트별 키보드 조작

컴포넌트키보드 조작특이사항
CommandPaletteCmd+K 열기, ↑↓ 항목, Enter 실행, Esc 닫기타이핑으로 필터링
DashboardGridTab 진입, ↑↓←→ 4방향 이동, Enter 선택focusLoop + focusWrap
ContentTabs←→ 탭 전환, Tab 패널 진입, Home/End자동 활성화
FaqAccordion↑↓ 항목, Enter/Space 토글수직 Composite
StatusSelectEnter 열기, ↑↓ 항목, Enter 선택, Esc 닫기Listbox 패턴
SearchCombobox타이핑 필터, ↑↓ 항목, Enter 선택입력 보호 (←→)
SettingsFormTab 필드 이동, Space 체크박스, ←→ 라디오폼 요소 표준
EnvPanel↑↓ 항목, Enter/Space 토글Disclosure 기반

키보드 체크리스트

새 컴포넌트를 구현할 때 확인해야 할 키보드 접근성 체크리스트입니다.

  • Tab 순서가 논리적인가? (시각적 순서와 일치)
  • 방향키 탐색 컨텍스트(CompositeZone)가 필요한가?
  • Esc로 닫히는 요소는 포커스 복원이 되는가?
  • 모든 인터랙션이 Enter/Space로 가능한가?
  • 포커스 표시가 명확한가? (data-[focus-visible] 스타일)
  • aria-label이 필요한 컨테이너에 부여되었는가?

전역 단축키

단축키동작구현 위치
Cmd+K / Ctrl+K커맨드 팔레트 토글app/layout.tsx
Ctrl+Shift+Fopt-devtool overlay 토글app/layout.tsx
↑ ↓ ← →Spatial Navigationspatial-nav.ts (전역)
Previous접근성Spatial Navigation, 포커스 관리, WAI-ARIA 역할, 키보드 단축키핵심 개념
접근성 페이지로 이동
Next스타일링data-attribute 셀렉터, className 오버라이드, 다크모드, 애니메이션핵심 개념