@object-ui/types 0.3.1 → 2.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 +1 -1
- package/dist/ai.d.ts +376 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +8 -0
- package/dist/app.d.ts +10 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/blocks.d.ts +332 -0
- package/dist/blocks.d.ts.map +1 -0
- package/dist/blocks.js +8 -0
- package/dist/crud.d.ts +177 -3
- package/dist/crud.d.ts.map +1 -1
- package/dist/data-display.d.ts +35 -0
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-protocol.d.ts +1268 -0
- package/dist/data-protocol.d.ts.map +1 -0
- package/dist/data-protocol.js +8 -0
- package/dist/data.d.ts +74 -1
- package/dist/data.d.ts.map +1 -1
- package/dist/designer.d.ts +473 -0
- package/dist/designer.d.ts.map +1 -0
- package/dist/designer.js +8 -0
- package/dist/field-types.d.ts +353 -11
- package/dist/field-types.d.ts.map +1 -1
- package/dist/form.d.ts +35 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/index.d.ts +58 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -0
- package/dist/layout.d.ts +63 -8
- package/dist/layout.d.ts.map +1 -1
- package/dist/mobile.d.ts +186 -0
- package/dist/mobile.d.ts.map +1 -0
- package/dist/mobile.js +8 -0
- package/dist/objectql.d.ts +337 -89
- package/dist/objectql.d.ts.map +1 -1
- package/dist/permissions.d.ts +150 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +8 -0
- package/dist/plugin-scope.d.ts +194 -0
- package/dist/plugin-scope.d.ts.map +1 -0
- package/dist/plugin-scope.js +8 -0
- package/dist/reports.d.ts +336 -0
- package/dist/reports.d.ts.map +1 -0
- package/dist/reports.js +8 -0
- package/dist/tenant.d.ts +138 -0
- package/dist/tenant.d.ts.map +1 -0
- package/dist/tenant.js +8 -0
- package/dist/theme.d.ts +180 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +8 -0
- package/dist/ui-action.d.ts +290 -0
- package/dist/ui-action.d.ts.map +1 -0
- package/dist/ui-action.js +8 -0
- package/dist/views.d.ts +427 -0
- package/dist/views.d.ts.map +1 -0
- package/dist/views.js +8 -0
- package/dist/widget.d.ts +181 -0
- package/dist/widget.d.ts.map +1 -0
- package/dist/widget.js +8 -0
- package/dist/workflow.d.ts +340 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +8 -0
- package/dist/zod/app.zod.d.ts +120 -0
- package/dist/zod/app.zod.d.ts.map +1 -0
- package/dist/zod/app.zod.js +60 -0
- package/dist/zod/blocks.zod.d.ts +834 -0
- package/dist/zod/blocks.zod.d.ts.map +1 -0
- package/dist/zod/blocks.zod.js +145 -0
- package/dist/zod/complex.zod.d.ts +4 -4
- package/dist/zod/complex.zod.js +1 -1
- package/dist/zod/crud.zod.d.ts +598 -0
- package/dist/zod/crud.zod.d.ts.map +1 -0
- package/dist/zod/crud.zod.js +230 -0
- package/dist/zod/data-display.zod.js +1 -1
- package/dist/zod/disclosure.zod.js +1 -1
- package/dist/zod/feedback.zod.d.ts +10 -10
- package/dist/zod/feedback.zod.js +1 -1
- package/dist/zod/form.zod.d.ts +4 -4
- package/dist/zod/form.zod.js +1 -1
- package/dist/zod/index.zod.d.ts +2032 -30
- package/dist/zod/index.zod.d.ts.map +1 -1
- package/dist/zod/index.zod.js +96 -19
- package/dist/zod/layout.zod.d.ts +134 -2
- package/dist/zod/layout.zod.d.ts.map +1 -1
- package/dist/zod/layout.zod.js +35 -1
- package/dist/zod/navigation.zod.js +1 -1
- package/dist/zod/objectql.zod.d.ts +34 -18
- package/dist/zod/objectql.zod.d.ts.map +1 -1
- package/dist/zod/objectql.zod.js +9 -1
- package/dist/zod/overlay.zod.js +1 -1
- package/dist/zod/reports.zod.d.ts +1628 -0
- package/dist/zod/reports.zod.d.ts.map +1 -0
- package/dist/zod/reports.zod.js +152 -0
- package/dist/zod/theme.zod.d.ts +1292 -0
- package/dist/zod/theme.zod.d.ts.map +1 -0
- package/dist/zod/theme.zod.js +260 -0
- package/dist/zod/views.zod.d.ts +675 -0
- package/dist/zod/views.zod.d.ts.map +1 -0
- package/dist/zod/views.zod.js +159 -0
- package/package.json +3 -2
- package/src/__tests__/namespace-exports.test.ts +36 -0
- package/src/__tests__/phase2-schemas.test.ts +634 -0
- package/src/ai.ts +454 -0
- package/src/app.ts +12 -0
- package/src/blocks.ts +405 -0
- package/src/crud.ts +180 -3
- package/src/data-display.ts +31 -0
- package/src/data-protocol.ts +1679 -0
- package/src/data.ts +84 -1
- package/src/designer.ts +509 -0
- package/src/field-types.ts +392 -11
- package/src/form.ts +35 -1
- package/src/index.ts +426 -0
- package/src/layout.ts +66 -8
- package/src/mobile.ts +205 -0
- package/src/objectql.ts +412 -94
- package/src/permissions.ts +166 -0
- package/src/plugin-scope.ts +210 -0
- package/src/reports.ts +408 -0
- package/src/tenant.ts +153 -0
- package/src/theme.ts +238 -0
- package/src/ui-action.ts +415 -0
- package/src/views.ts +436 -0
- package/src/widget.ts +197 -0
- package/src/workflow.ts +409 -0
- package/src/zod/app.zod.ts +72 -0
- package/src/zod/blocks.zod.ts +170 -0
- package/src/zod/complex.zod.ts +1 -1
- package/src/zod/crud.zod.ts +259 -0
- package/src/zod/data-display.zod.ts +1 -1
- package/src/zod/disclosure.zod.ts +1 -1
- package/src/zod/feedback.zod.ts +1 -1
- package/src/zod/form.zod.ts +1 -1
- package/src/zod/index.zod.ts +178 -19
- package/src/zod/layout.zod.ts +39 -1
- package/src/zod/navigation.zod.ts +1 -1
- package/src/zod/objectql.zod.ts +9 -1
- package/src/zod/overlay.zod.ts +1 -1
- package/src/zod/reports.zod.ts +183 -0
- package/src/zod/theme.zod.ts +296 -0
- package/src/zod/views.zod.ts +182 -0
package/src/views.ts
ADDED
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @object-ui/types - View Component Schemas
|
|
11
|
+
*
|
|
12
|
+
* Type definitions for various view components (List, Detail, Grid, Kanban, Calendar).
|
|
13
|
+
* These schemas enable building different data visualization interfaces.
|
|
14
|
+
*
|
|
15
|
+
* @module views
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { BaseSchema, SchemaNode } from './base';
|
|
20
|
+
import type { ActionSchema } from './crud';
|
|
21
|
+
import type { TableColumn } from './data-display';
|
|
22
|
+
import type { FormField } from './form';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* View Type
|
|
26
|
+
*/
|
|
27
|
+
export type ViewType = 'list' | 'detail' | 'grid' | 'kanban' | 'calendar' | 'timeline' | 'map';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Detail View Field Configuration
|
|
31
|
+
*/
|
|
32
|
+
export interface DetailViewField {
|
|
33
|
+
/**
|
|
34
|
+
* Field name/path
|
|
35
|
+
*/
|
|
36
|
+
name: string;
|
|
37
|
+
/**
|
|
38
|
+
* Display label
|
|
39
|
+
*/
|
|
40
|
+
label?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Field type for rendering
|
|
43
|
+
*/
|
|
44
|
+
type?: 'text' | 'image' | 'link' | 'badge' | 'date' | 'datetime' | 'json' | 'html' | 'markdown' | 'custom';
|
|
45
|
+
/**
|
|
46
|
+
* Format string (e.g., date format)
|
|
47
|
+
*/
|
|
48
|
+
format?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Custom renderer
|
|
51
|
+
*/
|
|
52
|
+
render?: SchemaNode;
|
|
53
|
+
/**
|
|
54
|
+
* Field value
|
|
55
|
+
*/
|
|
56
|
+
value?: any;
|
|
57
|
+
/**
|
|
58
|
+
* Whether field is read-only
|
|
59
|
+
*/
|
|
60
|
+
readonly?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Field visibility condition
|
|
63
|
+
*/
|
|
64
|
+
visible?: boolean | string;
|
|
65
|
+
/**
|
|
66
|
+
* Span across columns (for grid layout)
|
|
67
|
+
*/
|
|
68
|
+
span?: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Detail View Section/Group
|
|
73
|
+
*/
|
|
74
|
+
export interface DetailViewSection {
|
|
75
|
+
/**
|
|
76
|
+
* Section title
|
|
77
|
+
*/
|
|
78
|
+
title?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Section description
|
|
81
|
+
*/
|
|
82
|
+
description?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Section icon
|
|
85
|
+
*/
|
|
86
|
+
icon?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Fields in this section
|
|
89
|
+
*/
|
|
90
|
+
fields: DetailViewField[];
|
|
91
|
+
/**
|
|
92
|
+
* Collapsible section
|
|
93
|
+
*/
|
|
94
|
+
collapsible?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Default collapsed state
|
|
97
|
+
*/
|
|
98
|
+
defaultCollapsed?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Grid columns for field layout
|
|
101
|
+
*/
|
|
102
|
+
columns?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Section visibility condition
|
|
105
|
+
*/
|
|
106
|
+
visible?: boolean | string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Detail View Tab
|
|
111
|
+
*/
|
|
112
|
+
export interface DetailViewTab {
|
|
113
|
+
/**
|
|
114
|
+
* Tab key/identifier
|
|
115
|
+
*/
|
|
116
|
+
key: string;
|
|
117
|
+
/**
|
|
118
|
+
* Tab label
|
|
119
|
+
*/
|
|
120
|
+
label: string;
|
|
121
|
+
/**
|
|
122
|
+
* Tab icon
|
|
123
|
+
*/
|
|
124
|
+
icon?: string;
|
|
125
|
+
/**
|
|
126
|
+
* Tab content
|
|
127
|
+
*/
|
|
128
|
+
content: SchemaNode | SchemaNode[];
|
|
129
|
+
/**
|
|
130
|
+
* Tab visibility condition
|
|
131
|
+
*/
|
|
132
|
+
visible?: boolean | string;
|
|
133
|
+
/**
|
|
134
|
+
* Badge count
|
|
135
|
+
*/
|
|
136
|
+
badge?: string | number;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Detail View Schema - Display detailed information about a single record
|
|
141
|
+
* Enhanced in Phase 2 with better organization and features
|
|
142
|
+
*/
|
|
143
|
+
export interface DetailViewSchema extends BaseSchema {
|
|
144
|
+
type: 'detail-view';
|
|
145
|
+
/**
|
|
146
|
+
* Detail title
|
|
147
|
+
*/
|
|
148
|
+
title?: string;
|
|
149
|
+
/**
|
|
150
|
+
* API endpoint to fetch detail data
|
|
151
|
+
*/
|
|
152
|
+
api?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Resource ID to display
|
|
155
|
+
*/
|
|
156
|
+
resourceId?: string | number;
|
|
157
|
+
/**
|
|
158
|
+
* Object name (for ObjectQL integration)
|
|
159
|
+
*/
|
|
160
|
+
objectName?: string;
|
|
161
|
+
/**
|
|
162
|
+
* Data to display (if not fetching from API)
|
|
163
|
+
*/
|
|
164
|
+
data?: any;
|
|
165
|
+
/**
|
|
166
|
+
* Layout mode
|
|
167
|
+
*/
|
|
168
|
+
layout?: 'vertical' | 'horizontal' | 'grid';
|
|
169
|
+
/**
|
|
170
|
+
* Grid columns (for grid layout)
|
|
171
|
+
*/
|
|
172
|
+
columns?: number;
|
|
173
|
+
/**
|
|
174
|
+
* Field sections for organized display
|
|
175
|
+
*/
|
|
176
|
+
sections?: DetailViewSection[];
|
|
177
|
+
/**
|
|
178
|
+
* Direct fields (without sections)
|
|
179
|
+
*/
|
|
180
|
+
fields?: DetailViewField[];
|
|
181
|
+
/**
|
|
182
|
+
* Actions available in detail view
|
|
183
|
+
*/
|
|
184
|
+
actions?: ActionSchema[];
|
|
185
|
+
/**
|
|
186
|
+
* Tabs for additional content
|
|
187
|
+
*/
|
|
188
|
+
tabs?: DetailViewTab[];
|
|
189
|
+
/**
|
|
190
|
+
* Show back button
|
|
191
|
+
* @default true
|
|
192
|
+
*/
|
|
193
|
+
showBack?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Back button URL
|
|
196
|
+
*/
|
|
197
|
+
backUrl?: string;
|
|
198
|
+
/**
|
|
199
|
+
* Custom back action
|
|
200
|
+
*/
|
|
201
|
+
onBack?: string;
|
|
202
|
+
/**
|
|
203
|
+
* Show edit button
|
|
204
|
+
*/
|
|
205
|
+
showEdit?: boolean;
|
|
206
|
+
/**
|
|
207
|
+
* Edit button URL
|
|
208
|
+
*/
|
|
209
|
+
editUrl?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Show delete button
|
|
212
|
+
*/
|
|
213
|
+
showDelete?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Delete confirmation message
|
|
216
|
+
*/
|
|
217
|
+
deleteConfirmation?: string;
|
|
218
|
+
/**
|
|
219
|
+
* Whether to show loading state
|
|
220
|
+
* @default true
|
|
221
|
+
*/
|
|
222
|
+
loading?: boolean;
|
|
223
|
+
/**
|
|
224
|
+
* Custom header content
|
|
225
|
+
*/
|
|
226
|
+
header?: SchemaNode;
|
|
227
|
+
/**
|
|
228
|
+
* Custom footer content
|
|
229
|
+
*/
|
|
230
|
+
footer?: SchemaNode;
|
|
231
|
+
/**
|
|
232
|
+
* Navigation handler for SPA-aware routing.
|
|
233
|
+
* Called instead of window.location.href for back/edit navigation.
|
|
234
|
+
* @param url - The URL to navigate to
|
|
235
|
+
* @param options - Navigation options (replace, newTab, etc.)
|
|
236
|
+
*/
|
|
237
|
+
onNavigate?: (url: string, options?: { replace?: boolean; newTab?: boolean }) => void;
|
|
238
|
+
/**
|
|
239
|
+
* Related records section
|
|
240
|
+
*/
|
|
241
|
+
related?: Array<{
|
|
242
|
+
/**
|
|
243
|
+
* Relation title
|
|
244
|
+
*/
|
|
245
|
+
title: string;
|
|
246
|
+
/**
|
|
247
|
+
* Relation type
|
|
248
|
+
*/
|
|
249
|
+
type: 'list' | 'grid' | 'table';
|
|
250
|
+
/**
|
|
251
|
+
* API endpoint for related data
|
|
252
|
+
*/
|
|
253
|
+
api?: string;
|
|
254
|
+
/**
|
|
255
|
+
* Static data
|
|
256
|
+
*/
|
|
257
|
+
data?: any[];
|
|
258
|
+
/**
|
|
259
|
+
* Columns for table view
|
|
260
|
+
*/
|
|
261
|
+
columns?: TableColumn[];
|
|
262
|
+
/**
|
|
263
|
+
* Fields for list view
|
|
264
|
+
*/
|
|
265
|
+
fields?: string[];
|
|
266
|
+
}>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* View Switcher Schema - Toggle between different view modes
|
|
271
|
+
* New in Phase 2
|
|
272
|
+
*/
|
|
273
|
+
export interface ViewSwitcherSchema extends BaseSchema {
|
|
274
|
+
type: 'view-switcher';
|
|
275
|
+
/**
|
|
276
|
+
* Available view types
|
|
277
|
+
*/
|
|
278
|
+
views: Array<{
|
|
279
|
+
/**
|
|
280
|
+
* View type
|
|
281
|
+
*/
|
|
282
|
+
type: ViewType;
|
|
283
|
+
/**
|
|
284
|
+
* View label
|
|
285
|
+
*/
|
|
286
|
+
label?: string;
|
|
287
|
+
/**
|
|
288
|
+
* View icon
|
|
289
|
+
*/
|
|
290
|
+
icon?: string;
|
|
291
|
+
/**
|
|
292
|
+
* View schema
|
|
293
|
+
*/
|
|
294
|
+
schema?: SchemaNode;
|
|
295
|
+
}>;
|
|
296
|
+
/**
|
|
297
|
+
* Default/active view
|
|
298
|
+
*/
|
|
299
|
+
defaultView?: ViewType;
|
|
300
|
+
/**
|
|
301
|
+
* Current active view
|
|
302
|
+
*/
|
|
303
|
+
activeView?: ViewType;
|
|
304
|
+
/**
|
|
305
|
+
* Switcher variant
|
|
306
|
+
*/
|
|
307
|
+
variant?: 'tabs' | 'buttons' | 'dropdown';
|
|
308
|
+
/**
|
|
309
|
+
* Switcher position
|
|
310
|
+
*/
|
|
311
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
312
|
+
/**
|
|
313
|
+
* View change callback
|
|
314
|
+
*/
|
|
315
|
+
onViewChange?: string;
|
|
316
|
+
/**
|
|
317
|
+
* Persist view preference
|
|
318
|
+
*/
|
|
319
|
+
persistPreference?: boolean;
|
|
320
|
+
/**
|
|
321
|
+
* Storage key for persisting view
|
|
322
|
+
*/
|
|
323
|
+
storageKey?: string;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Filter UI Schema - Enhanced filter interface
|
|
328
|
+
* New in Phase 2
|
|
329
|
+
*/
|
|
330
|
+
export interface FilterUISchema extends BaseSchema {
|
|
331
|
+
type: 'filter-ui';
|
|
332
|
+
/**
|
|
333
|
+
* Available filters
|
|
334
|
+
*/
|
|
335
|
+
filters: Array<{
|
|
336
|
+
/**
|
|
337
|
+
* Filter field
|
|
338
|
+
*/
|
|
339
|
+
field: string;
|
|
340
|
+
/**
|
|
341
|
+
* Filter label
|
|
342
|
+
*/
|
|
343
|
+
label?: string;
|
|
344
|
+
/**
|
|
345
|
+
* Filter type
|
|
346
|
+
*/
|
|
347
|
+
type: 'text' | 'number' | 'select' | 'date' | 'date-range' | 'boolean';
|
|
348
|
+
/**
|
|
349
|
+
* Filter operator
|
|
350
|
+
*/
|
|
351
|
+
operator?: 'equals' | 'contains' | 'startsWith' | 'gt' | 'lt' | 'between' | 'in';
|
|
352
|
+
/**
|
|
353
|
+
* Options for select filter
|
|
354
|
+
*/
|
|
355
|
+
options?: Array<{ label: string; value: any }>;
|
|
356
|
+
/**
|
|
357
|
+
* Placeholder
|
|
358
|
+
*/
|
|
359
|
+
placeholder?: string;
|
|
360
|
+
}>;
|
|
361
|
+
/**
|
|
362
|
+
* Current filter values
|
|
363
|
+
*/
|
|
364
|
+
values?: Record<string, any>;
|
|
365
|
+
/**
|
|
366
|
+
* Filter change callback
|
|
367
|
+
*/
|
|
368
|
+
onChange?: string;
|
|
369
|
+
/**
|
|
370
|
+
* Show clear button
|
|
371
|
+
*/
|
|
372
|
+
showClear?: boolean;
|
|
373
|
+
/**
|
|
374
|
+
* Show apply button
|
|
375
|
+
*/
|
|
376
|
+
showApply?: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Filter layout
|
|
379
|
+
*/
|
|
380
|
+
layout?: 'inline' | 'popover' | 'drawer';
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Sort UI Schema - Enhanced sort interface
|
|
385
|
+
* New in Phase 2
|
|
386
|
+
*/
|
|
387
|
+
export interface SortUISchema extends BaseSchema {
|
|
388
|
+
type: 'sort-ui';
|
|
389
|
+
/**
|
|
390
|
+
* Sortable fields
|
|
391
|
+
*/
|
|
392
|
+
fields: Array<{
|
|
393
|
+
/**
|
|
394
|
+
* Field name
|
|
395
|
+
*/
|
|
396
|
+
field: string;
|
|
397
|
+
/**
|
|
398
|
+
* Field label
|
|
399
|
+
*/
|
|
400
|
+
label?: string;
|
|
401
|
+
}>;
|
|
402
|
+
/**
|
|
403
|
+
* Current sort configuration
|
|
404
|
+
*/
|
|
405
|
+
sort?: Array<{
|
|
406
|
+
/**
|
|
407
|
+
* Field to sort by
|
|
408
|
+
*/
|
|
409
|
+
field: string;
|
|
410
|
+
/**
|
|
411
|
+
* Sort direction
|
|
412
|
+
*/
|
|
413
|
+
direction: 'asc' | 'desc';
|
|
414
|
+
}>;
|
|
415
|
+
/**
|
|
416
|
+
* Sort change callback
|
|
417
|
+
*/
|
|
418
|
+
onChange?: string;
|
|
419
|
+
/**
|
|
420
|
+
* Allow multiple sort fields
|
|
421
|
+
*/
|
|
422
|
+
multiple?: boolean;
|
|
423
|
+
/**
|
|
424
|
+
* UI variant
|
|
425
|
+
*/
|
|
426
|
+
variant?: 'dropdown' | 'buttons';
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Union type of all view schemas
|
|
431
|
+
*/
|
|
432
|
+
export type ViewComponentSchema =
|
|
433
|
+
| DetailViewSchema
|
|
434
|
+
| ViewSwitcherSchema
|
|
435
|
+
| FilterUISchema
|
|
436
|
+
| SortUISchema;
|
package/src/widget.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @object-ui/types - Widget Manifest & Registry Types
|
|
11
|
+
*
|
|
12
|
+
* Defines the WidgetManifest interface for runtime widget registration,
|
|
13
|
+
* plugin auto-discovery from server metadata, and custom widget registry
|
|
14
|
+
* for user-defined components.
|
|
15
|
+
*
|
|
16
|
+
* @module widget
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Widget manifest describing a runtime-loadable widget.
|
|
22
|
+
*
|
|
23
|
+
* A manifest provides all metadata needed to discover, load, and render
|
|
24
|
+
* a widget without requiring an upfront import of its code.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* const manifest: WidgetManifest = {
|
|
29
|
+
* name: 'custom-chart',
|
|
30
|
+
* version: '1.0.0',
|
|
31
|
+
* type: 'chart',
|
|
32
|
+
* label: 'Custom Chart Widget',
|
|
33
|
+
* description: 'A custom chart powered by D3.',
|
|
34
|
+
* category: 'data-visualization',
|
|
35
|
+
* icon: 'BarChart',
|
|
36
|
+
* source: { type: 'module', url: '/widgets/custom-chart.js' },
|
|
37
|
+
* };
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export interface WidgetManifest {
|
|
41
|
+
/** Unique widget identifier (e.g., 'custom-chart', 'org.acme.table') */
|
|
42
|
+
name: string;
|
|
43
|
+
|
|
44
|
+
/** Semver version string */
|
|
45
|
+
version: string;
|
|
46
|
+
|
|
47
|
+
/** Component type key used for schema rendering (e.g., 'chart', 'grid') */
|
|
48
|
+
type: string;
|
|
49
|
+
|
|
50
|
+
/** Human-readable label for the widget */
|
|
51
|
+
label: string;
|
|
52
|
+
|
|
53
|
+
/** Short description of the widget */
|
|
54
|
+
description?: string;
|
|
55
|
+
|
|
56
|
+
/** Category for grouping in the designer palette */
|
|
57
|
+
category?: string;
|
|
58
|
+
|
|
59
|
+
/** Icon name (Lucide icon name) or SVG string */
|
|
60
|
+
icon?: string;
|
|
61
|
+
|
|
62
|
+
/** Thumbnail image URL for the designer palette */
|
|
63
|
+
thumbnail?: string;
|
|
64
|
+
|
|
65
|
+
/** Widget loading source configuration */
|
|
66
|
+
source: WidgetSource;
|
|
67
|
+
|
|
68
|
+
/** Required peer dependencies (e.g., { 'react': '^18.0.0' }) */
|
|
69
|
+
peerDependencies?: Record<string, string>;
|
|
70
|
+
|
|
71
|
+
/** Dependencies on other widgets by name */
|
|
72
|
+
dependencies?: string[];
|
|
73
|
+
|
|
74
|
+
/** Default props to apply when the widget is first dropped in the designer */
|
|
75
|
+
defaultProps?: Record<string, unknown>;
|
|
76
|
+
|
|
77
|
+
/** Input schema for the widget's configurable properties */
|
|
78
|
+
inputs?: WidgetInput[];
|
|
79
|
+
|
|
80
|
+
/** Whether the widget can contain child components */
|
|
81
|
+
isContainer?: boolean;
|
|
82
|
+
|
|
83
|
+
/** Widget capabilities */
|
|
84
|
+
capabilities?: WidgetCapabilities;
|
|
85
|
+
|
|
86
|
+
/** Additional metadata */
|
|
87
|
+
metadata?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Describes how to load the widget's code at runtime.
|
|
92
|
+
*/
|
|
93
|
+
export type WidgetSource =
|
|
94
|
+
| WidgetSourceModule
|
|
95
|
+
| WidgetSourceInline
|
|
96
|
+
| WidgetSourceRegistry;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Load from an ES module URL.
|
|
100
|
+
*
|
|
101
|
+
* ⚠️ SECURITY WARNING: Only use URLs from trusted sources.
|
|
102
|
+
* Never pass user-supplied URLs directly. URLs should be validated
|
|
103
|
+
* and controlled by your application. This feature uses dynamic imports
|
|
104
|
+
* which bypass static analysis and may be restricted by Content Security Policy.
|
|
105
|
+
*/
|
|
106
|
+
export interface WidgetSourceModule {
|
|
107
|
+
type: 'module';
|
|
108
|
+
/**
|
|
109
|
+
* URL to the ES module (e.g., '/widgets/chart.js' or 'https://cdn.example.com/widget.mjs')
|
|
110
|
+
* Must be from a trusted source - never user input.
|
|
111
|
+
*/
|
|
112
|
+
url: string;
|
|
113
|
+
/** Named export to use (default: 'default') */
|
|
114
|
+
exportName?: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** The component is provided inline (already loaded) */
|
|
118
|
+
export interface WidgetSourceInline {
|
|
119
|
+
type: 'inline';
|
|
120
|
+
/** The React component (already resolved) */
|
|
121
|
+
component: unknown;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** The component is registered in the global component registry */
|
|
125
|
+
export interface WidgetSourceRegistry {
|
|
126
|
+
type: 'registry';
|
|
127
|
+
/** The component type key in the registry */
|
|
128
|
+
registryKey: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Configurable input for a widget.
|
|
133
|
+
*/
|
|
134
|
+
export interface WidgetInput {
|
|
135
|
+
/** Input field name (maps to prop name) */
|
|
136
|
+
name: string;
|
|
137
|
+
/** Input field type */
|
|
138
|
+
type: 'string' | 'number' | 'boolean' | 'enum' | 'array' | 'object' | 'color' | 'date' | 'code' | 'file' | 'slot';
|
|
139
|
+
/** Human-readable label */
|
|
140
|
+
label?: string;
|
|
141
|
+
/** Default value */
|
|
142
|
+
defaultValue?: unknown;
|
|
143
|
+
/** Whether this input is required */
|
|
144
|
+
required?: boolean;
|
|
145
|
+
/** Enum options (for type: 'enum') */
|
|
146
|
+
options?: string[] | Array<{ label: string; value: unknown }>;
|
|
147
|
+
/** Help text */
|
|
148
|
+
description?: string;
|
|
149
|
+
/** Whether this is an advanced setting (hidden by default) */
|
|
150
|
+
advanced?: boolean;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Widget capabilities flag set.
|
|
155
|
+
*/
|
|
156
|
+
export interface WidgetCapabilities {
|
|
157
|
+
/** Widget supports data binding via dataSource */
|
|
158
|
+
dataBinding?: boolean;
|
|
159
|
+
/** Widget supports real-time updates */
|
|
160
|
+
realTime?: boolean;
|
|
161
|
+
/** Widget supports export (PDF, CSV, etc.) */
|
|
162
|
+
export?: boolean;
|
|
163
|
+
/** Widget supports responsive sizing */
|
|
164
|
+
responsive?: boolean;
|
|
165
|
+
/** Widget supports theming */
|
|
166
|
+
themeable?: boolean;
|
|
167
|
+
/** Widget supports drag and drop */
|
|
168
|
+
draggable?: boolean;
|
|
169
|
+
/** Widget supports resize */
|
|
170
|
+
resizable?: boolean;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Resolved widget: a manifest with its loaded component.
|
|
175
|
+
*/
|
|
176
|
+
export interface ResolvedWidget {
|
|
177
|
+
/** The original manifest */
|
|
178
|
+
manifest: WidgetManifest;
|
|
179
|
+
/** The loaded React component */
|
|
180
|
+
component: unknown;
|
|
181
|
+
/** Timestamp when the widget was loaded */
|
|
182
|
+
loadedAt: number;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Widget registry event types.
|
|
187
|
+
*/
|
|
188
|
+
export type WidgetRegistryEvent =
|
|
189
|
+
| { type: 'widget:registered'; widget: WidgetManifest }
|
|
190
|
+
| { type: 'widget:unregistered'; name: string }
|
|
191
|
+
| { type: 'widget:loaded'; widget: ResolvedWidget }
|
|
192
|
+
| { type: 'widget:error'; name: string; error: Error };
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Widget registry event listener.
|
|
196
|
+
*/
|
|
197
|
+
export type WidgetRegistryListener = (event: WidgetRegistryEvent) => void;
|