@reopt-ai/opt-ui 1.10.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/COMPONENT_CATALOG.md +522 -218
  2. package/README.md +61 -7
  3. package/dist/core/index.cjs +10 -8
  4. package/dist/core/index.d.cts +3 -3
  5. package/dist/core/index.d.ts +3 -3
  6. package/dist/core/index.js +3 -3
  7. package/dist/docs/02-components/01-core.md +213 -96
  8. package/dist/docs/02-components/02-visuals.md +1 -1
  9. package/dist/docs/02-components/03-shells.md +334 -123
  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-B6Ndr8HE.cjs → field-sidebar-BYgEmdy0.cjs} +2128 -1558
  14. package/dist/{field-sidebar-BXjvV7Cz.js → field-sidebar-BuO37l4c.js} +2111 -1561
  15. package/dist/{field-sidebar-nwcE9LC4.d.cts → field-sidebar-CrYlRZew.d.ts} +375 -154
  16. package/dist/{field-sidebar-DWfJAJlx.d.ts → field-sidebar-uXmoyvd7.d.cts} +375 -154
  17. package/dist/id-registry.cjs +124 -12
  18. package/dist/id-registry.d.cts +1 -2
  19. package/dist/id-registry.d.ts +1 -2
  20. package/dist/id-registry.js +124 -14
  21. package/dist/id-registry.json +265 -31
  22. package/dist/index.cjs +1162 -253
  23. package/dist/index.d.cts +573 -60
  24. package/dist/index.d.ts +573 -60
  25. package/dist/index.js +1134 -242
  26. package/dist/{key-pad-menu-DfZbeXhG.d.cts → key-pad-menu-CwcY_Vps.d.cts} +151 -7
  27. package/dist/{key-pad-menu-BQunU20e.js → key-pad-menu-Di2aRGbM.js} +388 -461
  28. package/dist/{key-pad-menu-D5mQcS5v.cjs → key-pad-menu-SItoHPLu.cjs} +490 -609
  29. package/dist/{key-pad-menu-BsgJMjD4.d.ts → key-pad-menu-WBJShCJn.d.ts} +152 -8
  30. package/dist/meta.cjs +1304 -168
  31. package/dist/meta.d.cts +12 -36
  32. package/dist/meta.d.ts +12 -36
  33. package/dist/meta.js +1304 -170
  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 +4 -1
  38. package/dist/shells/index.d.cts +2 -2
  39. package/dist/shells/index.d.ts +2 -2
  40. package/dist/shells/index.js +2 -2
  41. package/dist/{text-truncate-BGr7bB_8.d.cts → text-truncate-CQyfUZvq.d.cts} +48 -5
  42. package/dist/{text-truncate-BGr7bB_8.d.ts → text-truncate-CQyfUZvq.d.ts} +48 -5
  43. package/dist/{text-truncate-j6X3z7Pv.js → text-truncate-DSuZECy0.js} +446 -94
  44. package/dist/{text-truncate-CxdzAnhS.cjs → text-truncate-I1XLWmRa.cjs} +522 -90
  45. package/dist/theme/server.d.cts +1 -2
  46. package/dist/theme/server.d.ts +1 -2
  47. package/dist/theme/server.js +0 -2
  48. package/dist/visuals/index.js +0 -1
  49. package/package.json +4 -3
  50. package/dist/field-sidebar-BXjvV7Cz.js.map +0 -1
  51. package/dist/field-sidebar-DWfJAJlx.d.ts.map +0 -1
  52. package/dist/field-sidebar-nwcE9LC4.d.cts.map +0 -1
  53. package/dist/id-registry.d.cts.map +0 -1
  54. package/dist/id-registry.d.ts.map +0 -1
  55. package/dist/id-registry.js.map +0 -1
  56. package/dist/index.d.cts.map +0 -1
  57. package/dist/index.d.ts.map +0 -1
  58. package/dist/index.js.map +0 -1
  59. package/dist/key-pad-menu-BQunU20e.js.map +0 -1
  60. package/dist/key-pad-menu-BsgJMjD4.d.ts.map +0 -1
  61. package/dist/key-pad-menu-DfZbeXhG.d.cts.map +0 -1
  62. package/dist/meta.d.cts.map +0 -1
  63. package/dist/meta.d.ts.map +0 -1
  64. package/dist/meta.js.map +0 -1
  65. package/dist/query.d.cts.map +0 -1
  66. package/dist/query.d.ts.map +0 -1
  67. package/dist/query.js.map +0 -1
  68. package/dist/text-truncate-BGr7bB_8.d.cts.map +0 -1
  69. package/dist/text-truncate-BGr7bB_8.d.ts.map +0 -1
  70. package/dist/text-truncate-j6X3z7Pv.js.map +0 -1
  71. package/dist/theme/server.d.cts.map +0 -1
  72. package/dist/theme/server.d.ts.map +0 -1
  73. package/dist/theme/server.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: "Core Components"
3
- description: "68 Core layer components — props, examples, keyboard shortcuts."
4
- version: "1.9.0"
3
+ description: "74 Core layer components — props, examples, keyboard shortcuts."
4
+ version: "1.12.0"
5
5
  generated: true
6
6
  ---
7
7
 
8
- # Core Components (68)
8
+ # Core Components (74)
9
9
 
10
10
  ## Input
11
11
 
@@ -132,16 +132,17 @@ const store = useFormStore({ defaultValues: { name: "" } });
132
132
 
133
133
  **Checkbox:**
134
134
 
