@reopt-ai/opt-ui 1.4.1 → 1.6.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.
Files changed (89) hide show
  1. package/COMPONENT_CATALOG.md +374 -84
  2. package/README.md +28 -7
  3. package/dist/app.css +146 -0
  4. package/dist/core/index.cjs +164 -324
  5. package/dist/core/index.d.cts +3 -5
  6. package/dist/core/index.d.ts +3 -5
  7. package/dist/core/index.js +3 -323
  8. package/dist/docs/01-getting-started.md +25 -5
  9. package/dist/docs/02-components/01-core.md +192 -46
  10. package/dist/docs/02-components/02-visuals.md +1 -1
  11. package/dist/docs/02-components/03-shells.md +177 -42
  12. package/dist/docs/02-components/04-surfaces.md +1 -1
  13. package/dist/docs/02-components/index.md +1 -1
  14. package/dist/docs/03-recipes/03-layouts.md +20 -12
  15. package/dist/docs/04-theming.md +3 -1
  16. package/dist/docs/05-migration/01-breaking-changes.md +28 -0
  17. package/dist/id-registry.cjs +1899 -1872
  18. package/dist/id-registry.d.cts +13 -10
  19. package/dist/id-registry.d.cts.map +1 -0
  20. package/dist/id-registry.d.ts +13 -10
  21. package/dist/id-registry.d.ts.map +1 -0
  22. package/dist/id-registry.js +1897 -1871
  23. package/dist/id-registry.js.map +1 -0
  24. package/dist/id-registry.json +44 -44
  25. package/dist/index.cjs +8294 -9613
  26. package/dist/index.d.cts +1486 -1438
  27. package/dist/index.d.cts.map +1 -0
  28. package/dist/index.d.ts +1486 -1438
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +7933 -9600
  31. package/dist/index.js.map +1 -0
  32. package/dist/meta.cjs +7461 -6765
  33. package/dist/meta.d.cts.map +1 -0
  34. package/dist/meta.d.ts.map +1 -0
  35. package/dist/meta.js +7460 -6736
  36. package/dist/meta.js.map +1 -0
  37. package/dist/pagination-By7Ozv3U.js +3788 -0
  38. package/dist/pagination-By7Ozv3U.js.map +1 -0
  39. package/dist/pagination-Uv3CnGJz.cjs +4677 -0
  40. package/dist/shader-surface-BK1GMt5_.d.cts +1788 -0
  41. package/dist/shader-surface-BK1GMt5_.d.cts.map +1 -0
  42. package/dist/shader-surface-BWhO2xkk.js +3715 -0
  43. package/dist/shader-surface-BWhO2xkk.js.map +1 -0
  44. package/dist/shader-surface-DIVWtpFl.d.ts +1788 -0
  45. package/dist/shader-surface-DIVWtpFl.d.ts.map +1 -0
  46. package/dist/shader-surface-DxLLfrE6.cjs +4108 -0
  47. package/dist/shells/index.cjs +51 -65
  48. package/dist/shells/index.d.cts +4 -5
  49. package/dist/shells/index.d.ts +4 -5
  50. package/dist/shells/index.js +3 -64
  51. package/dist/tailwind.css +54 -5
  52. package/dist/theme/presets/default.css +12 -12
  53. package/dist/theme/server.cjs +310 -0
  54. package/dist/theme/server.d.cts +117 -0
  55. package/dist/theme/server.d.cts.map +1 -0
  56. package/dist/theme/server.d.ts +117 -0
  57. package/dist/theme/server.d.ts.map +1 -0
  58. package/dist/theme/server.js +287 -0
  59. package/dist/theme/server.js.map +1 -0
  60. package/dist/types-D0FlcYnM.d.cts +301 -0
  61. package/dist/types-D0FlcYnM.d.cts.map +1 -0
  62. package/dist/types-D0FlcYnM.d.ts +301 -0
  63. package/dist/types-D0FlcYnM.d.ts.map +1 -0
  64. package/dist/visuals/index.cjs +10 -4
  65. package/dist/visuals/index.d.cts +2 -1
  66. package/dist/visuals/index.d.ts +2 -1
  67. package/dist/visuals/index.js +1 -2
  68. package/dist/workflow-canvas-3Jeevkgy.cjs +2599 -0
  69. package/dist/workflow-canvas-BGBAcjf-.js +2403 -0
  70. package/dist/workflow-canvas-BGBAcjf-.js.map +1 -0
  71. package/dist/workflow-canvas-Bar_O2SQ.d.ts +494 -0
  72. package/dist/workflow-canvas-Bar_O2SQ.d.ts.map +1 -0
  73. package/dist/workflow-canvas-DghDRtHn.d.cts +494 -0
  74. package/dist/workflow-canvas-DghDRtHn.d.cts.map +1 -0
  75. package/package.json +24 -8
  76. package/dist/chunk-3GWWZKX7.js +0 -38
  77. package/dist/chunk-AFF2HPE5.cjs +0 -5008
  78. package/dist/chunk-ELWICXYY.js +0 -4745
  79. package/dist/chunk-N4NDU5ET.cjs +0 -4745
  80. package/dist/chunk-ONE3C5RV.cjs +0 -38
  81. package/dist/chunk-QWBHD54V.js +0 -3218
  82. package/dist/chunk-RBM2RNC2.js +0 -5008
  83. package/dist/chunk-X5WCXJAF.cjs +0 -3218
  84. package/dist/index-BZ_lBlO1.d.ts +0 -474
  85. package/dist/index-BuvxoWHf.d.cts +0 -474
  86. package/dist/index-DlAcuvQp.d.cts +0 -1686
  87. package/dist/index-Slu5hOj1.d.ts +0 -1686
  88. package/dist/types-D4-0lwaE.d.cts +0 -298
  89. package/dist/types-D4-0lwaE.d.ts +0 -298
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- DEPRECATED: Prefer dist/docs/02-components/ for per-layer reference. -->
4
4
  <!-- Auto-generated from ComponentMeta. Do not edit. -->
5
- <!-- Version: 1.4.1 -->
5
+ <!-- Version: 1.6.0 -->
6
6
 
7
7
  ## Quick Stats
8
8
 
@@ -184,7 +184,7 @@
184
184
  | Toggle | 눌림(pressed) 두 상태 버튼. 단독 사용하거나 ToggleGroup으로 묶어 단일/다중 선택을 만든다. | `Toggle`, `ToggleGroup` |
