@reopt-ai/opt-ui 1.11.0 → 1.12.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 (74) hide show
  1. package/COMPONENT_CATALOG.md +495 -230
  2. package/README.md +43 -5
  3. package/dist/core/index.cjs +2 -2
  4. package/dist/core/index.d.cts +2 -2
  5. package/dist/core/index.d.ts +2 -2
  6. package/dist/core/index.js +2 -2
  7. package/dist/docs/02-components/01-core.md +154 -85
  8. package/dist/docs/02-components/02-visuals.md +1 -1
  9. package/dist/docs/02-components/03-shells.md +349 -149
  10. package/dist/docs/02-components/04-surfaces.md +1 -1
  11. package/dist/docs/02-components/index.md +5 -5
  12. package/dist/docs/03-recipes/02-dashboards.md +126 -10
  13. package/dist/{field-sidebar-B5SQC35J.d.cts → field-sidebar-CrYlRZew.d.ts} +164 -154
  14. package/dist/{field-sidebar-DAuN4jPV.cjs → field-sidebar-oa6zOmcd.cjs} +1540 -1537
  15. package/dist/{field-sidebar-CBeWE8xX.d.ts → field-sidebar-uXmoyvd7.d.cts} +164 -154
  16. package/dist/{field-sidebar-BXl5RJ3q.js → field-sidebar-zkkqC7__.js} +1541 -1540
  17. package/dist/id-registry.cjs +78 -6
  18. package/dist/id-registry.d.cts +1 -2
  19. package/dist/id-registry.d.ts +1 -2
  20. package/dist/id-registry.js +78 -8
  21. package/dist/id-registry.json +168 -19
  22. package/dist/index.cjs +1127 -224
  23. package/dist/index.d.cts +567 -58
  24. package/dist/index.d.ts +567 -58
  25. package/dist/index.js +1118 -227
  26. package/dist/{key-pad-menu-BxTy_u0Q.d.cts → key-pad-menu-CwcY_Vps.d.cts} +2 -3
  27. package/dist/{key-pad-menu-wXkWn1I1.js → key-pad-menu-Di2aRGbM.js} +4 -6
  28. package/dist/{key-pad-menu-Cg6rZBie.cjs → key-pad-menu-SItoHPLu.cjs} +1 -1
  29. package/dist/{key-pad-menu-u5GTJl9B.d.ts → key-pad-menu-WBJShCJn.d.ts} +3 -4
  30. package/dist/meta.cjs +894 -28
  31. package/dist/meta.d.cts +12 -36
  32. package/dist/meta.d.ts +12 -36
  33. package/dist/meta.js +894 -30
  34. package/dist/query.d.cts +1 -2
  35. package/dist/query.d.ts +1 -2
  36. package/dist/query.js +0 -2
  37. package/dist/shells/index.cjs +1 -1
  38. package/dist/shells/index.d.cts +1 -1
  39. package/dist/shells/index.d.ts +1 -1
  40. package/dist/shells/index.js +1 -1
  41. package/dist/tailwind.css +7 -0
  42. package/dist/{text-truncate-DW78lg4S.d.cts → text-truncate-CQyfUZvq.d.cts} +31 -3
  43. package/dist/{text-truncate-DW78lg4S.d.ts → text-truncate-CQyfUZvq.d.ts} +31 -3
  44. package/dist/{text-truncate-C17HHCR-.js → text-truncate-DSuZECy0.js} +43 -10
  45. package/dist/{text-truncate-BZdL1k5Z.cjs → text-truncate-I1XLWmRa.cjs} +48 -7
  46. package/dist/theme/server.d.cts +1 -2
  47. package/dist/theme/server.d.ts +1 -2
  48. package/dist/theme/server.js +0 -2
  49. package/dist/visuals/index.js +0 -1
  50. package/package.json +4 -3
  51. package/dist/field-sidebar-B5SQC35J.d.cts.map +0 -1
  52. package/dist/field-sidebar-BXl5RJ3q.js.map +0 -1
  53. package/dist/field-sidebar-CBeWE8xX.d.ts.map +0 -1
  54. package/dist/id-registry.d.cts.map +0 -1
  55. package/dist/id-registry.d.ts.map +0 -1
  56. package/dist/id-registry.js.map +0 -1
  57. package/dist/index.d.cts.map +0 -1
  58. package/dist/index.d.ts.map +0 -1
  59. package/dist/index.js.map +0 -1
  60. package/dist/key-pad-menu-BxTy_u0Q.d.cts.map +0 -1
  61. package/dist/key-pad-menu-u5GTJl9B.d.ts.map +0 -1
  62. package/dist/key-pad-menu-wXkWn1I1.js.map +0 -1
  63. package/dist/meta.d.cts.map +0 -1
  64. package/dist/meta.d.ts.map +0 -1
  65. package/dist/meta.js.map +0 -1
  66. package/dist/query.d.cts.map +0 -1
  67. package/dist/query.d.ts.map +0 -1
  68. package/dist/query.js.map +0 -1
  69. package/dist/text-truncate-C17HHCR-.js.map +0 -1
  70. package/dist/text-truncate-DW78lg4S.d.cts.map +0 -1
  71. package/dist/text-truncate-DW78lg4S.d.ts.map +0 -1
  72. package/dist/theme/server.d.cts.map +0 -1
  73. package/dist/theme/server.d.ts.map +0 -1
  74. package/dist/theme/server.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: "Shell Components"
3
- description: "83 Shell layer components — props, examples, keyboard shortcuts."
4
- version: "1.10.0"
3
+ description: "86 Shell layer components — props, examples, keyboard shortcuts."
4
+ version: "1.12.0"
5
5
  generated: true
6
6
  ---
7
7
 
8
- # Shell Components (83)
8
+ # Shell Components (86)
9
9
 
10
10
  ## Navigation & Layout
11
11
 
@@ -38,6 +38,15 @@ generated: true
38
38
  | ------- | ----------- | -------- | ------- | --------------------------------------------------- |
39
39
  | `menus` | `MenuDef[]` | Yes | | 메뉴 정의 배열. { id, label, items: MenuItemDef[] } |
40
40
 
41
+ **Keyboard Shortcuts:**
42
+
43
+ | Keys | Action |
44
+ | ------------------- | -------------------------- |
45
+ | `← →` | 상위 메뉴 사이 포커스 이동 |
46
+ | `Enter / Space / ↓` | 메뉴 열기 |
47
+ | `↑ ↓` | 열린 메뉴 항목 이동 |
48
+ | `Escape` | 메뉴 닫고 트리거로 복귀 |
49
+
41
50
  ### MegaMenu
42
51
 
43
52
  > 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯.
@@ -45,13 +54,22 @@ generated: true
45
54
  **Import:** `import { MegaMenu } from "@reopt-ai/opt-ui"`
46
55
  **Dependencies:** popover (core)
47
56
 
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 클래스 |
57
+ | Prop | Type | Required | Default | Description |
58
+ | -------------- | ------------------- | -------- | ------- | ------------------------------------------- |
59
+ | `menus` | `MegaMenuSection[]` | Yes | | 메뉴 섹션 배열 |
60
+ | `columns` | `number` | | 3 | 그리드 컬럼 수 |
61
+ | `footer` | `ReactNode` | | | 하단 footer 슬롯 |
62
+ | `triggerLabel` | `string` | | "Menu" | 트리거 버튼 텍스트 |
63
+ | `aria-label` | `string` | | | 열린 메가 메뉴 탐색 영역의 접근 가능한 이름 |
64
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
65
+
66
+ **Keyboard Shortcuts:**
67
+
68
+ | Keys | Action |
69
+ | --------------- | -------------------------- |
70
+ | `Enter / Space` | 메가 메뉴 열기 |
71
+ | `Tab` | 메뉴 링크와 액션 사이 이동 |
72
+ | `Escape` | 메가 메뉴 닫기 |
55
73
 