135
- | Prop | Type | Required | Default | Description |
136
- | ---------------- | ---------------------------- | -------- | ------- | ---------------------------------- |
137
- | `label` | `string` | | | 체크박스 레이블 |
138
- | `description` | `string` | | | 레이블 아래 설명 텍스트 |
139
- | `checked` | `boolean` | | | 제어 모드: 체크 상태 |
140
- | `defaultChecked` | `boolean` | | | 비제어 모드: 초기 체크 상태 |
141
- | `onChange` | `(checked: boolean) => void` | | | 상태 변경 핸들러 |
142
- | `size` | `"sm" \| "md" \| "lg"` | | "md" | 체크박스 크기 |
143
- | `value` | `string` | | | CheckboxGroup 내에서 사용할 값 |
144
- | `indeterminate` | `boolean` | | false | 불확정 상태 표시 (마이너스 아이콘) |
135
+ | Prop | Type | Required | Default | Description |
136
+ | ---------------- | ---------------------------- | -------- | ------- | -------------------------------------------------------------------------- |
137
+ | `label` | `string` | | | 체크박스 레이블 |
138
+ | `hint` | `string` | | | 레이블 아래 보조 설명 텍스트 |
139
+ | `description` | `string` | | | 레이블 아래 설명 텍스트 **⚠️ deprecated since 1.9.0 — use `hint` instead** |
140
+ | `checked` | `boolean` | | | 제어 모드: 체크 상태 |
141
+ | `defaultChecked` | `boolean` | | | 비제어 모드: 초기 체크 상태 |
142
+ | `onChange` | `(checked: boolean) => void` | | | 상태 변경 핸들러 |
143
+ | `size` | `"sm" \| "md" \| "lg"` | | "md" | 체크박스 크기 |
144
+ | `value` | `string` | | | CheckboxGroup 내에서 사용할 |
145
+ | `indeterminate` | `boolean` | | false | 불확정 상태 표시 (마이너스 아이콘) |
145
146
 
146
147
  **CheckboxGroup:**
147
148
 
@@ -172,12 +173,13 @@ const store = useFormStore({ defaultValues: { name: "" } });
172
173
 
173
174
  **Radio:**
174
175
 
175
- | Prop | Type | Required | Default | Description |
176
- | ------------- | ---------------------- | -------- | ------- | ---------------------------------------------------------- |
177
- | `value` | `string` | | | 라디오 값 (RadioGroup 안에서는 부모가 관리하므로 optional) |
178
- | `label` | `string` | | | 라디오 레이블 |
179
- | `description` | `string` | | | 레이블 아래 설명 텍스트 |
180
- | `size` | `"sm" \| "md" \| "lg"` | | "md" | 라디오 크기 |
176
+ | Prop | Type | Required | Default | Description |
177
+ | ------------- | ---------------------- | -------- | ------- | -------------------------------------------------------------------------- |
178
+ | `value` | `string` | | | 라디오 값 (RadioGroup 안에서는 부모가 관리하므로 optional) |
179
+ | `label` | `string` | | | 라디오 레이블 |
180
+ | `hint` | `string` | | | 레이블 아래 보조 설명 텍스트 |
181
+ | `description` | `string` | | | 레이블 아래 설명 텍스트 **⚠️ deprecated since 1.9.0 — use `hint` instead** |
182
+ | `size` | `"sm" \| "md" \| "lg"` | | "md" | 라디오 크기 |
181
183
 
182
184
  **Keyboard Shortcuts:**
183
185
 
@@ -193,15 +195,16 @@ const store = useFormStore({ defaultValues: { name: "" } });
193
195
 
194
196
  **Import:** `import { Switch } from "@reopt-ai/opt-ui"`
195
197
 
196
- | Prop | Type | Required | Default | Description |
197
- | ---------------- | ---------------------------- | -------- | ------- | --------------------------- |
198
- | `label` | `string` | | | 스위치 레이블 |
199
- | `description` | `string` | | | 레이블 아래 설명 텍스트 |
200
- | `checked` | `boolean` | | | 제어 모드: 체크 상태 |
201
- | `defaultChecked` | `boolean` | | | 비제어 모드: 초기 체크 상태 |
202
- | `onChange` | `(checked: boolean) => void` | | | 상태 변경 핸들러 |
203
- | `size` | `"sm" \| "md" \| "lg"` | | "md" | 스위치 크기 |
204
- | `disabled` | `boolean` | | | 비활성화 상태 |
198
+ | Prop | Type | Required | Default | Description |
199
+ | ---------------- | ---------------------------- | -------- | ------- | -------------------------------------------------------------------------- |
200
+ | `label` | `string` | | | 스위치 레이블 |
201
+ | `hint` | `string` | | | 레이블 아래 보조 설명 텍스트 |
202
+ | `description` | `string` | | | 레이블 아래 설명 텍스트 **⚠️ deprecated since 1.9.0 — use `hint` instead** |
203
+ | `checked` | `boolean` | | | 제어 모드: 체크 상태 |
204
+ | `defaultChecked` | `boolean` | | | 비제어 모드: 초기 체크 상태 |
205
+ | `onChange` | `(checked: boolean) => void` | | | 상태 변경 핸들러 |
206
+ | `size` | `"sm" \| "md" \| "lg"` | | "md" | 스위치 크기 |
207
+ | `disabled` | `boolean` | | | 비활성화 상태 |
205
208
 
206
209
  ### Select
207
210
 