185
185
  | Accordion | 수직으로 쌓인 펼침/접힘 패널. single(한 개)/multiple(여러 개) 모드와 collapsible 지원. | `AccordionRoot`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` |
186
186
  | Meter | 범위 내 스칼라 측정값 게이지 (디스크 사용량·점수·용량 등). role=meter로 작업 진행률(Progress)과 구분된다. | `Meter` |
187
- | BlockLayout | Block 루트 레이아웃. flex + 기본 section spacing 적용, loading prop으로 LoadingOverlay 자동 래핑. | `BlockLayout` |
187
+ | BlockLayout | Block 루트 레이아웃. 자식 section spacing 선택적 시맨틱 inset을 제공하고 loading prop으로 LoadingOverlay 자동 래핑합니다. | `BlockLayout` |
188
188
  | createBlock | Block 팩토리 함수. BlockLayout 래핑을 구조적으로 강제하여 loading/className 처리를 자동화합니다. | `createBlock` |
189
189
  | StarRating | 1~N점 별점을 선택하는 인터랙티브 레이팅 입력. 읽기 전용 표시도 지원. | `StarRating` |
190
190
  | ErrorBoundary | React 에러 바운더리. 자식 컴포넌트 렌더 에러를 잡아 fallback UI를 표시합니다. | `ErrorBoundary` |
@@ -200,23 +200,23 @@
200
200
 
201
201
  ### Navigation & Layout
202
202
 
203
- | Component | Description | Key Exports |
204
- | --------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------- |
205
- | AppMenubar | 데스크톱 스타일 메뉴바. 체크박스, 라디오 메뉴 항목 지원. | `AppMenubar` |
206
- | MegaMenu | 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯. | `MegaMenu` |
207
- | SidebarNav | Composite 기반 사이드바 네비게이션. pathname 자동 동기화. | `SidebarNav` |
208
- | Sidebar | 접기/펼치기를 지원하는 compound 사이드바. Header/Content/Footer 구조 + Group/Item으로 네비게이션 구성. Ctrl+[ 단축키. | `Sidebar`, `useSidebar` |
209
- | AppShell | Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. Sidebar 컴포넌트와 조합. | `AppShell` |
210
- | ContentTabs | 탭 콘텐츠 패널. Tabs primitive 래퍼. | `ContentTabs` |
211
- | VerticalTabs | 세로 탭 레이아웃. 좌측 탭 리스트 + 우측 패널 구성입니다. | `VerticalTabs` |
212
- | FaqAccordion | FAQ 질문/답변 아코디언. Composite + Disclosure 조합. | `FaqAccordion` |
213
- | CommandPalette | Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색. | `CommandPalette` |
214
- | CommandPaletteTrigger | CommandPalette + Cmd+K 키보드 단축키 자동 바인딩. | `CommandPaletteTrigger` |
215
- | ProjectSwitcher | 프로젝트 검색 전환기. Combobox + match-sorter 퍼지 검색 지원. | `ProjectSwitcher` |
216
- | EditorToolbar | 리치 텍스트 에디터 스타일 툴바. Toolbar + Tooltip 조합. | `EditorToolbar` |
217
- | FloatingActionBar | 플로팅 액션 바. 선택된 항목에 대한 일괄 작업 버튼을 하단에 표시합니다. | `FloatingActionBar` |
218
- | TemplatePicker | 템플릿 선택기. 카테고리별 그리드와 검색을 제공하며 featured/tags 표시를 지원합니다. | `TemplatePicker` |
219
- | ThemeSwitcher | 테마 프리셋 선택기. 프리셋과 light/dark/system 모드 전환. | `ThemeSwitcher` |
203
+ | Component | Description | Key Exports |
204
+ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
205
+ | AppMenubar | 데스크톱 스타일 메뉴바. 체크박스, 라디오 메뉴 항목 지원. | `AppMenubar` |
206
+ | MegaMenu | 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯. | `MegaMenu` |
207
+ | SidebarNav | Composite 기반 사이드바 네비게이션. pathname 자동 동기화. | `SidebarNav` |
208
+ | Sidebar | 접기/펼치기를 지원하는 compound 사이드바. Header/Content/Footer 구조 + Group/Item으로 네비게이션 구성. Ctrl+[ 단축키. | `Sidebar`, `useSidebar` |
209
+ | AppShell | Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. AppShell.Sidebar 모든 viewport에서 기본 표시되며 반응형 숨김/Drawer 전환은 소비자가 제어합니다. | `AppShell` |
210
+ | ContentTabs | 탭 콘텐츠 패널. Tabs primitive 래퍼. | `ContentTabs` |
211
+ | VerticalTabs | 세로 탭 레이아웃. 좌측 탭 리스트 + 우측 패널 구성입니다. | `VerticalTabs` |
212
+ | FaqAccordion | FAQ 질문/답변 아코디언. Composite + Disclosure 조합. | `FaqAccordion` |
213
+ | CommandPalette | Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색. | `CommandPalette` |
214
+ | CommandPaletteTrigger | CommandPalette + Cmd+K 키보드 단축키 자동 바인딩. | `CommandPaletteTrigger` |
215
+ | ProjectSwitcher | 프로젝트 검색 전환기. Combobox + match-sorter 퍼지 검색 지원. | `ProjectSwitcher` |
216
+ | EditorToolbar | 리치 텍스트 에디터 스타일 툴바. Toolbar + Tooltip 조합. | `EditorToolbar` |
217
+ | FloatingActionBar | 플로팅 액션 바. 선택된 항목에 대한 일괄 작업 버튼을 하단에 표시합니다. | `FloatingActionBar` |
218
+ | TemplatePicker | 템플릿 선택기. 카테고리별 그리드와 검색을 제공하며 featured/tags 표시를 지원합니다. | `TemplatePicker` |
219
+ | ThemeSwitcher | 테마 프리셋 선택기. 프리셋과 light/dark/system 모드 전환. | `ThemeSwitcher` |
220
220
 
221
221
  ### Data Display
222
222
 
@@ -254,7 +254,7 @@
254
254
  | StatusSelect | 색상 인디케이터가 있는 상태 선택 드롭다운. | `StatusSelect` |
255
255
  | BranchSelect | Git 브랜치 선택 드롭다운. Select primitive 래퍼. | `BranchSelect` |
256
256
  | FilterBar | 필터링 바 컴포넌트. 검색, 선택, 다중 선택 필터 지원. | `FilterBar` |
257
- | SavedFilters | 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI. | `SavedFilters` |
257
+ | SavedFilters | 필터 프리셋 관리. 키보드 목록 탐색, 현재 필터 저장, 안전한 삭제 확인 흐름을 제공하는 Popover UI. | `SavedFilters` |
258
258
  | QuickActions | 빠른 작업 패널. 그리드/리스트 레이아웃, 단축키 표시 지원. | `QuickActions` |
259
259
  | TimeRangeSelector | 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용. | `TimeRangeSelector` |
260
260
  | ComparisonSelector | 비교 선택기. 고유 레이블이 연결된 Select × 2 + Swap 버튼 조합. CohortComparison, FunnelAnalysis 등에서 사용합니다. | `ComparisonSelector` |
@@ -373,9 +373,11 @@
373
373
 
374
374
  **Import:** `import { Kbd } from "@reopt-ai/opt-ui"`
375
375
 
376
- | Prop | Type | Required | Default | Description |
377
- | ---------- | ----------- | -------- | ------- | -------------------- |
378
- | `children` | `ReactNode` | Yes | | 표시할 단축키 텍스트 |
376
+ | Prop | Type | Required | Default | Description |
377
+ | ----------- | ----------- | -------- | ------- | ------------------------------------------------------------------------------- |
378
+ | `children` | `ReactNode` | Yes | | 표시할 단축키 텍스트 |
379
+ | `hint` | `boolean` | | | 인라인 힌트 배지로 표시. `data-shortcut-hints="hidden"`일 때 숨겨진다 (app.css) |
380
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
379
381
 
380
382
  #### Separator
381
383
 
@@ -495,6 +497,15 @@
495
497
  | `focusWrap` | `boolean` | | true | 행 끝에서 다음 행으로 이동 |
496
498
  | `className` | `string` | | | 컨테이너 CSS 클래스 |
497
499
 
500
+ **Keyboard Shortcuts:**
501
+
502
+ | Keys | Action |
503
+ | --------- | -------------------- |
504
+ | `↑ ↓ ← →` | 2D 방향 탐색 |
505
+ | `Home` | 첫 항목으로 이동 |
506
+ | `End` | 마지막 항목으로 이동 |
507
+ | `Tab` | 영역 밖으로 이동 |
508
+
498
509
  #### Disclosure
499
510
 
500
511
  **Import:** `import { DisclosureRoot } from "@reopt-ai/opt-ui"`
@@ -521,32 +532,43 @@
521
532
  | `children` | `ReactNode` | Yes | | 접히는 콘텐츠 |
522
533
  | `className` | `string` | | | 기본 스타일 오버라이드 |
523
534
 
535
+ **Keyboard Shortcuts:**
536
+
537
+ | Keys | Action |
538
+ | --------------- | -------------- |
539
+ | `Enter / Space` | 열기/닫기 토글 |
540
+
524
541
  #### Tabs
525
542
 
526
543
  **Import:** `import { TabsRoot } from "@reopt-ai/opt-ui"`
527
544
 
528
545
  **TabsRoot:**
529
546
 
530
- | Prop | Type | Required | Default | Description |
531
- | ------------------- | ------------------------------ | -------- | ------- | ------------------------- |
532
- | `defaultSelectedId` | `string` | | | 초기 선택된ID |
533
- | `selectedId` | `string \| null` | | | 제어 모드: 선택된 탭 ID |
534
- | `setSelectedId` | `(id: string \| null) => void` | | | 제어 모드: 탭 변경 핸들러 |
547
+ | Prop | Type | Required | Default | Description |
548
+ | ------------------- | ------------------------------ | -------- | ------- | -------------------------------------------------------------------------------------- |
549
+ | `variant` | `"underline" \| "workspace"` | | | 프레임 형태. workspace는 편집기 (문서/쿼리처럼 열고 닫히며 상태를 갖는 작업 단위) |
550
+ | `defaultSelectedId` | `string` | | | 초기 선택된 탭 ID |
551
+ | `selectedId` | `string \| null` | | | 제어 모드: 선택된 ID |
552
+ | `setSelectedId` | `(id: string \| null) => void` | | | 제어 모드: 탭 변경 핸들러 |
535
553
 
536
554
  **TabList:**
537
555
 
538
- | Prop | Type | Required | Default | Description |
539
- | ----------- | ----------- | -------- | ------- | ---------------------- |
540
- | `children` | `ReactNode` | Yes | | Tab 요소들 |
541
- | `className` | `string` | | | 기본 스타일 오버라이드 |
556
+ | Prop | Type | Required | Default | Description |
557
+ | ----------- | ----------- | -------- | ------- | -------------------------------------------------------------------------------------- |
558
+ | `children` | `ReactNode` | Yes | | Tab 요소들 |
559
+ | `actions` | `ReactNode` | | | 오른쪽 액션 영역 (새 탭, 닫기 등). tablist 바깥에 렌더돼 탭 순회에 끼어들지 않음 |
560
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
542
561
 
543
562
  **Tab:**
544
563
 
545
- | Prop | Type | Required | Default | Description |
546
- | ----------- | ----------- | -------- | ------- | ------------------------------------ |
547
- | `id` | `string` | Yes | | 탭 고유 ID (TabPanel의 tabId와 매칭) |
548
- | `children` | `ReactNode` | Yes | | 탭 레이블 |
549
- | `className` | `string` | | | 기본 스타일 오버라이드 |
564
+ | Prop | Type | Required | Default | Description |
565
+ | ------------- | ---------------------- | -------- | ------- | ------------------------------------------------- |
566
+ | `id` | `string` | Yes | | 탭 고유 ID (TabPanel의 tabId와 매칭) |
567
+ | `children` | `ReactNode` | Yes | | 탭 레이블 |
568
+ | `icon` | `ReactNode` | | | 이름 앞 아이콘. 활성 탭에서 accent 색으로 전환 |
569
+ | `status` | `"dirty" \| "running"` | | | 저장되지 않은 변경 / 실행 중 인디케이터 |
570
+ | `statusLabel` | `string` | | | status 인디케이터의 접근성 레이블 |
571
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
550
572
 
551
573
  **TabPanel:**
552
574
 
@@ -556,6 +578,14 @@
556
578
  | `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
