@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
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Shell Components"
3
3
  description: "75 Shell layer components — props, examples, keyboard shortcuts."
4
- version: "1.4.1"
4
+ version: "1.6.0"
5
5
  generated: true
6
6
  ---
7
7
 
@@ -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 표시.
@@ -457,6 +483,15 @@ import { DataTable } from "@reopt-ai/opt-ui";
457
483
 
458
484
  **Import:** `import { ConnectionIndicator } from "@reopt-ai/opt-ui"`
459
485
 
486
+ | Prop | Type | Required | Default | Description |
487
+ | ----------- | ----------------------------------------------------------- | -------- | ------- | --------------------------------------------------------------------- |
488
+ | `status` | `"connected" \| "connecting" \| "disconnected" \| "error"` | | | 연결 상태 프리셋. tone과 pulse의 기본값을 정함 |
489
+ | `tone` | `"neutral" \| "success" \| "warning" \| "danger" \| "info"` | | | status로 표현되지 않는 도메인 상태의 색을 직접 지정 (status보다 우선) |
490
+ | `label` | `string` | | | 상태 문구 |
491
+ | `showLabel` | `boolean` | | | 문구 표시 여부 |
492
+ | `pulse` | `boolean` | | | 점 애니메이션. 생략하면 status 프리셋을 따름 |
493
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
494
+
460
495
  ### EventIcon
461
496
 
462
497
  > 이벤트 아이콘. semantic key 또는 ReactNode 아이콘과 배경색을 표시합니다.
@@ -495,6 +530,14 @@ import { DataTable } from "@reopt-ai/opt-ui";
495
530
  | `onTaskStatusChange` | `(task: TaskDef, completed: boolean) => void` | | | 완료 상태 변경 핸들러 |
496
531
  | `showSubtasks` | `boolean` | | false | 하위 작업 표시 여부 |
497
532
 
533
+ **Keyboard Shortcuts:**
534
+
535
+ | Keys | Action |
536
+ | ------- | ------------ |
537
+ | `↑ ↓` | 작업 간 이동 |
538
+ | `Enter` | 작업 선택 |
539
+ | `Space` | 완료 토글 |
540
+
498
541
  ### ActivityFeed
499
542
 
500
543
  > 활동 피드/로그 컴포넌트. 타임라인 스타일, 상대 시간 표시.
@@ -511,6 +554,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
511
554
  | `layout` | `"list" \| "compact"` | | "list" | 시간 표시 레이아웃 모드 |
512
555
  | `renderActions` | `(activity: ActivityDef) => ReactNode` | | | 각 활동 항목 우측 액션 슬롯 렌더 함수 |
513
556
 
557
+ **Keyboard Shortcuts:**
558
+
559
+ | Keys | Action |
560
+ | ------- | ------------ |
561
+ | `↑ ↓` | 활동 간 이동 |
562
+ | `Enter` | 활동 선택 |
563
+
514
564
  ### TeamMemberList
515
565
 
516
566
  > 팀원 목록 컴포넌트. 온라인 상태, 다양한 레이아웃(list, compact, avatars-only) 지원.
@@ -526,6 +576,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
526
576
  | `maxDisplay` | `number` | | | 최대 표시 인원 |
527
577
  | `onMemberClick` | `(member: TeamMemberDef) => void` | | | 팀원 클릭 핸들러 |
528
578
 
579
+ **Keyboard Shortcuts:**
580
+
581
+ | Keys | Action |
582
+ | ------- | ------------ |
583
+ | `↑ ↓` | 팀원 간 이동 |
584
+ | `Enter` | 팀원 선택 |
585
+
529
586
  ### KanbanBoard
530
587
 
531
588
  > 칸반 보드. HTML5 DnD로 카드를 컬럼 간 드래그&드롭.
@@ -579,7 +636,7 @@ import { DataTable } from "@reopt-ai/opt-ui";
579
636
  | StatusSelect | 색상 인디케이터가 있는 상태 선택 드롭다운. | `StatusSelect` |
580
637
  | BranchSelect | Git 브랜치 선택 드롭다운. Select primitive 래퍼. | `BranchSelect` |
581
638
  | FilterBar | 필터링 바 컴포넌트. 검색, 선택, 다중 선택 필터 지원. | `FilterBar` |
582
- | SavedFilters | 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI. | `SavedFilters` |
639
+ | SavedFilters | 필터 프리셋 관리. 키보드 목록 탐색, 현재 필터 저장, 안전한 삭제 확인 흐름을 제공하는 Popover UI. | `SavedFilters` |
583
640
  | QuickActions | 빠른 작업 패널. 그리드/리스트 레이아웃, 단축키 표시 지원. | `QuickActions` |
