dashboardity 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -0
- package/dist/index.d.mts +383 -0
- package/dist/index.d.ts +383 -0
- package/dist/index.js +1007 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +966 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Dashboardity
|
|
2
|
+
|
|
3
|
+
Grafana 스타일 대시보드: **대시보드 엔진 + 위젯 라이브러리 + 앱 쉘 + 데모 앱** 구조.
|
|
4
|
+
|
|
5
|
+
## 구조
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
├── src/ # 라이브러리 소스
|
|
9
|
+
│ ├── core/ # 대시보드 엔진 (레이아웃, 스펙 해석, JSON → 렌더링)
|
|
10
|
+
│ ├── widget-wrapper/ # Widget 공통 래퍼 (header, padding, error, empty)
|
|
11
|
+
│ ├── app-shell/ # TopBar, SideNav, DashboardPicker, TimeRangePicker
|
|
12
|
+
│ ├── data-adapter/ # API → 위젯 입력 포맷 변환
|
|
13
|
+
│ └── shared/ # types, utils, theme
|
|
14
|
+
├── examples/
|
|
15
|
+
│ └── playground/ # 위젯/대시보드 테스트용 앱
|
|
16
|
+
└── package.json
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 위젯 (사용자 정의)
|
|
20
|
+
|
|
21
|
+
**기본 위젯은 내장하지 않습니다.** `WidgetDefinition` / `WidgetProps` 타입에 맞춰 위젯을 만들고 `createWidgetRegistry`로 등록해 사용합니다.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { createWidgetRegistry, type WidgetDefinition } from "dashboardity";
|
|
25
|
+
|
|
26
|
+
// 자체 위젯 정의 후
|
|
27
|
+
const widgetRegistry = createWidgetRegistry({
|
|
28
|
+
stat: MyStatWidget,
|
|
29
|
+
text: MyTextWidget,
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## App shell / 커스텀 픽커
|
|
34
|
+
|
|
35
|
+
`TopBar`에 `dashboardPicker`, `timeRangePicker` 슬롯이 있습니다. 기본 제공 컴포넌트를 쓰거나, **자기 걸** 넣을 수 있습니다.
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { TopBar, DashboardPicker, TimeRangePicker } from "dashboardity";
|
|
39
|
+
|
|
40
|
+
// 기본 픽커 사용
|
|
41
|
+
<TopBar
|
|
42
|
+
title="My App"
|
|
43
|
+
dashboardPicker={<DashboardPicker options={...} value={...} onChange={...} />}
|
|
44
|
+
timeRangePicker={<TimeRangePicker value={...} onChange={...} />}
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
// 커스텀 픽커 사용 (같은 props 타입 사용 가능: DashboardPickerProps, TimeRangePickerProps)
|
|
48
|
+
<TopBar
|
|
49
|
+
title="My App"
|
|
50
|
+
dashboardPicker={<MyDashboardPicker ... />}
|
|
51
|
+
timeRangePicker={<MyTimeRangePicker ... />}
|
|
52
|
+
/>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`dashboardPicker` / `timeRangePicker`를 넘기지 않으면 해당 슬롯은 비고, `children`으로만 우측 영역을 채울 수 있습니다.
|
|
56
|
+
|
|
57
|
+
## 시작하기
|
|
58
|
+
|
|
59
|
+
### 요구 사항
|
|
60
|
+
|
|
61
|
+
- Node 18+
|
|
62
|
+
|
|
63
|
+
### 의존성 (외부)
|
|
64
|
+
|
|
65
|
+
- `@dashboardity/layout-core`, `@dashboardity/layout-store`, `react-griditty` — npm `^1.0.0` 사용.
|
|
66
|
+
|
|
67
|
+
**로컬 개발만 할 때:** npm에 아직 안 올렸다면 `npm overrides` 또는 로컬 `file:` 로 임시 지정 가능.
|
|
68
|
+
|
|
69
|
+
### 설치 및 실행
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install
|
|
73
|
+
npm run build # 라이브러리 빌드
|
|
74
|
+
npm run example # playground 앱 실행
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 스크립트
|
|
78
|
+
|
|
79
|
+
- `npm run build` — 라이브러리 빌드 (tsup)
|
|
80
|
+
- `npm run dev` — 라이브러리 watch 빌드
|
|
81
|
+
- `npm run example` — playground 앱 실행 (Vite)
|
|
82
|
+
- `npm run clean` — dist 삭제
|
|
83
|
+
|
|
84
|
+
### npm install 오류 시 (`Cannot read properties of null (reading 'matches')`)
|
|
85
|
+
|
|
86
|
+
이전에 pnpm을 쓰던 폴더이거나 캐시 문제일 수 있습니다. **프로젝트 루트**에서 순서대로 시도하세요.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# 1) node_modules·lock 삭제
|
|
90
|
+
rmdir /s /q node_modules
|
|
91
|
+
del package-lock.json
|
|
92
|
+
|
|
93
|
+
# 2) npm 캐시 정리
|
|
94
|
+
npm cache clean --force
|
|
95
|
+
|
|
96
|
+
# 3) npm 최신으로 업데이트 (선택)
|
|
97
|
+
npm install -g npm@latest
|
|
98
|
+
|
|
99
|
+
# 4) 다시 설치
|
|
100
|
+
npm install
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
PowerShell: `node_modules` 삭제는 `Remove-Item -Recurse -Force node_modules`, lock 삭제는 `Remove-Item package-lock.json -ErrorAction SilentlyContinue`
|
|
104
|
+
|
|
105
|
+
## 배포 (npm + Git)
|
|
106
|
+
|
|
107
|
+
1. **Git**
|
|
108
|
+
- `package.json`의 `repository.url`에 실제 저장소 URL 넣기 (예: `"url": "https://github.com/사용자/react-dashitty.git"`).
|
|
109
|
+
- `git add .` → `git commit` → `git remote add origin ...` → `git push -u origin main` (또는 기본 브랜치 이름).
|
|
110
|
+
|
|
111
|
+
2. **npm**
|
|
112
|
+
- [npmjs.com](https://www.npmjs.com) 로그인: 터미널에서 `npm login`.
|
|
113
|
+
- 패키지 이름이 이미 쓰였으면 `package.json`의 `name`을 바꾸거나 스코프 사용 (예: `@내계정/dashboardity`).
|
|
114
|
+
- `npm run build` 후 `npm publish`. (`prepublishOnly`로 publish 시 자동 빌드됨.)
|
|
115
|
+
- 비공개 패키지가 아니면 스코프 패키지 첫 배포 시: `npm publish --access public`.
|
|
116
|
+
|
|
117
|
+
`dist/`는 `.gitignore`에 있어서 Git에는 안 올라가고, `npm publish` 시에만 `files: ["dist"]`로 포함됩니다.
|
|
118
|
+
|
|
119
|
+
## 스펙 → 렌더링
|
|
120
|
+
|
|
121
|
+
대시보드는 JSON 스펙으로 정의됩니다.
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
DashboardSpec
|
|
125
|
+
└─ panels[]
|
|
126
|
+
└─ widgets[] // type + options + dataSourceId
|
|
127
|
+
layout.items[] // grid 좌표 (layout-store)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Grid 계산은 `@dashboardity/layout-core` / `@dashboardity/layout-store`를 사용하며, 위젯은 width/height만 신경 쓰면 됩니다.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { LayoutStore } from '@dashboardity/layout-store';
|
|
2
|
+
export { LayoutState, LayoutStore, createLayoutStore } from '@dashboardity/layout-store';
|
|
3
|
+
import React$1, { CSSProperties, ReactNode } from 'react';
|
|
4
|
+
import { GridItem } from '@dashboardity/layout-core';
|
|
5
|
+
export { GridItem, LayoutAction } from '@dashboardity/layout-core';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 위젯 공통 props.
|
|
9
|
+
* data + options만 받아 독립적으로 렌더링.
|
|
10
|
+
*/
|
|
11
|
+
type WidgetProps<T = unknown> = {
|
|
12
|
+
data: T;
|
|
13
|
+
options?: Record<string, unknown>;
|
|
14
|
+
/** 루트 요소에 적용. 유저가 PanelConfig.widgetClassName 등으로 전달 가능 */
|
|
15
|
+
className?: string;
|
|
16
|
+
};
|
|
17
|
+
/** Registry에 등록 가능한 위젯. data는 런타임에 전달되므로 any로 수용 */
|
|
18
|
+
type WidgetComponent = React.FC<WidgetProps<any>>;
|
|
19
|
+
/** 위젯 옵션 필드 스키마 (플러그인 시스템). Editor 자동 생성용 */
|
|
20
|
+
type WidgetOptionSchemaField = {
|
|
21
|
+
type: "string";
|
|
22
|
+
label: string;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: "number";
|
|
26
|
+
label: string;
|
|
27
|
+
min?: number;
|
|
28
|
+
max?: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: "boolean";
|
|
31
|
+
label: string;
|
|
32
|
+
} | {
|
|
33
|
+
type: "select";
|
|
34
|
+
label: string;
|
|
35
|
+
options: {
|
|
36
|
+
value: string;
|
|
37
|
+
label: string;
|
|
38
|
+
}[];
|
|
39
|
+
} | {
|
|
40
|
+
type: "color";
|
|
41
|
+
label: string;
|
|
42
|
+
};
|
|
43
|
+
type WidgetOptionSchema = Record<string, WidgetOptionSchemaField>;
|
|
44
|
+
/** 위젯 정의: 컴포넌트 + 옵션 스키마. Registry는 이걸로 확장 */
|
|
45
|
+
type WidgetDefinition = {
|
|
46
|
+
Component: WidgetComponent;
|
|
47
|
+
options?: WidgetOptionSchema;
|
|
48
|
+
};
|
|
49
|
+
/** 레거시 호환: [type] => Component | WidgetDefinition */
|
|
50
|
+
type WidgetRegistry = {
|
|
51
|
+
[type: string]: WidgetComponent | WidgetDefinition;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* 패널 설정. (Grafana Panel JSON 참고, 단순화)
|
|
55
|
+
* layout(gridPos) 정보는 포함하지 않음 — layout-store 전담.
|
|
56
|
+
* JSON 직렬화 가능.
|
|
57
|
+
*/
|
|
58
|
+
type PanelConfig = {
|
|
59
|
+
id: string;
|
|
60
|
+
/** widget type (e.g. "stat", "chart", "text") */
|
|
61
|
+
type: string;
|
|
62
|
+
dataSourceId?: string;
|
|
63
|
+
options?: Record<string, unknown>;
|
|
64
|
+
style?: CSSProperties;
|
|
65
|
+
/** 패널 루트 요소 className */
|
|
66
|
+
className?: string;
|
|
67
|
+
/** WidgetContainer(제목+콘텐츠 래퍼) 루트 className */
|
|
68
|
+
containerClassName?: string;
|
|
69
|
+
/** 위젯 루트(Widget 컴포넌트 최상위)에 전달되는 className */
|
|
70
|
+
widgetClassName?: string;
|
|
71
|
+
/** Panel wrapper 옵션 */
|
|
72
|
+
containerStyle?: CSSProperties;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* 대시보드 공식 스펙. "대시보드 = JSON"
|
|
76
|
+
* layout.items[].id === panels[].id 1:1. panels에는 좌표 없음.
|
|
77
|
+
*/
|
|
78
|
+
type DashboardSpec = {
|
|
79
|
+
id: string;
|
|
80
|
+
title: string;
|
|
81
|
+
columns: number;
|
|
82
|
+
layout: {
|
|
83
|
+
items: GridItem[];
|
|
84
|
+
};
|
|
85
|
+
panels: PanelConfig[];
|
|
86
|
+
};
|
|
87
|
+
/** 편집 / 보기 모드 (Grafana 핵심 UX) */
|
|
88
|
+
type DashboardMode = "view" | "edit";
|
|
89
|
+
/** 패널 액션 (remove, duplicate, edit placeholder) */
|
|
90
|
+
type PanelAction = {
|
|
91
|
+
type: "remove";
|
|
92
|
+
id: string;
|
|
93
|
+
} | {
|
|
94
|
+
type: "duplicate";
|
|
95
|
+
id: string;
|
|
96
|
+
} | {
|
|
97
|
+
type: "edit";
|
|
98
|
+
id: string;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* 데이터 소스 인터페이스.
|
|
102
|
+
* 비동기/캐시/폴링은 고려하지 않음.
|
|
103
|
+
* Dashboard는 data의 shape를 가정하지 않음.
|
|
104
|
+
*/
|
|
105
|
+
interface DataSource {
|
|
106
|
+
getData(dataSourceId: string, panelId: string): unknown;
|
|
107
|
+
}
|
|
108
|
+
/** 대시보드 그리드 UI 옵션 */
|
|
109
|
+
type DashboardGridOptions = {
|
|
110
|
+
/** 리사이즈 핸들에 표시할 커스텀 아이콘(ReactNode). 미지정 시 기본 스타일 */
|
|
111
|
+
resizeHandle?: ReactNode;
|
|
112
|
+
/** 격자선 표시 여부 */
|
|
113
|
+
showGrid?: boolean;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* 패널에 넘길 props.
|
|
117
|
+
* 위젯은 래퍼만 제공하고, 콘텐츠는 content로 주입.
|
|
118
|
+
*/
|
|
119
|
+
type PanelProps = {
|
|
120
|
+
item: GridItem;
|
|
121
|
+
title?: string;
|
|
122
|
+
content: ReactNode;
|
|
123
|
+
className?: string;
|
|
124
|
+
style?: CSSProperties;
|
|
125
|
+
containerClassName?: string;
|
|
126
|
+
containerStyle?: CSSProperties;
|
|
127
|
+
/** edit 모드에서 패널 액션(remove/duplicate/edit) 시 호출 */
|
|
128
|
+
onAction?: (action: PanelAction) => void;
|
|
129
|
+
/** edit 모드에서 패널 클릭 시 선택. selected면 시각 강조용 */
|
|
130
|
+
selected?: boolean;
|
|
131
|
+
onSelect?: () => void;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* PanelOptionEditor props.
|
|
135
|
+
* layout/store 절대 접근 ❌. 오직 PanelConfig.options 수정만.
|
|
136
|
+
*/
|
|
137
|
+
type PanelOptionEditorProps = {
|
|
138
|
+
panel: PanelConfig;
|
|
139
|
+
/** 위젯 옵션 스키마 (widget definition에서). 없으면 기본 필드만 */
|
|
140
|
+
schema?: WidgetOptionSchema;
|
|
141
|
+
onChange: (next: PanelConfig) => void;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/** className 조합 유틸 */
|
|
145
|
+
declare const cn: (...parts: (string | undefined)[]) => string;
|
|
146
|
+
|
|
147
|
+
/** 색상 토큰 */
|
|
148
|
+
declare const colors: {
|
|
149
|
+
readonly text: "#333";
|
|
150
|
+
readonly textMuted: "#555";
|
|
151
|
+
readonly textSubtle: "#999";
|
|
152
|
+
readonly border: "#e0e0e0";
|
|
153
|
+
readonly background: "#fff";
|
|
154
|
+
readonly primary: "#1976d2";
|
|
155
|
+
readonly success: "#73bf69";
|
|
156
|
+
readonly warning: "#ff9830";
|
|
157
|
+
readonly danger: "#f2495c";
|
|
158
|
+
readonly chartGradientStart: "#73bf69";
|
|
159
|
+
readonly chartGradientEnd: "#5794f2";
|
|
160
|
+
};
|
|
161
|
+
/** spacing (px) */
|
|
162
|
+
declare const spacing: {
|
|
163
|
+
readonly xs: 4;
|
|
164
|
+
readonly sm: 8;
|
|
165
|
+
readonly md: 12;
|
|
166
|
+
readonly lg: 16;
|
|
167
|
+
readonly xl: 24;
|
|
168
|
+
};
|
|
169
|
+
/** typography */
|
|
170
|
+
declare const typography: {
|
|
171
|
+
readonly fontSize: {
|
|
172
|
+
readonly xs: 11;
|
|
173
|
+
readonly sm: 12;
|
|
174
|
+
readonly md: 14;
|
|
175
|
+
readonly lg: 18;
|
|
176
|
+
readonly xl: 24;
|
|
177
|
+
};
|
|
178
|
+
readonly fontWeight: {
|
|
179
|
+
readonly normal: 400;
|
|
180
|
+
readonly medium: 500;
|
|
181
|
+
readonly semibold: 600;
|
|
182
|
+
readonly bold: 700;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
type Theme = {
|
|
186
|
+
colors: typeof colors;
|
|
187
|
+
spacing: typeof spacing;
|
|
188
|
+
typography: typeof typography;
|
|
189
|
+
};
|
|
190
|
+
declare const defaultTheme: Theme;
|
|
191
|
+
|
|
192
|
+
type DashboardProps = {
|
|
193
|
+
store: LayoutStore;
|
|
194
|
+
columns: number;
|
|
195
|
+
/** item.id로 조회. JSON 직렬화 가능한 설정만 포함 (layout 제외) */
|
|
196
|
+
panelConfigs: PanelConfig[];
|
|
197
|
+
dataSource: DataSource;
|
|
198
|
+
widgets: WidgetRegistry;
|
|
199
|
+
rowHeight?: number;
|
|
200
|
+
/** 그리드 UI 옵션: resize 아이콘, 격자 보기 등 */
|
|
201
|
+
gridOptions?: DashboardGridOptions;
|
|
202
|
+
/** view = 읽기 전용, edit = 드래그/리사이즈/패널 액션 허용 */
|
|
203
|
+
mode?: DashboardMode;
|
|
204
|
+
/** edit 모드에서 패널 액션(remove/duplicate/edit) 시 호출 */
|
|
205
|
+
onPanelAction?: (action: PanelAction) => void;
|
|
206
|
+
/** edit 모드에서 패널 클릭 시 선택. 선택된 id */
|
|
207
|
+
selectedPanelId?: string | null;
|
|
208
|
+
onPanelSelect?: (id: string) => void;
|
|
209
|
+
className?: string;
|
|
210
|
+
style?: React$1.CSSProperties;
|
|
211
|
+
};
|
|
212
|
+
declare const Dashboard: React$1.FC<DashboardProps>;
|
|
213
|
+
|
|
214
|
+
type DashboardRuntimeProps = {
|
|
215
|
+
/** 초기 스펙. key={initialSpec.id} 로 대시보드 전환 시 리마운트 권장 */
|
|
216
|
+
initialSpec: DashboardSpec;
|
|
217
|
+
widgets: WidgetRegistry;
|
|
218
|
+
dataSource: DataSource;
|
|
219
|
+
mode?: "view" | "edit";
|
|
220
|
+
/** 레이아웃/패널 변경 시 직렬화된 스펙 전달 (저장/서버 연동용) */
|
|
221
|
+
onChange?: (spec: DashboardSpec) => void;
|
|
222
|
+
rowHeight?: number;
|
|
223
|
+
gridOptions?: DashboardGridOptions;
|
|
224
|
+
className?: string;
|
|
225
|
+
style?: React$1.CSSProperties;
|
|
226
|
+
};
|
|
227
|
+
/** ref 로 노출되는 API. 툴바/단축키/저장 연동용 */
|
|
228
|
+
type DashboardRuntimeHandle = {
|
|
229
|
+
addPanel: (type: string) => void;
|
|
230
|
+
removePanel: (id: string) => void;
|
|
231
|
+
export: () => DashboardSpec;
|
|
232
|
+
};
|
|
233
|
+
declare const DashboardRuntime: React$1.ForwardRefExoticComponent<DashboardRuntimeProps & React$1.RefAttributes<DashboardRuntimeHandle>>;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* 빈 패널 생성 (Add Panel 플로우용).
|
|
237
|
+
* layout은 store.dispatch({ type: "add", item: { id, x, y, w, h } })로 호출 측에서 처리.
|
|
238
|
+
*/
|
|
239
|
+
declare const createEmptyPanel: (type: string, defaultTitle?: string) => PanelConfig;
|
|
240
|
+
/**
|
|
241
|
+
* 라이브러리 레벨: store + panels + meta → JSON 스펙.
|
|
242
|
+
* 순서 보존, deterministic, side-effect 없음.
|
|
243
|
+
*/
|
|
244
|
+
declare const serializeDashboard: (store: LayoutStore, panels: PanelConfig[], meta: {
|
|
245
|
+
id: string;
|
|
246
|
+
title: string;
|
|
247
|
+
}) => DashboardSpec;
|
|
248
|
+
/**
|
|
249
|
+
* JSON 스펙 → store + panels 복원.
|
|
250
|
+
*/
|
|
251
|
+
declare const loadDashboard: (spec: DashboardSpec) => {
|
|
252
|
+
store: LayoutStore;
|
|
253
|
+
panels: PanelConfig[];
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
declare const Panel: React$1.FC<PanelProps>;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* PanelOptionEditor.
|
|
260
|
+
* layout/store 접근 없음. PanelConfig.options 만 수정.
|
|
261
|
+
*/
|
|
262
|
+
declare const PanelOptionEditor: React$1.FC<PanelOptionEditorProps>;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* 반응형 그리드: 화면(컨테이너) 크기와 columns에 맞춰 cellWidth/cellHeight만 동적 조정.
|
|
266
|
+
* GridItem 좌표(x,y,w,h)는 변경하지 않음. 픽셀 변환만 달라짐.
|
|
267
|
+
* 좌우 이동 자동 보정 없음. pack-up 규칙은 layout-core/store에서 유지.
|
|
268
|
+
*/
|
|
269
|
+
type UseResponsiveGridOptions = {
|
|
270
|
+
/** 그리드 열 수 (layout-store의 columns와 동일해야 함) */
|
|
271
|
+
columns: number;
|
|
272
|
+
/** 셀 높이(px). 미지정 시 cellWidth와 동일(정사각형) */
|
|
273
|
+
rowHeight?: number;
|
|
274
|
+
};
|
|
275
|
+
type ResponsiveGridSize = {
|
|
276
|
+
cellWidth: number;
|
|
277
|
+
cellHeight: number;
|
|
278
|
+
};
|
|
279
|
+
declare const useResponsiveGrid: (containerRef: React.RefObject<HTMLDivElement | null>, options: UseResponsiveGridOptions) => ResponsiveGridSize;
|
|
280
|
+
|
|
281
|
+
/** 존재하지 않는 type용 fallback 위젯 */
|
|
282
|
+
declare const FallbackWidget: WidgetComponent;
|
|
283
|
+
/**
|
|
284
|
+
* Widget Registry 생성.
|
|
285
|
+
* 단순 객체 반환. 존재하지 않는 type에 대한 fallback은 Dashboard에서 처리.
|
|
286
|
+
*/
|
|
287
|
+
declare const createWidgetRegistry: (widgets: WidgetRegistry) => WidgetRegistry;
|
|
288
|
+
|
|
289
|
+
type TopBarProps = {
|
|
290
|
+
title?: string;
|
|
291
|
+
/** 사용자 정의 대시보드 선택기. 미주입 시 기본 제공 안 함 → children으로 직접 넣거나 자체 컴포넌트 사용 */
|
|
292
|
+
dashboardPicker?: React$1.ReactNode;
|
|
293
|
+
/** 사용자 정의 시간 범위 선택기. 미주입 시 기본 제공 안 함 → children으로 직접 넣거나 자체 컴포넌트 사용 */
|
|
294
|
+
timeRangePicker?: React$1.ReactNode;
|
|
295
|
+
children?: React$1.ReactNode;
|
|
296
|
+
className?: string;
|
|
297
|
+
style?: React$1.CSSProperties;
|
|
298
|
+
};
|
|
299
|
+
declare const TopBar: React$1.FC<TopBarProps>;
|
|
300
|
+
|
|
301
|
+
type SideNavItem = {
|
|
302
|
+
id: string;
|
|
303
|
+
label: string;
|
|
304
|
+
href?: string;
|
|
305
|
+
};
|
|
306
|
+
type SideNavProps = {
|
|
307
|
+
items?: SideNavItem[];
|
|
308
|
+
activeId?: string;
|
|
309
|
+
onSelect?: (id: string) => void;
|
|
310
|
+
className?: string;
|
|
311
|
+
style?: React$1.CSSProperties;
|
|
312
|
+
};
|
|
313
|
+
declare const SideNav: React$1.FC<SideNavProps>;
|
|
314
|
+
|
|
315
|
+
type DashboardOption = {
|
|
316
|
+
id: string;
|
|
317
|
+
title: string;
|
|
318
|
+
};
|
|
319
|
+
type DashboardPickerProps = {
|
|
320
|
+
options?: DashboardOption[];
|
|
321
|
+
value?: string;
|
|
322
|
+
onChange?: (id: string) => void;
|
|
323
|
+
className?: string;
|
|
324
|
+
style?: React$1.CSSProperties;
|
|
325
|
+
};
|
|
326
|
+
declare const DashboardPicker: React$1.FC<DashboardPickerProps>;
|
|
327
|
+
|
|
328
|
+
type TimeRangePreset = {
|
|
329
|
+
label: string;
|
|
330
|
+
value: string;
|
|
331
|
+
};
|
|
332
|
+
type TimeRangePickerProps = {
|
|
333
|
+
presets?: TimeRangePreset[];
|
|
334
|
+
value?: string;
|
|
335
|
+
onChange?: (value: string) => void;
|
|
336
|
+
className?: string;
|
|
337
|
+
style?: React$1.CSSProperties;
|
|
338
|
+
};
|
|
339
|
+
declare const TimeRangePicker: React$1.FC<TimeRangePickerProps>;
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* 정적 데이터 소스.
|
|
343
|
+
* dataSourceId → 데이터 매핑으로 패널에 공급.
|
|
344
|
+
*/
|
|
345
|
+
declare const createStaticDataSource: (payload: {
|
|
346
|
+
dataByKey: Record<string, unknown>;
|
|
347
|
+
}) => DataSource;
|
|
348
|
+
/**
|
|
349
|
+
* PanelConfig + layout. layout-store 초기 상태용.
|
|
350
|
+
* layout은 오직 layout-store가 담당.
|
|
351
|
+
*/
|
|
352
|
+
type PanelConfigWithLayout = {
|
|
353
|
+
panelConfig: PanelConfig;
|
|
354
|
+
layout: {
|
|
355
|
+
x: number;
|
|
356
|
+
y: number;
|
|
357
|
+
w: number;
|
|
358
|
+
h: number;
|
|
359
|
+
};
|
|
360
|
+
};
|
|
361
|
+
declare const buildInitialItemsFromPanelConfigs: (configs: PanelConfigWithLayout[]) => GridItem[];
|
|
362
|
+
|
|
363
|
+
type WidgetContainerProps = {
|
|
364
|
+
/** 위젯 상단에 표시할 제목 (options.title 등) */
|
|
365
|
+
title?: string;
|
|
366
|
+
children: React$1.ReactNode;
|
|
367
|
+
/** 루트 요소 커스텀 */
|
|
368
|
+
className?: string;
|
|
369
|
+
style?: CSSProperties;
|
|
370
|
+
/** 제목 영역 커스텀 */
|
|
371
|
+
titleClassName?: string;
|
|
372
|
+
titleStyle?: CSSProperties;
|
|
373
|
+
/** 콘텐츠 영역 커스텀 */
|
|
374
|
+
contentClassName?: string;
|
|
375
|
+
contentStyle?: CSSProperties;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* 모든 위젯이 공통으로 사용하는 컨테이너.
|
|
379
|
+
* 제목 + 콘텐츠 영역 레이아웃과 패딩을 통일. className/style로 커스텀 가능.
|
|
380
|
+
*/
|
|
381
|
+
declare const WidgetContainer: React$1.FC<WidgetContainerProps>;
|
|
382
|
+
|
|
383
|
+
export { Dashboard, type DashboardGridOptions, type DashboardMode, type DashboardOption, DashboardPicker, type DashboardPickerProps, type DashboardProps, DashboardRuntime, type DashboardRuntimeHandle, type DashboardRuntimeProps, type DashboardSpec, type DataSource, FallbackWidget, Panel, type PanelAction, type PanelConfig, type PanelConfigWithLayout, PanelOptionEditor, type PanelOptionEditorProps, type PanelProps, type ResponsiveGridSize, SideNav, type SideNavItem, type SideNavProps, type Theme, TimeRangePicker, type TimeRangePickerProps, type TimeRangePreset, TopBar, type TopBarProps, type UseResponsiveGridOptions, type WidgetComponent, WidgetContainer, type WidgetContainerProps, type WidgetDefinition, type WidgetOptionSchema, type WidgetOptionSchemaField, type WidgetProps, type WidgetRegistry, buildInitialItemsFromPanelConfigs, cn, colors, createEmptyPanel, createStaticDataSource, createWidgetRegistry, defaultTheme, loadDashboard, serializeDashboard, spacing, typography, useResponsiveGrid };
|