56
74
  ### SidebarNav
57
75
 
@@ -165,6 +183,13 @@ import { AppShell } from "@reopt-ai/opt-ui";
165
183
  | `defaultTabId` | `string` | | | 기본 선택 탭 ID |
166
184
  | `className` | `string` | | | 커스텀 CSS 클래스 |
167
185
 
186
+ **Keyboard Shortcuts:**
187
+
188
+ | Keys | Action |
189
+ | ------------ | ------------------------------- |
190
+ | `↑ ↓` | 세로 탭 사이 이동 및 선택 |
191
+ | `Home / End` | 첫 번째 또는 마지막 탭으로 이동 |
192
+
168
193
  ### FaqAccordion
169
194
 
170
195
  > FAQ 질문/답변 아코디언. Composite + Disclosure 조합.
@@ -176,6 +201,13 @@ import { AppShell } from "@reopt-ai/opt-ui";
176
201
  | ------- | ----------- | -------- | ------- | --------------------------------------- |
177
202
  | `items` | `FaqItem[]` | Yes | | FAQ 항목 배열. { id, question, answer } |
178
203
 
204
+ **Keyboard Shortcuts:**
205
+
206
+ | Keys | Action |
207
+ | --------------- | --------------------- |
208
+ | `↑ ↓` | 질문 사이 포커스 이동 |
209
+ | `Enter / Space` | 답변 펼치기 또는 접기 |
210
+
179
211
  ### CommandPalette
180
212
 
181
213
  > Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색.
@@ -183,17 +215,17 @@ import { AppShell } from "@reopt-ai/opt-ui";
183
215
  **Import:** `import { CommandPalette } from "@reopt-ai/opt-ui"`
184
216
  **Dependencies:** dialog (core), combobox (core), kbd (core)
185
217
 
186
- | Prop | Type | Required | Default | Description |
187
- | --------------- | -------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
188
- | `commands` | `Omit<Command, "action">[]` | Yes | | 커맨드 목록. { id, label, group, shortcut? } |
189
- | `open` | `boolean` | Yes | | 열림 상태 |
190
- | `onOpenChange` | `(open: boolean) => void` | Yes | | 상태 변경 핸들러 |
191
- | `onSelect` | `(command: Omit<Command, 'action'>) => void` | | | 커맨드 선택 핸들러 |
192
- | `inline` | `boolean` | | false | true일 때 풀스크린 Dialog 대신 인라인 팝업으로 렌더링 |
193
- | `labels` | `CommandPaletteLabels` | | | title/description/input/list/empty/escape 문구 |
194
- | `footer` | `ReactNode` | | | 명령 목록 아래에 표시할 footer slot |
195
- | `empty` | `ReactNode` | | | 결과가 없을 때 표시할 empty slot |
196
- | `inputTrailing` | `ReactNode` | | | 검색 입력 우측 보조 콘텐츠 |
218
+ | Prop | Type | Required | Default | Description |
219
+ | --------------- | ----------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
220
+ | `commands` | `Omit<CommandDef, "action">[]` | Yes | | 커맨드 목록. { id, label, group, shortcut? } |
221
+ | `open` | `boolean` | Yes | | 열림 상태 |
222
+ | `onOpenChange` | `(open: boolean) => void` | Yes | | 상태 변경 핸들러 |
223
+ | `onSelect` | `(command: Omit<CommandDef, "action">) => void` | | | 커맨드 선택 핸들러 |
224
+ | `inline` | `boolean` | | false | true일 때 풀스크린 Dialog 대신 인라인 팝업으로 렌더링 |
225
+ | `labels` | `CommandPaletteLabels` | | | title/description/input/list/empty/escape 문구 |
226
+ | `footer` | `ReactNode` | | | 명령 목록 아래에 표시할 footer slot |
227
+ | `empty` | `ReactNode` | | | 결과가 없을 때 표시할 empty slot |
228
+ | `inputTrailing` | `ReactNode` | | | 검색 입력 우측 보조 콘텐츠 |
197
229
 
198
230
  ### CommandPaletteTrigger
199
231
 
@@ -202,11 +234,11 @@ import { AppShell } from "@reopt-ai/opt-ui";
202
234
  **Import:** `import { CommandPaletteTrigger } from "@reopt-ai/opt-ui"`
203
235
  **Dependencies:** command-palette (shells)
204
236
 
205
- | Prop | Type | Required | Default | Description |
206
- | ---------- | -------------------------------------------- | -------- | ------- | -------------------------------------------------- |
207
- | `commands` | `Omit<Command, "action">[]` | Yes | | 커맨드 목록 |
208
- | `onSelect` | `(command: Omit<Command, 'action'>) => void` | | | 커맨드 선택 핸들러 |
209
- | `labels` | `CommandPaletteTriggerLabels` | | | 내부 CommandPalette에 전달할 title/input/list 문구 |
237
+ | Prop | Type | Required | Default | Description |
238
+ | ---------- | ----------------------------------------------- | -------- | ------- | -------------------------------------------------- |
239
+ | `commands` | `Omit<CommandDef, "action">[]` | Yes | | 커맨드 목록 |
240
+ | `onSelect` | `(command: Omit<CommandDef, "action">) => void` | | | 커맨드 선택 핸들러 |
241
+ | `labels` | `CommandPaletteTriggerLabels` | | | 내부 CommandPalette에 전달할 title/input/list 문구 |
210
242
 
211
243
  ### ProjectSwitcher
212
244
 
@@ -267,37 +299,38 @@ import { AppShell } from "@reopt-ai/opt-ui";
267
299
 
268
300
  ## Data Display
269
301
 
