@reopt-ai/opt-ui 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -117,6 +117,13 @@ const store = useFormStore({ defaultValues: { name: "" } });
117
117
  | `disabledReason` | `string` | | | aria-disabled 상태에서 노출할 비활성 사유 |
118
118
  | `labels` | `NumberInputLabels` | | | 입력/증감/clear/invalid 접근성 문구 |
119
119
 
120
+ **Keyboard Shortcuts:**
121
+
122
+ | Keys | Action |
123
+ | ---- | ------------------- |
124
+ | `↑` | 값 증가 (step 단위) |
125
+ | `↓` | 값 감소 (step 단위) |
126
+
120
127
  ### Checkbox
121
128
 
122
129
  > 독립적인 체크박스 컴포넌트. 레이블, 설명, 그룹과 DOM property까지 동기화되는 indeterminate 상태를 지원합니다.
@@ -172,6 +179,14 @@ const store = useFormStore({ defaultValues: { name: "" } });
172
179
  | `description` | `string` | | | 레이블 아래 설명 텍스트 |
173
180
  | `size` | `"sm" \| "md" \| "lg"` | | "md" | 라디오 크기 |
174
181
 
182
+ **Keyboard Shortcuts:**
183
+
184
+ | Keys | Action |
185
+ | ------- | ------------------- |
186
+ | `↑ ↓` | 라디오 옵션 간 탐색 |
187
+ | `← →` | 라디오 옵션 간 탐색 |
188
+ | `Space` | 현재 옵션 선택 |
189
+
175
190
  ### Switch
176
191
 
177
192
  > 토글 스위치 컴포넌트. 3가지 크기와 레이블/설명의 명시적 접근성 연결을 지원합니다.
@@ -234,6 +249,15 @@ const store = useFormStore({ defaultValues: { name: "" } });
234
249
  | `children` | `ReactNode` | Yes | | 옵션 레이블 |
235
250
  | `className` | `string` | | | 기본 스타일 오버라이드 |
236
251
 
252
+ **Keyboard Shortcuts:**
253
+
254
+ | Keys | Action |
255
+ | --------------- | -------------- |
256
+ | `↑ ↓` | 옵션 탐색 |
257
+ | `Enter / Space` | 옵션 선택 |
258
+ | `Esc` | 팝오버 닫기 |
259
+ | `문자 입력` | Typeahead 탐색 |
260
+
237
261
  **Examples:**
238
262
 
239
263
  _기본 선택:_
