@reopt-ai/opt-ui 1.4.1

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 (64) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/COMPONENT_CATALOG.md +3000 -0
  3. package/LICENSE +21 -0
  4. package/README.md +244 -0
  5. package/dist/chunk-3GWWZKX7.js +38 -0
  6. package/dist/chunk-AFF2HPE5.cjs +5008 -0
  7. package/dist/chunk-ELWICXYY.js +4745 -0
  8. package/dist/chunk-N4NDU5ET.cjs +4745 -0
  9. package/dist/chunk-ONE3C5RV.cjs +38 -0
  10. package/dist/chunk-QWBHD54V.js +3218 -0
  11. package/dist/chunk-RBM2RNC2.js +5008 -0
  12. package/dist/chunk-X5WCXJAF.cjs +3218 -0
  13. package/dist/core/index.cjs +324 -0
  14. package/dist/core/index.d.cts +5 -0
  15. package/dist/core/index.d.ts +5 -0
  16. package/dist/core/index.js +324 -0
  17. package/dist/docs/01-getting-started.md +129 -0
  18. package/dist/docs/02-components/01-core.md +1841 -0
  19. package/dist/docs/02-components/02-visuals.md +11 -0
  20. package/dist/docs/02-components/03-shells.md +1361 -0
  21. package/dist/docs/02-components/04-surfaces.md +11 -0
  22. package/dist/docs/02-components/index.md +106 -0
  23. package/dist/docs/03-recipes/01-forms.md +471 -0
  24. package/dist/docs/03-recipes/02-dashboards.md +397 -0
  25. package/dist/docs/03-recipes/03-layouts.md +424 -0
  26. package/dist/docs/04-theming.md +232 -0
  27. package/dist/docs/05-migration/01-breaking-changes.md +117 -0
  28. package/dist/docs/05-migration/02-formstore.md +336 -0
  29. package/dist/docs/06-troubleshooting.md +119 -0
  30. package/dist/docs/index.md +71 -0
  31. package/dist/id-registry.cjs +1875 -0
  32. package/dist/id-registry.d.cts +27 -0
  33. package/dist/id-registry.d.ts +27 -0
  34. package/dist/id-registry.js +1875 -0
  35. package/dist/id-registry.json +3799 -0
  36. package/dist/index-BZ_lBlO1.d.ts +474 -0
  37. package/dist/index-BuvxoWHf.d.cts +474 -0
  38. package/dist/index-DlAcuvQp.d.cts +1686 -0
  39. package/dist/index-Slu5hOj1.d.ts +1686 -0
  40. package/dist/index.cjs +9959 -0
  41. package/dist/index.d.cts +2351 -0
  42. package/dist/index.d.ts +2351 -0
  43. package/dist/index.js +9959 -0
  44. package/dist/meta.cjs +6898 -0
  45. package/dist/meta.d.cts +36 -0
  46. package/dist/meta.d.ts +36 -0
  47. package/dist/meta.js +6869 -0
  48. package/dist/shells/index.cjs +65 -0
  49. package/dist/shells/index.d.cts +5 -0
  50. package/dist/shells/index.d.ts +5 -0
  51. package/dist/shells/index.js +65 -0
  52. package/dist/tailwind.css +401 -0
  53. package/dist/theme/presets/default.css +355 -0
  54. package/dist/theme/presets/minimal.css +354 -0
  55. package/dist/theme/presets/mono-dark.css +354 -0
  56. package/dist/theme/presets/natural.css +181 -0
  57. package/dist/theme/presets/pro.css +354 -0
  58. package/dist/types-D4-0lwaE.d.cts +298 -0
  59. package/dist/types-D4-0lwaE.d.ts +298 -0
  60. package/dist/visuals/index.cjs +4 -0
  61. package/dist/visuals/index.d.cts +1 -0
  62. package/dist/visuals/index.d.ts +1 -0
  63. package/dist/visuals/index.js +4 -0
  64. package/package.json +165 -0