270
- | Component | Description | Key Exports |
271
- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
272
- | DataTable | 제네릭 데이터 테이블. 동적 컬럼, 결측값 안전 정렬, 키보드 컬럼 리사이즈, 보정된 인라인 진행률과 Composite 탐색을 지원합니다. | `DataTable` |
273
- | InlineEditTable | 인라인 편집 테이블. 더블클릭으로 셀 편집, Enter 확정, Escape 취소. | `InlineEditTable` |
274
- | TreeTable | 계층형 트리 테이블. 재귀 행 렌더링 + 펼침/접기 셰브론. | `TreeTable` |
275
- | DomainTable | 도메인 테이블. Composite 기반 그리드로 키보드 탐색 지원. | `DomainTable` |
276
- | QueryResultsTable | 쿼리 결과 테이블. SQL 결과와 스크린 리더에 안내되는 로딩, 에러, 빈 상태를 지원합니다. | `QueryResultsTable` |
277
- | DashboardGrid | Composite 기반 통계 카드 그리드. 유효한 1–4열 레이아웃과 화살표 키 2D 탐색을 지원합니다. | `DashboardGrid` |
278
- | SummaryRow | 통계 요약 행. StatCard 그리드 레이아웃을 표준화합니다. loading 시 SkeletonCard 표시. | `SummaryRow` |
279
- | CodeSnippetViewer | 코드 스니펫 뷰어. 줄 번호, 복사 버튼, 포커스 가능한 스크롤 영역, syntaxTheme 톤을 지원합니다. | `CodeSnippetViewer` |
280
- | CodeDiffViewer | 코드 비교 뷰어. LCS 알고리즘 기반 unified/split 모드 diff와 포커스 가능한 스크롤 영역을 제공합니다. | `CodeDiffViewer` |
281
- | ConnectionIndicator | 연결 상태 표시기. connected, connecting, disconnected, error 상태를 지원합니다. | `ConnectionIndicator` |
282
- | EventIcon | 이벤트 아이콘. semantic key 또는 ReactNode 아이콘과 배경색을 표시합니다. | `EventIcon`, `POPULAR_ICONS`, `COLOR_PRESETS` |
302
+ | Component | Description | Key Exports |
303
+ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
304
+ | DataTable | 제네릭 데이터 테이블. 제목은 opt-in이고 ariaLabel로 grid를 이름 붙이며, 동적 컬럼·안전 정렬·키보드 리사이즈·Composite 탐색을 지원합니다. | `DataTable` |
305
+ | InlineEditTable | 인라인 편집 테이블. 더블클릭으로 셀 편집, Enter 확정, Escape 취소. | `InlineEditTable` |
306
+ | TreeTable | 계층형 트리 테이블. 재귀 행 렌더링 + 펼침/접기 셰브론. | `TreeTable` |
307
+ | DomainTable | 도메인 테이블. Composite 기반 그리드로 키보드 탐색 지원. | `DomainTable` |
308
+ | QueryResultsTable | 쿼리 결과 테이블. SQL 결과와 스크린 리더에 안내되는 로딩, 에러, 빈 상태를 지원합니다. | `QueryResultsTable` |
309
+ | DashboardGrid | Composite 기반 통계 카드 그리드. 유효한 1–4열 레이아웃과 화살표 키 2D 탐색을 지원합니다. | `DashboardGrid` |
310
+ | SummaryRow | 통계 요약 행. StatCard 그리드 레이아웃을 표준화합니다. loading 시 SkeletonCard 표시. | `SummaryRow` |
311
+ | CodeSnippetViewer | 코드 스니펫 뷰어. 줄 번호, 복사 버튼, 포커스 가능한 스크롤 영역, syntaxTheme 톤을 지원합니다. | `CodeSnippetViewer` |
312
+ | CodeDiffViewer | 코드 비교 뷰어. LCS 알고리즘 기반 unified/split 모드 diff와 포커스 가능한 스크롤 영역을 제공합니다. | `CodeDiffViewer` |
313
+ | ConnectionIndicator | 연결 상태 표시기. connected, connecting, disconnected, error 상태를 지원합니다. | `ConnectionIndicator` |
314
+ | EventIcon | 이벤트 아이콘. semantic key 또는 ReactNode 아이콘과 배경색을 표시합니다. | `EventIcon`, `POPULAR_ICONS`, `COLOR_PRESETS` |
283
315
 
284
316
  ### DataTable
285
317
 
286
- > 제네릭 데이터 테이블. 동적 컬럼, 결측값 안전 정렬, 키보드 컬럼 리사이즈, 보정된 인라인 진행률과 Composite 탐색을 지원합니다.
318
+ > 제네릭 데이터 테이블. 제목은 opt-in이고 ariaLabel로 grid를 이름 붙이며, 동적 컬럼·안전 정렬·키보드 리사이즈·Composite 탐색을 지원합니다.
287
319
 
288
320
  **Import:** `import { DataTable } from "@reopt-ai/opt-ui"`
289
321
  **Dependencies:** composite-zone (core), button (core), checkbox (core)
290
322
 
291
323
  **DataTable:**
292
324
 
293
- | Prop | Type | Required | Default | Description |
294
- | -------------- | -------------------- | -------- | ------------------- | --------------------------------------------------- |
295
- | `data` | `T[]` | Yes | | 테이블 데이터 배열 |
296
- | `columns` | `ColumnDef<T>[]` | Yes | | 컬럼 정의. { id, header, accessor, width?, align? } |
297
- | `keyExtractor` | `(row: T) => string` | Yes | | 각 행의 고유 키 추출 함수 |
298
- | `title` | `string` | | "데이터 테이블" | 테이블 제목 |
299
- | `onRowClick` | `(row: T) => void` | | | 클릭 핸들러 |
300
- | `emptyMessage` | `string` | | "데이터가 없습니다" | 데이터 없을 때 표시할 메시지 |
325
+ | Prop | Type | Required | Default | Description |
326
+ | -------------- | -------------------- | -------- | ------------------- | ----------------------------------------------------------- |
327
+ | `data` | `T[]` | Yes | | 테이블 데이터 배열 |
328
+ | `columns` | `ColumnDef<T>[]` | Yes | | 컬럼 정의. { id, header, accessor, width?, align? } |
329
+ | `keyExtractor` | `(row: T) => string` | Yes | | 각 행의 고유 키 추출 함수 |
330
+ | `title` | `string` | | | 테이블 위에 표시할 제목. 생략하면 제목 영역을 렌더하지 않음 |
331
+ | `ariaLabel` | `string` | | | 보이는 제목이 없을 때 grid에 제공할 접근 가능한 이름 |
332
+ | `onRowClick` | `(row: T) => void` | | | 클릭 핸들러 |
333
+ | `emptyMessage` | `string` | | "No data available" | 데이터 없을 때 표시할 메시지 |
301
334
 
302
335
  **ColumnDef:**
303
336
 
@@ -375,13 +408,22 @@ import { DataTable } from "@reopt-ai/opt-ui";
375
408
  **Import:** `import { TreeTable } from "@reopt-ai/opt-ui"`
376
409
  **Dependencies:** data-table (shells)
377
410
 
378
- | Prop | Type | Required | Default | Description |
379
- | ----------------- | -------------------- | -------- | ------- | ------------------ |
380
- | `data` | `TreeNode<T>[]` | Yes | | 트리 노드 배열 |
381
- | `columns` | `TreeColumnDef<T>[]` | Yes | | 컬럼 정의 |
382
- | `defaultExpanded` | `string[]` | | [] | 기본 펼침 노드 ID |
383
- | `indentSize` | `number` | | 24 | 들여쓰기 크기 (px) |
384
- | `className` | `string` | | | 커스텀 CSS 클래스 |
411
+ | Prop | Type | Required | Default | Description |
412
+ | ----------------- | ------------------------------- | -------- | ------- | ----------------------------------------------- |
413
+ | `data` | `TreeNode<T>[]` | Yes | | 트리 노드 배열 |
414
+ | `columns` | `TreeColumnDef<T>[]` | Yes | | 컬럼 정의 |
415
+ | `defaultExpanded` | `string[]` | | [] | 기본 펼침 노드 ID |
416
+ | `indentSize` | `number` | | 24 | 들여쓰기 크기 (px) |
417
+ | `getRowLabel` | `(node: TreeNode<T>) => string` | | | 행별 펼침/접기 컨트롤의 접근 가능한 이름 생성기 |
418
+ | `aria-label` | `string` | | | 표의 접근 가능한 이름 |
419
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
420
+
421
+ **Keyboard Shortcuts:**
422
+
423
+ | Keys | Action |
424
+ | --------------- | -------------------------- |
425
+ | `Tab` | 펼침/접기 컨트롤 사이 이동 |
426
+ | `Enter / Space` | 하위 행 펼치기 또는 접기 |
385
427
 
386
428
  ### DomainTable
387
429
 
@@ -592,13 +634,13 @@ import { DataTable } from "@reopt-ai/opt-ui";
592
634
  **Import:** `import { KanbanBoard } from "@reopt-ai/opt-ui"`
593
635
  **Dependencies:** scroll-area (core)
594
636
 