557
579
  | `className` | `string` | | | 기본 스타일 오버라이드 |
558
580
 
581
+ **Keyboard Shortcuts:**
582
+
583
+ | Keys | Action |
584
+ | ------ | ------------------- |
585
+ | `← →` | 탭 탐색 |
586
+ | `Home` | 첫 번째 탭으로 이동 |
587
+ | `End` | 마지막 탭으로 이동 |
588
+
559
589
  #### Select
560
590
 
561
591
  **Import:** `import { SelectRoot } from "@reopt-ai/opt-ui"`
@@ -600,6 +630,15 @@
600
630
  | `children` | `ReactNode` | Yes | | 옵션 레이블 |
601
631
  | `className` | `string` | | | 기본 스타일 오버라이드 |
602
632
 
633
+ **Keyboard Shortcuts:**
634
+
635
+ | Keys | Action |
636
+ | --------------- | -------------- |
637
+ | `↑ ↓` | 옵션 탐색 |
638
+ | `Enter / Space` | 옵션 선택 |
639
+ | `Esc` | 팝오버 닫기 |
640
+ | `문자 입력` | Typeahead 탐색 |
641
+
603
642
  **Examples:**
604
643
 
605
644
  _기본 선택:_
@@ -687,6 +726,13 @@ import {
687
726
  | ---------- | ----------- | -------- | ------- | -------------- |
688
727
  | `children` | `ReactNode` | Yes | | 액션 버튼 영역 |
689
728
 
729
+ **Keyboard Shortcuts:**
730
+
731
+ | Keys | Action |
732
+ | ----- | -------------------------------- |
733
+ | `Esc` | 다이얼로그 닫기 |
734
+ | `Tab` | 다이얼로그 내 포커스 이동 (트랩) |
735
+
690
736
  **Examples:**
691
737
 
692
738
  _모달 대화상자:_
@@ -766,6 +812,14 @@ import {
766
812
  | `children` | `ReactNode` | | "결과가 없습니다." | 빈 상태 메시지 |
767
813
  | `className` | `string` | | | 기본 스타일 오버라이드 |
768
814
 
815
+ **Keyboard Shortcuts:**
816
+
817
+ | Keys | Action |
818
+ | ------- | ----------- |
819
+ | `↑ ↓` | 항목 탐색 |
820
+ | `Enter` | 항목 선택 |
821
+ | `Esc` | 팝오버 닫기 |
822
+
769
823
  #### Menu
770
824
 
771
825
  **Import:** `import { MenubarRoot } from "@reopt-ai/opt-ui"`
@@ -844,6 +898,15 @@ import {
844
898
  | ----------- | -------- | -------- | ------- | ---------------------- |
845
899
  | `className` | `string` | | | 기본 스타일 오버라이드 |
846
900
 
901
+ **Keyboard Shortcuts:**
902
+
903
+ | Keys | Action |
904
+ | --------------- | -------------- |
905
+ | `← →` | 메뉴 간 탐색 |
906
+ | `↑ ↓` | 메뉴 항목 탐색 |
907
+ | `Enter / Space` | 항목 선택/토글 |
908
+ | `Esc` | 메뉴 닫기 |
909
+
847
910
  #### Toolbar
848
911
 
849
912
  **Import:** `import { ToolbarRoot } from "@reopt-ai/opt-ui"`
@@ -894,6 +957,15 @@ import {
894
957
  | `children` | `ReactNode` | Yes | | 툴팁 내용 |
895
958
  | `className` | `string` | | | 기본 스타일 오버라이드 |
896
959
 
960
+ **Keyboard Shortcuts:**
961
+
962
+ | Keys | Action |
963
+ | --------------- | --------------------- |
964
+ | `← →` | 버튼 간 탐색 |
965
+ | `Enter / Space` | 버튼 활성화 |
966
+ | `Home` | 첫 번째 버튼으로 이동 |
967
+ | `End` | 마지막 버튼으로 이동 |
968
+
897
969
  #### Form
898
970
 
899
971
  **Import:** `import { FormRoot } from "@reopt-ai/opt-ui"`
@@ -1533,6 +1605,14 @@ import {
1533
1605
  | `description` | `string` | | | 레이블 아래 설명 텍스트 |
1534
1606
  | `size` | `"sm" \| "md" \| "lg"` | | "md" | 라디오 크기 |
1535
1607
 
1608
+ **Keyboard Shortcuts:**
1609
+
1610
+ | Keys | Action |
1611
+ | ------- | ------------------- |
1612
+ | `↑ ↓` | 라디오 옵션 간 탐색 |
1613
+ | `← →` | 라디오 옵션 간 탐색 |
1614
+ | `Space` | 현재 옵션 선택 |
1615
+
1536
1616
  #### DateRangePicker
1537
1617
 
1538
1618
  **Import:** `import { DateRangePicker } from "@reopt-ai/opt-ui"`
@@ -1569,6 +1649,17 @@ import {
1569
1649
  | `delimiters` | `(string \| RegExp)[]` | | [",", ";", "\n"] | 붙여넣기 시 태그를 분할할 구분자 목록 |
1570
1650
  | `allowDuplicates` | `boolean` | | false | 중복 태그 허용 여부 |
1571
1651
 
1652
+ **Keyboard Shortcuts:**
1653
+
1654
+ | Keys | Action |
1655
+ | -------------- | ---------------------------------------- |
1656
+ | `Enter` | 태그 추가 |
1657
+ | `Backspace` | 마지막 태그 삭제 (입력 비어있을 때) |
1658
+ | `←/→` | 태그 간 이동 (Composite roving tabindex) |
1659
+ | `Delete` | 포커스된 태그 삭제 |
1660
+ | `Ctrl+Z` | 실행취소 |
1661
+ | `Ctrl+Shift+Z` | 다시실행 |
1662
+
1572
1663
  #### ColorPicker
1573
1664
 
1574
1665
  **Import:** `import { ColorPicker } from "@reopt-ai/opt-ui"`
@@ -1630,6 +1721,13 @@ import {
1630
1721
  | `gutter` | `number` | | 8 | 트리거와의 간격 (px) |
1631
1722
  | `className` | `string` | | | 커스텀 CSS 클래스 |
1632
1723
 
1724
+ **Keyboard Shortcuts:**
1725
+
1726
+ | Keys | Action |
1727
+ | --------------- | ------------- |
1728
+ | `Esc` | 팝오버 닫기 |
1729
+ | `Enter / Space` | 트리거 활성화 |
1730
+
1633
1731
  #### DropdownMenu
1634
1732
 
1635
1733
  **Import:** `import { DropdownMenu } from "@reopt-ai/opt-ui"`
@@ -1648,6 +1746,14 @@ import {
1648
1746
  | `onClick` | `() => void` | | | 항목 클릭 핸들러 |
1649
1747
  | `disabled` | `boolean` | | | 비활성 상태 |
1650
1748
 
1749
+ **Keyboard Shortcuts:**
1750
+
1751
+ | Keys | Action |
1752
+ | --------------- | -------------- |
1753
+ | `↑ ↓` | 메뉴 항목 탐색 |
1754
+ | `Enter / Space` | 항목 선택 |
1755
+ | `Esc` | 메뉴 닫기 |
1756
+
1651
1757
  #### NumberInput
1652
1758
 
1653
1759
  **Import:** `import { NumberInput } from "@reopt-ai/opt-ui"`
@@ -1668,6 +1774,13 @@ import {
1668
1774
  | `disabledReason` | `string` | | | aria-disabled 상태에서 노출할 비활성 사유 |
1669
1775
  | `labels` | `NumberInputLabels` | | | 입력/증감/clear/invalid 접근성 문구 |
1670
1776
 
1777
+ **Keyboard Shortcuts:**
1778
+
1779
+ | Keys | Action |
1780
+ | ---- | ------------------- |
1781
+ | `↑` | 값 증가 (step 단위) |
1782
+ | `↓` | 값 감소 (step 단위) |
1783
+
1671
1784
  #### Slider
1672
1785
 
1673
1786
  **Import:** `import { Slider } from "@reopt-ai/opt-ui"`
@@ -1735,42 +1848,50 @@ import {
1735
1848
 
1736
1849
  **ResizablePanelGroup:**
1737
1850
 
1738
- | Prop | Type | Required | Default | Description |
1739
- | ------------ | ---------------------------- | -------- | ------- | ---------------------------------------- |
1740
- | `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
1741
- | `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
1742
- | `autoSaveId` | `string` | | | 로컬 스토리지에 크기 상태 저장 (고유 ID) |
1743
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1851
+ | Prop | Type | Required | Default | Description |
1852
+ | ----------------- | ------------------------------------------ | -------- | ------- | --------------------------------------------------- |
1853
+ | `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
1854
+ | `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
1855
+ | `id` | `string` | | | 그룹과 defaultLayout의 패널 크기를 식별하는 고유 ID |
1856
+ | `defaultLayout` | `Record<string, number>` | | | 패널 ID별 초기 비율(0-100) |
1857
+ | `onLayoutChanged` | `(layout: Record<string, number>) => void` | | | 드래그가 끝난 뒤 확정된 레이아웃 콜백 |
1858
+ | `groupRef` | `Ref<ResizablePanelGroupHandle>` | | | 레이아웃 조회·설정을 위한 명령형 그룹 ref |
1859
+ | `autoSaveId` | `string` | | | id의 deprecated 별칭 |
1860
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1744
1861
 
1745
1862
  **ResizablePanel:**
1746
1863
 
1747
- | Prop | Type | Required | Default | Description |
1748
- | ------------- | ----------- | -------- | ------- | ----------------------------- |
1749
- | `defaultSize` | `number` | | | 초기 크기 (퍼센트, 0-100) |
1750
- | `minSize` | `number` | | | 최소 크기 (퍼센트) |
1751
- | `maxSize` | `number` | | | 최대 크기 (퍼센트) |
1752
- | `collapsible` | `boolean` | | false | 최소 크기 이하 시 접히기 허용 |
1753
- | `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
1754
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1864
+ | Prop | Type | Required | Default | Description |
1865
+ | ------------- | ------------------------------------------------------------------------------------------ | -------- | ------- | -------------------------------------------------- |
1866
+ | `defaultSize` | `number \| string` | | | 초기 크기. 숫자는 퍼센트, 문자열은 명시한 CSS 단위 |
1867
+ | `minSize` | `number \| string` | | | 최소 크기. 숫자는 퍼센트 |
1868
+ | `maxSize` | `number \| string` | | | 최대 크기. 숫자는 퍼센트 |
1869
+ | `collapsible` | `boolean` | | false | 최소 크기 이하 시 접히기 허용 |
1870
+ | `onResize` | `(size: ResizablePanelSize, id?: string \| number, previous?: ResizablePanelSize) => void` | | | 패널 크기 변경 콜백 |
1871
+ | `panelRef` | `Ref<ResizablePanelHandle>` | | | 접기·펼치기·크기 제어를 위한 명령형 패널 ref |
1872
+ | `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
1873
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1755
1874
 
1756
1875
  **ResizableHandle:**
1757
1876
 
1758
- | Prop | Type | Required | Default | Description |
1759
- | ------------ | --------- | -------- | ------- | ----------------------- |
1760
- | `withHandle` | `boolean` | | false | 시각적 드래그 핸들 표시 |
1761
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1877
+ | Prop | Type | Required | Default | Description |
1878
+ | ------------ | --------- | -------- | ------- | ---------------------------------- |
1879
+ | `withHandle` | `boolean` | | false | 시각적 드래그 핸들 표시 |
1880
+ | `disabled` | `boolean` | | | 드래그 키보드 리사이즈 비활성화 |
1881
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1762
1882
 
1763
1883
  #### BlockLayout
1764
1884
 
1765
1885
  **Import:** `import { BlockLayout } from "@reopt-ai/opt-ui"`
1766
1886
 
1767
- | Prop | Type | Required | Default | Description |
1768
- | -------------- | --------------------------------------------- | -------- | --------- | ------------------------------------------------------------------------------------ |
1769
- | `children` | `ReactNode` | Yes | | Block 콘텐츠 |
1770
- | `loading` | `boolean` | | | 로딩 상태. 설정 시 LoadingOverlay로 자동 래핑 |
1771
- | `loadingLabel` | `string` | | | LoadingOverlay 접근성 레이블 |
1772
- | `spacing` | `"section" \| "group" \| "element" \| "none"` | | "section" | Block 최상위 자식 사이 간격. 데이터 밀도가 높은 Block는 group/element로 낮출 수 있음 |
1773
- | `className` | `string` | | | 기본 스타일 오버라이드 |
1887
+ | Prop | Type | Required | Default | Description |
1888
+ | -------------- | --------------------------------------------- | -------- | --------- | ---------------------------------------------------------------------------------------------------- |
1889
+ | `children` | `ReactNode` | Yes | | Block 콘텐츠 |
1890
+ | `loading` | `boolean` | | | 로딩 상태. 설정 시 LoadingOverlay로 자동 래핑 |
1891
+ | `loadingLabel` | `string` | | | LoadingOverlay 접근성 레이블 |
1892
+ | `spacing` | `"section" \| "group" \| "element" \| "none"` | | "section" | Block 최상위 자식 사이 간격. 데이터 밀도가 높은 Block는 group/element로 낮출 수 있음 |
1893
+ | `inset` | `"section" \| "group" \| "element" \| "none"` | | | Block 안쪽 여백. 페이지 콘텐츠 경계에는 section을 사용하고, 이미 여백을 제공하는 Shell 안에서는 생략 |
1894
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
1774
1895
 
1775
1896
  **Examples:**
1776
1897
 
@@ -1779,7 +1900,7 @@ _Block 루트:_
1779
1900
  ```tsx
1780
1901
  import { BlockLayout, PageHeader } from "@reopt-ai/opt-ui";
1781
1902
 
1782
- <BlockLayout loading={isLoading} spacing="section">
1903
+ <BlockLayout loading={isLoading} spacing="section" inset="section">
1783
1904
  <PageHeader title="대시보드" description="프로젝트 현황" />
1784
1905
  <section>콘텐츠 영역</section>
1785
1906
  </BlockLayout>;
@@ -1856,6 +1977,13 @@ const MyDashboard = createBlock<MyDashboardProps>(
1856
1977
  | `swipeToDismiss` | `boolean` | | true | 가장자리 방향으로 드래그해 닫기 활성화 |
1857
1978
  | `swipeDismissThreshold` | `number` | | 80 | 닫힘 커밋에 필요한 드래그 거리(px) |
1858
1979
 
1980
+ **Keyboard Shortcuts:**
1981
+
1982
+ | Keys | Action |
1983
+ | ----- | ----------------------- |
1984
+ | `Esc` | 드로어 닫기 |
1985
+ | `Tab` | 드로어 내부 포커스 이동 |
1986
+
1859
1987
  #### Pagination
1860
1988
 
1861
1989
  **Import:** `import { Pagination } from "@reopt-ai/opt-ui"`
@@ -1909,6 +2037,15 @@ const MyDashboard = createBlock<MyDashboardProps>(
1909
2037
  | `readOnly` | `boolean` | | false | 읽기 전용 모드 |
1910
2038
  | `size` | `"sm" \| "md" \| "lg"` | | "md" | 별 아이콘 크기 |
1911
2039
 
2040
+ **Keyboard Shortcuts:**
2041
+
2042
+ | Keys | Action |
2043
+ | ----------------------- | ---------------- |
2044
+ | `ArrowRight / ArrowUp` | 별점 1 증가 |
2045
+ | `ArrowLeft / ArrowDown` | 별점 1 감소 |
2046
+ | `Home` | 별점 1로 설정 |
2047
+ | `End` | 별점 최대로 설정 |
2048
+
1912
2049
  #### ErrorBoundary
1913
2050
 
1914
2051
  **Import:** `import { ErrorBoundary } from "@reopt-ai/opt-ui"`
@@ -1951,6 +2088,15 @@ const MyDashboard = createBlock<MyDashboardProps>(
1951
2088
  | `keywords` | `string[]` | | | value에 더해 검색어와 비교할 추가 키워드 |
1952
2089
  | `onSelect` | `(value: string) => void` | | | Enter/클릭 시 호출 |
1953
2090
 
2091
+ **Keyboard Shortcuts:**
2092
+
2093
+ | Keys | Action |
2094
+ | ------------ | ---------------- |
2095
+ | `↑ ↓` | 활성 항목 이동 |
2096
+ | `Home / End` | 처음/마지막 항목 |
2097
+ | `Enter` | 활성 항목 선택 |
2098
+ | `Esc` | dialog 닫기 |
2099
+
1954
2100
  #### ShaderSurface
1955
2101
 
1956
2102
  **Import:** `import { ShaderSurface } from "@reopt-ai/opt-ui"`
@@ -2014,6 +2160,13 @@ const MyDashboard = createBlock<MyDashboardProps>(
2014
2160
  | `stats` | `StatCard[]` | Yes | | 통계 데이터 배열. { id, title, value, change, trend } |
2015
2161
  | `columns` | `number` | | 3 | 행당 컬럼 수 |
2016
2162
 
2163
+ **Keyboard Shortcuts:**
2164
+
2165
+ | Keys | Action |
2166
+ | --------- | ------------------ |
2167
+ | `↑ ↓ ← →` | 카드 간 2D 탐색 |
2168
+ | `Tab` | 다음 섹션으로 이동 |
2169
+
2017
2170
  #### SearchCombobox
2018
2171
 
2019
2172
  **Import:** `import { SearchCombobox } from "@reopt-ai/opt-ui"`
@@ -2212,6 +2365,17 @@ const fields = [
2212
2365
  | `bar` | `(row: T) => number` | | | 인라인 프로그레스 바 비율(0-1) 계산 함수. 범위 밖/NaN은 보정 |
2213
2366
  | `barColor` | `string` | | "bg-accent" | 인라인 바 색상 클래스 |
2214
2367
 
2368
+ **Keyboard Shortcuts:**
2369
+
2370
+ | Keys | Action |
2371
+ | -------------------------------- | ---------------------------------- |
2372
+ | `↑ ↓` | 행 탐색 |
2373
+ | `← →` | 셀 탐색 |
2374
+ | `Enter / Space` | 정렬 가능한 헤더 또는 행 활성화 |
2375
+ | `리사이즈 핸들: ← →` | 컬럼 너비를 10px 단위로 조절 |
2376
+ | `리사이즈 핸들: Shift+← Shift+→` | 컬럼 너비를 40px 단위로 조절 |
2377
+ | `리사이즈 핸들: Home / End` | 컬럼 너비를 최솟값/최댓값으로 이동 |
2378
+
2215
2379
  **Examples:**
2216
2380
 
2217
2381
  _기본 테이블:_
@@ -2301,6 +2465,14 @@ import { DataTable } from "@reopt-ai/opt-ui";
2301
2465
  | `onTaskStatusChange` | `(task: TaskDef, completed: boolean) => void` | | | 완료 상태 변경 핸들러 |
2302
2466
  | `showSubtasks` | `boolean` | | false | 하위 작업 표시 여부 |
2303
2467
 
2468
+ **Keyboard Shortcuts:**
2469
+
2470
+ | Keys | Action |
2471
+ | ------- | ------------ |
2472
+ | `↑ ↓` | 작업 간 이동 |
2473
+ | `Enter` | 작업 선택 |
2474
+ | `Space` | 완료 토글 |
2475
+
2304
2476
  #### ActivityFeed
2305
2477
 
2306
2478
  **Import:** `import { ActivityFeed } from "@reopt-ai/opt-ui"`
@@ -2315,6 +2487,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
2315
2487
  | `layout` | `"list" \| "compact"` | | "list" | 시간 표시 레이아웃 모드 |
2316
2488
  | `renderActions` | `(activity: ActivityDef) => ReactNode` | | | 각 활동 항목 우측 액션 슬롯 렌더 함수 |
2317
2489
 
2490
+ **Keyboard Shortcuts:**
2491
+
2492
+ | Keys | Action |
2493
+ | ------- | ------------ |
2494
+ | `↑ ↓` | 활동 간 이동 |
2495
+ | `Enter` | 활동 선택 |
2496
+
2318
2497
  #### FilterBar
2319
2498
 
2320
2499
  **Import:** `import { FilterBar } from "@reopt-ai/opt-ui"`
@@ -2357,6 +2536,14 @@ const filters = [
2357
2536
  | `layout` | `"grid" \| "list"` | | "grid" | 레이아웃 모드 |
2358
2537
  | `columns` | `2 \| 3 \| 4` | | 3 | 그리드 컬럼 수 |
2359
2538
 
2539
+ **Keyboard Shortcuts:**
2540
+
2541
+ | Keys | Action |
2542
+ | --------- | --------------------- |
2543
+ | `↑ ↓ ← →` | 그리드에서 4방향 탐색 |
2544
+ | `↑ ↓` | 리스트에서 수직 탐색 |
2545
+ | `Enter` | 작업 실행 |
2546
+
2360
2547
  #### TeamMemberList
2361
2548
 
2362
2549
  **Import:** `import { TeamMemberList } from "@reopt-ai/opt-ui"`
@@ -2370,6 +2557,13 @@ const filters = [
2370
2557
  | `maxDisplay` | `number` | | | 최대 표시 인원 |
2371
2558
  | `onMemberClick` | `(member: TeamMemberDef) => void` | | | 팀원 클릭 핸들러 |
2372
2559
 
2560
+ **Keyboard Shortcuts:**
2561
+
2562
+ | Keys | Action |
2563
+ | ------- | ------------ |
2564
+ | `↑ ↓` | 팀원 간 이동 |
2565
+ | `Enter` | 팀원 선택 |
2566
+
2373
2567
  #### AuthForm
2374
2568
 
2375
2569
  **Import:** `import { AuthForm } from "@reopt-ai/opt-ui"`
@@ -2419,17 +2613,17 @@ const filters = [
2419
2613
  **Import:** `import { FileUploadForm } from "@reopt-ai/opt-ui"`
2420
2614
  **Dependencies:** form (core)
2421
2615
 
2422
- | Prop | Type | Required | Default | Description |
2423
- | ----------------- | ------------------------------------------------ | -------- | -------------------------- | ----------------------------------------- |
2424
- | `accept` | `string` | | "image/\*,.pdf,.doc,.docx" | 허용 파일 타입 |
2425
- | `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
2426
- | `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
2427
- | `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
2428
- | `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
2429
- | `onSubmit` | `(values: { title, description, file }) => void` | | | 제출 핸들러 |
2430
- | `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
2431
- | `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
2432
- | `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
2616
+ | Prop | Type | Required | Default | Description |
2617
+ | ----------------- | ------------------------------------------------ | -------- | ------------------------- | ----------------------------------------- |
2618
+ | `accept` | `string` | | "image/*,.pdf,.doc,.docx" | 허용 파일 타입 |
2619
+ | `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
2620
+ | `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
2621
+ | `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
2622
+ | `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
2623
+ | `onSubmit` | `(values: { title, description, file }) => void` | | | 제출 핸들러 |
2624
+ | `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
2625
+ | `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
2626
+ | `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
2433
2627
 
2434
2628
  #### EventIcon
2435
2629
 
@@ -2441,6 +2635,19 @@ const filters = [
2441
2635
  | `color` | `string` | | theme accent | 사용자 지정 아이콘 색상. 없으면 theme accent 토큰을 사용하고, 전달하면 전경색과 tint 배경에 적용됩니다. |
2442
2636
  | `size` | `"sm" \| "md" \| "lg"` | | "md" | 아이콘 크기 (sm=20px, md=28px, lg=36px) |
2443
2637
 
2638
+ #### ConnectionIndicator
2639
+
2640
+ **Import:** `import { ConnectionIndicator } from "@reopt-ai/opt-ui"`
2641
+
2642
+ | Prop | Type | Required | Default | Description |
2643
+ | ----------- | ----------------------------------------------------------- | -------- | ------- | --------------------------------------------------------------------- |
2644
+ | `status` | `"connected" \| "connecting" \| "disconnected" \| "error"` | | | 연결 상태 프리셋. tone과 pulse의 기본값을 정함 |
2645
+ | `tone` | `"neutral" \| "success" \| "warning" \| "danger" \| "info"` | | | status로 표현되지 않는 도메인 상태의 색을 직접 지정 (status보다 우선) |
2646
+ | `label` | `string` | | | 상태 문구 |
2647
+ | `showLabel` | `boolean` | | | 문구 표시 여부 |
2648
+ | `pulse` | `boolean` | | | 점 애니메이션. 생략하면 status 프리셋을 따름 |
2649
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
2650
+
2444
2651
  #### TemplatePicker
2445
2652
 
2446
2653
  **Import:** `import { TemplatePicker } from "@reopt-ai/opt-ui"`
@@ -2466,6 +2673,13 @@ const filters = [
2466
2673
  | `onFailureClick` | `(failure: FailureItem) => void` | | | 실패 항목 클릭 핸들러 |
2467
2674
  | `renderActions` | `(failure: FailureItem) => ReactNode` | | | 각 항목 우측 액션 슬롯 렌더 함수 |
2468
2675
 
2676
+ **Keyboard Shortcuts:**
2677
+
2678
+ | Keys | Action |
2679
+ | ------- | ----------------- |
2680
+ | `↑ ↓` | 실패 항목 간 이동 |
2681
+ | `Enter` | 실패 항목 선택 |
2682
+
2469
2683
  #### KeyValueEditor
2470
2684
 
2471
2685
  **Import:** `import { KeyValueEditor } from "@reopt-ai/opt-ui"`
@@ -2482,6 +2696,12 @@ const filters = [
2482
2696
  | `renderActions` | `(entry: KeyValueEntry, index: number) => ReactNode` | | | 항목별 커스텀 액션 슬롯 |
2483
2697
  | `validateKey` | `(key: string, entries: KeyValueEntry[]) => string \| undefined` | | | 키 유효성 검사 함수 |
2484
2698
 
2699
+ **Keyboard Shortcuts:**
2700
+
2701
+ | Keys | Action |
2702
+ | ----- | ------------------ |
2703
+ | `Tab` | 키/값 필드 간 이동 |
2704
+
2485
2705
  #### WorkflowCanvas
2486
2706
 
2487
2707
  **Import:** `import { WorkflowCanvas } from "@reopt-ai/opt-ui"`
@@ -2494,6 +2714,13 @@ const filters = [
2494
2714
  | `onStepMove` | `(stepId: string, row: number, col: number) => void` | | | 화살표 키 이동 핸들러 |
2495
2715
  | `onSelectStep` | `(step: WorkflowCanvasStep) => void` | | | 스텝 선택 핸들러 |
2496
2716
 
2717
+ **Keyboard Shortcuts:**
2718
+
2719
+ | Keys | Action |
2720
+ | --------- | ----------------------------------- |
2721
+ | `↑ ↓ ← →` | 선택 스텝 이동 (onStepMove 제공 시) |
2722
+ | `Enter` | 스텝 선택 |
2723
+
2497
2724
  #### CodeSnippetViewer
2498
2725
 
2499
2726
  **Import:** `import { CodeSnippetViewer } from "@reopt-ai/opt-ui"`
@@ -2522,6 +2749,30 @@ const filters = [
2522
2749
  | `error` | `string` | | | assertive 오류 상태 |
2523
2750
  | `labels` | `QueryResultsTableLabels` | | | 로딩/빈 상태/행 수 문구 |
2524
2751
 
2752
+ #### SqlEditor
2753
+
2754
+ **Import:** `import { SqlEditor } from "@reopt-ai/opt-ui"`
2755
+ **Dependencies:** button (core)
2756
+
2757
+ | Prop | Type | Required | Default | Description |
2758
+ | ------------------- | ----------------------------- | -------- | ------- | -------------------------------------------------------------------------------- |
2759
+ | `value` | `string` | Yes | | 편집 중인 SQL |
2760
+ | `onChange` | `(sql: string) => void` | Yes | | 본문 변경 핸들러 |
2761
+ | `onRun` | `(sql: string) => void` | | | Mod+Enter 실행 핸들러 |
2762
+ | `onRunAndAdvance` | `(sql: string) => void` | | | Shift+Enter — 실행 후 다음 셀/탭으로 이동 |
2763
+ | `schema` | `SqlEditorSchema` | | | 테이블/컬럼 자동완성 스키마. 변경 시 에디터를 다시 만들지 않고 자동완성만 재구성 |
2764
+ | `completionSources` | `SqlEditorCompletionSource[]` | | | 스키마 자동완성에 더할 완성 소스 (함수 시그니처, 스니펫) |
2765
+ | `keymap` | `SqlEditorKeyBinding[]` | | | 추가 키 바인딩. 내장 실행 바인딩보다 먼저 평가 |
2766
+ | `extensions` | `SqlEditorExtension[]` | | | 임의의 CodeMirror 확장. 내장 확장 뒤에 붙어 우선권을 가짐 |
2767
+ | `height` | `number \| "fill"` | | | px 고정 높이. fill이면 부모가 정한 높이를 채움 |
2768
+ | `placeholder` | `string` | | | 빈 편집기 안내 문구 |
2769
+ | `readOnly` | `boolean` | | | 편집 잠금 |
2770
+ | `ariaLabel` | `string` | | | 편집 영역 접근성 레이블 |
2771
+ | `autoFocus` | `boolean` | | | 마운트 시 포커스 |
2772
+ | `showFooter` | `boolean` | | | 실행 힌트/버튼 표시. 기본값은 onRun이 있을 때 표시 |
2773
+ | `labels` | `SqlEditorLabels` | | | 문구 오버라이드 |
2774
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
2775
+
2525
2776
  #### ReportBuilder
2526
2777
 
2527
2778
  **Import:** `import { ReportBuilder } from "@reopt-ai/opt-ui"`
@@ -2668,6 +2919,14 @@ const filters = [
2668
2919
  | `badge` | `ReactNode` | | | 우측 배지 (숫자/텍스트). 접힌 상태에서 아이콘 위 dot으로 축소 |
2669
2920
  | `className` | `string` | | | 커스텀 CSS 클래스 |
2670
2921
 
2922
+ **Keyboard Shortcuts:**
2923
+
2924
+ | Keys | Action |
2925
+ | ------------ | ------------------------------------- |
2926
+ | `Ctrl+[` | 사이드바 접기/펼치기 토글 |
2927
+ | `↑ ↓` | 사이드바 항목 간 이동 |
2928
+ | `Home / End` | 첫 번째/마지막 사이드바 항목으로 이동 |
2929
+
2671
2930
  #### AppShell
2672
2931
 
2673
2932
  **Import:** `import { AppShell } from "@reopt-ai/opt-ui"`
@@ -2876,16 +3135,40 @@ import { AppShell } from "@reopt-ai/opt-ui";
2876
3135
  #### SavedFilters
2877
3136
 
2878
3137
  **Import:** `import { SavedFilters } from "@reopt-ai/opt-ui"`
2879
- **Dependencies:** popover (core), input (core)
2880
-
2881
- | Prop | Type | Required | Default | Description |
2882
- | ---------------- | ---------------------------------------------------------- | -------- | ------- | -------------------- |
2883
- | `currentFilters` | `Record<string, unknown>` | Yes | | 현재 적용 중인 필터 |
2884
- | `presets` | `FilterPreset[]` | Yes | | 저장된 프리셋 목록 |
2885
- | `onSavePreset` | `(name: string, filters: Record<string, unknown>) => void` | Yes | | 프리셋 저장 콜백 |
2886
- | `onLoadPreset` | `(preset: FilterPreset) => void` | Yes | | 프리셋 불러오기 콜백 |
2887
- | `onDeletePreset` | `(presetId: string) => void` | Yes | | 프리셋 삭제 콜백 |
2888
- | `className` | `string` | | | 커스텀 CSS 클래스 |
3138
+ **Dependencies:** popover (core), input (core), button (core)
3139
+
3140
+ **SavedFilters:**
3141
+
3142
+ | Prop | Type | Required | Default | Description |
3143
+ | ---------------- | ---------------------------------------------------------- | -------- | ------- | -------------------------------------------------- |
3144
+ | `currentFilters` | `Record<string, unknown>` | Yes | | 현재 적용 중인 필터 |
3145
+ | `presets` | `FilterPreset[]` | Yes | | 저장된 프리셋 목록 |
3146
+ | `onSavePreset` | `(name: string, filters: Record<string, unknown>) => void` | Yes | | 프리셋 저장 콜백 |
3147
+ | `onLoadPreset` | `(preset: FilterPreset) => void` | Yes | | 프리셋 불러오기 콜백 |
3148
+ | `onDeletePreset` | `(presetId: string) => void` | Yes | | 프리셋 삭제 콜백 |
3149
+ | `labels` | `SavedFiltersLabels` | | | 트리거, 빈 상태, 저장 및 삭제 확인 문구 오버라이드 |
3150
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
3151
+
3152
+ **SavedFiltersLabels:**
3153
+
3154
+ | Prop | Type | Required | Default | Description |
3155
+ | -------------------- | --------------------------- | -------- | ------------------ | --------------------------------------- |
3156
+ | `triggerLabel` | `(count: number) => string` | | | 저장된 프리셋 수를 포함한 트리거 레이블 |
3157
+ | `emptyMessage` | `string` | | "No saved filters" | 프리셋이 없을 때 표시할 메시지 |
3158
+ | `deleteLabel` | `(name: string) => string` | | | 프리셋 삭제 버튼의 접근 가능한 이름 |
3159
+ | `namePlaceholder` | `string` | | "Filter name…" | 새 프리셋 이름 입력 안내 |
3160
+ | `saveLabel` | `string` | | "Save" | 새 프리셋 저장 버튼 레이블 |
3161
+ | `confirmDeleteLabel` | `string` | | "Confirm" | 삭제 확인 버튼 레이블 |
3162
+ | `cancelDeleteLabel` | `string` | | "Cancel" | 삭제 취소 버튼 레이블 |
3163
+
3164
+ **Keyboard Shortcuts:**
3165
+
3166
+ | Keys | Action |
3167
+ | ------------ | ------------------------------------------- |
3168
+ | `↑ ↓` | 저장된 프리셋 간 이동 |
3169
+ | `Home / End` | 첫 번째/마지막 프리셋으로 이동 |
3170
+ | `Enter` | 프리셋 불러오기 또는 새 프리셋 저장 |
3171
+ | `Escape` | 삭제 확인 취소 후 삭제 버튼으로 포커스 복귀 |
2889
3172
 
2890
3173
  #### NotificationCenter
2891
3174
 
@@ -2954,6 +3237,13 @@ import { AppShell } from "@reopt-ai/opt-ui";
2954
3237
  | `showHint` | `boolean` | | true | Shift+Enter 힌트 표시 여부 |
2955
3238
  | `labels` | `ChatInputLabels` | | | i18n 라벨 오버라이드 |
2956
3239
 
3240
+ **Keyboard Shortcuts:**
3241
+
3242
+ | Keys | Action |
3243
+ | --------------- | ----------- |
3244
+ | `Enter` | 메시지 전송 |
3245
+ | `Shift + Enter` | 줄바꿈 |
3246
+
2957
3247
  **Examples:**
2958
3248
 
2959
3249
  _채팅 입력:_