@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.
- package/CHANGELOG.md +40 -0
- package/COMPONENT_CATALOG.md +3000 -0
- package/LICENSE +21 -0
- package/README.md +244 -0
- package/dist/chunk-3GWWZKX7.js +38 -0
- package/dist/chunk-AFF2HPE5.cjs +5008 -0
- package/dist/chunk-ELWICXYY.js +4745 -0
- package/dist/chunk-N4NDU5ET.cjs +4745 -0
- package/dist/chunk-ONE3C5RV.cjs +38 -0
- package/dist/chunk-QWBHD54V.js +3218 -0
- package/dist/chunk-RBM2RNC2.js +5008 -0
- package/dist/chunk-X5WCXJAF.cjs +3218 -0
- package/dist/core/index.cjs +324 -0
- package/dist/core/index.d.cts +5 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +324 -0
- package/dist/docs/01-getting-started.md +129 -0
- package/dist/docs/02-components/01-core.md +1841 -0
- package/dist/docs/02-components/02-visuals.md +11 -0
- package/dist/docs/02-components/03-shells.md +1361 -0
- package/dist/docs/02-components/04-surfaces.md +11 -0
- package/dist/docs/02-components/index.md +106 -0
- package/dist/docs/03-recipes/01-forms.md +471 -0
- package/dist/docs/03-recipes/02-dashboards.md +397 -0
- package/dist/docs/03-recipes/03-layouts.md +424 -0
- package/dist/docs/04-theming.md +232 -0
- package/dist/docs/05-migration/01-breaking-changes.md +117 -0
- package/dist/docs/05-migration/02-formstore.md +336 -0
- package/dist/docs/06-troubleshooting.md +119 -0
- package/dist/docs/index.md +71 -0
- package/dist/id-registry.cjs +1875 -0
- package/dist/id-registry.d.cts +27 -0
- package/dist/id-registry.d.ts +27 -0
- package/dist/id-registry.js +1875 -0
- package/dist/id-registry.json +3799 -0
- package/dist/index-BZ_lBlO1.d.ts +474 -0
- package/dist/index-BuvxoWHf.d.cts +474 -0
- package/dist/index-DlAcuvQp.d.cts +1686 -0
- package/dist/index-Slu5hOj1.d.ts +1686 -0
- package/dist/index.cjs +9959 -0
- package/dist/index.d.cts +2351 -0
- package/dist/index.d.ts +2351 -0
- package/dist/index.js +9959 -0
- package/dist/meta.cjs +6898 -0
- package/dist/meta.d.cts +36 -0
- package/dist/meta.d.ts +36 -0
- package/dist/meta.js +6869 -0
- package/dist/shells/index.cjs +65 -0
- package/dist/shells/index.d.cts +5 -0
- package/dist/shells/index.d.ts +5 -0
- package/dist/shells/index.js +65 -0
- package/dist/tailwind.css +401 -0
- package/dist/theme/presets/default.css +355 -0
- package/dist/theme/presets/minimal.css +354 -0
- package/dist/theme/presets/mono-dark.css +354 -0
- package/dist/theme/presets/natural.css +181 -0
- package/dist/theme/presets/pro.css +354 -0
- package/dist/types-D4-0lwaE.d.cts +298 -0
- package/dist/types-D4-0lwaE.d.ts +298 -0
- package/dist/visuals/index.cjs +4 -0
- package/dist/visuals/index.d.cts +1 -0
- package/dist/visuals/index.d.ts +1 -0
- package/dist/visuals/index.js +4 -0
- package/package.json +165 -0
|
@@ -0,0 +1,3000 @@
|
|
|
1
|
+
# @reopt-ai/opt-ui Component Catalog
|
|
2
|
+
|
|
3
|
+
<!-- DEPRECATED: Prefer dist/docs/02-components/ for per-layer reference. -->
|
|
4
|
+
<!-- Auto-generated from ComponentMeta. Do not edit. -->
|
|
5
|
+
<!-- Version: 1.4.1 -->
|
|
6
|
+
|
|
7
|
+
## Quick Stats
|
|
8
|
+
|
|
9
|
+
| Layer | Count |
|
|
10
|
+
| --------- | ------- |
|
|
11
|
+
| Core | 59 |
|
|
12
|
+
| Visuals | 0 |
|
|
13
|
+
| Shells | 75 |
|
|
14
|
+
| Surfaces | 0 |
|
|
15
|
+
| **Total** | **134** |
|
|
16
|
+
|
|
17
|
+
## Component Selection Guide
|
|
18
|
+
|
|
19
|
+
| 요구사항 | 추천 컴포넌트 | 레이어 |
|
|
20
|
+
| ------------------- | -------------------------------------------------- | ------------ |
|
|
21
|
+
| 텍스트 입력 | Input | Core |
|
|
22
|
+
| 멀티라인 텍스트 | Textarea | Core |
|
|
23
|
+
| 숫자 입력 | NumberInput | Core |
|
|
24
|
+
| 드롭다운 선택 | Select / StatusSelect / BranchSelect | Core / Shell |
|
|
25
|
+
| 검색 + 선택 | Combobox / SearchCombobox / AsyncCombobox | Core / Shell |
|
|
26
|
+
| 체크박스 | Checkbox / CheckboxGroup | Core |
|
|
27
|
+
| 라디오 버튼 | RadioGroup | Core |
|
|
28
|
+
| 토글 스위치 | Switch | Core |
|
|
29
|
+
| 날짜 범위 선택 | DateRangePicker | Core |
|
|
30
|
+
| 태그 입력 | TagInput | Core |
|
|
31
|
+
| 색상 선택 | ColorPicker | Core |
|
|
32
|
+
| 아이콘 선택 | IconPicker | Core |
|
|
33
|
+
| 데이터 테이블 | DataTable | Shell |
|
|
34
|
+
| 인라인 편집 테이블 | InlineEditTable | Shell |
|
|
35
|
+
| 트리/계층 테이블 | TreeTable | Shell |
|
|
36
|
+
| 칸반 보드 | KanbanBoard | Shell |
|
|
37
|
+
| 필터 바 | FilterBar | Shell |
|
|
38
|
+
| 필터 프리셋 저장 | SavedFilters | Shell |
|
|
39
|
+
| 일괄 작업 | BulkActions | Shell |
|
|
40
|
+
| 컬럼 표시 토글 | ColumnToggler | Shell |
|
|
41
|
+
| 시간 범위 선택 | TimeRangeSelector | Shell |
|
|
42
|
+
| A/B 비교 선택 | ComparisonSelector | Shell |
|
|
43
|
+
| 선 차트 / 영역 차트 | LineChart / AreaChart | Visual |
|
|
44
|
+
| 막대 차트 | BarChart | Visual |
|
|
45
|
+
| 파이/도넛 차트 | PieChart | Visual |
|
|
46
|
+
| 인라인 스파크라인 | Sparkline | Visual |
|
|
47
|
+
| 흐름 다이어그램 | SankeyChart | Visual |
|
|
48
|
+
| 퍼널 차트 | FunnelChart | Visual |
|
|
49
|
+
| 리텐션 히트맵 | RetentionHeatmap | Visual |
|
|
50
|
+
| 캘린더 히트맵 | CalendarHeatmap | Visual |
|
|
51
|
+
| 폭포 차트 | WaterfallChart | Visual |
|
|
52
|
+
| 버블 차트 | BubbleChart | Visual |
|
|
53
|
+
| 게이지/미터 | GaugeChart | Visual |
|
|
54
|
+
| KPI/통계 카드 | StatCard (Core) / MetricsCard / SummaryRow (Shell) | Core / Shell |
|
|
55
|
+
| 모달 대화상자 | Dialog | Core |
|
|
56
|
+
| 확인 대화상자 | ConfirmDialog | Shell |
|
|
57
|
+
| 서랍 패널 | Drawer | Core |
|
|
58
|
+
| 팝오버 | Popover | Core |
|
|
59
|
+
| 드롭다운 메뉴 | DropdownMenu | Core |
|
|
60
|
+
| 토스트 알림 | NotificationToast | Shell |
|
|
61
|
+
| 알림 센터 | NotificationCenter | Shell |
|
|
62
|
+
| 사이드바 내비게이션 | SidebarNav / Sidebar | Shell |
|
|
63
|
+
| 앱 레이아웃 | AppShell | Shell |
|
|
64
|
+
| 탭 내비게이션 | Tabs (Core) / ContentTabs / VerticalTabs (Shell) | Core / Shell |
|
|
65
|
+
| 메뉴 | Menu (Core) / AppMenubar / MegaMenu (Shell) | Core / Shell |
|
|
66
|
+
| 커맨드 팔레트 | CommandPalette | Shell |
|
|
67
|
+
| 아코디언 | Disclosure (Core) / FaqAccordion (Shell) | Core / Shell |
|
|
68
|
+
| 설정 폼 | SettingsForm | Shell |
|
|
69
|
+
| 로그인 폼 | AuthForm | Shell |
|
|
70
|
+
| 다단계 폼 | WizardForm | Shell |
|
|
71
|
+
| 동적 필드 폼 | DynamicFieldForm | Shell |
|
|
72
|
+
| 파일 업로드 폼 | FileUploadForm | Shell |
|
|
73
|
+
| SQL 에디터 | SqlEditor | Shell |
|
|
74
|
+
| 코드 표시 | CodeSnippetViewer | Shell |
|
|
75
|
+
| 코드 비교 | CodeDiffViewer | Shell |
|
|
76
|
+
| 리치 텍스트 에디터 | RichTextEditor | Shell |
|
|
77
|
+
| 단계 빌더 | StepBuilder | Core |
|
|
78
|
+
| 조건 빌더 | ConditionBuilder | Core |
|
|
79
|
+
| 경로 탐색 | Breadcrumb | Core |
|
|
80
|
+
| 빈 상태 표시 | EmptyState | Core |
|
|
81
|
+
| 로딩 스피너 | Spinner / LoadingOverlay | Core |
|
|
82
|
+
| 프로그레스 바 | Progress | Core |
|
|
83
|
+
| 아바타 | Avatar | Core |
|
|
84
|
+
| 페이지네이션 | Pagination | Core |
|
|
85
|
+
| 가상 목록 | VirtualList | Core |
|
|
86
|
+
| 리사이즈 패널 | Resizable | Core |
|
|
87
|
+
| 페이지 헤더 | PageHeader | Core |
|
|
88
|
+
| 테마 전환 | ThemeSwitcher | Shell |
|
|
89
|
+
| 데이터 내보내기 | ExportButton | Shell |
|
|
90
|
+
| 데이터 임포트 | DataImportWizard | Shell |
|
|
91
|
+
| 웹훅 설정 | WebhookConfig | Shell |
|
|
92
|
+
| 피처 플래그 | FeatureFlagPanel | Shell |
|
|
93
|
+
| 감사 로그 | AuditLog | Shell |
|
|
94
|
+
| 워크플로우 에디터 | WorkflowCanvas | Shell |
|
|
95
|
+
| 인사이트/이상탐지 | InsightsPanel | Shell |
|
|
96
|
+
| 프롬프트 템플릿 | PromptTemplate | Shell |
|
|
97
|
+
|
|
98
|
+
## Core Components (59)
|
|
99
|
+
|
|
100
|
+
### Input
|
|
101
|
+
|
|
102
|
+
| Component | Description | Key Exports |
|
|
103
|
+
| --------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
|
104
|
+
| Input | 독립적인 텍스트 입력 컴포넌트. 레이블, 에러, 힌트, 아이콘 지원. | `Input` |
|
|
105
|
+
| Textarea | 멀티라인 텍스트 입력. Input과 동일한 API (label, error, hint). | `Textarea` |
|
|
106
|
+
| NumberInput | 숫자 입력 컴포넌트. +/- 버튼, nullable/clear, unit suffix, invalid draft alert, min/max, step, 키보드 화살표를 지원합니다. | `NumberInput` |
|
|
107
|
+
| Checkbox | 독립적인 체크박스 컴포넌트. 레이블, 설명, 그룹과 DOM property까지 동기화되는 indeterminate 상태를 지원합니다. | `Checkbox`, `CheckboxGroup` |
|
|
108
|
+
| RadioGroup | 독립적인 라디오 그룹 컴포넌트. 그룹 설명과 항목별 설명을 분리 연결하고 다양한 크기를 지원합니다. | `RadioGroup`, `Radio` |
|
|
109
|
+
| Switch | 토글 스위치 컴포넌트. 3가지 크기와 레이블/설명의 명시적 접근성 연결을 지원합니다. | `Switch` |
|
|
110
|
+
| Select | 드롭다운 선택 컴포넌트. 5-part anatomy: Root, Label, Trigger, Popover, Item. | `SelectRoot`, `SelectLabel`, `SelectTrigger`, `SelectPopover`, `SelectItem` |
|
|
111
|
+
| Combobox | 자동완성 검색 입력. 7 exports: Root, Input, Popover, Item, Group, GroupLabel, Empty. | `ComboboxRoot`, `ComboboxInput`, `ComboboxPopover`, `ComboboxItem`, `ComboboxGroup`, `ComboboxGroupLabel`, `ComboboxEmpty` |
|
|
112
|
+
| DateRangePicker | 날짜 범위 선택 컴포넌트. 프리셋, 달력 UI, 포커스 관리와 RTL 방향 탐색 아이콘을 지원합니다. | `DateRangePicker` |
|
|
113
|
+
| TagInput | 태그 입력 컴포넌트. 텍스트를 입력하고 Enter로 태그를 추가, Backspace로 삭제합니다. | `TagInput` |
|
|
114
|
+
| ColorPicker | 색상 선택 컴포넌트. 프리셋 팔레트와 hex 입력을 지원합니다. | `ColorPicker` |
|
|
115
|
+
| IconPicker | 아이콘 선택 컴포넌트. 검색, 그룹별 분류, semantic key 기반 Lucide 아이콘과 커스텀 ReactNode를 지원합니다. | `IconPicker` |
|
|
116
|
+
| Slider | 범위 슬라이더 입력. native range input 래핑, 범위로 정규화된 값/ARIA 상태, 값 표시와 포맷 함수를 지원합니다. | `Slider` |
|
|
117
|
+
|
|
118
|
+
### Form Integration
|
|
119
|
+
|
|
120
|
+
| Component | Description | Key Exports |
|
|
121
|
+
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| Form | 접근성 폼 시스템. opt-ui-primitives Form API 기반. 31 exports: FormRoot, FormProvider, FormGroup, FormGroupLabel, FormDescription, FormField, FormControl, FormInput, FormTextarea, FormSelect, FormSelectPopover, FormSelectItem, FormSwitch, FormLabel, FormError, FormSubmit, FormCheckbox, FormRadioGroup, FormRadio, FormPush, FormRemove, FormReset, FormNumberInput, FormSlider, FormStarRating, FormColorPicker, FormIconPicker, FormTagInput, FormDateRangePicker + useFormStore, useFormContext hooks. | `FormRoot`, `FormProvider`, `FormGroup`, `FormGroupLabel`, `FormDescription`, `FormField`, `FormControl`, `FormInput`, `FormTextarea`, `FormSelect`, `FormSelectPopover`, `FormSelectItem`, `FormSwitch`, `FormLabel`, `FormError`, `FormSubmit`, `FormCheckbox`, `FormRadioGroup`, `FormRadio`, `FormPush`, `FormRemove`, `FormReset`, `FormNumberInput`, `FormSlider`, `FormStarRating`, `FormColorPicker`, `FormIconPicker`, `FormTagInput`, `FormDateRangePicker`, `useFormStore`, `useFormContext` |
|
|
123
|
+
|
|
124
|
+
### Display
|
|
125
|
+
|
|
126
|
+
| Component | Description | Key Exports |
|
|
127
|
+
| -------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
128
|
+
| Kbd | 키보드 단축키를 시각적으로 표시하는 인라인 뱃지 컴포넌트. | `Kbd` |
|
|
129
|
+
| Button | 접근성 버튼 컴포넌트. 4가지 변형(primary, secondary, ghost, danger), 3가지 크기, 로딩/아이콘과 aria-busy 상태를 지원합니다. | `Button` |
|
|
130
|
+
| Badge | 인라인 상태 뱃지. 5가지 색상 변형, 상태 점(dot) 옵션 지원. | `Badge` |
|
|
131
|
+
| Alert | 알림 메시지 컴포넌트. 4가지 변형(info, success, warning, error), 제목/본문/닫기 버튼 지원. | `Alert` |
|
|
132
|
+
| Spinner | 로딩 상태 표시 스피너. 3가지 크기와 장식용 aria-hidden 모드를 지원합니다. | `Spinner` |
|
|
133
|
+
| LoadingOverlay | 로딩 오버레이. 중복 status 없이 하나의 aria-busy 라이브 영역으로 콘텐츠 위 로딩 상태를 표시합니다. | `LoadingOverlay` |
|
|
134
|
+
| Progress | 진행률 표시. Linear/Circular, determinate/indeterminate 변형과 안전하게 보정된 ARIA 값을 지원합니다. | `Progress`, `CircularProgress` |
|
|
135
|
+
| Avatar | 사용자 아바타. 이미지, 이니셜 자동 생성, 스크린 리더에 노출되는 상태 인디케이터, 그룹을 지원합니다. | `Avatar`, `AvatarGroup` |
|
|
136
|
+
| Skeleton | 로딩 플레이스홀더. text/circular/rectangular 변형. 프리셋 컴포넌트 포함. | `Skeleton`, `SkeletonText`, `SkeletonAvatar`, `SkeletonCard`, `SkeletonTable` |
|
|
137
|
+
| Card | 범용 카드 컨테이너. Header, Title, Description, Content, Footer 하위 컴포넌트 포함. | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` |
|
|
138
|
+
| Breadcrumb | 현재 위치를 표시하고 계층 탐색을 제공하는 컴포넌트. | `Breadcrumb` |
|
|
139
|
+
| EmptyState | 데이터가 없을 때 표시하는 빈 상태 컴포넌트. 아이콘, 제목, 설명, 액션 버튼 지원. | `EmptyState` |
|
|
140
|
+
| StatCard | 트렌드 방향과 변화량을 표시하는 통계 카드. | `StatCard` |
|
|
141
|
+
| Logo | 아이콘+텍스트 조합, 이미지, 링크 래핑을 지원하는 로고 컴포넌트. Sidebar 등에서 활용. | `Logo` |
|
|
142
|
+
|
|
143
|
+
### Navigation & Overlay
|
|
144
|
+
|
|
145
|
+
| Component | Description | Key Exports |
|
|
146
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
147
|
+
| Menu | 메뉴바 + 개별 메뉴 시스템. 10 exports: MenubarRoot, MenubarContainer, MenuRoot, MenuTrigger, MenuButtonArrow, MenuPopover, MenuItem, MenuItemCheckbox, MenuItemRadio, MenuSeparator. | `MenubarRoot`, `MenubarContainer`, `MenuRoot`, `MenuTrigger`, `MenuButtonArrow`, `MenuPopover`, `MenuItem`, `MenuItemCheckbox`, `MenuItemRadio`, `MenuSeparator` |
|
|
148
|
+
| DropdownMenu | Menu Core 위의 간편 래퍼. 단일 트리거 드롭다운 메뉴에 특화되었습니다. | `DropdownMenu`, `DropdownTrigger`, `DropdownContent`, `DropdownItem`, `DropdownSeparator` |
|
|
149
|
+
| Popover | Popover 프리미티브 래퍼. 트리거 요소에 연결된 플로팅 콘텐츠를 표시합니다. | `PopoverRoot`, `PopoverTrigger`, `PopoverContent`, `PopoverClose` |
|
|
150
|
+
| Tabs | 탭 패널 시스템. 4-part anatomy: Root, TabList, Tab, TabPanel. | `TabsRoot`, `TabList`, `Tab`, `TabPanel` |
|
|
151
|
+
| Disclosure | 접기/펼치기 콘텐츠 영역. 3-part anatomy: Root, Trigger, Content. | `DisclosureRoot`, `DisclosureTrigger`, `DisclosureContent` |
|
|
152
|
+
| Dialog | 모달 다이얼로그. 9-part anatomy: Root, Disclosure, Panel, Heading, Description, Dismiss, Header, Body, Footer. | `DialogRoot`, `DialogDisclosure`, `DialogPanel`, `AlertDialogPanel`, `DialogHeading`, `DialogDescription`, `DialogDismiss`, `DialogHeader`, `DialogBody`, `DialogFooter` |
|
|
153
|
+
| Drawer | 사이드/하단 슬라이드 패널. Dialog 기반 compound 패턴으로 접근성을 보장합니다. | `DrawerRoot`, `DrawerPanel`, `DrawerClose` |
|
|
154
|
+
| Toolbar | 툴바 컨테이너 + 툴팁. 7 exports: ToolbarRoot, ToolbarContainer, ToolbarButton, ToolbarSeparator, TooltipProvider, TooltipAnchor, Tooltip. | `ToolbarRoot`, `ToolbarContainer`, `ToolbarButton`, `ToolbarSeparator`, `TooltipProvider`, `TooltipAnchor`, `Tooltip` |
|
|
155
|
+
| Pagination | 페이지 넘김 네비게이션. ellipsis 포함 페이지 번호, compact/count variant, totalPages/cursor pagination, Prev/Next 버튼을 제공합니다. | `Pagination` |
|
|
156
|
+
|
|
157
|
+
### Layout
|
|
158
|
+
|
|
159
|
+
| Component | Description | Key Exports |
|
|
160
|
+
| ------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
161
|
+
| CompositeZone | Composite 기반 2D 키보드 탐색 컨테이너. 화살표 키로 자식 요소 간 이동 가능. | `CompositeZone` |
|
|
162
|
+
| PageHeader | 페이지 제목, 설명, 액션 슬롯을 제공하는 레이아웃 헤더 컴포넌트. | `PageHeader` |
|
|
163
|
+
| ScrollArea | 커스텀 스크롤바를 제공하는 스크롤 컨테이너. 수직/수평/양방향 지원. | `ScrollArea` |
|
|
164
|
+
| Container | 최대 너비 제약과 중앙 정렬을 제공하는 래퍼. 페이지 콘텐츠 폭 제한용. | `Container` |
|
|
165
|
+
| Section | 시맨틱 스페이싱 블록. 제목이 있으면 aria-labelledby를 자동 설정합니다. | `Section` |
|
|
166
|
+
| Resizable | react-resizable-panels 래퍼. 드래그로 크기를 조절할 수 있는 패널 분할 레이아웃. | `ResizablePanelGroup`, `ResizablePanel`, `ResizableHandle` |
|
|
167
|
+
| VirtualList | 가상 스크롤 리스트. 대량 데이터를 윈도잉 기법으로 효율적으로 렌더링합니다. | `VirtualList` |
|
|
168
|
+
|
|
169
|
+
### Builder
|
|
170
|
+
|
|
171
|
+
| Component | Description | Key Exports |
|
|
172
|
+
| ---------------- | ------------------------------------------------------------------------- | ------------------ |
|
|
173
|
+
| StepBuilder | 순서가 있는 단계를 추가, 제거, 재정렬할 수 있는 빌더 컴포넌트. | `StepBuilder` |
|
|
174
|
+
| ConditionBuilder | AND/OR 로직으로 조건 그룹을 구성하는 빌더. 속성, 연산자, 값을 조합합니다. | `ConditionBuilder` |
|
|
175
|
+
|
|
176
|
+
### Other
|
|
177
|
+
|
|
178
|
+
| Component | Description | Key Exports |
|
|
179
|
+
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
180
|
+
| Text | 본문, 레이블, 보조 설명, 코드에 일관된 의미 기반 타이포그래피를 적용합니다. | `Text` |
|
|
181
|
+
| Heading | 문서의 의미 계층과 시각적 타이포그래피 계층을 독립적으로 제어합니다. | `Heading` |
|
|
182
|
+
| Separator | 콘텐츠를 구분하는 가로/세로 디바이더. 라벨을 넣으면 가운데 정렬 구분선이 된다. | `Separator` |
|
|
183
|
+
| OtpField | 일회용 코드(OTP)/PIN 입력. 셀 단위 입력, 붙여넣기 분배, 자동 포커스 이동, 백스페이스 네비게이션과 폼 이름/오류 연결을 지원합니다. | `OtpField` |
|
|
184
|
+
| Toggle | 눌림(pressed) 두 상태 버튼. 단독 사용하거나 ToggleGroup으로 묶어 단일/다중 선택을 만든다. | `Toggle`, `ToggleGroup` |
|
|
185
|
+
| Accordion | 수직으로 쌓인 펼침/접힘 패널. single(한 개)/multiple(여러 개) 모드와 collapsible 지원. | `AccordionRoot`, `AccordionItem`, `AccordionTrigger`, `AccordionContent` |
|
|
186
|
+
| Meter | 범위 내 스칼라 측정값 게이지 (디스크 사용량·점수·용량 등). role=meter로 작업 진행률(Progress)과 구분된다. | `Meter` |
|
|
187
|
+
| BlockLayout | Block 루트 레이아웃. flex + 기본 section spacing 적용, loading prop으로 LoadingOverlay 자동 래핑. | `BlockLayout` |
|
|
188
|
+
| createBlock | Block 팩토리 함수. BlockLayout 래핑을 구조적으로 강제하여 loading/className 처리를 자동화합니다. | `createBlock` |
|
|
189
|
+
| StarRating | 1~N점 별점을 선택하는 인터랙티브 레이팅 입력. 읽기 전용 표시도 지원. | `StarRating` |
|
|
190
|
+
| ErrorBoundary | React 에러 바운더리. 자식 컴포넌트 렌더 에러를 잡아 fallback UI를 표시합니다. | `ErrorBoundary` |
|
|
191
|
+
| Command | cmdk 스타일 명령 anatomy. 자동 필터링 + 키보드 내비게이션. 인라인 또는 CommandDialog로 사용. | `Command`, `CommandDialog`, `CommandInput`, `CommandList`, `CommandEmpty`, `CommandGroup`, `CommandItem`, `CommandSeparator`, `CommandShortcut` |
|
|
192
|
+
| ShaderSurface | ogl 기반 애니메이션 WebGL 셰이더 배경. 럭셔리 프리셋(메탈릭/실크/유리 등) + 색·파라미터로 배경·카드 배경을 만든다. 정지 프레임·PNG 캡처·WebGL 폴백 지원. | `ShaderSurface` |
|
|
193
|
+
|
|
194
|
+
## Visual Components (0)
|
|
195
|
+
|
|
196
|
+
| Component | Description | Key Exports |
|
|
197
|
+
| --------- | ----------- | ----------- |
|
|
198
|
+
|
|
199
|
+
## Shell Components (75)
|
|
200
|
+
|
|
201
|
+
### Navigation & Layout
|
|
202
|
+
|
|
203
|
+
| Component | Description | Key Exports |
|
|
204
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
205
|
+
| AppMenubar | 데스크톱 스타일 메뉴바. 체크박스, 라디오 메뉴 항목 지원. | `AppMenubar` |
|
|
206
|
+
| MegaMenu | 메가 메뉴. Popover + CSS grid 멀티컬럼 + 카테고리 헤딩 + footer 슬롯. | `MegaMenu` |
|
|
207
|
+
| SidebarNav | Composite 기반 사이드바 네비게이션. pathname 자동 동기화. | `SidebarNav` |
|
|
208
|
+
| Sidebar | 접기/펼치기를 지원하는 compound 사이드바. Header/Content/Footer 구조 + Group/Item으로 네비게이션 구성. Ctrl+[ 단축키. | `Sidebar`, `useSidebar` |
|
|
209
|
+
| AppShell | Header + Sidebar + Content + Footer 4영역 페이지 레이아웃 템플릿. Sidebar 컴포넌트와 조합. | `AppShell` |
|
|
210
|
+
| ContentTabs | 탭 콘텐츠 패널. Tabs primitive 래퍼. | `ContentTabs` |
|
|
211
|
+
| VerticalTabs | 세로 탭 레이아웃. 좌측 탭 리스트 + 우측 패널 구성입니다. | `VerticalTabs` |
|
|
212
|
+
| FaqAccordion | FAQ 질문/답변 아코디언. Composite + Disclosure 조합. | `FaqAccordion` |
|
|
213
|
+
| CommandPalette | Cmd+K 스타일 커맨드 팔레트. Dialog + Combobox + match-sorter 퍼지 검색. | `CommandPalette` |
|
|
214
|
+
| CommandPaletteTrigger | CommandPalette + Cmd+K 키보드 단축키 자동 바인딩. | `CommandPaletteTrigger` |
|
|
215
|
+
| ProjectSwitcher | 프로젝트 검색 전환기. Combobox + match-sorter 퍼지 검색 지원. | `ProjectSwitcher` |
|
|
216
|
+
| EditorToolbar | 리치 텍스트 에디터 스타일 툴바. Toolbar + Tooltip 조합. | `EditorToolbar` |
|
|
217
|
+
| FloatingActionBar | 플로팅 액션 바. 선택된 항목에 대한 일괄 작업 버튼을 하단에 표시합니다. | `FloatingActionBar` |
|
|
218
|
+
| TemplatePicker | 템플릿 선택기. 카테고리별 그리드와 검색을 제공하며 featured/tags 표시를 지원합니다. | `TemplatePicker` |
|
|
219
|
+
| ThemeSwitcher | 테마 프리셋 선택기. 프리셋과 light/dark/system 모드 전환. | `ThemeSwitcher` |
|
|
220
|
+
|
|
221
|
+
### Data Display
|
|
222
|
+
|
|
223
|
+
| Component | Description | Key Exports |
|
|
224
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
|
|
225
|
+
| DataTable | 제네릭 데이터 테이블. 동적 컬럼, 결측값 안전 정렬, 키보드 컬럼 리사이즈, 보정된 인라인 진행률과 Composite 탐색을 지원합니다. | `DataTable` |
|
|
226
|
+
| InlineEditTable | 인라인 편집 테이블. 더블클릭으로 셀 편집, Enter 확정, Escape 취소. | `InlineEditTable` |
|
|
227
|
+
| TreeTable | 계층형 트리 테이블. 재귀 행 렌더링 + 펼침/접기 셰브론. | `TreeTable` |
|
|
228
|
+
| DomainTable | 도메인 테이블. Composite 기반 그리드로 키보드 탐색 지원. | `DomainTable` |
|
|
229
|
+
| QueryResultsTable | 쿼리 결과 테이블. SQL 결과와 스크린 리더에 안내되는 로딩, 에러, 빈 상태를 지원합니다. | `QueryResultsTable` |
|
|
230
|
+
| DashboardGrid | Composite 기반 통계 카드 그리드. 유효한 1–4열 레이아웃과 화살표 키 2D 탐색을 지원합니다. | `DashboardGrid` |
|
|
231
|
+
| SummaryRow | 통계 요약 행. StatCard 그리드 레이아웃을 표준화합니다. loading 시 SkeletonCard 표시. | `SummaryRow` |
|
|
232
|
+
| CodeSnippetViewer | 코드 스니펫 뷰어. 줄 번호, 복사 버튼, 포커스 가능한 스크롤 영역, syntaxTheme 톤을 지원합니다. | `CodeSnippetViewer` |
|
|
233
|
+
| CodeDiffViewer | 코드 비교 뷰어. LCS 알고리즘 기반 unified/split 모드 diff와 포커스 가능한 스크롤 영역을 제공합니다. | `CodeDiffViewer` |
|
|
234
|
+
| ConnectionIndicator | 연결 상태 표시기. connected, connecting, disconnected, error 상태를 지원합니다. | `ConnectionIndicator` |
|
|
235
|
+
| EventIcon | 이벤트 아이콘. semantic key 또는 ReactNode 아이콘과 배경색을 표시합니다. | `EventIcon`, `POPULAR_ICONS`, `COLOR_PRESETS` |
|
|
236
|
+
|
|
237
|
+
### Lists & Feeds
|
|
238
|
+
|
|
239
|
+
| Component | Description | Key Exports |
|
|
240
|
+
| ------------------ | ----------------------------------------------------------------------------------- | -------------------- |
|
|
241
|
+
| TaskList | 작업 목록 관리 컴포넌트. 우선순위, 상태, 담당자, 태그, 하위 작업 지원. | `TaskList` |
|
|
242
|
+
| ActivityFeed | 활동 피드/로그 컴포넌트. 타임라인 스타일, 상대 시간 표시. | `ActivityFeed` |
|
|
243
|
+
| TeamMemberList | 팀원 목록 컴포넌트. 온라인 상태, 다양한 레이아웃(list, compact, avatars-only) 지원. | `TeamMemberList` |
|
|
244
|
+
| KanbanBoard | 칸반 보드. HTML5 DnD로 카드를 컬럼 간 드래그&드롭. | `KanbanBoard` |
|
|
245
|
+
| AuditLog | 감사 로그 타임라인. 아바타 + 액션 텍스트 + 메타데이터 배지 레이아웃. | `AuditLog` |
|
|
246
|
+
| NotificationCenter | 알림 센터. 벨 아이콘 트리거 + 미읽음 배지 + 스크롤 알림 목록. | `NotificationCenter` |
|
|
247
|
+
|
|
248
|
+
### Filters & Search
|
|
249
|
+
|
|
250
|
+
| Component | Description | Key Exports |
|
|
251
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------ | -------------------- |
|
|
252
|
+
| SearchCombobox | match-sorter 기반 퍼지 검색 콤보박스. | `SearchCombobox` |
|
|
253
|
+
| AsyncCombobox | 비동기 검색 콤보박스. 디바운스 + 로딩 스피너와 stale response 방어를 내장합니다. | `AsyncCombobox` |
|
|
254
|
+
| StatusSelect | 색상 인디케이터가 있는 상태 선택 드롭다운. | `StatusSelect` |
|
|
255
|
+
| BranchSelect | Git 브랜치 선택 드롭다운. Select primitive 래퍼. | `BranchSelect` |
|
|
256
|
+
| FilterBar | 필터링 바 컴포넌트. 검색, 선택, 다중 선택 필터 지원. | `FilterBar` |
|
|
257
|
+
| SavedFilters | 필터 프리셋 관리. 현재 필터를 저장하고 불러오는 Popover UI. | `SavedFilters` |
|
|
258
|
+
| QuickActions | 빠른 작업 패널. 그리드/리스트 레이아웃, 단축키 표시 지원. | `QuickActions` |
|
|
259
|
+
| TimeRangeSelector | 시간 범위 선택기. Popover + DateRangePicker + 프리셋 버튼 조합. 12개 시계열 Surface에서 사용. | `TimeRangeSelector` |
|
|
260
|
+
| ComparisonSelector | 비교 선택기. 고유 레이블이 연결된 Select × 2 + Swap 버튼 조합. CohortComparison, FunnelAnalysis 등에서 사용합니다. | `ComparisonSelector` |
|
|
261
|
+
| ColumnToggler | 테이블 컬럼 표시/숨김 토글러. Popover + Checkbox 리스트입니다. | `ColumnToggler` |
|
|
262
|
+
| BulkActions | 일괄 작업 바. 선택 카운트 배지 + DropdownMenu 액션 목록 + 해제 버튼. | `BulkActions` |
|
|
263
|
+
|
|
264
|
+
### Forms
|
|
265
|
+
|
|
266
|
+
| Component | Description | Key Exports |
|
|
267
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
|
268
|
+
| SettingsForm | 데이터 기반 설정 폼. 유효성 검증, 라디오, 체크박스 지원. | `SettingsForm` |
|
|
269
|
+
| AuthForm | 로그인/회원가입 모드 전환 가능한 인증 폼. 이메일·비밀번호 검증, FormSwitch로 로그인 상태 유지 옵션 지원. | `AuthForm` |
|
|
270
|
+
| DynamicFieldForm | 런타임 필드 추가/제거 폼. 최소/최대 필드 수 제약, 개별 검증, 동적 스토어 업데이트 지원. | `DynamicFieldForm` |
|
|
271
|
+
| FileUploadForm | 파일 선택, 메타데이터 표시, 이미지 미리보기를 포함한 업로드 폼. 파일 크기 제한, 설명 입력 지원. | `FileUploadForm` |
|
|
272
|
+
| WizardForm | 다단계 순차 입력 폼. FormFieldDef 기반 필드 정의, 단계별 검증, 현재 단계가 연결된 진행 표시기, 리뷰 단계를 지원합니다. | `WizardForm` |
|
|
273
|
+
| ConfirmDialog | 확인/취소 대화 상자. danger 변형으로 위험 작업 확인을 지원합니다. | `ConfirmDialog` |
|
|
274
|
+
| PromptTemplate | AI 프롬프트 뷰어/헬퍼. 변수 입력 → 실시간 치환 → 복사 기능. | `PromptTemplate` |
|
|
275
|
+
|
|
276
|
+
### Infrastructure
|
|
277
|
+
|
|
278
|
+
| Component | Description | Key Exports |
|
|
279
|
+
| ------------------ | --------------------------------------------------------------------------- | -------------------- |
|
|
280
|
+
| DeploymentTimeline | 배포 단계 타임라인. Composite 기반 키보드 탐색 지원. | `DeploymentTimeline` |
|
|
281
|
+
| EnvPanel | 환경변수 패널. Disclosure로 환경별 그룹 접기/펼치기, Composite로 변수 탐색. | `EnvPanel` |
|
|
282
|
+
| WebhookConfig | 웹훅 설정 패널. URL 입력 + 이벤트 체크박스 + 재시도 설정 + 테스트 버튼. | `WebhookConfig` |
|
|
283
|
+
| FeatureFlagPanel | 피처 플래그 관리 패널. 플래그 토글 + 환경 배지 + 롤아웃 % 조절. | `FeatureFlagPanel` |
|
|
284
|
+
| DataImportWizard | 데이터 임포트 마법사. 4단계: 업로드 → 컬럼 매핑 → 미리보기 → 확인. | `DataImportWizard` |
|
|
285
|
+
|
|
286
|
+
### Analytics
|
|
287
|
+
|
|
288
|
+
| Component | Description | Key Exports |
|
|
289
|
+
| ---------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------ |
|
|
290
|
+
| SqlEditor | SQL 에디터. CodeMirror 기반의 SQL 편집기로 구문 강조와 자동 완성을 지원합니다. | `SqlEditor` |
|
|
291
|
+
| EventMetaEditor | 이벤트 메타 에디터. 레이블이 연결된 IconPicker + ColorPicker + TagInput 조합으로 이벤트 메타데이터를 편집합니다. | `EventMetaEditor` |
|
|
292
|
+
| PropertyExplorer | 프로퍼티 탐색기. 검색 가능한 속성 목록을 그룹별로 표시합니다. | `PropertyExplorer` |
|
|
293
|
+
| RichTextEditor | 마크다운 리치 텍스트 에디터. 서식 툴바 + textarea 조합. | `RichTextEditor` |
|
|
294
|
+
| ExportButton | 데이터 내보내기 버튼. CSV/JSON 변환 내장, PDF는 콜백 위임. DropdownMenu 기반. | `ExportButton` |
|
|
295
|
+
| InsightsPanel | 이상 탐지 인사이트 패널. severity별 카드, 통계 필터, dismiss 기능, 검출 설정(유형/Z-score/days). | `InsightsPanel` |
|
|
296
|
+
|
|
297
|
+
### Builders
|
|
298
|
+
|
|
299
|
+
| Component | Description | Key Exports |
|
|
300
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------- |
|
|
301
|
+
| AlertBuilder | 알림 빌더. 명시적으로 연결된 폼 레이블로 메트릭 조건, 빈도, 채널을 구성합니다. | `AlertBuilder` |
|
|
302
|
+
| SegmentBuilder | 세그먼트 빌더. 각 조건 컨트롤의 접근 가능한 이름을 유지하며 event, property, cohort, custom 세그먼트를 정의합니다. | `SegmentBuilder` |
|
|
303
|
+
| ReportBuilder | 리포트 빌더. 레이블이 연결된 4단계 위저드 (차트 타입 → 데이터 설정 → 스타일 → 미리보기). | `ReportBuilder` |
|
|
304
|
+
|
|
305
|
+
### Widgets & Reports
|
|
306
|
+
|
|
307
|
+
| Component | Description | Key Exports |
|
|
308
|
+
| ---------- | ---------------------------------------------------------------------------------------- | ------------ |
|
|
309
|
+
| WidgetGrid | 위젯 그리드. react-grid-layout 래퍼로 드래그/리사이즈 가능한 대시보드 위젯을 배치합니다. | `WidgetGrid` |
|
|
310
|
+
|
|
311
|
+
### Notification
|
|
312
|
+
|
|
313
|
+
| Component | Description | Key Exports |
|
|
314
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
315
|
+
| NotificationToast | 토스트 알림 시스템. 포인터/키보드 상호작용 중 자동 닫힘을 일시 정지하고, 중요도별 live region으로 전역 알림을 관리합니다. | `ToastProvider`, `useToast`, `NotificationToast`, `toast` |
|
|
316
|
+
|
|
317
|
+
### Development
|
|
318
|
+
|
|
319
|
+
| Component | Description | Key Exports |
|
|
320
|
+
| ---------------- | --------------------------------------------------------------------------------------------------- | ------------------ |
|
|
321
|
+
| DesignGuidePanel | 디자인 시스템 참조 패널. 프리미티브 맵, 키보드 패턴, Tailwind 셀렉터, 접근성 속성 등 6개 섹션 제공. | `DesignGuidePanel` |
|
|
322
|
+
|
|
323
|
+
### Workflow
|
|
324
|
+
|
|
325
|
+
| Component | Description | Key Exports |
|
|
326
|
+
| -------------- | ---------------------------------------------------------------------------------- | ---------------- |
|
|
327
|
+
| WorkflowCanvas | 워크플로우 캔버스. 그리드 셀 기반 스텝 배치, SVG 연결선, 키보드 이동을 지원합니다. | `WorkflowCanvas` |
|
|
328
|
+
|
|
329
|
+
### Other
|
|
330
|
+
|
|
331
|
+
| Component | Description | Key Exports |
|
|
332
|
+
| --------------- | -------------------------------------------------------------------------- | ----------------- |
|
|
333
|
+
| PageAside | Sticky 페이지 사이드 aside chrome. 고정 너비 + header/body/footer 3-slot. | `PageAside` |
|
|
334
|
+
| FailureList | 실패 목록 패널. severity별 색상 강조, 그룹핑, 액션 슬롯을 지원합니다. | `FailureList` |
|
|
335
|
+
| KeyValueEditor | 키-값 쌍 편집기. 동적 행 추가/삭제, 비밀값 토글, 유효성 검사를 지원합니다. | `KeyValueEditor` |
|
|
336
|
+
| AuditTimeline | 변경 이력 타임라인. 액션별 색상 코딩 + 확장 가능한 diff 뷰. | `AuditTimeline` |
|
|
337
|
+
| ChatSidebar | AI 채팅 사이드바. 대화 목록, 검색, 새 대화 버튼. | `ChatSidebar` |
|
|
338
|
+
| ChatInput | 채팅 입력 컴포넌트. 자동 리사이즈 textarea, 파일 첨부, 모델/스타일 Select. | `ChatInput` |
|
|
339
|
+
| ChatMessageList | 채팅 메시지 목록. 역할별 말풍선, 타이핑 인디케이터, 자동 스크롤. | `ChatMessageList` |
|
|
340
|
+
|
|
341
|
+
## Surface Components (0)
|
|
342
|
+
|
|
343
|
+
| Surface | Description | Key Props | Dependencies |
|
|
344
|
+
| ------- | ----------- | --------- | ------------ |
|
|
345
|
+
|
|
346
|
+
## Detailed Props Reference
|
|
347
|
+
|
|
348
|
+
### Core Layer
|
|
349
|
+
|
|
350
|
+
#### Text
|
|
351
|
+
|
|
352
|
+
**Import:** `import { Text } from "@reopt-ai/opt-ui"`
|
|
353
|
+
|
|
354
|
+
| Prop | Type | Required | Default | Description |
|
|
355
|
+
| ---------- | ----------------------------------------------------- | -------- | ------- | --------------------- |
|
|
356
|
+
| `as` | `"span" \| "p" \| "div" \| "label" \| "code"` | | | 렌더링할 HTML 요소 |
|
|
357
|
+
| `variant` | `"body" \| "label" \| "supporting" \| "code"` | | | 시각적 텍스트 역할 |
|
|
358
|
+
| `tone` | `"primary" \| "secondary" \| "tertiary" \| "inherit"` | | | 의미 기반 텍스트 색상 |
|
|
359
|
+
| `truncate` | `boolean` | | | 한 줄 말줄임 적용 |
|
|
360
|
+
| `children` | `ReactNode` | | | 텍스트 콘텐츠 |
|
|
361
|
+
|
|
362
|
+
#### Heading
|
|
363
|
+
|
|
364
|
+
**Import:** `import { Heading } from "@reopt-ai/opt-ui"`
|
|
365
|
+
|
|
366
|
+
| Prop | Type | Required | Default | Description |
|
|
367
|
+
| ---------- | ------------------------------------------------------------------------ | -------- | ------- | ------------------------ |
|
|
368
|
+
| `level` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | | | 의미 기반 HTML 제목 레벨 |
|
|
369
|
+
| `variant` | `"heading-1" … "heading-6" \| "display-1" \| "display-2" \| "display-3"` | | | 시각적 제목 역할 |
|
|
370
|
+
| `children` | `ReactNode` | | | 제목 콘텐츠 |
|
|
371
|
+
|
|
372
|
+
#### Kbd
|
|
373
|
+
|
|
374
|
+
**Import:** `import { Kbd } from "@reopt-ai/opt-ui"`
|
|
375
|
+
|
|
376
|
+
| Prop | Type | Required | Default | Description |
|
|
377
|
+
| ---------- | ----------- | -------- | ------- | -------------------- |
|
|
378
|
+
| `children` | `ReactNode` | Yes | | 표시할 단축키 텍스트 |
|
|
379
|
+
|
|
380
|
+
#### Separator
|
|
381
|
+
|
|
382
|
+
**Import:** `import { Separator } from "@reopt-ai/opt-ui"`
|
|
383
|
+
|
|
384
|
+
| Prop | Type | Required | Default | Description |
|
|
385
|
+
| ------------- | ---------------------------- | -------- | ------- | ------------------------------------- |
|
|
386
|
+
| `orientation` | `"horizontal" \| "vertical"` | | | 구분선 방향 (기본 horizontal) |
|
|
387
|
+
| `decorative` | `boolean` | | | 접근성 트리에서 숨김 (순수 시각 구분) |
|
|
388
|
+
| `children` | `ReactNode` | | | 가운데 라벨 (horizontal 전용) |
|
|
389
|
+
| `className` | `string` | | | 추가 CSS 클래스 |
|
|
390
|
+
|
|
391
|
+
#### OtpField
|
|
392
|
+
|
|
393
|
+
**Import:** `import { OtpField } from "@reopt-ai/opt-ui"`
|
|
394
|
+
|
|
395
|
+
| Prop | Type | Required | Default | Description |
|
|
396
|
+
| -------------- | ----------------------------- | -------- | ------- | ------------------------------------------- |
|
|
397
|
+
| `length` | `number` | | | 셀 개수 (기본 6) |
|
|
398
|
+
| `value` | `string` | | | 제어 모드 값 |
|
|
399
|
+
| `defaultValue` | `string` | | | 비제어 초기값 |
|
|
400
|
+
| `onChange` | `(value: string) => void` | | | 값 변경 콜백 |
|
|
401
|
+
| `onComplete` | `(value: string) => void` | | | 모든 셀이 채워지면 1회 호출 |
|
|
402
|
+
| `type` | `"numeric" \| "alphanumeric"` | | | 허용 문자 (기본 numeric) |
|
|
403
|
+
| `mask` | `boolean` | | | 채워진 셀을 점(•)으로 마스킹 (PIN 용) |
|
|
404
|
+
| `disabled` | `boolean` | | | 비활성화 |
|
|
405
|
+
| `name` | `string` | | | 폼 필드명. 전체 값을 담은 hidden input 렌더 |
|
|
406
|
+
| `label` | `string` | | | 필드 레이블 |
|
|
407
|
+
| `error` | `string` | | | 에러 메시지 |
|
|
408
|
+
| `hint` | `string` | | | 도움말 텍스트 |
|
|
409
|
+
|
|
410
|
+
#### Toggle
|
|
411
|
+
|
|
412
|
+
**Import:** `import { Toggle } from "@reopt-ai/opt-ui"`
|
|
413
|
+
|
|
414
|
+
**Toggle:**
|
|
415
|
+
|
|
416
|
+
| Prop | Type | Required | Default | Description |
|
|
417
|
+
| ----------------- | ---------------------------- | -------- | ------- | ---------------------------------------- |
|
|
418
|
+
| `pressed` | `boolean` | | | 제어 모드: 눌림 상태 (단독 사용) |
|
|
419
|
+
| `defaultPressed` | `boolean` | | | 비제어 초기 눌림 상태 (단독 사용) |
|
|
420
|
+
| `onPressedChange` | `(pressed: boolean) => void` | | | 눌림 상태 변경 콜백 (단독 사용) |
|
|
421
|
+
| `value` | `string` | | | ToggleGroup 내에서 이 토글을 식별하는 값 |
|
|
422
|
+
| `size` | `"sm" \| "md"` | | | 크기 (기본 md) |
|
|
423
|
+
| `disabled` | `boolean` | | | 비활성화 |
|
|
424
|
+
| `children` | `ReactNode` | | | 토글 콘텐츠 |
|
|
425
|
+
|
|
426
|
+
**ToggleGroup:**
|
|
427
|
+
|
|
428
|
+
| Prop | Type | Required | Default | Description |
|
|
429
|
+
| ---------------- | ------------------------------------- | -------- | ------- | ------------------------------------------------- |
|
|
430
|
+
| `value` | `string \| string[]` | | | 선택 값. 단일은 string, toggleMultiple은 string[] |
|
|
431
|
+
| `defaultValue` | `string \| string[]` | | | 비제어 초기 선택 값 |
|
|
432
|
+
| `onValueChange` | `(value: string \| string[]) => void` | | | 선택 변경 콜백 |
|
|
433
|
+
| `toggleMultiple` | `boolean` | | | 동시에 여러 개 눌림 허용 |
|
|
434
|
+
| `orientation` | `"horizontal" \| "vertical"` | | | 배치 방향 (기본 horizontal) |
|
|
435
|
+
| `disabled` | `boolean` | | | 그룹 전체 비활성화 |
|
|
436
|
+
| `children` | `ReactNode` | | | Toggle 항목들 |
|
|
437
|
+
|
|
438
|
+
#### Accordion
|
|
439
|
+
|
|
440
|
+
**Import:** `import { AccordionRoot } from "@reopt-ai/opt-ui"`
|
|
441
|
+
|
|
442
|
+
**AccordionRoot:**
|
|
443
|
+
|
|
444
|
+
| Prop | Type | Required | Default | Description |
|
|
445
|
+
| --------------- | --------------------------------------------- | -------- | ------- | ------------------------------------------------------------- |
|
|
446
|
+
| `type` | `"single" \| "multiple"` | | | 한 개만 열림(single) 또는 여러 개 열림(multiple). 기본 single |
|
|
447
|
+
| `value` | `string \| string[] \| null` | | | 열린 항목 값. single은 string\|null, multiple은 string[] |
|
|
448
|
+
| `defaultValue` | `string \| string[] \| null` | | | 비제어 초기 열림 값 |
|
|
449
|
+
| `onValueChange` | `(value: string \| string[] \| null) => void` | | | 열림 변경 콜백 |
|
|
450
|
+
| `collapsible` | `boolean` | | | single 모드에서 열린 패널을 다시 닫을 수 있게 허용 |
|
|
451
|
+
| `disabled` | `boolean` | | | 전체 비활성화 |
|
|
452
|
+
| `animated` | `boolean` | | | 콘텐츠 enter/leave 애니메이션 (기본 true) |
|
|
453
|
+
| `children` | `ReactNode` | | | AccordionItem 목록 |
|
|
454
|
+
|
|
455
|
+
**AccordionItem:**
|
|
456
|
+
|
|
457
|
+
| Prop | Type | Required | Default | Description |
|
|
458
|
+
| ---------- | ----------- | -------- | ------- | ------------------ |
|
|
459
|
+
| `value` | `string` | Yes | | 항목 식별 값 |
|
|
460
|
+
| `disabled` | `boolean` | | | 이 항목만 비활성화 |
|
|
461
|
+
| `children` | `ReactNode` | | | Trigger + Content |
|
|
462
|
+
|
|
463
|
+
**AccordionTrigger:**
|
|
464
|
+
|
|
465
|
+
| Prop | Type | Required | Default | Description |
|
|
466
|
+
| ---------- | ----------- | -------- | ------- | ----------------------------------- |
|
|
467
|
+
| `children` | `ReactNode` | Yes | | 헤더 라벨 (쉐브론 아이콘 자동 추가) |
|
|
468
|
+
|
|
469
|
+
**AccordionContent:**
|
|
470
|
+
|
|
471
|
+
| Prop | Type | Required | Default | Description |
|
|
472
|
+
| ---------- | ----------- | -------- | ------- | ------------------ |
|
|
473
|
+
| `children` | `ReactNode` | Yes | | 펼쳐지는 패널 본문 |
|
|
474
|
+
|
|
475
|
+
#### StatCard
|
|
476
|
+
|
|
477
|
+
**Import:** `import { StatCard } from "@reopt-ai/opt-ui"`
|
|
478
|
+
|
|
479
|
+
| Prop | Type | Required | Default | Description |
|
|
480
|
+
| -------- | ----------------------------- | -------- | ------- | ------------------------------- |
|
|
481
|
+
| `title` | `string` | Yes | | 통계 제목 |
|
|
482
|
+
| `value` | `string` | Yes | | 통계 값 |
|
|
483
|
+
| `change` | `string` | Yes | | 변화량 텍스트 (예: '+12.5%') |
|
|
484
|
+
| `trend` | `"up" \| "down" \| "neutral"` | Yes | | 트렌드 방향. 색상과 아이콘 결정 |
|
|
485
|
+
|
|
486
|
+
#### CompositeZone
|
|
487
|
+
|
|
488
|
+
**Import:** `import { CompositeZone } from "@reopt-ai/opt-ui"`
|
|
489
|
+
|
|
490
|
+
| Prop | Type | Required | Default | Description |
|
|
491
|
+
| ----------- | ----------- | -------- | ------- | --------------------------------- |
|
|
492
|
+
| `children` | `ReactNode` | Yes | | CompositeRow + CompositeItem 자식 |
|
|
493
|
+
| `label` | `string` | Yes | | aria-label 값 |
|
|
494
|
+
| `focusLoop` | `boolean` | | true | 포커스가 끝에서 처음으로 순환 |
|
|
495
|
+
| `focusWrap` | `boolean` | | true | 행 끝에서 다음 행으로 이동 |
|
|
496
|
+
| `className` | `string` | | | 컨테이너 CSS 클래스 |
|
|
497
|
+
|
|
498
|
+
#### Disclosure
|
|
499
|
+
|
|
500
|
+
**Import:** `import { DisclosureRoot } from "@reopt-ai/opt-ui"`
|
|
501
|
+
|
|
502
|
+
**DisclosureRoot:**
|
|
503
|
+
|
|
504
|
+
| Prop | Type | Required | Default | Description |
|
|
505
|
+
| ------------- | ------------------------- | -------- | ------- | --------------------------- |
|
|
506
|
+
| `open` | `boolean` | | | 제어 모드: 열림 상태 |
|
|
507
|
+
| `setOpen` | `(open: boolean) => void` | | | 제어 모드: 상태 변경 핸들러 |
|
|
508
|
+
| `defaultOpen` | `boolean` | | false | 비제어 모드: 초기 열림 상태 |
|
|
509
|
+
|
|
510
|
+
**DisclosureTrigger:**
|
|
511
|
+
|
|
512
|
+
| Prop | Type | Required | Default | Description |
|
|
513
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
514
|
+
| `children` | `ReactNode` | Yes | | 트리거 내용 |
|
|
515
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
516
|
+
|
|
517
|
+
**DisclosureContent:**
|
|
518
|
+
|
|
519
|
+
| Prop | Type | Required | Default | Description |
|
|
520
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
521
|
+
| `children` | `ReactNode` | Yes | | 접히는 콘텐츠 |
|
|
522
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
523
|
+
|
|
524
|
+
#### Tabs
|
|
525
|
+
|
|
526
|
+
**Import:** `import { TabsRoot } from "@reopt-ai/opt-ui"`
|
|
527
|
+
|
|
528
|
+
**TabsRoot:**
|
|
529
|
+
|
|
530
|
+
| Prop | Type | Required | Default | Description |
|
|
531
|
+
| ------------------- | ------------------------------ | -------- | ------- | ------------------------- |
|
|
532
|
+
| `defaultSelectedId` | `string` | | | 초기 선택된 탭 ID |
|
|
533
|
+
| `selectedId` | `string \| null` | | | 제어 모드: 선택된 탭 ID |
|
|
534
|
+
| `setSelectedId` | `(id: string \| null) => void` | | | 제어 모드: 탭 변경 핸들러 |
|
|
535
|
+
|
|
536
|
+
**TabList:**
|
|
537
|
+
|
|
538
|
+
| Prop | Type | Required | Default | Description |
|
|
539
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
540
|
+
| `children` | `ReactNode` | Yes | | Tab 요소들 |
|
|
541
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
542
|
+
|
|
543
|
+
**Tab:**
|
|
544
|
+
|
|
545
|
+
| Prop | Type | Required | Default | Description |
|
|
546
|
+
| ----------- | ----------- | -------- | ------- | ------------------------------------ |
|
|
547
|
+
| `id` | `string` | Yes | | 탭 고유 ID (TabPanel의 tabId와 매칭) |
|
|
548
|
+
| `children` | `ReactNode` | Yes | | 탭 레이블 |
|
|
549
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
550
|
+
|
|
551
|
+
**TabPanel:**
|
|
552
|
+
|
|
553
|
+
| Prop | Type | Required | Default | Description |
|
|
554
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
555
|
+
| `tabId` | `string` | Yes | | 연결된 Tab의 ID |
|
|
556
|
+
| `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
|
|
557
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
558
|
+
|
|
559
|
+
#### Select
|
|
560
|
+
|
|
561
|
+
**Import:** `import { SelectRoot } from "@reopt-ai/opt-ui"`
|
|
562
|
+
|
|
563
|
+
**SelectRoot:**
|
|
564
|
+
|
|
565
|
+
| Prop | Type | Required | Default | Description |
|
|
566
|
+
| --------------- | ------------------------------------- | -------- | ------- | -------------------------------------------------------- |
|
|
567
|
+
| `value` | `string \| string[]` | | | 제어 모드: 현재 선택 값 (multiple이면 string[]) |
|
|
568
|
+
| `onValueChange` | `(value: string \| string[]) => void` | | | 제어 모드: 값 변경 핸들러 |
|
|
569
|
+
| `defaultValue` | `string \| string[]` | | | 비제어 모드: 초기값 |
|
|
570
|
+
| `multiple` | `boolean` | | | 다중 선택 허용 (값이 string[]이 됨) |
|
|
571
|
+
| `name` | `string` | | | 폼 필드명. 선택값마다 hidden input을 렌더해 폼 전송 지원 |
|
|
572
|
+
|
|
573
|
+
**SelectLabel:**
|
|
574
|
+
|
|
575
|
+
| Prop | Type | Required | Default | Description |
|
|
576
|
+
| ---------- | ----------- | -------- | ------- | ------------- |
|
|
577
|
+
| `children` | `ReactNode` | Yes | | 레이블 텍스트 |
|
|
578
|
+
|
|
579
|
+
**SelectTrigger:**
|
|
580
|
+
|
|
581
|
+
| Prop | Type | Required | Default | Description |
|
|
582
|
+
| ----------- | ----------- | -------- | ------- | ---------------------------- |
|
|
583
|
+
| `children` | `ReactNode` | Yes | | 트리거 내용 (선택된 값 표시) |
|
|
584
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
585
|
+
|
|
586
|
+
**SelectPopover:**
|
|
587
|
+
|
|
588
|
+
| Prop | Type | Required | Default | Description |
|
|
589
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
590
|
+
| `children` | `ReactNode` | Yes | | SelectItem 목록 |
|
|
591
|
+
| `sameWidth` | `boolean` | | true | 트리거와 같은 너비 |
|
|
592
|
+
| `gutter` | `number` | | 4 | 트리거와의 간격 (px) |
|
|
593
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
594
|
+
|
|
595
|
+
**SelectItem:**
|
|
596
|
+
|
|
597
|
+
| Prop | Type | Required | Default | Description |
|
|
598
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
599
|
+
| `value` | `string` | Yes | | 옵션 값 |
|
|
600
|
+
| `children` | `ReactNode` | Yes | | 옵션 레이블 |
|
|
601
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
602
|
+
|
|
603
|
+
**Examples:**
|
|
604
|
+
|
|
605
|
+
_기본 선택:_
|
|
606
|
+
|
|
607
|
+
```tsx
|
|
608
|
+
import {
|
|
609
|
+
SelectRoot,
|
|
610
|
+
SelectLabel,
|
|
611
|
+
SelectTrigger,
|
|
612
|
+
SelectPopover,
|
|
613
|
+
SelectItem,
|
|
614
|
+
} from "@reopt-ai/opt-ui";
|
|
615
|
+
|
|
616
|
+
<SelectRoot value={role} onValueChange={setRole}>
|
|
617
|
+
<SelectLabel>역할</SelectLabel>
|
|
618
|
+
<SelectTrigger>{role || "선택하세요"}</SelectTrigger>
|
|
619
|
+
<SelectPopover>
|
|
620
|
+
<SelectItem value="admin">관리자</SelectItem>
|
|
621
|
+
<SelectItem value="editor">편집자</SelectItem>
|
|
622
|
+
<SelectItem value="viewer">뷰어</SelectItem>
|
|
623
|
+
</SelectPopover>
|
|
624
|
+
</SelectRoot>;
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
#### Dialog
|
|
628
|
+
|
|
629
|
+
**Import:** `import { DialogRoot } from "@reopt-ai/opt-ui"`
|
|
630
|
+
|
|
631
|
+
**DialogRoot:**
|
|
632
|
+
|
|
633
|
+
| Prop | Type | Required | Default | Description |
|
|
634
|
+
| --------- | ------------------------- | -------- | ------- | --------------------------- |
|
|
635
|
+
| `open` | `boolean` | | | 제어 모드: 열림 상태 |
|
|
636
|
+
| `setOpen` | `(open: boolean) => void` | | | 제어 모드: 상태 변경 핸들러 |
|
|
637
|
+
|
|
638
|
+
**DialogDisclosure:**
|
|
639
|
+
|
|
640
|
+
| Prop | Type | Required | Default | Description |
|
|
641
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
642
|
+
| `children` | `ReactNode` | Yes | | 트리거 버튼 내용 |
|
|
643
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
644
|
+
|
|
645
|
+
**DialogPanel:**
|
|
646
|
+
|
|
647
|
+
| Prop | Type | Required | Default | Description |
|
|
648
|
+
| ----------- | ------------------------------------------------ | -------- | ------------------- | ---------------------- |
|
|
649
|
+
| `children` | `ReactNode` | Yes | | 다이얼로그 콘텐츠 |
|
|
650
|
+
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl" \| "full"` | | "md" | 최대 너비 프리셋 |
|
|
651
|
+
| `backdrop` | `ReactElement` | | <div> (반투명 배경) | 배경 오버레이 요소 |
|
|
652
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
653
|
+
|
|
654
|
+
**DialogHeading:**
|
|
655
|
+
|
|
656
|
+
| Prop | Type | Required | Default | Description |
|
|
657
|
+
| ---------- | ----------- | -------- | ------- | --------------------------------------- |
|
|
658
|
+
| `children` | `ReactNode` | Yes | | 제목 텍스트 (자동 aria-labelledby 연결) |
|
|
659
|
+
|
|
660
|
+
**DialogDescription:**
|
|
661
|
+
|
|
662
|
+
| Prop | Type | Required | Default | Description |
|
|
663
|
+
| ---------- | ----------- | -------- | ------- | ---------------------------------------- |
|
|
664
|
+
| `children` | `ReactNode` | Yes | | 설명 텍스트 (자동 aria-describedby 연결) |
|
|
665
|
+
|
|
666
|
+
**DialogDismiss:**
|
|
667
|
+
|
|
668
|
+
| Prop | Type | Required | Default | Description |
|
|
669
|
+
| ---------- | ----------- | -------- | ------- | -------------- |
|
|
670
|
+
| `children` | `ReactNode` | | | 닫기 버튼 내용 |
|
|
671
|
+
|
|
672
|
+
**DialogHeader:**
|
|
673
|
+
|
|
674
|
+
| Prop | Type | Required | Default | Description |
|
|
675
|
+
| ---------- | ----------- | -------- | ------- | -------------------------------------------- |
|
|
676
|
+
| `children` | `ReactNode` | Yes | | Heading, Description, Dismiss 등 헤더 콘텐츠 |
|
|
677
|
+
|
|
678
|
+
**DialogBody:**
|
|
679
|
+
|
|
680
|
+
| Prop | Type | Required | Default | Description |
|
|
681
|
+
| ---------- | ----------- | -------- | ------- | ------------------------- |
|
|
682
|
+
| `children` | `ReactNode` | Yes | | 스크롤 가능한 본문 콘텐츠 |
|
|
683
|
+
|
|
684
|
+
**DialogFooter:**
|
|
685
|
+
|
|
686
|
+
| Prop | Type | Required | Default | Description |
|
|
687
|
+
| ---------- | ----------- | -------- | ------- | -------------- |
|
|
688
|
+
| `children` | `ReactNode` | Yes | | 액션 버튼 영역 |
|
|
689
|
+
|
|
690
|
+
**Examples:**
|
|
691
|
+
|
|
692
|
+
_모달 대화상자:_
|
|
693
|
+
|
|
694
|
+
```tsx
|
|
695
|
+
import {
|
|
696
|
+
DialogRoot,
|
|
697
|
+
DialogDisclosure,
|
|
698
|
+
DialogPanel,
|
|
699
|
+
DialogHeading,
|
|
700
|
+
DialogDismiss,
|
|
701
|
+
} from "@reopt-ai/opt-ui";
|
|
702
|
+
|
|
703
|
+
<DialogRoot>
|
|
704
|
+
<DialogDisclosure>열기</DialogDisclosure>
|
|
705
|
+
<DialogPanel size="md">
|
|
706
|
+
<DialogHeading>확인</DialogHeading>
|
|
707
|
+
<p>변경 사항을 저장하시겠습니까?</p>
|
|
708
|
+
<DialogDismiss>닫기</DialogDismiss>
|
|
709
|
+
</DialogPanel>
|
|
710
|
+
</DialogRoot>;
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
#### Combobox
|
|
714
|
+
|
|
715
|
+
**Import:** `import { ComboboxRoot } from "@reopt-ai/opt-ui"`
|
|
716
|
+
|
|
717
|
+
**ComboboxRoot:**
|
|
718
|
+
|
|
719
|
+
| Prop | Type | Required | Default | Description |
|
|
720
|
+
| ------------------ | ------------------------- | -------- | ------- | -------------------------- |
|
|
721
|
+
| `setValue` | `(value: string) => void` | | | 입력값 변경 핸들러 |
|
|
722
|
+
| `resetValueOnHide` | `boolean` | | false | 팝오버 닫힐 때 입력값 리셋 |
|
|
723
|
+
|
|
724
|
+
**ComboboxInput:**
|
|
725
|
+
|
|
726
|
+
| Prop | Type | Required | Default | Description |
|
|
727
|
+
| ------------- | --------- | -------- | ------- | ---------------------- |
|
|
728
|
+
| `placeholder` | `string` | | | 플레이스홀더 텍스트 |
|
|
729
|
+
| `autoSelect` | `boolean` | | false | 첫 항목 자동 선택 |
|
|
730
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
731
|
+
|
|
732
|
+
**ComboboxPopover:**
|
|
733
|
+
|
|
734
|
+
| Prop | Type | Required | Default | Description |
|
|
735
|
+
| ----------- | ----------- | -------- | ------- | ----------------------- |
|
|
736
|
+
| `children` | `ReactNode` | Yes | | ComboboxItem/Group 목록 |
|
|
737
|
+
| `sameWidth` | `boolean` | | true | 입력과 같은 너비 |
|
|
738
|
+
| `gutter` | `number` | | 4 | 입력과의 간격 (px) |
|
|
739
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
740
|
+
|
|
741
|
+
**ComboboxItem:**
|
|
742
|
+
|
|
743
|
+
| Prop | Type | Required | Default | Description |
|
|
744
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
745
|
+
| `value` | `string` | Yes | | 항목 값 |
|
|
746
|
+
| `children` | `ReactNode` | Yes | | 항목 내용 |
|
|
747
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
748
|
+
|
|
749
|
+
**ComboboxGroup:**
|
|
750
|
+
|
|
751
|
+
| Prop | Type | Required | Default | Description |
|
|
752
|
+
| ---------- | ----------- | -------- | ------- | ---------------------- |
|
|
753
|
+
| `children` | `ReactNode` | Yes | | GroupLabel + Item 그룹 |
|
|
754
|
+
|
|
755
|
+
**ComboboxGroupLabel:**
|
|
756
|
+
|
|
757
|
+
| Prop | Type | Required | Default | Description |
|
|
758
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
759
|
+
| `children` | `ReactNode` | Yes | | 그룹 레이블 |
|
|
760
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
761
|
+
|
|
762
|
+
**ComboboxEmpty:**
|
|
763
|
+
|
|
764
|
+
| Prop | Type | Required | Default | Description |
|
|
765
|
+
| ----------- | ----------- | -------- | ------------------ | ---------------------- |
|
|
766
|
+
| `children` | `ReactNode` | | "결과가 없습니다." | 빈 상태 메시지 |
|
|
767
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
768
|
+
|
|
769
|
+
#### Menu
|
|
770
|
+
|
|
771
|
+
**Import:** `import { MenubarRoot } from "@reopt-ai/opt-ui"`
|
|
772
|
+
|
|
773
|
+
**MenubarRoot:**
|
|
774
|
+
|
|
775
|
+
| Prop | Type | Required | Default | Description |
|
|
776
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
777
|
+
|
|
778
|
+
**MenubarContainer:**
|
|
779
|
+
|
|
780
|
+
| Prop | Type | Required | Default | Description |
|
|
781
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
782
|
+
| `children` | `ReactNode` | Yes | | MenuRoot 요소들 |
|
|
783
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
784
|
+
|
|
785
|
+
**MenuRoot:**
|
|
786
|
+
|
|
787
|
+
| Prop | Type | Required | Default | Description |
|
|
788
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
789
|
+
|
|
790
|
+
**MenuTrigger:**
|
|
791
|
+
|
|
792
|
+
| Prop | Type | Required | Default | Description |
|
|
793
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
794
|
+
| `children` | `ReactNode` | Yes | | 메뉴 버튼 레이블 |
|
|
795
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
796
|
+
|
|
797
|
+
**MenuButtonArrow:**
|
|
798
|
+
|
|
799
|
+
| Prop | Type | Required | Default | Description |
|
|
800
|
+
| ----------- | -------- | -------- | ------- | ----------------- |
|
|
801
|
+
| `className` | `string` | | | 화살표 CSS 클래스 |
|
|
802
|
+
|
|
803
|
+
**MenuPopover:**
|
|
804
|
+
|
|
805
|
+
| Prop | Type | Required | Default | Description |
|
|
806
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
807
|
+
| `children` | `ReactNode` | Yes | | MenuItem 목록 |
|
|
808
|
+
| `gutter` | `number` | | 8 | 트리거와의 간격 (px) |
|
|
809
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
810
|
+
|
|
811
|
+
**MenuItem:**
|
|
812
|
+
|
|
813
|
+
| Prop | Type | Required | Default | Description |
|
|
814
|
+
| ----------- | ------------ | -------- | ------- | ---------------------- |
|
|
815
|
+
| `children` | `ReactNode` | Yes | | 메뉴 항목 내용 |
|
|
816
|
+
| `onClick` | `() => void` | | | 클릭 핸들러 |
|
|
817
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
818
|
+
|
|
819
|
+
**MenuItemCheckbox:**
|
|
820
|
+
|
|
821
|
+
| Prop | Type | Required | Default | Description |
|
|
822
|
+
| ----------- | -------------------------- | -------- | ------- | ---------------------- |
|
|
823
|
+
| `name` | `string` | Yes | | 체크박스 이름 |
|
|
824
|
+
| `value` | `string` | Yes | | 체크박스 값 |
|
|
825
|
+
| `checked` | `boolean` | | | 체크 상태 |
|
|
826
|
+
| `onChange` | `(e: ChangeEvent) => void` | | | 변경 핸들러 |
|
|
827
|
+
| `children` | `ReactNode` | Yes | | 항목 내용 |
|
|
828
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
829
|
+
|
|
830
|
+
**MenuItemRadio:**
|
|
831
|
+
|
|
832
|
+
| Prop | Type | Required | Default | Description |
|
|
833
|
+
| ----------- | -------------------------- | -------- | ------- | ---------------------- |
|
|
834
|
+
| `name` | `string` | Yes | | 라디오 그룹 이름 |
|
|
835
|
+
| `value` | `string` | Yes | | 라디오 값 |
|
|
836
|
+
| `checked` | `boolean` | | | 선택 상태 |
|
|
837
|
+
| `onChange` | `(e: ChangeEvent) => void` | | | 변경 핸들러 |
|
|
838
|
+
| `children` | `ReactNode` | Yes | | 항목 내용 |
|
|
839
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
840
|
+
|
|
841
|
+
**MenuSeparator:**
|
|
842
|
+
|
|
843
|
+
| Prop | Type | Required | Default | Description |
|
|
844
|
+
| ----------- | -------- | -------- | ------- | ---------------------- |
|
|
845
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
846
|
+
|
|
847
|
+
#### Toolbar
|
|
848
|
+
|
|
849
|
+
**Import:** `import { ToolbarRoot } from "@reopt-ai/opt-ui"`
|
|
850
|
+
|
|
851
|
+
**ToolbarRoot:**
|
|
852
|
+
|
|
853
|
+
| Prop | Type | Required | Default | Description |
|
|
854
|
+
| ----------- | --------- | -------- | ------- | ---------------- |
|
|
855
|
+
| `focusLoop` | `boolean` | | false | 포커스 순환 여부 |
|
|
856
|
+
|
|
857
|
+
**ToolbarContainer:**
|
|
858
|
+
|
|
859
|
+
| Prop | Type | Required | Default | Description |
|
|
860
|
+
| ----------- | ----------- | -------- | ------- | ------------------------------ |
|
|
861
|
+
| `children` | `ReactNode` | Yes | | ToolbarButton/Separator 요소들 |
|
|
862
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
863
|
+
|
|
864
|
+
**ToolbarButton:**
|
|
865
|
+
|
|
866
|
+
| Prop | Type | Required | Default | Description |
|
|
867
|
+
| ----------- | ------------ | -------- | ------- | ---------------------- |
|
|
868
|
+
| `children` | `ReactNode` | Yes | | 버튼 내용 |
|
|
869
|
+
| `onClick` | `() => void` | | | 클릭 핸들러 |
|
|
870
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
871
|
+
|
|
872
|
+
**ToolbarSeparator:**
|
|
873
|
+
|
|
874
|
+
| Prop | Type | Required | Default | Description |
|
|
875
|
+
| ----------- | -------- | -------- | ------- | ---------------------- |
|
|
876
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
877
|
+
|
|
878
|
+
**TooltipProvider:**
|
|
879
|
+
|
|
880
|
+
| Prop | Type | Required | Default | Description |
|
|
881
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
882
|
+
|
|
883
|
+
**TooltipAnchor:**
|
|
884
|
+
|
|
885
|
+
| Prop | Type | Required | Default | Description |
|
|
886
|
+
| ---------- | -------------- | -------- | ------- | ------------------ |
|
|
887
|
+
| `render` | `ReactElement` | | | 앵커로 사용할 요소 |
|
|
888
|
+
| `children` | `ReactNode` | | | 앵커 내용 |
|
|
889
|
+
|
|
890
|
+
**Tooltip:**
|
|
891
|
+
|
|
892
|
+
| Prop | Type | Required | Default | Description |
|
|
893
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
894
|
+
| `children` | `ReactNode` | Yes | | 툴팁 내용 |
|
|
895
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
896
|
+
|
|
897
|
+
#### Form
|
|
898
|
+
|
|
899
|
+
**Import:** `import { FormRoot } from "@reopt-ai/opt-ui"`
|
|
900
|
+
|
|
901
|
+
**FormRoot:**
|
|
902
|
+
|
|
903
|
+
| Prop | Type | Required | Default | Description |
|
|
904
|
+
| ----------- | ----------- | -------- | ------- | ------------------------------------------------------------------------ |
|
|
905
|
+
| `store` | `FormStore` | | | useFormStore()로 생성한 폼 스토어. 미지정 시 자식의 FormProvider가 제공. |
|
|
906
|
+
| `children` | `ReactNode` | Yes | | 폼 필드들 |
|
|
907
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
908
|
+
|
|
909
|
+
**FormInput:**
|
|
910
|
+
|
|
911
|
+
| Prop | Type | Required | Default | Description |
|
|
912
|
+
| ------------- | -------- | -------- | ------- | ------------------------------- |
|
|
913
|
+
| `name` | `string` | Yes | | 폼 필드 이름 (스토어 키와 매칭) |
|
|
914
|
+
| `type` | `string` | | "text" | 입력 타입 |
|
|
915
|
+
| `placeholder` | `string` | | | 플레이스홀더 |
|
|
916
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
917
|
+
|
|
918
|
+
**FormTextarea:**
|
|
919
|
+
|
|
920
|
+
| Prop | Type | Required | Default | Description |
|
|
921
|
+
| ------------- | ------------------------------------------------ | -------- | ---------- | --------------- |
|
|
922
|
+
| `name` | `string` | Yes | | 폼 필드 이름 |
|
|
923
|
+
| `rows` | `number` | | 4 | 표시 줄 수 |
|
|
924
|
+
| `resize` | `"none" \| "vertical" \| "horizontal" \| "both"` | | "vertical" | 크기 조절 방향 |
|
|
925
|
+
| `placeholder` | `string` | | | 플레이스홀더 |
|
|
926
|
+
| `className` | `string` | | | 추가 CSS 클래스 |
|
|
927
|
+
|
|
928
|
+
**FormSelect:**
|
|
929
|
+
|
|
930
|
+
| Prop | Type | Required | Default | Description |
|
|
931
|
+
| ------------- | ----------- | -------- | ------- | ------------------------------ |
|
|
932
|
+
| `name` | `string` | Yes | | 폼 필드 이름 |
|
|
933
|
+
| `children` | `ReactNode` | Yes | | FormSelectPopover 등 자식 요소 |
|
|
934
|
+
| `placeholder` | `string` | | | 미선택 시 표시 텍스트 |
|
|
935
|
+
| `className` | `string` | | | 추가 CSS 클래스 |
|
|
936
|
+
|
|
937
|
+
**FormSelectPopover:**
|
|
938
|
+
|
|
939
|
+
| Prop | Type | Required | Default | Description |
|
|
940
|
+
| ----------- | ----------- | -------- | ------- | -------------------- |
|
|
941
|
+
| `children` | `ReactNode` | Yes | | FormSelectItem 목록 |
|
|
942
|
+
| `sameWidth` | `boolean` | | true | 트리거와 같은 너비 |
|
|
943
|
+
| `gutter` | `number` | | 4 | 트리거와의 간격 (px) |
|
|
944
|
+
|
|
945
|
+
**FormSelectItem:**
|
|
946
|
+
|
|
947
|
+
| Prop | Type | Required | Default | Description |
|
|
948
|
+
| ---------- | ----------- | -------- | ------- | ----------- |
|
|
949
|
+
| `value` | `string` | Yes | | 옵션 값 |
|
|
950
|
+
| `children` | `ReactNode` | Yes | | 옵션 레이블 |
|
|
951
|
+
|
|
952
|
+
**FormSwitch:**
|
|
953
|
+
|
|
954
|
+
| Prop | Type | Required | Default | Description |
|
|
955
|
+
| ---------- | ---------------------- | -------- | ------- | ------------- |
|
|
956
|
+
| `name` | `string` | Yes | | 폼 필드 이름 |
|
|
957
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 스위치 크기 |
|
|
958
|
+
| `disabled` | `boolean` | | | 비활성화 상태 |
|
|
959
|
+
|
|
960
|
+
**FormLabel:**
|
|
961
|
+
|
|
962
|
+
| Prop | Type | Required | Default | Description |
|
|
963
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
964
|
+
| `name` | `string` | Yes | | 연결된 필드 이름 |
|
|
965
|
+
| `children` | `ReactNode` | Yes | | 레이블 텍스트 |
|
|
966
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
967
|
+
|
|
968
|
+
**FormError:**
|
|
969
|
+
|
|
970
|
+
| Prop | Type | Required | Default | Description |
|
|
971
|
+
| ----------- | -------- | -------- | ------- | ---------------------- |
|
|
972
|
+
| `name` | `string` | Yes | | 연결된 필드 이름 |
|
|
973
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
974
|
+
|
|
975
|
+
**FormSubmit:**
|
|
976
|
+
|
|
977
|
+
| Prop | Type | Required | Default | Description |
|
|
978
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
979
|
+
| `children` | `ReactNode` | Yes | | 버튼 텍스트 |
|
|
980
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
981
|
+
|
|
982
|
+
**FormProvider:**
|
|
983
|
+
|
|
984
|
+
| Prop | Type | Required | Default | Description |
|
|
985
|
+
| ---------- | ----------- | -------- | ------- | --------------------------------- |
|
|
986
|
+
| `store` | `FormStore` | Yes | | useFormStore()로 생성한 폼 스토어 |
|
|
987
|
+
| `children` | `ReactNode` | Yes | | 자식 폼 요소 |
|
|
988
|
+
|
|
989
|
+
**FormGroup:**
|
|
990
|
+
|
|
991
|
+
| Prop | Type | Required | Default | Description |
|
|
992
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
993
|
+
| `children` | `ReactNode` | Yes | | 그룹 내 필드들 |
|
|
994
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
995
|
+
|
|
996
|
+
**FormGroupLabel:**
|
|
997
|
+
|
|
998
|
+
| Prop | Type | Required | Default | Description |
|
|
999
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
1000
|
+
| `children` | `ReactNode` | Yes | | 그룹 레이블 텍스트 |
|
|
1001
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1002
|
+
|
|
1003
|
+
**FormDescription:**
|
|
1004
|
+
|
|
1005
|
+
| Prop | Type | Required | Default | Description |
|
|
1006
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
1007
|
+
| `name` | `string` | Yes | | 연결된 필드 이름 |
|
|
1008
|
+
| `children` | `ReactNode` | Yes | | 도움말 텍스트 |
|
|
1009
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1010
|
+
|
|
1011
|
+
**FormField:**
|
|
1012
|
+
|
|
1013
|
+
| Prop | Type | Required | Default | Description |
|
|
1014
|
+
| ----------- | ----------- | -------- | ------- | ------------------------ |
|
|
1015
|
+
| `name` | `string` | Yes | | 필드 이름 |
|
|
1016
|
+
| `children` | `ReactNode` | Yes | | label + input + error 등 |
|
|
1017
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1018
|
+
|
|
1019
|
+
**FormControl:**
|
|
1020
|
+
|
|
1021
|
+
| Prop | Type | Required | Default | Description |
|
|
1022
|
+
| ----------- | -------- | -------- | ------- | ---------------------- |
|
|
1023
|
+
| `name` | `string` | Yes | | 연결된 필드 이름 |
|
|
1024
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1025
|
+
|
|
1026
|
+
**FormCheckbox:**
|
|
1027
|
+
|
|
1028
|
+
| Prop | Type | Required | Default | Description |
|
|
1029
|
+
| ----------- | -------- | -------- | ------- | ------------------------ |
|
|
1030
|
+
| `name` | `string` | Yes | | 폼 필드 이름 (스토어 키) |
|
|
1031
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1032
|
+
|
|
1033
|
+
**FormRadioGroup:**
|
|
1034
|
+
|
|
1035
|
+
| Prop | Type | Required | Default | Description |
|
|
1036
|
+
| ----------- | ----------- | -------- | ------- | ------------------------ |
|
|
1037
|
+
| `name` | `string` | Yes | | 폼 필드 이름 (스토어 키) |
|
|
1038
|
+
| `children` | `ReactNode` | Yes | | FormRadio 목록 |
|
|
1039
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1040
|
+
|
|
1041
|
+
**FormRadio:**
|
|
1042
|
+
|
|
1043
|
+
| Prop | Type | Required | Default | Description |
|
|
1044
|
+
| ----------- | -------- | -------- | ------- | ------------------------ |
|
|
1045
|
+
| `name` | `string` | Yes | | 폼 필드 이름 (스토어 키) |
|
|
1046
|
+
| `value` | `string` | Yes | | 라디오 값 |
|
|
1047
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1048
|
+
|
|
1049
|
+
**FormPush:**
|
|
1050
|
+
|
|
1051
|
+
| Prop | Type | Required | Default | Description |
|
|
1052
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
1053
|
+
| `name` | `string` | Yes | | 배열 필드 이름 |
|
|
1054
|
+
| `value` | `unknown` | Yes | | 추가할 기본값 |
|
|
1055
|
+
| `children` | `ReactNode` | Yes | | 버튼 텍스트 |
|
|
1056
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1057
|
+
|
|
1058
|
+
**FormRemove:**
|
|
1059
|
+
|
|
1060
|
+
| Prop | Type | Required | Default | Description |
|
|
1061
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
1062
|
+
| `name` | `string` | Yes | | 배열 필드 이름 |
|
|
1063
|
+
| `index` | `number` | Yes | | 제거할 인덱스 |
|
|
1064
|
+
| `children` | `ReactNode` | Yes | | 버튼 텍스트 |
|
|
1065
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1066
|
+
|
|
1067
|
+
**FormReset:**
|
|
1068
|
+
|
|
1069
|
+
| Prop | Type | Required | Default | Description |
|
|
1070
|
+
| ----------- | ----------- | -------- | ------- | ---------------------- |
|
|
1071
|
+
| `children` | `ReactNode` | Yes | | 버튼 텍스트 |
|
|
1072
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1073
|
+
|
|
1074
|
+
**useFormContext:**
|
|
1075
|
+
|
|
1076
|
+
| Prop | Type | Required | Default | Description |
|
|
1077
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
1078
|
+
|
|
1079
|
+
**useFormStore:**
|
|
1080
|
+
|
|
1081
|
+
| Prop | Type | Required | Default | Description |
|
|
1082
|
+
| --------------- | ------------------------- | -------- | ------- | ----------- |
|
|
1083
|
+
| `defaultValues` | `Record<string, unknown>` | | | 초기 폼 값 |
|
|
1084
|
+
|
|
1085
|
+
**Examples:**
|
|
1086
|
+
|
|
1087
|
+
_기본 폼:_
|
|
1088
|
+
|
|
1089
|
+
```tsx
|
|
1090
|
+
import {
|
|
1091
|
+
useFormStore,
|
|
1092
|
+
FormRoot,
|
|
1093
|
+
FormField,
|
|
1094
|
+
FormControl,
|
|
1095
|
+
FormLabel,
|
|
1096
|
+
FormError,
|
|
1097
|
+
FormSubmit,
|
|
1098
|
+
Input,
|
|
1099
|
+
} from "@reopt-ai/opt-ui";
|
|
1100
|
+
|
|
1101
|
+
const store = useFormStore({ defaultValues: { name: "", email: "" } });
|
|
1102
|
+
|
|
1103
|
+
<FormRoot store={store}>
|
|
1104
|
+
<FormField name="name">
|
|
1105
|
+
<FormLabel name="name">이름</FormLabel>
|
|
1106
|
+
<FormControl name="name">
|
|
1107
|
+
<Input />
|
|
1108
|
+
</FormControl>
|
|
1109
|
+
<FormError name="name" />
|
|
1110
|
+
</FormField>
|
|
1111
|
+
<FormSubmit>저장</FormSubmit>
|
|
1112
|
+
</FormRoot>;
|
|
1113
|
+
```
|
|
1114
|
+
|
|
1115
|
+
_검증 + 비동기 제출:_
|
|
1116
|
+
|
|
1117
|
+
```tsx
|
|
1118
|
+
import {
|
|
1119
|
+
useFormStore,
|
|
1120
|
+
FormRoot,
|
|
1121
|
+
FormField,
|
|
1122
|
+
FormControl,
|
|
1123
|
+
FormLabel,
|
|
1124
|
+
FormError,
|
|
1125
|
+
FormSubmit,
|
|
1126
|
+
Input,
|
|
1127
|
+
} from "@reopt-ai/opt-ui";
|
|
1128
|
+
|
|
1129
|
+
const store = useFormStore({
|
|
1130
|
+
defaultValues: { email: "" },
|
|
1131
|
+
validate: (values) => {
|
|
1132
|
+
const errors: Record<string, string> = {};
|
|
1133
|
+
if (!values.email) errors.email = "이메일을 입력하세요";
|
|
1134
|
+
return errors;
|
|
1135
|
+
},
|
|
1136
|
+
onSubmit: async (values) => {
|
|
1137
|
+
await fetch("/api/submit", {
|
|
1138
|
+
method: "POST",
|
|
1139
|
+
body: JSON.stringify(values),
|
|
1140
|
+
});
|
|
1141
|
+
},
|
|
1142
|
+
});
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
_schemaValidator (Zod):_
|
|
1146
|
+
|
|
1147
|
+
```tsx
|
|
1148
|
+
import { useFormStore, schemaValidator } from "@reopt-ai/opt-ui";
|
|
1149
|
+
import { z } from "zod";
|
|
1150
|
+
|
|
1151
|
+
const schema = z.object({
|
|
1152
|
+
name: z.string().min(1, "필수 항목"),
|
|
1153
|
+
age: z.number().min(0, "0 이상"),
|
|
1154
|
+
});
|
|
1155
|
+
|
|
1156
|
+
const store = useFormStore({
|
|
1157
|
+
defaultValues: { name: "", age: 0 },
|
|
1158
|
+
validate: schemaValidator(schema),
|
|
1159
|
+
});
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
#### Button
|
|
1163
|
+
|
|
1164
|
+
**Import:** `import { Button } from "@reopt-ai/opt-ui"`
|
|
1165
|
+
|
|
1166
|
+
| Prop | Type | Required | Default | Description |
|
|
1167
|
+
| ----------- | ------------------------------------------------- | -------- | --------- | ----------------------------------------- |
|
|
1168
|
+
| `variant` | `"primary" \| "secondary" \| "ghost" \| "danger"` | | "primary" | 버튼 스타일 변형 |
|
|
1169
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 버튼 크기 |
|
|
1170
|
+
| `loading` | `boolean` | | false | 로딩 상태. true면 스피너 표시 및 비활성화 |
|
|
1171
|
+
| `leftIcon` | `ReactNode` | | | 버튼 텍스트 왼쪽에 표시할 아이콘 |
|
|
1172
|
+
| `rightIcon` | `ReactNode` | | | 버튼 텍스트 오른쪽에 표시할 아이콘 |
|
|
1173
|
+
| `disabled` | `boolean` | | | 비활성화 상태 |
|
|
1174
|
+
|
|
1175
|
+
**Examples:**
|
|
1176
|
+
|
|
1177
|
+
_버튼 변형:_
|
|
1178
|
+
|
|
1179
|
+
```tsx
|
|
1180
|
+
import { Button } from "@reopt-ai/opt-ui";
|
|
1181
|
+
|
|
1182
|
+
<Button variant="primary">Primary</Button>
|
|
1183
|
+
<Button variant="secondary">Secondary</Button>
|
|
1184
|
+
<Button variant="ghost">Ghost</Button>
|
|
1185
|
+
<Button variant="danger" disabled>Danger</Button>
|
|
1186
|
+
<Button variant="primary" loading>저장 중...</Button>
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
#### Badge
|
|
1190
|
+
|
|
1191
|
+
**Import:** `import { Badge } from "@reopt-ai/opt-ui"`
|
|
1192
|
+
|
|
1193
|
+
| Prop | Type | Required | Default | Description |
|
|
1194
|
+
| -------------- | ---------------------------------------------------------- | -------- | --------- | -------------------------------------------- |
|
|
1195
|
+
| `variant` | `"default" \| "success" \| "warning" \| "error" \| "info"` | | "default" | 뱃지 색상 변형 |
|
|
1196
|
+
| `size` | `"sm" \| "md"` | | "md" | 뱃지 크기 |
|
|
1197
|
+
| `dot` | `boolean` | | false | 상태 점 표시 여부 |
|
|
1198
|
+
| `progress` | `number` | | | 원형 프로그레스 값 (0-100). 설정 시 dot 무시 |
|
|
1199
|
+
| `progressSize` | `number` | | 16 | 프로그레스 링 SVG 크기 (px) |
|
|
1200
|
+
|
|
1201
|
+
#### Spinner
|
|
1202
|
+
|
|
1203
|
+
**Import:** `import { Spinner } from "@reopt-ai/opt-ui"`
|
|
1204
|
+
|
|
1205
|
+
| Prop | Type | Required | Default | Description |
|
|
1206
|
+
| ------ | ---------------------- | -------- | ------- | ----------- |
|
|
1207
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 스피너 크기 |
|
|
1208
|
+
|
|
1209
|
+
#### Alert
|
|
1210
|
+
|
|
1211
|
+
**Import:** `import { Alert } from "@reopt-ai/opt-ui"`
|
|
1212
|
+
|
|
1213
|
+
| Prop | Type | Required | Default | Description |
|
|
1214
|
+
| ------------- | --------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
|
|
1215
|
+
| `variant` | `"info" \| "success" \| "warning" \| "error"` | | "info" | 알림 변형 (색상 및 아이콘 결정) |
|
|
1216
|
+
| `title` | `string` | | | 알림 제목 |
|
|
1217
|
+
| `icon` | `ReactNode` | | | 커스텀 아이콘. 미지정 시 변형에 따른 기본 아이콘 사용 |
|
|
1218
|
+
| `dismissible` | `boolean` | | false | 닫기 버튼 표시 여부 |
|
|
1219
|
+
| `onDismiss` | `() => void` | | | 닫기 버튼 클릭 핸들러 |
|
|
1220
|
+
|
|
1221
|
+
#### Input
|
|
1222
|
+
|
|
1223
|
+
**Import:** `import { Input } from "@reopt-ai/opt-ui"`
|
|
1224
|
+
|
|
1225
|
+
| Prop | Type | Required | Default | Description |
|
|
1226
|
+
| ----------- | ----------- | -------- | ------- | ------------------------------------------- |
|
|
1227
|
+
| `label` | `string` | | | 입력 필드 레이블 |
|
|
1228
|
+
| `error` | `string` | | | 에러 메시지. 표시 시 aria-invalid=true 설정 |
|
|
1229
|
+
| `hint` | `string` | | | 힌트 텍스트 (에러 없을 때만 표시) |
|
|
1230
|
+
| `leftIcon` | `ReactNode` | | | 입력 필드 왼쪽에 표시할 아이콘 |
|
|
1231
|
+
| `rightIcon` | `ReactNode` | | | 입력 필드 오른쪽에 표시할 아이콘 |
|
|
1232
|
+
| `fullWidth` | `boolean` | | false | 전체 너비 사용 여부 |
|
|
1233
|
+
|
|
1234
|
+
**Examples:**
|
|
1235
|
+
|
|
1236
|
+
_기본 사용:_
|
|
1237
|
+
|
|
1238
|
+
```tsx
|
|
1239
|
+
import { Input } from "@reopt-ai/opt-ui";
|
|
1240
|
+
|
|
1241
|
+
<Input
|
|
1242
|
+
label="이메일"
|
|
1243
|
+
hint="업무용 이메일을 입력하세요"
|
|
1244
|
+
placeholder="user@example.com"
|
|
1245
|
+
value={email}
|
|
1246
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
1247
|
+
/>;
|
|
1248
|
+
```
|
|
1249
|
+
|
|
1250
|
+
_FormStore 연동:_
|
|
1251
|
+
|
|
1252
|
+
```tsx
|
|
1253
|
+
import {
|
|
1254
|
+
useFormStore,
|
|
1255
|
+
FormRoot,
|
|
1256
|
+
FormField,
|
|
1257
|
+
FormControl,
|
|
1258
|
+
FormLabel,
|
|
1259
|
+
Input,
|
|
1260
|
+
} from "@reopt-ai/opt-ui";
|
|
1261
|
+
|
|
1262
|
+
const store = useFormStore({ defaultValues: { name: "" } });
|
|
1263
|
+
|
|
1264
|
+
<FormRoot store={store}>
|
|
1265
|
+
<FormField name="name">
|
|
1266
|
+
<FormLabel name="name">이름</FormLabel>
|
|
1267
|
+
<FormControl name="name">
|
|
1268
|
+
<Input />
|
|
1269
|
+
</FormControl>
|
|
1270
|
+
</FormField>
|
|
1271
|
+
</FormRoot>;
|
|
1272
|
+
```
|
|
1273
|
+
|
|
1274
|
+
#### Switch
|
|
1275
|
+
|
|
1276
|
+
**Import:** `import { Switch } from "@reopt-ai/opt-ui"`
|
|
1277
|
+
|
|
1278
|
+
| Prop | Type | Required | Default | Description |
|
|
1279
|
+
| ---------------- | ---------------------------- | -------- | ------- | --------------------------- |
|
|
1280
|
+
| `label` | `string` | | | 스위치 레이블 |
|
|
1281
|
+
| `description` | `string` | | | 레이블 아래 설명 텍스트 |
|
|
1282
|
+
| `checked` | `boolean` | | | 제어 모드: 체크 상태 |
|
|
1283
|
+
| `defaultChecked` | `boolean` | | | 비제어 모드: 초기 체크 상태 |
|
|
1284
|
+
| `onChange` | `(checked: boolean) => void` | | | 상태 변경 핸들러 |
|
|
1285
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 스위치 크기 |
|
|
1286
|
+
| `disabled` | `boolean` | | | 비활성화 상태 |
|
|
1287
|
+
|
|
1288
|
+
#### Skeleton
|
|
1289
|
+
|
|
1290
|
+
**Import:** `import { Skeleton } from "@reopt-ai/opt-ui"`
|
|
1291
|
+
|
|
1292
|
+
**Skeleton:**
|
|
1293
|
+
|
|
1294
|
+
| Prop | Type | Required | Default | Description |
|
|
1295
|
+
| ---------- | --------------------------------------- | -------- | ------- | ----------------------- |
|
|
1296
|
+
| `variant` | `"text" \| "circular" \| "rectangular"` | | "text" | 스켈레톤 형태 |
|
|
1297
|
+
| `width` | `string \| number` | | | 너비 (px 또는 CSS 값) |
|
|
1298
|
+
| `height` | `string \| number` | | | 높이 (px 또는 CSS 값) |
|
|
1299
|
+
| `lines` | `number` | | 1 | text variant일 때 줄 수 |
|
|
1300
|
+
| `animated` | `boolean` | | true | 펄스 애니메이션 활성화 |
|
|
1301
|
+
|
|
1302
|
+
**SkeletonText:**
|
|
1303
|
+
|
|
1304
|
+
| Prop | Type | Required | Default | Description |
|
|
1305
|
+
| ------- | -------- | -------- | ------- | ------------ |
|
|
1306
|
+
| `lines` | `number` | | 3 | 텍스트 줄 수 |
|
|
1307
|
+
|
|
1308
|
+
**SkeletonAvatar:**
|
|
1309
|
+
|
|
1310
|
+
| Prop | Type | Required | Default | Description |
|
|
1311
|
+
| ------ | -------- | -------- | ------- | ---------------- |
|
|
1312
|
+
| `size` | `number` | | 40 | 아바타 크기 (px) |
|
|
1313
|
+
|
|
1314
|
+
**SkeletonTable:**
|
|
1315
|
+
|
|
1316
|
+
| Prop | Type | Required | Default | Description |
|
|
1317
|
+
| --------- | -------- | -------- | ------- | ------------ |
|
|
1318
|
+
| `rows` | `number` | | 5 | 테이블 행 수 |
|
|
1319
|
+
| `columns` | `number` | | 4 | 테이블 열 수 |
|
|
1320
|
+
|
|
1321
|
+
#### Textarea
|
|
1322
|
+
|
|
1323
|
+
**Import:** `import { Textarea } from "@reopt-ai/opt-ui"`
|
|
1324
|
+
|
|
1325
|
+
| Prop | Type | Required | Default | Description |
|
|
1326
|
+
| ----------- | ------------------------------------------------ | -------- | ---------- | ---------------- |
|
|
1327
|
+
| `label` | `string` | | | 입력 필드 레이블 |
|
|
1328
|
+
| `error` | `string` | | | 에러 메시지 |
|
|
1329
|
+
| `hint` | `string` | | | 힌트 텍스트 |
|
|
1330
|
+
| `fullWidth` | `boolean` | | false | 전체 너비 사용 |
|
|
1331
|
+
| `resize` | `"none" \| "vertical" \| "horizontal" \| "both"` | | "vertical" | 크기 조절 방향 |
|
|
1332
|
+
| `rows` | `number` | | 4 | 표시 줄 수 |
|
|
1333
|
+
|
|
1334
|
+
#### Avatar
|
|
1335
|
+
|
|
1336
|
+
**Import:** `import { Avatar } from "@reopt-ai/opt-ui"`
|
|
1337
|
+
|
|
1338
|
+
**Avatar:**
|
|
1339
|
+
|
|
1340
|
+
| Prop | Type | Required | Default | Description |
|
|
1341
|
+
| ---------- | ------------------------------------------- | -------- | ------- | -------------------------------------- |
|
|
1342
|
+
| `src` | `string` | | | 이미지 URL |
|
|
1343
|
+
| `alt` | `string` | | | 이미지 대체 텍스트 |
|
|
1344
|
+
| `name` | `string` | | | 사용자 이름 (이니셜 생성 및 색상 결정) |
|
|
1345
|
+
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | | "md" | 아바타 크기 |
|
|
1346
|
+
| `fallback` | `ReactNode` | | | 이미지 실패 시 표시할 콘텐츠 |
|
|
1347
|
+
| `status` | `"online" \| "offline" \| "busy" \| "away"` | | | 상태 인디케이터 |
|
|
1348
|
+
|
|
1349
|
+
**AvatarGroup:**
|
|
1350
|
+
|
|
1351
|
+
| Prop | Type | Required | Default | Description |
|
|
1352
|
+
| ---------- | -------------------------------------- | -------- | ------- | -------------- |
|
|
1353
|
+
| `max` | `number` | | 4 | 최대 표시 개수 |
|
|
1354
|
+
| `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | | "md" | 아바타 크기 |
|
|
1355
|
+
| `children` | `ReactNode` | Yes | | Avatar 요소들 |
|
|
1356
|
+
|
|
1357
|
+
#### Progress
|
|
1358
|
+
|
|
1359
|
+
**Import:** `import { Progress } from "@reopt-ai/opt-ui"`
|
|
1360
|
+
|
|
1361
|
+
**Progress:**
|
|
1362
|
+
|
|
1363
|
+
| Prop | Type | Required | Default | Description |
|
|
1364
|
+
| --------------- | ------------------------------------------------ | -------- | --------- | ------------------------------------ |
|
|
1365
|
+
| `value` | `number` | | | 현재 값. 생략하면 indeterminate 상태 |
|
|
1366
|
+
| `max` | `number` | | 100 | 최대 값 |
|
|
1367
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 진행바 높이 |
|
|
1368
|
+
| `variant` | `"default" \| "success" \| "warning" \| "error"` | | "default" | 색상 변형 |
|
|
1369
|
+
| `showLabel` | `boolean` | | false | 퍼센트 표시 |
|
|
1370
|
+
| `label` | `string` | | | 레이블 텍스트 |
|
|
1371
|
+
| `animated` | `boolean` | | true | 애니메이션 활성화 |
|
|
1372
|
+
| `indeterminate` | `boolean` | | false | 값을 알 수 없는 진행 상태 |
|
|
1373
|
+
|
|
1374
|
+
**CircularProgress:**
|
|
1375
|
+
|
|
1376
|
+
| Prop | Type | Required | Default | Description |
|
|
1377
|
+
| --------------- | ------------------------------------------------ | -------- | --------- | ------------------------------------ |
|
|
1378
|
+
| `value` | `number` | | | 현재 값. 생략하면 indeterminate 상태 |
|
|
1379
|
+
| `max` | `number` | | 100 | 최대 값 |
|
|
1380
|
+
| `size` | `number` | | 48 | 원 크기 (px) |
|
|
1381
|
+
| `strokeWidth` | `number` | | 4 | 선 두께 |
|
|
1382
|
+
| `variant` | `"default" \| "success" \| "warning" \| "error"` | | "default" | 색상 변형 |
|
|
1383
|
+
| `showLabel` | `boolean` | | false | 중앙에 퍼센트 표시 |
|
|
1384
|
+
| `label` | `string` | | | 접근성 레이블 |
|
|
1385
|
+
| `indeterminate` | `boolean` | | false | 값을 알 수 없는 진행 상태 |
|
|
1386
|
+
|
|
1387
|
+
#### Meter
|
|
1388
|
+
|
|
1389
|
+
**Import:** `import { Meter } from "@reopt-ai/opt-ui"`
|
|
1390
|
+
|
|
1391
|
+
| Prop | Type | Required | Default | Description |
|
|
1392
|
+
| ----------- | ------------------------------------------------ | -------- | --------- | ------------- |
|
|
1393
|
+
| `value` | `number` | Yes | | 현재 값 |
|
|
1394
|
+
| `min` | `number` | | 0 | 최소 값 |
|
|
1395
|
+
| `max` | `number` | | 100 | 최대 값 |
|
|
1396
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 게이지 높이 |
|
|
1397
|
+
| `variant` | `"default" \| "success" \| "warning" \| "error"` | | "default" | 색상 변형 |
|
|
1398
|
+
| `showValue` | `boolean` | | false | 퍼센트 표시 |
|
|
1399
|
+
| `label` | `string` | | | 레이블 텍스트 |
|
|
1400
|
+
|
|
1401
|
+
#### Breadcrumb
|
|
1402
|
+
|
|
1403
|
+
**Import:** `import { Breadcrumb } from "@reopt-ai/opt-ui"`
|
|
1404
|
+
|
|
1405
|
+
| Prop | Type | Required | Default | Description |
|
|
1406
|
+
| ------------ | -------------------------------- | -------- | ------- | ------------------------------------------- |
|
|
1407
|
+
| `items` | `BreadcrumbItem[]` | Yes | | 경로 항목 배열. { id, label, href?, icon? } |
|
|
1408
|
+
| `separator` | `ReactNode` | | "/" | 항목 간 구분자 |
|
|
1409
|
+
| `onNavigate` | `(item: BreadcrumbItem) => void` | | | 항목 클릭 핸들러 |
|
|
1410
|
+
|
|
1411
|
+
#### EmptyState
|
|
1412
|
+
|
|
1413
|
+
**Import:** `import { EmptyState } from "@reopt-ai/opt-ui"`
|
|
1414
|
+
|
|
1415
|
+
| Prop | Type | Required | Default | Description |
|
|
1416
|
+
| ------------- | -------------------- | -------- | ------- | -------------------------------------------- |
|
|
1417
|
+
| `title` | `string` | Yes | | 빈 상태 제목 |
|
|
1418
|
+
| `description` | `string` | | | 빈 상태 설명 |
|
|
1419
|
+
| `icon` | `ReactNode` | | | 표시할 아이콘 |
|
|
1420
|
+
| `actions` | `EmptyStateAction[]` | | | 액션 버튼 배열. { label, onClick, variant? } |
|
|
1421
|
+
|
|
1422
|
+
#### Card
|
|
1423
|
+
|
|
1424
|
+
**Import:** `import { Card } from "@reopt-ai/opt-ui"`
|
|
1425
|
+
|
|
1426
|
+
**Card:**
|
|
1427
|
+
|
|
1428
|
+
| Prop | Type | Required | Default | Description |
|
|
1429
|
+
| ------------------ | ----------------------------------- | -------- | --------- | ------------------------------ |
|
|
1430
|
+
| `variant` | `"default" \| "outline" \| "ghost"` | | "default" | 카드 스타일 변형 |
|
|
1431
|
+
| `padding` | `"none" \| "sm" \| "md" \| "lg"` | | "md" | 내부 패딩 크기 |
|
|
1432
|
+
| `selectable` | `boolean` | | false | 선택 가능 모드 활성화 |
|
|
1433
|
+
| `selected` | `boolean` | | | 선택 상태 (selectable=true 시) |
|
|
1434
|
+
| `onSelectedChange` | `(selected: boolean) => void` | | | 선택 상태 변경 콜백 |
|
|
1435
|
+
|
|
1436
|
+
**CardHeader:**
|
|
1437
|
+
|
|
1438
|
+
| Prop | Type | Required | Default | Description |
|
|
1439
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
1440
|
+
|
|
1441
|
+
**CardTitle:**
|
|
1442
|
+
|
|
1443
|
+
| Prop | Type | Required | Default | Description |
|
|
1444
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
1445
|
+
|
|
1446
|
+
**CardDescription:**
|
|
1447
|
+
|
|
1448
|
+
| Prop | Type | Required | Default | Description |
|
|
1449
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
1450
|
+
|
|
1451
|
+
**CardContent:**
|
|
1452
|
+
|
|
1453
|
+
| Prop | Type | Required | Default | Description |
|
|
1454
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
1455
|
+
|
|
1456
|
+
**CardFooter:**
|
|
1457
|
+
|
|
1458
|
+
| Prop | Type | Required | Default | Description |
|
|
1459
|
+
| ---- | ---- | -------- | ------- | ----------- |
|
|
1460
|
+
|
|
1461
|
+
**Examples:**
|
|
1462
|
+
|
|
1463
|
+
_카드 레이아웃:_
|
|
1464
|
+
|
|
1465
|
+
```tsx
|
|
1466
|
+
import {
|
|
1467
|
+
Card,
|
|
1468
|
+
CardHeader,
|
|
1469
|
+
CardTitle,
|
|
1470
|
+
CardDescription,
|
|
1471
|
+
CardContent,
|
|
1472
|
+
} from "@reopt-ai/opt-ui";
|
|
1473
|
+
|
|
1474
|
+
<Card>
|
|
1475
|
+
<CardHeader>
|
|
1476
|
+
<CardTitle>프로젝트 요약</CardTitle>
|
|
1477
|
+
<CardDescription>최근 7일간 활동 현황</CardDescription>
|
|
1478
|
+
</CardHeader>
|
|
1479
|
+
<CardContent>
|
|
1480
|
+
<p>활성 사용자: 1,234명</p>
|
|
1481
|
+
</CardContent>
|
|
1482
|
+
</Card>;
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
#### Checkbox
|
|
1486
|
+
|
|
1487
|
+
**Import:** `import { Checkbox } from "@reopt-ai/opt-ui"`
|
|
1488
|
+
|
|
1489
|
+
**Checkbox:**
|
|
1490
|
+
|
|
1491
|
+
| Prop | Type | Required | Default | Description |
|
|
1492
|
+
| ---------------- | ---------------------------- | -------- | ------- | ---------------------------------- |
|
|
1493
|
+
| `label` | `string` | | | 체크박스 레이블 |
|
|
1494
|
+
| `description` | `string` | | | 레이블 아래 설명 텍스트 |
|
|
1495
|
+
| `checked` | `boolean` | | | 제어 모드: 체크 상태 |
|
|
1496
|
+
| `defaultChecked` | `boolean` | | | 비제어 모드: 초기 체크 상태 |
|
|
1497
|
+
| `onChange` | `(checked: boolean) => void` | | | 상태 변경 핸들러 |
|
|
1498
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 체크박스 크기 |
|
|
1499
|
+
| `value` | `string` | | | CheckboxGroup 내에서 사용할 값 |
|
|
1500
|
+
| `indeterminate` | `boolean` | | false | 불확정 상태 표시 (마이너스 아이콘) |
|
|
1501
|
+
|
|
1502
|
+
**CheckboxGroup:**
|
|
1503
|
+
|
|
1504
|
+
| Prop | Type | Required | Default | Description |
|
|
1505
|
+
| -------------- | ---------------------------- | -------- | ---------- | ------------------------------ |
|
|
1506
|
+
| `value` | `string[]` | | | 제어 모드: 선택된 값 배열 |
|
|
1507
|
+
| `defaultValue` | `string[]` | | [] | 비제어 모드: 초기 선택 값 배열 |
|
|
1508
|
+
| `onChange` | `(value: string[]) => void` | | | 선택 변경 핸들러 |
|
|
1509
|
+
| `orientation` | `"horizontal" \| "vertical"` | | "vertical" | 레이아웃 방향 |
|
|
1510
|
+
| `label` | `string` | | | 그룹 레이블 |
|
|
1511
|
+
|
|
1512
|
+
#### RadioGroup
|
|
1513
|
+
|
|
1514
|
+
**Import:** `import { RadioGroup } from "@reopt-ai/opt-ui"`
|
|
1515
|
+
|
|
1516
|
+
**RadioGroup:**
|
|
1517
|
+
|
|
1518
|
+
| Prop | Type | Required | Default | Description |
|
|
1519
|
+
| -------------- | ---------------------------- | -------- | ---------- | ------------------------- |
|
|
1520
|
+
| `value` | `string` | | | 제어 모드: 선택된 값 |
|
|
1521
|
+
| `defaultValue` | `string` | | "" | 비제어 모드: 초기 선택 값 |
|
|
1522
|
+
| `onChange` | `(value: string) => void` | | | 선택 변경 핸들러 |
|
|
1523
|
+
| `orientation` | `"horizontal" \| "vertical"` | | "vertical" | 레이아웃 방향 |
|
|
1524
|
+
| `label` | `string` | | | 그룹 레이블 |
|
|
1525
|
+
| `name` | `string` | | | 폼 제출 시 사용할 이름 |
|
|
1526
|
+
|
|
1527
|
+
**Radio:**
|
|
1528
|
+
|
|
1529
|
+
| Prop | Type | Required | Default | Description |
|
|
1530
|
+
| ------------- | ---------------------- | -------- | ------- | ---------------------------------------------------------- |
|
|
1531
|
+
| `value` | `string` | | | 라디오 값 (RadioGroup 안에서는 부모가 관리하므로 optional) |
|
|
1532
|
+
| `label` | `string` | | | 라디오 레이블 |
|
|
1533
|
+
| `description` | `string` | | | 레이블 아래 설명 텍스트 |
|
|
1534
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 라디오 크기 |
|
|
1535
|
+
|
|
1536
|
+
#### DateRangePicker
|
|
1537
|
+
|
|
1538
|
+
**Import:** `import { DateRangePicker } from "@reopt-ai/opt-ui"`
|
|
1539
|
+
|
|
1540
|
+
| Prop | Type | Required | Default | Description |
|
|
1541
|
+
| --------------------- | ----------------------------------------------------- | -------- | ------------------- | ------------------------------------------------------ |
|
|
1542
|
+
| `value` | `DateRange` | | | 제어 모드: { start: Date \| null, end: Date \| null } |
|
|
1543
|
+
| `onChange` | `(range: DateRange) => void` | | | 범위 변경 핸들러 |
|
|
1544
|
+
| `presets` | `DateRangePreset[]` | | | 빠른 선택 프리셋 배열 (기본: Today, Last 7/30/90 days) |
|
|
1545
|
+
| `placeholder` | `string` | | "Select date range" | 미선택 시 표시 텍스트 |
|
|
1546
|
+
| `label` | `string` | | | 입력 필드 레이블 |
|
|
1547
|
+
| `disabled` | `boolean` | | false | 비활성화 상태 |
|
|
1548
|
+
| `format` | `(date: Date) => string` | | | 날짜 포맷 함수 |
|
|
1549
|
+
| `comparison` | `boolean` | | false | 비교 모드 활성화 |
|
|
1550
|
+
| `comparisonMode` | `"previous" \| "year-over-year"` | | "previous" | 비교 기준 (이전 기간 / 전년 동기) |
|
|
1551
|
+
| `onComparisonChange` | `(comparison: boolean, mode: ComparisonMode) => void` | | | 비교 모드 변경 콜백 |
|
|
1552
|
+
| `showGranularity` | `boolean` | | false | 시간 단위 선택기 표시 |
|
|
1553
|
+
| `granularity` | `"hour" \| "day" \| "week" \| "month"` | | "day" | 시간 단위 |
|
|
1554
|
+
| `onGranularityChange` | `(granularity: DateGranularity) => void` | | | 시간 단위 변경 콜백 |
|
|
1555
|
+
|
|
1556
|
+
#### TagInput
|
|
1557
|
+
|
|
1558
|
+
**Import:** `import { TagInput } from "@reopt-ai/opt-ui"`
|
|
1559
|
+
|
|
1560
|
+
| Prop | Type | Required | Default | Description |
|
|
1561
|
+
| ----------------- | -------------------------- | -------- | ---------------- | ----------------------------------------- |
|
|
1562
|
+
| `value` | `string[]` | | | 제어 모드: 현재 태그 배열 |
|
|
1563
|
+
| `onChange` | `(tags: string[]) => void` | | | 태그 변경 핸들러 |
|
|
1564
|
+
| `placeholder` | `string` | | "Add tag..." | 입력 플레이스홀더 |
|
|
1565
|
+
| `label` | `string` | | | 입력 필드 레이블 |
|
|
1566
|
+
| `maxTags` | `number` | | | 최대 태그 수 |
|
|
1567
|
+
| `disabled` | `boolean` | | false | 비활성화 상태 |
|
|
1568
|
+
| `suggestions` | `string[]` | | | 자동완성 드롭다운에 표시할 추천 태그 목록 |
|
|
1569
|
+
| `delimiters` | `(string \| RegExp)[]` | | [",", ";", "\n"] | 붙여넣기 시 태그를 분할할 구분자 목록 |
|
|
1570
|
+
| `allowDuplicates` | `boolean` | | false | 중복 태그 허용 여부 |
|
|
1571
|
+
|
|
1572
|
+
#### ColorPicker
|
|
1573
|
+
|
|
1574
|
+
**Import:** `import { ColorPicker } from "@reopt-ai/opt-ui"`
|
|
1575
|
+
|
|
1576
|
+
| Prop | Type | Required | Default | Description |
|
|
1577
|
+
| ---------- | ------------------------- | -------- | ------- | -------------------------------------- |
|
|
1578
|
+
| `value` | `string` | | | 제어 모드: hex 색상 값 (예: '#3b82f6') |
|
|
1579
|
+
| `onChange` | `(color: string) => void` | | | 색상 변경 핸들러 |
|
|
1580
|
+
| `presets` | `string[]` | | | 프리셋 색상 배열 (기본 16색) |
|
|
1581
|
+
| `label` | `string` | | | 입력 필드 레이블 |
|
|
1582
|
+
| `disabled` | `boolean` | | false | 비활성화 상태 |
|
|
1583
|
+
|
|
1584
|
+
#### IconPicker
|
|
1585
|
+
|
|
1586
|
+
**Import:** `import { IconPicker } from "@reopt-ai/opt-ui"`
|
|
1587
|
+
|
|
1588
|
+
| Prop | Type | Required | Default | Description |
|
|
1589
|
+
| ---------- | -------------------------- | -------- | ------- | ------------------------------------------ |
|
|
1590
|
+
| `value` | `string` | | | 제어 모드: 선택된 아이콘 ID |
|
|
1591
|
+
| `onChange` | `(iconId: string) => void` | | | 아이콘 변경 핸들러 |
|
|
1592
|
+
| `icons` | `IconDef[]` | | | 아이콘 목록 (기본 24개 Lucide 아이콘 제공) |
|
|
1593
|
+
| `label` | `string` | | | 입력 필드 레이블 |
|
|
1594
|
+
| `disabled` | `boolean` | | false | 비활성화 상태 |
|
|
1595
|
+
|
|
1596
|
+
#### StepBuilder
|
|
1597
|
+
|
|
1598
|
+
**Import:** `import { StepBuilder } from "@reopt-ai/opt-ui"`
|
|
1599
|
+
|
|
1600
|
+
| Prop | Type | Required | Default | Description |
|
|
1601
|
+
| ---------- | ---------------------------- | -------- | ------- | --------------------------------------- |
|
|
1602
|
+
| `steps` | `StepDef[]` | Yes | | 단계 배열 ({ id, label, description? }) |
|
|
1603
|
+
| `onChange` | `(steps: StepDef[]) => void` | Yes | | 단계 변경 핸들러 |
|
|
1604
|
+
| `label` | `string` | | | 빌더 레이블 |
|
|
1605
|
+
| `maxSteps` | `number` | | | 최대 단계 수 |
|
|
1606
|
+
|
|
1607
|
+
#### ConditionBuilder
|
|
1608
|
+
|
|
1609
|
+
**Import:** `import { ConditionBuilder } from "@reopt-ai/opt-ui"`
|
|
1610
|
+
|
|
1611
|
+
| Prop | Type | Required | Default | Description |
|
|
1612
|
+
| --------------------- | --------------------------------------- | -------- | ------------------ | -------------------------------------- |
|
|
1613
|
+
| `groups` | `ConditionGroup[]` | Yes | | 조건 그룹 배열 |
|
|
1614
|
+
| `onChange` | `(groups: ConditionGroup[]) => void` | Yes | | 그룹 변경 핸들러 |
|
|
1615
|
+
| `properties` | `string[]` | | | 선택 가능한 속성 목록 (기본 10개 제공) |
|
|
1616
|
+
| `label` | `string` | | | 빌더 레이블 |
|
|
1617
|
+
| `nested` | `boolean` | | false | 중첩 AND/OR 그룹 활성화 |
|
|
1618
|
+
| `maxDepth` | `number` | | 3 | 최대 중첩 깊이 |
|
|
1619
|
+
| `conditionTypes` | `Record<string, ConditionTypeRenderer>` | | | 이질적 조건 타입 렌더러 레지스트리 |
|
|
1620
|
+
| `onPreview` | `(groups: ConditionGroup[]) => void` | | | 조건 변경 시 미리보기 콜백 |
|
|
1621
|
+
| `previewCount` | `number` | | | 매치 카운트 표시 (toLocaleString 포맷) |
|
|
1622
|
+
| `addNestedGroupLabel` | `string` | | "Add nested group" | 중첩 그룹 추가 버튼 텍스트 |
|
|
1623
|
+
|
|
1624
|
+
#### Popover
|
|
1625
|
+
|
|
1626
|
+
**Import:** `import { PopoverRoot } from "@reopt-ai/opt-ui"`
|
|
1627
|
+
|
|
1628
|
+
| Prop | Type | Required | Default | Description |
|
|
1629
|
+
| ----------- | -------- | -------- | ------- | -------------------- |
|
|
1630
|
+
| `gutter` | `number` | | 8 | 트리거와의 간격 (px) |
|
|
1631
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1632
|
+
|
|
1633
|
+
#### DropdownMenu
|
|
1634
|
+
|
|
1635
|
+
**Import:** `import { DropdownMenu } from "@reopt-ai/opt-ui"`
|
|
1636
|
+
|
|
1637
|
+
**DropdownContent:**
|
|
1638
|
+
|
|
1639
|
+
| Prop | Type | Required | Default | Description |
|
|
1640
|
+
| -------- | -------- | -------- | ------- | -------------------- |
|
|
1641
|
+
| `gutter` | `number` | | 4 | 트리거와의 간격 (px) |
|
|
1642
|
+
|
|
1643
|
+
**DropdownItem:**
|
|
1644
|
+
|
|
1645
|
+
| Prop | Type | Required | Default | Description |
|
|
1646
|
+
| ---------- | ---------------------------- | -------- | --------- | --------------------------------------------------- |
|
|
1647
|
+
| `variant` | `"default" \| "destructive"` | | "default" | 메뉴 아이템 시각 변형. destructive는 위험 작업 강조 |
|
|
1648
|
+
| `onClick` | `() => void` | | | 항목 클릭 핸들러 |
|
|
1649
|
+
| `disabled` | `boolean` | | | 비활성 상태 |
|
|
1650
|
+
|
|
1651
|
+
#### NumberInput
|
|
1652
|
+
|
|
1653
|
+
**Import:** `import { NumberInput } from "@reopt-ai/opt-ui"`
|
|
1654
|
+
|
|
1655
|
+
| Prop | Type | Required | Default | Description |
|
|
1656
|
+
| ---------------- | --------------------------------- | -------- | ------- | ------------------------------------------------ |
|
|
1657
|
+
| `value` | `number \| null` | | | 제어 모드 값. nullable=true일 때 null 허용 |
|
|
1658
|
+
| `defaultValue` | `number \| null` | | 0 | 비제어 모드 초기값. nullable=true일 때 null 허용 |
|
|
1659
|
+
| `onChange` | `(value: number \| null) => void` | | | 값 변경 핸들러 |
|
|
1660
|
+
| `nullable` | `boolean` | | false | 빈 값을 null로 커밋할지 여부 |
|
|
1661
|
+
| `clearable` | `boolean` | | false | nullable 값 지우기 버튼 표시 |
|
|
1662
|
+
| `min` | `number` | | | 최솟값 |
|
|
1663
|
+
| `max` | `number` | | | 최댓값 |
|
|
1664
|
+
| `step` | `number` | | 1 | 증감 단위 |
|
|
1665
|
+
| `label` | `string` | | | 라벨 텍스트 |
|
|
1666
|
+
| `unit` | `ReactNode` | | | 입력값 단위 suffix |
|
|
1667
|
+
| `disabled` | `boolean` | | | 비활성 상태 |
|
|
1668
|
+
| `disabledReason` | `string` | | | aria-disabled 상태에서 노출할 비활성 사유 |
|
|
1669
|
+
| `labels` | `NumberInputLabels` | | | 입력/증감/clear/invalid 접근성 문구 |
|
|
1670
|
+
|
|
1671
|
+
#### Slider
|
|
1672
|
+
|
|
1673
|
+
**Import:** `import { Slider } from "@reopt-ai/opt-ui"`
|
|
1674
|
+
|
|
1675
|
+
| Prop | Type | Required | Default | Description |
|
|
1676
|
+
| -------------- | --------------------------- | -------- | ------- | ------------------ |
|
|
1677
|
+
| `value` | `number` | | | 제어 모드 값 |
|
|
1678
|
+
| `defaultValue` | `number` | | 0 | 비제어 모드 초기값 |
|
|
1679
|
+
| `onChange` | `(value: number) => void` | | | 값 변경 핸들러 |
|
|
1680
|
+
| `min` | `number` | | 0 | 최솟값 |
|
|
1681
|
+
| `max` | `number` | | 100 | 최댓값 |
|
|
1682
|
+
| `step` | `number` | | 1 | 증감 단위 |
|
|
1683
|
+
| `label` | `string` | | | 레이블 텍스트 |
|
|
1684
|
+
| `showValue` | `boolean` | | false | 현재 값 표시 여부 |
|
|
1685
|
+
| `formatValue` | `(value: number) => string` | | | 값 포맷 함수 |
|
|
1686
|
+
| `disabled` | `boolean` | | | 비활성화 |
|
|
1687
|
+
| `className` | `string` | | | 최외곽 CSS 클래스 |
|
|
1688
|
+
|
|
1689
|
+
#### PageHeader
|
|
1690
|
+
|
|
1691
|
+
**Import:** `import { PageHeader } from "@reopt-ai/opt-ui"`
|
|
1692
|
+
|
|
1693
|
+
| Prop | Type | Required | Default | Description |
|
|
1694
|
+
| ------------- | ----------- | -------- | ------- | ----------------------------------- |
|
|
1695
|
+
| `title` | `string` | Yes | | 페이지 제목 |
|
|
1696
|
+
| `description` | `string` | | | 제목 아래 설명 텍스트 |
|
|
1697
|
+
| `actions` | `ReactNode` | | | 오른쪽에 표시할 액션 슬롯 (버튼 등) |
|
|
1698
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1699
|
+
|
|
1700
|
+
#### ScrollArea
|
|
1701
|
+
|
|
1702
|
+
**Import:** `import { ScrollArea } from "@reopt-ai/opt-ui"`
|
|
1703
|
+
|
|
1704
|
+
| Prop | Type | Required | Default | Description |
|
|
1705
|
+
| ------------- | -------------------------------------- | -------- | ---------- | ----------------- |
|
|
1706
|
+
| `children` | `ReactNode` | Yes | | 스크롤할 콘텐츠 |
|
|
1707
|
+
| `orientation` | `"vertical" \| "horizontal" \| "both"` | | "vertical" | 스크롤 방향 |
|
|
1708
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1709
|
+
|
|
1710
|
+
#### Container
|
|
1711
|
+
|
|
1712
|
+
**Import:** `import { Container } from "@reopt-ai/opt-ui"`
|
|
1713
|
+
|
|
1714
|
+
| Prop | Type | Required | Default | Description |
|
|
1715
|
+
| ----------- | ------------------------------------------------- | -------- | ------- | ------------------------ |
|
|
1716
|
+
| `children` | `ReactNode` | Yes | | 래핑할 콘텐츠 |
|
|
1717
|
+
| `maxWidth` | `"sm" \| "md" \| "lg" \| "xl" \| "2xl" \| "full"` | | "xl" | 최대 너비 크기 |
|
|
1718
|
+
| `center` | `boolean` | | true | 중앙 정렬 여부 (mx-auto) |
|
|
1719
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1720
|
+
|
|
1721
|
+
#### Section
|
|
1722
|
+
|
|
1723
|
+
**Import:** `import { Section } from "@reopt-ai/opt-ui"`
|
|
1724
|
+
|
|
1725
|
+
| Prop | Type | Required | Default | Description |
|
|
1726
|
+
| ------------- | ----------- | -------- | ------- | --------------------- |
|
|
1727
|
+
| `children` | `ReactNode` | Yes | | 섹션 콘텐츠 |
|
|
1728
|
+
| `title` | `string` | | | 섹션 제목 (h3) |
|
|
1729
|
+
| `description` | `string` | | | 제목 아래 설명 텍스트 |
|
|
1730
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1731
|
+
|
|
1732
|
+
#### Resizable
|
|
1733
|
+
|
|
1734
|
+
**Import:** `import { ResizablePanelGroup } from "@reopt-ai/opt-ui"`
|
|
1735
|
+
|
|
1736
|
+
**ResizablePanelGroup:**
|
|
1737
|
+
|
|
1738
|
+
| Prop | Type | Required | Default | Description |
|
|
1739
|
+
| ------------ | ---------------------------- | -------- | ------- | ---------------------------------------- |
|
|
1740
|
+
| `direction` | `"horizontal" \| "vertical"` | Yes | | 패널 분할 방향 |
|
|
1741
|
+
| `children` | `ReactNode` | Yes | | ResizablePanel + ResizableHandle 조합 |
|
|
1742
|
+
| `autoSaveId` | `string` | | | 로컬 스토리지에 크기 상태 저장 (고유 ID) |
|
|
1743
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1744
|
+
|
|
1745
|
+
**ResizablePanel:**
|
|
1746
|
+
|
|
1747
|
+
| Prop | Type | Required | Default | Description |
|
|
1748
|
+
| ------------- | ----------- | -------- | ------- | ----------------------------- |
|
|
1749
|
+
| `defaultSize` | `number` | | | 초기 크기 (퍼센트, 0-100) |
|
|
1750
|
+
| `minSize` | `number` | | | 최소 크기 (퍼센트) |
|
|
1751
|
+
| `maxSize` | `number` | | | 최대 크기 (퍼센트) |
|
|
1752
|
+
| `collapsible` | `boolean` | | false | 최소 크기 이하 시 접히기 허용 |
|
|
1753
|
+
| `children` | `ReactNode` | Yes | | 패널 콘텐츠 |
|
|
1754
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1755
|
+
|
|
1756
|
+
**ResizableHandle:**
|
|
1757
|
+
|
|
1758
|
+
| Prop | Type | Required | Default | Description |
|
|
1759
|
+
| ------------ | --------- | -------- | ------- | ----------------------- |
|
|
1760
|
+
| `withHandle` | `boolean` | | false | 시각적 드래그 핸들 표시 |
|
|
1761
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1762
|
+
|
|
1763
|
+
#### BlockLayout
|
|
1764
|
+
|
|
1765
|
+
**Import:** `import { BlockLayout } from "@reopt-ai/opt-ui"`
|
|
1766
|
+
|
|
1767
|
+
| Prop | Type | Required | Default | Description |
|
|
1768
|
+
| -------------- | --------------------------------------------- | -------- | --------- | ------------------------------------------------------------------------------------ |
|
|
1769
|
+
| `children` | `ReactNode` | Yes | | Block 콘텐츠 |
|
|
1770
|
+
| `loading` | `boolean` | | | 로딩 상태. 설정 시 LoadingOverlay로 자동 래핑 |
|
|
1771
|
+
| `loadingLabel` | `string` | | | LoadingOverlay 접근성 레이블 |
|
|
1772
|
+
| `spacing` | `"section" \| "group" \| "element" \| "none"` | | "section" | Block 최상위 자식 사이 간격. 데이터 밀도가 높은 Block는 group/element로 낮출 수 있음 |
|
|
1773
|
+
| `className` | `string` | | | 기본 스타일 오버라이드 |
|
|
1774
|
+
|
|
1775
|
+
**Examples:**
|
|
1776
|
+
|
|
1777
|
+
_Block 루트:_
|
|
1778
|
+
|
|
1779
|
+
```tsx
|
|
1780
|
+
import { BlockLayout, PageHeader } from "@reopt-ai/opt-ui";
|
|
1781
|
+
|
|
1782
|
+
<BlockLayout loading={isLoading} spacing="section">
|
|
1783
|
+
<PageHeader title="대시보드" description="프로젝트 현황" />
|
|
1784
|
+
<section>콘텐츠 영역</section>
|
|
1785
|
+
</BlockLayout>;
|
|
1786
|
+
```
|
|
1787
|
+
|
|
1788
|
+
#### createBlock
|
|
1789
|
+
|
|
1790
|
+
**Import:** `import { createBlock } from "@reopt-ai/opt-ui"`
|
|
1791
|
+
|
|
1792
|
+
| Prop | Type | Required | Default | Description |
|
|
1793
|
+
| ------------------------- | --------------------------------------------------------- | -------- | ------- | ----------------------------------- |
|
|
1794
|
+
| `name` | `string` | Yes | | 컴포넌트 displayName |
|
|
1795
|
+
| `render` | `(props: Omit<P, 'loading' \| 'className'>) => ReactNode` | Yes | | 콘텐츠를 반환하는 렌더 함수 |
|
|
1796
|
+
| `options.layoutClassName` | `string` | | | BlockLayout에 전달할 기본 className |
|
|
1797
|
+
|
|
1798
|
+
**Examples:**
|
|
1799
|
+
|
|
1800
|
+
_Block 팩토리:_
|
|
1801
|
+
|
|
1802
|
+
```tsx
|
|
1803
|
+
import { createBlock, PageHeader } from "@reopt-ai/opt-ui";
|
|
1804
|
+
|
|
1805
|
+
interface MyDashboardProps {
|
|
1806
|
+
title: string;
|
|
1807
|
+
count: number;
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
const MyDashboard = createBlock<MyDashboardProps>(
|
|
1811
|
+
"MyDashboard",
|
|
1812
|
+
({ title, count }) => (
|
|
1813
|
+
<>
|
|
1814
|
+
<PageHeader title={title} />
|
|
1815
|
+
<p>항목 수: {count}</p>
|
|
1816
|
+
</>
|
|
1817
|
+
),
|
|
1818
|
+
);
|
|
1819
|
+
|
|
1820
|
+
// loading, className은 자동 처리
|
|
1821
|
+
<MyDashboard title="개요" count={42} loading={false} />;
|
|
1822
|
+
```
|
|
1823
|
+
|
|
1824
|
+
#### Logo
|
|
1825
|
+
|
|
1826
|
+
**Import:** `import { Logo } from "@reopt-ai/opt-ui"`
|
|
1827
|
+
|
|
1828
|
+
| Prop | Type | Required | Default | Description |
|
|
1829
|
+
| ----------- | ---------------------- | -------- | ------- | -------------------------------- |
|
|
1830
|
+
| `src` | `string` | | | 로고 이미지 URL |
|
|
1831
|
+
| `icon` | `ReactNode` | | | 로고 아이콘 — src 미설정 시 표시 |
|
|
1832
|
+
| `text` | `string` | | | 텍스트 레이블 |
|
|
1833
|
+
| `alt` | `string` | | "Logo" | 이미지 alt 텍스트 |
|
|
1834
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 크기 (sm=24px, md=32px, lg=40px) |
|
|
1835
|
+
| `href` | `string` | | | 링크 URL — 설정 시 <a>로 래핑 |
|
|
1836
|
+
| `onClick` | `() => void` | | | 클릭 핸들러 |
|
|
1837
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
1838
|
+
|
|
1839
|
+
#### Drawer
|
|
1840
|
+
|
|
1841
|
+
**Import:** `import { DrawerRoot } from "@reopt-ai/opt-ui"`
|
|
1842
|
+
|
|
1843
|
+
**DrawerRoot:**
|
|
1844
|
+
|
|
1845
|
+
| Prop | Type | Required | Default | Description |
|
|
1846
|
+
| --------- | ------------ | -------- | ------- | ------------------- |
|
|
1847
|
+
| `open` | `boolean` | | | 제어 모드 열림 상태 |
|
|
1848
|
+
| `onClose` | `() => void` | | | 닫힘 콜백 |
|
|
1849
|
+
|
|
1850
|
+
**DrawerPanel:**
|
|
1851
|
+
|
|
1852
|
+
| Prop | Type | Required | Default | Description |
|
|
1853
|
+
| ----------------------- | -------------------------------- | -------- | ------- | -------------------------------------- |
|
|
1854
|
+
| `side` | `"left" \| "right" \| "bottom"` | | "right" | 슬라이드 방향 |
|
|
1855
|
+
| `size` | `"sm" \| "md" \| "lg" \| "full"` | | "md" | 패널 크기 |
|
|
1856
|
+
| `swipeToDismiss` | `boolean` | | true | 가장자리 방향으로 드래그해 닫기 활성화 |
|
|
1857
|
+
| `swipeDismissThreshold` | `number` | | 80 | 닫힘 커밋에 필요한 드래그 거리(px) |
|
|
1858
|
+
|
|
1859
|
+
#### Pagination
|
|
1860
|
+
|
|
1861
|
+
**Import:** `import { Pagination } from "@reopt-ai/opt-ui"`
|
|
1862
|
+
|
|
1863
|
+
| Prop | Type | Required | Default | Description |
|
|
1864
|
+
| ----------------- | ------------------------------------------- | -------- | ------------ | ------------------------------------------- |
|
|
1865
|
+
| `totalItems` | `number` | | | 전체 항목 수 |
|
|
1866
|
+
| `totalPages` | `number` | | | 전체 페이지 수. 전체 항목 수를 모를 때 사용 |
|
|
1867
|
+
| `hasMore` | `boolean` | | | cursor pagination에서 다음 페이지 존재 여부 |
|
|
1868
|
+
| `pageSize` | `number` | | | 페이지당 항목 수 |
|
|
1869
|
+
| `currentPage` | `number` | Yes | | 현재 페이지 (1부터 시작) |
|
|
1870
|
+
| `onPageChange` | `(page: number) => void` | Yes | | 페이지 변경 콜백 |
|
|
1871
|
+
| `showPageNumbers` | `boolean` | | true | 페이지 번호 표시 여부 |
|
|
1872
|
+
| `siblingCount` | `number` | | 1 | 현재 페이지 좌우 표시할 페이지 수 |
|
|
1873
|
+
| `variant` | `"pages" \| "count" \| "compact" \| "none"` | | "pages" | 중앙 표시 방식 |
|
|
1874
|
+
| `isDisabled` | `boolean` | | false | 전체 pagination 비활성화 |
|
|
1875
|
+
| `label` | `string` | | "Pagination" | navigation landmark 접근성 라벨 |
|
|
1876
|
+
| `labels` | `PaginationLabels` | | | Prev/Next/page/count 접근성 및 표시 문구 |
|
|
1877
|
+
|
|
1878
|
+
#### VirtualList
|
|
1879
|
+
|
|
1880
|
+
**Import:** `import { VirtualList } from "@reopt-ai/opt-ui"`
|
|
1881
|
+
|
|
1882
|
+
| Prop | Type | Required | Default | Description |
|
|
1883
|
+
| ------------ | --------------------------------------- | -------- | ------- | --------------------------------- |
|
|
1884
|
+
| `items` | `T[]` | Yes | | 렌더링할 항목 배열 |
|
|
1885
|
+
| `renderItem` | `(item: T, index: number) => ReactNode` | Yes | | 항목 렌더 함수 |
|
|
1886
|
+
| `itemHeight` | `number` | Yes | | 각 항목의 고정 높이(px) |
|
|
1887
|
+
| `overscan` | `number` | | 3 | 뷰포트 밖에 미리 렌더링할 항목 수 |
|
|
1888
|
+
|
|
1889
|
+
#### LoadingOverlay
|
|
1890
|
+
|
|
1891
|
+
**Import:** `import { LoadingOverlay } from "@reopt-ai/opt-ui"`
|
|
1892
|
+
**Dependencies:** spinner (core)
|
|
1893
|
+
|
|
1894
|
+
| Prop | Type | Required | Default | Description |
|
|
1895
|
+
| ---------- | ----------- | -------- | ---------- | ------------- |
|
|
1896
|
+
| `loading` | `boolean` | Yes | | 로딩 상태 |
|
|
1897
|
+
| `children` | `ReactNode` | Yes | | 감싸는 콘텐츠 |
|
|
1898
|
+
| `label` | `string` | | "Loading…" | 로딩 텍스트 |
|
|
1899
|
+
|
|
1900
|
+
#### StarRating
|
|
1901
|
+
|
|
1902
|
+
**Import:** `import { StarRating } from "@reopt-ai/opt-ui"`
|
|
1903
|
+
|
|
1904
|
+
| Prop | Type | Required | Default | Description |
|
|
1905
|
+
| ---------- | ------------------------- | -------- | ------- | ---------------- |
|
|
1906
|
+
| `value` | `number` | | | 현재 선택된 별점 |
|
|
1907
|
+
| `onChange` | `(value: number) => void` | | | 별점 변경 콜백 |
|
|
1908
|
+
| `max` | `number` | | 5 | 최대 별 개수 |
|
|
1909
|
+
| `readOnly` | `boolean` | | false | 읽기 전용 모드 |
|
|
1910
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 별 아이콘 크기 |
|
|
1911
|
+
|
|
1912
|
+
#### ErrorBoundary
|
|
1913
|
+
|
|
1914
|
+
**Import:** `import { ErrorBoundary } from "@reopt-ai/opt-ui"`
|
|
1915
|
+
|
|
1916
|
+
| Prop | Type | Required | Default | Description |
|
|
1917
|
+
| ---------- | -------------------------------------------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
|
|
1918
|
+
| `children` | `ReactNode` | Yes | | 에러를 감시할 자식 컴포넌트 |
|
|
1919
|
+
| `fallback` | `ReactNode \| ((error: Error) => ReactNode)` | | | 에러 발생 시 표시할 UI. 함수 전달 시 에러 객체를 인자로 받음. 미지정 시 Alert error 표시 |
|
|
1920
|
+
| `onError` | `(error: Error, info: ErrorInfo) => void` | | | 에러 발생 시 호출되는 콜백 (에러 리포팅용) |
|
|
1921
|
+
|
|
1922
|
+
#### Command
|
|
1923
|
+
|
|
1924
|
+
**Import:** `import { Command } from "@reopt-ai/opt-ui"`
|
|
1925
|
+
|
|
1926
|
+
**Command:**
|
|
1927
|
+
|
|
1928
|
+
| Prop | Type | Required | Default | Description |
|
|
1929
|
+
| -------------- | ---------------------------------------------------------------- | -------- | ------- | --------------------------------------------------- |
|
|
1930
|
+
| `shouldFilter` | `boolean` | | | 자동 필터링 여부 (기본 true) |
|
|
1931
|
+
| `filter` | `(value: string, search: string, keywords: string[]) => boolean` | | | 커스텀 필터 함수 (기본: case-insensitive substring) |
|
|
1932
|
+
|
|
1933
|
+
**CommandInput:**
|
|
1934
|
+
|
|
1935
|
+
| Prop | Type | Required | Default | Description |
|
|
1936
|
+
| ------------------ | ----------- | -------- | ------- | ----------------------------------- |
|
|
1937
|
+
| `trailing` | `ReactNode` | | | 검색 입력 우측에 표시할 보조 콘텐츠 |
|
|
1938
|
+
| `wrapperClassName` | `string` | | | 입력 wrapper className |
|
|
1939
|
+
|
|
1940
|
+
**CommandList:**
|
|
1941
|
+
|
|
1942
|
+
| Prop | Type | Required | Default | Description |
|
|
1943
|
+
| ------------ | -------- | -------- | ---------- | ------------------- |
|
|
1944
|
+
| `aria-label` | `string` | | "Commands" | listbox 접근성 라벨 |
|
|
1945
|
+
|
|
1946
|
+
**CommandItem:**
|
|
1947
|
+
|
|
1948
|
+
| Prop | Type | Required | Default | Description |
|
|
1949
|
+
| ---------- | ------------------------- | -------- | ------- | ---------------------------------------- |
|
|
1950
|
+
| `value` | `string` | Yes | | 이 항목의 검색 가능 값 (고유 식별자) |
|
|
1951
|
+
| `keywords` | `string[]` | | | value에 더해 검색어와 비교할 추가 키워드 |
|
|
1952
|
+
| `onSelect` | `(value: string) => void` | | | Enter/클릭 시 호출 |
|
|
1953
|
+
|
|
1954
|
+
#### ShaderSurface
|
|
1955
|
+
|
|
1956
|
+
**Import:** `import { ShaderSurface } from "@reopt-ai/opt-ui"`
|
|
1957
|
+
|
|
1958
|
+
| Prop | Type | Required | Default | Description |
|
|
1959
|
+
| ------------ | ---------------- | -------- | ------- | ------------------------------------------ |
|
|
1960
|
+
| `preset` | `ShaderPresetId` | Yes | | 렌더할 셰이더 프리셋 id |
|
|
1961
|
+
| `colors` | `string[]` | | | hex 색상 배열 (미지정 시 프리셋 기본 색) |
|
|
1962
|
+
| `scale` | `number` | | | 패턴 스케일 |
|
|
1963
|
+
| `speed` | `number` | | | 애니메이션 속도 |
|
|
1964
|
+
| `distortion` | `number` | | | 왜곡 강도 |
|
|
1965
|
+
| `grain` | `number` | | | 필름 그레인 양 |
|
|
1966
|
+
| `contrast` | `number` | | | 하이라이트 대비 |
|
|
1967
|
+
| `angle` | `number` | | | 회전 각도(도) |
|
|
1968
|
+
| `paused` | `boolean` | | | true면 단일 프레임만 렌더 (카드 배경 등) |
|
|
1969
|
+
| `dpr` | `number` | | | device pixel ratio 상한 (기본 min(dpr, 2)) |
|
|
1970
|
+
|
|
1971
|
+
### Visual Layer
|
|
1972
|
+
|
|
1973
|
+
### Shell Layer
|
|
1974
|
+
|
|
1975
|
+
#### FaqAccordion
|
|
1976
|
+
|
|
1977
|
+
**Import:** `import { FaqAccordion } from "@reopt-ai/opt-ui"`
|
|
1978
|
+
**Dependencies:** disclosure (core)
|
|
1979
|
+
|
|
1980
|
+
| Prop | Type | Required | Default | Description |
|
|
1981
|
+
| ------- | ----------- | -------- | ------- | --------------------------------------- |
|
|
1982
|
+
| `items` | `FaqItem[]` | Yes | | FAQ 항목 배열. { id, question, answer } |
|
|
1983
|
+
|
|
1984
|
+
#### PageAside
|
|
1985
|
+
|
|
1986
|
+
**Import:** `import { PageAside } from "@reopt-ai/opt-ui"`
|
|
1987
|
+
|
|
1988
|
+
| Prop | Type | Required | Default | Description |
|
|
1989
|
+
| ---------------- | ----------- | -------- | ------- | -------------------------------------- |
|
|
1990
|
+
| `header` | `ReactNode` | | | 상단 고정 슬롯 (예: package switcher). |
|
|
1991
|
+
| `children` | `ReactNode` | Yes | | 스크롤 가능한 네비게이션 영역. |
|
|
1992
|
+
| `footer` | `ReactNode` | | | 하단 고정 슬롯 (예: version label). |
|
|
1993
|
+
| `widthClassName` | `string` | | | 너비 Tailwind 클래스. 기본값 `w-60`. |
|
|
1994
|
+
| `label` | `string` | | | `<aside>`의 aria-label. |
|
|
1995
|
+
| `hideOnMobile` | `boolean` | | | md 아래에서 숨김. 기본값 true. |
|
|
1996
|
+
|
|
1997
|
+
#### ContentTabs
|
|
1998
|
+
|
|
1999
|
+
**Import:** `import { ContentTabs } from "@reopt-ai/opt-ui"`
|
|
2000
|
+
**Dependencies:** tabs (core)
|
|
2001
|
+
|
|
2002
|
+
| Prop | Type | Required | Default | Description |
|
|
2003
|
+
| -------------- | ---------- | -------- | ------- | ------------------------------------ |
|
|
2004
|
+
| `tabs` | `TabDef[]` | Yes | | 탭 정의 배열. { id, label, content } |
|
|
2005
|
+
| `defaultTabId` | `string` | | | 초기 선택 탭 ID. 미지정 시 첫 탭 |
|
|
2006
|
+
|
|
2007
|
+
#### DashboardGrid
|
|
2008
|
+
|
|
2009
|
+
**Import:** `import { DashboardGrid } from "@reopt-ai/opt-ui"`
|
|
2010
|
+
**Dependencies:** stat-card (core), composite-zone (core)
|
|
2011
|
+
|
|
2012
|
+
| Prop | Type | Required | Default | Description |
|
|
2013
|
+
| --------- | ------------ | -------- | ------- | ----------------------------------------------------- |
|
|
2014
|
+
| `stats` | `StatCard[]` | Yes | | 통계 데이터 배열. { id, title, value, change, trend } |
|
|
2015
|
+
| `columns` | `number` | | 3 | 행당 컬럼 수 |
|
|
2016
|
+
|
|
2017
|
+
#### SearchCombobox
|
|
2018
|
+
|
|
2019
|
+
**Import:** `import { SearchCombobox } from "@reopt-ai/opt-ui"`
|
|
2020
|
+
**Dependencies:** combobox (core)
|
|
2021
|
+
|
|
2022
|
+
| Prop | Type | Required | Default | Description |
|
|
2023
|
+
| ------------- | -------------------------------------- | -------- | --------- | -------------------------------- |
|
|
2024
|
+
| `items` | `string[]` | Yes | | 검색 대상 문자열 목록 |
|
|
2025
|
+
| `placeholder` | `string` | | "검색..." | 입력 플레이스홀더 |
|
|
2026
|
+
| `label` | `string` | | "검색" | 입력 레이블 |
|
|
2027
|
+
| `onSelect` | `(item: string) => void` | | | 항목 선택 핸들러 |
|
|
2028
|
+
| `labels` | `SearchComboboxLabels` | | | noResults/loading 문구 |
|
|
2029
|
+
| `async` | `boolean` | | false | 비동기 검색 모드 활성화 |
|
|
2030
|
+
| `onSearch` | `(query: string) => Promise<string[]>` | | | async=true일 때 사용할 검색 콜백 |
|
|
2031
|
+
| `debounceMs` | `number` | | 300 | 비동기 검색 디바운스 ms |
|
|
2032
|
+
|
|
2033
|
+
**Examples:**
|
|
2034
|
+
|
|
2035
|
+
_검색 + 선택:_
|
|
2036
|
+
|
|
2037
|
+
```tsx
|
|
2038
|
+
import { SearchCombobox } from "@reopt-ai/opt-ui";
|
|
2039
|
+
|
|
2040
|
+
<SearchCombobox
|
|
2041
|
+
items={["React", "Vue", "Angular", "Svelte"]}
|
|
2042
|
+
placeholder="프레임워크 검색..."
|
|
2043
|
+
onSelect={(item) => console.log(item)}
|
|
2044
|
+
/>;
|
|
2045
|
+
```
|
|
2046
|
+
|
|
2047
|
+
#### StatusSelect
|
|
2048
|
+
|
|
2049
|
+
**Import:** `import { StatusSelect } from "@reopt-ai/opt-ui"`
|
|
2050
|
+
**Dependencies:** select (core)
|
|
2051
|
+
|
|
2052
|
+
| Prop | Type | Required | Default | Description |
|
|
2053
|
+
| ---------- | ------------------------- | -------- | ------- | ----------------------------------- |
|
|
2054
|
+
| `options` | `SelectOption[]` | Yes | | 옵션 목록. { value, label, color? } |
|
|
2055
|
+
| `value` | `string` | | | 제어 모드: 현재 선택 값 |
|
|
2056
|
+
| `onChange` | `(value: string) => void` | | | 제어 모드: 값 변경 핸들러 |
|
|
2057
|
+
| `label` | `string` | | "상태" | Select 레이블 |
|
|
2058
|
+
|
|
2059
|
+
#### EditorToolbar
|
|
2060
|
+
|
|
2061
|
+
**Import:** `import { EditorToolbar } from "@reopt-ai/opt-ui"`
|
|
2062
|
+
**Dependencies:** toolbar (core)
|
|
2063
|
+
|
|
2064
|
+
| Prop | Type | Required | Default | Description |
|
|
2065
|
+
| --------------- | ---------------------- | -------- | ------- | ------------------------------------------ |
|
|
2066
|
+
| `buttons` | `ToolbarButtonDef[]` | Yes | | 버튼 정의. { id, label, icon, separator? } |
|
|
2067
|
+
| `onAction` | `(id: string) => void` | | | 버튼 클릭 핸들러 |
|
|
2068
|
+
| `activeButtons` | `string[]` | | [] | 활성 상태 버튼 ID 배열 |
|
|
2069
|
+
|
|
2070
|
+
#### SidebarNav
|
|
2071
|
+
|
|
2072
|
+
**Import:** `import { SidebarNav } from "@reopt-ai/opt-ui"`
|
|
2073
|
+
|
|
2074
|
+
| Prop | Type | Required | Default | Description |
|
|
2075
|
+
| ------- | -------------- | -------- | ------- | --------------------------------------------------------------- |
|
|
2076
|
+
| `items` | `NavItemDef[]` | Yes | | 네비게이션 항목. { id, label, href, separator?, sectionLabel? } |
|
|
2077
|
+
|
|
2078
|
+
#### SettingsForm
|
|
2079
|
+
|
|
2080
|
+
**Import:** `import { SettingsForm } from "@reopt-ai/opt-ui"`
|
|
2081
|
+
**Dependencies:** form (core), checkbox (core), radio-group (core), switch (core)
|
|
2082
|
+
|
|
2083
|
+
| Prop | Type | Required | Default | Description |
|
|
2084
|
+
| ---------- | ------------------------------------------- | -------- | ------- | ----------------- |
|
|
2085
|
+
| `fields` | `FormFieldDef[]` | Yes | | 폼 필드 정의 배열 |
|
|
2086
|
+
| `onSubmit` | `(values: Record<string, unknown>) => void` | | | 제출 핸들러 |
|
|
2087
|
+
|
|
2088
|
+
**Examples:**
|
|
2089
|
+
|
|
2090
|
+
_설정 폼:_
|
|
2091
|
+
|
|
2092
|
+
```tsx
|
|
2093
|
+
import { SettingsForm } from "@reopt-ai/opt-ui";
|
|
2094
|
+
|
|
2095
|
+
const fields = [
|
|
2096
|
+
{ name: "username", label: "사용자명", type: "text", required: true },
|
|
2097
|
+
{ name: "theme", label: "테마", type: "select", options: ["light", "dark"] },
|
|
2098
|
+
{ name: "notifications", label: "알림", type: "switch" },
|
|
2099
|
+
];
|
|
2100
|
+
|
|
2101
|
+
<SettingsForm fields={fields} onSubmit={(values) => console.log(values)} />;
|
|
2102
|
+
```
|
|
2103
|
+
|
|
2104
|
+
#### AppMenubar
|
|
2105
|
+
|
|
2106
|
+
**Import:** `import { AppMenubar } from "@reopt-ai/opt-ui"`
|
|
2107
|
+
**Dependencies:** menu (core), kbd (core)
|
|
2108
|
+
|
|
2109
|
+
| Prop | Type | Required | Default | Description |
|
|
2110
|
+
| ------- | ----------- | -------- | ------- | --------------------------------------------------- |
|
|
2111
|
+
| `menus` | `MenuDef[]` | Yes | | 메뉴 정의 배열. { id, label, items: MenuItemDef[] } |
|
|
2112
|
+
|
|
2113
|
+
#### CommandPalette
|
|
2114
|
+
|
|
2115
|
+
**Import:** `import { CommandPalette } from "@reopt-ai/opt-ui"`
|
|
2116
|
+
**Dependencies:** dialog (core), combobox (core), kbd (core)
|
|
2117
|
+
|
|
2118
|
+
| Prop | Type | Required | Default | Description |
|
|
2119
|
+
| --------------- | -------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
|
|
2120
|
+
| `commands` | `Omit<Command, "action">[]` | Yes | | 커맨드 목록. { id, label, group, shortcut? } |
|
|
2121
|
+
| `open` | `boolean` | Yes | | 열림 상태 |
|
|
2122
|
+
| `onOpenChange` | `(open: boolean) => void` | Yes | | 상태 변경 핸들러 |
|
|
2123
|
+
| `onSelect` | `(command: Omit<Command, 'action'>) => void` | | | 커맨드 선택 핸들러 |
|
|
2124
|
+
| `inline` | `boolean` | | false | true일 때 풀스크린 Dialog 대신 인라인 팝업으로 렌더링 |
|
|
2125
|
+
| `labels` | `CommandPaletteLabels` | | | title/description/input/list/empty/escape 문구 |
|
|
2126
|
+
| `footer` | `ReactNode` | | | 명령 목록 아래에 표시할 footer slot |
|
|
2127
|
+
| `empty` | `ReactNode` | | | 결과가 없을 때 표시할 empty slot |
|
|
2128
|
+
| `inputTrailing` | `ReactNode` | | | 검색 입력 우측 보조 콘텐츠 |
|
|
2129
|
+
|
|
2130
|
+
#### CommandPaletteTrigger
|
|
2131
|
+
|
|
2132
|
+
**Import:** `import { CommandPaletteTrigger } from "@reopt-ai/opt-ui"`
|
|
2133
|
+
**Dependencies:** command-palette (shells)
|
|
2134
|
+
|
|
2135
|
+
| Prop | Type | Required | Default | Description |
|
|
2136
|
+
| ---------- | -------------------------------------------- | -------- | ------- | -------------------------------------------------- |
|
|
2137
|
+
| `commands` | `Omit<Command, "action">[]` | Yes | | 커맨드 목록 |
|
|
2138
|
+
| `onSelect` | `(command: Omit<Command, 'action'>) => void` | | | 커맨드 선택 핸들러 |
|
|
2139
|
+
| `labels` | `CommandPaletteTriggerLabels` | | | 내부 CommandPalette에 전달할 title/input/list 문구 |
|
|
2140
|
+
|
|
2141
|
+
#### DeploymentTimeline
|
|
2142
|
+
|
|
2143
|
+
**Import:** `import { DeploymentTimeline } from "@reopt-ai/opt-ui"`
|
|
2144
|
+
|
|
2145
|
+
| Prop | Type | Required | Default | Description |
|
|
2146
|
+
| ------- | ------------------ | -------- | --------------- | -------------------------------------------------------- |
|
|
2147
|
+
| `steps` | `DeploymentStep[]` | Yes | | 배포 단계 배열. { id, name, status, duration?, detail? } |
|
|
2148
|
+
| `title` | `string` | | "배포 타임라인" | 타임라인 제목 |
|
|
2149
|
+
|
|
2150
|
+
#### ProjectSwitcher
|
|
2151
|
+
|
|
2152
|
+
**Import:** `import { ProjectSwitcher } from "@reopt-ai/opt-ui"`
|
|
2153
|
+
**Dependencies:** combobox (core)
|
|
2154
|
+
|
|
2155
|
+
| Prop | Type | Required | Default | Description |
|
|
2156
|
+
| ------------- | ---------------------- | -------- | ------------------ | ------------------------------------------------------- |
|
|
2157
|
+
| `projects` | `ProjectDef[]` | Yes | | 프로젝트 목록. { id, name, framework, status, domain? } |
|
|
2158
|
+
| `value` | `string` | | | 제어 모드: 현재 선택된 프로젝트 ID |
|
|
2159
|
+
| `onChange` | `(id: string) => void` | | | 프로젝트 선택 핸들러 |
|
|
2160
|
+
| `placeholder` | `string` | | "프로젝트 검색..." | 검색 입력 플레이스홀더 |
|
|
2161
|
+
|
|
2162
|
+
#### EnvPanel
|
|
2163
|
+
|
|
2164
|
+
**Import:** `import { EnvPanel } from "@reopt-ai/opt-ui"`
|
|
2165
|
+
**Dependencies:** disclosure (core)
|
|
2166
|
+
|
|
2167
|
+
| Prop | Type | Required | Default | Description |
|
|
2168
|
+
| -------- | --------------- | -------- | ------- | ------------------------------------------ |
|
|
2169
|
+
| `groups` | `EnvGroupDef[]` | Yes | | 환경 그룹 배열. { env, vars: EnvVarDef[] } |
|
|
2170
|
+
|
|
2171
|
+
#### BranchSelect
|
|
2172
|
+
|
|
2173
|
+
**Import:** `import { BranchSelect } from "@reopt-ai/opt-ui"`
|
|
2174
|
+
**Dependencies:** select (core)
|
|
2175
|
+
|
|
2176
|
+
| Prop | Type | Required | Default | Description |
|
|
2177
|
+
| ---------- | ------------------------ | -------- | -------- | ------------------------------------------------------- |
|
|
2178
|
+
| `branches` | `BranchDef[]` | Yes | | 브랜치 목록. { name, isDefault?, lastCommit?, author? } |
|
|
2179
|
+
| `value` | `string` | | | 제어 모드: 현재 선택된 브랜치 이름 |
|
|
2180
|
+
| `onChange` | `(name: string) => void` | | | 브랜치 선택 핸들러 |
|
|
2181
|
+
| `label` | `string` | | "브랜치" | Select 레이블 |
|
|
2182
|
+
|
|
2183
|
+
#### DomainTable
|
|
2184
|
+
|
|
2185
|
+
**Import:** `import { DomainTable } from "@reopt-ai/opt-ui"`
|
|
2186
|
+
|
|
2187
|
+
| Prop | Type | Required | Default | Description |
|
|
2188
|
+
| --------- | ------------- | -------- | -------- | --------------------------------------------------------- |
|
|
2189
|
+
| `domains` | `DomainDef[]` | Yes | | 도메인 목록. { domain, status, ssl, redirect?, addedAt? } |
|
|
2190
|
+
| `title` | `string` | | "도메인" | 테이블 제목 |
|
|
2191
|
+
|
|
2192
|
+
#### DataTable
|
|
2193
|
+
|
|
2194
|
+
**Import:** `import { DataTable } from "@reopt-ai/opt-ui"`
|
|
2195
|
+
**Dependencies:** composite-zone (core), button (core), checkbox (core)
|
|
2196
|
+
|
|
2197
|
+
**DataTable:**
|
|
2198
|
+
|
|
2199
|
+
| Prop | Type | Required | Default | Description |
|
|
2200
|
+
| -------------- | -------------------- | -------- | ------------------- | --------------------------------------------------- |
|
|
2201
|
+
| `data` | `T[]` | Yes | | 테이블 데이터 배열 |
|
|
2202
|
+
| `columns` | `ColumnDef<T>[]` | Yes | | 컬럼 정의. { id, header, accessor, width?, align? } |
|
|
2203
|
+
| `keyExtractor` | `(row: T) => string` | Yes | | 각 행의 고유 키 추출 함수 |
|
|
2204
|
+
| `title` | `string` | | "데이터 테이블" | 테이블 제목 |
|
|
2205
|
+
| `onRowClick` | `(row: T) => void` | | | 행 클릭 핸들러 |
|
|
2206
|
+
| `emptyMessage` | `string` | | "데이터가 없습니다" | 데이터 없을 때 표시할 메시지 |
|
|
2207
|
+
|
|
2208
|
+
**ColumnDef:**
|
|
2209
|
+
|
|
2210
|
+
| Prop | Type | Required | Default | Description |
|
|
2211
|
+
| ---------- | -------------------- | -------- | ----------- | ------------------------------------------------------------ |
|
|
2212
|
+
| `bar` | `(row: T) => number` | | | 인라인 프로그레스 바 비율(0-1) 계산 함수. 범위 밖/NaN은 보정 |
|
|
2213
|
+
| `barColor` | `string` | | "bg-accent" | 인라인 바 색상 클래스 |
|
|
2214
|
+
|
|
2215
|
+
**Examples:**
|
|
2216
|
+
|
|
2217
|
+
_기본 테이블:_
|
|
2218
|
+
|
|
2219
|
+
```tsx
|
|
2220
|
+
import { DataTable } from "@reopt-ai/opt-ui";
|
|
2221
|
+
|
|
2222
|
+
const columns = [
|
|
2223
|
+
{ id: "name", header: "이름", accessor: (r) => r.name },
|
|
2224
|
+
{ id: "email", header: "이메일", accessor: (r) => r.email },
|
|
2225
|
+
];
|
|
2226
|
+
const data = [
|
|
2227
|
+
{ name: "홍길동", email: "hong@example.com" },
|
|
2228
|
+
{ name: "김철수", email: "kim@example.com" },
|
|
2229
|
+
];
|
|
2230
|
+
|
|
2231
|
+
<DataTable columns={columns} data={data} keyExtractor={(r) => r.email} />;
|
|
2232
|
+
```
|
|
2233
|
+
|
|
2234
|
+
_선택 + 정렬:_
|
|
2235
|
+
|
|
2236
|
+
```tsx
|
|
2237
|
+
import { DataTable } from "@reopt-ai/opt-ui";
|
|
2238
|
+
|
|
2239
|
+
<DataTable
|
|
2240
|
+
columns={columns}
|
|
2241
|
+
data={data}
|
|
2242
|
+
keyExtractor={(r) => r.id}
|
|
2243
|
+
selectable
|
|
2244
|
+
selectedKeys={selected}
|
|
2245
|
+
onSelectionChange={setSelected}
|
|
2246
|
+
sortable
|
|
2247
|
+
onSort={(colId, dir) => console.log(colId, dir)}
|
|
2248
|
+
/>;
|
|
2249
|
+
```
|
|
2250
|
+
|
|
2251
|
+
#### NotificationToast
|
|
2252
|
+
|
|
2253
|
+
**Import:** `import { ToastProvider } from "@reopt-ai/opt-ui"`
|
|
2254
|
+
**Dependencies:** alert (core)
|
|
2255
|
+
|
|
2256
|
+
**ToastProvider:**
|
|
2257
|
+
|
|
2258
|
+
| Prop | Type | Required | Default | Description |
|
|
2259
|
+
| ----------------- | -------------------------------------------------------------- | -------- | ----------- | ------------------- |
|
|
2260
|
+
| `children` | `ReactNode` | Yes | | 앱 컨텐츠 |
|
|
2261
|
+
| `position` | `"top-right" \| "top-left" \| "bottom-right" \| "bottom-left"` | | "top-right" | 토스트 표시 위치 |
|
|
2262
|
+
| `defaultDuration` | `number` | | 5000 | 기본 표시 시간 (ms) |
|
|
2263
|
+
|
|
2264
|
+
**useToast:**
|
|
2265
|
+
|
|
2266
|
+
| Prop | Type | Required | Default | Description |
|
|
2267
|
+
| --------- | ----------------------------------- | -------- | ------- | ------------------------ |
|
|
2268
|
+
| `returns` | `{ toasts, addToast, removeToast }` | | | 토스트 상태 및 제어 함수 |
|
|
2269
|
+
|
|
2270
|
+
**toast:**
|
|
2271
|
+
|
|
2272
|
+
| Prop | Type | Required | Default | Description |
|
|
2273
|
+
| ---------------------------------------- | --------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------ |
|
|
2274
|
+
| `toast.success / error / info / warning` | `(message: string, options?) => string` | | | 훅 없이 어디서든 호출하는 프로그램매틱 API. toast.dismiss(id) / toast.clear()도 제공 |
|
|
2275
|
+
|
|
2276
|
+
**NotificationToast:**
|
|
2277
|
+
|
|
2278
|
+
| Prop | Type | Required | Default | Description |
|
|
2279
|
+
| ----------- | -------------- | -------- | ------- | ------------------ |
|
|
2280
|
+
| `toast` | `ToastMessage` | Yes | | 토스트 메시지 객체 |
|
|
2281
|
+
| `onDismiss` | `() => void` | Yes | | 닫기 핸들러 |
|
|
2282
|
+
|
|
2283
|
+
#### DesignGuidePanel
|
|
2284
|
+
|
|
2285
|
+
**Import:** `import { DesignGuidePanel } from "@reopt-ai/opt-ui"`
|
|
2286
|
+
|
|
2287
|
+
| Prop | Type | Required | Default | Description |
|
|
2288
|
+
| ----------- | -------- | -------- | ------- | --------------- |
|
|
2289
|
+
| `className` | `string` | | | 추가 CSS 클래스 |
|
|
2290
|
+
|
|
2291
|
+
#### TaskList
|
|
2292
|
+
|
|
2293
|
+
**Import:** `import { TaskList } from "@reopt-ai/opt-ui"`
|
|
2294
|
+
**Dependencies:** avatar (core), checkbox (core)
|
|
2295
|
+
|
|
2296
|
+
| Prop | Type | Required | Default | Description |
|
|
2297
|
+
| -------------------- | --------------------------------------------- | -------- | ----------- | ---------------------------------------------------------- |
|
|
2298
|
+
| `tasks` | `TaskDef[]` | Yes | | 작업 배열. { id, title, status, priority, assignee?, ... } |
|
|
2299
|
+
| `title` | `string` | | "작업 목록" | 섹션 제목 |
|
|
2300
|
+
| `onTaskClick` | `(task: TaskDef) => void` | | | 작업 클릭 핸들러 |
|
|
2301
|
+
| `onTaskStatusChange` | `(task: TaskDef, completed: boolean) => void` | | | 완료 상태 변경 핸들러 |
|
|
2302
|
+
| `showSubtasks` | `boolean` | | false | 하위 작업 표시 여부 |
|
|
2303
|
+
|
|
2304
|
+
#### ActivityFeed
|
|
2305
|
+
|
|
2306
|
+
**Import:** `import { ActivityFeed } from "@reopt-ai/opt-ui"`
|
|
2307
|
+
**Dependencies:** avatar (core)
|
|
2308
|
+
|
|
2309
|
+
| Prop | Type | Required | Default | Description |
|
|
2310
|
+
| ----------------- | -------------------------------------- | -------- | ----------- | ----------------------------------------------------- |
|
|
2311
|
+
| `activities` | `ActivityDef[]` | Yes | | 활동 배열. { id, type, title, actor, timestamp, ... } |
|
|
2312
|
+
| `title` | `string` | | "활동 피드" | 섹션 제목 |
|
|
2313
|
+
| `maxItems` | `number` | | | 최대 표시 개수 |
|
|
2314
|
+
| `onActivityClick` | `(activity: ActivityDef) => void` | | | 활동 클릭 핸들러 |
|
|
2315
|
+
| `layout` | `"list" \| "compact"` | | "list" | 시간 표시 레이아웃 모드 |
|
|
2316
|
+
| `renderActions` | `(activity: ActivityDef) => ReactNode` | | | 각 활동 항목 우측 액션 슬롯 렌더 함수 |
|
|
2317
|
+
|
|
2318
|
+
#### FilterBar
|
|
2319
|
+
|
|
2320
|
+
**Import:** `import { FilterBar } from "@reopt-ai/opt-ui"`
|
|
2321
|
+
**Dependencies:** select (core), input (core), button (core), switch (core), checkbox (core), date-range-picker (core)
|
|
2322
|
+
|
|
2323
|
+
| Prop | Type | Required | Default | Description |
|
|
2324
|
+
| ---------------- | ------------------------------------------------------- | -------- | ------- | ----------------------------------------------------- |
|
|
2325
|
+
| `filters` | `FilterGroupDef[]` | Yes | | 필터 그룹 배열. { id, label, type, options?, value? } |
|
|
2326
|
+
| `onFilterChange` | `(filterId: string, value: string \| string[]) => void` | | | 필터 변경 핸들러 |
|
|
2327
|
+
| `onClearAll` | `() => void` | | | 모든 필터 초기화 핸들러 |
|
|
2328
|
+
|
|
2329
|
+
**Examples:**
|
|
2330
|
+
|
|
2331
|
+
_필터 바:_
|
|
2332
|
+
|
|
2333
|
+
```tsx
|
|
2334
|
+
import { FilterBar } from "@reopt-ai/opt-ui";
|
|
2335
|
+
|
|
2336
|
+
const filters = [
|
|
2337
|
+
{ id: "status", label: "상태", type: "select", options: ["활성", "비활성"] },
|
|
2338
|
+
{ id: "search", label: "검색", type: "search" },
|
|
2339
|
+
];
|
|
2340
|
+
|
|
2341
|
+
<FilterBar
|
|
2342
|
+
filters={filters}
|
|
2343
|
+
onFilterChange={(id, value) => console.log(id, value)}
|
|
2344
|
+
onClearAll={() => console.log("clear")}
|
|
2345
|
+
/>;
|
|
2346
|
+
```
|
|
2347
|
+
|
|
2348
|
+
#### QuickActions
|
|
2349
|
+
|
|
2350
|
+
**Import:** `import { QuickActions } from "@reopt-ai/opt-ui"`
|
|
2351
|
+
**Dependencies:** kbd (core)
|
|
2352
|
+
|
|
2353
|
+
| Prop | Type | Required | Default | Description |
|
|
2354
|
+
| --------- | ------------------ | -------- | ----------- | ----------------------------------------------------------------- |
|
|
2355
|
+
| `actions` | `QuickActionDef[]` | Yes | | 작업 배열. { id, label, description?, icon?, shortcut?, onClick } |
|
|
2356
|
+
| `title` | `string` | | "빠른 작업" | 섹션 제목 |
|
|
2357
|
+
| `layout` | `"grid" \| "list"` | | "grid" | 레이아웃 모드 |
|
|
2358
|
+
| `columns` | `2 \| 3 \| 4` | | 3 | 그리드 컬럼 수 |
|
|
2359
|
+
|
|
2360
|
+
#### TeamMemberList
|
|
2361
|
+
|
|
2362
|
+
**Import:** `import { TeamMemberList } from "@reopt-ai/opt-ui"`
|
|
2363
|
+
**Dependencies:** avatar (core)
|
|
2364
|
+
|
|
2365
|
+
| Prop | Type | Required | Default | Description |
|
|
2366
|
+
| --------------- | --------------------------------------- | -------- | ------- | ------------------------------------------------------- |
|
|
2367
|
+
| `members` | `TeamMemberDef[]` | Yes | | 팀원 배열. { id, name, email, avatar?, role?, status? } |
|
|
2368
|
+
| `title` | `string` | | "팀원" | 섹션 제목 |
|
|
2369
|
+
| `layout` | `"list" \| "compact" \| "avatars-only"` | | "list" | 레이아웃 모드 |
|
|
2370
|
+
| `maxDisplay` | `number` | | | 최대 표시 인원 |
|
|
2371
|
+
| `onMemberClick` | `(member: TeamMemberDef) => void` | | | 팀원 클릭 핸들러 |
|
|
2372
|
+
|
|
2373
|
+
#### AuthForm
|
|
2374
|
+
|
|
2375
|
+
**Import:** `import { AuthForm } from "@reopt-ai/opt-ui"`
|
|
2376
|
+
**Dependencies:** form (core)
|
|
2377
|
+
|
|
2378
|
+
| Prop | Type | Required | Default | Description |
|
|
2379
|
+
| ------------------- | ---------------------------------------------------------------------------- | -------- | ------- | -------------------------------------------- |
|
|
2380
|
+
| `defaultMode` | `"login" \| "signup"` | | "login" | 초기 모드 (비제어) |
|
|
2381
|
+
| `mode` | `"login" \| "signup"` | | | 제어 모드: 현재 모드 |
|
|
2382
|
+
| `onModeChange` | `(mode: "login" \| "signup") => void` | | | 모드 변경 핸들러 |
|
|
2383
|
+
| `showRememberMe` | `boolean` | | true | 로그인 모드에서 '로그인 상태 유지' 표시 여부 |
|
|
2384
|
+
| `minPasswordLength` | `number` | | 8 | 비밀번호 최소 길이 |
|
|
2385
|
+
| `onSubmit` | `(values: { email, password, confirmPassword?, rememberMe?, mode }) => void` | | | 제출 핸들러 |
|
|
2386
|
+
| `labels` | `AuthFormLabels` | | | i18n용 라벨 오버라이드 |
|
|
2387
|
+
|
|
2388
|
+
#### WizardForm
|
|
2389
|
+
|
|
2390
|
+
**Import:** `import { WizardForm } from "@reopt-ai/opt-ui"`
|
|
2391
|
+
**Dependencies:** form (core), checkbox (core), radio-group (core)
|
|
2392
|
+
|
|
2393
|
+
| Prop | Type | Required | Default | Description |
|
|
2394
|
+
| -------------- | ------------------------------------------- | -------- | ------- | ------------------------------------------ |
|
|
2395
|
+
| `fields` | `FormFieldDef[]` | Yes | | 폼 필드 정의 배열 |
|
|
2396
|
+
| `steps` | `WizardStepDef[]` | Yes | | 단계 정의. { id, label, fields: string[] } |
|
|
2397
|
+
| `showReview` | `boolean` | | true | 마지막 리뷰 단계 표시 여부 |
|
|
2398
|
+
| `onSubmit` | `(values: Record<string, unknown>) => void` | | | 제출 핸들러 |
|
|
2399
|
+
| `onStepChange` | `(stepIndex: number) => void` | | | 단계 변경 핸들러 |
|
|
2400
|
+
| `labels` | `WizardFormLabels` | | | i18n용 라벨 오버라이드 |
|
|
2401
|
+
|
|
2402
|
+
#### DynamicFieldForm
|
|
2403
|
+
|
|
2404
|
+
**Import:** `import { DynamicFieldForm } from "@reopt-ai/opt-ui"`
|
|
2405
|
+
**Dependencies:** form (core)
|
|
2406
|
+
|
|
2407
|
+
| Prop | Type | Required | Default | Description |
|
|
2408
|
+
| --------------- | ------------------------------------------------------- | -------- | ------- | ---------------------- |
|
|
2409
|
+
| `initialCount` | `number` | | 1 | 초기 필드 수 |
|
|
2410
|
+
| `minFields` | `number` | | 1 | 최소 필드 수 |
|
|
2411
|
+
| `maxFields` | `number` | | | 최대 필드 수 |
|
|
2412
|
+
| `fieldType` | `"text" \| "email" \| "url" \| "number"` | | "text" | 필드 입력 타입 |
|
|
2413
|
+
| `validateField` | `(value: string, index: number) => string \| undefined` | | | 커스텀 필드 검증 함수 |
|
|
2414
|
+
| `onSubmit` | `(values: string[]) => void` | | | 제출 핸들러 |
|
|
2415
|
+
| `labels` | `DynamicFieldFormLabels` | | | i18n용 라벨 오버라이드 |
|
|
2416
|
+
|
|
2417
|
+
#### FileUploadForm
|
|
2418
|
+
|
|
2419
|
+
**Import:** `import { FileUploadForm } from "@reopt-ai/opt-ui"`
|
|
2420
|
+
**Dependencies:** form (core)
|
|
2421
|
+
|
|
2422
|
+
| Prop | Type | Required | Default | Description |
|
|
2423
|
+
| ----------------- | ------------------------------------------------ | -------- | -------------------------- | ----------------------------------------- |
|
|
2424
|
+
| `accept` | `string` | | "image/\*,.pdf,.doc,.docx" | 허용 파일 타입 |
|
|
2425
|
+
| `showPreview` | `boolean` | | true | 이미지 미리보기 표시 |
|
|
2426
|
+
| `showFileInfo` | `boolean` | | true | 파일 정보 표시 |
|
|
2427
|
+
| `showDescription` | `boolean` | | true | 설명 텍스트영역 표시 |
|
|
2428
|
+
| `maxFileSize` | `number` | | | 최대 파일 크기 (bytes) |
|
|
2429
|
+
| `onSubmit` | `(values: { title, description, file }) => void` | | | 제출 핸들러 |
|
|
2430
|
+
| `labels` | `FileUploadFormLabels` | | | i18n용 라벨 오버라이드 |
|
|
2431
|
+
| `onPreview` | `(file: File) => void` | | | 파일 선택 후 프리뷰 콜백 |
|
|
2432
|
+
| `columnMapping` | `ReactNode` | | | CSV 컬럼 매핑 UI 슬롯 (파일 선택 후 표시) |
|
|
2433
|
+
|
|
2434
|
+
#### EventIcon
|
|
2435
|
+
|
|
2436
|
+
**Import:** `import { EventIcon } from "@reopt-ai/opt-ui"`
|
|
2437
|
+
|
|
2438
|
+
| Prop | Type | Required | Default | Description |
|
|
2439
|
+
| ------- | --------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------- |
|
|
2440
|
+
| `icon` | `string \| React.ReactNode` | Yes | | semantic icon key, legacy key, 또는 React 노드 (Lucide 등) |
|
|
2441
|
+
| `color` | `string` | | theme accent | 사용자 지정 아이콘 색상. 없으면 theme accent 토큰을 사용하고, 전달하면 전경색과 tint 배경에 적용됩니다. |
|
|
2442
|
+
| `size` | `"sm" \| "md" \| "lg"` | | "md" | 아이콘 크기 (sm=20px, md=28px, lg=36px) |
|
|
2443
|
+
|
|
2444
|
+
#### TemplatePicker
|
|
2445
|
+
|
|
2446
|
+
**Import:** `import { TemplatePicker } from "@reopt-ai/opt-ui"`
|
|
2447
|
+
|
|
2448
|
+
| Prop | Type | Required | Default | Description |
|
|
2449
|
+
| ------------ | ------------------------------ | -------- | ------- | --------------------------------------------------------------------------- |
|
|
2450
|
+
| `templates` | `TemplateDef[]` | Yes | | 템플릿 배열. { id, name, description?, icon?, category?, featured?, tags? } |
|
|
2451
|
+
| `selected` | `string` | | | 현재 선택된 템플릿 ID |
|
|
2452
|
+
| `onSelect` | `(templateId: string) => void` | Yes | | 템플릿 선택 핸들러 |
|
|
2453
|
+
| `showSearch` | `boolean` | | false | 검색 입력 표시 여부 |
|
|
2454
|
+
|
|
2455
|
+
#### FailureList
|
|
2456
|
+
|
|
2457
|
+
**Import:** `import { FailureList } from "@reopt-ai/opt-ui"`
|
|
2458
|
+
**Dependencies:** badge (core)
|
|
2459
|
+
|
|
2460
|
+
| Prop | Type | Required | Default | Description |
|
|
2461
|
+
| ---------------- | ------------------------------------- | -------- | ----------- | -------------------------------------------------------------------- |
|
|
2462
|
+
| `failures` | `FailureItem[]` | Yes | | 실패 항목 배열. { id, title, message?, severity, timestamp, group? } |
|
|
2463
|
+
| `title` | `string` | | "최근 실패" | 섹션 제목 |
|
|
2464
|
+
| `maxItems` | `number` | | | 최대 표시 개수 |
|
|
2465
|
+
| `grouped` | `boolean` | | false | group 필드 기준으로 그룹핑 표시 |
|
|
2466
|
+
| `onFailureClick` | `(failure: FailureItem) => void` | | | 실패 항목 클릭 핸들러 |
|
|
2467
|
+
| `renderActions` | `(failure: FailureItem) => ReactNode` | | | 각 항목 우측 액션 슬롯 렌더 함수 |
|
|
2468
|
+
|
|
2469
|
+
#### KeyValueEditor
|
|
2470
|
+
|
|
2471
|
+
**Import:** `import { KeyValueEditor } from "@reopt-ai/opt-ui"`
|
|
2472
|
+
|
|
2473
|
+
| Prop | Type | Required | Default | Description |
|
|
2474
|
+
| ------------------ | ---------------------------------------------------------------- | -------- | ------- | --------------------------------- |
|
|
2475
|
+
| `value` | `KeyValueEntry[]` | | | 현재 엔트리 (controlled 모드) |
|
|
2476
|
+
| `defaultValue` | `KeyValueEntry[]` | | | 초기 엔트리 (uncontrolled 모드) |
|
|
2477
|
+
| `onChange` | `(entries: KeyValueEntry[]) => void` | | | 엔트리 변경 핸들러 |
|
|
2478
|
+
| `showSecretToggle` | `boolean` | | false | 비밀값 표시/숨김 토글 버튼 활성화 |
|
|
2479
|
+
| `maxEntries` | `number` | | | 최대 항목 수 제한 |
|
|
2480
|
+
| `readOnly` | `boolean` | | false | 읽기 전용 모드 |
|
|
2481
|
+
| `labels` | `KeyValueEditorLabels` | | | i18n 라벨 오버라이드 |
|
|
2482
|
+
| `renderActions` | `(entry: KeyValueEntry, index: number) => ReactNode` | | | 항목별 커스텀 액션 슬롯 |
|
|
2483
|
+
| `validateKey` | `(key: string, entries: KeyValueEntry[]) => string \| undefined` | | | 키 유효성 검사 함수 |
|
|
2484
|
+
|
|
2485
|
+
#### WorkflowCanvas
|
|
2486
|
+
|
|
2487
|
+
**Import:** `import { WorkflowCanvas } from "@reopt-ai/opt-ui"`
|
|
2488
|
+
**Dependencies:** badge (core)
|
|
2489
|
+
|
|
2490
|
+
| Prop | Type | Required | Default | Description |
|
|
2491
|
+
| -------------- | ---------------------------------------------------- | -------- | ------- | ------------------------------------------- |
|
|
2492
|
+
| `steps` | `WorkflowCanvasStep[]` | Yes | | 스텝 배열. { id, title, row, col, status? } |
|
|
2493
|
+
| `connections` | `WorkflowCanvasConnection[]` | | [] | 연결선 배열. { from, to, label? } |
|
|
2494
|
+
| `onStepMove` | `(stepId: string, row: number, col: number) => void` | | | 화살표 키 이동 핸들러 |
|
|
2495
|
+
| `onSelectStep` | `(step: WorkflowCanvasStep) => void` | | | 스텝 선택 핸들러 |
|
|
2496
|
+
|
|
2497
|
+
#### CodeSnippetViewer
|
|
2498
|
+
|
|
2499
|
+
**Import:** `import { CodeSnippetViewer } from "@reopt-ai/opt-ui"`
|
|
2500
|
+
|
|
2501
|
+
| Prop | Type | Required | Default | Description |
|
|
2502
|
+
| ----------------- | ---------------------------------------------- | -------- | --------- | --------------------------------- |
|
|
2503
|
+
| `code` | `string` | Yes | | 표시할 코드 문자열 |
|
|
2504
|
+
| `language` | `string` | | "text" | 코드 언어 라벨 |
|
|
2505
|
+
| `title` | `string` | | | 헤더에 표시할 제목 |
|
|
2506
|
+
| `showLineNumbers` | `boolean` | | true | 줄 번호 표시 여부 |
|
|
2507
|
+
| `showCopyButton` | `boolean` | | true | 복사 버튼 표시 여부 |
|
|
2508
|
+
| `maxHeight` | `number` | | 400 | 스크롤 영역의 최대 높이(px) |
|
|
2509
|
+
| `syntaxTheme` | `"default" \| "muted" \| "dark" \| "terminal"` | | "default" | 코드 블록 색상 톤 |
|
|
2510
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2511
|
+
| `labels` | `CodeSnippetViewerLabels` | | | 복사 버튼과 코드 영역 레이블 문구 |
|
|
2512
|
+
|
|
2513
|
+
#### QueryResultsTable
|
|
2514
|
+
|
|
2515
|
+
**Import:** `import { QueryResultsTable } from "@reopt-ai/opt-ui"`
|
|
2516
|
+
|
|
2517
|
+
| Prop | Type | Required | Default | Description |
|
|
2518
|
+
| --------- | -------------------------------- | -------- | ------- | ----------------------- |
|
|
2519
|
+
| `columns` | `string[]` | Yes | | 컬럼 이름 |
|
|
2520
|
+
| `rows` | `Array<Record<string, unknown>>` | Yes | | 결과 행 |
|
|
2521
|
+
| `loading` | `boolean` | | | polite 로딩 상태 |
|
|
2522
|
+
| `error` | `string` | | | assertive 오류 상태 |
|
|
2523
|
+
| `labels` | `QueryResultsTableLabels` | | | 로딩/빈 상태/행 수 문구 |
|
|
2524
|
+
|
|
2525
|
+
#### ReportBuilder
|
|
2526
|
+
|
|
2527
|
+
**Import:** `import { ReportBuilder } from "@reopt-ai/opt-ui"`
|
|
2528
|
+
**Dependencies:** button (core), input (core)
|
|
2529
|
+
|
|
2530
|
+
| Prop | Type | Required | Default | Description |
|
|
2531
|
+
| ------------- | ------------------------------------------------------------------ | -------- | ------- | ----------------------------------- |
|
|
2532
|
+
| `chartTypes` | `ChartTypeDef[]` | | | 차트 타입 그리드 (기본 9종 제공) |
|
|
2533
|
+
| `dataSources` | `DataSourceDef[]` | | | 데이터 소스 드롭다운 옵션 |
|
|
2534
|
+
| `configForm` | `ReactNode` | | | 차트별 데이터 설정 폼 슬롯 (step 2) |
|
|
2535
|
+
| `styleForm` | `ReactNode` | | | 차트별 스타일 설정 폼 슬롯 (step 3) |
|
|
2536
|
+
| `preview` | `ReactNode` | | | 차트 미리보기 슬롯 (step 4) |
|
|
2537
|
+
| `onSave` | `(report: { name, description, chartType, dataSourceId }) => void` | | | 저장 콜백 |
|
|
2538
|
+
| `onCancel` | `() => void` | | | 취소 콜백 |
|
|
2539
|
+
| `labels` | `ReportBuilderLabels` | | | UI 텍스트 커스터마이징 |
|
|
2540
|
+
|
|
2541
|
+
#### InsightsPanel
|
|
2542
|
+
|
|
2543
|
+
**Import:** `import { InsightsPanel } from "@reopt-ai/opt-ui"`
|
|
2544
|
+
**Dependencies:** button (core), stat-card (core), badge (core)
|
|
2545
|
+
|
|
2546
|
+
| Prop | Type | Required | Default | Description |
|
|
2547
|
+
| ------------------------- | ----------------------------------- | -------- | ------- | -------------------------------------------------- |
|
|
2548
|
+
| `insights` | `InsightItem[]` | Yes | | 인사이트 항목 배열 |
|
|
2549
|
+
| `stats` | `InsightsStat[]` | | | 통계 필터 카드 배열 (클릭 가능) |
|
|
2550
|
+
| `detectionTypes` | `DetectionTypeDef[]` | | | 검출 유형 토글 배열 (volume_anomaly, new_event 등) |
|
|
2551
|
+
| `detectionConfig` | `DetectionConfig` | | | 검출 파라미터 (days, zScoreThreshold) |
|
|
2552
|
+
| `onDetectionConfigChange` | `(config: DetectionConfig) => void` | | | 검출 파라미터 변경 핸들러 |
|
|
2553
|
+
| `onDismiss` | `(id: string) => void` | | | 인사이트 dismiss 핸들러 |
|
|
2554
|
+
|
|
2555
|
+
#### TimeRangeSelector
|
|
2556
|
+
|
|
2557
|
+
**Import:** `import { TimeRangeSelector } from "@reopt-ai/opt-ui"`
|
|
2558
|
+
**Dependencies:** button (core), popover (core), date-range-picker (core)
|
|
2559
|
+
|
|
2560
|
+
| Prop | Type | Required | Default | Description |
|
|
2561
|
+
| ---------- | ---------------------------- | -------- | ------- | ------------------------------------ |
|
|
2562
|
+
| `value` | `DateRange` | | | 현재 선택된 날짜 범위 |
|
|
2563
|
+
| `onChange` | `(range: DateRange) => void` | | | 범위 변경 핸들러 |
|
|
2564
|
+
| `presets` | `TimePresetDef[]` | | | 빠른 프리셋 목록 (Today, Last 7d 등) |
|
|
2565
|
+
| `labels` | `TimeRangeSelectorLabels` | | | i18n용 라벨 오버라이드 |
|
|
2566
|
+
|
|
2567
|
+
#### ExportButton
|
|
2568
|
+
|
|
2569
|
+
**Import:** `import { ExportButton } from "@reopt-ai/opt-ui"`
|
|
2570
|
+
**Dependencies:** dropdown-menu (core), button (core)
|
|
2571
|
+
|
|
2572
|
+
| Prop | Type | Required | Default | Description |
|
|
2573
|
+
| ---------- | -------------------------------- | -------- | --------------- | ------------------------ |
|
|
2574
|
+
| `data` | `Record<string, unknown>[]` | Yes | | 내보낼 데이터 배열 |
|
|
2575
|
+
| `columns` | `ExportColumn[]` | | | 컬럼 매핑 (key → header) |
|
|
2576
|
+
| `fileName` | `string` | | "export" | 파일 이름 |
|
|
2577
|
+
| `formats` | `ExportFormat[]` | | ["csv", "json"] | 지원 포맷 |
|
|
2578
|
+
| `onExport` | `(format: ExportFormat) => void` | | | 커스텀 내보내기 핸들러 |
|
|
2579
|
+
|
|
2580
|
+
#### SummaryRow
|
|
2581
|
+
|
|
2582
|
+
**Import:** `import { SummaryRow } from "@reopt-ai/opt-ui"`
|
|
2583
|
+
**Dependencies:** stat-card (core), skeleton (core)
|
|
2584
|
+
|
|
2585
|
+
| Prop | Type | Required | Default | Description |
|
|
2586
|
+
| -------------------------- | -------------------------------- | -------- | ------- | -------------------------------- |
|
|
2587
|
+
| `stats` | `StatCardType[]` | Yes | | 통계 카드 배열 |
|
|
2588
|
+
| `columns` | `2 \| 3 \| 4` | | 4 | 컬럼 수 |
|
|
2589
|
+
| `onStatClick` | `(stat: StatCardType) => void` | | | 카드 클릭 핸들러 |
|
|
2590
|
+
| `formatValue` | `(stat: StatCardType) => string` | | | 값 표시 커스텀 포맷 함수 |
|
|
2591
|
+
| `durationFractionDigits` | `number` | | 1 | duration 포맷 시 소수점 자리수 |
|
|
2592
|
+
| `percentageFractionDigits` | `number` | | 1 | percentage 포맷 시 소수점 자리수 |
|
|
2593
|
+
| `loading` | `boolean` | | false | 로딩 시 스켈레톤 표시 |
|
|
2594
|
+
|
|
2595
|
+
#### ComparisonSelector
|
|
2596
|
+
|
|
2597
|
+
**Import:** `import { ComparisonSelector } from "@reopt-ai/opt-ui"`
|
|
2598
|
+
**Dependencies:** select (core), button (core)
|
|
2599
|
+
|
|
2600
|
+
| Prop | Type | Required | Default | Description |
|
|
2601
|
+
| ----------- | -------------------------- | -------- | ------- | ------------------------- |
|
|
2602
|
+
| `segments` | `ComparisonOption[]` | Yes | | 선택 가능한 세그먼트 목록 |
|
|
2603
|
+
| `valueA` | `string` | | | Base 선택값 |
|
|
2604
|
+
| `valueB` | `string` | | | Compare 선택값 |
|
|
2605
|
+
| `onChangeA` | `(value: string) => void` | | | Base 변경 핸들러 |
|
|
2606
|
+
| `onChangeB` | `(value: string) => void` | | | Compare 변경 핸들러 |
|
|
2607
|
+
| `labels` | `ComparisonSelectorLabels` | | | i18n용 라벨 오버라이드 |
|
|
2608
|
+
|
|
2609
|
+
#### ThemeSwitcher
|
|
2610
|
+
|
|
2611
|
+
**Import:** `import { ThemeSwitcher } from "@reopt-ai/opt-ui"`
|
|
2612
|
+
|
|
2613
|
+
| Prop | Type | Required | Default | Description |
|
|
2614
|
+
| -------- | --------------------- | -------- | ------- | ---------------------- |
|
|
2615
|
+
| `labels` | `ThemeSwitcherLabels` | | | i18n용 라벨 오버라이드 |
|
|
2616
|
+
|
|
2617
|
+
#### PromptTemplate
|
|
2618
|
+
|
|
2619
|
+
**Import:** `import { PromptTemplate } from "@reopt-ai/opt-ui"`
|
|
2620
|
+
**Dependencies:** input (core)
|
|
2621
|
+
|
|
2622
|
+
| Prop | Type | Required | Default | Description |
|
|
2623
|
+
| ------------- | ---------------------- | -------- | ------- | ------------------------------------------------------------ |
|
|
2624
|
+
| `title` | `string` | Yes | | 프롬프트 제목 |
|
|
2625
|
+
| `description` | `string` | | | 프롬프트 설명 (헤더 아래 표시) |
|
|
2626
|
+
| `template` | `string` | Yes | | 프롬프트 템플릿. {변수명}으로 치환 가능 |
|
|
2627
|
+
| `variables` | `PromptVariable[]` | | | 변수 정의 배열. { name, label, placeholder?, defaultValue? } |
|
|
2628
|
+
| `labels` | `PromptTemplateLabels` | | | i18n용 라벨 오버라이드 |
|
|
2629
|
+
|
|
2630
|
+
#### Sidebar
|
|
2631
|
+
|
|
2632
|
+
**Import:** `import { Sidebar } from "@reopt-ai/opt-ui"`
|
|
2633
|
+
**Dependencies:** sidebar-nav (shells)
|
|
2634
|
+
|
|
2635
|
+
**Sidebar:**
|
|
2636
|
+
|
|
2637
|
+
| Prop | Type | Required | Default | Description |
|
|
2638
|
+
| ------------------- | ------------------------------ | -------- | ---------- | --------------------------------------------------------- |
|
|
2639
|
+
| `children` | `ReactNode` | Yes | | Sidebar.Header, Sidebar.Content, Sidebar.Footer 자식 요소 |
|
|
2640
|
+
| `collapsible` | `boolean` | | false | 접기/펼치기 토글 지원 |
|
|
2641
|
+
| `defaultCollapsed` | `boolean` | | false | 초기 접힘 상태 |
|
|
2642
|
+
| `collapsed` | `boolean` | | | 제어 모드: 접힘 상태 |
|
|
2643
|
+
| `onCollapsedChange` | `(collapsed: boolean) => void` | | | 제어 모드: 접힘 상태 변경 핸들러 |
|
|
2644
|
+
| `width` | `number` | | 280 | 펼침 상태 너비 (px) |
|
|
2645
|
+
| `collapsedWidth` | `number` | | 56 | 접힘 상태 너비 (px) |
|
|
2646
|
+
| `side` | `"left" \| "right"` | | "left" | 사이드바 위치 |
|
|
2647
|
+
| `label` | `string` | | "사이드바" | aside aria-label |
|
|
2648
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2649
|
+
|
|
2650
|
+
**Sidebar.Group:**
|
|
2651
|
+
|
|
2652
|
+
| Prop | Type | Required | Default | Description |
|
|
2653
|
+
| ----------- | ----------- | -------- | ------- | ---------------------------------- |
|
|
2654
|
+
| `children` | `ReactNode` | Yes | | Sidebar.Item 요소들 |
|
|
2655
|
+
| `label` | `string` | | | 그룹 레이블 (접힌 상태에서 숨겨짐) |
|
|
2656
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2657
|
+
|
|
2658
|
+
**Sidebar.Item:**
|
|
2659
|
+
|
|
2660
|
+
| Prop | Type | Required | Default | Description |
|
|
2661
|
+
| ----------- | ------------ | -------- | ------- | ------------------------------------------------------------- |
|
|
2662
|
+
| `children` | `ReactNode` | Yes | | 항목 레이블 텍스트 |
|
|
2663
|
+
| `icon` | `ReactNode` | | | 아이콘 (접힌 상태에서도 표시) |
|
|
2664
|
+
| `active` | `boolean` | | false | 활성 상태 (aria-current=page) |
|
|
2665
|
+
| `onClick` | `() => void` | | | 클릭 핸들러 |
|
|
2666
|
+
| `href` | `string` | | | 링크 URL — 설정 시 <a> 태그로 렌더링 |
|
|
2667
|
+
| `tooltip` | `string` | | | 접힌 상태에서 Tooltip 표시 (미지정 시 children 텍스트) |
|
|
2668
|
+
| `badge` | `ReactNode` | | | 우측 배지 (숫자/텍스트). 접힌 상태에서 아이콘 위 dot으로 축소 |
|
|
2669
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2670
|
+
|
|
2671
|
+
#### AppShell
|
|
2672
|
+
|
|
2673
|
+
**Import:** `import { AppShell } from "@reopt-ai/opt-ui"`
|
|
2674
|
+
**Dependencies:** sidebar (shells), page-header (core)
|
|
2675
|
+
|
|
2676
|
+
| Prop | Type | Required | Default | Description |
|
|
2677
|
+
| ----------- | ----------- | -------- | ------- | ------------------------------------------------------------------------------ |
|
|
2678
|
+
| `children` | `ReactNode` | Yes | | AppShell.Header, AppShell.Sidebar, AppShell.Content, AppShell.Footer 자식 요소 |
|
|
2679
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2680
|
+
|
|
2681
|
+
**Examples:**
|
|
2682
|
+
|
|
2683
|
+
_앱 레이아웃:_
|
|
2684
|
+
|
|
2685
|
+
```tsx
|
|
2686
|
+
import { AppShell } from "@reopt-ai/opt-ui";
|
|
2687
|
+
|
|
2688
|
+
<AppShell>
|
|
2689
|
+
<AppShell.Header>헤더 영역</AppShell.Header>
|
|
2690
|
+
<AppShell.Sidebar>사이드바 영역</AppShell.Sidebar>
|
|
2691
|
+
<AppShell.Content>메인 콘텐츠</AppShell.Content>
|
|
2692
|
+
</AppShell>;
|
|
2693
|
+
```
|
|
2694
|
+
|
|
2695
|
+
#### ConfirmDialog
|
|
2696
|
+
|
|
2697
|
+
**Import:** `import { ConfirmDialog } from "@reopt-ai/opt-ui"`
|
|
2698
|
+
**Dependencies:** dialog (core)
|
|
2699
|
+
|
|
2700
|
+
| Prop | Type | Required | Default | Description |
|
|
2701
|
+
| -------------- | ----------------------- | -------- | --------- | ---------------- |
|
|
2702
|
+
| `open` | `boolean` | Yes | | 열림 상태 |
|
|
2703
|
+
| `onConfirm` | `() => void` | Yes | | 확인 콜백 |
|
|
2704
|
+
| `onCancel` | `() => void` | Yes | | 취소 콜백 |
|
|
2705
|
+
| `title` | `string` | Yes | | 대화 상자 제목 |
|
|
2706
|
+
| `description` | `string` | | | 설명 텍스트 |
|
|
2707
|
+
| `confirmLabel` | `string` | | "Confirm" | 확인 버튼 텍스트 |
|
|
2708
|
+
| `cancelLabel` | `string` | | "Cancel" | 취소 버튼 텍스트 |
|
|
2709
|
+
| `variant` | `"default" \| "danger"` | | "default" | 변형 |
|
|
2710
|
+
|
|
2711
|
+
#### AsyncCombobox
|
|
2712
|
+
|
|
2713
|
+
**Import:** `import { AsyncCombobox } from "@reopt-ai/opt-ui"`
|
|
2714
|
+
**Dependencies:** combobox (core), spinner (core)
|
|
2715
|
+
|
|
2716
|
+
| Prop | Type | Required | Default | Description |
|
|
2717
|
+
| ------------- | ---------------------------------- | -------- | --------- | ---------------------------------------- |
|
|
2718
|
+
| `onSearch` | `(q: string) => Promise<string[]>` | Yes | | 검색 콜백 |
|
|
2719
|
+
| `debounceMs` | `number` | | 300 | 디바운스 ms |
|
|
2720
|
+
| `minChars` | `number` | | 1 | 최소 검색 글자 수 |
|
|
2721
|
+
| `placeholder` | `string` | | "Search…" | 플레이스홀더 |
|
|
2722
|
+
| `onSelect` | `(value: string) => void` | | | 선택 콜백 |
|
|
2723
|
+
| `labels` | `AsyncComboboxLabels` | | | input/loading/noResults/placeholder 문구 |
|
|
2724
|
+
| `loadingText` | `string` | | | 로딩 문구. labels.loading 사용 권장 |
|
|
2725
|
+
|
|
2726
|
+
#### VerticalTabs
|
|
2727
|
+
|
|
2728
|
+
**Import:** `import { VerticalTabs } from "@reopt-ai/opt-ui"`
|
|
2729
|
+
**Dependencies:** tabs (core)
|
|
2730
|
+
|
|
2731
|
+
| Prop | Type | Required | Default | Description |
|
|
2732
|
+
| -------------- | ---------- | -------- | ------- | ----------------- |
|
|
2733
|
+
| `tabs` | `TabDef[]` | Yes | | 탭 정의 배열 |
|
|
2734
|
+
| `defaultTabId` | `string` | | | 기본 선택 탭 ID |
|
|
2735
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2736
|
+
|
|
2737
|
+
#### ColumnToggler
|
|
2738
|
+
|
|
2739
|
+
**Import:** `import { ColumnToggler } from "@reopt-ai/opt-ui"`
|
|
2740
|
+
**Dependencies:** popover (core), checkbox (core)
|
|
2741
|
+
|
|
2742
|
+
| Prop | Type | Required | Default | Description |
|
|
2743
|
+
| ---------------- | ------------------------------------ | -------- | ------- | ---------------------- |
|
|
2744
|
+
| `columns` | `ColumnTogglerColumn[]` | Yes | | 전체 컬럼 목록 |
|
|
2745
|
+
| `visibleColumns` | `string[]` | Yes | | 표시 중인 컬럼 ID 배열 |
|
|
2746
|
+
| `onChange` | `(visibleColumns: string[]) => void` | Yes | | 변경 콜백 |
|
|
2747
|
+
|
|
2748
|
+
#### TreeTable
|
|
2749
|
+
|
|
2750
|
+
**Import:** `import { TreeTable } from "@reopt-ai/opt-ui"`
|
|
2751
|
+
**Dependencies:** data-table (shells)
|
|
2752
|
+
|
|
2753
|
+
| Prop | Type | Required | Default | Description |
|
|
2754
|
+
| ----------------- | -------------------- | -------- | ------- | ------------------ |
|
|
2755
|
+
| `data` | `TreeNode<T>[]` | Yes | | 트리 노드 배열 |
|
|
2756
|
+
| `columns` | `TreeColumnDef<T>[]` | Yes | | 컬럼 정의 |
|
|
2757
|
+
| `defaultExpanded` | `string[]` | | [] | 기본 펼침 노드 ID |
|
|
2758
|
+
| `indentSize` | `number` | | 24 | 들여쓰기 크기 (px) |
|
|
2759
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2760
|
+
|
|
2761
|
+
#### InlineEditTable
|
|
2762
|
+
|
|
2763
|
+
**Import:** `import { InlineEditTable } from "@reopt-ai/opt-ui"`
|
|
2764
|
+
**Dependencies:** data-table (shells)
|
|
2765
|
+
|
|
2766
|
+
| Prop | Type | Required | Default | Description |
|
|
2767
|
+
| -------------- | ---------------------------------------------------------- | -------- | ------- | -------------------------------- |
|
|
2768
|
+
| `data` | `T[]` | Yes | | 행 데이터 배열 |
|
|
2769
|
+
| `columns` | `InlineEditColumnDef<T>[]` | Yes | | 컬럼 정의 (editable 플래그 포함) |
|
|
2770
|
+
| `keyExtractor` | `(row: T) => string` | Yes | | 행 키 추출기 |
|
|
2771
|
+
| `onCellEdit` | `(rowId: string, columnId: string, value: string) => void` | | | 셀 편집 확정 콜백 |
|
|
2772
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2773
|
+
|
|
2774
|
+
#### KanbanBoard
|
|
2775
|
+
|
|
2776
|
+
**Import:** `import { KanbanBoard } from "@reopt-ai/opt-ui"`
|
|
2777
|
+
**Dependencies:** scroll-area (core)
|
|
2778
|
+
|
|
2779
|
+
| Prop | Type | Required | Default | Description |
|
|
2780
|
+
| -------------- | ------------------------------------------- | -------- | ------- | -------------------------------- |
|
|
2781
|
+
| `columns` | `KanbanColumn<T>[]` | Yes | | 컬럼 목록 (각 컬럼에 items 배열) |
|
|
2782
|
+
| `onDragEnd` | `(itemId, fromCol, toCol, toIndex) => void` | Yes | | 드래그 완료 콜백 |
|
|
2783
|
+
| `renderCard` | `(item: T) => ReactNode` | Yes | | 카드 렌더링 함수 |
|
|
2784
|
+
| `keyExtractor` | `(item: T) => string` | Yes | | 항목 키 추출기 |
|
|
2785
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2786
|
+
|
|
2787
|
+
#### RichTextEditor
|
|
2788
|
+
|
|
2789
|
+
**Import:** `import { RichTextEditor } from "@reopt-ai/opt-ui"`
|
|
2790
|
+
|
|
2791
|
+
| Prop | Type | Required | Default | Description |
|
|
2792
|
+
| ------------- | ------------------------- | -------- | -------------------------------------------------------- | ----------------- |
|
|
2793
|
+
| `value` | `string` | Yes | | 텍스트 값 |
|
|
2794
|
+
| `onChange` | `(value: string) => void` | Yes | | 변경 콜백 |
|
|
2795
|
+
| `placeholder` | `string` | | "Write something…" | 플레이스홀더 |
|
|
2796
|
+
| `toolbar` | `ToolbarAction[]` | | ["bold","italic","code","link","heading","list","quote"] | 툴바 액션 목록 |
|
|
2797
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2798
|
+
|
|
2799
|
+
#### CodeDiffViewer
|
|
2800
|
+
|
|
2801
|
+
**Import:** `import { CodeDiffViewer } from "@reopt-ai/opt-ui"`
|
|
2802
|
+
|
|
2803
|
+
| Prop | Type | Required | Default | Description |
|
|
2804
|
+
| ----------------- | ---------------------- | -------- | --------- | --------------------------------------- |
|
|
2805
|
+
| `original` | `string` | Yes | | 원본 코드 |
|
|
2806
|
+
| `modified` | `string` | Yes | | 수정된 코드 |
|
|
2807
|
+
| `mode` | `"split" \| "unified"` | | "unified" | 뷰 모드 |
|
|
2808
|
+
| `showLineNumbers` | `boolean` | | true | 줄 번호 표시 |
|
|
2809
|
+
| `scrollLabel` | `string` | | | 스크롤 가능한 diff 영역의 접근성 레이블 |
|
|
2810
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2811
|
+
|
|
2812
|
+
#### WebhookConfig
|
|
2813
|
+
|
|
2814
|
+
**Import:** `import { WebhookConfig } from "@reopt-ai/opt-ui"`
|
|
2815
|
+
**Dependencies:** input (core), checkbox (core), number-input (core), button (core)
|
|
2816
|
+
|
|
2817
|
+
| Prop | Type | Required | Default | Description |
|
|
2818
|
+
| ----------------- | ------------------------------- | -------- | ------- | ----------------------- |
|
|
2819
|
+
| `webhook` | `WebhookDef` | Yes | | 웹훅 설정 객체 |
|
|
2820
|
+
| `onChange` | `(webhook: WebhookDef) => void` | Yes | | 변경 콜백 |
|
|
2821
|
+
| `availableEvents` | `string[]` | Yes | | 선택 가능한 이벤트 목록 |
|
|
2822
|
+
| `onTest` | `() => void` | | | 테스트 버튼 콜백 |
|
|
2823
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2824
|
+
|
|
2825
|
+
#### FeatureFlagPanel
|
|
2826
|
+
|
|
2827
|
+
**Import:** `import { FeatureFlagPanel } from "@reopt-ai/opt-ui"`
|
|
2828
|
+
**Dependencies:** switch (core), badge (core), number-input (core)
|
|
2829
|
+
|
|
2830
|
+
| Prop | Type | Required | Default | Description |
|
|
2831
|
+
| ----------------- | ---------------------------------------------- | -------- | ------- | ------------------ |
|
|
2832
|
+
| `flags` | `FeatureFlag[]` | Yes | | 피처 플래그 목록 |
|
|
2833
|
+
| `onToggle` | `(flagId: string, enabled: boolean) => void` | Yes | | 토글 콜백 |
|
|
2834
|
+
| `onRolloutChange` | `(flagId: string, percentage: number) => void` | | | 롤아웃 % 변경 콜백 |
|
|
2835
|
+
| `environments` | `string[]` | Yes | | 전체 환경 목록 |
|
|
2836
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2837
|
+
|
|
2838
|
+
#### DataImportWizard
|
|
2839
|
+
|
|
2840
|
+
**Import:** `import { DataImportWizard } from "@reopt-ai/opt-ui"`
|
|
2841
|
+
**Dependencies:** button (core)
|
|
2842
|
+
|
|
2843
|
+
| Prop | Type | Required | Default | Description |
|
|
2844
|
+
| ----------------- | ------------------------- | -------- | ------- | ------------------- |
|
|
2845
|
+
| `fields` | `ImportFieldDef[]` | Yes | | 매핑 대상 필드 목록 |
|
|
2846
|
+
| `onImport` | `(mapping, data) => void` | Yes | | 임포트 확정 콜백 |
|
|
2847
|
+
| `acceptedFormats` | `string` | | ".csv" | 허용 파일 형식 |
|
|
2848
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2849
|
+
|
|
2850
|
+
#### MegaMenu
|
|
2851
|
+
|
|
2852
|
+
**Import:** `import { MegaMenu } from "@reopt-ai/opt-ui"`
|
|
2853
|
+
**Dependencies:** popover (core)
|
|
2854
|
+
|
|
2855
|
+
| Prop | Type | Required | Default | Description |
|
|
2856
|
+
| -------------- | ------------------- | -------- | ------- | ------------------ |
|
|
2857
|
+
| `menus` | `MegaMenuSection[]` | Yes | | 메뉴 섹션 배열 |
|
|
2858
|
+
| `columns` | `number` | | 3 | 그리드 컬럼 수 |
|
|
2859
|
+
| `footer` | `ReactNode` | | | 하단 footer 슬롯 |
|
|
2860
|
+
| `triggerLabel` | `string` | | "Menu" | 트리거 버튼 텍스트 |
|
|
2861
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2862
|
+
|
|
2863
|
+
#### BulkActions
|
|
2864
|
+
|
|
2865
|
+
**Import:** `import { BulkActions } from "@reopt-ai/opt-ui"`
|
|
2866
|
+
**Dependencies:** dropdown-menu (core), badge (core)
|
|
2867
|
+
|
|
2868
|
+
| Prop | Type | Required | Default | Description |
|
|
2869
|
+
| --------------- | ---------------------------- | -------- | ------- | -------------------------------------------- |
|
|
2870
|
+
| `selectedCount` | `number` | Yes | | 선택된 항목 수 |
|
|
2871
|
+
| `actions` | `BulkActionDef[]` | Yes | | 액션 목록. { id, label, variant?: "danger" } |
|
|
2872
|
+
| `onAction` | `(actionId: string) => void` | Yes | | 액션 실행 콜백 |
|
|
2873
|
+
| `onClear` | `() => void` | Yes | | 선택 해제 콜백 |
|
|
2874
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2875
|
+
|
|
2876
|
+
#### SavedFilters
|
|
2877
|
+
|
|
2878
|
+
**Import:** `import { SavedFilters } from "@reopt-ai/opt-ui"`
|
|
2879
|
+
**Dependencies:** popover (core), input (core)
|
|
2880
|
+
|
|
2881
|
+
| Prop | Type | Required | Default | Description |
|
|
2882
|
+
| ---------------- | ---------------------------------------------------------- | -------- | ------- | -------------------- |
|
|
2883
|
+
| `currentFilters` | `Record<string, unknown>` | Yes | | 현재 적용 중인 필터 |
|
|
2884
|
+
| `presets` | `FilterPreset[]` | Yes | | 저장된 프리셋 목록 |
|
|
2885
|
+
| `onSavePreset` | `(name: string, filters: Record<string, unknown>) => void` | Yes | | 프리셋 저장 콜백 |
|
|
2886
|
+
| `onLoadPreset` | `(preset: FilterPreset) => void` | Yes | | 프리셋 불러오기 콜백 |
|
|
2887
|
+
| `onDeletePreset` | `(presetId: string) => void` | Yes | | 프리셋 삭제 콜백 |
|
|
2888
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2889
|
+
|
|
2890
|
+
#### NotificationCenter
|
|
2891
|
+
|
|
2892
|
+
**Import:** `import { NotificationCenter } from "@reopt-ai/opt-ui"`
|
|
2893
|
+
**Dependencies:** popover (core), badge (core), scroll-area (core)
|
|
2894
|
+
|
|
2895
|
+
| Prop | Type | Required | Default | Description |
|
|
2896
|
+
| --------------- | ---------------------- | -------- | ------- | ------------------- |
|
|
2897
|
+
| `notifications` | `NotificationItem[]` | Yes | | 알림 목록 |
|
|
2898
|
+
| `onMarkRead` | `(id: string) => void` | Yes | | 읽음 처리 콜백 |
|
|
2899
|
+
| `onMarkAllRead` | `() => void` | Yes | | 전체 읽음 처리 콜백 |
|
|
2900
|
+
| `onAction` | `(id: string) => void` | | | 알림 액션 콜백 |
|
|
2901
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2902
|
+
|
|
2903
|
+
#### AuditLog
|
|
2904
|
+
|
|
2905
|
+
**Import:** `import { AuditLog } from "@reopt-ai/opt-ui"`
|
|
2906
|
+
**Dependencies:** avatar (core), badge (core)
|
|
2907
|
+
|
|
2908
|
+
| Prop | Type | Required | Default | Description |
|
|
2909
|
+
| ------------ | -------------- | -------- | ------- | ------------------- |
|
|
2910
|
+
| `entries` | `AuditEntry[]` | Yes | | 감사 로그 항목 배열 |
|
|
2911
|
+
| `onLoadMore` | `() => void` | | | 더 보기 콜백 |
|
|
2912
|
+
| `loading` | `boolean` | | false | 로딩 상태 |
|
|
2913
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2914
|
+
|
|
2915
|
+
#### AuditTimeline
|
|
2916
|
+
|
|
2917
|
+
**Import:** `import { AuditTimeline } from "@reopt-ai/opt-ui"`
|
|
2918
|
+
**Dependencies:** badge (core), button (core), empty-state (core)
|
|
2919
|
+
|
|
2920
|
+
| Prop | Type | Required | Default | Description |
|
|
2921
|
+
| -------------- | ----------------------------- | -------- | ------- | ---------------------- |
|
|
2922
|
+
| `entries` | `AuditEntry[]` | Yes | | 변경 이력 항목 배열 |
|
|
2923
|
+
| `labels` | `AuditTimelineLabels` | | | UI 텍스트 커스터마이징 |
|
|
2924
|
+
| `onEntryClick` | `(entry: AuditEntry) => void` | | | 항목 클릭 콜백 |
|
|
2925
|
+
| `className` | `string` | | | 커스텀 CSS 클래스 |
|
|
2926
|
+
|
|
2927
|
+
#### ChatSidebar
|
|
2928
|
+
|
|
2929
|
+
**Import:** `import { ChatSidebar } from "@reopt-ai/opt-ui"`
|
|
2930
|
+
**Dependencies:** button (core), input (core), scroll-area (core), empty-state (core)
|
|
2931
|
+
|
|
2932
|
+
| Prop | Type | Required | Default | Description |
|
|
2933
|
+
| ---------------------- | --------------------------------------------- | -------- | ------- | --------------------------------------------------------------- |
|
|
2934
|
+
| `conversations` | `ChatConversationDef[]` | Yes | | 대화 목록 배열. { id, title, lastMessage?, timestamp, unread? } |
|
|
2935
|
+
| `activeConversationId` | `string` | | | 현재 활성 대화 ID |
|
|
2936
|
+
| `onConversationSelect` | `(conversation: ChatConversationDef) => void` | | | 대화 선택 핸들러 |
|
|
2937
|
+
| `onNewChat` | `() => void` | | | 새 대화 생성 핸들러 |
|
|
2938
|
+
| `onSearch` | `(query: string) => void` | | | 검색 핸들러 |
|
|
2939
|
+
| `labels` | `ChatSidebarLabels` | | | i18n 라벨 오버라이드 |
|
|
2940
|
+
|
|
2941
|
+
#### ChatInput
|
|
2942
|
+
|
|
2943
|
+
**Import:** `import { ChatInput } from "@reopt-ai/opt-ui"`
|
|
2944
|
+
**Dependencies:** button (core), kbd (core), select (core)
|
|
2945
|
+
|
|
2946
|
+
| Prop | Type | Required | Default | Description |
|
|
2947
|
+
| -------------- | --------------------------- | -------- | ------- | -------------------------- |
|
|
2948
|
+
| `value` | `string` | | | 제어 모드: 입력 값 |
|
|
2949
|
+
| `onSend` | `(message: string) => void` | | | 메시지 전송 핸들러 |
|
|
2950
|
+
| `onFileAttach` | `() => void` | | | 파일 첨부 클릭 핸들러 |
|
|
2951
|
+
| `models` | `ChatModelDef[]` | | | 모델 선택 옵션 |
|
|
2952
|
+
| `stylePresets` | `ChatStylePresetDef[]` | | | 스타일 프리셋 옵션 |
|
|
2953
|
+
| `maxRows` | `number` | | 6 | textarea 최대 행 수 |
|
|
2954
|
+
| `showHint` | `boolean` | | true | Shift+Enter 힌트 표시 여부 |
|
|
2955
|
+
| `labels` | `ChatInputLabels` | | | i18n 라벨 오버라이드 |
|
|
2956
|
+
|
|
2957
|
+
**Examples:**
|
|
2958
|
+
|
|
2959
|
+
_채팅 입력:_
|
|
2960
|
+
|
|
2961
|
+
```tsx
|
|
2962
|
+
import { ChatInput } from "@reopt-ai/opt-ui";
|
|
2963
|
+
|
|
2964
|
+
<ChatInput
|
|
2965
|
+
placeholder="메시지를 입력하세요..."
|
|
2966
|
+
onSend={(message) => console.log(message)}
|
|
2967
|
+
/>;
|
|
2968
|
+
```
|
|
2969
|
+
|
|
2970
|
+
#### ChatMessageList
|
|
2971
|
+
|
|
2972
|
+
**Import:** `import { ChatMessageList } from "@reopt-ai/opt-ui"`
|
|
2973
|
+
**Dependencies:** scroll-area (core), avatar (core), empty-state (core)
|
|
2974
|
+
|
|
2975
|
+
| Prop | Type | Required | Default | Description |
|
|
2976
|
+
| ----------------- | ---------------------------------------- | -------- | ------- | --------------------------------------------- |
|
|
2977
|
+
| `messages` | `ChatMessageDef[]` | Yes | | 메시지 배열. { id, role, content, timestamp } |
|
|
2978
|
+
| `loading` | `boolean` | | false | 타이핑 인디케이터 표시 |
|
|
2979
|
+
| `renderContent` | `(message: ChatMessageDef) => ReactNode` | | | 커스텀 메시지 렌더러. 기본: plain text |
|
|
2980
|
+
| `assistantAvatar` | `string` | | | 어시스턴트 아바타 이미지 URL |
|
|
2981
|
+
| `showTimestamps` | `boolean` | | true | 타임스탬프 표시 여부 |
|
|
2982
|
+
| `autoScroll` | `boolean` | | true | 새 메시지 시 자동 스크롤 |
|
|
2983
|
+
| `labels` | `ChatMessageListLabels` | | | i18n 라벨 오버라이드 |
|
|
2984
|
+
|
|
2985
|
+
**Examples:**
|
|
2986
|
+
|
|
2987
|
+
_메시지 목록:_
|
|
2988
|
+
|
|
2989
|
+
```tsx
|
|
2990
|
+
import { ChatMessageList } from "@reopt-ai/opt-ui";
|
|
2991
|
+
|
|
2992
|
+
const messages = [
|
|
2993
|
+
{ id: "1", role: "user", content: "안녕하세요!", timestamp: new Date() },
|
|
2994
|
+
{ id: "2", role: "assistant", content: "반갑습니다.", timestamp: new Date() },
|
|
2995
|
+
];
|
|
2996
|
+
|
|
2997
|
+
<ChatMessageList messages={messages} loading={false} />;
|
|
2998
|
+
```
|
|
2999
|
+
|
|
3000
|
+
### Surface Layer
|