@@ -0,0 +1,1361 @@
1
+ ---
2
+ title: "Shell Components"
3
+ description: "75 Shell layer components — props, examples, keyboard shortcuts."
4
+ version: "1.4.1"
5
+ generated: true
6
+ ---
7
+
8
+ # Shell Components (75)
9
+
10
+ ## Navigation & Layout
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` |
29
+
30
+ ### AppMenubar
31
+
32
+ > 데스크톱 스타일 메뉴바. 체크박스, 라디오 메뉴 항목 지원.
33
+
34
+ **Import:** `import { AppMenubar } from "@reopt-ai/opt-ui"`
35
+ **Dependencies:** menu (core), kbd (core)
36
+
37
+ | Prop | Type | Required | Default | Description |
38
+ | ------- | ----------- | -------- | ------- | --------------------------------------------------- |
39
+ | `menus` | `MenuDef[]` | Yes | | 메뉴 정의 배열. { id, label, items: MenuItemDef[] } |
40
+
41
+ ### MegaMenu
42
+
43
+ > 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯.
44
+
45
+ **Import:** `import { MegaMenu } from "@reopt-ai/opt-ui"`
46
+ **Dependencies:** popover (core)
47
+
48
+ | Prop | Type | Required | Default | Description |
49
+ | -------------- | ------------------- | -------- | ------- | ------------------ |
50
+ | `menus` | `MegaMenuSection[]` | Yes | | 메뉴 섹션 배열 |
51
+ | `columns` | `number` | | 3 | 그리드 컬럼 수 |
52
+ | `footer` | `ReactNode` | | | 하단 footer 슬롯 |
53
+ | `triggerLabel` | `string` | | "Menu" | 트리거 버튼 텍스트 |
54
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
55
+
56
+ ### SidebarNav
57
+
58
+ > Composite 기반 사이드바 네비게이션. pathname 자동 동기화.
59
+
60
+ **Import:** `import { SidebarNav } from "@reopt-ai/opt-ui"`
61
+
62
+ | Prop | Type | Required | Default | Description |
63
+ | ------- | -------------- | -------- | ------- | --------------------------------------------------------------- |
64
+ | `items` | `NavItemDef[]` | Yes | | 네비게이션 항목. { id, label, href, separator?, sectionLabel? } |
65
+
66
+ ### Sidebar
67
+
68
+ > 접기/펼치기를 지원하는 compound 사이드바. Header/Content/Footer 구조 + Group/Item으로 네비게이션 구성. Ctrl+[ 단축키.
69
+
70
+ **Import:** `import { Sidebar } from "@reopt-ai/opt-ui"`
71
+ **Dependencies:** sidebar-nav (shells)
72
+
73
+ **Sidebar:**
74
+
75
+ | Prop | Type | Required | Default | Description |
76
+ | ------------------- | ------------------------------ | -------- | ---------- | --------------------------------------------------------- |
77
+ | `children` | `ReactNode` | Yes | | Sidebar.Header, Sidebar.Content, Sidebar.Footer 자식 요소 |
78
+ | `collapsible` | `boolean` | | false | 접기/펼치기 토글 지원 |
79
+ | `defaultCollapsed` | `boolean` | | false | 초기 접힘 상태 |
80
+ | `collapsed` | `boolean` | | | 제어 모드: 접힘 상태 |
81
+ | `onCollapsedChange` | `(collapsed: boolean) => void` | | | 제어 모드: 접힘 상태 변경 핸들러 |
82
+ | `width` | `number` | | 280 | 펼침 상태 너비 (px) |
83
+ | `collapsedWidth` | `number` | | 56 | 접힘 상태 너비 (px) |
84
+ | `side` | `"left" \| "right"` | | "left" | 사이드바 위치 |
85
+ | `label` | `string` | | "사이드바" | aside aria-label |
86
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
87
+
88
+ **Sidebar.Group:**
89
+
90
+ | Prop | Type | Required | Default | Description |
91
+ | ----------- | ----------- | -------- | ------- | ---------------------------------- |
92
+ | `children` | `ReactNode` | Yes | | Sidebar.Item 요소들 |
93
+ | `label` | `string` | | | 그룹 레이블 (접힌 상태에서 숨겨짐) |
94
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
95
+
96
+ **Sidebar.Item:**
97
+
98
+ | Prop | Type | Required | Default | Description |
99
+ | ----------- | ------------ | -------- | ------- | ------------------------------------------------------------- |
100
+ | `children` | `ReactNode` | Yes | | 항목 레이블 텍스트 |
101
+ | `icon` | `ReactNode` | | | 아이콘 (접힌 상태에서도 표시) |
102
+ | `active` | `boolean` | | false | 활성 상태 (aria-current=page) |
103
+ | `onClick` | `() => void` | | | 클릭 핸들러 |
104
+ | `href` | `string` | | | 링크 URL — 설정 시 <a> 태그로 렌더링 |
105
+ | `tooltip` | `string` | | | 접힌 상태에서 Tooltip 표시 (미지정 시 children 텍스트) |
106
+ | `badge` | `ReactNode` | | | 우측 배지 (숫자/텍스트). 접힌 상태에서 아이콘 위 dot으로 축소 |
107
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
108
+
109
+ ### AppShell
110
+
111
+ > Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. Sidebar 컴포넌트와 조합.
112
+
113
+ **Import:** `import { AppShell } from "@reopt-ai/opt-ui"`
114
+ **Dependencies:** sidebar (shells), page-header (core)
115
+
116
+ | Prop | Type | Required | Default | Description |
117
+ | ----------- | ----------- | -------- | ------- | ------------------------------------------------------------------------------ |
118
+ | `children` | `ReactNode` | Yes | | AppShell.Header, AppShell.Sidebar, AppShell.Content, AppShell.Footer 자식 요소 |
119
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
120
+
121
+ **Examples:**
122
+
123
+ _앱 레이아웃:_
124
+
125
+ ```tsx
126
+ import { AppShell } from "@reopt-ai/opt-ui";
127
+
128
+ <AppShell>
129
+ <AppShell.Header>헤더 영역</AppShell.Header>
130
+ <AppShell.Sidebar>사이드바 영역</AppShell.Sidebar>
131
+ <AppShell.Content>메인 콘텐츠</AppShell.Content>
132
+ </AppShell>;
133
+ ```
134
+
135
+ ### ContentTabs
136
+
137
+ > 탭 콘텐츠 패널. Tabs primitive 래퍼.
138
+
139
+ **Import:** `import { ContentTabs } from "@reopt-ai/opt-ui"`
140
+ **Dependencies:** tabs (core)
141
+
142
+ | Prop | Type | Required | Default | Description |
143
+ | -------------- | ---------- | -------- | ------- | ------------------------------------ |
144
+ | `tabs` | `TabDef[]` | Yes | | 탭 정의 배열. { id, label, content } |
145
+ | `defaultTabId` | `string` | | | 초기 선택 탭 ID. 미지정 시 첫 탭 |
146
+
147
+ ### VerticalTabs
148
+
149
+ > 세로 탭 레이아웃. 좌측 탭 리스트 + 우측 패널 구성입니다.
150
+
151
+ **Import:** `import { VerticalTabs } from "@reopt-ai/opt-ui"`
152
+ **Dependencies:** tabs (core)
153
+
154
+ | Prop | Type | Required | Default | Description |
155
+ | -------------- | ---------- | -------- | ------- | ----------------- |
156
+ | `tabs` | `TabDef[]` | Yes | | 탭 정의 배열 |
157
+ | `defaultTabId` | `string` | | | 기본 선택 탭 ID |
158
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
159
+
160
+ ### FaqAccordion
161
+
162
+ > FAQ 질문/답변 아코디언. Composite + Disclosure 조합.
163
+
164
+ **Import:** `import { FaqAccordion } from "@reopt-ai/opt-ui"`
165
+ **Dependencies:** disclosure (core)
166
+
167
+ | Prop | Type | Required | Default | Description |
168
+ | ------- | ----------- | -------- | ------- | --------------------------------------- |
169
+ | `items` | `FaqItem[]` | Yes | | FAQ 항목 배열. { id, question, answer } |
170
+
171
+ ### CommandPalette
172
+
173
+ > Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색.
174
+
175
+ **Import:** `import { CommandPalette } from "@reopt-ai/opt-ui"`
176
+ **Dependencies:** dialog (core), combobox (core), kbd (core)
177
+
178
+ | Prop | Type | Required | Default | Description |
179
+ | --------------- | -------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
180
+ | `commands` | `Omit<Command, "action">[]` | Yes | | 커맨드 목록. { id, label, group, shortcut? } |
181
+ | `open` | `boolean` | Yes | | 열림 상태 |
182
+ | `onOpenChange` | `(open: boolean) => void` | Yes | | 상태 변경 핸들러 |
183
+ | `onSelect` | `(command: Omit<Command, 'action'>) => void` | | | 커맨드 선택 핸들러 |
184
+ | `inline` | `boolean` | | false | true일 때 풀스크린 Dialog 대신 인라인 팝업으로 렌더링 |
185
+ | `labels` | `CommandPaletteLabels` | | | title/description/input/list/empty/escape 문구 |
186
+ | `footer` | `ReactNode` | | | 명령 목록 아래에 표시할 footer slot |
187
+ | `empty` | `ReactNode` | | | 결과가 없을 때 표시할 empty slot |
188
+ | `inputTrailing` | `ReactNode` | | | 검색 입력 우측 보조 콘텐츠 |
189
+
190
+ ### CommandPaletteTrigger
191
+
192
+ > CommandPalette + Cmd+K 키보드 단축키 자동 바인딩.
193
+
194
+ **Import:** `import { CommandPaletteTrigger } from "@reopt-ai/opt-ui"`
195
+ **Dependencies:** command-palette (shells)
196
+
197
+ | Prop | Type | Required | Default | Description |
198
+ | ---------- | -------------------------------------------- | -------- | ------- | -------------------------------------------------- |
199
+ | `commands` | `Omit<Command, "action">[]` | Yes | | 커맨드 목록 |
200
+ | `onSelect` | `(command: Omit<Command, 'action'>) => void` | | | 커맨드 선택 핸들러 |
201
+ | `labels` | `CommandPaletteTriggerLabels` | | | 내부 CommandPalette에 전달할 title/input/list 문구 |
202
+
203
+ ### ProjectSwitcher
204
+
205
+ > 프로젝트 검색 전환기. Combobox + match-sorter 퍼지 검색 지원.
206
+
207
+ **Import:** `import { ProjectSwitcher } from "@reopt-ai/opt-ui"`
208
+ **Dependencies:** combobox (core)
209
+
210
+ | Prop | Type | Required | Default | Description |
211
+ | ------------- | ---------------------- | -------- | ------------------ | ------------------------------------------------------- |
212
+ | `projects` | `ProjectDef[]` | Yes | | 프로젝트 목록. { id, name, framework, status, domain? } |
213
+ | `value` | `string` | | | 제어 모드: 현재 선택된 프로젝트 ID |
214
+ | `onChange` | `(id: string) => void` | | | 프로젝트 선택 핸들러 |
215
+ | `placeholder` | `string` | | "프로젝트 검색..." | 검색 입력 플레이스홀더 |
216
+
217
+ ### EditorToolbar
218
+
219
+ > 리치 텍스트 에디터 스타일 툴바. Toolbar + Tooltip 조합.
220
+
221
+ **Import:** `import { EditorToolbar } from "@reopt-ai/opt-ui"`
222
+ **Dependencies:** toolbar (core)
223
+
224
+ | Prop | Type | Required | Default | Description |
225
+ | --------------- | ---------------------- | -------- | ------- | ------------------------------------------ |
226
+ | `buttons` | `ToolbarButtonDef[]` | Yes | | 버튼 정의. { id, label, icon, separator? } |
227
+ | `onAction` | `(id: string) => void` | | | 버튼 클릭 핸들러 |
228
+ | `activeButtons` | `string[]` | | [] | 활성 상태 버튼 ID 배열 |
229
+
230
+ ### FloatingActionBar
231
+
232
+ > 플로팅 액션 바. 선택된 항목에 대한 일괄 작업 버튼을 하단에 표시합니다.
233
+
234
+ **Import:** `import { FloatingActionBar } from "@reopt-ai/opt-ui"`
235
+ **Dependencies:** button (core)
236
+
237
+ ### TemplatePicker
238
+
239
+ > 템플릿 선택기. 카테고리별 그리드와 검색을 제공하며 featured/tags 표시를 지원합니다.
240
+
241
+ **Import:** `import { TemplatePicker } from "@reopt-ai/opt-ui"`
242
+
243
+ | Prop | Type | Required | Default | Description |
244
+ | ------------ | ------------------------------ | -------- | ------- | --------------------------------------------------------------------------- |
245
+ | `templates` | `TemplateDef[]` | Yes | | 템플릿 배열. { id, name, description?, icon?, category?, featured?, tags? } |
246
+ | `selected` | `string` | | | 현재 선택된 템플릿 ID |
247
+ | `onSelect` | `(templateId: string) => void` | Yes | | 템플릿 선택 핸들러 |
248
+ | `showSearch` | `boolean` | | false | 검색 입력 표시 여부 |
249
+
250
+ ### ThemeSwitcher
251
+
252
+ > 테마 프리셋 선택기. 프리셋과 light/dark/system 모드 전환.
253
+
254
+ **Import:** `import { ThemeSwitcher } from "@reopt-ai/opt-ui"`
255
+
256
+ | Prop | Type | Required | Default | Description |
257
+ | -------- | --------------------- | -------- | ------- | ---------------------- |
258
+ | `labels` | `ThemeSwitcherLabels` | | | i18n용 라벨 오버라이드 |
259
+
260
+ ## Data Display
261
+
262
+ | Component | Description | Key Exports |
263
+ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
264
+ | DataTable | 제네릭 데이터 테이블. 동적 컬럼, 결측값 안전 정렬, 키보드 컬럼 리사이즈, 보정된 인라인 진행률과 Composite 탐색을 지원합니다. | `DataTable` |
265
+ | InlineEditTable | 인라인 편집 테이블. 더블클릭으로 셀 편집, Enter 확정, Escape 취소. | `InlineEditTable` |
266
+ | TreeTable | 계층형 트리 테이블. 재귀 행 렌더링 + 펼침/접기 셰브론. | `TreeTable` |
267
+ | DomainTable | 도메인 테이블. Composite 기반 그리드로 키보드 탐색 지원. | `DomainTable` |
268
+ | QueryResultsTable | 쿼리 결과 테이블. SQL 결과와 스크린 리더에 안내되는 로딩, 에러, 빈 상태를 지원합니다. | `QueryResultsTable` |
269
+ | DashboardGrid | Composite 기반 통계 카드 그리드. 유효한 1–4열 레이아웃과 화살표 키 2D 탐색을 지원합니다. | `DashboardGrid` |
270
+ | SummaryRow | 통계 요약 행. StatCard 그리드 레이아웃을 표준화합니다. loading 시 SkeletonCard 표시. | `SummaryRow` |
271
+ | CodeSnippetViewer | 코드 스니펫 뷰어. 줄 번호, 복사 버튼, 포커스 가능한 스크롤 영역, syntaxTheme 톤을 지원합니다. | `CodeSnippetViewer` |
272
+ | CodeDiffViewer | 코드 비교 뷰어. LCS 알고리즘 기반 unified/split 모드 diff와 포커스 가능한 스크롤 영역을 제공합니다. | `CodeDiffViewer` |
273
+ | ConnectionIndicator | 연결 상태 표시기. connected, connecting, disconnected, error 상태를 지원합니다. | `ConnectionIndicator` |
274
+ | EventIcon | 이벤트 아이콘. semantic key 또는 ReactNode 아이콘과 배경색을 표시합니다. | `EventIcon`, `POPULAR_ICONS`, `COLOR_PRESETS` |
275
+
276
+ ### DataTable
277
+
278
+ > 제네릭 데이터 테이블. 동적 컬럼, 결측값 안전 정렬, 키보드 컬럼 리사이즈, 보정된 인라인 진행률과 Composite 탐색을 지원합니다.
279
+
280
+ **Import:** `import { DataTable } from "@reopt-ai/opt-ui"`
281
+ **Dependencies:** composite-zone (core), button (core), checkbox (core)
282
+
283
+ **DataTable:**
284
+
285
+ | Prop | Type | Required | Default | Description |
286
+ | -------------- | -------------------- | -------- | ------------------- | --------------------------------------------------- |
287
+ | `data` | `T[]` | Yes | | 테이블 데이터 배열 |
288
+ | `columns` | `ColumnDef<T>[]` | Yes | | 컬럼 정의. { id, header, accessor, width?, align? } |
289
+ | `keyExtractor` | `(row: T) => string` | Yes | | 각 행의 고유 키 추출 함수 |
290
+ | `title` | `string` | | "데이터 테이블" | 테이블 제목 |
291
+ | `onRowClick` | `(row: T) => void` | | | 행 클릭 핸들러 |
292
+ | `emptyMessage` | `string` | | "데이터가 없습니다" | 데이터 없을 때 표시할 메시지 |
293
+
294
+ **ColumnDef:**
295
+
296
+ | Prop | Type | Required | Default | Description |
297
+ | ---------- | -------------------- | -------- | ----------- | ------------------------------------------------------------ |
298
+ | `bar` | `(row: T) => number` | | | 인라인 프로그레스 바 비율(0-1) 계산 함수. 범위 밖/NaN은 보정 |
299
+ | `barColor` | `string` | | "bg-accent" | 인라인 바 색상 클래스 |
300
+
301
+ **Examples:**
302
+
303
+ _기본 테이블:_
304
+
305
+ ```tsx
306
+ import { DataTable } from "@reopt-ai/opt-ui";
307
+
308
+ const columns = [
309
+ { id: "name", header: "이름", accessor: (r) => r.name },
310
+ { id: "email", header: "이메일", accessor: (r) => r.email },
311
+ ];
312
+ const data = [
313
+ { name: "홍길동", email: "hong@example.com" },
314
+ { name: "김철수", email: "kim@example.com" },
315
+ ];
316
+
317
+ <DataTable columns={columns} data={data} keyExtractor={(r) => r.email} />;
318
+ ```
319
+
320
+ _선택 + 정렬:_
321
+
322
+ ```tsx
323
+ import { DataTable } from "@reopt-ai/opt-ui";
324
+
325
+ <DataTable
326
+ columns={columns}
327
+ data={data}
328
+ keyExtractor={(r) => r.id}
329
+ selectable
330
+ selectedKeys={selected}
331
+ onSelectionChange={setSelected}
332
+ sortable
333
+ onSort={(colId, dir) => console.log(colId, dir)}
334
+ />;
335
+ ```
336
+
337
+ ### InlineEditTable
338
+
339
+ > 인라인 편집 테이블. 더블클릭으로 셀 편집, Enter 확정, Escape 취소.
340
+
341
+ **Import:** `import { InlineEditTable } from "@reopt-ai/opt-ui"`
342
+ **Dependencies:** data-table (shells)
343
+
344
+ | Prop | Type | Required | Default | Description |
345
+ | -------------- | ---------------------------------------------------------- | -------- | ------- | -------------------------------- |
346
+ | `data` | `T[]` | Yes | | 행 데이터 배열 |
347
+ | `columns` | `InlineEditColumnDef<T>[]` | Yes | | 컬럼 정의 (editable 플래그 포함) |
348
+ | `keyExtractor` | `(row: T) => string` | Yes | | 행 키 추출기 |
349
+ | `onCellEdit` | `(rowId: string, columnId: string, value: string) => void` | | | 셀 편집 확정 콜백 |
350
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
351
+
352
+ ### TreeTable
353
+
354
+ > 계층형 트리 테이블. 재귀 행 렌더링 + 펼침/접기 셰브론.
355
+
356
+ **Import:** `import { TreeTable } from "@reopt-ai/opt-ui"`
357
+ **Dependencies:** data-table (shells)
358
+
359
+ | Prop | Type | Required | Default | Description |
360
+ | ----------------- | -------------------- | -------- | ------- | ------------------ |
361
+ | `data` | `TreeNode<T>[]` | Yes | | 트리 노드 배열 |
362
+ | `columns` | `TreeColumnDef<T>[]` | Yes | | 컬럼 정의 |
363
+ | `defaultExpanded` | `string[]` | | [] | 기본 펼침 노드 ID |
364
+ | `indentSize` | `number` | | 24 | 들여쓰기 크기 (px) |
365
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
366
+
367
+ ### DomainTable
368
+
369
+ > 도메인 테이블. Composite 기반 그리드로 키보드 탐색 지원.
370
+
371
+ **Import:** `import { DomainTable } from "@reopt-ai/opt-ui"`
372
+
373
+ | Prop | Type | Required | Default | Description |
374
+ | --------- | ------------- | -------- | -------- | --------------------------------------------------------- |
375
+ | `domains` | `DomainDef[]` | Yes | | 도메인 목록. { domain, status, ssl, redirect?, addedAt? } |
376
+ | `title` | `string` | | "도메인" | 테이블 제목 |
377
+
378
+ ### QueryResultsTable
379
+
380
+ > 쿼리 결과 테이블. SQL 결과와 스크린 리더에 안내되는 로딩, 에러, 빈 상태를 지원합니다.
381
+
382
+ **Import:** `import { QueryResultsTable } from "@reopt-ai/opt-ui"`
383
+
384
+ | Prop | Type | Required | Default | Description |
385
+ | --------- | -------------------------------- | -------- | ------- | ----------------------- |
386
+ | `columns` | `string[]` | Yes | | 컬럼 이름 |
387
+ | `rows` | `Array<Record<string, unknown>>` | Yes | | 결과 행 |
388
+ | `loading` | `boolean` | | | polite 로딩 상태 |
389
+ | `error` | `string` | | | assertive 오류 상태 |
390
+ | `labels` | `QueryResultsTableLabels` | | | 로딩/빈 상태/행 수 문구 |
391
+
392
+ ### DashboardGrid
393
+
394
+ > Composite 기반 통계 카드 그리드. 유효한 1–4열 레이아웃과 화살표 키 2D 탐색을 지원합니다.
395
+
396
+ **Import:** `import { DashboardGrid } from "@reopt-ai/opt-ui"`
397
+ **Dependencies:** stat-card (core), composite-zone (core)
398
+
399
+ | Prop | Type | Required | Default | Description |
400
+ | --------- | ------------ | -------- | ------- | ----------------------------------------------------- |
401
+ | `stats` | `StatCard[]` | Yes | | 통계 데이터 배열. { id, title, value, change, trend } |
402
+ | `columns` | `number` | | 3 | 행당 컬럼 수 |
403
+
404
+ ### SummaryRow
405
+
406
+ > 통계 요약 행. StatCard 그리드 레이아웃을 표준화합니다. loading 시 SkeletonCard 표시.
407
+
408
+ **Import:** `import { SummaryRow } from "@reopt-ai/opt-ui"`
409
+ **Dependencies:** stat-card (core), skeleton (core)
410
+
411
+ | Prop | Type | Required | Default | Description |
412
+ | -------------------------- | -------------------------------- | -------- | ------- | -------------------------------- |
413
+ | `stats` | `StatCardType[]` | Yes | | 통계 카드 배열 |
414
+ | `columns` | `2 \| 3 \| 4` | | 4 | 컬럼 수 |
415
+ | `onStatClick` | `(stat: StatCardType) => void` | | | 카드 클릭 핸들러 |
416
+ | `formatValue` | `(stat: StatCardType) => string` | | | 값 표시 커스텀 포맷 함수 |
417
+ | `durationFractionDigits` | `number` | | 1 | duration 포맷 시 소수점 자리수 |
418
+ | `percentageFractionDigits` | `number` | | 1 | percentage 포맷 시 소수점 자리수 |
419
+ | `loading` | `boolean` | | false | 로딩 시 스켈레톤 표시 |
420
+
421
+ ### CodeSnippetViewer
422
+
423
+ > 코드 스니펫 뷰어. 줄 번호, 복사 버튼, 포커스 가능한 스크롤 영역, syntaxTheme 톤을 지원합니다.
424
+
425
+ **Import:** `import { CodeSnippetViewer } from "@reopt-ai/opt-ui"`
426
+
427
+ | Prop | Type | Required | Default | Description |
428
+ | ----------------- | ---------------------------------------------- | -------- | --------- | --------------------------------- |
429
+ | `code` | `string` | Yes | | 표시할 코드 문자열 |
430
+ | `language` | `string` | | "text" | 코드 언어 라벨 |
431
+ | `title` | `string` | | | 헤더에 표시할 제목 |
432
+ | `showLineNumbers` | `boolean` | | true | 줄 번호 표시 여부 |
433
+ | `showCopyButton` | `boolean` | | true | 복사 버튼 표시 여부 |
434
+ | `maxHeight` | `number` | | 400 | 스크롤 영역의 최대 높이(px) |
435
+ | `syntaxTheme` | `"default" \| "muted" \| "dark" \| "terminal"` | | "default" | 코드 블록 색상 톤 |
436
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
437
+ | `labels` | `CodeSnippetViewerLabels` | | | 복사 버튼과 코드 영역 레이블 문구 |
438
+
439
+ ### CodeDiffViewer
440
+
441
+ > 코드 비교 뷰어. LCS 알고리즘 기반 unified/split 모드 diff와 포커스 가능한 스크롤 영역을 제공합니다.
442
+
443
+ **Import:** `import { CodeDiffViewer } from "@reopt-ai/opt-ui"`
444
+
445
+ | Prop | Type | Required | Default | Description |
446
+ | ----------------- | ---------------------- | -------- | --------- | --------------------------------------- |
447
+ | `original` | `string` | Yes | | 원본 코드 |
448
+ | `modified` | `string` | Yes | | 수정된 코드 |
449
+ | `mode` | `"split" \| "unified"` | | "unified" | 뷰 모드 |
450
+ | `showLineNumbers` | `boolean` | | true | 줄 번호 표시 |
451
+ | `scrollLabel` | `string` | | | 스크롤 가능한 diff 영역의 접근성 레이블 |
452
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
453
+
454
+ ### ConnectionIndicator
455
+
456
+ > 연결 상태 표시기. connected, connecting, disconnected, error 상태를 지원합니다.
457
+
458
+ **Import:** `import { ConnectionIndicator } from "@reopt-ai/opt-ui"`
459
+
460
+ ### EventIcon
461
+
462
+ > 이벤트 아이콘. semantic key 또는 ReactNode 아이콘과 배경색을 표시합니다.
463
+
464
+ **Import:** `import { EventIcon } from "@reopt-ai/opt-ui"`
465
+
466
+ | Prop | Type | Required | Default | Description |
467
+ | ------- | --------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------- |
468
+ | `icon` | `string \| React.ReactNode` | Yes | | semantic icon key, legacy key, 또는 React 노드 (Lucide 등) |
469
+ | `color` | `string` | | theme accent | 사용자 지정 아이콘 색상. 없으면 theme accent 토큰을 사용하고, 전달하면 전경색과 tint 배경에 적용됩니다. |
470
+ | `size` | `"sm" \| "md" \| "lg"` | | "md" | 아이콘 크기 (sm=20px, md=28px, lg=36px) |
471
+
472
+ ## Lists & Feeds
473
+
474
+ | Component | Description | Key Exports |
475
+ | ------------------ | ----------------------------------------------------------------------------------- | -------------------- |
476
+ | TaskList | 작업 목록 관리 컴포넌트. 우선순위, 상태, 담당자, 태그, 하위 작업 지원. | `TaskList` |
477
+ | ActivityFeed | 활동 피드/로그 컴포넌트. 타임라인 스타일, 상대 시간 표시. | `ActivityFeed` |
478
+ | TeamMemberList | 팀원 목록 컴포넌트. 온라인 상태, 다양한 레이아웃(list, compact, avatars-only) 지원. | `TeamMemberList` |
479
+ | KanbanBoard | 칸반 보드. HTML5 DnD로 카드를 컬럼 간 드래그&드롭. | `KanbanBoard` |
480
+ | AuditLog | 감사 로그 타임라인. 아바타 + 액션 텍스트 + 메타데이터 배지 레이아웃. | `AuditLog` |
481
+ | NotificationCenter | 알림 센터. 벨 아이콘 트리거 + 미읽음 배지 + 스크롤 알림 목록. | `NotificationCenter` |
482
+
483
+ ### TaskList
484
+
485
+ > 작업 목록 관리 컴포넌트. 우선순위, 상태, 담당자, 태그, 하위 작업 지원.
486
+
487
+ **Import:** `import { TaskList } from "@reopt-ai/opt-ui"`
488
+ **Dependencies:** avatar (core), checkbox (core)
489
+
490
+ | Prop | Type | Required | Default | Description |
491
+ | -------------------- | --------------------------------------------- | -------- | ----------- | ---------------------------------------------------------- |
492
+ | `tasks` | `TaskDef[]` | Yes | | 작업 배열. { id, title, status, priority, assignee?, ... } |
493
+ | `title` | `string` | | "작업 목록" | 섹션 제목 |
494
+ | `onTaskClick` | `(task: TaskDef) => void` | | | 작업 클릭 핸들러 |
495
+ | `onTaskStatusChange` | `(task: TaskDef, completed: boolean) => void` | | | 완료 상태 변경 핸들러 |
496
+ | `showSubtasks` | `boolean` | | false | 하위 작업 표시 여부 |
497
+
498
+ ### ActivityFeed
499
+
500
+ > 활동 피드/로그 컴포넌트. 타임라인 스타일, 상대 시간 표시.
501
+
502
+ **Import:** `import { ActivityFeed } from "@reopt-ai/opt-ui"`
503
+ **Dependencies:** avatar (core)
504
+
505
+ | Prop | Type | Required | Default | Description |
506
+ | ----------------- | -------------------------------------- | -------- | ----------- | ----------------------------------------------------- |
507
+ | `activities` | `ActivityDef[]` | Yes | | 활동 배열. { id, type, title, actor, timestamp, ... } |
508
+ | `title` | `string` | | "활동 피드" | 섹션 제목 |
509
+ | `maxItems` | `number` | | | 최대 표시 개수 |
510
+ | `onActivityClick` | `(activity: ActivityDef) => void` | | | 활동 클릭 핸들러 |
511
+ | `layout` | `"list" \| "compact"` | | "list" | 시간 표시 레이아웃 모드 |
512
+ | `renderActions` | `(activity: ActivityDef) => ReactNode` | | | 각 활동 항목 우측 액션 슬롯 렌더 함수 |
513
+
514
+ ### TeamMemberList
515
+
516
+ > 팀원 목록 컴포넌트. 온라인 상태, 다양한 레이아웃(list, compact, avatars-only) 지원.
517
+
518
+ **Import:** `import { TeamMemberList } from "@reopt-ai/opt-ui"`
519
+ **Dependencies:** avatar (core)
520
+
521
+ | Prop | Type | Required | Default | Description |
522
+ | --------------- | --------------------------------------- | -------- | ------- | ------------------------------------------------------- |
523
+ | `members` | `TeamMemberDef[]` | Yes | | 팀원 배열. { id, name, email, avatar?, role?, status? } |
524
+ | `title` | `string` | | "팀원" | 섹션 제목 |
525
+ | `layout` | `"list" \| "compact" \| "avatars-only"` | | "list" | 레이아웃 모드 |
526
+ | `maxDisplay` | `number` | | | 최대 표시 인원 |
527
+ | `onMemberClick` | `(member: TeamMemberDef) => void` | | | 팀원 클릭 핸들러 |
528
+
529
+ ### KanbanBoard
530
+
531
+ > 칸반 보드. HTML5 DnD로 카드를 컬럼 간 드래그&드롭.
532
+
533
+ **Import:** `import { KanbanBoard } from "@reopt-ai/opt-ui"`
534
+ **Dependencies:** scroll-area (core)
535
+
536
+ | Prop | Type | Required | Default | Description |
537
+ | -------------- | ------------------------------------------- | -------- | ------- | -------------------------------- |
538
+ | `columns` | `KanbanColumn<T>[]` | Yes | | 컬럼 목록 (각 컬럼에 items 배열) |
539
+ | `onDragEnd` | `(itemId, fromCol, toCol, toIndex) => void` | Yes | | 드래그 완료 콜백 |
540
+ | `renderCard` | `(item: T) => ReactNode` | Yes | | 카드 렌더링 함수 |
541
+ | `keyExtractor` | `(item: T) => string` | Yes | | 항목 키 추출기 |
542
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
543
+
544
+ ### AuditLog
545
+
546
+ > 감사 로그 타임라인. 아바타 + 액션 텍스트 + 메타데이터 배지 레이아웃.
547
+
548
+ **Import:** `import { AuditLog } from "@reopt-ai/opt-ui"`
549
+ **Dependencies:** avatar (core), badge (core)
550
+
551
+ | Prop | Type | Required | Default | Description |
552
+ | ------------ | -------------- | -------- | ------- | ------------------- |
553
+ | `entries` | `AuditEntry[]` | Yes | | 감사 로그 항목 배열 |
554
+ | `onLoadMore` | `() => void` | | | 더 보기 콜백 |
555
+ | `loading` | `boolean` | | false | 로딩 상태 |
556
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
557
+
558
+ ### NotificationCenter
559
+
560
+ > 알림 센터. 벨 아이콘 트리거 + 미읽음 배지 + 스크롤 알림 목록.
561
+
562
+ **Import:** `import { NotificationCenter } from "@reopt-ai/opt-ui"`
563
+ **Dependencies:** popover (core), badge (core), scroll-area (core)
564
+
565
+ | Prop | Type | Required | Default | Description |
566
+ | --------------- | ---------------------- | -------- | ------- | ------------------- |
567
+ | `notifications` | `NotificationItem[]` | Yes | | 알림 목록 |
568
+ | `onMarkRead` | `(id: string) => void` | Yes | | 읽음 처리 콜백 |
569
+ | `onMarkAllRead` | `() => void` | Yes | | 전체 읽음 처리 콜백 |
570
+ | `onAction` | `(id: string) => void` | | | 알림 액션 콜백 |
571
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
572
+
573
+ ## Filters & Search
574
+
575
+ | Component | Description | Key Exports |
576
+ | ------------------ | ------------------------------------------------------------------------------------------------------------------ | -------------------- |
577
+ | SearchCombobox | match-sorter 기반 퍼지 검색 콤보박스. | `SearchCombobox` |
578
+ | AsyncCombobox | 비동기 검색 콤보박스. 디바운스 + 로딩 스피너와 stale response 방어를 내장합니다. | `AsyncCombobox` |
579
+ | StatusSelect | 색상 인디케이터가 있는 상태 선택 드롭다운. | `StatusSelect` |
580
+ | BranchSelect | Git 브랜치 선택 드롭다운. Select primitive 래퍼. | `BranchSelect` |
581
+ | FilterBar | 필터링 바 컴포넌트. 검색, 선택, 다중 선택 필터 지원. | `FilterBar` |
582
+ | SavedFilters | 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI. | `SavedFilters` |
583
+ | QuickActions | 빠른 작업 패널. 그리드/리스트 레이아웃, 단축키 표시 지원. | `QuickActions` |
584
+ | TimeRangeSelector | 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용. | `TimeRangeSelector` |
585
+ | ComparisonSelector | 비교 선택기. 고유 레이블이 연결된 Select × 2 + Swap 버튼 조합. CohortComparison, FunnelAnalysis 등에서 사용합니다. | `ComparisonSelector` |
586
+ | ColumnToggler | 테이블 컬럼 표시/숨김 토글러. Popover + Checkbox 리스트입니다. | `ColumnToggler` |
587
+ | BulkActions | 일괄 작업 바. 선택 카운트 배지 + DropdownMenu 액션 목록 + 해제 버튼. | `BulkActions` |
588
+
589
+ ### SearchCombobox
590
+
591
+ > match-sorter 기반 퍼지 검색 콤보박스.
592
+
593
+ **Import:** `import { SearchCombobox } from "@reopt-ai/opt-ui"`
594
+ **Dependencies:** combobox (core)
595
+
596
+ | Prop | Type | Required | Default | Description |
597
+ | ------------- | -------------------------------------- | -------- | --------- | -------------------------------- |
598
+ | `items` | `string[]` | Yes | | 검색 대상 문자열 목록 |
599
+ | `placeholder` | `string` | | "검색..." | 입력 플레이스홀더 |
600
+ | `label` | `string` | | "검색" | 입력 레이블 |
601
+ | `onSelect` | `(item: string) => void` | | | 항목 선택 핸들러 |
602
+ | `labels` | `SearchComboboxLabels` | | | noResults/loading 문구 |
603
+ | `async` | `boolean` | | false | 비동기 검색 모드 활성화 |
604
+ | `onSearch` | `(query: string) => Promise<string[]>` | | | async=true일 때 사용할 검색 콜백 |
605
+ | `debounceMs` | `number` | | 300 | 비동기 검색 디바운스 ms |
606
+
607
+ **Examples:**
608
+
609
+ _검색 + 선택:_
610
+
611
+ ```tsx
612
+ import { SearchCombobox } from "@reopt-ai/opt-ui";
613
+
614
+ <SearchCombobox
615
+ items={["React", "Vue", "Angular", "Svelte"]}
616
+ placeholder="프레임워크 검색..."
617
+ onSelect={(item) => console.log(item)}
618
+ />;
619
+ ```
620
+
621
+ ### AsyncCombobox
622
+
623
+ > 비동기 검색 콤보박스. 디바운스 + 로딩 스피너와 stale response 방어를 내장합니다.
624
+
625
+ **Import:** `import { AsyncCombobox } from "@reopt-ai/opt-ui"`
626
+ **Dependencies:** combobox (core), spinner (core)
627
+
628
+ | Prop | Type | Required | Default | Description |
629
+ | ------------- | ---------------------------------- | -------- | --------- | ---------------------------------------- |
630
+ | `onSearch` | `(q: string) => Promise<string[]>` | Yes | | 검색 콜백 |
631
+ | `debounceMs` | `number` | | 300 | 디바운스 ms |
632
+ | `minChars` | `number` | | 1 | 최소 검색 글자 수 |
633
+ | `placeholder` | `string` | | "Search…" | 플레이스홀더 |
634
+ | `onSelect` | `(value: string) => void` | | | 선택 콜백 |
635
+ | `labels` | `AsyncComboboxLabels` | | | input/loading/noResults/placeholder 문구 |
636
+ | `loadingText` | `string` | | | 로딩 문구. labels.loading 사용 권장 |
637
+
638
+ ### StatusSelect
639
+
640
+ > 색상 인디케이터가 있는 상태 선택 드롭다운.
641
+
642
+ **Import:** `import { StatusSelect } from "@reopt-ai/opt-ui"`
643
+ **Dependencies:** select (core)
644
+
645
+ | Prop | Type | Required | Default | Description |
646
+ | ---------- | ------------------------- | -------- | ------- | ----------------------------------- |
647
+ | `options` | `SelectOption[]` | Yes | | 옵션 목록. { value, label, color? } |
648
+ | `value` | `string` | | | 제어 모드: 현재 선택 값 |
649
+ | `onChange` | `(value: string) => void` | | | 제어 모드: 값 변경 핸들러 |
650
+ | `label` | `string` | | "상태" | Select 레이블 |
651
+
652
+ ### BranchSelect
653
+
654
+ > Git 브랜치 선택 드롭다운. Select primitive 래퍼.
655
+
656
+ **Import:** `import { BranchSelect } from "@reopt-ai/opt-ui"`
657
+ **Dependencies:** select (core)
658
+
659
+ | Prop | Type | Required | Default | Description |
660
+ | ---------- | ------------------------ | -------- | -------- | ------------------------------------------------------- |
661
+ | `branches` | `BranchDef[]` | Yes | | 브랜치 목록. { name, isDefault?, lastCommit?, author? } |
662
+ | `value` | `string` | | | 제어 모드: 현재 선택된 브랜치 이름 |
663
+ | `onChange` | `(name: string) => void` | | | 브랜치 선택 핸들러 |
664
+ | `label` | `string` | | "브랜치" | Select 레이블 |
665
+
666
+ ### FilterBar
667
+
668
+ > 필터링 바 컴포넌트. 검색, 선택, 다중 선택 필터 지원.
669
+
670
+ **Import:** `import { FilterBar } from "@reopt-ai/opt-ui"`
671
+ **Dependencies:** select (core), input (core), button (core), switch (core), checkbox (core), date-range-picker (core)
672
+
673
+ | Prop | Type | Required | Default | Description |
674
+ | ---------------- | ------------------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
675
+ | `filters` | `FilterGroupDef[]` | Yes | | 필터 그룹 배열. { id, label, type, options?, value? } |
676
+ | `onFilterChange` | `(filterId: string, value: string \| string[]) => void` | | | 필터 변경 핸들러 |
677
+ | `onClearAll` | `() => void` | | | 모든 필터 초기화 핸들러 |
678
+
679
+ **Examples:**
680
+
681
+ _필터 바:_
682
+
683
+ ```tsx
684
+ import { FilterBar } from "@reopt-ai/opt-ui";
685
+
686
+ const filters = [
687
+ { id: "status", label: "상태", type: "select", options: ["활성", "비활성"] },
688
+ { id: "search", label: "검색", type: "search" },
689
+ ];
690
+
691
+ <FilterBar
692
+ filters={filters}
693
+ onFilterChange={(id, value) => console.log(id, value)}
694
+ onClearAll={() => console.log("clear")}
695
+ />;
696
+ ```
697
+
698
+ ### SavedFilters
699
+
700
+ > 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI.
701
+
702
+ **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 클래스 |
713
+
714
+ ### QuickActions
715
+
716
+ > 빠른 작업 패널. 그리드/리스트 레이아웃, 단축키 표시 지원.
717
+
718
+ **Import:** `import { QuickActions } from "@reopt-ai/opt-ui"`
719
+ **Dependencies:** kbd (core)
720
+
721
+ | Prop | Type | Required | Default | Description |
722
+ | --------- | ------------------ | -------- | ----------- | ----------------------------------------------------------------- |
723
+ | `actions` | `QuickActionDef[]` | Yes | | 작업 배열. { id, label, description?, icon?, shortcut?, onClick } |
724
+ | `title` | `string` | | "빠른 작업" | 섹션 제목 |
725
+ | `layout` | `"grid" \| "list"` | | "grid" | 레이아웃 모드 |
726
+ | `columns` | `2 \| 3 \| 4` | | 3 | 그리드 컬럼 수 |
727
+
728
+ ### TimeRangeSelector
729
+
730
+ > 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용.
731
+
732
+ **Import:** `import { TimeRangeSelector } from "@reopt-ai/opt-ui"`
733
+ **Dependencies:** button (core), popover (core), date-range-picker (core)
734
+
735
+ | Prop | Type | Required | Default | Description |
736
+ | ---------- | ---------------------------- | -------- | ------- | ------------------------------------ |
737
+ | `value` | `DateRange` | | | 현재 선택된 날짜 범위 |
738
+ | `onChange` | `(range: DateRange) => void` | | | 범위 변경 핸들러 |
739
+ | `presets` | `TimePresetDef[]` | | | 빠른 프리셋 목록 (Today, Last 7d 등) |
740
+ | `labels` | `TimeRangeSelectorLabels` | | | i18n용 라벨 오버라이드 |
741
+
742
+ ### ComparisonSelector
743
+
744
+ > 비교 선택기. 고유 레이블이 연결된 Select × 2 + Swap 버튼 조합. CohortComparison, FunnelAnalysis 등에서 사용합니다.
745
+
746
+ **Import:** `import { ComparisonSelector } from "@reopt-ai/opt-ui"`
747
+ **Dependencies:** select (core), button (core)
748
+
749
+ | Prop | Type | Required | Default | Description |
750
+ | ----------- | -------------------------- | -------- | ------- | ------------------------- |
751
+ | `segments` | `ComparisonOption[]` | Yes | | 선택 가능한 세그먼트 목록 |
752
+ | `valueA` | `string` | | | Base 선택값 |
753
+ | `valueB` | `string` | | | Compare 선택값 |
754
+ | `onChangeA` | `(value: string) => void` | | | Base 변경 핸들러 |
755
+ | `onChangeB` | `(value: string) => void` | | | Compare 변경 핸들러 |
756
+ | `labels` | `ComparisonSelectorLabels` | | | i18n용 라벨 오버라이드 |
757
+
758
+ ### ColumnToggler
759
+
760
+ > 테이블 컬럼 표시/숨김 토글러. Popover + Checkbox 리스트입니다.
761
+
762
+ **Import:** `import { ColumnToggler } from "@reopt-ai/opt-ui"`
763
+ **Dependencies:** popover (core), checkbox (core)
764
+
765
+ | Prop | Type | Required | Default | Description |
766
+ | ---------------- | ------------------------------------ | -------- | ------- | ---------------------- |
767
+ | `columns` | `ColumnTogglerColumn[]` | Yes | | 전체 컬럼 목록 |
768
+ | `visibleColumns` | `string[]` | Yes | | 표시 중인 컬럼 ID 배열 |
769
+ | `onChange` | `(visibleColumns: string[]) => void` | Yes | | 변경 콜백 |
770
+
771
+ ### BulkActions
772
+
773
+ > 일괄 작업 바. 선택 카운트 배지 + DropdownMenu 액션 목록 + 해제 버튼.
774
+
775
+ **Import:** `import { BulkActions } from "@reopt-ai/opt-ui"`
776
+ **Dependencies:** dropdown-menu (core), badge (core)
777
+
778
+ | Prop | Type | Required | Default | Description |
779
+ | --------------- | ---------------------------- | -------- | ------- | -------------------------------------------- |
780
+ | `selectedCount` | `number` | Yes | | 선택된 항목 수 |
781
+ | `actions` | `BulkActionDef[]` | Yes | | 액션 목록. { id, label, variant?: "danger" } |
782
+ | `onAction` | `(actionId: string) => void` | Yes | | 액션 실행 콜백 |
783
+ | `onClear` | `() => void` | Yes | | 선택 해제 콜백 |
784
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
785
+
786
+ ## Forms
787
+
788
+ | Component | Description | Key Exports |
789
+ | ---------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ |
790
+ | SettingsForm | 데이터 기반 설정 폼. 유효성 검증, 라디오, 체크박스 지원. | `SettingsForm` |
791
+ | AuthForm | 로그인/회원가입 모드 전환 가능한 인증 폼. 이메일·비밀번호 검증, FormSwitch로 로그인 상태 유지 옵션 지원. | `AuthForm` |
792
+ | DynamicFieldForm | 런타임 필드 추가/제거 폼. 최소/최대 필드 수 제약, 개별 검증, 동적 스토어 업데이트 지원. | `DynamicFieldForm` |
793
+ | FileUploadForm | 파일 선택, 메타데이터 표시, 이미지 미리보기를 포함한 업로드 폼. 파일 크기 제한, 설명 입력 지원. | `FileUploadForm` |
794
+ | WizardForm | 다단계 순차 입력 폼. FormFieldDef 기반 필드 정의, 단계별 검증, 현재 단계가 연결된 진행 표시기, 리뷰 단계를 지원합니다. | `WizardForm` |
795
+ | ConfirmDialog | 확인/취소 대화 상자. danger 변형으로 위험 작업 확인을 지원합니다. | `ConfirmDialog` |
796
+ | PromptTemplate | AI 프롬프트 뷰어/헬퍼. 변수 입력 → 실시간 치환 → 복사 기능. | `PromptTemplate` |
797
+
798
+ ### SettingsForm
799
+
800
+ > 데이터 기반 설정 폼. 유효성 검증, 라디오, 체크박스 지원.
801
+
802
+ **Import:** `import { SettingsForm } from "@reopt-ai/opt-ui"`
803
+ **Dependencies:** form (core), checkbox (core), radio-group (core), switch (core)
804
+
805
+ | Prop | Type | Required | Default | Description |
806
+ | ---------- | ------------------------------------------- | -------- | ------- | ----------------- |
807
+ | `fields` | `FormFieldDef[]` | Yes | | 폼 필드 정의 배열 |
808
+ | `onSubmit` | `(values: Record<string, unknown>) => void` | | | 제출 핸들러 |
809
+
810
+ **Examples:**
811
+
812
+ _설정 폼:_
813
+
814
+ ```tsx
815
+ import { SettingsForm } from "@reopt-ai/opt-ui";
816
+
817
+ const fields = [
818
+ { name: "username", label: "사용자명", type: "text", required: true },
819
+ { name: "theme", label: "테마", type: "select", options: ["light", "dark"] },
820
+ { name: "notifications", label: "알림", type: "switch" },
821
+ ];
822
+
823
+ <SettingsForm fields={fields} onSubmit={(values) => console.log(values)} />;
824
+ ```
825
+
826
+ ### AuthForm
827
+
828
+ > 로그인/회원가입 모드 전환 가능한 인증 폼. 이메일·비밀번호 검증, FormSwitch로 로그인 상태 유지 옵션 지원.
829
+
830
+ **Import:** `import { AuthForm } from "@reopt-ai/opt-ui"`
831
+ **Dependencies:** form (core)
832
+
833
+ | Prop | Type | Required | Default | Description |
834
+ | ------------------- | ---------------------------------------------------------------------------- | -------- | ------- | -------------------------------------------- |
835
+ | `defaultMode` | `"login" \| "signup"` | | "login" | 초기 모드 (비제어) |
836
+ | `mode` | `"login" \| "signup"` | | | 제어 모드: 현재 모드 |
837
+ | `onModeChange` | `(mode: "login" \| "signup") => void` | | | 모드 변경 핸들러 |
838
+ | `showRememberMe` | `boolean` | | true | 로그인 모드에서 '로그인 상태 유지' 표시 여부 |
839
+ | `minPasswordLength` | `number` | | 8 | 비밀번호 최소 길이 |
840
+ | `onSubmit` | `(values: { email, password, confirmPassword?, rememberMe?, mode }) => void` | | | 제출 핸들러 |
841
+ | `labels` | `AuthFormLabels` | | | i18n용 라벨 오버라이드 |
842
+
843
+ ### DynamicFieldForm
844
+
845
+ > 런타임 필드 추가/제거 폼. 최소/최대 필드 수 제약, 개별 검증, 동적 스토어 업데이트 지원.
846
+
847
+ **Import:** `import { DynamicFieldForm } from "@reopt-ai/opt-ui"`
848
+ **Dependencies:** form (core)
849
+
850
+ | Prop | Type | Required | Default | Description |
851
+ | --------------- | ------------------------------------------------------- | -------- | ------- | ---------------------- |
852
+ | `initialCount` | `number` | | 1 | 초기 필드 수 |
853
+ | `minFields` | `number` | | 1 | 최소 필드 수 |
854
+ | `maxFields` | `number` | | | 최대 필드 수 |
855
+ | `fieldType` | `"text" \| "email" \| "url" \| "number"` | | "text" | 필드 입력 타입 |
856
+ | `validateField` | `(value: string, index: number) => string \| undefined` | | | 커스텀 필드 검증 함수 |
857
+ | `onSubmit` | `(values: string[]) => void` | | | 제출 핸들러 |
858
+ | `labels` | `DynamicFieldFormLabels` | | | i18n용 라벨 오버라이드 |
859
+
860
+ ### FileUploadForm
861
+
862
+ > 파일 선택, 메타데이터 표시, 이미지 미리보기를 포함한 업로드 폼. 파일 크기 제한, 설명 입력 지원.
863
+
864
+ **Import:** `import { FileUploadForm } from "@reopt-ai/opt-ui"`
865
+ **Dependencies:** form (core)
866
+
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 슬롯 (파일 선택 후 표시) |
878
+
879
+ ### WizardForm
880
+
881
+ > 다단계 순차 입력 폼. FormFieldDef 기반 필드 정의, 단계별 검증, 현재 단계가 연결된 진행 표시기, 리뷰 단계를 지원합니다.
882
+
883
+ **Import:** `import { WizardForm } from "@reopt-ai/opt-ui"`
884
+ **Dependencies:** form (core), checkbox (core), radio-group (core)
885
+
886
+ | Prop | Type | Required | Default | Description |
887
+ | -------------- | ------------------------------------------- | -------- | ------- | ------------------------------------------ |
888
+ | `fields` | `FormFieldDef[]` | Yes | | 폼 필드 정의 배열 |
889
+ | `steps` | `WizardStepDef[]` | Yes | | 단계 정의. { id, label, fields: string[] } |
890
+ | `showReview` | `boolean` | | true | 마지막 리뷰 단계 표시 여부 |
891
+ | `onSubmit` | `(values: Record<string, unknown>) => void` | | | 제출 핸들러 |
892
+ | `onStepChange` | `(stepIndex: number) => void` | | | 단계 변경 핸들러 |
893
+ | `labels` | `WizardFormLabels` | | | i18n용 라벨 오버라이드 |
894
+
895
+ ### ConfirmDialog
896
+
897
+ > 확인/취소 대화 상자. danger 변형으로 위험 작업 확인을 지원합니다.
898
+
899
+ **Import:** `import { ConfirmDialog } from "@reopt-ai/opt-ui"`
900
+ **Dependencies:** dialog (core)
901
+
902
+ | Prop | Type | Required | Default | Description |
903
+ | -------------- | ----------------------- | -------- | --------- | ---------------- |
904
+ | `open` | `boolean` | Yes | | 열림 상태 |
905
+ | `onConfirm` | `() => void` | Yes | | 확인 콜백 |
906
+ | `onCancel` | `() => void` | Yes | | 취소 콜백 |
907
+ | `title` | `string` | Yes | | 대화 상자 제목 |
908
+ | `description` | `string` | | | 설명 텍스트 |
909
+ | `confirmLabel` | `string` | | "Confirm" | 확인 버튼 텍스트 |
910
+ | `cancelLabel` | `string` | | "Cancel" | 취소 버튼 텍스트 |
911
+ | `variant` | `"default" \| "danger"` | | "default" | 변형 |
912
+
913
+ ### PromptTemplate
914
+
915
+ > AI 프롬프트 뷰어/헬퍼. 변수 입력 → 실시간 치환 → 복사 기능.
916
+
917
+ **Import:** `import { PromptTemplate } from "@reopt-ai/opt-ui"`
918
+ **Dependencies:** input (core)
919
+
920
+ | Prop | Type | Required | Default | Description |
921
+ | ------------- | ---------------------- | -------- | ------- | ------------------------------------------------------------ |
922
+ | `title` | `string` | Yes | | 프롬프트 제목 |
923
+ | `description` | `string` | | | 프롬프트 설명 (헤더 아래 표시) |
924
+ | `template` | `string` | Yes | | 프롬프트 템플릿. {변수명}으로 치환 가능 |
925
+ | `variables` | `PromptVariable[]` | | | 변수 정의 배열. { name, label, placeholder?, defaultValue? } |
926
+ | `labels` | `PromptTemplateLabels` | | | i18n용 라벨 오버라이드 |
927
+
928
+ ## Infrastructure
929
+
930
+ | Component | Description | Key Exports |
931
+ | ------------------ | --------------------------------------------------------------------------- | -------------------- |
932
+ | DeploymentTimeline | 배포 단계 타임라인. Composite 기반 키보드 탐색 지원. | `DeploymentTimeline` |
933
+ | EnvPanel | 환경변수 패널. Disclosure로 환경별 그룹 접기/펼치기, Composite로 변수 탐색. | `EnvPanel` |
934
+ | WebhookConfig | 웹훅 설정 패널. URL 입력 + 이벤트 체크박스 + 재시도 설정 + 테스트 버튼. | `WebhookConfig` |
935
+ | FeatureFlagPanel | 피처 플래그 관리 패널. 플래그 토글 + 환경 배지 + 롤아웃 % 조절. | `FeatureFlagPanel` |
936
+ | DataImportWizard | 데이터 임포트 마법사. 4단계: 업로드 → 컬럼 매핑 → 미리보기 → 확인. | `DataImportWizard` |
937
+
938
+ ### DeploymentTimeline
939
+
940
+ > 배포 단계 타임라인. Composite 기반 키보드 탐색 지원.
941
+
942
+ **Import:** `import { DeploymentTimeline } from "@reopt-ai/opt-ui"`
943
+
944
+ | Prop | Type | Required | Default | Description |
945
+ | ------- | ------------------ | -------- | --------------- | -------------------------------------------------------- |
946
+ | `steps` | `DeploymentStep[]` | Yes | | 배포 단계 배열. { id, name, status, duration?, detail? } |
947
+ | `title` | `string` | | "배포 타임라인" | 타임라인 제목 |
948
+
949
+ ### EnvPanel
950
+
951
+ > 환경변수 패널. Disclosure로 환경별 그룹 접기/펼치기, Composite로 변수 탐색.
952
+
953
+ **Import:** `import { EnvPanel } from "@reopt-ai/opt-ui"`
954
+ **Dependencies:** disclosure (core)
955
+
956
+ | Prop | Type | Required | Default | Description |
957
+ | -------- | --------------- | -------- | ------- | ------------------------------------------ |
958
+ | `groups` | `EnvGroupDef[]` | Yes | | 환경 그룹 배열. { env, vars: EnvVarDef[] } |
959
+
960
+ ### WebhookConfig
961
+
962
+ > 웹훅 설정 패널. URL 입력 + 이벤트 체크박스 + 재시도 설정 + 테스트 버튼.
963
+
964
+ **Import:** `import { WebhookConfig } from "@reopt-ai/opt-ui"`
965
+ **Dependencies:** input (core), checkbox (core), number-input (core), button (core)
966
+
967
+ | Prop | Type | Required | Default | Description |
968
+ | ----------------- | ------------------------------- | -------- | ------- | ----------------------- |
969
+ | `webhook` | `WebhookDef` | Yes | | 웹훅 설정 객체 |
970
+ | `onChange` | `(webhook: WebhookDef) => void` | Yes | | 변경 콜백 |
971
+ | `availableEvents` | `string[]` | Yes | | 선택 가능한 이벤트 목록 |
972
+ | `onTest` | `() => void` | | | 테스트 버튼 콜백 |
973
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
974
+
975
+ ### FeatureFlagPanel
976
+
977
+ > 피처 플래그 관리 패널. 플래그 토글 + 환경 배지 + 롤아웃 % 조절.
978
+
979
+ **Import:** `import { FeatureFlagPanel } from "@reopt-ai/opt-ui"`
980
+ **Dependencies:** switch (core), badge (core), number-input (core)
981
+
982
+ | Prop | Type | Required | Default | Description |
983
+ | ----------------- | ---------------------------------------------- | -------- | ------- | ------------------ |
984
+ | `flags` | `FeatureFlag[]` | Yes | | 피처 플래그 목록 |
985
+ | `onToggle` | `(flagId: string, enabled: boolean) => void` | Yes | | 토글 콜백 |
986
+ | `onRolloutChange` | `(flagId: string, percentage: number) => void` | | | 롤아웃 % 변경 콜백 |
987
+ | `environments` | `string[]` | Yes | | 전체 환경 목록 |
988
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
989
+
990
+ ### DataImportWizard
991
+
992
+ > 데이터 임포트 마법사. 4단계: 업로드 → 컬럼 매핑 → 미리보기 → 확인.
993
+
994
+ **Import:** `import { DataImportWizard } from "@reopt-ai/opt-ui"`
995
+ **Dependencies:** button (core)
996
+
997
+ | Prop | Type | Required | Default | Description |
998
+ | ----------------- | ------------------------- | -------- | ------- | ------------------- |
999
+ | `fields` | `ImportFieldDef[]` | Yes | | 매핑 대상 필드 목록 |
1000
+ | `onImport` | `(mapping, data) => void` | Yes | | 임포트 확정 콜백 |
1001
+ | `acceptedFormats` | `string` | | ".csv" | 허용 파일 형식 |
1002
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1003
+
1004
+ ## Analytics
1005
+
1006
+ | Component | Description | Key Exports |
1007
+ | ---------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------ |
1008
+ | SqlEditor | SQL 에디터. CodeMirror 기반의 SQL 편집기로 구문 강조와 자동 완성을 지원합니다. | `SqlEditor` |
1009
+ | EventMetaEditor | 이벤트 메타 에디터. 레이블이 연결된 IconPicker + ColorPicker + TagInput 조합으로 이벤트 메타데이터를 편집합니다. | `EventMetaEditor` |
1010
+ | PropertyExplorer | 프로퍼티 탐색기. 검색 가능한 속성 목록을 그룹별로 표시합니다. | `PropertyExplorer` |
1011
+ | RichTextEditor | 마크다운 리치 텍스트 에디터. 서식 툴바 + textarea 조합. | `RichTextEditor` |
1012
+ | ExportButton | 데이터 내보내기 버튼. CSV/JSON 변환 내장, PDF는 콜백 위임. DropdownMenu 기반. | `ExportButton` |
1013
+ | InsightsPanel | 이상 탐지 인사이트 패널. severity별 카드, 통계 필터, dismiss 기능, 검출 설정(유형/Z-score/days). | `InsightsPanel` |
1014
+
1015
+ ### SqlEditor
1016
+
1017
+ > SQL 에디터. CodeMirror 기반의 SQL 편집기로 구문 강조와 자동 완성을 지원합니다.
1018
+
1019
+ **Import:** `import { SqlEditor } from "@reopt-ai/opt-ui"`
1020
+ **Dependencies:** button (core)
1021
+
1022
+ ### EventMetaEditor
1023
+
1024
+ > 이벤트 메타 에디터. 레이블이 연결된 IconPicker + ColorPicker + TagInput 조합으로 이벤트 메타데이터를 편집합니다.
1025
+
1026
+ **Import:** `import { EventMetaEditor } from "@reopt-ai/opt-ui"`
1027
+ **Dependencies:** input (core), icon-picker (core), color-picker (core), tag-input (core)
1028
+
1029
+ ### PropertyExplorer
1030
+
1031
+ > 프로퍼티 탐색기. 검색 가능한 속성 목록을 그룹별로 표시합니다.
1032
+
1033
+ **Import:** `import { PropertyExplorer } from "@reopt-ai/opt-ui"`
1034
+ **Dependencies:** input (core)
1035
+
1036
+ ### RichTextEditor
1037
+
1038
+ > 마크다운 리치 텍스트 에디터. 서식 툴바 + textarea 조합.
1039
+
1040
+ **Import:** `import { RichTextEditor } from "@reopt-ai/opt-ui"`
1041
+
1042
+ | Prop | Type | Required | Default | Description |
1043
+ | ------------- | ------------------------- | -------- | -------------------------------------------------------- | ----------------- |
1044
+ | `value` | `string` | Yes | | 텍스트 값 |
1045
+ | `onChange` | `(value: string) => void` | Yes | | 변경 콜백 |
1046
+ | `placeholder` | `string` | | "Write something…" | 플레이스홀더 |
1047
+ | `toolbar` | `ToolbarAction[]` | | ["bold","italic","code","link","heading","list","quote"] | 툴바 액션 목록 |
1048
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1049
+
1050
+ ### ExportButton
1051
+
1052
+ > 데이터 내보내기 버튼. CSV/JSON 변환 내장, PDF는 콜백 위임. DropdownMenu 기반.
1053
+
1054
+ **Import:** `import { ExportButton } from "@reopt-ai/opt-ui"`
1055
+ **Dependencies:** dropdown-menu (core), button (core)
1056
+
1057
+ | Prop | Type | Required | Default | Description |
1058
+ | ---------- | -------------------------------- | -------- | --------------- | ------------------------ |
1059
+ | `data` | `Record<string, unknown>[]` | Yes | | 내보낼 데이터 배열 |
1060
+ | `columns` | `ExportColumn[]` | | | 컬럼 매핑 (key → header) |
1061
+ | `fileName` | `string` | | "export" | 파일 이름 |
1062
+ | `formats` | `ExportFormat[]` | | ["csv", "json"] | 지원 포맷 |
1063
+ | `onExport` | `(format: ExportFormat) => void` | | | 커스텀 내보내기 핸들러 |
1064
+
1065
+ ### InsightsPanel
1066
+
1067
+ > 이상 탐지 인사이트 패널. severity별 카드, 통계 필터, dismiss 기능, 검출 설정(유형/Z-score/days).
1068
+
1069
+ **Import:** `import { InsightsPanel } from "@reopt-ai/opt-ui"`
1070
+ **Dependencies:** button (core), stat-card (core), badge (core)
1071
+
1072
+ | Prop | Type | Required | Default | Description |
1073
+ | ------------------------- | ----------------------------------- | -------- | ------- | -------------------------------------------------- |
1074
+ | `insights` | `InsightItem[]` | Yes | | 인사이트 항목 배열 |
1075
+ | `stats` | `InsightsStat[]` | | | 통계 필터 카드 배열 (클릭 가능) |
1076
+ | `detectionTypes` | `DetectionTypeDef[]` | | | 검출 유형 토글 배열 (volume_anomaly, new_event 등) |
1077
+ | `detectionConfig` | `DetectionConfig` | | | 검출 파라미터 (days, zScoreThreshold) |
1078
+ | `onDetectionConfigChange` | `(config: DetectionConfig) => void` | | | 검출 파라미터 변경 핸들러 |
1079
+ | `onDismiss` | `(id: string) => void` | | | 인사이트 dismiss 핸들러 |
1080
+
1081
+ ## Builders
1082
+
1083
+ | Component | Description | Key Exports |
1084
+ | -------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------- |
1085
+ | AlertBuilder | 알림 빌더. 명시적으로 연결된 폼 레이블로 메트릭 조건, 빈도, 채널을 구성합니다. | `AlertBuilder` |
1086
+ | SegmentBuilder | 세그먼트 빌더. 각 조건 컨트롤의 접근 가능한 이름을 유지하며 event, property, cohort, custom 세그먼트를 정의합니다. | `SegmentBuilder` |
1087
+ | ReportBuilder | 리포트 빌더. 레이블이 연결된 4단계 위저드 (차트 타입 → 데이터 설정 → 스타일 → 미리보기). | `ReportBuilder` |
1088
+
1089
+ ### AlertBuilder
1090
+
1091
+ > 알림 빌더. 명시적으로 연결된 폼 레이블로 메트릭 조건, 빈도, 채널을 구성합니다.
1092
+
1093
+ **Import:** `import { AlertBuilder } from "@reopt-ai/opt-ui"`
1094
+ **Dependencies:** button (core), input (core)
1095
+
1096
+ ### SegmentBuilder
1097
+
1098
+ > 세그먼트 빌더. 각 조건 컨트롤의 접근 가능한 이름을 유지하며 event, property, cohort, custom 세그먼트를 정의합니다.
1099
+
1100
+ **Import:** `import { SegmentBuilder } from "@reopt-ai/opt-ui"`
1101
+ **Dependencies:** button (core), input (core)
1102
+
1103
+ ### ReportBuilder
1104
+
1105
+ > 리포트 빌더. 레이블이 연결된 4단계 위저드 (차트 타입 → 데이터 설정 → 스타일 → 미리보기).
1106
+
1107
+ **Import:** `import { ReportBuilder } from "@reopt-ai/opt-ui"`
1108
+ **Dependencies:** button (core), input (core)
1109
+
1110
+ | Prop | Type | Required | Default | Description |
1111
+ | ------------- | ------------------------------------------------------------------ | -------- | ------- | ----------------------------------- |
1112
+ | `chartTypes` | `ChartTypeDef[]` | | | 차트 타입 그리드 (기본 9종 제공) |
1113
+ | `dataSources` | `DataSourceDef[]` | | | 데이터 소스 드롭다운 옵션 |
1114
+ | `configForm` | `ReactNode` | | | 차트별 데이터 설정 폼 슬롯 (step 2) |
1115
+ | `styleForm` | `ReactNode` | | | 차트별 스타일 설정 폼 슬롯 (step 3) |
1116
+ | `preview` | `ReactNode` | | | 차트 미리보기 슬롯 (step 4) |
1117
+ | `onSave` | `(report: { name, description, chartType, dataSourceId }) => void` | | | 저장 콜백 |
1118
+ | `onCancel` | `() => void` | | | 취소 콜백 |
1119
+ | `labels` | `ReportBuilderLabels` | | | UI 텍스트 커스터마이징 |
1120
+
1121
+ ## Widgets & Reports
1122
+
1123
+ | Component | Description | Key Exports |
1124
+ | ---------- | ---------------------------------------------------------------------------------------- | ------------ |
1125
+ | WidgetGrid | 위젯 그리드. react-grid-layout 래퍼로 드래그/리사이즈 가능한 대시보드 위젯을 배치합니다. | `WidgetGrid` |
1126
+
1127
+ ### WidgetGrid
1128
+
1129
+ > 위젯 그리드. react-grid-layout 래퍼로 드래그/리사이즈 가능한 대시보드 위젯을 배치합니다.
1130
+
1131
+ **Import:** `import { WidgetGrid } from "@reopt-ai/opt-ui"`
1132
+
1133
+ ## Notification
1134
+
1135
+ | Component | Description | Key Exports |
1136
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
1137
+ | NotificationToast | 토스트 알림 시스템. 포인터/키보드 상호작용 중 자동 닫힘을 일시 정지하고, 중요도별 live region으로 전역 알림을 관리합니다. | `ToastProvider`, `useToast`, `NotificationToast`, `toast` |
1138
+
1139
+ ### NotificationToast
1140
+
1141
+ > 토스트 알림 시스템. 포인터/키보드 상호작용 중 자동 닫힘을 일시 정지하고, 중요도별 live region으로 전역 알림을 관리합니다.
1142
+
1143
+ **Import:** `import { ToastProvider } from "@reopt-ai/opt-ui"`
1144
+ **Dependencies:** alert (core)
1145
+
1146
+ **ToastProvider:**
1147
+
1148
+ | Prop | Type | Required | Default | Description |
1149
+ | ----------------- | -------------------------------------------------------------- | -------- | ----------- | ------------------- |
1150
+ | `children` | `ReactNode` | Yes | | 앱 컨텐츠 |
1151
+ | `position` | `"top-right" \| "top-left" \| "bottom-right" \| "bottom-left"` | | "top-right" | 토스트 표시 위치 |
1152
+ | `defaultDuration` | `number` | | 5000 | 기본 표시 시간 (ms) |
1153
+
1154
+ **useToast:**
1155
+
1156
+ | Prop | Type | Required | Default | Description |
1157
+ | --------- | ----------------------------------- | -------- | ------- | ------------------------ |
1158
+ | `returns` | `{ toasts, addToast, removeToast }` | | | 토스트 상태 및 제어 함수 |
1159
+
1160
+ **toast:**
1161
+
1162
+ | Prop | Type | Required | Default | Description |
1163
+ | ---------------------------------------- | --------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------ |
1164
+ | `toast.success / error / info / warning` | `(message: string, options?) => string` | | | 훅 없이 어디서든 호출하는 프로그램매틱 API. toast.dismiss(id) / toast.clear()도 제공 |
1165
+
1166
+ **NotificationToast:**
1167
+
1168
+ | Prop | Type | Required | Default | Description |
1169
+ | ----------- | -------------- | -------- | ------- | ------------------ |
1170
+ | `toast` | `ToastMessage` | Yes | | 토스트 메시지 객체 |
1171
+ | `onDismiss` | `() => void` | Yes | | 닫기 핸들러 |
1172
+
1173
+ ## Development
1174
+
1175
+ | Component | Description | Key Exports |
1176
+ | ---------------- | --------------------------------------------------------------------------------------------------- | ------------------ |
1177
+ | DesignGuidePanel | 디자인 시스템 참조 패널. 프리미티브 맵, 키보드 패턴, Tailwind 셀렉터, 접근성 속성 등 6개 섹션 제공. | `DesignGuidePanel` |
1178
+
1179
+ ### DesignGuidePanel
1180
+
1181
+ > 디자인 시스템 참조 패널. 프리미티브 맵, 키보드 패턴, Tailwind 셀렉터, 접근성 속성 등 6개 섹션 제공.
1182
+
1183
+ **Import:** `import { DesignGuidePanel } from "@reopt-ai/opt-ui"`
1184
+
1185
+ | Prop | Type | Required | Default | Description |
1186
+ | ----------- | -------- | -------- | ------- | --------------- |
1187
+ | `className` | `string` | | | 추가 CSS 클래스 |
1188
+
1189
+ ## Workflow
1190
+
1191
+ | Component | Description | Key Exports |
1192
+ | -------------- | ---------------------------------------------------------------------------------- | ---------------- |
1193
+ | WorkflowCanvas | 워크플로우 캔버스. 그리드 셀 기반 스텝 배치, SVG 연결선, 키보드 이동을 지원합니다. | `WorkflowCanvas` |
1194
+
1195
+ ### WorkflowCanvas
1196
+
1197
+ > 워크플로우 캔버스. 그리드 셀 기반 스텝 배치, SVG 연결선, 키보드 이동을 지원합니다.
1198
+
1199
+ **Import:** `import { WorkflowCanvas } from "@reopt-ai/opt-ui"`
1200
+ **Dependencies:** badge (core)
1201
+
1202
+ | Prop | Type | Required | Default | Description |
1203
+ | -------------- | ---------------------------------------------------- | -------- | ------- | ------------------------------------------- |
1204
+ | `steps` | `WorkflowCanvasStep[]` | Yes | | 스텝 배열. { id, title, row, col, status? } |
1205
+ | `connections` | `WorkflowCanvasConnection[]` | | [] | 연결선 배열. { from, to, label? } |
1206
+ | `onStepMove` | `(stepId: string, row: number, col: number) => void` | | | 화살표 키 이동 핸들러 |
1207
+ | `onSelectStep` | `(step: WorkflowCanvasStep) => void` | | | 스텝 선택 핸들러 |
1208
+
1209
+ ## Other
1210
+
1211
+ | Component | Description | Key Exports |
1212
+ | --------------- | -------------------------------------------------------------------------- | ----------------- |
1213
+ | PageAside | Sticky 페이지 사이드 aside chrome. 고정 너비 + header/body/footer 3-slot. | `PageAside` |
1214
+ | FailureList | 실패 목록 패널. severity별 색상 강조, 그룹핑, 액션 슬롯을 지원합니다. | `FailureList` |
1215
+ | KeyValueEditor | 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다. | `KeyValueEditor` |
1216
+ | AuditTimeline | 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰. | `AuditTimeline` |
1217
+ | ChatSidebar | AI 채팅 사이드바. 대화 목록, 검색, 새 대화 버튼. | `ChatSidebar` |
1218
+ | ChatInput | 채팅 입력 컴포넌트. 자동 리사이즈 textarea, 파일 첨부, 모델/스타일 Select. | `ChatInput` |
1219
+ | ChatMessageList | 채팅 메시지 목록. 역할별 말풍선, 타이핑 인디케이터, 자동 스크롤. | `ChatMessageList` |
1220
+
1221
+ ### PageAside
1222
+
1223
+ > Sticky 페이지 사이드 aside chrome. 고정 너비 + header/body/footer 3-slot.
1224
+
1225
+ **Import:** `import { PageAside } from "@reopt-ai/opt-ui"`
1226
+
1227
+ | Prop | Type | Required | Default | Description |
1228
+ | ---------------- | ----------- | -------- | ------- | -------------------------------------- |
1229
+ | `header` | `ReactNode` | | | 상단 고정 슬롯 (예: package switcher). |
1230
+ | `children` | `ReactNode` | Yes | | 스크롤 가능한 네비게이션 영역. |
1231
+ | `footer` | `ReactNode` | | | 하단 고정 슬롯 (예: version label). |
1232
+ | `widthClassName` | `string` | | | 너비 Tailwind 클래스. 기본값 `w-60`. |
1233
+ | `label` | `string` | | | `<aside>`의 aria-label. |
1234
+ | `hideOnMobile` | `boolean` | | | md 아래에서 숨김. 기본값 true. |
1235
+
1236
+ ### FailureList
1237
+
1238
+ > 실패 목록 패널. severity별 색상 강조, 그룹핑, 액션 슬롯을 지원합니다.
1239
+
1240
+ **Import:** `import { FailureList } from "@reopt-ai/opt-ui"`
1241
+ **Dependencies:** badge (core)
1242
+
1243
+ | Prop | Type | Required | Default | Description |
1244
+ | ---------------- | ------------------------------------- | -------- | ----------- | -------------------------------------------------------------------- |
1245
+ | `failures` | `FailureItem[]` | Yes | | 실패 항목 배열. { id, title, message?, severity, timestamp, group? } |
1246
+ | `title` | `string` | | "최근 실패" | 섹션 제목 |
1247
+ | `maxItems` | `number` | | | 최대 표시 개수 |
1248
+ | `grouped` | `boolean` | | false | group 필드 기준으로 그룹핑 표시 |
1249
+ | `onFailureClick` | `(failure: FailureItem) => void` | | | 실패 항목 클릭 핸들러 |
1250
+ | `renderActions` | `(failure: FailureItem) => ReactNode` | | | 각 항목 우측 액션 슬롯 렌더 함수 |
1251
+
1252
+ ### KeyValueEditor
1253
+
1254
+ > 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다.
1255
+
1256
+ **Import:** `import { KeyValueEditor } from "@reopt-ai/opt-ui"`
1257
+
1258
+ | Prop | Type | Required | Default | Description |
1259
+ | ------------------ | ---------------------------------------------------------------- | -------- | ------- | --------------------------------- |
1260
+ | `value` | `KeyValueEntry[]` | | | 현재 엔트리 (controlled 모드) |
1261
+ | `defaultValue` | `KeyValueEntry[]` | | | 초기 엔트리 (uncontrolled 모드) |
1262
+ | `onChange` | `(entries: KeyValueEntry[]) => void` | | | 엔트리 변경 핸들러 |
1263
+ | `showSecretToggle` | `boolean` | | false | 비밀값 표시/숨김 토글 버튼 활성화 |
1264
+ | `maxEntries` | `number` | | | 최대 항목 수 제한 |
1265
+ | `readOnly` | `boolean` | | false | 읽기 전용 모드 |
1266
+ | `labels` | `KeyValueEditorLabels` | | | i18n 라벨 오버라이드 |
1267
+ | `renderActions` | `(entry: KeyValueEntry, index: number) => ReactNode` | | | 항목별 커스텀 액션 슬롯 |
1268
+ | `validateKey` | `(key: string, entries: KeyValueEntry[]) => string \| undefined` | | | 키 유효성 검사 함수 |
1269
+
1270
+ ### AuditTimeline
1271
+
1272
+ > 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰.
1273
+
1274
+ **Import:** `import { AuditTimeline } from "@reopt-ai/opt-ui"`
1275
+ **Dependencies:** badge (core), button (core), empty-state (core)
1276
+
1277
+ | Prop | Type | Required | Default | Description |
1278
+ | -------------- | ----------------------------- | -------- | ------- | ---------------------- |
1279
+ | `entries` | `AuditEntry[]` | Yes | | 변경 이력 항목 배열 |
1280
+ | `labels` | `AuditTimelineLabels` | | | UI 텍스트 커스터마이징 |
1281
+ | `onEntryClick` | `(entry: AuditEntry) => void` | | | 항목 클릭 콜백 |
1282
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1283
+
1284
+ ### ChatSidebar
1285
+
1286
+ > AI 채팅 사이드바. 대화 목록, 검색, 새 대화 버튼.
1287
+
1288
+ **Import:** `import { ChatSidebar } from "@reopt-ai/opt-ui"`
1289
+ **Dependencies:** button (core), input (core), scroll-area (core), empty-state (core)
1290
+
1291
+ | Prop | Type | Required | Default | Description |
1292
+ | ---------------------- | --------------------------------------------- | -------- | ------- | --------------------------------------------------------------- |
1293
+ | `conversations` | `ChatConversationDef[]` | Yes | | 대화 목록 배열. { id, title, lastMessage?, timestamp, unread? } |
1294
+ | `activeConversationId` | `string` | | | 현재 활성 대화 ID |
1295
+ | `onConversationSelect` | `(conversation: ChatConversationDef) => void` | | | 대화 선택 핸들러 |
1296
+ | `onNewChat` | `() => void` | | | 새 대화 생성 핸들러 |
1297
+ | `onSearch` | `(query: string) => void` | | | 검색 핸들러 |
1298
+ | `labels` | `ChatSidebarLabels` | | | i18n 라벨 오버라이드 |
1299
+
1300
+ ### ChatInput
1301
+
1302
+ > 채팅 입력 컴포넌트. 자동 리사이즈 textarea, 파일 첨부, 모델/스타일 Select.
1303
+
1304
+ **Import:** `import { ChatInput } from "@reopt-ai/opt-ui"`
1305
+ **Dependencies:** button (core), kbd (core), select (core)
1306
+
1307
+ | Prop | Type | Required | Default | Description |
1308
+ | -------------- | --------------------------- | -------- | ------- | -------------------------- |
1309
+ | `value` | `string` | | | 제어 모드: 입력 값 |
1310
+ | `onSend` | `(message: string) => void` | | | 메시지 전송 핸들러 |
1311
+ | `onFileAttach` | `() => void` | | | 파일 첨부 클릭 핸들러 |
1312
+ | `models` | `ChatModelDef[]` | | | 모델 선택 옵션 |
1313
+ | `stylePresets` | `ChatStylePresetDef[]` | | | 스타일 프리셋 옵션 |
1314
+ | `maxRows` | `number` | | 6 | textarea 최대 행 수 |
1315
+ | `showHint` | `boolean` | | true | Shift+Enter 힌트 표시 여부 |
1316
+ | `labels` | `ChatInputLabels` | | | i18n 라벨 오버라이드 |
1317
+
1318
+ **Examples:**
1319
+
1320
+ _채팅 입력:_
1321
+
1322
+ ```tsx
1323
+ import { ChatInput } from "@reopt-ai/opt-ui";
1324
+
1325
+ <ChatInput
1326
+ placeholder="메시지를 입력하세요..."
1327
+ onSend={(message) => console.log(message)}
1328
+ />;
1329
+ ```
1330
+
1331
+ ### ChatMessageList
1332
+
1333
+ > 채팅 메시지 목록. 역할별 말풍선, 타이핑 인디케이터, 자동 스크롤.
1334
+
1335
+ **Import:** `import { ChatMessageList } from "@reopt-ai/opt-ui"`
1336
+ **Dependencies:** scroll-area (core), avatar (core), empty-state (core)
1337
+
1338
+ | Prop | Type | Required | Default | Description |
1339
+ | ----------------- | ---------------------------------------- | -------- | ------- | --------------------------------------------- |
1340
+ | `messages` | `ChatMessageDef[]` | Yes | | 메시지 배열. { id, role, content, timestamp } |
1341
+ | `loading` | `boolean` | | false | 타이핑 인디케이터 표시 |
1342
+ | `renderContent` | `(message: ChatMessageDef) => ReactNode` | | | 커스텀 메시지 렌더러. 기본: plain text |
1343
+ | `assistantAvatar` | `string` | | | 어시스턴트 아바타 이미지 URL |
1344
+ | `showTimestamps` | `boolean` | | true | 타임스탬프 표시 여부 |
1345
+ | `autoScroll` | `boolean` | | true | 새 메시지 시 자동 스크롤 |
1346
+ | `labels` | `ChatMessageListLabels` | | | i18n 라벨 오버라이드 |
1347
+
1348
+ **Examples:**
1349
+
1350
+ _메시지 목록:_
1351
+
1352
+ ```tsx
1353
+ import { ChatMessageList } from "@reopt-ai/opt-ui";
1354
+
1355
+ const messages = [
1356
+ { id: "1", role: "user", content: "안녕하세요!", timestamp: new Date() },
1357
+ { id: "2", role: "assistant", content: "반갑습니다.", timestamp: new Date() },
1358
+ ];
1359
+
1360
+ <ChatMessageList messages={messages} loading={false} />;
1361
+ ```