@@ -354,21 +357,21 @@ import {
354
357
 
355
358
  **Import:** `import { DateRangePicker } from "@reopt-ai/opt-ui"`
356
359
 
357
- | Prop | Type | Required | Default | Description |
358
- | --------------------- | ----------------------------------------------------- | -------- | ------------------- | ------------------------------------------------------ |
359
- | `value` | `DateRange` | | | 제어 모드: { start: Date \| null, end: Date \| null } |
360
- | `onChange` | `(range: DateRange) => void` | | | 범위 변경 핸들러 |
361
- | `presets` | `DateRangePreset[]` | | | 빠른 선택 프리셋 배열 (기본: Today, Last 7/30/90 days) |
362
- | `placeholder` | `string` | | "Select date range" | 미선택 시 표시 텍스트 |
363
- | `label` | `string` | | | 입력 필드 레이블 |
364
- | `disabled` | `boolean` | | false | 비활성화 상태 |
365
- | `format` | `(date: Date) => string` | | | 날짜 포맷 함수 |
366
- | `comparison` | `boolean` | | false | 비교 모드 활성화 |
367
- | `comparisonMode` | `"previous" \| "year-over-year"` | | "previous" | 비교 기준 (이전 기간 / 전년 동기) |
368
- | `onComparisonChange` | `(comparison: boolean, mode: ComparisonMode) => void` | | | 비교 모드 변경 콜백 |
369
- | `showGranularity` | `boolean` | | false | 시간 단위 선택기 표시 |
370
- | `granularity` | `"hour" \| "day" \| "week" \| "month"` | | "day" | 시간 단위 |
371
- | `onGranularityChange` | `(granularity: DateGranularity) => void` | | | 시간 단위 변경 콜백 |
360
+ | Prop | Type | Required | Default | Description |
361
+ | --------------------- | ---------------------------------------- | -------- | ------------------- | ------------------------------------------------------ |
362
+ | `value` | `DateRange` | | | 제어 모드: { start: Date \| null, end: Date \| null } |
363
+ | `onChange` | `(range: DateRange) => void` | | | 범위 변경 핸들러 |
364
+ | `presets` | `DateRangePreset[]` | | | 빠른 선택 프리셋 배열 (기본: Today, Last 7/30/90 days) |
365
+ | `placeholder` | `string` | | "Select date range" | 미선택 시 표시 텍스트 |
366
+ | `label` | `string` | | | 입력 필드 레이블 |
367
+ | `disabled` | `boolean` | | false | 비활성화 상태 |
368
+ | `format` | `(date: Date) => string` | | | 날짜 포맷 함수 |
369
+ | `comparison` | `boolean` | | false | 비교 모드 활성화 |
370
+ | `comparisonMode` | `"previous" \| "year-over-year"` | | "previous" | 비교 기준 (이전 기간 / 전년 동기) |
371
+ | `onComparisonChange` | `(mode: ComparisonMode \| null) => void` | | | 비교 모드 변경 콜백 |
372
+ | `showGranularity` | `boolean` | | false | 시간 단위 선택기 표시 |
373
+ | `granularity` | `"hour" \| "day" \| "week" \| "month"` | | "day" | 시간 단위 |
374
+ | `onGranularityChange` | `(granularity: DateGranularity) => void` | | | 시간 단위 변경 콜백 |
372
375
 
373
376
  ### TagInput
374
377
 
@@ -736,7 +739,7 @@ const store = useFormStore({
736
739
  | Card | 범용 카드 컨테이너. Header, Title, Description, Content, Footer 하위 컴포넌트 포함. | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` |
737
740
  | Breadcrumb | 현재 위치를 표시하고 계층 탐색을 제공하는 컴포넌트. | `Breadcrumb` |
738
741
  | EmptyState | 데이터가 없을 때 표시하는 빈 상태 컴포넌트. 아이콘, 제목, 설명, 액션 버튼 지원. | `EmptyState` |
739
- | StatCard | 트렌드 방향과 변화량을 표시하는 통계 카드. | `StatCard` |
742
+ | StatCard | 단일 지표를 값·변화량·보조 설명으로 표시하는 통계 카드. 비교 기준이 없으면 변화량 줄을 렌더하지 않는다. | `StatCard` |
740
743
  | Logo | 아이콘+텍스트 조합, 이미지, 링크 래핑을 지원하는 로고 컴포넌트. Sidebar 등에서 활용. | `Logo` |
741
744
 
742
745
  ### Kbd
@@ -1006,25 +1009,42 @@ import {
1006
1009
 
1007
1010
  **Import:** `import { EmptyState } from "@reopt-ai/opt-ui"`
1008
1011
 
1009
- | Prop | Type | Required | Default | Description |
1010
- | ------------- | -------------------- | -------- | ------- | -------------------------------------------- |
1011
- | `title` | `string` | Yes | | 빈 상태 제목 |
1012
- | `description` | `string` | | | 빈 상태 설명 |
1013
- | `icon` | `ReactNode` | | | 표시할 아이콘 |
1014
- | `actions` | `EmptyStateAction[]` | | | 액션 버튼 배열. { label, onClick, variant? } |
1012
+ | Prop | Type | Required | Default | Description |
1013
+ | -------------- | ----------------------------------- | -------- | ---------- | ------------------------------------------------------------------------------ |
1014
+ | `title` | `string` | Yes | | 빈 상태 제목 |
1015
+ | `description` | `string` | | | 빈 상태 설명 |
1016
+ | `icon` | `ReactNode` | | | 표시할 아이콘 |
1017
+ | `actions` | `EmptyStateAction[] \| ReactNode` | | | 액션 버튼 배열 { label, onClick, variant? } 또는 직접 렌더할 노드 |
1018
+ | `body` | `ReactNode` | | | description 대신 넣는 리치 본문 (문단·목록·코드 스니펫) |
1019
+ | `footer` | `ReactNode` | | | 구분선 아래 보조 콘텐츠. 문서 링크·단축키 안내 등 |
1020
+ | `layout` | `"vertical" \| "horizontal"` | | "vertical" | horizontal은 아이콘을 텍스트 옆으로 옮긴다 (전체 페이지용) |
1021
+ | `titleSize` | `"sm" \| "md" \| "lg"` | | "md" | 제목 시각 크기. headingLevel과 독립 |
1022
+ | `hasBorder` | `boolean` | | false | 테두리 있는 패널로 렌더 |
1023
+ | `tone` | `"default" \| "subdued" \| "error"` | | "default" | error는 실패를 알리고 role=alert로 렌더. subdued는 아직 데이터가 없음을 뜻한다 |
1024
+ | `iconSize` | `"sm" \| "md" \| "lg"` | | "md" | 아이콘 크기 프리셋 |
1025
+ | `headingLevel` | `"h2" \| "h3" \| "h4"` | | "h3" | 문서 구조상 제목 레벨 |
1015
1026
 
1016
1027
  ### StatCard
1017
1028
 
1018
- > 트렌드 방향과 변화량을 표시하는 통계 카드.
1029
+ > 단일 지표를 값·변화량·보조 설명으로 표시하는 통계 카드. 비교 기준이 없으면 변화량 줄을 렌더하지 않는다.
1019
1030
 
1020
1031
  **Import:** `import { StatCard } from "@reopt-ai/opt-ui"`
1021
1032
 
1022
- | Prop | Type | Required | Default | Description |
1023
- | -------- | ----------------------------- | -------- | ------- | ------------------------------- |
1024
- | `title` | `string` | Yes | | 통계 제목 |
1025
- | `value` | `string` | Yes | | 통계 값 |
1026
- | `change` | `string` | Yes | | 변화량 텍스트 (예: '+12.5%') |
1027
- | `trend` | `"up" \| "down" \| "neutral"` | Yes | | 트렌드 방향. 색상과 아이콘 결정 |
1033
+ | Prop | Type | Required | Default | Description |
1034
+ | --------------- | ----------------------------- | -------- | ---------- | --------------------------------------------------------------------------------------- |
1035
+ | `title` | `string` | Yes | | 통계 제목 |
1036
+ | `value` | `string` | Yes | | 통계 값 |
1037
+ | `change` | `string` | | | 변화량 텍스트 (예: '+12.5%'). 비교 기준이 없으면 생략 — trend와 함께 있을 때만 렌더된다 |
1038
+ | `trend` | `"up" \| "down" \| "neutral"` | | | 변화 방향. change와 함께 있을 때만 의미를 갖는다 |
1039
+ | `polarity` | `"positive" \| "negative"` | | "positive" | 상승이 좋은 지표인지. 이탈률·에러 수처럼 반대인 지표는 negative로 색을 뒤집는다 |
1040
+ | `description` | `string` | | | 값 아래 한 줄 보조 설명 (집계 대상·기간 등) |
1041
+ | `hint` | `string` | | | 산출 근거 등 긴 설명. 툴팁과 aria-describedby로 노출 |
1042
+ | `size` | `"sm" \| "md"` | | "md" | 밀도 프리셋. 요약 행에는 sm |
1043
+ | `loading` | `boolean` | | false | 값 로딩 중 스켈레톤 표시 |
1044
+ | `href` | `string` | | | 드릴다운 링크. 지정 시 카드가 앵커로 렌더된다 |
1045
+ | `onSelect` | `() => void` | | | 드릴다운 핸들러. 지정 시 카드가 버튼으로 렌더된다 |
1046
+ | `selected` | `boolean` | | false | 선택 가능한 카드 행에서 현재 선택 상태 |
1047
+ | `sparklineData` | `number[]` | | | 값 옆에 그릴 미니 추세선 데이터 |
1028
1048
 
1029
1049
  ### Logo
1030
1050
 
@@ -1576,16 +1596,16 @@ import {
1576
1596
 
1577
1597
  **ResizablePanelGroup:**
1578
1598
 
1579
- | Prop | Type | Required | Default | Description |
1580
- | ----------------- | ------------------------------------------ | -------- | ------- | --------------------------------------------------- |
1581
- | `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
1582
- | `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
1583
- | `id` | `string` | | | 그룹과 defaultLayout의 패널 크기를 식별하는 고유 ID |
1584
- | `defaultLayout` | `Record<string, number>` | | | 패널 ID별 초기 비율(0-100) |
1585
- | `onLayoutChanged` | `(layout: Record<string, number>) => void` | | | 드래그가 끝난 뒤 확정된 레이아웃 콜백 |
1586
- | `groupRef` | `Ref<ResizablePanelGroupHandle>` | | | 레이아웃 조회·설정을 위한 명령형 그룹 ref |
1587
- | `autoSaveId` | `string` | | | id의 deprecated 별칭 |
1588
- | `className` | `string` | | | 커스텀 CSS 클래스 |
1599
+ | Prop | Type | Required | Default | Description |
1600
+ | ----------------- | ------------------------------------------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- |
1601
+ | `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
1602
+ | `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
1603
+ | `id` | `string` | | | 그룹과 defaultLayout의 패널 크기를 식별하는 고유 ID |
1604
+ | `defaultLayout` | `Record<string, number>` | | | 패널 ID별 초기 비율(0-100) |
1605
+ | `onLayoutChanged` | `(layout: Record<string, number>) => void` | | | 드래그가 끝난 뒤 확정된 레이아웃 콜백 |
1606
+ | `groupRef` | `Ref<ResizablePanelGroupHandle>` | | | 레이아웃 조회·설정을 위한 명령형 그룹 ref |
1607
+ | `autoSaveId` | `string` | | | id의 deprecated 별칭 **⚠️ deprecated since 1.6.0 — use `id` instead — id + defaultLayout + onLayoutChanged 조합으로 대체되었습니다.** |
1608
+ | `className` | `string` | | | 커스텀 CSS 클래스 |
1589
1609
 
1590
1610
  **ResizablePanel:**
1591
1611
 
@@ -1662,30 +1682,36 @@ import {
1662
1682
 
1663
1683
  ## Other
1664
1684
 
1665
- | Component | Description | Key Exports |
1666
- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
1667
- | FieldToken | 필드 타입을 글리프 하나로 표현하는 토큰. 문자열·숫자·날짜·IP·지오 등 분석 스키마 타입마다 고정된 아이콘과 팔레트 슬롯을 부여해 필드 목록·컬럼 헤더·속성 테이블 전역에서 같은 어휘를 쓴다. | `FieldToken`, `FIELD_TYPE_TOKENS`, `resolveFieldType` |
1668
- | Facet | 필드 값 분포를 카운트와 점유율 막대로 보여주고 그 행 자체가 필터가 되는 패싯. 긴 꼬리는 접어 두고 상위 값부터 읽힌다. | `Facet`, `FacetGroup` |
1669
- | Expression | 조건을 폼이 아니라 문장으로 쓰고 그 자리에서 편집하는 표현식 절. 알림 규칙·세그먼트 필터처럼 읽어서 검증해야 하는 조건에 쓴다. | `Expression`, `ExpressionGroup` |
1670
- | TextTruncate | 실제 폰트로 실제 가용 폭을 측정해 문자열의 식별력이 가장 낮은 부분을 잘라내는 생략. CSS가 못 하는 앞·중간·양끝 생략을 지원하고 전체 문자열은 접근성 트리에 남는다. | `TextTruncate` |
1671
- | Highlight | 검색어에 해당하는 구간을 <mark>로 표시. 긴 항목 우선 매칭이라 겹치는 검색어도 조각나지 않는다. | `Highlight` |
1672
- | LiveRegion | 라이브 뷰의 변화를 스크린 리더에 읽어 주는 영역. 스로틀로 폭주를 요약하고 두 노드를 번갈아 써서 같은 문구도 다시 읽힌다. | `LiveRegion` |
1673
- | ColorPalette | 시각화 색 팔레트를 그 팔레트의 모습 그대로 보여 주고 고르게 하는 컴포넌트. 범주형은 블록, 순차·발산형은 그라디언트로 그려 데이터 종류를 그림이 말한다. | `ColorPaletteDisplay`, `ColorPalettePicker`, `THEME_PALETTES` |
1674
- | InlineEdit | 대시보드 제목·지표 이름처럼 읽히는 횟수가 훨씬 많은 값을 그 자리에서 고치는 편집. Enter 확정, Escape 되돌리기, 거절된 저장은 입력을 유지한다. | `InlineEdit` |
1675
- | KeyPadMenu | 이름보다 그림으로 알아보기 쉬운 선택지를 타일로 고르는 메뉴. 내부는 실제 radio·checkbox라 키보드와 스크린 리더가 그대로 동작한다. | `KeyPadMenu` |
1676
- | Text | 본문, 레이블, 보조 설명, 코드에 일관된 의미 기반 타이포그래피를 적용합니다. | `Text` |
1677
- | Heading | 문서의 의미 계층과 시각적 타이포그래피 계층을 독립적으로 제어합니다. | `Heading` |
1678
- | Separator | 콘텐츠를 구분하는 가로/세로 디바이더. 라벨을 넣으면 가운데 정렬 구분선이 된다. | `Separator` |
1679
- | OtpField | 일회용 코드(OTP)/PIN 입력. 셀 단위 입력, 붙여넣기 분배, 자동 포커스 이동, 백스페이스 네비게이션과 폼 이름/오류 연결을 지원합니다. | `OtpField` |
1680
- | Toggle | 눌림(pressed) 두 상태 버튼. 단독 사용하거나 ToggleGroup으로 묶어 단일/다중 선택을 만든다. | `Toggle`, `ToggleGroup` |
1681
- | Accordion | 수직으로 쌓인 펼침/접힘 패널. single(한 개)/multiple(여러 개) 모드와 collapsible 지원. | `AccordionRoot`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` |
1682
- | Meter | 범위 내 스칼라 측정값 게이지 (디스크 사용량·점수·용량 등). role=meter로 작업 진행률(Progress)과 구분된다. | `Meter` |
1683
- | BlockLayout | Block 루트 레이아웃. 자식 section spacing과 선택적 시맨틱 inset을 제공하고 loading prop으로 LoadingOverlay를 자동 래핑합니다. | `BlockLayout` |
1684
- | createBlock | Block 팩토리 함수. BlockLayout 래핑을 구조적으로 강제하여 loading/className 처리를 자동화합니다. | `createBlock` |
1685
- | StarRating | 1~N점 별점을 선택하는 인터랙티브 레이팅 입력. 읽기 전용 표시도 지원. | `StarRating` |
1686
- | ErrorBoundary | React 에러 바운더리. 자식 컴포넌트 렌더 에러를 잡아 fallback UI를 표시합니다. | `ErrorBoundary` |
1687
- | Command | cmdk 스타일 명령 anatomy. 자동 필터링 + 키보드 내비게이션. 인라인 또는 CommandDialog로 사용. | `Command`, `CommandDialog`, `CommandInput`, `CommandList`, `CommandEmpty`, `CommandGroup`, `CommandItem`, `CommandSeparator`, `CommandShortcut` |
1688
- | ShaderSurface | ogl 기반 애니메이션 WebGL 셰이더 배경. 럭셔리 프리셋(메탈릭/실크/유리 등) + 색·파라미터로 배경·카드 배경을 만든다. 정지 프레임·PNG 캡처·WebGL 폴백 지원. | `ShaderSurface` |
1685
+ | Component | Description | Key Exports |
1686
+ | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
1687
+ | FieldToken | 필드 타입을 글리프 하나로 표현하는 토큰. 문자열·숫자·날짜·IP·지오 등 분석 스키마 타입마다 고정된 아이콘과 팔레트 슬롯을 부여해 필드 목록·컬럼 헤더·속성 테이블 전역에서 같은 어휘를 쓴다. | `FieldToken`, `FIELD_TYPE_TOKENS`, `resolveFieldType` |
1688
+ | Facet | 필드 값 분포를 카운트와 점유율 막대로 보여주고 그 행 자체가 필터가 되는 패싯. 긴 꼬리는 접어 두고 상위 값부터 읽힌다. | `Facet`, `FacetGroup` |
1689
+ | Expression | 조건을 폼이 아니라 문장으로 쓰고 그 자리에서 편집하는 표현식 절. 알림 규칙·세그먼트 필터처럼 읽어서 검증해야 하는 조건에 쓴다. | `Expression`, `ExpressionGroup` |
1690
+ | TextTruncate | 실제 폰트로 실제 가용 폭을 측정해 문자열의 식별력이 가장 낮은 부분을 잘라내는 생략. CSS가 못 하는 앞·중간·양끝 생략을 지원하고 전체 문자열은 접근성 트리에 남는다. | `TextTruncate` |
1691
+ | Highlight | 검색어에 해당하는 구간을 <mark>로 표시. 긴 항목 우선 매칭이라 겹치는 검색어도 조각나지 않는다. | `Highlight` |
1692
+ | LiveRegion | 라이브 뷰의 변화를 스크린 리더에 읽어 주는 영역. 스로틀로 폭주를 요약하고 두 노드를 번갈아 써서 같은 문구도 다시 읽힌다. | `LiveRegion` |
1693
+ | ColorPalette | 시각화 색 팔레트를 그 팔레트의 모습 그대로 보여 주고 고르게 하는 컴포넌트. 범주형은 블록, 순차·발산형은 그라디언트로 그려 데이터 종류를 그림이 말한다. | `ColorPaletteDisplay`, `ColorPalettePicker`, `THEME_PALETTES` |
1694
+ | InlineEdit | 대시보드 제목·지표 이름처럼 읽히는 횟수가 훨씬 많은 값을 그 자리에서 고치는 편집. Enter 확정, Escape 되돌리기, 거절된 저장은 입력을 유지한다. | `InlineEdit` |
1695
+ | KeyPadMenu | 이름보다 그림으로 알아보기 쉬운 선택지를 타일로 고르는 메뉴. 내부는 실제 radio·checkbox라 키보드와 스크린 리더가 그대로 동작한다. | `KeyPadMenu` |
1696
+ | Text | 본문, 레이블, 보조 설명, 코드에 일관된 의미 기반 타이포그래피를 적용합니다. | `Text` |
1697
+ | Heading | 문서의 의미 계층과 시각적 타이포그래피 계층을 독립적으로 제어합니다. | `Heading` |
1698
+ | Separator | 콘텐츠를 구분하는 가로/세로 디바이더. 라벨을 넣으면 가운데 정렬 구분선이 된다. | `Separator` |
1699
+ | OtpField | 일회용 코드(OTP)/PIN 입력. 셀 단위 입력, 붙여넣기 분배, 자동 포커스 이동, 백스페이스 네비게이션과 폼 이름/오류 연결을 지원합니다. | `OtpField` |
1700
+ | Toggle | 눌림(pressed) 두 상태 버튼. 단독 사용하거나 ToggleGroup으로 묶어 단일/다중 선택을 만든다. | `Toggle`, `ToggleGroup` |
1701
+ | Accordion | 수직으로 쌓인 펼침/접힘 패널. single(한 개)/multiple(여러 개) 모드와 collapsible 지원. | `AccordionRoot`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` |
1702
+ | Meter | 범위 내 스칼라 측정값 게이지 (디스크 사용량·점수·용량 등). role=meter로 작업 진행률(Progress)과 구분된다. | `Meter` |
1703
+ | DescriptionList | 대상의 라벨 있는 사실들을 시맨틱 <dl>로 표시한다. 상세 패널의 필드 나열을 표준화하고 식별자 복사를 제공한다. | `DescriptionList` |
1704
+ | Identity | 사람(또는 익명 디바이스)을 목록 칸으로 표현한다. 이름→이메일→ID 폴백과 익명 표식을 한 곳에서 처리한다. | `Identity` |
1705
+ | BlockLayout | Block 루트 레이아웃. 자식 section spacing과 선택적 시맨틱 inset을 제공하고 loading prop으로 LoadingOverlay를 자동 래핑합니다. | `BlockLayout` |
1706
+ | createBlock | Block 팩토리 함수. BlockLayout 래핑을 구조적으로 강제하여 loading/className 처리를 자동화합니다. | `createBlock` |
1707
+ | StarRating | 1~N점 별점을 선택하는 인터랙티브 레이팅 입력. 읽기 전용 표시도 지원. | `StarRating` |
1708
+ | ErrorBoundary | React 에러 바운더리. 자식 컴포넌트 렌더 에러를 잡아 fallback UI를 표시합니다. | `ErrorBoundary` |
1709
+ | Command | cmdk 스타일 명령 anatomy. 자동 필터링 + 키보드 내비게이션. 인라인 또는 CommandDialog로 사용. | `Command`, `CommandDialog`, `CommandInput`, `CommandList`, `CommandEmpty`, `CommandGroup`, `CommandItem`, `CommandSeparator`, `CommandShortcut` |
1710
+ | ShaderSurface | ogl 기반 애니메이션 WebGL 셰이더 배경. 럭셔리 프리셋(메탈릭/실크/유리 등) + 색·파라미터로 배경·카드 배경을 만든다. 정지 프레임·PNG 캡처·WebGL 폴백 지원. | `ShaderSurface` |
1711
+ | Callout | 페이지에 머무는 인페이지 고지. Alert와 달리 dismiss가 없고, 조건이 참인 동안 레이아웃의 일부로 남습니다. | `Callout` |
1712
+ | StatusDot | 점 + 텍스트로 상태를 표현합니다. 라벨이 필수라 색만으로 상태를 말할 수 없습니다. | `StatusDot` |
1713
+ | CopyButton | 값을 클립보드에 올리고 성공 여부를 알립니다. 클립보드 거부를 삼키지 않습니다. | `CopyButton` |
1714
+ | SegmentedControl | 선택지를 모두 보여주는 단일 선택 컨트롤. radio-group 프리미티브 위에 올려 화살표 키가 동작합니다. | `SegmentedControl` |
1689
1715
 
1690
1716
  ### FieldToken
1691
1717
 
@@ -1903,11 +1929,11 @@ import {
1903
1929
 
1904
1930
  **Import:** `import { Heading } from "@reopt-ai/opt-ui"`
1905
1931
 
1906
- | Prop | Type | Required | Default | Description |
1907
- | ---------- | ------------------------------------------------------------------------ | -------- | ------- | ------------------------ |
1908
- | `level` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | | | 의미 기반 HTML 제목 레벨 |
1909
- | `variant` | `"heading-1" "heading-6" \| "display-1" \| "display-2" \| "display-3"` | | | 시각적 제목 역할 |
1910
- | `children` | `ReactNode` | | | 제목 콘텐츠 |
1932
+ | Prop | Type | Required | Default | Description |
1933
+ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- | ------------------------ |
1934
+ | `level` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | | | 의미 기반 HTML 제목 레벨 |
1935
+ | `variant` | `"heading-1" \| "heading-2" \| "heading-3" \| "heading-4" \| "heading-5" \| "heading-6" \| "display-1" \| "display-2" \| "display-3"` | | | 시각적 제목 역할 |
1936
+ | `children` | `ReactNode` | | | 제목 콘텐츠 |
1911
1937
 
1912
1938
  ### Separator
1913
1939
 
@@ -2028,6 +2054,38 @@ import {
2028
2054
  | `showValue` | `boolean` | | false | 퍼센트 표시 |
2029
2055
  | `label` | `string` | | | 레이블 텍스트 |
2030
2056
 
2057
+ ### DescriptionList
2058
+
2059
+ > 한 대상의 라벨 있는 사실들을 시맨틱 <dl>로 표시한다. 상세 패널의 필드 나열을 표준화하고 식별자 복사를 제공한다.
2060
+
2061
+ **Import:** `import { DescriptionList } from "@reopt-ai/opt-ui"`
2062
+
2063
+ | Prop | Type | Required | Default | Description |
2064
+ | ------------ | ------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
2065
+ | `items` | `DescriptionListItem[]` | Yes | | term/description 쌍 배열. { id, term, description, copyValue?, hint?, wrap? } |
2066
+ | `layout` | `"grid" \| "stack" \| "inline"` | | "grid" | grid는 각 쌍을 박스로 감싼다(필드가 많은 상세 패널). stack은 평범한 정의 목록, inline은 헤더 스트립용 한 줄 배치 |
2067
+ | `columns` | `1 \| 2 \| 3 \| 4` | | 2 | grid/stack 레이아웃의 컬럼 수 |
2068
+ | `compressed` | `boolean` | | false | 밀도 축소 |
2069
+ | `labels` | `DescriptionListLabels` | | | 복사/복사됨/빈 값 문구 |
2070
+
2071
+ ### Identity
2072
+
2073
+ > 사람(또는 익명 디바이스)을 목록 셀 한 칸으로 표현한다. 이름→이메일→ID 폴백과 익명 표식을 한 곳에서 처리한다.
2074
+
2075
+ **Import:** `import { Identity } from "@reopt-ai/opt-ui"`
2076
+
2077
+ | Prop | Type | Required | Default | Description |
2078
+ | ------------ | --------------------------------------------- | -------- | ------- | ------------------------------------------------------------ |
2079
+ | `name` | `string \| null` | | | 표시 이름. 없으면 secondary, 그다음 id로 폴백한다 |
2080
+ | `secondary` | `string \| null` | | | 보통 이메일. 이름이 없으면 주 라벨로 승격된다 |
2081
+ | `id` | `string` | | | 최후 폴백 라벨이자 hover 시 title |
2082
+ | `avatarSrc` | `string \| null` | | | 아바타 이미지 URL |
2083
+ | `state` | `"identified" \| "anonymous"` | | | 익명 여부. 디바이스를 사람으로 오독하지 않게 배지로 표시한다 |
2084
+ | `badge` | `ReactNode` | | | state 배지 대신 표시할 내용 (라이프사이클 단계 등) |
2085
+ | `size` | `"sm" \| "md"` | | "md" | 밀도 프리셋 |
2086
+ | `hideAvatar` | `boolean` | | false | 이미 밀도가 높은 행에서 아바타 제거 |
2087
+ | `labels` | `{ identified?: string; anonymous?: string }` | | | 식별/익명 배지 문구 |
2088
+
2031
2089
  ### BlockLayout
2032
2090
 
2033
2091
  > Block 루트 레이아웃. 자식 간 section spacing과 선택적 시맨틱 inset을 제공하고 loading prop으로 LoadingOverlay를 자동 래핑합니다.
@@ -2190,3 +2248,62 @@ const MyDashboard = createBlock<MyDashboardProps>(
2190
2248
  | `angle` | `number` | | | 회전 각도(도) |
2191
2249
  | `paused` | `boolean` | | | true면 단일 프레임만 렌더 (카드 배경 등) |
2192
2250
  | `dpr` | `number` | | | device pixel ratio 상한 (기본 min(dpr, 2)) |
2251
+
2252
+ ### Callout
2253
+
2254
+ > 페이지에 머무는 인페이지 고지. Alert와 달리 dismiss가 없고, 조건이 참인 동안 레이아웃의 일부로 남습니다.
2255
+
2256
+ **Import:** `import { Callout } from "@reopt-ai/opt-ui"`
2257
+
2258
+ | Prop | Type | Required | Default | Description |
2259
+ | ---------- | ----------------------------------------------------------- | -------- | ------- | ------------------------------------------- |
2260
+ | `tone` | `"info" \| "success" \| "warning" \| "danger" \| "neutral"` | | "info" | 고지의 성격 |
2261
+ | `title` | `ReactNode` | | | 한 줄 제목 |
2262
+ | `icon` | `ReactNode` | | | tone 기본 글리프 대체. null이면 글리프 없음 |
2263
+ | `action` | `ReactNode` | | | 다음 한 걸음. 둘 이상이면 고지가 아니라 폼 |
2264
+ | `size` | `"sm" \| "md"` | | "md" | 밀도 |
2265
+ | `children` | `ReactNode` | | | 본문 |
2266
+
2267
+ ### StatusDot
2268
+
2269
+ > 점 + 텍스트로 상태를 표현합니다. 라벨이 필수라 색만으로 상태를 말할 수 없습니다.
2270
+
2271
+ **Import:** `import { StatusDot } from "@reopt-ai/opt-ui"`
2272
+
2273
+ | Prop | Type | Required | Default | Description |
2274
+ | ---------- | ---------------------------------------------------------------------- | -------- | --------- | -------------------------------------- |
2275
+ | `tone` | `"neutral" \| "muted" \| "info" \| "success" \| "warning" \| "danger"` | | "neutral" | 점 색상 |
2276
+ | `size` | `"sm" \| "md"` | | "md" | 점과 글자 크기 |
2277
+ | `children` | `ReactNode` | Yes | | 상태 라벨. 필수 — 색은 상태가 아닙니다 |
2278
+ | `hint` | `string` | | | 판정 기준 툴팁 |
2279
+
2280
+ ### CopyButton
2281
+
2282
+ > 값을 클립보드에 올리고 성공 여부를 알립니다. 클립보드 거부를 삼키지 않습니다.
2283
+
2284
+ **Import:** `import { CopyButton } from "@reopt-ai/opt-ui"`
2285
+
2286
+ | Prop | Type | Required | Default | Description |
2287
+ | ------------------ | ----------------------- | -------- | ------- | ------------------------------------------------------- |
2288
+ | `value` | `string` | Yes | | 복사할 텍스트 |
2289
+ | `variant` | `"icon" \| "text"` | | "icon" | 글리프만 / 글리프 + 라벨 |
2290
+ | `size` | `"sm" \| "md"` | | "md" | 버튼 크기 |
2291
+ | `feedbackDuration` | `number` | | 1500 | 확인 상태 유지 시간 (ms) |
2292
+ | `onCopy` | `(ok: boolean) => void` | | | 실제로 복사됐는지 — 비보안 컨텍스트·권한 거부에서 false |
2293
+ | `labels` | `CopyButtonLabels` | | | copy / copied / failed 문구 |
2294
+
2295
+ ### SegmentedControl
2296
+
2297
+ > 선택지를 모두 보여주는 단일 선택 컨트롤. radio-group 프리미티브 위에 올려 화살표 키가 동작합니다.
2298
+
2299
+ **Import:** `import { SegmentedControl } from "@reopt-ai/opt-ui"`
2300
+
2301
+ | Prop | Type | Required | Default | Description |
2302
+ | ------------ | ----------------------------- | -------- | ------- | ------------------------------------------------------- |
2303
+ | `options` | `SegmentedControlOption<T>[]` | Yes | | 세그먼트 목록 (value / label / icon / badge / disabled) |
2304
+ | `value` | `T` | Yes | | 선택된 값 |
2305
+ | `onChange` | `(value: T) => void` | Yes | | 선택 변경 |
2306
+ | `size` | `"sm" \| "md"` | | "md" | 컨트롤 크기 |
2307
+ | `fullWidth` | `boolean` | | false | 컨테이너를 균등 분할 |
2308
+ | `disabled` | `boolean` | | false | 전체 비활성 |
2309
+ | `aria-label` | `string` | Yes | | radiogroup 이름. 필수 |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Visual Components"
3
3
  description: "0 Visual layer components — props, examples, keyboard shortcuts."
4
- version: "1.9.0"
4
+ version: "1.12.0"
5
5
  generated: true
6
6
  ---
7
7