@@ -316,6 +340,14 @@ import {
316
340
  | `children` | `ReactNode` | | "결과가 없습니다." | 빈 상태 메시지 |
317
341
  | `className` | `string` | | | 기본 스타일 오버라이드 |
318
342
 
343
+ **Keyboard Shortcuts:**
344
+
345
+ | Keys | Action |
346
+ | ------- | ----------- |
347
+ | `↑ ↓` | 항목 탐색 |
348
+ | `Enter` | 항목 선택 |
349
+ | `Esc` | 팝오버 닫기 |
350
+
319
351
  ### DateRangePicker
320
352
 
321
353
  > 날짜 범위 선택 컴포넌트. 프리셋, 달력 UI, 포커스 관리와 RTL 방향 탐색 아이콘을 지원합니다.
@@ -356,6 +388,17 @@ import {
356
388
  | `delimiters` | `(string \| RegExp)[]` | | [",", ";", "\n"] | 붙여넣기 시 태그를 분할할 구분자 목록 |
357
389
  | `allowDuplicates` | `boolean` | | false | 중복 태그 허용 여부 |
358
390
 
391
+ **Keyboard Shortcuts:**
392
+
393
+ | Keys | Action |
394
+ | -------------- | ---------------------------------------- |
395
+ | `Enter` | 태그 추가 |
396
+ | `Backspace` | 마지막 태그 삭제 (입력 비어있을 때) |
397
+ | `←/→` | 태그 간 이동 (Composite roving tabindex) |
398
+ | `Delete` | 포커스된 태그 삭제 |
399
+ | `Ctrl+Z` | 실행취소 |
400
+ | `Ctrl+Shift+Z` | 다시실행 |
401
+
359
402
  ### ColorPicker
360
403
 
361
404
  > 색상 선택 컴포넌트. 프리셋 팔레트와 hex 입력을 지원합니다.
@@ -1092,6 +1135,15 @@ import {
1092
1135
  | ----------- | -------- | -------- | ------- | ---------------------- |
1093
1136
  | `className` | `string` | | | 기본 스타일 오버라이드 |
1094
1137
 
1138
+ **Keyboard Shortcuts:**
1139
+
1140
+ | Keys | Action |
1141
+ | --------------- | -------------- |
1142
+ | `← →` | 메뉴 간 탐색 |
1143
+ | `↑ ↓` | 메뉴 항목 탐색 |
1144
+ | `Enter / Space` | 항목 선택/토글 |
1145
+ | `Esc` | 메뉴 닫기 |
1146
+
1095
1147
  ### DropdownMenu
1096
1148
 
1097
1149
  > Menu Core 위의 간편 래퍼. 단일 트리거 드롭다운 메뉴에 특화되었습니다.
@@ -1112,6 +1164,14 @@ import {
1112
1164
  | `onClick` | `() => void` | | | 항목 클릭 핸들러 |
1113
1165
  | `disabled` | `boolean` | | | 비활성 상태 |
1114
1166
 
1167
+ **Keyboard Shortcuts:**
1168
+
1169
+ | Keys | Action |
1170
+ | --------------- | -------------- |
1171
+ | `↑ ↓` | 메뉴 항목 탐색 |
1172
+ | `Enter / Space` | 항목 선택 |
1173
+ | `Esc` | 메뉴 닫기 |
1174
+
1115
1175
  ### Popover
1116
1176
 
1117
1177
  > Popover 프리미티브 래퍼. 트리거 요소에 연결된 플로팅 콘텐츠를 표시합니다.
@@ -1123,6 +1183,13 @@ import {
1123
1183
  | `gutter` | `number` | | 8 | 트리거와의 간격 (px) |
1124
1184
  | `className` | `string` | | | 커스텀 CSS 클래스 |
1125
1185
 
1186
+ **Keyboard Shortcuts:**
1187
+
1188
+ | Keys | Action |
1189
+ | --------------- | ------------- |
1190
+ | `Esc` | 팝오버 닫기 |
1191
+ | `Enter / Space` | 트리거 활성화 |
1192
+
1126
1193
  ### Tabs
1127
1194
 
1128
1195
  > 탭 패널 시스템. 4-part anatomy: Root, TabList, Tab, TabPanel.
@@ -1160,6 +1227,14 @@ import {
1160
1227
  | `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
1161
1228
  | `className` | `string` | | | 기본 스타일 오버라이드 |
1162
1229
 
1230
+ **Keyboard Shortcuts:**
1231
+
1232
+ | Keys | Action |
1233
+ | ------ | ------------------- |
1234
+ | `← →` | 탭 탐색 |
1235
+ | `Home` | 첫 번째 탭으로 이동 |
1236
+ | `End` | 마지막 탭으로 이동 |
1237
+
1163
1238
  ### Disclosure
1164
1239
 
1165
1240
  > 접기/펼치기 콘텐츠 영역. 3-part anatomy: Root, Trigger, Content.
@@ -1188,6 +1263,12 @@ import {
1188
1263
  | `children` | `ReactNode` | Yes | | 접히는 콘텐츠 |
1189
1264
  | `className` | `string` | | | 기본 스타일 오버라이드 |
1190
1265
 
1266
+ **Keyboard Shortcuts:**
1267
+
1268
+ | Keys | Action |
1269
+ | --------------- | -------------- |
1270
+ | `Enter / Space` | 열기/닫기 토글 |
1271
+
1191
1272
  ### Dialog
1192
1273
 
1193
1274
  > 모달 다이얼로그. 9-part anatomy: Root, Disclosure, Panel, Heading, Description, Dismiss, Header, Body, Footer.
@@ -1253,6 +1334,13 @@ import {
1253
1334
  | ---------- | ----------- | -------- | ------- | -------------- |
1254
1335
  | `children` | `ReactNode` | Yes | | 액션 버튼 영역 |
1255
1336
 
1337
+ **Keyboard Shortcuts:**
1338
+
1339
+ | Keys | Action |
1340
+ | ----- | -------------------------------- |
1341
+ | `Esc` | 다이얼로그 닫기 |
1342
+ | `Tab` | 다이얼로그 내 포커스 이동 (트랩) |
1343
+
1256
1344
  **Examples:**
1257
1345
 
1258
1346
  _모달 대화상자:_
@@ -1298,6 +1386,13 @@ import {
1298
1386
  | `swipeToDismiss` | `boolean` | | true | 가장자리 방향으로 드래그해 닫기 활성화 |
1299
1387
  | `swipeDismissThreshold` | `number` | | 80 | 닫힘 커밋에 필요한 드래그 거리(px) |
1300
1388
 
1389
+ **Keyboard Shortcuts:**
1390
+
1391
+ | Keys | Action |
1392
+ | ----- | ----------------------- |
1393
+ | `Esc` | 드로어 닫기 |
1394
+ | `Tab` | 드로어 내부 포커스 이동 |
1395
+
1301
1396
  ### Toolbar
1302
1397
 
1303
1398
  > 툴바 컨테이너 + 툴팁. 7 exports: ToolbarRoot, ToolbarContainer, ToolbarButton, ToolbarSeparator, TooltipProvider, TooltipAnchor, Tooltip.
@@ -1350,6 +1445,15 @@ import {
1350
1445
  | `children` | `ReactNode` | Yes | | 툴팁 내용 |
1351
1446
  | `className` | `string` | | | 기본 스타일 오버라이드 |
1352
1447
 
1448
+ **Keyboard Shortcuts:**
1449
+
1450
+ | Keys | Action |
1451
+ | --------------- | --------------------- |
1452
+ | `← →` | 버튼 간 탐색 |
1453
+ | `Enter / Space` | 버튼 활성화 |
1454
+ | `Home` | 첫 번째 버튼으로 이동 |
1455
+ | `End` | 마지막 버튼으로 이동 |
1456
+
1353
1457
  ### Pagination
1354
1458
 
1355
1459
  > 페이지 넘김 네비게이션. ellipsis 포함 페이지 번호, compact/count variant, totalPages/cursor pagination, Prev/Next 버튼을 제공합니다.
@@ -1397,6 +1501,15 @@ import {
1397
1501
  | `focusWrap` | `boolean` | | true | 행 끝에서 다음 행으로 이동 |
1398
1502
  | `className` | `string` | | | 컨테이너 CSS 클래스 |
1399
1503
 
1504
+ **Keyboard Shortcuts:**
1505
+
1506
+ | Keys | Action |
1507
+ | --------- | -------------------- |
1508
+ | `↑ ↓ ← →` | 2D 방향 탐색 |
1509
+ | `Home` | 첫 항목으로 이동 |
1510
+ | `End` | 마지막 항목으로 이동 |
1511
+ | `Tab` | 영역 밖으로 이동 |
1512
+
1400
1513
  ### PageHeader
1401
1514
 
1402
1515
  > 페이지 제목, 설명, 액션 슬롯을 제공하는 레이아웃 헤더 컴포넌트.
@@ -1456,30 +1569,37 @@ import {
1456
1569
 
1457
1570
  **ResizablePanelGroup:**
1458
1571
 
1459
- | Prop | Type | Required | Default | Description |
1460
- | ------------ | ---------------------------- | -------- | ------- | ---------------------------------------- |
1461
- | `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
1462
- | `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
1463
- | `autoSaveId` | `string` | | | 로컬 스토리지에 크기 상태 저장 (고유 ID) |
1464
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1572
+ | Prop | Type | Required | Default | Description |
1573
+ | ----------------- | ------------------------------------------ | -------- | ------- | --------------------------------------------------- |
1574
+ | `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
1575
+ | `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
1576
+ | `id` | `string` | | | 그룹과 defaultLayout의 패널 크기를 식별하는 고유 ID |
1577
+ | `defaultLayout` | `Record<string, number>` | | | 패널 ID별 초기 비율(0-100) |
1578
+ | `onLayoutChanged` | `(layout: Record<string, number>) => void` | | | 드래그가 끝난 뒤 확정된 레이아웃 콜백 |
1579
+ | `groupRef` | `Ref<ResizablePanelGroupHandle>` | | | 레이아웃 조회·설정을 위한 명령형 그룹 ref |
1580
+ | `autoSaveId` | `string` | | | id의 deprecated 별칭 |
1581
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1465
1582
 
1466
1583
  **ResizablePanel:**
1467
1584
 
1468
- | Prop | Type | Required | Default | Description |
1469
- | ------------- | ----------- | -------- | ------- | ----------------------------- |
1470
- | `defaultSize` | `number` | | | 초기 크기 (퍼센트, 0-100) |
1471
- | `minSize` | `number` | | | 최소 크기 (퍼센트) |
1472
- | `maxSize` | `number` | | | 최대 크기 (퍼센트) |
1473
- | `collapsible` | `boolean` | | false | 최소 크기 이하 시 접히기 허용 |
1474
- | `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
1475
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1585
+ | Prop | Type | Required | Default | Description |
1586
+ | ------------- | ------------------------------------------------------------------------------------------ | -------- | ------- | -------------------------------------------------- |
1587
+ | `defaultSize` | `number \| string` | | | 초기 크기. 숫자는 퍼센트, 문자열은 명시한 CSS 단위 |
1588
+ | `minSize` | `number \| string` | | | 최소 크기. 숫자는 퍼센트 |
1589
+ | `maxSize` | `number \| string` | | | 최대 크기. 숫자는 퍼센트 |
1590
+ | `collapsible` | `boolean` | | false | 최소 크기 이하 시 접히기 허용 |
1591
+ | `onResize` | `(size: ResizablePanelSize, id?: string \| number, previous?: ResizablePanelSize) => void` | | | 패널 크기 변경 콜백 |
1592
+ | `panelRef` | `Ref<ResizablePanelHandle>` | | | 접기·펼치기·크기 제어를 위한 명령형 패널 ref |
1593
+ | `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
1594
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1476
1595
 
1477
1596
  **ResizableHandle:**
1478
1597
 
1479
- | Prop | Type | Required | Default | Description |
1480
- | ------------ | --------- | -------- | ------- | ----------------------- |
1481
- | `withHandle` | `boolean` | | false | 시각적 드래그 핸들 표시 |
1482
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1598
+ | Prop | Type | Required | Default | Description |
1599
+ | ------------ | --------- | -------- | ------- | ---------------------------------- |
1600
+ | `withHandle` | `boolean` | | false | 시각적 드래그 핸들 표시 |
1601
+ | `disabled` | `boolean` | | | 드래그 키보드 리사이즈 비활성화 |
1602
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1483
1603
 
1484
1604
  ### VirtualList
1485
1605
 
@@ -1775,6 +1895,15 @@ const MyDashboard = createBlock<MyDashboardProps>(
1775
1895
  | `readOnly` | `boolean` | | false | 읽기 전용 모드 |
1776
1896
  | `size` | `"sm" \| "md" \| "lg"` | | "md" | 별 아이콘 크기 |
1777
1897
 
1898
+ **Keyboard Shortcuts:**
1899
+
1900
+ | Keys | Action |
1901
+ | ----------------------- | ---------------- |
1902
+ | `ArrowRight / ArrowUp` | 별점 1 증가 |
1903
+ | `ArrowLeft / ArrowDown` | 별점 1 감소 |
1904
+ | `Home` | 별점 1로 설정 |
1905
+ | `End` | 별점 최대로 설정 |
1906
+
1778
1907
  ### ErrorBoundary
1779
1908
 
1780
1909
  > React 에러 바운더리. 자식 컴포넌트 렌더 에러를 잡아 fallback UI를 표시합니다.
@@ -1821,6 +1950,15 @@ const MyDashboard = createBlock<MyDashboardProps>(
1821
1950
  | `keywords` | `string[]` | | | value에 더해 검색어와 비교할 추가 키워드 |
1822
1951
  | `onSelect` | `(value: string) => void` | | | Enter/클릭 시 호출 |
1823
1952
 
1953
+ **Keyboard Shortcuts:**
1954
+
1955
+ | Keys | Action |
1956
+ | ------------ | ---------------- |
1957
+ | `↑ ↓` | 활성 항목 이동 |
1958
+ | `Home / End` | 처음/마지막 항목 |
1959
+ | `Enter` | 활성 항목 선택 |
1960
+ | `Esc` | dialog 닫기 |
1961
+
1824
1962
  ### ShaderSurface
1825
1963
 
1826
1964
  > ogl 기반 애니메이션 WebGL 셰이더 배경. 럭셔리 프리셋(메탈릭/실크/유리 등) + 색·파라미터로 배경·카드 배경을 만든다. 정지 프레임·PNG 캡처·WebGL 폴백 지원.
@@ -9,23 +9,23 @@ generated: true
9
9
 
10
10
  ## Navigation & Layout
11
11
 
12
- | Component | Description | Key Exports |
13
- | --------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------- |
14
- | AppMenubar | 데스크톱 스타일 메뉴바. 체크박스, 라디오 메뉴 항목 지원. | `AppMenubar` |
15
- | MegaMenu | 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯. | `MegaMenu` |
16
- | SidebarNav | Composite 기반 사이드바 네비게이션. pathname 자동 동기화. | `SidebarNav` |
17
- | Sidebar | 접기/펼치기를 지원하는 compound 사이드바. Header/Content/Footer 구조 + Group/Item으로 네비게이션 구성. Ctrl+[ 단축키. | `Sidebar`, `useSidebar` |
18
- | AppShell | Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. Sidebar 컴포넌트와 조합. | `AppShell` |
19
- | ContentTabs | 탭 콘텐츠 패널. Tabs primitive 래퍼. | `ContentTabs` |
20
- | VerticalTabs | 세로 탭 레이아웃. 좌측 탭 리스트 + 우측 패널 구성입니다. | `VerticalTabs` |
21
- | FaqAccordion | FAQ 질문/답변 아코디언. Composite + Disclosure 조합. | `FaqAccordion` |
22
- | CommandPalette | Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색. | `CommandPalette` |
23
- | CommandPaletteTrigger | CommandPalette + Cmd+K 키보드 단축키 자동 바인딩. | `CommandPaletteTrigger` |
24
- | ProjectSwitcher | 프로젝트 검색 전환기. Combobox + match-sorter 퍼지 검색 지원. | `ProjectSwitcher` |
25
- | EditorToolbar | 리치 텍스트 에디터 스타일 툴바. Toolbar + Tooltip 조합. | `EditorToolbar` |
26
- | FloatingActionBar | 플로팅 액션 바. 선택된 항목에 대한 일괄 작업 버튼을 하단에 표시합니다. | `FloatingActionBar` |
27
- | TemplatePicker | 템플릿 선택기. 카테고리별 그리드와 검색을 제공하며 featured/tags 표시를 지원합니다. | `TemplatePicker` |
28
- | ThemeSwitcher | 테마 프리셋 선택기. 프리셋과 light/dark/system 모드 전환. | `ThemeSwitcher` |
12
+ | Component | Description | Key Exports |
13
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
14
+ | AppMenubar | 데스크톱 스타일 메뉴바. 체크박스, 라디오 메뉴 항목 지원. | `AppMenubar` |
15
+ | MegaMenu | 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯. | `MegaMenu` |
16
+ | SidebarNav | Composite 기반 사이드바 네비게이션. pathname 자동 동기화. | `SidebarNav` |
17
+ | Sidebar | 접기/펼치기를 지원하는 compound 사이드바. Header/Content/Footer 구조 + Group/Item으로 네비게이션 구성. Ctrl+[ 단축키. | `Sidebar`, `useSidebar` |
18
+ | AppShell | Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. AppShell.Sidebar 모든 viewport에서 기본 표시되며 반응형 숨김/Drawer 전환은 소비자가 제어합니다. | `AppShell` |
19
+ | ContentTabs | 탭 콘텐츠 패널. Tabs primitive 래퍼. | `ContentTabs` |
20
+ | VerticalTabs | 세로 탭 레이아웃. 좌측 탭 리스트 + 우측 패널 구성입니다. | `VerticalTabs` |
21
+ | FaqAccordion | FAQ 질문/답변 아코디언. Composite + Disclosure 조합. | `FaqAccordion` |
22
+ | CommandPalette | Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색. | `CommandPalette` |
23
+ | CommandPaletteTrigger | CommandPalette + Cmd+K 키보드 단축키 자동 바인딩. | `CommandPaletteTrigger` |
24
+ | ProjectSwitcher | 프로젝트 검색 전환기. Combobox + match-sorter 퍼지 검색 지원. | `ProjectSwitcher` |
25
+ | EditorToolbar | 리치 텍스트 에디터 스타일 툴바. Toolbar + Tooltip 조합. | `EditorToolbar` |
26
+ | FloatingActionBar | 플로팅 액션 바. 선택된 항목에 대한 일괄 작업 버튼을 하단에 표시합니다. | `FloatingActionBar` |
27
+ | TemplatePicker | 템플릿 선택기. 카테고리별 그리드와 검색을 제공하며 featured/tags 표시를 지원합니다. | `TemplatePicker` |
28
+ | ThemeSwitcher | 테마 프리셋 선택기. 프리셋과 light/dark/system 모드 전환. | `ThemeSwitcher` |
29
29
 
30
30
  ### AppMenubar
31
31
 
@@ -106,9 +106,17 @@ generated: true
106
106
  | `badge` | `ReactNode` | | | 우측 배지 (숫자/텍스트). 접힌 상태에서 아이콘 위 dot으로 축소 |
107
107
  | `className` | `string` | | | 커스텀 CSS 클래스 |
108
108
 
109
+ **Keyboard Shortcuts:**
110
+
111
+ | Keys | Action |
112
+ | ------------ | ------------------------------------- |
113
+ | `Ctrl+[` | 사이드바 접기/펼치기 토글 |
114
+ | `↑ ↓` | 사이드바 항목 간 이동 |
115
+ | `Home / End` | 첫 번째/마지막 사이드바 항목으로 이동 |
116
+
109
117
  ### AppShell
110
118
 
111
- > Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. Sidebar 컴포넌트와 조합.
119
+ > Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. AppShell.Sidebar 모든 viewport에서 기본 표시되며 반응형 숨김/Drawer 전환은 소비자가 제어합니다.
112
120
 
113
121
  **Import:** `import { AppShell } from "@reopt-ai/opt-ui"`
114
122
  **Dependencies:** sidebar (shells), page-header (core)
@@ -298,6 +306,17 @@ import { AppShell } from "@reopt-ai/opt-ui";
298
306
  | `bar` | `(row: T) => number` | | | 인라인 프로그레스 바 비율(0-1) 계산 함수. 범위 밖/NaN은 보정 |
299
307
  | `barColor` | `string` | | "bg-accent" | 인라인 바 색상 클래스 |
300
308
 
309
+ **Keyboard Shortcuts:**
310
+
311
+ | Keys | Action |
312
+ | -------------------------------- | ---------------------------------- |
313
+ | `↑ ↓` | 행 탐색 |
314
+ | `← →` | 셀 탐색 |
315
+ | `Enter / Space` | 정렬 가능한 헤더 또는 행 활성화 |
316
+ | `리사이즈 핸들: ← →` | 컬럼 너비를 10px 단위로 조절 |
317
+ | `리사이즈 핸들: Shift+← Shift+→` | 컬럼 너비를 40px 단위로 조절 |
318
+ | `리사이즈 핸들: Home / End` | 컬럼 너비를 최솟값/최댓값으로 이동 |
319
+
301
320
  **Examples:**
302
321
 
303
322
  _기본 테이블:_
@@ -401,6 +420,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
401
420
  | `stats` | `StatCard[]` | Yes | | 통계 데이터 배열. { id, title, value, change, trend } |
402
421
  | `columns` | `number` | | 3 | 행당 컬럼 수 |
403
422
 
423
+ **Keyboard Shortcuts:**
424
+
425
+ | Keys | Action |
426
+ | --------- | ------------------ |
427
+ | `↑ ↓ ← →` | 카드 간 2D 탐색 |
428
+ | `Tab` | 다음 섹션으로 이동 |
429
+
404
430
  ### SummaryRow
405
431
 
406
432
  > 통계 요약 행. StatCard 그리드 레이아웃을 표준화합니다. loading 시 SkeletonCard 표시.
@@ -495,6 +521,14 @@ import { DataTable } from "@reopt-ai/opt-ui";
495
521
  | `onTaskStatusChange` | `(task: TaskDef, completed: boolean) => void` | | | 완료 상태 변경 핸들러 |
496
522
  | `showSubtasks` | `boolean` | | false | 하위 작업 표시 여부 |
497
523
 
524
+ **Keyboard Shortcuts:**
525
+
526
+ | Keys | Action |
527
+ | ------- | ------------ |
528
+ | `↑ ↓` | 작업 간 이동 |
529
+ | `Enter` | 작업 선택 |
530
+ | `Space` | 완료 토글 |
531
+
498
532
  ### ActivityFeed
499
533
 
500
534
  > 활동 피드/로그 컴포넌트. 타임라인 스타일, 상대 시간 표시.
@@ -511,6 +545,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
511
545
  | `layout` | `"list" \| "compact"` | | "list" | 시간 표시 레이아웃 모드 |
512
546
  | `renderActions` | `(activity: ActivityDef) => ReactNode` | | | 각 활동 항목 우측 액션 슬롯 렌더 함수 |
513
547
 
548
+ **Keyboard Shortcuts:**
549
+
550
+ | Keys | Action |
551
+ | ------- | ------------ |
552
+ | `↑ ↓` | 활동 간 이동 |
553
+ | `Enter` | 활동 선택 |
554
+
514
555
  ### TeamMemberList
515
556
 
516
557
  > 팀원 목록 컴포넌트. 온라인 상태, 다양한 레이아웃(list, compact, avatars-only) 지원.
@@ -526,6 +567,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
526
567
  | `maxDisplay` | `number` | | | 최대 표시 인원 |
527
568
  | `onMemberClick` | `(member: TeamMemberDef) => void` | | | 팀원 클릭 핸들러 |
528
569
 
570
+ **Keyboard Shortcuts:**
571
+
572
+ | Keys | Action |
573
+ | ------- | ------------ |
574
+ | `↑ ↓` | 팀원 간 이동 |
575
+ | `Enter` | 팀원 선택 |
576
+
529
577
  ### KanbanBoard
530
578
 
531
579
  > 칸반 보드. HTML5 DnD로 카드를 컬럼 간 드래그&드롭.
@@ -579,7 +627,7 @@ import { DataTable } from "@reopt-ai/opt-ui";
579
627
  | StatusSelect | 색상 인디케이터가 있는 상태 선택 드롭다운. | `StatusSelect` |
580
628
  | BranchSelect | Git 브랜치 선택 드롭다운. Select primitive 래퍼. | `BranchSelect` |
581
629
  | FilterBar | 필터링 바 컴포넌트. 검색, 선택, 다중 선택 필터 지원. | `FilterBar` |
582
- | SavedFilters | 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI. | `SavedFilters` |
630
+ | SavedFilters | 필터 프리셋 관리. 키보드 목록 탐색, 현재 필터 저장, 안전한 삭제 확인 흐름을 제공하는 Popover UI. | `SavedFilters` |
583
631
  | QuickActions | 빠른 작업 패널. 그리드/리스트 레이아웃, 단축키 표시 지원. | `QuickActions` |
584
632
  | TimeRangeSelector | 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용. | `TimeRangeSelector` |
585
633
  | ComparisonSelector | 비교 선택기. 고유 레이블이 연결된 Select × 2 + Swap 버튼 조합. CohortComparison, FunnelAnalysis 등에서 사용합니다. | `ComparisonSelector` |
@@ -697,19 +745,43 @@ const filters = [
697
745
 
698
746
  ### SavedFilters
699
747
 
700
- > 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI.
748
+ > 필터 프리셋 관리. 키보드 목록 탐색, 현재 필터 저장, 안전한 삭제 확인 흐름을 제공하는 Popover UI.
701
749
 
702
750
  **Import:** `import { SavedFilters } from "@reopt-ai/opt-ui"`
703
- **Dependencies:** popover (core), input (core)
704
-
705
- | Prop | Type | Required | Default | Description |
706
- | ---------------- | ---------------------------------------------------------- | -------- | ------- | -------------------- |
707
- | `currentFilters` | `Record<string, unknown>` | Yes | | 현재 적용 중인 필터 |
708
- | `presets` | `FilterPreset[]` | Yes | | 저장된 프리셋 목록 |
709
- | `onSavePreset` | `(name: string, filters: Record<string, unknown>) => void` | Yes | | 프리셋 저장 콜백 |
710
- | `onLoadPreset` | `(preset: FilterPreset) => void` | Yes | | 프리셋 불러오기 콜백 |
711
- | `onDeletePreset` | `(presetId: string) => void` | Yes | | 프리셋 삭제 콜백 |
712
- | `className` | `string` | | | 커스텀 CSS 클래스 |
751
+ **Dependencies:** popover (core), input (core), button (core)
752
+
753
+ **SavedFilters:**
754
+
755
+ | Prop | Type | Required | Default | Description |
756
+ | ---------------- | ---------------------------------------------------------- | -------- | ------- | -------------------------------------------------- |
757
+ | `currentFilters` | `Record<string, unknown>` | Yes | | 현재 적용 중인 필터 |
758
+ | `presets` | `FilterPreset[]` | Yes | | 저장된 프리셋 목록 |
759
+ | `onSavePreset` | `(name: string, filters: Record<string, unknown>) => void` | Yes | | 프리셋 저장 콜백 |
760
+ | `onLoadPreset` | `(preset: FilterPreset) => void` | Yes | | 프리셋 불러오기 콜백 |
761
+ | `onDeletePreset` | `(presetId: string) => void` | Yes | | 프리셋 삭제 콜백 |
762
+ | `labels` | `SavedFiltersLabels` | | | 트리거, 빈 상태, 저장 및 삭제 확인 문구 오버라이드 |
763
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
764
+
765
+ **SavedFiltersLabels:**
766
+
767
+ | Prop | Type | Required | Default | Description |
768
+ | -------------------- | --------------------------- | -------- | ------------------ | --------------------------------------- |
769
+ | `triggerLabel` | `(count: number) => string` | | | 저장된 프리셋 수를 포함한 트리거 레이블 |
770
+ | `emptyMessage` | `string` | | "No saved filters" | 프리셋이 없을 때 표시할 메시지 |
771
+ | `deleteLabel` | `(name: string) => string` | | | 프리셋 삭제 버튼의 접근 가능한 이름 |
772
+ | `namePlaceholder` | `string` | | "Filter name…" | 새 프리셋 이름 입력 안내 |
773
+ | `saveLabel` | `string` | | "Save" | 새 프리셋 저장 버튼 레이블 |
774
+ | `confirmDeleteLabel` | `string` | | "Confirm" | 삭제 확인 버튼 레이블 |
775
+ | `cancelDeleteLabel` | `string` | | "Cancel" | 삭제 취소 버튼 레이블 |
776
+
777
+ **Keyboard Shortcuts:**
778
+
779
+ | Keys | Action |
780
+ | ------------ | ------------------------------------------- |
781
+ | `↑ ↓` | 저장된 프리셋 간 이동 |
782
+ | `Home / End` | 첫 번째/마지막 프리셋으로 이동 |
783
+ | `Enter` | 프리셋 불러오기 또는 새 프리셋 저장 |
784
+ | `Escape` | 삭제 확인 취소 후 삭제 버튼으로 포커스 복귀 |
713
785
 
714
786
  ### QuickActions
715
787
 
@@ -725,6 +797,14 @@ const filters = [
725
797
  | `layout` | `"grid" \| "list"` | | "grid" | 레이아웃 모드 |
726
798
  | `columns` | `2 \| 3 \| 4` | | 3 | 그리드 컬럼 수 |
727
799
 
800
+ **Keyboard Shortcuts:**
801
+
802
+ | Keys | Action |
803
+ | --------- | --------------------- |
804
+ | `↑ ↓ ← →` | 그리드에서 4방향 탐색 |
805
+ | `↑ ↓` | 리스트에서 수직 탐색 |
806
+ | `Enter` | 작업 실행 |
807
+
728
808
  ### TimeRangeSelector
729
809
 
730
810
  > 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용.
@@ -1206,6 +1286,13 @@ const fields = [
1206
1286
  | `onStepMove` | `(stepId: string, row: number, col: number) => void` | | | 화살표 키 이동 핸들러 |
1207
1287
  | `onSelectStep` | `(step: WorkflowCanvasStep) => void` | | | 스텝 선택 핸들러 |
1208
1288
 
1289
+ **Keyboard Shortcuts:**
1290
+
1291
+ | Keys | Action |
1292
+ | --------- | ----------------------------------- |
1293
+ | `↑ ↓ ← →` | 선택 스텝 이동 (onStepMove 제공 시) |
1294
+ | `Enter` | 스텝 선택 |
1295
+
1209
1296
  ## Other
1210
1297
 
1211
1298
  | Component | Description | Key Exports |
@@ -1249,6 +1336,13 @@ const fields = [
1249
1336
  | `onFailureClick` | `(failure: FailureItem) => void` | | | 실패 항목 클릭 핸들러 |
1250
1337
  | `renderActions` | `(failure: FailureItem) => ReactNode` | | | 각 항목 우측 액션 슬롯 렌더 함수 |
1251
1338
 
1339
+ **Keyboard Shortcuts:**
1340
+
1341
+ | Keys | Action |
1342
+ | ------- | ----------------- |
1343
+ | `↑ ↓` | 실패 항목 간 이동 |
1344
+ | `Enter` | 실패 항목 선택 |
1345
+
1252
1346
  ### KeyValueEditor
1253
1347
 
1254
1348
  > 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다.
@@ -1267,6 +1361,12 @@ const fields = [
1267
1361
  | `renderActions` | `(entry: KeyValueEntry, index: number) => ReactNode` | | | 항목별 커스텀 액션 슬롯 |
1268
1362
  | `validateKey` | `(key: string, entries: KeyValueEntry[]) => string \| undefined` | | | 키 유효성 검사 함수 |
1269
1363
 
1364
+ **Keyboard Shortcuts:**
1365
+
1366
+ | Keys | Action |
1367
+ | ----- | ------------------ |
1368
+ | `Tab` | 키/값 필드 간 이동 |
1369
+
1270
1370
  ### AuditTimeline
1271
1371
 
1272
1372
  > 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰.
@@ -1315,6 +1415,13 @@ const fields = [
1315
1415
  | `showHint` | `boolean` | | true | Shift+Enter 힌트 표시 여부 |
1316
1416
  | `labels` | `ChatInputLabels` | | | i18n 라벨 오버라이드 |
1317
1417
 
1418
+ **Keyboard Shortcuts:**
1419
+
1420
+ | Keys | Action |
1421
+ | --------------- | ----------- |
1422
+ | `Enter` | 메시지 전송 |
1423
+ | `Shift + Enter` | 줄바꿈 |
1424
+
1318
1425
  **Examples:**
1319
1426
 
1320
1427
  _채팅 입력:_
@@ -18,6 +18,10 @@ All imports from `@reopt-ai/opt-ui`.
18
18
 
19
19
  Full application chrome: header, collapsible sidebar, main content area.
20
20
 
21
+ `AppShell.Sidebar` stays mounted and visible at every viewport size. Apply a
22
+ responsive `className` such as `hidden xl:block`, or replace it with a mobile
23
+ drawer, when the product should hide navigation on smaller screens.
24
+
21
25
  ```tsx
22
26
  "use client";
23
27
 
@@ -186,7 +186,9 @@ Dark mode uses the `[data-theme="preset-dark"]` selector. The compound theme sys
186
186
 
187
187
  /* Dark mode */
188
188
  [data-theme="default-dark"] {
189
- --opt-surface: hsl(204 4% 16%);
189
+ --opt-surface: hsl(204 5% 7%);
190
+ --opt-surface-raised: hsl(204 5% 9%);
191
+ --opt-surface-overlay: hsl(204 5% 12%);
190
192
  --opt-text: hsl(0 0% 82%);
191
193
  }
192
194
  ```
@@ -1043,19 +1043,19 @@ var ID_REGISTRY = Object.freeze({
1043
1043
  layer: "shells",
1044
1044
  metaName: "ReportBuilder"
1045
1045
  },
1046
- "7QWEQ": {
1046
+ "6Z22W": {
1047
1047
  slug: "resizable",
1048
1048
  exportName: "ResizableHandle",
1049
1049
  layer: "core",
1050
1050
  metaName: "Resizable"
1051
1051
  },
1052
- QRQV9: {
1052
+ "88X4V": {
1053
1053
  slug: "resizable",
1054
1054
  exportName: "ResizablePanel",
1055
1055
  layer: "core",
1056
1056
  metaName: "Resizable"
1057
1057
  },
1058
- MW6TZ: {
1058
+ BM5RR: {
1059
1059
  slug: "resizable",
1060
1060
  exportName: "ResizablePanelGroup",
1061
1061
  layer: "core",
@@ -1067,7 +1067,7 @@ var ID_REGISTRY = Object.freeze({
1067
1067
  layer: "shells",
1068
1068
  metaName: "RichTextEditor"
1069
1069
  },
1070
- DAB08: {
1070
+ SPRCB: {
1071
1071
  slug: "saved-filters",
1072
1072
  exportName: "SavedFilters",
1073
1073
  layer: "shells",
@@ -1570,11 +1570,11 @@ var SLUG_TO_ID = Object.freeze({
1570
1570
  "radio-group.Radio": "HY7YG",
1571
1571
  "radio-group.RadioGroup": "2F20H",
1572
1572
  "report-builder.ReportBuilder": "K9STD",
1573
- "resizable.ResizableHandle": "7QWEQ",
1574
- "resizable.ResizablePanel": "QRQV9",
1575
- "resizable.ResizablePanelGroup": "MW6TZ",
1573
+ "resizable.ResizableHandle": "6Z22W",
1574
+ "resizable.ResizablePanel": "88X4V",
1575
+ "resizable.ResizablePanelGroup": "BM5RR",
1576
1576
  "rich-text-editor.RichTextEditor": "441JQ",
1577
- "saved-filters.SavedFilters": "DAB08",
1577
+ "saved-filters.SavedFilters": "SPRCB",
1578
1578
  "scroll-area.ScrollArea": "A9X4K",
1579
1579
  "search-combobox.SearchCombobox": "KH4TQ",
1580
1580
  "section.Section": "M3QXW",