595
- | Prop | Type | Required | Default | Description |
596
- | -------------- | ------------------------------------------- | -------- | ------- | -------------------------------- |
597
- | `columns` | `KanbanColumn<T>[]` | Yes | | 컬럼 목록 (각 컬럼에 items 배열) |
598
- | `onDragEnd` | `(itemId, fromCol, toCol, toIndex) => void` | Yes | | 드래그 완료 콜백 |
599
- | `renderCard` | `(item: T) => ReactNode` | Yes | | 카드 렌더링 함수 |
600
- | `keyExtractor` | `(item: T) => string` | Yes | | 항목 키 추출기 |
601
- | `className` | `string` | | | 커스텀 CSS 클래스 |
637
+ | Prop | Type | Required | Default | Description |
638
+ | -------------- | ------------------------------------------------------------------------------------- | -------- | ------- | -------------------------------- |
639
+ | `columns` | `KanbanColumn<T>[]` | Yes | | 컬럼 목록 (각 컬럼에 items 배열) |
640
+ | `onDragEnd` | `(itemId: string, fromColumnId: string, toColumnId: string, toIndex: number) => void` | Yes | | 드래그 완료 콜백 |
641
+ | `renderCard` | `(item: T) => ReactNode` | Yes | | 카드 렌더링 함수 |
642
+ | `keyExtractor` | `(item: T) => string` | Yes | | 항목 키 추출기 |
643
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
602
644
 
603
645
  ### AuditLog
604
646
 
@@ -684,15 +726,15 @@ import { SearchCombobox } from "@reopt-ai/opt-ui";
684
726
  **Import:** `import { AsyncCombobox } from "@reopt-ai/opt-ui"`
685
727
  **Dependencies:** combobox (core), spinner (core)
686
728
 
687
- | Prop | Type | Required | Default | Description |
688
- | ------------- | ---------------------------------- | -------- | --------- | ---------------------------------------- |
689
- | `onSearch` | `(q: string) => Promise<string[]>` | Yes | | 검색 콜백 |
690
- | `debounceMs` | `number` | | 300 | 디바운스 ms |
691
- | `minChars` | `number` | | 1 | 최소 검색 글자 수 |
692
- | `placeholder` | `string` | | "Search…" | 플레이스홀더 |
693
- | `onSelect` | `(value: string) => void` | | | 선택 콜백 |
694
- | `labels` | `AsyncComboboxLabels` | | | input/loading/noResults/placeholder 문구 |
695
- | `loadingText` | `string` | | | 로딩 문구. labels.loading 사용 권장 |
729
+ | Prop | Type | Required | Default | Description |
730
+ | ------------- | -------------------------------------- | -------- | --------- | ----------------------------------------------------------------------------- |
731
+ | `onSearch` | `(query: string) => Promise<string[]>` | Yes | | 검색 콜백 |
732
+ | `debounceMs` | `number` | | 300 | 디바운스 ms |
733
+ | `minChars` | `number` | | 1 | 최소 검색 글자 수 |
734
+ | `placeholder` | `string` | | "Search…" | 플레이스홀더 **⚠️ deprecated since 1.9.0 — use `labels.placeholder` instead** |
735
+ | `onSelect` | `(value: string) => void` | | | 선택 콜백 |
736
+ | `labels` | `AsyncComboboxLabels` | | | input/loading/noResults/placeholder 문구 |
737
+ | `loadingText` | `string` | | | 로딩 문구 **⚠️ deprecated since 1.9.0 — use `labels.loading` instead** |
696
738
 
697
739
  ### StatusSelect
698
740
 
@@ -729,11 +771,11 @@ import { SearchCombobox } from "@reopt-ai/opt-ui";
729
771
  **Import:** `import { FilterBar } from "@reopt-ai/opt-ui"`
730
772
  **Dependencies:** select (core), input (core), button (core), switch (core), checkbox (core), date-range-picker (core)
731
773
 
732
- | Prop | Type | Required | Default | Description |
733
- | ---------------- | ------------------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
734
- | `filters` | `FilterGroupDef[]` | Yes | | 필터 그룹 배열. { id, label, type, options?, value? } |
735
- | `onFilterChange` | `(filterId: string, value: string \| string[]) => void` | | | 필터 변경 핸들러 |
736
- | `onClearAll` | `() => void` | | | 모든 필터 초기화 핸들러 |
774
+ | Prop | Type | Required | Default | Description |
775
+ | ---------------- | ------------------------------------------------------------------ | -------- | ------- | ----------------------------------------------------- |
776
+ | `filters` | `FilterGroupDef[]` | Yes | | 필터 그룹 배열. { id, label, type, options?, value? } |
777
+ | `onFilterChange` | `(filterId: string, value: string \| string[] \| boolean) => void` | | | 필터 변경 핸들러 |
778
+ | `onClearAll` | `() => void` | | | 모든 필터 초기화 핸들러 |
737
779
 
738
780
  **Examples:**
739
781
 