584
641
  | TimeRangeSelector | 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용. | `TimeRangeSelector` |
585
642
  | ComparisonSelector | 비교 선택기. 고유 레이블이 연결된 Select × 2 + Swap 버튼 조합. CohortComparison, FunnelAnalysis 등에서 사용합니다. | `ComparisonSelector` |
@@ -697,19 +754,43 @@ const filters = [
697
754
 
698
755
  ### SavedFilters
699
756
 
700
- > 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI.
757
+ > 필터 프리셋 관리. 키보드 목록 탐색, 현재 필터 저장, 안전한 삭제 확인 흐름을 제공하는 Popover UI.
701
758
 
702
759
  **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 클래스 |
760
+ **Dependencies:** popover (core), input (core), button (core)
761
+
762
+ **SavedFilters:**
763
+
764
+ | Prop | Type | Required | Default | Description |
765
+ | ---------------- | ---------------------------------------------------------- | -------- | ------- | -------------------------------------------------- |
766
+ | `currentFilters` | `Record<string, unknown>` | Yes | | 현재 적용 중인 필터 |
767
+ | `presets` | `FilterPreset[]` | Yes | | 저장된 프리셋 목록 |
768
+ | `onSavePreset` | `(name: string, filters: Record<string, unknown>) => void` | Yes | | 프리셋 저장 콜백 |
769
+ | `onLoadPreset` | `(preset: FilterPreset) => void` | Yes | | 프리셋 불러오기 콜백 |
770
+ | `onDeletePreset` | `(presetId: string) => void` | Yes | | 프리셋 삭제 콜백 |
771
+ | `labels` | `SavedFiltersLabels` | | | 트리거, 빈 상태, 저장 및 삭제 확인 문구 오버라이드 |
772
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
773
+
774
+ **SavedFiltersLabels:**
775
+
776
+ | Prop | Type | Required | Default | Description |
777
+ | -------------------- | --------------------------- | -------- | ------------------ | --------------------------------------- |
778
+ | `triggerLabel` | `(count: number) => string` | | | 저장된 프리셋 수를 포함한 트리거 레이블 |
779
+ | `emptyMessage` | `string` | | "No saved filters" | 프리셋이 없을 때 표시할 메시지 |
780
+ | `deleteLabel` | `(name: string) => string` | | | 프리셋 삭제 버튼의 접근 가능한 이름 |
781
+ | `namePlaceholder` | `string` | | "Filter name…" | 새 프리셋 이름 입력 안내 |
782
+ | `saveLabel` | `string` | | "Save" | 새 프리셋 저장 버튼 레이블 |
783
+ | `confirmDeleteLabel` | `string` | | "Confirm" | 삭제 확인 버튼 레이블 |
784
+ | `cancelDeleteLabel` | `string` | | "Cancel" | 삭제 취소 버튼 레이블 |
785
+
786
+ **Keyboard Shortcuts:**
787
+
788
+ | Keys | Action |
789
+ | ------------ | ------------------------------------------- |
790
+ | `↑ ↓` | 저장된 프리셋 간 이동 |
791
+ | `Home / End` | 첫 번째/마지막 프리셋으로 이동 |
792
+ | `Enter` | 프리셋 불러오기 또는 새 프리셋 저장 |
793
+ | `Escape` | 삭제 확인 취소 후 삭제 버튼으로 포커스 복귀 |
713
794
 
714
795
  ### QuickActions
715
796
 
@@ -725,6 +806,14 @@ const filters = [
725
806
  | `layout` | `"grid" \| "list"` | | "grid" | 레이아웃 모드 |
726
807
  | `columns` | `2 \| 3 \| 4` | | 3 | 그리드 컬럼 수 |
727
808
 
809
+ **Keyboard Shortcuts:**
810
+
811
+ | Keys | Action |
812
+ | --------- | --------------------- |
813
+ | `↑ ↓ ← →` | 그리드에서 4방향 탐색 |
814
+ | `↑ ↓` | 리스트에서 수직 탐색 |
815
+ | `Enter` | 작업 실행 |
816
+
728
817
  ### TimeRangeSelector
729
818
 
730
819
  > 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용.
@@ -864,17 +953,17 @@ const fields = [
864
953
  **Import:** `import { FileUploadForm } from "@reopt-ai/opt-ui"`
865
954
  **Dependencies:** form (core)
866
955
 
867
- | Prop | Type | Required | Default | Description |
868
- | ----------------- | ------------------------------------------------ | -------- | -------------------------- | ----------------------------------------- |
869
- | `accept` | `string` | | "image/\*,.pdf,.doc,.docx" | 허용 파일 타입 |
870
- | `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
871
- | `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
872
- | `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
873
- | `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
874
- | `onSubmit` | `(values: { title, description, file }) => void` | | | 제출 핸들러 |
875
- | `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
876
- | `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
877
- | `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
956
+ | Prop | Type | Required | Default | Description |
957
+ | ----------------- | ------------------------------------------------ | -------- | ------------------------- | ----------------------------------------- |
958
+ | `accept` | `string` | | "image/*,.pdf,.doc,.docx" | 허용 파일 타입 |
959
+ | `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
960
+ | `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
961
+ | `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
962
+ | `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
963
+ | `onSubmit` | `(values: { title, description, file }) => void` | | | 제출 핸들러 |
964
+ | `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
965
+ | `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
966
+ | `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
878
967
 
879
968
  ### WizardForm
880
969
 
@@ -1019,6 +1108,25 @@ const fields = [
1019
1108
  **Import:** `import { SqlEditor } from "@reopt-ai/opt-ui"`
1020
1109
  **Dependencies:** button (core)
1021
1110
 
1111
+ | Prop | Type | Required | Default | Description |
1112
+ | ------------------- | ----------------------------- | -------- | ------- | -------------------------------------------------------------------------------- |
1113
+ | `value` | `string` | Yes | | 편집 중인 SQL |
1114
+ | `onChange` | `(sql: string) => void` | Yes | | 본문 변경 핸들러 |
1115
+ | `onRun` | `(sql: string) => void` | | | Mod+Enter 실행 핸들러 |
1116
+ | `onRunAndAdvance` | `(sql: string) => void` | | | Shift+Enter — 실행 후 다음 셀/탭으로 이동 |
1117
+ | `schema` | `SqlEditorSchema` | | | 테이블/컬럼 자동완성 스키마. 변경 시 에디터를 다시 만들지 않고 자동완성만 재구성 |
1118
+ | `completionSources` | `SqlEditorCompletionSource[]` | | | 스키마 자동완성에 더할 완성 소스 (함수 시그니처, 스니펫) |
1119
+ | `keymap` | `SqlEditorKeyBinding[]` | | | 추가 키 바인딩. 내장 실행 바인딩보다 먼저 평가 |
1120
+ | `extensions` | `SqlEditorExtension[]` | | | 임의의 CodeMirror 확장. 내장 확장 뒤에 붙어 우선권을 가짐 |
1121
+ | `height` | `number \| "fill"` | | | px 고정 높이. fill이면 부모가 정한 높이를 채움 |
1122
+ | `placeholder` | `string` | | | 빈 편집기 안내 문구 |
1123
+ | `readOnly` | `boolean` | | | 편집 잠금 |
1124
+ | `ariaLabel` | `string` | | | 편집 영역 접근성 레이블 |
1125
+ | `autoFocus` | `boolean` | | | 마운트 시 포커스 |
1126
+ | `showFooter` | `boolean` | | | 실행 힌트/버튼 표시. 기본값은 onRun이 있을 때 표시 |
1127
+ | `labels` | `SqlEditorLabels` | | | 문구 오버라이드 |
1128
+ | `className` | `string` | | | 기본 스타일 오버라이드 |
1129
+
1022
1130
  ### EventMetaEditor
1023
1131
 
1024
1132
  > 이벤트 메타 에디터. 레이블이 연결된 IconPicker + ColorPicker + TagInput 조합으로 이벤트 메타데이터를 편집합니다.
@@ -1206,6 +1314,13 @@ const fields = [
1206
1314
  | `onStepMove` | `(stepId: string, row: number, col: number) => void` | | | 화살표 키 이동 핸들러 |
1207
1315
  | `onSelectStep` | `(step: WorkflowCanvasStep) => void` | | | 스텝 선택 핸들러 |
1208
1316
 
1317
+ **Keyboard Shortcuts:**
1318
+
1319
+ | Keys | Action |
1320
+ | --------- | ----------------------------------- |
1321
+ | `↑ ↓ ← →` | 선택 스텝 이동 (onStepMove 제공 시) |
1322
+ | `Enter` | 스텝 선택 |
1323
+
1209
1324
  ## Other
1210
1325
 
1211
1326
  | Component | Description | Key Exports |
@@ -1249,6 +1364,13 @@ const fields = [
1249
1364
  | `onFailureClick` | `(failure: FailureItem) => void` | | | 실패 항목 클릭 핸들러 |
1250
1365
  | `renderActions` | `(failure: FailureItem) => ReactNode` | | | 각 항목 우측 액션 슬롯 렌더 함수 |
1251
1366
 
1367
+ **Keyboard Shortcuts:**
1368
+
1369
+ | Keys | Action |
1370
+ | ------- | ----------------- |
1371
+ | `↑ ↓` | 실패 항목 간 이동 |
1372
+ | `Enter` | 실패 항목 선택 |
1373
+
1252
1374
  ### KeyValueEditor
1253
1375
 
1254
1376
  > 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다.
@@ -1267,6 +1389,12 @@ const fields = [
1267
1389
  | `renderActions` | `(entry: KeyValueEntry, index: number) => ReactNode` | | | 항목별 커스텀 액션 슬롯 |
1268
1390
  | `validateKey` | `(key: string, entries: KeyValueEntry[]) => string \| undefined` | | | 키 유효성 검사 함수 |
1269
1391
 
1392
+ **Keyboard Shortcuts:**
1393
+
1394
+ | Keys | Action |
1395
+ | ----- | ------------------ |
1396
+ | `Tab` | 키/값 필드 간 이동 |
1397
+
1270
1398
  ### AuditTimeline
1271
1399
 
1272
1400
  > 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰.
@@ -1315,6 +1443,13 @@ const fields = [
1315
1443
  | `showHint` | `boolean` | | true | Shift+Enter 힌트 표시 여부 |
1316
1444
  | `labels` | `ChatInputLabels` | | | i18n 라벨 오버라이드 |
1317
1445
 
1446
+ **Keyboard Shortcuts:**
1447
+
1448
+ | Keys | Action |
1449
+ | --------------- | ----------- |
1450
+ | `Enter` | 메시지 전송 |
1451
+ | `Shift + Enter` | 줄바꿈 |
1452
+
1318
1453
  **Examples:**
1319
1454
 
1320
1455
  _채팅 입력:_
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Surface Components"
3
3
  description: "0 Surface layer components — props, examples, keyboard shortcuts."
4
- version: "1.4.1"
4
+ version: "1.6.0"
5
5
  generated: true
6
6
  ---
7
7
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Component Reference"
3
3
  description: "Complete reference for 134 @reopt-ai/opt-ui components across 4 layers."
4
- version: "1.4.1"
4
+ version: "1.6.0"
5
5
  generated: true
6
6
  ---
7
7
 
@@ -7,7 +7,7 @@ related:
7
7
  - ../02-components/03-shells.md
8
8
  ---
9
9
 
10
- <!-- AI agent hint: Surface/페이지 루트에 직접 space-y-* 사용 금지. 반드시 SurfaceLayout 또는 createSurface 사용. -->
10
+ <!-- AI agent hint: Block/페이지 루트에 직접 space-y-* 사용 금지. 반드시 BlockLayout 또는 createBlock 사용. 페이지 경계를 직접 맡으면 inset="section"을 지정. -->
11
11
 
12
12
  # Layout Recipes
13
13
 
@@ -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
 
@@ -107,14 +111,14 @@ export function AppLayout({ children }: { children: React.ReactNode }) {
107
111
 
108
112
  ## 2. Data Explorer Page
109
113
 
110
- FilterBar + DataTable + Pagination in a SurfaceLayout.
114
+ FilterBar + DataTable + Pagination in a BlockLayout.
111
115
 
112
116
  ```tsx
113
117
  "use client";
114
118
 
115
119
  import { useState, useMemo } from "react";
116
120
  import {
117
- SurfaceLayout,
121
+ BlockLayout,
118
122
  PageHeader,
119
123
  FilterBar,
120
124
  DataTable,
@@ -217,7 +221,7 @@ export function UserExplorerPage() {
217
221
  };
218
222
 
219
223
  return (
220
- <SurfaceLayout>
224
+ <BlockLayout inset="section">
221
225
  <PageHeader
222
226
  title="사용자 관리"
223
227
  description={`총 ${filtered.length}명`}
@@ -249,20 +253,20 @@ export function UserExplorerPage() {
249
253
  currentPage={page}
250
254
  onPageChange={setPage}
251
255
  />
252
- </SurfaceLayout>
256
+ </BlockLayout>
253
257
  );
254
258
  }
255
259
  ```
256
260
 
257
261
  ## 3. Settings Page with Vertical Tabs
258
262
 
259
- SurfaceLayout with VerticalTabs for section navigation and SettingsForm for each tab.
263
+ BlockLayout with VerticalTabs for section navigation and SettingsForm for each tab.
260
264
 
261
265
  ```tsx
262
266
  "use client";
263
267
 
264
268
  import {
265
- SurfaceLayout,
269
+ BlockLayout,
266
270
  PageHeader,
267
271
  VerticalTabs,
268
272
  SettingsForm,
@@ -387,7 +391,7 @@ const tabs: TabDef[] = [
387
391
 
388
392
  export function SettingsPage() {
389
393
  return (
390
- <SurfaceLayout>
394
+ <BlockLayout inset="section">
391
395
  <PageHeader title="설정" description="프로젝트 설정을 관리합니다" />
392
396
 
393
397
  <VerticalTabs
@@ -395,7 +399,7 @@ export function SettingsPage() {
395
399
  defaultTabId="general"
396
400
  labels={{ ariaLabel: "설정 카테고리" }}
397
401
  />
398
- </SurfaceLayout>
402
+ </BlockLayout>
399
403
  );
400
404
  }
401
405
  ```
@@ -404,14 +408,14 @@ export function SettingsPage() {
404
408
 
405
409
  | Element | Approach |
406
410
  | -------------- | ------------------------------------------------------------------------- |
407
- | Page root | `SurfaceLayout` (provides `gap-section` between children) |
411
+ | Page root | `BlockLayout inset="section"` (page inset + `gap-section`) |
408
412
  | App chrome | `AppShell` + `AppShell.Header/Sidebar/Content/Footer` |
409
413
  | Sidebar nav | `Sidebar` with `Sidebar.Header/Content/Footer` sub-components |
410
- | Page title | `PageHeader` with optional `description` and `actions` slot |
414
+ | Page title | `PageHeader` with optional slots; outer inset belongs to the page root |
411
415
  | Section grids | `gap-group` between columns, `gap-element` for tight spacing |
412
416
  | Tab navigation | `VerticalTabs` for left-side tabs, `ContentTabs` for horizontal |
413
417
  | Pagination | `Pagination` below `DataTable` with `totalItems`/`pageSize`/`currentPage` |
414
- | Loading state | `SurfaceLayout loading={true}` wraps content with `LoadingOverlay` |
418
+ | Loading state | `BlockLayout loading={true}` wraps content with `LoadingOverlay` |
415
419
 
416
420
  ### Semantic Spacing Quick Reference
417
421
 
@@ -419,6 +423,10 @@ export function SettingsPage() {
419
423
  gap-section -> 24px (between major sections)
420
424
  gap-group -> 16px (between related items)
421
425
  gap-element -> 8px (between tightly coupled elements)
426
+ p-section -> 24px (inside a page-owned content boundary)
422
427
  ```
423
428
 
424
429
  CSS variables: `--opt-space-section`, `--opt-space-group`, `--opt-space-element`.
430
+
431
+ `BlockLayout`의 inset 기본값은 없음입니다. 재사용 Block이 카드나 Shell 안에 들어갈 때 이중
432
+ 여백이 생기지 않게 하고, 페이지 콘텐츠 경계를 맡는 호출부만 `inset="section"`을 명시합니다.
@@ -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
  ```
@@ -25,6 +25,34 @@ description: "opt-ui 버전별 Breaking/Deprecated 변경사항 레지스트리"
25
25
 
26
26
  ---
27
27
 
28
+ ## Version 1.5.0
29
+
30
+ ### Breaking
31
+
32
+ - version: "1.5.0"
33
+ level: B
34
+ component: "Surface runtime exports"
35
+ change: "런타임 Surface export 제거 — opt-cli 블록 registry로 이관"
36
+ detail: "ChatAssistant, DataExplorer, DeploymentCenter 등 런타임 Surface와 createSurface가 @reopt-ai/opt-ui에서 더 이상 export되지 않습니다. 페이지 템플릿은 opt-cli 블록 registry(copy-paste)로 소비합니다."
37
+ scan: "ChatAssistant\\|DataExplorer\\|DeploymentCenter\\|createSurface"
38
+ fix:
39
+ type: manual
40
+ from: 'import { ChatAssistant } from "@reopt-ai/opt-ui"'
41
+ to: "npx @reopt-ai/opt-cli surface add <slug>"
42
+
43
+ ### Deprecated
44
+
45
+ - version: "1.5.0"
46
+ level: D
47
+ component: "SurfaceLayout"
48
+ change: "SurfaceLayout deprecated → BlockLayout / createBlock"
49
+ detail: "SurfaceLayout이 deprecated 되었습니다. 페이지 간격·레이아웃은 BlockLayout 또는 createBlock을 사용하세요."
50
+ scan: "SurfaceLayout"
51
+ fix:
52
+ type: rename
53
+ from: "<SurfaceLayout>"
54
+ to: "<BlockLayout>"
55
+
28
56
  ## Version 1.2.0
29
57
 
30
58
  ### Breaking