infaira-canvas 0.1.9
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 +264 -0
- package/dist/commands/init.d.ts +17 -0
- package/dist/commands/init.js +647 -0
- package/dist/commands/upload.d.ts +8 -0
- package/dist/commands/upload.js +164 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +123 -0
- package/package.json +44 -0
- package/templates/ICan-Customizing-Components.md +195 -0
- package/templates/ICan-Widget-Development-Guide.md +500 -0
- package/templates/ICan-Widget-Styling-Patterns.md +890 -0
- package/templates/ICan-Widget-Theming-Guide.md +633 -0
- package/templates/README.md +127 -0
- package/templates/designer.d.ts +468 -0
- package/templates/ican.d.ts +763 -0
- package/templates/index.html +2225 -0
- package/templates/resources/favicon.ico +2 -0
- package/templates/resources/ican-components.js +1734 -0
- package/templates/resources/infaira-icon.png +0 -0
- package/templates/resources/infaira-logo.png +0 -0
- package/templates/site.webmanifest +17 -0
- package/templates/ui.html +1670 -0
|
@@ -0,0 +1,763 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ICan Components — TypeScript declarations
|
|
3
|
+
* InfAIra Canvas v2.0
|
|
4
|
+
*
|
|
5
|
+
* Canonical mirror of widget-bridge.ts (the runtime).
|
|
6
|
+
* Keep in sync with apps_frontend/src/microservices/ican/widget-bridge.ts.
|
|
7
|
+
*
|
|
8
|
+
* Every ICan component supports two universal props:
|
|
9
|
+
* - className?: string — adds a CSS class to the root element
|
|
10
|
+
* - style?: React.CSSProperties — merges with the component's base inline styles (yours wins)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
declare module "ican/components" {
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
|
|
16
|
+
// ─── Shared primitives ──────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
export type ICanVariant = "primary" | "secondary" | "danger" | "ghost";
|
|
19
|
+
export type ICanBadgeVariant = "default" | "success" | "warning" | "error" | "info";
|
|
20
|
+
export type ICanSize = "xs" | "sm" | "md" | "lg";
|
|
21
|
+
export type ICanPosition = "top" | "bottom" | "left" | "right";
|
|
22
|
+
export type ICanDropdownPosition = "bottom-left" | "bottom-right" | "top-left" | "top-right";
|
|
23
|
+
export type ICanIconType =
|
|
24
|
+
| "search" | "close" | "done" | "edit" | "delete" | "add"
|
|
25
|
+
| "filter" | "arrow-up" | "arrow-down" | "arrow-left" | "arrow-right"
|
|
26
|
+
| "pin" | "copy" | "refresh";
|
|
27
|
+
|
|
28
|
+
export interface ICanOption { label: string; value: string; }
|
|
29
|
+
|
|
30
|
+
/** Universal styling props supported by every ICan component. */
|
|
31
|
+
export interface ICanStyledProps {
|
|
32
|
+
className?: string;
|
|
33
|
+
style?: React.CSSProperties;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─── Layout ────────────────────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
export interface IWidgetWrapperProps extends ICanStyledProps {
|
|
39
|
+
children: React.ReactNode;
|
|
40
|
+
}
|
|
41
|
+
export const WidgetWrapper: React.FC<IWidgetWrapperProps>;
|
|
42
|
+
|
|
43
|
+
export interface ILoadingProps extends ICanStyledProps { label?: string; }
|
|
44
|
+
export const Loading: React.FC<ILoadingProps>;
|
|
45
|
+
|
|
46
|
+
export interface ITitleBarProps extends ICanStyledProps {
|
|
47
|
+
title: string;
|
|
48
|
+
subtitle?: string;
|
|
49
|
+
children?: React.ReactNode;
|
|
50
|
+
}
|
|
51
|
+
export const TitleBar: React.FC<ITitleBarProps>;
|
|
52
|
+
|
|
53
|
+
export interface IFilterPanelProps extends ICanStyledProps { children?: React.ReactNode; }
|
|
54
|
+
export const FilterPanel: React.FC<IFilterPanelProps>;
|
|
55
|
+
|
|
56
|
+
export interface IErrorDisplayProps extends ICanStyledProps { message: string; }
|
|
57
|
+
export const ErrorDisplay: React.FC<IErrorDisplayProps>;
|
|
58
|
+
|
|
59
|
+
export interface ICardProps extends ICanStyledProps {
|
|
60
|
+
children?: React.ReactNode;
|
|
61
|
+
/** Optional header slot rendered above children with a divider. */
|
|
62
|
+
header?: React.ReactNode;
|
|
63
|
+
/** Optional footer slot rendered below children with a divider. */
|
|
64
|
+
footer?: React.ReactNode;
|
|
65
|
+
}
|
|
66
|
+
export const Card: React.FC<ICardProps>;
|
|
67
|
+
|
|
68
|
+
export interface IDataListProps extends ICanStyledProps {
|
|
69
|
+
items: Array<{ label: string; value: string | number }>;
|
|
70
|
+
}
|
|
71
|
+
export const DataList: React.FC<IDataListProps>;
|
|
72
|
+
|
|
73
|
+
// ─── Buttons ───────────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
export interface IButtonProps extends ICanStyledProps {
|
|
76
|
+
label: string;
|
|
77
|
+
onClick: () => void;
|
|
78
|
+
variant?: ICanVariant;
|
|
79
|
+
size?: "sm" | "md" | "lg";
|
|
80
|
+
disabled?: boolean;
|
|
81
|
+
loading?: boolean;
|
|
82
|
+
/** Optional icon (string/emoji or any React node) rendered before the label. */
|
|
83
|
+
icon?: React.ReactNode;
|
|
84
|
+
}
|
|
85
|
+
export const Button: React.FC<IButtonProps>;
|
|
86
|
+
|
|
87
|
+
export interface IAsyncButtonProps extends ICanStyledProps {
|
|
88
|
+
label: string;
|
|
89
|
+
onClick: () => Promise<void>;
|
|
90
|
+
icon?: string;
|
|
91
|
+
loadingLabel?: string;
|
|
92
|
+
disabled?: boolean;
|
|
93
|
+
variant?: "primary" | "secondary" | "danger";
|
|
94
|
+
}
|
|
95
|
+
export const AsyncButton: React.FC<IAsyncButtonProps>;
|
|
96
|
+
|
|
97
|
+
export interface IConfirmButtonProps extends ICanStyledProps {
|
|
98
|
+
label: string;
|
|
99
|
+
confirmLabel?: string;
|
|
100
|
+
onConfirm: () => Promise<void>;
|
|
101
|
+
variant?: "primary" | "danger";
|
|
102
|
+
disabled?: boolean;
|
|
103
|
+
}
|
|
104
|
+
export const ConfirmButton: React.FC<IConfirmButtonProps>;
|
|
105
|
+
|
|
106
|
+
export interface IIconButtonProps extends ICanStyledProps {
|
|
107
|
+
type: ICanIconType;
|
|
108
|
+
onClick: () => void;
|
|
109
|
+
active?: boolean;
|
|
110
|
+
disabled?: boolean;
|
|
111
|
+
size?: "sm" | "md" | "lg";
|
|
112
|
+
tooltip?: string;
|
|
113
|
+
}
|
|
114
|
+
export const IconButton: React.FC<IIconButtonProps>;
|
|
115
|
+
|
|
116
|
+
// ─── Form inputs ───────────────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
export interface IInputProps extends ICanStyledProps {
|
|
119
|
+
value: string;
|
|
120
|
+
onChange: (v: string) => void;
|
|
121
|
+
placeholder?: string;
|
|
122
|
+
label?: string;
|
|
123
|
+
type?: string;
|
|
124
|
+
disabled?: boolean;
|
|
125
|
+
error?: string;
|
|
126
|
+
}
|
|
127
|
+
export const Input: React.FC<IInputProps>;
|
|
128
|
+
|
|
129
|
+
export interface ITextAreaProps extends ICanStyledProps {
|
|
130
|
+
value: string;
|
|
131
|
+
onChange: (v: string) => void;
|
|
132
|
+
placeholder?: string;
|
|
133
|
+
label?: string;
|
|
134
|
+
rows?: number;
|
|
135
|
+
disabled?: boolean;
|
|
136
|
+
error?: string;
|
|
137
|
+
maxLength?: number;
|
|
138
|
+
}
|
|
139
|
+
export const TextArea: React.FC<ITextAreaProps>;
|
|
140
|
+
|
|
141
|
+
export interface ISelectProps extends ICanStyledProps {
|
|
142
|
+
value: string;
|
|
143
|
+
onChange: (v: string) => void;
|
|
144
|
+
options: ICanOption[];
|
|
145
|
+
placeholder?: string;
|
|
146
|
+
label?: string;
|
|
147
|
+
disabled?: boolean;
|
|
148
|
+
}
|
|
149
|
+
export const Select: React.FC<ISelectProps>;
|
|
150
|
+
|
|
151
|
+
export interface ICheckboxProps extends ICanStyledProps {
|
|
152
|
+
checked: boolean;
|
|
153
|
+
onChange: (v: boolean) => void;
|
|
154
|
+
label?: string;
|
|
155
|
+
type?: "default" | "bordered" | "switch" | "toggle" | "indicator";
|
|
156
|
+
disabled?: boolean;
|
|
157
|
+
}
|
|
158
|
+
export const Checkbox: React.FC<ICheckboxProps>;
|
|
159
|
+
|
|
160
|
+
export interface IMultiSelectProps extends ICanStyledProps {
|
|
161
|
+
options: ICanOption[];
|
|
162
|
+
selected: string[];
|
|
163
|
+
onChange: (values: string[]) => void;
|
|
164
|
+
placeholder?: string;
|
|
165
|
+
label?: string;
|
|
166
|
+
searchable?: boolean;
|
|
167
|
+
maxHeight?: string;
|
|
168
|
+
}
|
|
169
|
+
export const MultiSelect: React.FC<IMultiSelectProps>;
|
|
170
|
+
|
|
171
|
+
export interface IToggleFilterProps extends ICanStyledProps {
|
|
172
|
+
options: ICanOption[];
|
|
173
|
+
value: string;
|
|
174
|
+
onChange: (v: string) => void;
|
|
175
|
+
size?: "sm" | "md";
|
|
176
|
+
}
|
|
177
|
+
export const ToggleFilter: React.FC<IToggleFilterProps>;
|
|
178
|
+
|
|
179
|
+
export interface IColorPickerProps extends ICanStyledProps {
|
|
180
|
+
color: string;
|
|
181
|
+
onChange: (color: string) => void;
|
|
182
|
+
label?: string;
|
|
183
|
+
presets?: string[];
|
|
184
|
+
}
|
|
185
|
+
export const ColorPicker: React.FC<IColorPickerProps>;
|
|
186
|
+
|
|
187
|
+
export interface ISearchInputProps extends ICanStyledProps {
|
|
188
|
+
value: string;
|
|
189
|
+
onChange: (v: string) => void;
|
|
190
|
+
placeholder?: string;
|
|
191
|
+
onClear?: () => void;
|
|
192
|
+
}
|
|
193
|
+
export const SearchInput: React.FC<ISearchInputProps>;
|
|
194
|
+
|
|
195
|
+
export interface IFormFieldProps extends ICanStyledProps {
|
|
196
|
+
label?: string;
|
|
197
|
+
hint?: string;
|
|
198
|
+
error?: string;
|
|
199
|
+
required?: boolean;
|
|
200
|
+
inline?: boolean;
|
|
201
|
+
children?: React.ReactNode;
|
|
202
|
+
}
|
|
203
|
+
export const FormField: React.FC<IFormFieldProps>;
|
|
204
|
+
|
|
205
|
+
export interface ILabelProps extends ICanStyledProps {
|
|
206
|
+
required?: boolean;
|
|
207
|
+
children?: React.ReactNode;
|
|
208
|
+
}
|
|
209
|
+
export const Label: React.FC<ILabelProps>;
|
|
210
|
+
|
|
211
|
+
export interface IFormFeedbackProps extends ICanStyledProps {
|
|
212
|
+
validInput?: boolean;
|
|
213
|
+
children?: React.ReactNode;
|
|
214
|
+
}
|
|
215
|
+
export const FormFeedback: React.FC<IFormFeedbackProps>;
|
|
216
|
+
|
|
217
|
+
// ─── Date / time pickers (string-based ISO values) ─────────────────────────
|
|
218
|
+
|
|
219
|
+
export interface IDatePickerProps extends ICanStyledProps {
|
|
220
|
+
value: string | null;
|
|
221
|
+
onChange: (date: string) => void;
|
|
222
|
+
label?: string;
|
|
223
|
+
placeholder?: string;
|
|
224
|
+
minDate?: string;
|
|
225
|
+
maxDate?: string;
|
|
226
|
+
disabled?: boolean;
|
|
227
|
+
}
|
|
228
|
+
export const DatePicker: React.FC<IDatePickerProps>;
|
|
229
|
+
|
|
230
|
+
export interface ITimePickerProps extends ICanStyledProps {
|
|
231
|
+
value: string | null;
|
|
232
|
+
onChange: (time: string) => void;
|
|
233
|
+
label?: string;
|
|
234
|
+
placeholder?: string;
|
|
235
|
+
disabled?: boolean;
|
|
236
|
+
}
|
|
237
|
+
export const TimePicker: React.FC<ITimePickerProps>;
|
|
238
|
+
|
|
239
|
+
export interface IDateRangePickerProps extends ICanStyledProps {
|
|
240
|
+
startDate: string | null;
|
|
241
|
+
endDate: string | null;
|
|
242
|
+
onChange: (start: string, end: string) => void;
|
|
243
|
+
label?: string;
|
|
244
|
+
placeholder?: string;
|
|
245
|
+
disabled?: boolean;
|
|
246
|
+
}
|
|
247
|
+
export const DateRangePicker: React.FC<IDateRangePickerProps>;
|
|
248
|
+
|
|
249
|
+
export interface IDateTimePickerProps extends ICanStyledProps {
|
|
250
|
+
value: string | null;
|
|
251
|
+
onChange: (datetime: string) => void;
|
|
252
|
+
label?: string;
|
|
253
|
+
disabled?: boolean;
|
|
254
|
+
}
|
|
255
|
+
export const DateTimePicker: React.FC<IDateTimePickerProps>;
|
|
256
|
+
|
|
257
|
+
export interface ICalendarViewProps extends ICanStyledProps {
|
|
258
|
+
dates?: string[];
|
|
259
|
+
onSelectDate?: (date: string) => void;
|
|
260
|
+
minDate?: string;
|
|
261
|
+
maxDate?: string;
|
|
262
|
+
}
|
|
263
|
+
export const CalendarView: React.FC<ICalendarViewProps>;
|
|
264
|
+
|
|
265
|
+
// ─── Data Display ──────────────────────────────────────────────────────────
|
|
266
|
+
|
|
267
|
+
export interface IBadgeProps extends ICanStyledProps {
|
|
268
|
+
label: string;
|
|
269
|
+
variant?: ICanBadgeVariant;
|
|
270
|
+
dot?: boolean;
|
|
271
|
+
}
|
|
272
|
+
export const Badge: React.FC<IBadgeProps>;
|
|
273
|
+
|
|
274
|
+
export interface IStatCardProps extends ICanStyledProps {
|
|
275
|
+
label: string;
|
|
276
|
+
value: string | number;
|
|
277
|
+
unit?: string;
|
|
278
|
+
trend?: number;
|
|
279
|
+
icon?: string;
|
|
280
|
+
/** Small subtext rendered below the value (e.g. "vs last month"). */
|
|
281
|
+
description?: string;
|
|
282
|
+
}
|
|
283
|
+
export const StatCard: React.FC<IStatCardProps>;
|
|
284
|
+
|
|
285
|
+
export interface IEmptyStateProps extends ICanStyledProps {
|
|
286
|
+
title: string;
|
|
287
|
+
description?: string;
|
|
288
|
+
icon?: string;
|
|
289
|
+
action?: React.ReactNode;
|
|
290
|
+
}
|
|
291
|
+
export const EmptyState: React.FC<IEmptyStateProps>;
|
|
292
|
+
|
|
293
|
+
export interface IDataTableColumn {
|
|
294
|
+
key: string;
|
|
295
|
+
label: string;
|
|
296
|
+
width?: string;
|
|
297
|
+
render?: (value: unknown, row: Record<string, unknown>) => React.ReactNode;
|
|
298
|
+
/** When true, the column header is clickable and toggles asc/desc/off sorting. */
|
|
299
|
+
sortable?: boolean;
|
|
300
|
+
}
|
|
301
|
+
export interface IDataTableProps extends ICanStyledProps {
|
|
302
|
+
columns: IDataTableColumn[];
|
|
303
|
+
rows: Array<Record<string, unknown>>;
|
|
304
|
+
loading?: boolean;
|
|
305
|
+
emptyMessage?: string;
|
|
306
|
+
onRowClick?: (row: Record<string, unknown>) => void;
|
|
307
|
+
stickyHeader?: boolean;
|
|
308
|
+
}
|
|
309
|
+
export const DataTable: React.FC<IDataTableProps>;
|
|
310
|
+
|
|
311
|
+
export interface IDataGridProps extends ICanStyledProps {
|
|
312
|
+
items: unknown[];
|
|
313
|
+
renderItem: (item: unknown, index: number) => React.ReactNode;
|
|
314
|
+
columns?: number;
|
|
315
|
+
gap?: string;
|
|
316
|
+
loading?: boolean;
|
|
317
|
+
emptyMessage?: string;
|
|
318
|
+
}
|
|
319
|
+
export const DataGrid: React.FC<IDataGridProps>;
|
|
320
|
+
|
|
321
|
+
export interface IItemCardProps extends ICanStyledProps {
|
|
322
|
+
title: string;
|
|
323
|
+
subtitle?: string;
|
|
324
|
+
image?: string;
|
|
325
|
+
name?: string;
|
|
326
|
+
meta?: string;
|
|
327
|
+
onClick?: () => void;
|
|
328
|
+
actions?: React.ReactNode;
|
|
329
|
+
}
|
|
330
|
+
export const ItemCard: React.FC<IItemCardProps>;
|
|
331
|
+
|
|
332
|
+
export interface IItemListCardProps extends ICanStyledProps {
|
|
333
|
+
title: string;
|
|
334
|
+
subtitle?: string;
|
|
335
|
+
fields: Array<{ label: string; value: string | number | React.ReactNode }>;
|
|
336
|
+
actions?: React.ReactNode;
|
|
337
|
+
onClick?: () => void;
|
|
338
|
+
}
|
|
339
|
+
export const ItemListCard: React.FC<IItemListCardProps>;
|
|
340
|
+
|
|
341
|
+
export interface IHorizontalScrollListProps extends ICanStyledProps {
|
|
342
|
+
items: unknown[];
|
|
343
|
+
renderItem: (item: unknown, index: number) => React.ReactNode;
|
|
344
|
+
itemWidth?: string;
|
|
345
|
+
}
|
|
346
|
+
export const HorizontalScrollList: React.FC<IHorizontalScrollListProps>;
|
|
347
|
+
|
|
348
|
+
export interface INotificationBlockProps extends ICanStyledProps {
|
|
349
|
+
message: string;
|
|
350
|
+
type?: "info" | "success" | "warning" | "error";
|
|
351
|
+
onClose?: () => void;
|
|
352
|
+
icon?: string;
|
|
353
|
+
/** Optional bold heading rendered above the message. */
|
|
354
|
+
title?: string;
|
|
355
|
+
}
|
|
356
|
+
export const NotificationBlock: React.FC<INotificationBlockProps>;
|
|
357
|
+
|
|
358
|
+
export interface IProfileImageProps extends ICanStyledProps {
|
|
359
|
+
image?: string;
|
|
360
|
+
name: string;
|
|
361
|
+
size?: ICanSize;
|
|
362
|
+
bgColor?: string;
|
|
363
|
+
}
|
|
364
|
+
export const ProfileImage: React.FC<IProfileImageProps>;
|
|
365
|
+
|
|
366
|
+
export interface ISampleDataLabelProps extends ICanStyledProps { show?: boolean; }
|
|
367
|
+
export const SampleDataLabel: React.FC<ISampleDataLabelProps>;
|
|
368
|
+
|
|
369
|
+
// ─── Overlays ──────────────────────────────────────────────────────────────
|
|
370
|
+
|
|
371
|
+
export interface ITooltipProps extends ICanStyledProps {
|
|
372
|
+
content: string | React.ReactNode;
|
|
373
|
+
position?: ICanPosition;
|
|
374
|
+
children: React.ReactNode;
|
|
375
|
+
/** Delay in ms before the tooltip appears on hover. Default 200. */
|
|
376
|
+
delay?: number;
|
|
377
|
+
}
|
|
378
|
+
export const Tooltip: React.FC<ITooltipProps>;
|
|
379
|
+
|
|
380
|
+
export interface IPopoverProps extends ICanStyledProps {
|
|
381
|
+
trigger: React.ReactNode;
|
|
382
|
+
content: React.ReactNode;
|
|
383
|
+
position?: ICanPosition;
|
|
384
|
+
onOpen?: () => void;
|
|
385
|
+
onClose?: () => void;
|
|
386
|
+
}
|
|
387
|
+
export const Popover: React.FC<IPopoverProps>;
|
|
388
|
+
|
|
389
|
+
export interface IDropDownButtonProps extends ICanStyledProps {
|
|
390
|
+
label?: string;
|
|
391
|
+
icon?: string;
|
|
392
|
+
children: React.ReactNode;
|
|
393
|
+
position?: ICanDropdownPosition;
|
|
394
|
+
onOpen?: () => void;
|
|
395
|
+
onClose?: () => void;
|
|
396
|
+
}
|
|
397
|
+
export const DropDownButton: React.FC<IDropDownButtonProps>;
|
|
398
|
+
|
|
399
|
+
// ─── Tabs / Modal / Pagination ─────────────────────────────────────────────
|
|
400
|
+
|
|
401
|
+
export interface ITabConfig {
|
|
402
|
+
key: string;
|
|
403
|
+
label: string;
|
|
404
|
+
}
|
|
405
|
+
export interface ITabsProps extends ICanStyledProps {
|
|
406
|
+
tabs: ITabConfig[];
|
|
407
|
+
activeKey: string;
|
|
408
|
+
onChange: (key: string) => void;
|
|
409
|
+
}
|
|
410
|
+
export const Tabs: React.FC<ITabsProps>;
|
|
411
|
+
|
|
412
|
+
export interface IModalProps extends ICanStyledProps {
|
|
413
|
+
open: boolean;
|
|
414
|
+
onClose: () => void;
|
|
415
|
+
title?: string;
|
|
416
|
+
children: React.ReactNode;
|
|
417
|
+
footer?: React.ReactNode;
|
|
418
|
+
width?: string;
|
|
419
|
+
/** When false, disables Escape, X-button, and backdrop-click closing. Default true. */
|
|
420
|
+
closable?: boolean;
|
|
421
|
+
}
|
|
422
|
+
export const Modal: React.FC<IModalProps>;
|
|
423
|
+
|
|
424
|
+
export interface IPaginationProps extends ICanStyledProps {
|
|
425
|
+
page: number;
|
|
426
|
+
pageSize: number;
|
|
427
|
+
total: number;
|
|
428
|
+
onChange: (page: number) => void;
|
|
429
|
+
}
|
|
430
|
+
export const Pagination: React.FC<IPaginationProps>;
|
|
431
|
+
|
|
432
|
+
// ─── Wizard ────────────────────────────────────────────────────────────────
|
|
433
|
+
|
|
434
|
+
export interface IWizardStepRenderArgs {
|
|
435
|
+
next: () => void;
|
|
436
|
+
prev: () => void;
|
|
437
|
+
isFirst: boolean;
|
|
438
|
+
isLast: boolean;
|
|
439
|
+
}
|
|
440
|
+
export interface IWizardStep {
|
|
441
|
+
id: string;
|
|
442
|
+
title: string;
|
|
443
|
+
render: (args: IWizardStepRenderArgs) => React.ReactNode;
|
|
444
|
+
onNext?: () => boolean | Promise<boolean>;
|
|
445
|
+
}
|
|
446
|
+
export interface IWizardProps extends ICanStyledProps {
|
|
447
|
+
steps: IWizardStep[];
|
|
448
|
+
onComplete: () => void;
|
|
449
|
+
completionTitle?: string;
|
|
450
|
+
}
|
|
451
|
+
export const Wizard: React.FC<IWizardProps>;
|
|
452
|
+
|
|
453
|
+
export interface IModalWizardProps extends ICanStyledProps {
|
|
454
|
+
open: boolean;
|
|
455
|
+
onClose: () => void;
|
|
456
|
+
steps: IWizardStep[];
|
|
457
|
+
onComplete: () => void;
|
|
458
|
+
completionTitle?: string;
|
|
459
|
+
title?: string;
|
|
460
|
+
width?: string;
|
|
461
|
+
}
|
|
462
|
+
export const ModalWizard: React.FC<IModalWizardProps>;
|
|
463
|
+
|
|
464
|
+
// ─── Charts ────────────────────────────────────────────────────────────────
|
|
465
|
+
|
|
466
|
+
export interface IPieChartDataItem {
|
|
467
|
+
label: string;
|
|
468
|
+
value: number;
|
|
469
|
+
color?: string;
|
|
470
|
+
}
|
|
471
|
+
export interface IPieChartProps extends ICanStyledProps {
|
|
472
|
+
data: IPieChartDataItem[];
|
|
473
|
+
size?: number;
|
|
474
|
+
showLegend?: boolean;
|
|
475
|
+
donut?: boolean;
|
|
476
|
+
centerLabel?: string;
|
|
477
|
+
}
|
|
478
|
+
export const PieChart: React.FC<IPieChartProps>;
|
|
479
|
+
|
|
480
|
+
export interface ILineChartSeries {
|
|
481
|
+
label: string;
|
|
482
|
+
data: Array<{ x: string | number; y: number }>;
|
|
483
|
+
color?: string;
|
|
484
|
+
fill?: boolean;
|
|
485
|
+
}
|
|
486
|
+
export interface ILineChartProps extends ICanStyledProps {
|
|
487
|
+
series: ILineChartSeries[];
|
|
488
|
+
height?: number;
|
|
489
|
+
showGrid?: boolean;
|
|
490
|
+
showDots?: boolean;
|
|
491
|
+
xLabel?: string;
|
|
492
|
+
yLabel?: string;
|
|
493
|
+
}
|
|
494
|
+
export const LineChart: React.FC<ILineChartProps>;
|
|
495
|
+
|
|
496
|
+
export interface IBarChartDataItem {
|
|
497
|
+
label: string;
|
|
498
|
+
value: number;
|
|
499
|
+
color?: string;
|
|
500
|
+
}
|
|
501
|
+
export interface IBarChartProps extends ICanStyledProps {
|
|
502
|
+
data: IBarChartDataItem[];
|
|
503
|
+
height?: number;
|
|
504
|
+
horizontal?: boolean;
|
|
505
|
+
showValues?: boolean;
|
|
506
|
+
showGrid?: boolean;
|
|
507
|
+
}
|
|
508
|
+
export const BarChart: React.FC<IBarChartProps>;
|
|
509
|
+
|
|
510
|
+
export interface IRadialGaugeProps extends ICanStyledProps {
|
|
511
|
+
value: number;
|
|
512
|
+
min?: number;
|
|
513
|
+
max?: number;
|
|
514
|
+
label?: string;
|
|
515
|
+
unit?: string;
|
|
516
|
+
colors?: Array<{ color: string; stopAt: number }>;
|
|
517
|
+
size?: number;
|
|
518
|
+
thickness?: number;
|
|
519
|
+
showNeedle?: boolean;
|
|
520
|
+
animated?: boolean;
|
|
521
|
+
}
|
|
522
|
+
export const RadialGauge: React.FC<IRadialGaugeProps>;
|
|
523
|
+
|
|
524
|
+
// ─── Chart Loaders (skeletons) ─────────────────────────────────────────────
|
|
525
|
+
|
|
526
|
+
export interface IChartLoaderProps extends ICanStyledProps {
|
|
527
|
+
height?: number;
|
|
528
|
+
animated?: boolean;
|
|
529
|
+
}
|
|
530
|
+
export const ChartLoader: React.FC<IChartLoaderProps>;
|
|
531
|
+
export const BarChartLoader: React.FC<IChartLoaderProps>;
|
|
532
|
+
export const DonutChartLoader: React.FC<IChartLoaderProps>;
|
|
533
|
+
export const GaugeLoader: React.FC<IChartLoaderProps>;
|
|
534
|
+
|
|
535
|
+
// ─── Map ───────────────────────────────────────────────────────────────────
|
|
536
|
+
|
|
537
|
+
export interface IMapMarker {
|
|
538
|
+
lat: number;
|
|
539
|
+
lng: number;
|
|
540
|
+
popup?: string;
|
|
541
|
+
color?: string;
|
|
542
|
+
}
|
|
543
|
+
export interface IMapStaticImage {
|
|
544
|
+
url: string;
|
|
545
|
+
width: number;
|
|
546
|
+
height: number;
|
|
547
|
+
}
|
|
548
|
+
export interface IMapComponentProps extends ICanStyledProps {
|
|
549
|
+
center?: [number, number];
|
|
550
|
+
zoom?: number;
|
|
551
|
+
height?: string;
|
|
552
|
+
markers?: IMapMarker[];
|
|
553
|
+
onMarkerClick?: (marker: unknown) => void;
|
|
554
|
+
tileUrl?: string;
|
|
555
|
+
staticImage?: IMapStaticImage;
|
|
556
|
+
}
|
|
557
|
+
export const MapComponent: React.FC<IMapComponentProps>;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// ─── Hooks ────────────────────────────────────────────────────────────────────
|
|
561
|
+
// ICan exposes a set of React hooks at runtime via global window slots.
|
|
562
|
+
// Widgets can either declare these as webpack externals or use the canonical
|
|
563
|
+
// import path "ican/hooks". The runtime resolves them to the portal's globals.
|
|
564
|
+
|
|
565
|
+
declare module "ican/hooks" {
|
|
566
|
+
import * as React from "react";
|
|
567
|
+
|
|
568
|
+
// ─── useExecuteAction ─────────────────────────────────────────────────────
|
|
569
|
+
/**
|
|
570
|
+
* Returns a function that calls a registered model action on the current
|
|
571
|
+
* dashboard. Used by widgets to invoke server-side actions.
|
|
572
|
+
*/
|
|
573
|
+
export function useExecuteAction(
|
|
574
|
+
dashboardId: string
|
|
575
|
+
): (model: string, action: string, params?: Record<string, unknown>) => Promise<unknown>;
|
|
576
|
+
|
|
577
|
+
// ─── useMessageBus ────────────────────────────────────────────────────────
|
|
578
|
+
/**
|
|
579
|
+
* Subscribe to a pub/sub channel. The handler is invoked whenever any other
|
|
580
|
+
* widget calls publishMessage(channel, payload) on the same channel.
|
|
581
|
+
*/
|
|
582
|
+
export type MessageHandler = (payload: unknown) => void;
|
|
583
|
+
export function useMessageBus(channel: string, handler: MessageHandler): void;
|
|
584
|
+
export function publishMessage(channel: string, payload: unknown): void;
|
|
585
|
+
|
|
586
|
+
// ─── useToast ─────────────────────────────────────────────────────────────
|
|
587
|
+
export interface IToastOptions {
|
|
588
|
+
duration?: number;
|
|
589
|
+
type?: "info" | "success" | "warning" | "error";
|
|
590
|
+
action?: { label: string; onClick: () => void };
|
|
591
|
+
}
|
|
592
|
+
export interface IToastHook {
|
|
593
|
+
show: (message: string, options?: IToastOptions) => void;
|
|
594
|
+
success: (message: string, options?: Omit<IToastOptions, "type">) => void;
|
|
595
|
+
error: (message: string, options?: Omit<IToastOptions, "type">) => void;
|
|
596
|
+
warning: (message: string, options?: Omit<IToastOptions, "type">) => void;
|
|
597
|
+
info: (message: string, options?: Omit<IToastOptions, "type">) => void;
|
|
598
|
+
dismiss: (id?: string) => void;
|
|
599
|
+
}
|
|
600
|
+
export function useToast(): IToastHook;
|
|
601
|
+
|
|
602
|
+
// ─── useAlert ─────────────────────────────────────────────────────────────
|
|
603
|
+
export interface IAlertHook {
|
|
604
|
+
confirm: (
|
|
605
|
+
title: string,
|
|
606
|
+
message?: string,
|
|
607
|
+
options?: { confirmLabel?: string; cancelLabel?: string; danger?: boolean }
|
|
608
|
+
) => Promise<boolean>;
|
|
609
|
+
alert: (title: string, message?: string) => Promise<void>;
|
|
610
|
+
prompt: (
|
|
611
|
+
title: string,
|
|
612
|
+
message?: string,
|
|
613
|
+
options?: { defaultValue?: string; placeholder?: string }
|
|
614
|
+
) => Promise<string | null>;
|
|
615
|
+
}
|
|
616
|
+
export function useAlert(): IAlertHook;
|
|
617
|
+
|
|
618
|
+
// ─── useDebounce ──────────────────────────────────────────────────────────
|
|
619
|
+
/**
|
|
620
|
+
* Returns a value that only updates after `delay` ms have elapsed since the
|
|
621
|
+
* last change. Useful for typing-driven search inputs and API calls.
|
|
622
|
+
*/
|
|
623
|
+
export function useDebounce<T>(value: T, delay?: number): T;
|
|
624
|
+
|
|
625
|
+
// ─── usePolling ───────────────────────────────────────────────────────────
|
|
626
|
+
/**
|
|
627
|
+
* Calls `callback` on a fixed interval (`intervalMs`). Pause via the
|
|
628
|
+
* `paused` arg. The interval restarts each time deps change.
|
|
629
|
+
*/
|
|
630
|
+
export function usePolling(
|
|
631
|
+
callback: () => void | Promise<void>,
|
|
632
|
+
intervalMs: number,
|
|
633
|
+
paused?: boolean
|
|
634
|
+
): void;
|
|
635
|
+
|
|
636
|
+
// ─── useTranslation ───────────────────────────────────────────────────────
|
|
637
|
+
/**
|
|
638
|
+
* Returns the active locale and a translator function `t(key, default)`.
|
|
639
|
+
*/
|
|
640
|
+
export function useTranslation(): {
|
|
641
|
+
t: (key: string, defaultValue: string) => string;
|
|
642
|
+
locale: string;
|
|
643
|
+
};
|
|
644
|
+
export function t(key: string, defaultValue: string): string;
|
|
645
|
+
export function setLocale(locale: string, dict: Record<string, string>): void;
|
|
646
|
+
|
|
647
|
+
// ─── useWidgetPrefs ───────────────────────────────────────────────────────
|
|
648
|
+
/**
|
|
649
|
+
* Persisted per-widget preferences. Returns [prefs, setPrefs] like useState
|
|
650
|
+
* but synced to the portal's prefs store keyed by `instanceId`.
|
|
651
|
+
*/
|
|
652
|
+
export function useWidgetPrefs<T extends Record<string, unknown>>(
|
|
653
|
+
instanceId: string,
|
|
654
|
+
defaults: T
|
|
655
|
+
): [T, (next: Partial<T>) => void];
|
|
656
|
+
export function clearWidgetPrefs(instanceId: string): void;
|
|
657
|
+
|
|
658
|
+
// ─── useFields ────────────────────────────────────────────────────────────
|
|
659
|
+
/**
|
|
660
|
+
* Lightweight controlled-form helper. Returns a getter/setter for each named
|
|
661
|
+
* field. Mirrors the UXP useFields hook for migrating widgets.
|
|
662
|
+
*/
|
|
663
|
+
export function useFields<T extends Record<string, unknown>>(
|
|
664
|
+
initial: T
|
|
665
|
+
): {
|
|
666
|
+
fields: T;
|
|
667
|
+
setField: <K extends keyof T>(name: K, value: T[K]) => void;
|
|
668
|
+
setFields: (next: Partial<T>) => void;
|
|
669
|
+
reset: () => void;
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
// ─── useResizeObserver ────────────────────────────────────────────────────
|
|
673
|
+
/**
|
|
674
|
+
* Returns the current size of the element referenced by `ref`. Updates
|
|
675
|
+
* automatically when the element's content box changes size.
|
|
676
|
+
*/
|
|
677
|
+
export interface Size { width: number; height: number; }
|
|
678
|
+
export function useResizeObserver(ref: React.RefObject<HTMLElement>): Size;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// ─── Widget context type (passed to every widget as `icanContext` prop) ────────
|
|
682
|
+
|
|
683
|
+
declare module "ican/context" {
|
|
684
|
+
/**
|
|
685
|
+
* The runtime context object every widget receives via the icanContext prop.
|
|
686
|
+
* Provides access to the portal's services from inside a widget bundle.
|
|
687
|
+
*/
|
|
688
|
+
export interface IICanContext {
|
|
689
|
+
/** Stable id for this widget instance on the dashboard. */
|
|
690
|
+
instanceId: string;
|
|
691
|
+
/** Id of the dashboard the widget is rendered on. */
|
|
692
|
+
dashboardId: string;
|
|
693
|
+
/** Active theme name applied to the portal. */
|
|
694
|
+
theme: "light" | "dark" | "glass-dark" | "glass-light";
|
|
695
|
+
/** Locale string (e.g. "en", "es-ES"). */
|
|
696
|
+
locale: string;
|
|
697
|
+
/** Current authenticated user info, if available. */
|
|
698
|
+
user?: {
|
|
699
|
+
id: string;
|
|
700
|
+
name: string;
|
|
701
|
+
email?: string;
|
|
702
|
+
roles?: string[];
|
|
703
|
+
};
|
|
704
|
+
/** Invoke a registered model action on this dashboard. */
|
|
705
|
+
executeAction(
|
|
706
|
+
model: string,
|
|
707
|
+
action: string,
|
|
708
|
+
params?: Record<string, unknown>
|
|
709
|
+
): Promise<unknown>;
|
|
710
|
+
/** Resolve a relative ICan backend path against the portal base URL. */
|
|
711
|
+
resolveUrl(path: string): string;
|
|
712
|
+
/** Logging helper namespaced to this widget instance. */
|
|
713
|
+
log(level: "info" | "warn" | "error", ...args: unknown[]): void;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// ─── Global runtime declarations ─────────────────────────────────────────────
|
|
718
|
+
// These are set by widget-bridge.ts on the host portal and consumed by widget
|
|
719
|
+
// bundles via webpack externals.
|
|
720
|
+
//
|
|
721
|
+
// This file is an ambient declaration (.d.ts with no top-level imports/exports
|
|
722
|
+
// outside `declare module` blocks), so the `interface Window` below augments
|
|
723
|
+
// the global Window type automatically.
|
|
724
|
+
|
|
725
|
+
interface Window {
|
|
726
|
+
React: unknown;
|
|
727
|
+
ReactDOM: unknown;
|
|
728
|
+
ICanComponents: Record<string, unknown>;
|
|
729
|
+
UXPComponents: Record<string, unknown>;
|
|
730
|
+
WidgetDesignerComponents: Record<string, unknown>;
|
|
731
|
+
/** Widget registry — qualifiedId → registration entry. */
|
|
732
|
+
__ican_registry: Map<string, unknown>;
|
|
733
|
+
/** Widget registration handshake. Widgets call this after their script loads. */
|
|
734
|
+
registerWidget(registration: {
|
|
735
|
+
id: string;
|
|
736
|
+
component?: unknown;
|
|
737
|
+
/** UXP-legacy alias for `component`. */
|
|
738
|
+
widget?: unknown;
|
|
739
|
+
configs?: unknown;
|
|
740
|
+
defaultProps?: Record<string, unknown>;
|
|
741
|
+
label?: string;
|
|
742
|
+
name?: string;
|
|
743
|
+
description?: string;
|
|
744
|
+
icon?: string;
|
|
745
|
+
}): void;
|
|
746
|
+
__ican_messageBus?: {
|
|
747
|
+
useMessageBus: (channel: string, handler: (payload: unknown) => void) => void;
|
|
748
|
+
publishMessage: (channel: string, payload: unknown) => void;
|
|
749
|
+
};
|
|
750
|
+
__ican_i18n?: {
|
|
751
|
+
useTranslation: () => { t: (k: string, d: string) => string; locale: string };
|
|
752
|
+
t: (k: string, d: string) => string;
|
|
753
|
+
setLocale: (locale: string, dict: Record<string, string>) => void;
|
|
754
|
+
};
|
|
755
|
+
__ican_prefs?: {
|
|
756
|
+
useWidgetPrefs: <T extends Record<string, unknown>>(
|
|
757
|
+
instanceId: string,
|
|
758
|
+
defaults: T
|
|
759
|
+
) => [T, (next: Partial<T>) => void];
|
|
760
|
+
clearWidgetPrefs: (instanceId: string) => void;
|
|
761
|
+
};
|
|
762
|
+
__ican_hooks?: Record<string, unknown>;
|
|
763
|
+
}
|