@@ -921,15 +963,15 @@ const fields = [
921
963
  **Import:** `import { AuthForm } from "@reopt-ai/opt-ui"`
922
964
  **Dependencies:** form (core)
923
965
 
924
- | Prop | Type | Required | Default | Description |
925
- | ------------------- | ---------------------------------------------------------------------------- | -------- | ------- | -------------------------------------------- |
926
- | `defaultMode` | `"login" \| "signup"` | | "login" | 초기 모드 (비제어) |
927
- | `mode` | `"login" \| "signup"` | | | 제어 모드: 현재 모드 |
928
- | `onModeChange` | `(mode: "login" \| "signup") => void` | | | 모드 변경 핸들러 |
929
- | `showRememberMe` | `boolean` | | true | 로그인 모드에서 '로그인 상태 유지' 표시 여부 |
930
- | `minPasswordLength` | `number` | | 8 | 비밀번호 최소 길이 |
931
- | `onSubmit` | `(values: { email, password, confirmPassword?, rememberMe?, mode }) => void` | | | 제출 핸들러 |
932
- | `labels` | `AuthFormLabels` | | | i18n용 라벨 오버라이드 |
966
+ | Prop | Type | Required | Default | Description |
967
+ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | -------------------------------------------- |
968
+ | `defaultMode` | `"login" \| "signup"` | | "login" | 초기 모드 (비제어) |
969
+ | `mode` | `"login" \| "signup"` | | | 제어 모드: 현재 모드 |
970
+ | `onModeChange` | `(mode: "login" \| "signup") => void` | | | 모드 변경 핸들러 |
971
+ | `showRememberMe` | `boolean` | | true | 로그인 모드에서 '로그인 상태 유지' 표시 여부 |
972
+ | `minPasswordLength` | `number` | | 8 | 비밀번호 최소 길이 |
973
+ | `onSubmit` | `(values: { email: string; password: string; confirmPassword?: string; rememberMe?: boolean; mode: "login" \| "signup" }) => void` | | | 제출 핸들러 |
974
+ | `labels` | `AuthFormLabels` | | | i18n용 라벨 오버라이드 |
933
975
 
934
976
  ### DynamicFieldForm
935
977
 
@@ -955,17 +997,17 @@ const fields = [
955
997
  **Import:** `import { FileUploadForm } from "@reopt-ai/opt-ui"`
956
998
  **Dependencies:** form (core)
957
999
 
958
- | Prop | Type | Required | Default | Description |
959
- | ----------------- | ------------------------------------------------ | -------- | ------------------------- | ----------------------------------------- |
960
- | `accept` | `string` | | "image/*,.pdf,.doc,.docx" | 허용 파일 타입 |
961
- | `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
962
- | `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
963
- | `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
964
- | `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
965
- | `onSubmit` | `(values: { title, description, file }) => void` | | | 제출 핸들러 |
966
- | `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
967
- | `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
968
- | `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
1000
+ | Prop | Type | Required | Default | Description |
1001
+ | ----------------- | ------------------------------------------------------------------------------ | -------- | ------------------------- | ----------------------------------------- |
1002
+ | `accept` | `string` | | "image/*,.pdf,.doc,.docx" | 허용 파일 타입 |
1003
+ | `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
1004
+ | `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
1005
+ | `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
1006
+ | `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
1007
+ | `onSubmit` | `(values: { title: string; description: string; file: File \| null }) => void` | | | 제출 핸들러 |
1008
+ | `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
1009
+ | `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
1010
+ | `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
969
1011
 
970
1012
  ### WizardForm
971
1013
 
@@ -1085,23 +1127,23 @@ const fields = [
1085
1127
  **Import:** `import { DataImportWizard } from "@reopt-ai/opt-ui"`
1086
1128
  **Dependencies:** button (core)
1087
1129
 
1088
- | Prop | Type | Required | Default | Description |
1089
- | ----------------- | ------------------------- | -------- | ------- | ------------------- |
1090
- | `fields` | `ImportFieldDef[]` | Yes | | 매핑 대상 필드 목록 |
1091
- | `onImport` | `(mapping, data) => void` | Yes | | 임포트 확정 콜백 |
1092
- | `acceptedFormats` | `string` | | ".csv" | 허용 파일 형식 |
1093
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1130
+ | Prop | Type | Required | Default | Description |
1131
+ | ----------------- | ------------------------------------------------------------- | -------- | ------- | ------------------- |
1132
+ | `fields` | `ImportFieldDef[]` | Yes | | 매핑 대상 필드 목록 |
1133
+ | `onImport` | `(mapping: Record<string, string>, data: string[][]) => void` | Yes | | 임포트 확정 콜백 |
1134
+ | `acceptedFormats` | `string` | | ".csv" | 허용 파일 형식 |
1135
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1094
1136
 
1095
1137
  ## Analytics
1096
1138
 
1097
- | Component | Description | Key Exports |
1098
- | ---------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------ |
1099
- | SqlEditor | SQL 에디터. CodeMirror 기반의 SQL 편집기로 구문 강조와 자동 완성을 지원합니다. | `SqlEditor` |
1100
- | EventMetaEditor | 이벤트 메타 에디터. 레이블이 연결된 IconPicker + ColorPicker + TagInput 조합으로 이벤트 메타데이터를 편집합니다. | `EventMetaEditor` |
1101
- | PropertyExplorer | 프로퍼티 탐색기. 검색 가능한 속성 목록을 그룹별로 표시합니다. | `PropertyExplorer` |
1102
- | RichTextEditor | 마크다운 리치 텍스트 에디터. 서식 툴바 + textarea 조합. | `RichTextEditor` |
1103
- | ExportButton | 데이터 내보내기 버튼. CSV/JSON 변환 내장, PDF는 콜백 위임. DropdownMenu 기반. | `ExportButton` |
1104
- | InsightsPanel | 이상 탐지 인사이트 패널. severity별 카드, 통계 필터, dismiss 기능, 검출 설정(유형/Z-score/days). | `InsightsPanel` |
1139
+ | Component | Description | Key Exports |
1140
+ | ---------------- | ---------------------------------------------------------------------------------------------------------- | ------------------ |
1141
+ | SqlEditor | SQL 에디터. CodeMirror 기반의 SQL 편집기로 구문 강조와 자동 완성을 지원합니다. | `SqlEditor` |
1142
+ | EventMetaEditor | 기본 이벤트 메타와 호출자 소유 섹션을 폼에서 편집하고, footer의 액션으로 함께 저장할 있습니다. | `EventMetaEditor` |
1143
+ | PropertyExplorer | 검색 가능한 속성 목록을 그룹별로 표시하고, 숨김 상태와 호출자 소유의 명시적인 편집 액션을 함께 제공합니다. | `PropertyExplorer` |
1144
+ | RichTextEditor | 마크다운 리치 텍스트 에디터. 서식 툴바 + textarea 조합. | `RichTextEditor` |
1145
+ | ExportButton | 데이터 내보내기 버튼. CSV/JSON 변환 내장, PDF는 콜백 위임. DropdownMenu 기반. | `ExportButton` |
1146
+ | InsightsPanel | 이상 탐지 인사이트 패널. severity별 카드, 통계 필터, dismiss 기능, 검출 설정(유형/Z-score/days). | `InsightsPanel` |
1105
1147
 
1106
1148
  ### SqlEditor
1107
1149
 
@@ -1131,18 +1173,61 @@ const fields = [
1131
1173
 
1132
1174
  ### EventMetaEditor
1133
1175
 
1134
- > 이벤트 메타 에디터. 레이블이 연결된 IconPicker + ColorPicker + TagInput 조합으로 이벤트 메타데이터를 편집합니다.
1176
+ > 기본 이벤트 메타와 호출자 소유 섹션을 폼에서 편집하고, footer의 액션으로 함께 저장할 수 있습니다.
1135
1177
 
1136
1178
  **Import:** `import { EventMetaEditor } from "@reopt-ai/opt-ui"`
1137
1179
  **Dependencies:** input (core), icon-picker (core), color-picker (core), tag-input (core)
1138
1180
 
1181
+ **EventMetaEditor:**
1182
+
1183
+ | Prop | Type | Required | Default | Description |
1184
+ | ----------- | --------------------------- | -------- | ------- | ------------------------------------------------------ |
1185
+ | `value` | `EventMeta` | Yes | | 편집 중인 이벤트 메타데이터 |
1186
+ | `onChange` | `(meta: EventMeta) => void` | Yes | | 메타데이터 변경 |
1187
+ | `icons` | `IconDef[]` | | | 선택 가능한 아이콘 |
1188
+ | `sections` | `EventMetaEditorSection[]` | | | 기본 여섯 필드 뒤에 렌더할 호출자 소유 섹션 |
1189
+ | `footer` | `ReactNode` | | | 내장 필드와 추가 섹션을 함께 저장하는 마지막 액션 영역 |
1190
+ | `className` | `string` | | | 추가 CSS 클래스 |
1191
+ | `labels` | `EventMetaEditorLabels` | | | 필드 레이블과 placeholder 문구 |
1192
+
1193
+ **EventMetaEditorSection:**
1194
+
1195
+ | Prop | Type | Required | Default | Description |
1196
+ | ------------- | ----------- | -------- | ------- | ---------------------------- |
1197
+ | `id` | `string` | Yes | | 섹션 키 |
1198
+ | `title` | `ReactNode` | | | 섹션 제목 |
1199
+ | `description` | `ReactNode` | | | 섹션 변경이 미치는 영향 안내 |
1200
+ | `children` | `ReactNode` | Yes | | 호출자가 소유하는 필드 |
1201
+
1139
1202
  ### PropertyExplorer
1140
1203
 
1141
- > 프로퍼티 탐색기. 검색 가능한 속성 목록을 그룹별로 표시합니다.
1204
+ > 검색 가능한 속성 목록을 그룹별로 표시하고, 숨김 상태와 호출자 소유의 명시적인 편집 액션을 함께 제공합니다.
1142
1205
 
1143
1206
  **Import:** `import { PropertyExplorer } from "@reopt-ai/opt-ui"`
1144
1207
  **Dependencies:** input (core)
1145
1208
 
1209
+ **PropertyExplorer:**
1210
+
1211
+ | Prop | Type | Required | Default | Description |
1212
+ | ----------- | --------------------------------- | -------- | ------- | -------------------------------------------------------------- |
1213
+ | `groups` | `PropertyGroup[]` | Yes | | 그룹별 속성 목록. 각 속성은 dataType과 hidden 상태를 포함 가능 |
1214
+ | `onSelect` | `(property: PropertyDef) => void` | | | 속성 선택 |
1215
+ | `onEdit` | `(property: PropertyDef) => void` | | | 행에 명시적인 편집 버튼을 표시하고 선택한 속성을 전달 |
1216
+ | `className` | `string` | | | 추가 CSS 클래스 |
1217
+ | `labels` | `PropertyExplorerLabels` | | | 검색·빈 상태·편집·숨김 문구 |
1218
+
1219
+ **PropertyDef:**
1220
+
1221
+ | Prop | Type | Required | Default | Description |
1222
+ | -------------- | --------------- | -------- | ------- | ------------------------------------------------- |
1223
+ | `name` | `string` | Yes | | 속성 이름 |
1224
+ | `type` | `string` | Yes | | 원본 스키마 타입 |
1225
+ | `dataType` | `FieldDataType` | | | 호출자가 이미 판정한 opt-ui 필드 타입 |
1226
+ | `description` | `string` | | | 속성 설명 |
1227
+ | `exampleValue` | `string` | | | 예시 값 |
1228
+ | `eventCount` | `number` | | | 관측 이벤트 수 |
1229
+ | `hidden` | `boolean` | | | 피커에서는 숨기되 탐색기에서는 흐리게 표시할 상태 |
1230
+
1146
1231
  ### RichTextEditor
1147
1232
 
1148
1233
  > 마크다운 리치 텍스트 에디터. 서식 툴바 + textarea 조합.
@@ -1217,16 +1302,16 @@ const fields = [
1217
1302
  **Import:** `import { ReportBuilder } from "@reopt-ai/opt-ui"`
1218
1303
  **Dependencies:** button (core), input (core)
1219
1304
 
1220
- | Prop | Type | Required | Default | Description |
1221
- | ------------- | ------------------------------------------------------------------ | -------- | ------- | ----------------------------------- |
1222
- | `chartTypes` | `ChartTypeDef[]` | | | 차트 타입 그리드 (기본 9종 제공) |
1223
- | `dataSources` | `DataSourceDef[]` | | | 데이터 소스 드롭다운 옵션 |
1224
- | `configForm` | `ReactNode` | | | 차트별 데이터 설정 폼 슬롯 (step 2) |
1225
- | `styleForm` | `ReactNode` | | | 차트별 스타일 설정 폼 슬롯 (step 3) |
1226
- | `preview` | `ReactNode` | | | 차트 미리보기 슬롯 (step 4) |
1227
- | `onSave` | `(report: { name, description, chartType, dataSourceId }) => void` | | | 저장 콜백 |
1228
- | `onCancel` | `() => void` | | | 취소 콜백 |
1229
- | `labels` | `ReportBuilderLabels` | | | UI 텍스트 커스터마이징 |
1305
+ | Prop | Type | Required | Default | Description |
1306
+ | ------------- | ------------------------------------------------------------------------------------------------------------------ | -------- | ------- | ----------------------------------- |
1307
+ | `chartTypes` | `ChartTypeDef[]` | | | 차트 타입 그리드 (기본 9종 제공) |
1308
+ | `dataSources` | `DataSourceDef[]` | | | 데이터 소스 드롭다운 옵션 |
1309
+ | `configForm` | `ReactNode` | | | 차트별 데이터 설정 폼 슬롯 (step 2) |
1310
+ | `styleForm` | `ReactNode` | | | 차트별 스타일 설정 폼 슬롯 (step 3) |
1311
+ | `preview` | `ReactNode` | | | 차트 미리보기 슬롯 (step 4) |
1312
+ | `onSave` | `(report: { name: string; description: string; chartType: ReportBuilderChartType; dataSourceId: string }) => void` | | | 저장 콜백 |
1313
+ | `onCancel` | `() => void` | | | 취소 콜백 |
1314
+ | `labels` | `ReportBuilderLabels` | | | UI 텍스트 커스터마이징 |
1230
1315
 
1231
1316
  ## Widgets & Reports
1232
1317
 
@@ -1325,23 +1410,26 @@ const fields = [
1325
1410
 
1326
1411
  ## Other
1327
1412
 
1328
- | Component | Description | Key Exports |
1329
- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ |
1330
- | PageAside | Sticky 페이지 사이드 aside chrome. 고정 너비 + header/body/footer 3-slot. | `PageAside` |
1331
- | FailureList | 실패 목록 패널. severity별 색상 강조, 그룹핑, 액션 슬롯을 지원합니다. | `FailureList` |
1332
- | KeyValueEditor | 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다. | `KeyValueEditor` |
1333
- | EventTimeline | 이벤트를 순서로 읽히게 하는 타임라인. 인접 이벤트 사이의 경과 시간을 라벨링하고, 속성 페이로드를 제자리에서 펼치며, 세션 단위 그룹핑을 지원한다. | `EventTimeline` |
1334
- | ScoreBreakdown | 합성 점수를 축별로 분해해 보여준다. 총점과 함께 각 축의 값·가중치·의미를 노출해 '43'을 판정이 아니라 발견으로 만든다. | `ScoreBreakdown` |
1335
- | Flyout | 목록을 화면에 둔 채 레코드를 옆에서 보여주는 상세 패널. 모달이 아니다 — 포커스 트랩·aria-modal·inert 없이 Escape로 닫고 포커스를 되돌린다. | `Flyout` |
1336
- | AuditTimeline | 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰. | `AuditTimeline` |
1337
- | ChatSidebar | AI 채팅 사이드바. 대화 목록, 검색, 새 대화 버튼. | `ChatSidebar` |
1338
- | ChatInput | 채팅 입력 컴포넌트. 자동 리사이즈 textarea, 파일 첨부, 모델/스타일 Select. | `ChatInput` |
1339
- | ChatMessageList | 채팅 메시지 목록. 역할별 말풍선, 타이핑 인디케이터, 자동 스크롤. | `ChatMessageList` |
1340
- | TimeRangeControl | date math(now-7d, now/d) 기반 시간 범위 컨트롤. quick select, 프리셋/최근 사용, 명시적 Update, 자동 갱신, 창 이동·확대/축소 버튼을 제공합니다. | `TimeRangeControl`, `DEFAULT_TIME_PRESETS` |
1341
- | TimeSeriesPanel | 시간 범위 컨트롤과 시계열 차트를 한 단위로 묶은 패널. 드래그 줌과 줌 히스토리(되돌리기), 범례 토글을 포함합니다. | `TimeSeriesPanel` |
1342
- | LogTable | 계속 도착하는 로그용 윈도잉 테이블. 컬럼 정의 기반, 상단 삽입 시 스크롤 위치 보존, follow 상태 보고, 셀 값 즉시 필터, 밀도·정렬을 지원합니다. | `LogTable` |
1343
- | QueryBar | 검색과 필터를 한 입력으로 합친 쿼리 바. field:value, -부정, (a or b), 비교 연산, 필드·값 자동완성, 절(clause) 칩을 지원합니다. | `QueryBar` |
1344
- | FieldSidebar | 데이터에 어떤 필드가 있고 각 필드가 무슨 값을 갖는지 보여주는 사이드바. 값 분포 막대, 컬럼으로 승격, 값 기준 포함/제외 필터를 제공합니다. | `FieldSidebar` |
1413
+ | Component | Description | Key Exports |
1414
+ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- |
1415
+ | PageAside | Sticky 페이지 사이드 aside chrome. 고정 너비 + header/body/footer 3-slot. | `PageAside` |
1416
+ | FailureList | 실패 목록 패널. severity별 색상 강조, 그룹핑, 액션 슬롯을 지원합니다. | `FailureList` |
1417
+ | KeyValueEditor | 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다. | `KeyValueEditor` |
1418
+ | EventTimeline | 이벤트를 순서로 읽히게 하는 타임라인. 인접 이벤트 사이의 경과 시간을 라벨링하고, 속성 페이로드를 제자리에서 펼치며, 세션 단위 그룹핑을 지원한다. | `EventTimeline` |
1419
+ | ScoreBreakdown | 합성 점수를 축별로 분해해 보여준다. 총점과 함께 각 축의 값·가중치·의미를 노출해 '43'을 판정이 아니라 발견으로 만든다. | `ScoreBreakdown` |
1420
+ | Flyout | 목록을 화면에 둔 채 레코드를 옆에서 보여주는 상세 패널. 모달이 아니다 — 포커스 트랩·aria-modal·inert 없이 Escape로 닫고 포커스를 되돌린다. | `Flyout` |
1421
+ | AuditTimeline | 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰. | `AuditTimeline` |
1422
+ | ChatSidebar | AI 채팅 사이드바. 대화 목록, 검색, 새 대화 버튼. | `ChatSidebar` |
1423
+ | ChatInput | 채팅 입력 컴포넌트. 자동 리사이즈 textarea, 파일 첨부, 모델/스타일 Select. | `ChatInput` |
1424
+ | ChatMessageList | 채팅 메시지 목록. 역할별 말풍선, 타이핑 인디케이터, 자동 스크롤. | `ChatMessageList` |
1425
+ | TimeRangeControl | date math(now-7d, now/d) 기반 시간 범위 컨트롤. quick select, 프리셋/최근 사용, 명시적 Update, 자동 갱신, 창 이동·확대/축소 버튼을 제공합니다. | `TimeRangeControl`, `DEFAULT_TIME_PRESETS` |
1426
+ | TimeSeriesPanel | 시간 범위 컨트롤과 시계열 차트를 한 단위로 묶은 패널. 드래그 줌과 줌 히스토리(되돌리기), 범례 토글을 포함합니다. | `TimeSeriesPanel` |
1427
+ | LogTable | 계속 도착하는 로그용 윈도잉 테이블. 컬럼 정의 기반, 상단 삽입 시 스크롤 위치 보존, follow 상태 보고, 셀 값 즉시 필터, 밀도·정렬을 지원합니다. | `LogTable` |
1428
+ | QueryBar | 검색과 필터를 한 입력으로 합친 쿼리 바. field:value, -부정, (a or b), 비교 연산, 필드·값 자동완성, 절(clause) 칩을 지원합니다. | `QueryBar` |
1429
+ | FieldSidebar | 데이터에 어떤 필드가 있고 각 필드가 무슨 값을 갖는지 보여주는 사이드바. 값 분포 막대, 컬럼으로 승격, 값 기준 포함/제외 필터를 제공합니다. | `FieldSidebar` |
1430
+ | InspectorLayout | 목록과 인스펙터의 2-pane 레이아웃. 넓으면 밀어내고(push) 좁으면 덮으며(overlay), 닫을 때 포커스를 열었던 자리로 되돌립니다. | `InspectorLayout` |
1431
+ | QueryFilterBar | QueryBar와 필터 버튼이 하나의 Query를 공유합니다. 버튼은 상태를 갖지 않고 Query를 읽어 활성 여부를 계산합니다. | `QueryFilterBar`, `hasActiveQuery` |
1432
+ | CatalogFrame | 카탈로그 목록의 공통 뼈대. 헤더·통계·고지·필터·인스펙터·페이지네이션·일괄 작업과 빈/에러 상태를 담고, 필터나 페이지가 바뀌면 선택을 비웁니다. | `CatalogFrame`, `CatalogRowActions`, `CatalogCellControls` |
1345
1433
 
1346
1434
  ### PageAside
1347
1435
 
@@ -1594,16 +1682,19 @@ const messages = [
1594
1682
 
1595
1683
  **Import:** `import { TimeSeriesPanel } from "@reopt-ai/opt-ui"`
1596
1684
 
1597
- | Prop | Type | Required | Default | Description |
1598
- | ------------------ | ---------------------------- | -------- | ------- | --------------------------------------------- |
1599
- | `data` | `TimeSeriesPoint[]` | Yes | | 시계열 데이터 |
1600
- | `series` | `TimeSeriesDef[]` | Yes | | 시리즈 정의 |
1601
- | `range` | `TimeRange` | Yes | | 조회 구간 — 차트 축도 여기에 고정됩니다 |
1602
- | `onRangeChange` | `(range: TimeRange) => void` | Yes | | 드래그 줌·컨트롤 변경으로 구간이 바뀔 때 호출 |
1603
- | `showRangeControl` | `boolean` | | true | 헤더에 TimeRangeControl 렌더 |
1604
- | `toggleableLegend` | `boolean` | | false | 범례 클릭으로 시리즈 숨김 |
1605
- | `annotations` | `TimeSeriesAnnotation[]` | | | 시간축 마커/구간 |
1606
- | `height` | `number` | | 280 | 차트 높이 |
1685
+ | Prop | Type | Required | Default | Description |
1686
+ | ------------------ | ---------------------------- | -------- | ------- | --------------------------------------------------------- |
1687
+ | `title` | `ReactNode` | | | 패널 제목. aria-label이 없으면 region 이름으로 연결됩니다 |
1688
+ | `description` | `ReactNode` | | | 패널 보조 설명 |
1689
+ | `data` | `TimeSeriesPoint[]` | Yes | | 시계열 데이터 |
1690
+ | `series` | `TimeSeriesDef[]` | Yes | | 시리즈 정의 |
1691
+ | `range` | `TimeRange` | Yes | | 조회 구간 — 차트 축도 여기에 고정됩니다 |
1692
+ | `onRangeChange` | `(range: TimeRange) => void` | Yes | | 드래그 줌·컨트롤 변경으로 구간이 바뀔 때 호출 |
1693
+ | `showRangeControl` | `boolean` | | true | 헤더에 TimeRangeControl 렌더 |
1694
+ | `toggleableLegend` | `boolean` | | false | 범례 클릭으로 시리즈 숨김 |
1695
+ | `annotations` | `TimeSeriesAnnotation[]` | | | 시간축 마커/구간 |
1696
+ | `height` | `number` | | 280 | 차트 높이 |
1697
+ | `aria-label` | `string` | | | 제목 대신 사용할 패널 region의 접근 가능한 이름 |
1607
1698
 
1608
1699
  ### LogTable
1609
1700
 
@@ -1658,3 +1749,112 @@ const messages = [
1658
1749
  | `sampledRows` | `number` | | | 집계 대상 행 수 (분모) |
1659
1750
  | `onToggleColumn` | `(field: string, next: boolean) => void` | | | 컬럼 추가/제거 |
1660
1751
  | `onFilter` | `(field: string, value: string, intent: "include" \| "exclude") => void` | | | 값 기준 필터 |
1752
+
1753
+ ### InspectorLayout
1754
+
1755
+ > 목록과 인스펙터의 2-pane 레이아웃. 넓으면 밀어내고(push) 좁으면 덮으며(overlay), 닫을 때 포커스를 열었던 자리로 되돌립니다.
1756
+
1757
+ **Import:** `import { InspectorLayout } from "@reopt-ai/opt-ui"`
1758
+
1759
+ | Prop | Type | Required | Default | Description |
1760
+ | ------------- | ----------------------- | -------- | ------- | ---------------------------------------------- |
1761
+ | `children` | `ReactNode` | Yes | | 목록. 인스펙터가 열려도 마운트와 스크롤을 유지 |
1762
+ | `inspector` | `ReactNode` | | | 인스펙터 내용. 닫혀 있으면 렌더하지 않음 |
1763
+ | `open` | `boolean` | Yes | | 열림 |
1764
+ | `onClose` | `() => void` | Yes | | 닫기 |
1765
+ | `title` | `ReactNode` | | | 인스펙터 제목 |
1766
+ | `description` | `ReactNode` | | | 제목 아래 한 줄 |
1767
+ | `actions` | `ReactNode` | | | 닫기 버튼 옆 컨트롤 |
1768
+ | `footer` | `ReactNode` | | | 인스펙터 하단 |
1769
+ | `breakpoint` | `"lg" \| "xl" \| "2xl"` | | "xl" | 이 폭 이상이면 push |
1770
+ | `width` | `"sm" \| "md" \| "lg"` | | "md" | push 레이아웃에서의 인스펙터 폭 |
1771
+ | `labels` | `InspectorLayoutLabels` | | | 닫기 버튼 등 인스펙터 문구 |
1772
+ | `className` | `string` | | | 추가 CSS 클래스 |
1773
+
1774
+ ### QueryFilterBar
1775
+
1776
+ > QueryBar와 필터 버튼이 하나의 Query를 공유합니다. 버튼은 상태를 갖지 않고 Query를 읽어 활성 여부를 계산합니다.
1777
+
1778
+ **Import:** `import { QueryFilterBar } from "@reopt-ai/opt-ui"`
1779
+
1780
+ | Prop | Type | Required | Default | Description |
1781
+ | ---------------- | ------------------------ | -------- | ------- | -------------------------------------------------------------------------- |
1782
+ | `value` | `Query` | Yes | | 필터 상태 전부 |
1783
+ | `onChange` | `(query: Query) => void` | Yes | | Query 변경 |
1784
+ | `filters` | `QueryFilterDef[]` | Yes | | 필터 컨트롤 정의 (is / field_value_selection / field_value_toggle) |
1785
+ | `fields` | `QueryField[]` | | | 텍스트 입력 자동완성 |
1786
+ | `actions` | `ReactNode` | | | 필터 행 끝 슬롯 |
1787
+ | `showClauses` | `boolean` | | true | 절을 제거 가능한 칩으로 표시 |
1788
+ | `live` | `boolean` | | false | 매 입력마다 커밋 |
1789
+ | `disabled` | `boolean` | | false | 전체 비활성 |
1790
+ | `queryBarLabels` | `QueryBarLabels` | | | QueryBar로 통과되는 나머지 문구. placeholder/ariaLabel은 labels가 이깁니다 |
1791
+ | `labels` | `QueryFilterBarLabels` | | | 검색·필터·초기화 문구 |
1792
+ | `className` | `string` | | | 추가 CSS 클래스 |
1793
+
1794
+ ### CatalogFrame
1795
+
1796
+ > 카탈로그 목록의 공통 뼈대. 헤더·통계·고지·필터·인스펙터·페이지네이션·일괄 작업과 빈/에러 상태를 담고, 필터나 페이지가 바뀌면 선택을 비웁니다.
1797
+
1798
+ **Import:** `import { CatalogFrame } from "@reopt-ai/opt-ui"`
1799
+
1800
+ **CatalogFrame:**
1801
+
1802
+ | Prop | Type | Required | Default | Description |
1803
+ | ---------------------- | ------------------------------ | -------- | ------- | ----------------------------------------------------------------- |
1804
+ | `children` | `ReactNode` | Yes | | 테이블. 빈/에러 상태에서는 대체됨 |
1805
+ | `isEmpty` | `boolean` | Yes | | 테이블이 0행인지 |
1806
+ | `query` | `Query` | Yes | | 필터 상태 |
1807
+ | `onQueryChange` | `(query: Query) => void` | Yes | | Query 변경 |
1808
+ | `filters` | `QueryFilterDef[]` | | | 필터 정의 |
1809
+ | `stats` | `StatCardType[]` | | | 통계 카드 |
1810
+ | `onStatClick` | `(stat: StatCardType) => void` | | | 카드 클릭 = 필터 |
1811
+ | `notice` | `ReactNode` | | | 목록 위 고지 |
1812
+ | `emptyActions` | `ReactNode` | | | 필터 없는 빈 상태의 다음 행동 (필터된 빈 상태는 필터 지우기 유지) |
1813
+ | `header` | `ReactNode` | | | 헤더 슬롯 |
1814
+ | `actions` | `ReactNode` | | | 액션 슬롯 |
1815
+ | `toolbar` | `ReactNode` | | | 통계와 필터 사이 컨트롤 (스코프 세그먼트 등) |
1816
+ | `inspector` | `ReactNode` | | | 인스펙터 내용 |
1817
+ | `inspectorOpen` | `boolean` | Yes | | 인스펙터 열림 |
1818
+ | `onInspectorClose` | `() => void` | Yes | | 인스펙터 닫기 |
1819
+ | `inspectorTitle` | `ReactNode` | | | 인스펙터 제목 |
1820
+ | `inspectorDescription` | `ReactNode` | | | 인스펙터 설명 |
1821
+ | `inspectorActions` | `ReactNode` | | | 인스펙터 헤더 컨트롤 |
1822
+ | `inspectorFooter` | `ReactNode` | | | 인스펙터 하단 |
1823
+ | `inspectorWidth` | `"sm" \| "md" \| "lg"` | | | push 레이아웃 폭 |
1824
+ | `page` | `number` | | 1 | 현재 페이지 |
1825
+ | `pageSize` | `number` | | 50 | 페이지 크기 |
1826
+ | `totalCount` | `number` | | | 필터 반영 총 개수 |
1827
+ | `onPageChange` | `(page: number) => void` | | | 페이지 변경 |
1828
+ | `selectedKeys` | `string[]` | | | 선택된 행 |
1829
+ | `onSelectionChange` | `(keys: string[]) => void` | | | 선택 변경. 필터·페이지가 바뀌면 프레임이 비웁니다 |
1830
+ | `bulkActions` | `FloatingAction[]` | | | 일괄 작업 |
1831
+ | `onBulkAction` | `(actionId: string) => void` | | | 일괄 작업 실행 |
1832
+ | `error` | `ReactNode` | | | 읽기 실패. 빈 목록과 다른 답 |
1833
+ | `onRetry` | `() => void` | | | 재시도 |
1834
+ | `labels` | `CatalogFrameLabels` | | | 빈/필터된 빈/에러 문구 |
1835
+ | `className` | `string` | | | 추가 CSS 클래스 |
1836
+
1837
+ **CatalogRowActions:**
1838
+
1839
+ | Prop | Type | Required | Default | Description |
1840
+ | -------------- | ------------------------- | -------- | ------- | ------------------------------------------------------- |
1841
+ | `item` | `T` | Yes | | 이 행의 항목 |
1842
+ | `actions` | `CatalogRowAction<T>[]` | Yes | | 행 액션 |
1843
+ | `visibleCount` | `number` | | 2 | 오버플로 전에 노출할 개수. available 필터링 후에 적용됨 |
1844
+ | `labels` | `CatalogRowActionsLabels` | | | 그룹·오버플로 라벨 |
1845
+
1846
+ **CatalogRowAction:**
1847
+
1848
+ | Prop | Type | Required | Default | Description |
1849
+ | ----------- | ---------------------- | -------- | ------- | ----------------------------------------------- |
1850
+ | `id` | `string` | Yes | | 액션 키 |
1851
+ | `label` | `string` | Yes | | 액션 문구 |
1852
+ | `icon` | `ReactNode` | | | 선택적 액션 아이콘 |
1853
+ | `onSelect` | `(item: T) => void` | Yes | | 행과 함께 호출되는 액션 |
1854
+ | `available` | `(item: T) => boolean` | | | 이 행에 적용되지 않는 액션을 비활성화 대신 제거 |
1855
+
1856
+ **CatalogCellControls:**
1857
+
1858
+ | Prop | Type | Required | Default | Description |
1859
+ | ---------- | ----------- | -------- | ------- | ---------------------------------- |
1860
+ | `children` | `ReactNode` | Yes | | 행 클릭으로 새면 안 되는 셀 컨트롤 |