@praxisui/tabs 9.0.0-beta.11 → 9.0.0-beta.13
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/ai/component-registry.json +2056 -0
- package/package.json +9 -6
|
@@ -0,0 +1,2056 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0.0",
|
|
3
|
+
"generatedAt": "2026-06-22T22:56:44.148Z",
|
|
4
|
+
"packageName": "@praxisui/tabs",
|
|
5
|
+
"packageVersion": "9.0.0-beta.13",
|
|
6
|
+
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
|
+
"sourceRegistryVersion": "1.0.0",
|
|
8
|
+
"componentCount": 1,
|
|
9
|
+
"components": {
|
|
10
|
+
"praxis-tabs": {
|
|
11
|
+
"id": "praxis-tabs",
|
|
12
|
+
"description": "Abas dinâmicas baseadas em metadata, com MatTabGroup/TabNav e suporte a tokens M3 via appearance.",
|
|
13
|
+
"inputs": [
|
|
14
|
+
{
|
|
15
|
+
"name": "config",
|
|
16
|
+
"type": "TabsMetadata",
|
|
17
|
+
"required": false
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "tabsId",
|
|
21
|
+
"type": "string",
|
|
22
|
+
"required": false
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "componentInstanceId",
|
|
26
|
+
"type": "string",
|
|
27
|
+
"required": false
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "configPersistenceStrategy",
|
|
31
|
+
"type": "\"storage-first\" | \"input-first\"",
|
|
32
|
+
"required": false
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "selectedIndex",
|
|
36
|
+
"type": "number",
|
|
37
|
+
"required": false
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "enableCustomization",
|
|
41
|
+
"type": "boolean",
|
|
42
|
+
"required": false
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "form",
|
|
46
|
+
"type": "FormGroup",
|
|
47
|
+
"required": false
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "context",
|
|
51
|
+
"type": "Record<string, any>",
|
|
52
|
+
"required": false
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
"outputs": [
|
|
56
|
+
{
|
|
57
|
+
"name": "selectedIndexChange",
|
|
58
|
+
"type": "number",
|
|
59
|
+
"required": false
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "configChange",
|
|
63
|
+
"type": "TabsConfigChangeEvent",
|
|
64
|
+
"required": false
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "selectedTabChange",
|
|
68
|
+
"type": "MatTabChangeEvent",
|
|
69
|
+
"required": false
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "animationDone",
|
|
73
|
+
"type": "void",
|
|
74
|
+
"required": false
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "focusChange",
|
|
78
|
+
"type": "MatTabChangeEvent",
|
|
79
|
+
"required": false
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "indexFocused",
|
|
83
|
+
"type": "number",
|
|
84
|
+
"required": false
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "selectFocusedIndex",
|
|
88
|
+
"type": "number",
|
|
89
|
+
"required": false
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "widgetEvent",
|
|
93
|
+
"type": "WidgetEventEnvelope",
|
|
94
|
+
"required": false
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"configSchemaId": null,
|
|
98
|
+
"selector": "praxis-tabs",
|
|
99
|
+
"friendlyName": "Praxis Tabs",
|
|
100
|
+
"icon": "tab",
|
|
101
|
+
"tags": [
|
|
102
|
+
"widget",
|
|
103
|
+
"tabs",
|
|
104
|
+
"configurable",
|
|
105
|
+
"stable"
|
|
106
|
+
],
|
|
107
|
+
"lib": "@praxisui/tabs",
|
|
108
|
+
"source": "projects/praxis-tabs/src/lib/praxis-tabs.metadata.ts",
|
|
109
|
+
"exportName": "PRAXIS_TABS_COMPONENT_METADATA",
|
|
110
|
+
"componentCapabilities": [
|
|
111
|
+
{
|
|
112
|
+
"path": "meta",
|
|
113
|
+
"category": "meta",
|
|
114
|
+
"valueKind": "object",
|
|
115
|
+
"description": "Metadata bag for tabs."
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"path": "appearance",
|
|
119
|
+
"category": "appearance",
|
|
120
|
+
"valueKind": "object",
|
|
121
|
+
"description": "Appearance settings."
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"path": "appearance.density",
|
|
125
|
+
"category": "appearance",
|
|
126
|
+
"valueKind": "enum",
|
|
127
|
+
"allowedValues": [
|
|
128
|
+
"compact",
|
|
129
|
+
"comfortable",
|
|
130
|
+
"spacious"
|
|
131
|
+
],
|
|
132
|
+
"description": "Density preset."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"path": "appearance.themeClass",
|
|
136
|
+
"category": "appearance",
|
|
137
|
+
"valueKind": "string",
|
|
138
|
+
"description": "Theme CSS class applied to root."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"path": "appearance.customCss",
|
|
142
|
+
"category": "appearance",
|
|
143
|
+
"valueKind": "string",
|
|
144
|
+
"description": "Custom CSS injected into component.",
|
|
145
|
+
"safetyNotes": "CSS is injected as raw string."
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"path": "appearance.tokens",
|
|
149
|
+
"category": "appearance",
|
|
150
|
+
"valueKind": "object",
|
|
151
|
+
"description": "Style tokens mapped to runtime CSS."
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"path": "behavior",
|
|
155
|
+
"category": "behavior",
|
|
156
|
+
"valueKind": "object",
|
|
157
|
+
"description": "Behavior settings."
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"path": "behavior.lazyLoad",
|
|
161
|
+
"category": "behavior",
|
|
162
|
+
"valueKind": "boolean",
|
|
163
|
+
"description": "Lazy load tab content."
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"path": "behavior.closeable",
|
|
167
|
+
"category": "behavior",
|
|
168
|
+
"valueKind": "boolean",
|
|
169
|
+
"description": "Show close button on tabs."
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"path": "behavior.reorderable",
|
|
173
|
+
"category": "behavior",
|
|
174
|
+
"valueKind": "boolean",
|
|
175
|
+
"description": "Allow reorder tabs/links."
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"path": "accessibility",
|
|
179
|
+
"category": "accessibility",
|
|
180
|
+
"valueKind": "object",
|
|
181
|
+
"description": "Accessibility settings."
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"path": "accessibility.highContrast",
|
|
185
|
+
"category": "accessibility",
|
|
186
|
+
"valueKind": "boolean",
|
|
187
|
+
"description": "High contrast mode."
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"path": "accessibility.reduceMotion",
|
|
191
|
+
"category": "accessibility",
|
|
192
|
+
"valueKind": "boolean",
|
|
193
|
+
"description": "Reduce motion."
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"path": "group",
|
|
197
|
+
"category": "group",
|
|
198
|
+
"valueKind": "object",
|
|
199
|
+
"description": "MatTabGroup settings."
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"path": "group.alignTabs",
|
|
203
|
+
"category": "group",
|
|
204
|
+
"valueKind": "enum",
|
|
205
|
+
"allowedValues": [
|
|
206
|
+
"start",
|
|
207
|
+
"center",
|
|
208
|
+
"end"
|
|
209
|
+
],
|
|
210
|
+
"description": "Align tabs in header."
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"path": "group.animationDuration",
|
|
214
|
+
"category": "group",
|
|
215
|
+
"valueKind": "string",
|
|
216
|
+
"description": "Animation duration (e.g., 500ms)."
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"path": "group.ariaLabel",
|
|
220
|
+
"category": "group",
|
|
221
|
+
"valueKind": "string",
|
|
222
|
+
"description": "aria-label for tab group."
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"path": "group.ariaLabelledby",
|
|
226
|
+
"category": "group",
|
|
227
|
+
"valueKind": "string",
|
|
228
|
+
"description": "aria-labelledby for tab group."
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"path": "group.color",
|
|
232
|
+
"category": "group",
|
|
233
|
+
"valueKind": "enum",
|
|
234
|
+
"allowedValues": [
|
|
235
|
+
"primary",
|
|
236
|
+
"accent",
|
|
237
|
+
"warn"
|
|
238
|
+
],
|
|
239
|
+
"description": "M2 color."
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"path": "group.backgroundColor",
|
|
243
|
+
"category": "group",
|
|
244
|
+
"valueKind": "enum",
|
|
245
|
+
"allowedValues": [
|
|
246
|
+
"primary",
|
|
247
|
+
"accent",
|
|
248
|
+
"warn"
|
|
249
|
+
],
|
|
250
|
+
"description": "M2 background color."
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"path": "group.disablePagination",
|
|
254
|
+
"category": "group",
|
|
255
|
+
"valueKind": "boolean",
|
|
256
|
+
"description": "Disable pagination of header."
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"path": "group.disableRipple",
|
|
260
|
+
"category": "group",
|
|
261
|
+
"valueKind": "boolean",
|
|
262
|
+
"description": "Disable ripple."
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"path": "group.dynamicHeight",
|
|
266
|
+
"category": "group",
|
|
267
|
+
"valueKind": "boolean",
|
|
268
|
+
"description": "Enable dynamic height."
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"path": "group.fitInkBarToContent",
|
|
272
|
+
"category": "group",
|
|
273
|
+
"valueKind": "boolean",
|
|
274
|
+
"description": "Fit ink bar to content."
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"path": "group.headerPosition",
|
|
278
|
+
"category": "group",
|
|
279
|
+
"valueKind": "enum",
|
|
280
|
+
"allowedValues": [
|
|
281
|
+
"above",
|
|
282
|
+
"below"
|
|
283
|
+
],
|
|
284
|
+
"description": "Header position."
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"path": "group.preserveContent",
|
|
288
|
+
"category": "group",
|
|
289
|
+
"valueKind": "boolean",
|
|
290
|
+
"description": "Preserve content of inactive tabs."
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"path": "group.selectedIndex",
|
|
294
|
+
"category": "group",
|
|
295
|
+
"valueKind": "number",
|
|
296
|
+
"description": "Selected tab index."
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"path": "group.stretchTabs",
|
|
300
|
+
"category": "group",
|
|
301
|
+
"valueKind": "boolean",
|
|
302
|
+
"description": "Stretch tabs."
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"path": "nav",
|
|
306
|
+
"category": "nav",
|
|
307
|
+
"valueKind": "object",
|
|
308
|
+
"description": "Tab nav settings."
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"path": "nav.animationDuration",
|
|
312
|
+
"category": "nav",
|
|
313
|
+
"valueKind": "string",
|
|
314
|
+
"description": "Animation duration (e.g., 500ms)."
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"path": "nav.ariaLabel",
|
|
318
|
+
"category": "nav",
|
|
319
|
+
"valueKind": "string",
|
|
320
|
+
"description": "aria-label for nav mode."
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
"path": "nav.ariaLabelledby",
|
|
324
|
+
"category": "nav",
|
|
325
|
+
"valueKind": "string",
|
|
326
|
+
"description": "aria-labelledby for nav mode."
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"path": "nav.color",
|
|
330
|
+
"category": "nav",
|
|
331
|
+
"valueKind": "enum",
|
|
332
|
+
"allowedValues": [
|
|
333
|
+
"primary",
|
|
334
|
+
"accent",
|
|
335
|
+
"warn"
|
|
336
|
+
],
|
|
337
|
+
"description": "M2 color."
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"path": "nav.backgroundColor",
|
|
341
|
+
"category": "nav",
|
|
342
|
+
"valueKind": "enum",
|
|
343
|
+
"allowedValues": [
|
|
344
|
+
"primary",
|
|
345
|
+
"accent",
|
|
346
|
+
"warn"
|
|
347
|
+
],
|
|
348
|
+
"description": "M2 background color."
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"path": "nav.disablePagination",
|
|
352
|
+
"category": "nav",
|
|
353
|
+
"valueKind": "boolean",
|
|
354
|
+
"description": "Disable pagination of nav."
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"path": "nav.disableRipple",
|
|
358
|
+
"category": "nav",
|
|
359
|
+
"valueKind": "boolean",
|
|
360
|
+
"description": "Disable ripple."
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"path": "nav.fitInkBarToContent",
|
|
364
|
+
"category": "nav",
|
|
365
|
+
"valueKind": "boolean",
|
|
366
|
+
"description": "Fit ink bar to content."
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"path": "nav.selectedIndex",
|
|
370
|
+
"category": "nav",
|
|
371
|
+
"valueKind": "number",
|
|
372
|
+
"description": "Selected nav link index."
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"path": "nav.stretchTabs",
|
|
376
|
+
"category": "nav",
|
|
377
|
+
"valueKind": "boolean",
|
|
378
|
+
"description": "Stretch nav tabs."
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"path": "nav.links",
|
|
382
|
+
"category": "nav",
|
|
383
|
+
"valueKind": "array",
|
|
384
|
+
"description": "Nav links array."
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"path": "nav.links[].id",
|
|
388
|
+
"category": "nav",
|
|
389
|
+
"valueKind": "string",
|
|
390
|
+
"description": "Link id."
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"path": "nav.links[].label",
|
|
394
|
+
"category": "nav",
|
|
395
|
+
"valueKind": "string",
|
|
396
|
+
"description": "Link label."
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"path": "nav.links[].active",
|
|
400
|
+
"category": "nav",
|
|
401
|
+
"valueKind": "boolean",
|
|
402
|
+
"description": "Link active flag."
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"path": "nav.links[].disabled",
|
|
406
|
+
"category": "nav",
|
|
407
|
+
"valueKind": "boolean",
|
|
408
|
+
"description": "Disable link."
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"path": "nav.links[].disableRipple",
|
|
412
|
+
"category": "nav",
|
|
413
|
+
"valueKind": "boolean",
|
|
414
|
+
"description": "Disable ripple on link."
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"path": "nav.links[].fitInkBarToContent",
|
|
418
|
+
"category": "nav",
|
|
419
|
+
"valueKind": "boolean",
|
|
420
|
+
"description": "Fit ink bar to link content."
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"path": "nav.links[].content",
|
|
424
|
+
"category": "nav",
|
|
425
|
+
"valueKind": "array",
|
|
426
|
+
"description": "Dynamic field metadata list."
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
"path": "nav.links[].widgets",
|
|
430
|
+
"category": "nav",
|
|
431
|
+
"valueKind": "array",
|
|
432
|
+
"description": "Widget definitions for link content."
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"path": "tabs",
|
|
436
|
+
"category": "tabs",
|
|
437
|
+
"valueKind": "array",
|
|
438
|
+
"description": "Tabs array."
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"path": "tabs[].id",
|
|
442
|
+
"category": "tabs",
|
|
443
|
+
"valueKind": "string",
|
|
444
|
+
"description": "Tab id."
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"path": "tabs[].textLabel",
|
|
448
|
+
"category": "tabs",
|
|
449
|
+
"valueKind": "string",
|
|
450
|
+
"description": "Tab label."
|
|
451
|
+
},
|
|
452
|
+
{
|
|
453
|
+
"path": "tabs[].labelClass",
|
|
454
|
+
"category": "tabs",
|
|
455
|
+
"valueKind": "string",
|
|
456
|
+
"description": "Label class (string or string[])."
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"path": "tabs[].bodyClass",
|
|
460
|
+
"category": "tabs",
|
|
461
|
+
"valueKind": "string",
|
|
462
|
+
"description": "Body class (string or string[])."
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
"path": "tabs[].ariaLabel",
|
|
466
|
+
"category": "tabs",
|
|
467
|
+
"valueKind": "string",
|
|
468
|
+
"description": "aria-label for tab."
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"path": "tabs[].ariaLabelledby",
|
|
472
|
+
"category": "tabs",
|
|
473
|
+
"valueKind": "string",
|
|
474
|
+
"description": "aria-labelledby for tab."
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
"path": "tabs[].disabled",
|
|
478
|
+
"category": "tabs",
|
|
479
|
+
"valueKind": "boolean",
|
|
480
|
+
"description": "Disable tab."
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"path": "tabs[].content",
|
|
484
|
+
"category": "tabs",
|
|
485
|
+
"valueKind": "array",
|
|
486
|
+
"description": "Dynamic field metadata list."
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"path": "tabs[].widgets",
|
|
490
|
+
"category": "tabs",
|
|
491
|
+
"valueKind": "array",
|
|
492
|
+
"description": "Widget definitions for tab content."
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
"path": "tabs[].isActive",
|
|
496
|
+
"category": "tabs",
|
|
497
|
+
"valueKind": "boolean",
|
|
498
|
+
"description": "Active flag (metadata only)."
|
|
499
|
+
},
|
|
500
|
+
{
|
|
501
|
+
"path": "tabs[].origin",
|
|
502
|
+
"category": "tabs",
|
|
503
|
+
"valueKind": "number",
|
|
504
|
+
"description": "Origin index (metadata only)."
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"path": "tabs[].position",
|
|
508
|
+
"category": "tabs",
|
|
509
|
+
"valueKind": "number",
|
|
510
|
+
"description": "Position index (metadata only)."
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
"path": "events",
|
|
514
|
+
"category": "events",
|
|
515
|
+
"valueKind": "object",
|
|
516
|
+
"description": "Event config (placeholder)."
|
|
517
|
+
}
|
|
518
|
+
],
|
|
519
|
+
"componentCapabilityNotes": [
|
|
520
|
+
"TabsMetadata drives both group and nav modes. Use nav.* when links are present.",
|
|
521
|
+
"appearance.customCss is injected into a <style> tag; avoid unsafe CSS from untrusted sources.",
|
|
522
|
+
"tabs[].content expects DynamicFieldMetadata[] and widgets[] expects WidgetDefinition[]."
|
|
523
|
+
],
|
|
524
|
+
"componentContext": {
|
|
525
|
+
"version": "v1",
|
|
526
|
+
"optionsByPath": {
|
|
527
|
+
"appearance.density": {
|
|
528
|
+
"mode": "enum",
|
|
529
|
+
"options": [
|
|
530
|
+
{
|
|
531
|
+
"value": "compact",
|
|
532
|
+
"label": "Compact"
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
"value": "comfortable",
|
|
536
|
+
"label": "Comfortable"
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
"value": "spacious",
|
|
540
|
+
"label": "Spacious"
|
|
541
|
+
}
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
"group.alignTabs": {
|
|
545
|
+
"mode": "enum",
|
|
546
|
+
"options": [
|
|
547
|
+
{
|
|
548
|
+
"value": "start",
|
|
549
|
+
"label": "Start"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
"value": "center",
|
|
553
|
+
"label": "Center"
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"value": "end",
|
|
557
|
+
"label": "End"
|
|
558
|
+
}
|
|
559
|
+
]
|
|
560
|
+
},
|
|
561
|
+
"group.headerPosition": {
|
|
562
|
+
"mode": "enum",
|
|
563
|
+
"options": [
|
|
564
|
+
{
|
|
565
|
+
"value": "above",
|
|
566
|
+
"label": "Above"
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"value": "below",
|
|
570
|
+
"label": "Below"
|
|
571
|
+
}
|
|
572
|
+
]
|
|
573
|
+
},
|
|
574
|
+
"group.color": {
|
|
575
|
+
"mode": "enum",
|
|
576
|
+
"options": [
|
|
577
|
+
{
|
|
578
|
+
"value": "primary",
|
|
579
|
+
"label": "Primary"
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
"value": "accent",
|
|
583
|
+
"label": "Accent"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
"value": "warn",
|
|
587
|
+
"label": "Warn"
|
|
588
|
+
}
|
|
589
|
+
]
|
|
590
|
+
},
|
|
591
|
+
"group.backgroundColor": {
|
|
592
|
+
"mode": "enum",
|
|
593
|
+
"options": [
|
|
594
|
+
{
|
|
595
|
+
"value": "primary",
|
|
596
|
+
"label": "Primary"
|
|
597
|
+
},
|
|
598
|
+
{
|
|
599
|
+
"value": "accent",
|
|
600
|
+
"label": "Accent"
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"value": "warn",
|
|
604
|
+
"label": "Warn"
|
|
605
|
+
}
|
|
606
|
+
]
|
|
607
|
+
},
|
|
608
|
+
"nav.color": {
|
|
609
|
+
"mode": "enum",
|
|
610
|
+
"options": [
|
|
611
|
+
{
|
|
612
|
+
"value": "primary",
|
|
613
|
+
"label": "Primary"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"value": "accent",
|
|
617
|
+
"label": "Accent"
|
|
618
|
+
},
|
|
619
|
+
{
|
|
620
|
+
"value": "warn",
|
|
621
|
+
"label": "Warn"
|
|
622
|
+
}
|
|
623
|
+
]
|
|
624
|
+
},
|
|
625
|
+
"nav.backgroundColor": {
|
|
626
|
+
"mode": "enum",
|
|
627
|
+
"options": [
|
|
628
|
+
{
|
|
629
|
+
"value": "primary",
|
|
630
|
+
"label": "Primary"
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
"value": "accent",
|
|
634
|
+
"label": "Accent"
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
"value": "warn",
|
|
638
|
+
"label": "Warn"
|
|
639
|
+
}
|
|
640
|
+
]
|
|
641
|
+
}
|
|
642
|
+
},
|
|
643
|
+
"actionCatalog": [
|
|
644
|
+
{
|
|
645
|
+
"id": "appearance.density.set",
|
|
646
|
+
"intentExamples": [
|
|
647
|
+
"density",
|
|
648
|
+
"compact",
|
|
649
|
+
"spacious"
|
|
650
|
+
],
|
|
651
|
+
"patchTemplate": {
|
|
652
|
+
"appearance": {
|
|
653
|
+
"density": "{{value}}"
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
"id": "group.alignTabs.set",
|
|
659
|
+
"intentExamples": [
|
|
660
|
+
"align tabs",
|
|
661
|
+
"tab alignment",
|
|
662
|
+
"align header"
|
|
663
|
+
],
|
|
664
|
+
"patchTemplate": {
|
|
665
|
+
"group": {
|
|
666
|
+
"alignTabs": "{{value}}"
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
},
|
|
670
|
+
{
|
|
671
|
+
"id": "group.headerPosition.set",
|
|
672
|
+
"intentExamples": [
|
|
673
|
+
"header position",
|
|
674
|
+
"tabs position"
|
|
675
|
+
],
|
|
676
|
+
"patchTemplate": {
|
|
677
|
+
"group": {
|
|
678
|
+
"headerPosition": "{{value}}"
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
"id": "group.selectedIndex.set",
|
|
684
|
+
"intentExamples": [
|
|
685
|
+
"select tab",
|
|
686
|
+
"active tab",
|
|
687
|
+
"selected index"
|
|
688
|
+
],
|
|
689
|
+
"patchTemplate": {
|
|
690
|
+
"group": {
|
|
691
|
+
"selectedIndex": "{{value}}"
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"id": "nav.selectedIndex.set",
|
|
697
|
+
"intentExamples": [
|
|
698
|
+
"select link",
|
|
699
|
+
"active link",
|
|
700
|
+
"selected nav"
|
|
701
|
+
],
|
|
702
|
+
"patchTemplate": {
|
|
703
|
+
"nav": {
|
|
704
|
+
"selectedIndex": "{{value}}"
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
"id": "behavior.lazyLoad.enable",
|
|
710
|
+
"intentExamples": [
|
|
711
|
+
"lazy load",
|
|
712
|
+
"load on demand",
|
|
713
|
+
"lazy"
|
|
714
|
+
],
|
|
715
|
+
"patchTemplate": {
|
|
716
|
+
"behavior": {
|
|
717
|
+
"lazyLoad": true
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
"id": "behavior.lazyLoad.disable",
|
|
723
|
+
"intentExamples": [
|
|
724
|
+
"no lazy",
|
|
725
|
+
"eager load"
|
|
726
|
+
],
|
|
727
|
+
"patchTemplate": {
|
|
728
|
+
"behavior": {
|
|
729
|
+
"lazyLoad": false
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
{
|
|
734
|
+
"id": "group.stretchTabs.enable",
|
|
735
|
+
"intentExamples": [
|
|
736
|
+
"stretch tabs",
|
|
737
|
+
"full width tabs"
|
|
738
|
+
],
|
|
739
|
+
"patchTemplate": {
|
|
740
|
+
"group": {
|
|
741
|
+
"stretchTabs": true
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
"id": "group.stretchTabs.disable",
|
|
747
|
+
"intentExamples": [
|
|
748
|
+
"no stretch tabs",
|
|
749
|
+
"compact tabs"
|
|
750
|
+
],
|
|
751
|
+
"patchTemplate": {
|
|
752
|
+
"group": {
|
|
753
|
+
"stretchTabs": false
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
"id": "group.disablePagination.enable",
|
|
759
|
+
"intentExamples": [
|
|
760
|
+
"disable pagination",
|
|
761
|
+
"no pagination"
|
|
762
|
+
],
|
|
763
|
+
"patchTemplate": {
|
|
764
|
+
"group": {
|
|
765
|
+
"disablePagination": true
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
"id": "group.disablePagination.disable",
|
|
771
|
+
"intentExamples": [
|
|
772
|
+
"enable pagination",
|
|
773
|
+
"allow pagination"
|
|
774
|
+
],
|
|
775
|
+
"patchTemplate": {
|
|
776
|
+
"group": {
|
|
777
|
+
"disablePagination": false
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
"id": "tab.add",
|
|
783
|
+
"intentExamples": [
|
|
784
|
+
"add tab",
|
|
785
|
+
"new tab",
|
|
786
|
+
"create tab",
|
|
787
|
+
"nova aba",
|
|
788
|
+
"adicionar aba",
|
|
789
|
+
"criar aba"
|
|
790
|
+
],
|
|
791
|
+
"patchTemplate": {
|
|
792
|
+
"tabs": [
|
|
793
|
+
{
|
|
794
|
+
"id": "{{target}}",
|
|
795
|
+
"textLabel": "{{value}}"
|
|
796
|
+
}
|
|
797
|
+
]
|
|
798
|
+
}
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
"id": "tab.content.set",
|
|
802
|
+
"intentExamples": [
|
|
803
|
+
"tab content",
|
|
804
|
+
"current tab content",
|
|
805
|
+
"add widget to tab",
|
|
806
|
+
"list in current tab",
|
|
807
|
+
"inside tab",
|
|
808
|
+
"conteudo da aba",
|
|
809
|
+
"nesta aba",
|
|
810
|
+
"aba atual",
|
|
811
|
+
"componente dentro da aba"
|
|
812
|
+
],
|
|
813
|
+
"patchTemplate": {
|
|
814
|
+
"tabs": [
|
|
815
|
+
{
|
|
816
|
+
"id": "{{target}}",
|
|
817
|
+
"content": "{{params.content}}",
|
|
818
|
+
"widgets": "{{params.widgets}}"
|
|
819
|
+
}
|
|
820
|
+
]
|
|
821
|
+
}
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
"id": "tab.label.set",
|
|
825
|
+
"intentExamples": [
|
|
826
|
+
"rename tab",
|
|
827
|
+
"tab label",
|
|
828
|
+
"tab title"
|
|
829
|
+
],
|
|
830
|
+
"patchTemplate": {
|
|
831
|
+
"tabs": [
|
|
832
|
+
{
|
|
833
|
+
"id": "{{target}}",
|
|
834
|
+
"textLabel": "{{value}}"
|
|
835
|
+
}
|
|
836
|
+
]
|
|
837
|
+
}
|
|
838
|
+
},
|
|
839
|
+
{
|
|
840
|
+
"id": "tab.disable",
|
|
841
|
+
"intentExamples": [
|
|
842
|
+
"disable tab",
|
|
843
|
+
"lock tab"
|
|
844
|
+
],
|
|
845
|
+
"patchTemplate": {
|
|
846
|
+
"tabs": [
|
|
847
|
+
{
|
|
848
|
+
"id": "{{target}}",
|
|
849
|
+
"disabled": true
|
|
850
|
+
}
|
|
851
|
+
]
|
|
852
|
+
}
|
|
853
|
+
},
|
|
854
|
+
{
|
|
855
|
+
"id": "tab.enable",
|
|
856
|
+
"intentExamples": [
|
|
857
|
+
"enable tab",
|
|
858
|
+
"unlock tab"
|
|
859
|
+
],
|
|
860
|
+
"patchTemplate": {
|
|
861
|
+
"tabs": [
|
|
862
|
+
{
|
|
863
|
+
"id": "{{target}}",
|
|
864
|
+
"disabled": false
|
|
865
|
+
}
|
|
866
|
+
]
|
|
867
|
+
}
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
"id": "nav.link.add",
|
|
871
|
+
"intentExamples": [
|
|
872
|
+
"add link",
|
|
873
|
+
"add nav link",
|
|
874
|
+
"new link"
|
|
875
|
+
],
|
|
876
|
+
"patchTemplate": {
|
|
877
|
+
"nav": {
|
|
878
|
+
"links": [
|
|
879
|
+
{
|
|
880
|
+
"id": "{{target}}",
|
|
881
|
+
"label": "{{value}}"
|
|
882
|
+
}
|
|
883
|
+
]
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
"id": "nav.link.label.set",
|
|
889
|
+
"intentExamples": [
|
|
890
|
+
"rename link",
|
|
891
|
+
"link label"
|
|
892
|
+
],
|
|
893
|
+
"patchTemplate": {
|
|
894
|
+
"nav": {
|
|
895
|
+
"links": [
|
|
896
|
+
{
|
|
897
|
+
"id": "{{target}}",
|
|
898
|
+
"label": "{{value}}"
|
|
899
|
+
}
|
|
900
|
+
]
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
"id": "nav.link.disable",
|
|
906
|
+
"intentExamples": [
|
|
907
|
+
"disable link",
|
|
908
|
+
"lock link"
|
|
909
|
+
],
|
|
910
|
+
"patchTemplate": {
|
|
911
|
+
"nav": {
|
|
912
|
+
"links": [
|
|
913
|
+
{
|
|
914
|
+
"id": "{{target}}",
|
|
915
|
+
"disabled": true
|
|
916
|
+
}
|
|
917
|
+
]
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
"id": "nav.link.enable",
|
|
923
|
+
"intentExamples": [
|
|
924
|
+
"enable link",
|
|
925
|
+
"unlock link"
|
|
926
|
+
],
|
|
927
|
+
"patchTemplate": {
|
|
928
|
+
"nav": {
|
|
929
|
+
"links": [
|
|
930
|
+
{
|
|
931
|
+
"id": "{{target}}",
|
|
932
|
+
"disabled": false
|
|
933
|
+
}
|
|
934
|
+
]
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
],
|
|
939
|
+
"fieldResolvers": {
|
|
940
|
+
"tabs[]": [
|
|
941
|
+
"id",
|
|
942
|
+
"textLabel"
|
|
943
|
+
],
|
|
944
|
+
"nav.links[]": [
|
|
945
|
+
"id",
|
|
946
|
+
"label"
|
|
947
|
+
]
|
|
948
|
+
},
|
|
949
|
+
"hints": [
|
|
950
|
+
"Use tabs[].id or tabs[].textLabel as merge keys; avoid array indexes.",
|
|
951
|
+
"When using nav mode, prefer nav.links[]; when using group mode, prefer tabs[].",
|
|
952
|
+
"Selected index expects a zero-based number.",
|
|
953
|
+
"DOC: Widget purpose: tabs or nav links with dynamic content.",
|
|
954
|
+
"DOC: Host inputs: tabsId (required), config (optional), and configPersistenceStrategy. Use input-first for governed previews that must render the explicit nested widget config.",
|
|
955
|
+
"DOC: Provide either tabs[] (group mode) or nav.links[] (nav mode).",
|
|
956
|
+
"DOC: Each tab/link should define a label (tabs[].textLabel or nav.links[].label)."
|
|
957
|
+
]
|
|
958
|
+
},
|
|
959
|
+
"authoringManifest": {
|
|
960
|
+
"schemaVersion": "1.0.0",
|
|
961
|
+
"componentId": "praxis-tabs",
|
|
962
|
+
"ownerPackage": "@praxisui/tabs",
|
|
963
|
+
"configSchemaId": "TabsMetadata",
|
|
964
|
+
"manifestVersion": "1.0.0",
|
|
965
|
+
"runtimeInputs": [
|
|
966
|
+
{
|
|
967
|
+
"name": "config",
|
|
968
|
+
"type": "TabsMetadata",
|
|
969
|
+
"description": "Canonical tabs/nav configuration."
|
|
970
|
+
},
|
|
971
|
+
{
|
|
972
|
+
"name": "tabsId",
|
|
973
|
+
"type": "string",
|
|
974
|
+
"description": "Stable id used to derive persistence scope."
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
"name": "componentInstanceId",
|
|
978
|
+
"type": "string",
|
|
979
|
+
"description": "Optional instance discriminator for persistence scope."
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
"name": "configPersistenceStrategy",
|
|
983
|
+
"type": "\"storage-first\" | \"input-first\"",
|
|
984
|
+
"description": "Controls whether persisted customization or explicit input config governs the runtime. Governed previews with nested widgets should use input-first."
|
|
985
|
+
},
|
|
986
|
+
{
|
|
987
|
+
"name": "form",
|
|
988
|
+
"type": "FormGroup",
|
|
989
|
+
"description": "FormGroup consumed by dynamic field content."
|
|
990
|
+
},
|
|
991
|
+
{
|
|
992
|
+
"name": "context",
|
|
993
|
+
"type": "Record<string, any>",
|
|
994
|
+
"description": "Context passed to nested widgets."
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
"name": "enableCustomization",
|
|
998
|
+
"type": "boolean",
|
|
999
|
+
"description": "Enables Settings Panel authoring surfaces."
|
|
1000
|
+
}
|
|
1001
|
+
],
|
|
1002
|
+
"editableTargets": [
|
|
1003
|
+
{
|
|
1004
|
+
"kind": "tab",
|
|
1005
|
+
"resolver": "tab-by-id-or-label",
|
|
1006
|
+
"description": "A group-mode tab in config.tabs[]."
|
|
1007
|
+
},
|
|
1008
|
+
{
|
|
1009
|
+
"kind": "tabLabel",
|
|
1010
|
+
"resolver": "tab-by-id-or-label",
|
|
1011
|
+
"description": "The text label of a group-mode tab."
|
|
1012
|
+
},
|
|
1013
|
+
{
|
|
1014
|
+
"kind": "tabIcon",
|
|
1015
|
+
"resolver": "tab-by-id-or-label",
|
|
1016
|
+
"description": "Icon metadata rendered in a group tab label."
|
|
1017
|
+
},
|
|
1018
|
+
{
|
|
1019
|
+
"kind": "tabContent",
|
|
1020
|
+
"resolver": "tab-or-link-by-id",
|
|
1021
|
+
"description": "Dynamic fields or widgets hosted by a tab or nav link."
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
"kind": "activeTab",
|
|
1025
|
+
"resolver": "tab-index-or-id",
|
|
1026
|
+
"description": "Selected tab or nav link index."
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
"kind": "visibility",
|
|
1030
|
+
"resolver": "tab-or-link-by-id",
|
|
1031
|
+
"description": "Runtime visibility flag for a group tab or nav link."
|
|
1032
|
+
},
|
|
1033
|
+
{
|
|
1034
|
+
"kind": "disabledState",
|
|
1035
|
+
"resolver": "tab-or-link-by-id",
|
|
1036
|
+
"description": "Disabled state of a tab or nav link."
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
"kind": "layout",
|
|
1040
|
+
"resolver": "tabs-layout-config",
|
|
1041
|
+
"description": "Group/nav mode, header position, density, stretch and behavior settings."
|
|
1042
|
+
}
|
|
1043
|
+
],
|
|
1044
|
+
"operations": [
|
|
1045
|
+
{
|
|
1046
|
+
"operationId": "tab.add",
|
|
1047
|
+
"title": "Add tab",
|
|
1048
|
+
"scope": "global",
|
|
1049
|
+
"targetKind": "tab",
|
|
1050
|
+
"target": {
|
|
1051
|
+
"kind": "tab",
|
|
1052
|
+
"resolver": "tabs-array",
|
|
1053
|
+
"ambiguityPolicy": "fail",
|
|
1054
|
+
"required": false
|
|
1055
|
+
},
|
|
1056
|
+
"inputSchema": {
|
|
1057
|
+
"type": "object",
|
|
1058
|
+
"required": [
|
|
1059
|
+
"id",
|
|
1060
|
+
"textLabel"
|
|
1061
|
+
],
|
|
1062
|
+
"properties": {
|
|
1063
|
+
"id": {
|
|
1064
|
+
"type": "string"
|
|
1065
|
+
},
|
|
1066
|
+
"textLabel": {
|
|
1067
|
+
"type": "string"
|
|
1068
|
+
},
|
|
1069
|
+
"icon": {
|
|
1070
|
+
"type": "string"
|
|
1071
|
+
},
|
|
1072
|
+
"disabled": {
|
|
1073
|
+
"type": "boolean"
|
|
1074
|
+
},
|
|
1075
|
+
"visible": {
|
|
1076
|
+
"type": "boolean",
|
|
1077
|
+
"default": true
|
|
1078
|
+
},
|
|
1079
|
+
"content": {
|
|
1080
|
+
"type": "array",
|
|
1081
|
+
"items": {
|
|
1082
|
+
"type": "object"
|
|
1083
|
+
}
|
|
1084
|
+
},
|
|
1085
|
+
"widgets": {
|
|
1086
|
+
"type": "array",
|
|
1087
|
+
"items": {
|
|
1088
|
+
"type": "object"
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
},
|
|
1093
|
+
"effects": [
|
|
1094
|
+
{
|
|
1095
|
+
"kind": "append-unique",
|
|
1096
|
+
"path": "tabs[]",
|
|
1097
|
+
"key": "id"
|
|
1098
|
+
}
|
|
1099
|
+
],
|
|
1100
|
+
"validators": [
|
|
1101
|
+
"tab-id-unique",
|
|
1102
|
+
"tabs-mode-compatible",
|
|
1103
|
+
"tab-content-valid"
|
|
1104
|
+
],
|
|
1105
|
+
"destructive": false,
|
|
1106
|
+
"requiresConfirmation": false,
|
|
1107
|
+
"affectedPaths": [
|
|
1108
|
+
"tabs[]"
|
|
1109
|
+
],
|
|
1110
|
+
"submissionImpact": "config-only",
|
|
1111
|
+
"preconditions": [
|
|
1112
|
+
"config-initialized"
|
|
1113
|
+
]
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
"operationId": "tab.remove",
|
|
1117
|
+
"title": "Remove tab",
|
|
1118
|
+
"scope": "layout",
|
|
1119
|
+
"targetKind": "tab",
|
|
1120
|
+
"target": {
|
|
1121
|
+
"kind": "tab",
|
|
1122
|
+
"resolver": "tab-by-id-or-label",
|
|
1123
|
+
"ambiguityPolicy": "fail",
|
|
1124
|
+
"required": true
|
|
1125
|
+
},
|
|
1126
|
+
"inputSchema": {
|
|
1127
|
+
"type": "object",
|
|
1128
|
+
"properties": {
|
|
1129
|
+
"replacementActiveTabId": {
|
|
1130
|
+
"type": "string"
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
},
|
|
1134
|
+
"effects": [
|
|
1135
|
+
{
|
|
1136
|
+
"kind": "compile-domain-patch",
|
|
1137
|
+
"handler": "tabs.remove-tab-and-reselect",
|
|
1138
|
+
"handlerContract": {
|
|
1139
|
+
"reads": [
|
|
1140
|
+
"tabs[]",
|
|
1141
|
+
"group.selectedIndex"
|
|
1142
|
+
],
|
|
1143
|
+
"writes": [
|
|
1144
|
+
"tabs[]",
|
|
1145
|
+
"group.selectedIndex"
|
|
1146
|
+
],
|
|
1147
|
+
"identityKeys": [
|
|
1148
|
+
"tabs[].id"
|
|
1149
|
+
],
|
|
1150
|
+
"inputSchema": {
|
|
1151
|
+
"type": "object",
|
|
1152
|
+
"properties": {
|
|
1153
|
+
"replacementActiveTabId": {
|
|
1154
|
+
"type": "string"
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
},
|
|
1158
|
+
"failureModes": [
|
|
1159
|
+
"target-tab-missing",
|
|
1160
|
+
"replacement-tab-missing",
|
|
1161
|
+
"confirmation-missing"
|
|
1162
|
+
],
|
|
1163
|
+
"description": "Removes the target tab by stable id and reselects a safe replacement when the active/default tab is removed."
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
],
|
|
1167
|
+
"destructive": true,
|
|
1168
|
+
"requiresConfirmation": true,
|
|
1169
|
+
"validators": [
|
|
1170
|
+
"tab-exists",
|
|
1171
|
+
"active-tab-removal-safe",
|
|
1172
|
+
"tab-content-removal-confirmed"
|
|
1173
|
+
],
|
|
1174
|
+
"affectedPaths": [
|
|
1175
|
+
"tabs[]",
|
|
1176
|
+
"group.selectedIndex"
|
|
1177
|
+
],
|
|
1178
|
+
"submissionImpact": "config-only",
|
|
1179
|
+
"preconditions": [
|
|
1180
|
+
"config-initialized",
|
|
1181
|
+
"target-tab-exists",
|
|
1182
|
+
"confirmation-collected"
|
|
1183
|
+
]
|
|
1184
|
+
},
|
|
1185
|
+
{
|
|
1186
|
+
"operationId": "tab.label.set",
|
|
1187
|
+
"title": "Set tab label",
|
|
1188
|
+
"scope": "layout",
|
|
1189
|
+
"targetKind": "tabLabel",
|
|
1190
|
+
"target": {
|
|
1191
|
+
"kind": "tabLabel",
|
|
1192
|
+
"resolver": "tab-by-id-or-label",
|
|
1193
|
+
"ambiguityPolicy": "fail",
|
|
1194
|
+
"required": true
|
|
1195
|
+
},
|
|
1196
|
+
"inputSchema": {
|
|
1197
|
+
"type": "object",
|
|
1198
|
+
"required": [
|
|
1199
|
+
"textLabel"
|
|
1200
|
+
],
|
|
1201
|
+
"properties": {
|
|
1202
|
+
"textLabel": {
|
|
1203
|
+
"type": "string"
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
},
|
|
1207
|
+
"effects": [
|
|
1208
|
+
{
|
|
1209
|
+
"kind": "merge-by-key",
|
|
1210
|
+
"path": "tabs[]",
|
|
1211
|
+
"key": "id"
|
|
1212
|
+
}
|
|
1213
|
+
],
|
|
1214
|
+
"destructive": false,
|
|
1215
|
+
"requiresConfirmation": false,
|
|
1216
|
+
"validators": [
|
|
1217
|
+
"tab-exists",
|
|
1218
|
+
"tab-label-valid"
|
|
1219
|
+
],
|
|
1220
|
+
"affectedPaths": [
|
|
1221
|
+
"tabs[].textLabel"
|
|
1222
|
+
],
|
|
1223
|
+
"submissionImpact": "config-only",
|
|
1224
|
+
"preconditions": [
|
|
1225
|
+
"config-initialized",
|
|
1226
|
+
"target-tab-exists"
|
|
1227
|
+
]
|
|
1228
|
+
},
|
|
1229
|
+
{
|
|
1230
|
+
"operationId": "tab.icon.set",
|
|
1231
|
+
"title": "Set tab icon",
|
|
1232
|
+
"scope": "layout",
|
|
1233
|
+
"targetKind": "tabIcon",
|
|
1234
|
+
"target": {
|
|
1235
|
+
"kind": "tabIcon",
|
|
1236
|
+
"resolver": "tab-by-id-or-label",
|
|
1237
|
+
"ambiguityPolicy": "fail",
|
|
1238
|
+
"required": true
|
|
1239
|
+
},
|
|
1240
|
+
"inputSchema": {
|
|
1241
|
+
"type": "object",
|
|
1242
|
+
"required": [
|
|
1243
|
+
"icon"
|
|
1244
|
+
],
|
|
1245
|
+
"properties": {
|
|
1246
|
+
"icon": {
|
|
1247
|
+
"type": "string"
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
},
|
|
1251
|
+
"effects": [
|
|
1252
|
+
{
|
|
1253
|
+
"kind": "merge-by-key",
|
|
1254
|
+
"path": "tabs[]",
|
|
1255
|
+
"key": "id"
|
|
1256
|
+
}
|
|
1257
|
+
],
|
|
1258
|
+
"destructive": false,
|
|
1259
|
+
"requiresConfirmation": false,
|
|
1260
|
+
"validators": [
|
|
1261
|
+
"tab-exists",
|
|
1262
|
+
"tab-icon-valid"
|
|
1263
|
+
],
|
|
1264
|
+
"affectedPaths": [
|
|
1265
|
+
"tabs[].icon"
|
|
1266
|
+
],
|
|
1267
|
+
"submissionImpact": "visual-only",
|
|
1268
|
+
"preconditions": [
|
|
1269
|
+
"config-initialized",
|
|
1270
|
+
"target-tab-exists"
|
|
1271
|
+
]
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
"operationId": "tab.order.set",
|
|
1275
|
+
"title": "Reorder tabs",
|
|
1276
|
+
"scope": "layout",
|
|
1277
|
+
"targetKind": "tab",
|
|
1278
|
+
"target": {
|
|
1279
|
+
"kind": "tab",
|
|
1280
|
+
"resolver": "tab-by-id-or-label",
|
|
1281
|
+
"ambiguityPolicy": "fail",
|
|
1282
|
+
"required": true
|
|
1283
|
+
},
|
|
1284
|
+
"inputSchema": {
|
|
1285
|
+
"type": "object",
|
|
1286
|
+
"required": [
|
|
1287
|
+
"beforeTabId"
|
|
1288
|
+
],
|
|
1289
|
+
"properties": {
|
|
1290
|
+
"beforeTabId": {
|
|
1291
|
+
"type": "string"
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
},
|
|
1295
|
+
"effects": [
|
|
1296
|
+
{
|
|
1297
|
+
"kind": "compile-domain-patch",
|
|
1298
|
+
"handler": "tabs.reorder-tab-and-preserve-selection",
|
|
1299
|
+
"handlerContract": {
|
|
1300
|
+
"reads": [
|
|
1301
|
+
"tabs[]",
|
|
1302
|
+
"group.selectedIndex"
|
|
1303
|
+
],
|
|
1304
|
+
"writes": [
|
|
1305
|
+
"tabs[]",
|
|
1306
|
+
"group.selectedIndex"
|
|
1307
|
+
],
|
|
1308
|
+
"identityKeys": [
|
|
1309
|
+
"tabs[].id"
|
|
1310
|
+
],
|
|
1311
|
+
"inputSchema": {
|
|
1312
|
+
"type": "object",
|
|
1313
|
+
"required": [
|
|
1314
|
+
"beforeTabId"
|
|
1315
|
+
],
|
|
1316
|
+
"properties": {
|
|
1317
|
+
"beforeTabId": {
|
|
1318
|
+
"type": "string"
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
},
|
|
1322
|
+
"failureModes": [
|
|
1323
|
+
"target-tab-missing",
|
|
1324
|
+
"before-tab-missing",
|
|
1325
|
+
"unstable-tab-id"
|
|
1326
|
+
],
|
|
1327
|
+
"description": "Reorders tabs by stable id and remaps group.selectedIndex when the selected tab crosses positions."
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
],
|
|
1331
|
+
"destructive": false,
|
|
1332
|
+
"requiresConfirmation": false,
|
|
1333
|
+
"validators": [
|
|
1334
|
+
"tab-exists",
|
|
1335
|
+
"tab-order-deterministic"
|
|
1336
|
+
],
|
|
1337
|
+
"affectedPaths": [
|
|
1338
|
+
"tabs[]",
|
|
1339
|
+
"group.selectedIndex"
|
|
1340
|
+
],
|
|
1341
|
+
"submissionImpact": "config-only",
|
|
1342
|
+
"preconditions": [
|
|
1343
|
+
"config-initialized",
|
|
1344
|
+
"target-tab-exists"
|
|
1345
|
+
]
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
"operationId": "tab.disabled.set",
|
|
1349
|
+
"title": "Set tab disabled state",
|
|
1350
|
+
"scope": "interaction",
|
|
1351
|
+
"targetKind": "disabledState",
|
|
1352
|
+
"target": {
|
|
1353
|
+
"kind": "disabledState",
|
|
1354
|
+
"resolver": "tab-or-link-by-id",
|
|
1355
|
+
"ambiguityPolicy": "fail",
|
|
1356
|
+
"required": true
|
|
1357
|
+
},
|
|
1358
|
+
"inputSchema": {
|
|
1359
|
+
"type": "object",
|
|
1360
|
+
"required": [
|
|
1361
|
+
"disabled"
|
|
1362
|
+
],
|
|
1363
|
+
"properties": {
|
|
1364
|
+
"disabled": {
|
|
1365
|
+
"type": "boolean"
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
},
|
|
1369
|
+
"effects": [
|
|
1370
|
+
{
|
|
1371
|
+
"kind": "compile-domain-patch",
|
|
1372
|
+
"handler": "tabs.set-tab-or-link-disabled",
|
|
1373
|
+
"handlerContract": {
|
|
1374
|
+
"reads": [
|
|
1375
|
+
"tabs[]",
|
|
1376
|
+
"nav.links[]",
|
|
1377
|
+
"group.selectedIndex",
|
|
1378
|
+
"nav.selectedIndex"
|
|
1379
|
+
],
|
|
1380
|
+
"writes": [
|
|
1381
|
+
"tabs[].disabled",
|
|
1382
|
+
"nav.links[].disabled"
|
|
1383
|
+
],
|
|
1384
|
+
"identityKeys": [
|
|
1385
|
+
"tabs[].id",
|
|
1386
|
+
"nav.links[].id"
|
|
1387
|
+
],
|
|
1388
|
+
"inputSchema": {
|
|
1389
|
+
"type": "object",
|
|
1390
|
+
"required": [
|
|
1391
|
+
"disabled"
|
|
1392
|
+
],
|
|
1393
|
+
"properties": {
|
|
1394
|
+
"disabled": {
|
|
1395
|
+
"type": "boolean"
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
},
|
|
1399
|
+
"failureModes": [
|
|
1400
|
+
"target-tab-or-link-missing",
|
|
1401
|
+
"ambiguous-target",
|
|
1402
|
+
"active-item-disabled-without-reselection"
|
|
1403
|
+
],
|
|
1404
|
+
"description": "Sets disabled on the resolved group tab or nav link without guessing between modes."
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
],
|
|
1408
|
+
"destructive": false,
|
|
1409
|
+
"requiresConfirmation": false,
|
|
1410
|
+
"validators": [
|
|
1411
|
+
"tab-or-link-exists",
|
|
1412
|
+
"active-tab-disabled-safe"
|
|
1413
|
+
],
|
|
1414
|
+
"affectedPaths": [
|
|
1415
|
+
"tabs[].disabled",
|
|
1416
|
+
"nav.links[].disabled"
|
|
1417
|
+
],
|
|
1418
|
+
"submissionImpact": "config-only",
|
|
1419
|
+
"preconditions": [
|
|
1420
|
+
"config-initialized",
|
|
1421
|
+
"target-tab-or-link-exists"
|
|
1422
|
+
]
|
|
1423
|
+
},
|
|
1424
|
+
{
|
|
1425
|
+
"operationId": "tab.visible.set",
|
|
1426
|
+
"title": "Set tab visibility",
|
|
1427
|
+
"scope": "interaction",
|
|
1428
|
+
"targetKind": "visibility",
|
|
1429
|
+
"target": {
|
|
1430
|
+
"kind": "visibility",
|
|
1431
|
+
"resolver": "tab-or-link-by-id",
|
|
1432
|
+
"ambiguityPolicy": "fail",
|
|
1433
|
+
"required": true
|
|
1434
|
+
},
|
|
1435
|
+
"inputSchema": {
|
|
1436
|
+
"type": "object",
|
|
1437
|
+
"required": [
|
|
1438
|
+
"visible"
|
|
1439
|
+
],
|
|
1440
|
+
"properties": {
|
|
1441
|
+
"visible": {
|
|
1442
|
+
"type": "boolean"
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
},
|
|
1446
|
+
"effects": [
|
|
1447
|
+
{
|
|
1448
|
+
"kind": "compile-domain-patch",
|
|
1449
|
+
"handler": "tabs.set-tab-or-link-visible",
|
|
1450
|
+
"handlerContract": {
|
|
1451
|
+
"reads": [
|
|
1452
|
+
"tabs[]",
|
|
1453
|
+
"nav.links[]",
|
|
1454
|
+
"group.selectedIndex",
|
|
1455
|
+
"nav.selectedIndex"
|
|
1456
|
+
],
|
|
1457
|
+
"writes": [
|
|
1458
|
+
"tabs[].visible",
|
|
1459
|
+
"nav.links[].visible"
|
|
1460
|
+
],
|
|
1461
|
+
"identityKeys": [
|
|
1462
|
+
"tabs[].id",
|
|
1463
|
+
"nav.links[].id"
|
|
1464
|
+
],
|
|
1465
|
+
"inputSchema": {
|
|
1466
|
+
"type": "object",
|
|
1467
|
+
"required": [
|
|
1468
|
+
"visible"
|
|
1469
|
+
],
|
|
1470
|
+
"properties": {
|
|
1471
|
+
"visible": {
|
|
1472
|
+
"type": "boolean"
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
},
|
|
1476
|
+
"failureModes": [
|
|
1477
|
+
"target-tab-or-link-missing",
|
|
1478
|
+
"ambiguous-target",
|
|
1479
|
+
"active-item-hidden-without-reselection"
|
|
1480
|
+
],
|
|
1481
|
+
"description": "Sets visible on the resolved group tab or nav link and preserves deterministic visible-index mapping."
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
],
|
|
1485
|
+
"destructive": false,
|
|
1486
|
+
"requiresConfirmation": false,
|
|
1487
|
+
"validators": [
|
|
1488
|
+
"tab-or-link-exists",
|
|
1489
|
+
"active-tab-visibility-safe"
|
|
1490
|
+
],
|
|
1491
|
+
"affectedPaths": [
|
|
1492
|
+
"tabs[].visible",
|
|
1493
|
+
"nav.links[].visible"
|
|
1494
|
+
],
|
|
1495
|
+
"submissionImpact": "config-only",
|
|
1496
|
+
"preconditions": [
|
|
1497
|
+
"config-initialized",
|
|
1498
|
+
"target-tab-or-link-exists"
|
|
1499
|
+
]
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
"operationId": "tab.active.set",
|
|
1503
|
+
"title": "Set active tab",
|
|
1504
|
+
"scope": "interaction",
|
|
1505
|
+
"targetKind": "activeTab",
|
|
1506
|
+
"target": {
|
|
1507
|
+
"kind": "activeTab",
|
|
1508
|
+
"resolver": "tab-index-or-id",
|
|
1509
|
+
"ambiguityPolicy": "fail",
|
|
1510
|
+
"required": true
|
|
1511
|
+
},
|
|
1512
|
+
"inputSchema": {
|
|
1513
|
+
"type": "object",
|
|
1514
|
+
"required": [
|
|
1515
|
+
"selectedIndex"
|
|
1516
|
+
],
|
|
1517
|
+
"properties": {
|
|
1518
|
+
"selectedIndex": {
|
|
1519
|
+
"type": "number"
|
|
1520
|
+
},
|
|
1521
|
+
"tabId": {
|
|
1522
|
+
"type": "string"
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
},
|
|
1526
|
+
"effects": [
|
|
1527
|
+
{
|
|
1528
|
+
"kind": "compile-domain-patch",
|
|
1529
|
+
"handler": "tabs.set-active-item",
|
|
1530
|
+
"handlerContract": {
|
|
1531
|
+
"reads": [
|
|
1532
|
+
"tabs[]",
|
|
1533
|
+
"nav.links[]",
|
|
1534
|
+
"group.selectedIndex",
|
|
1535
|
+
"nav.selectedIndex"
|
|
1536
|
+
],
|
|
1537
|
+
"writes": [
|
|
1538
|
+
"group.selectedIndex",
|
|
1539
|
+
"nav.selectedIndex"
|
|
1540
|
+
],
|
|
1541
|
+
"identityKeys": [
|
|
1542
|
+
"tabs[].id",
|
|
1543
|
+
"nav.links[].id"
|
|
1544
|
+
],
|
|
1545
|
+
"inputSchema": {
|
|
1546
|
+
"type": "object",
|
|
1547
|
+
"required": [
|
|
1548
|
+
"selectedIndex"
|
|
1549
|
+
],
|
|
1550
|
+
"properties": {
|
|
1551
|
+
"selectedIndex": {
|
|
1552
|
+
"type": "number"
|
|
1553
|
+
},
|
|
1554
|
+
"tabId": {
|
|
1555
|
+
"type": "string"
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
},
|
|
1559
|
+
"failureModes": [
|
|
1560
|
+
"target-tab-or-link-missing",
|
|
1561
|
+
"selected-index-out-of-range",
|
|
1562
|
+
"hidden-or-disabled-target"
|
|
1563
|
+
],
|
|
1564
|
+
"description": "Sets the active index for the current primary mode using either selectedIndex or a resolved tab/link id."
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
],
|
|
1568
|
+
"destructive": false,
|
|
1569
|
+
"requiresConfirmation": false,
|
|
1570
|
+
"validators": [
|
|
1571
|
+
"active-tab-exists",
|
|
1572
|
+
"selected-index-in-range"
|
|
1573
|
+
],
|
|
1574
|
+
"affectedPaths": [
|
|
1575
|
+
"group.selectedIndex",
|
|
1576
|
+
"nav.selectedIndex"
|
|
1577
|
+
],
|
|
1578
|
+
"submissionImpact": "config-only",
|
|
1579
|
+
"preconditions": [
|
|
1580
|
+
"config-initialized",
|
|
1581
|
+
"target-tab-or-link-exists"
|
|
1582
|
+
]
|
|
1583
|
+
},
|
|
1584
|
+
{
|
|
1585
|
+
"operationId": "layout.variant.set",
|
|
1586
|
+
"title": "Set tabs layout variant",
|
|
1587
|
+
"scope": "layout",
|
|
1588
|
+
"targetKind": "layout",
|
|
1589
|
+
"target": {
|
|
1590
|
+
"kind": "layout",
|
|
1591
|
+
"resolver": "tabs-layout-config",
|
|
1592
|
+
"ambiguityPolicy": "fail",
|
|
1593
|
+
"required": true
|
|
1594
|
+
},
|
|
1595
|
+
"inputSchema": {
|
|
1596
|
+
"type": "object",
|
|
1597
|
+
"required": [
|
|
1598
|
+
"mode"
|
|
1599
|
+
],
|
|
1600
|
+
"properties": {
|
|
1601
|
+
"mode": {
|
|
1602
|
+
"enum": [
|
|
1603
|
+
"group",
|
|
1604
|
+
"nav"
|
|
1605
|
+
]
|
|
1606
|
+
},
|
|
1607
|
+
"density": {
|
|
1608
|
+
"enum": [
|
|
1609
|
+
"compact",
|
|
1610
|
+
"comfortable",
|
|
1611
|
+
"spacious"
|
|
1612
|
+
]
|
|
1613
|
+
},
|
|
1614
|
+
"headerPosition": {
|
|
1615
|
+
"enum": [
|
|
1616
|
+
"above",
|
|
1617
|
+
"below"
|
|
1618
|
+
]
|
|
1619
|
+
},
|
|
1620
|
+
"alignTabs": {
|
|
1621
|
+
"enum": [
|
|
1622
|
+
"start",
|
|
1623
|
+
"center",
|
|
1624
|
+
"end"
|
|
1625
|
+
]
|
|
1626
|
+
},
|
|
1627
|
+
"stretchTabs": {
|
|
1628
|
+
"type": "boolean"
|
|
1629
|
+
},
|
|
1630
|
+
"lazyLoad": {
|
|
1631
|
+
"type": "boolean"
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
},
|
|
1635
|
+
"effects": [
|
|
1636
|
+
{
|
|
1637
|
+
"kind": "merge-object",
|
|
1638
|
+
"path": "appearance"
|
|
1639
|
+
},
|
|
1640
|
+
{
|
|
1641
|
+
"kind": "merge-object",
|
|
1642
|
+
"path": "group"
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
"kind": "merge-object",
|
|
1646
|
+
"path": "nav"
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
"kind": "merge-object",
|
|
1650
|
+
"path": "behavior"
|
|
1651
|
+
}
|
|
1652
|
+
],
|
|
1653
|
+
"destructive": false,
|
|
1654
|
+
"requiresConfirmation": false,
|
|
1655
|
+
"validators": [
|
|
1656
|
+
"tabs-mode-compatible",
|
|
1657
|
+
"layout-values-valid",
|
|
1658
|
+
"editor-runtime-round-trip"
|
|
1659
|
+
],
|
|
1660
|
+
"affectedPaths": [
|
|
1661
|
+
"appearance.density",
|
|
1662
|
+
"group.headerPosition",
|
|
1663
|
+
"group.alignTabs",
|
|
1664
|
+
"group.stretchTabs",
|
|
1665
|
+
"nav.stretchTabs",
|
|
1666
|
+
"behavior.lazyLoad"
|
|
1667
|
+
],
|
|
1668
|
+
"submissionImpact": "config-only",
|
|
1669
|
+
"preconditions": [
|
|
1670
|
+
"config-initialized"
|
|
1671
|
+
]
|
|
1672
|
+
},
|
|
1673
|
+
{
|
|
1674
|
+
"operationId": "tab.content.set",
|
|
1675
|
+
"title": "Set tab content",
|
|
1676
|
+
"scope": "layout",
|
|
1677
|
+
"targetKind": "tabContent",
|
|
1678
|
+
"target": {
|
|
1679
|
+
"kind": "tabContent",
|
|
1680
|
+
"resolver": "tab-or-link-by-id",
|
|
1681
|
+
"ambiguityPolicy": "fail",
|
|
1682
|
+
"required": true
|
|
1683
|
+
},
|
|
1684
|
+
"inputSchema": {
|
|
1685
|
+
"type": "object",
|
|
1686
|
+
"minProperties": 1,
|
|
1687
|
+
"properties": {
|
|
1688
|
+
"id": {
|
|
1689
|
+
"type": "string"
|
|
1690
|
+
},
|
|
1691
|
+
"textLabel": {
|
|
1692
|
+
"type": "string"
|
|
1693
|
+
},
|
|
1694
|
+
"icon": {
|
|
1695
|
+
"type": "string"
|
|
1696
|
+
},
|
|
1697
|
+
"disabled": {
|
|
1698
|
+
"type": "boolean"
|
|
1699
|
+
},
|
|
1700
|
+
"visible": {
|
|
1701
|
+
"type": "boolean"
|
|
1702
|
+
},
|
|
1703
|
+
"content": {
|
|
1704
|
+
"type": "array",
|
|
1705
|
+
"items": {
|
|
1706
|
+
"type": "object"
|
|
1707
|
+
}
|
|
1708
|
+
},
|
|
1709
|
+
"widgets": {
|
|
1710
|
+
"type": "array",
|
|
1711
|
+
"items": {
|
|
1712
|
+
"type": "object"
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
},
|
|
1717
|
+
"effects": [
|
|
1718
|
+
{
|
|
1719
|
+
"kind": "compile-domain-patch",
|
|
1720
|
+
"handler": "tabs.set-tab-or-link-content",
|
|
1721
|
+
"handlerContract": {
|
|
1722
|
+
"reads": [
|
|
1723
|
+
"tabs[]",
|
|
1724
|
+
"nav.links[]"
|
|
1725
|
+
],
|
|
1726
|
+
"writes": [
|
|
1727
|
+
"tabs[].content",
|
|
1728
|
+
"tabs[].widgets",
|
|
1729
|
+
"nav.links[].content",
|
|
1730
|
+
"nav.links[].widgets"
|
|
1731
|
+
],
|
|
1732
|
+
"identityKeys": [
|
|
1733
|
+
"tabs[].id",
|
|
1734
|
+
"nav.links[].id"
|
|
1735
|
+
],
|
|
1736
|
+
"failureModes": [
|
|
1737
|
+
"target-tab-or-link-missing",
|
|
1738
|
+
"invalid-dynamic-field-content",
|
|
1739
|
+
"invalid-widget-definition"
|
|
1740
|
+
],
|
|
1741
|
+
"description": "Updates content/widgets only on the resolved group tab or nav link while preserving nested widget identity."
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
],
|
|
1745
|
+
"destructive": false,
|
|
1746
|
+
"requiresConfirmation": false,
|
|
1747
|
+
"validators": [
|
|
1748
|
+
"tab-or-link-exists",
|
|
1749
|
+
"tab-content-valid",
|
|
1750
|
+
"widget-event-delegated"
|
|
1751
|
+
],
|
|
1752
|
+
"affectedPaths": [
|
|
1753
|
+
"tabs[].content",
|
|
1754
|
+
"tabs[].widgets",
|
|
1755
|
+
"nav.links[].content",
|
|
1756
|
+
"nav.links[].widgets"
|
|
1757
|
+
],
|
|
1758
|
+
"submissionImpact": "config-only",
|
|
1759
|
+
"preconditions": [
|
|
1760
|
+
"config-initialized",
|
|
1761
|
+
"target-tab-or-link-exists"
|
|
1762
|
+
]
|
|
1763
|
+
}
|
|
1764
|
+
],
|
|
1765
|
+
"validators": [
|
|
1766
|
+
{
|
|
1767
|
+
"validatorId": "tab-id-unique",
|
|
1768
|
+
"level": "error",
|
|
1769
|
+
"code": "PTABS001",
|
|
1770
|
+
"description": "Tab ids and nav link ids must be unique within their mode."
|
|
1771
|
+
},
|
|
1772
|
+
{
|
|
1773
|
+
"validatorId": "tab-exists",
|
|
1774
|
+
"level": "error",
|
|
1775
|
+
"code": "PTABS002",
|
|
1776
|
+
"description": "Target tab must exist before applying the operation."
|
|
1777
|
+
},
|
|
1778
|
+
{
|
|
1779
|
+
"validatorId": "tab-or-link-exists",
|
|
1780
|
+
"level": "error",
|
|
1781
|
+
"code": "PTABS003",
|
|
1782
|
+
"description": "Target must resolve to an existing group tab or nav link."
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
"validatorId": "active-tab-exists",
|
|
1786
|
+
"level": "error",
|
|
1787
|
+
"code": "PTABS004",
|
|
1788
|
+
"description": "Active tab or nav link selection must reference an existing item."
|
|
1789
|
+
},
|
|
1790
|
+
{
|
|
1791
|
+
"validatorId": "selected-index-in-range",
|
|
1792
|
+
"level": "error",
|
|
1793
|
+
"code": "PTABS005",
|
|
1794
|
+
"description": "Selected index must be clamped to the target mode item count."
|
|
1795
|
+
},
|
|
1796
|
+
{
|
|
1797
|
+
"validatorId": "active-tab-removal-safe",
|
|
1798
|
+
"level": "error",
|
|
1799
|
+
"code": "PTABS006",
|
|
1800
|
+
"description": "Removing the active/default tab requires confirmation or a replacement active tab."
|
|
1801
|
+
},
|
|
1802
|
+
{
|
|
1803
|
+
"validatorId": "tab-content-removal-confirmed",
|
|
1804
|
+
"level": "error",
|
|
1805
|
+
"code": "PTABS007",
|
|
1806
|
+
"description": "Removing a tab or link with content/widgets is destructive and requires confirmation."
|
|
1807
|
+
},
|
|
1808
|
+
{
|
|
1809
|
+
"validatorId": "tab-label-valid",
|
|
1810
|
+
"level": "error",
|
|
1811
|
+
"code": "PTABS008",
|
|
1812
|
+
"description": "Tab labels must be non-empty text values after localization/domain projection."
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
"validatorId": "tab-icon-valid",
|
|
1816
|
+
"level": "warning",
|
|
1817
|
+
"code": "PTABS009",
|
|
1818
|
+
"description": "Tab icon metadata must remain compatible with the icon directive and editor round-trip."
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
"validatorId": "tab-order-deterministic",
|
|
1822
|
+
"level": "error",
|
|
1823
|
+
"code": "PTABS010",
|
|
1824
|
+
"description": "Tab ordering must use stable ids, not transient array index as identity."
|
|
1825
|
+
},
|
|
1826
|
+
{
|
|
1827
|
+
"validatorId": "tabs-mode-compatible",
|
|
1828
|
+
"level": "error",
|
|
1829
|
+
"code": "PTABS011",
|
|
1830
|
+
"description": "Authoring must resolve to one primary mode: group tabs or nav links."
|
|
1831
|
+
},
|
|
1832
|
+
{
|
|
1833
|
+
"validatorId": "layout-values-valid",
|
|
1834
|
+
"level": "error",
|
|
1835
|
+
"code": "PTABS012",
|
|
1836
|
+
"description": "Layout values must match TabsMetadata enums and runtime bindings."
|
|
1837
|
+
},
|
|
1838
|
+
{
|
|
1839
|
+
"validatorId": "editor-runtime-round-trip",
|
|
1840
|
+
"level": "error",
|
|
1841
|
+
"code": "PTABS013",
|
|
1842
|
+
"description": "Settings Panel, quick setup, JSON editor and runtime must preserve ids, order and selected index."
|
|
1843
|
+
},
|
|
1844
|
+
{
|
|
1845
|
+
"validatorId": "active-tab-disabled-safe",
|
|
1846
|
+
"level": "warning",
|
|
1847
|
+
"code": "PTABS014",
|
|
1848
|
+
"description": "Disabling the active item should move selection or request explicit confirmation."
|
|
1849
|
+
},
|
|
1850
|
+
{
|
|
1851
|
+
"validatorId": "active-tab-visibility-safe",
|
|
1852
|
+
"level": "warning",
|
|
1853
|
+
"code": "PTABS015",
|
|
1854
|
+
"description": "Hiding the active item should move selection or request explicit confirmation."
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
"validatorId": "tab-content-valid",
|
|
1858
|
+
"level": "error",
|
|
1859
|
+
"code": "PTABS016",
|
|
1860
|
+
"description": "Tab content must be valid DynamicFieldMetadata[] or WidgetDefinition[] and preserve nested widget identity."
|
|
1861
|
+
},
|
|
1862
|
+
{
|
|
1863
|
+
"validatorId": "widget-event-delegated",
|
|
1864
|
+
"level": "info",
|
|
1865
|
+
"code": "PTABS017",
|
|
1866
|
+
"description": "Nested widget event paths remain delegated to the tabs runtime contract and are not redefined by authoring."
|
|
1867
|
+
}
|
|
1868
|
+
],
|
|
1869
|
+
"roundTripRequirements": [
|
|
1870
|
+
"Operations must preserve stable tab/link ids; array index may be used only as a resolver fallback, never as canonical identity.",
|
|
1871
|
+
"Settings Panel, quick setup and JSON editor must round-trip through TabsAuthoringDocument without losing config or bindings.",
|
|
1872
|
+
"Group and nav modes must remain mutually explicit; authoring cannot silently mix config.tabs and nav.links as competing primary modes.",
|
|
1873
|
+
"Nested widget events remain delegated through widgetEvent path enrichment and component-port nestedPath semantics."
|
|
1874
|
+
],
|
|
1875
|
+
"examples": [
|
|
1876
|
+
{
|
|
1877
|
+
"id": "add-overview-tab",
|
|
1878
|
+
"request": "Add an Overview tab before the details tab.",
|
|
1879
|
+
"operationId": "tab.add",
|
|
1880
|
+
"params": {
|
|
1881
|
+
"id": "overview",
|
|
1882
|
+
"textLabel": "Overview"
|
|
1883
|
+
},
|
|
1884
|
+
"isPositive": true
|
|
1885
|
+
},
|
|
1886
|
+
{
|
|
1887
|
+
"id": "add-list-to-current-tab",
|
|
1888
|
+
"request": "Create a list widget inside the current training tab.",
|
|
1889
|
+
"operationId": "tab.content.set",
|
|
1890
|
+
"target": "training",
|
|
1891
|
+
"params": {
|
|
1892
|
+
"widgets": [
|
|
1893
|
+
{
|
|
1894
|
+
"id": "training-list",
|
|
1895
|
+
"component": "praxis-list",
|
|
1896
|
+
"title": "Training list"
|
|
1897
|
+
}
|
|
1898
|
+
]
|
|
1899
|
+
},
|
|
1900
|
+
"isPositive": true
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
"id": "add-form-fields-to-existing-tab",
|
|
1904
|
+
"request": "Add name, date and status fields to the existing onboarding tab.",
|
|
1905
|
+
"operationId": "tab.content.set",
|
|
1906
|
+
"target": "onboarding",
|
|
1907
|
+
"params": {
|
|
1908
|
+
"content": [
|
|
1909
|
+
{
|
|
1910
|
+
"name": "name",
|
|
1911
|
+
"label": "Name",
|
|
1912
|
+
"controlType": "text"
|
|
1913
|
+
},
|
|
1914
|
+
{
|
|
1915
|
+
"name": "plannedDate",
|
|
1916
|
+
"label": "Planned date",
|
|
1917
|
+
"controlType": "date"
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
"name": "status",
|
|
1921
|
+
"label": "Status",
|
|
1922
|
+
"controlType": "select"
|
|
1923
|
+
}
|
|
1924
|
+
]
|
|
1925
|
+
},
|
|
1926
|
+
"isPositive": true
|
|
1927
|
+
},
|
|
1928
|
+
{
|
|
1929
|
+
"id": "rename-tab",
|
|
1930
|
+
"request": "Rename the details tab to Account Details.",
|
|
1931
|
+
"operationId": "tab.label.set",
|
|
1932
|
+
"target": "details",
|
|
1933
|
+
"params": {
|
|
1934
|
+
"textLabel": "Account Details"
|
|
1935
|
+
},
|
|
1936
|
+
"isPositive": true
|
|
1937
|
+
},
|
|
1938
|
+
{
|
|
1939
|
+
"id": "reorder-tabs",
|
|
1940
|
+
"request": "Move billing before overview.",
|
|
1941
|
+
"operationId": "tab.order.set",
|
|
1942
|
+
"target": "billing",
|
|
1943
|
+
"params": {
|
|
1944
|
+
"beforeTabId": "overview"
|
|
1945
|
+
},
|
|
1946
|
+
"isPositive": true
|
|
1947
|
+
},
|
|
1948
|
+
{
|
|
1949
|
+
"id": "disable-tab",
|
|
1950
|
+
"request": "Disable the audit tab until the user has permission.",
|
|
1951
|
+
"operationId": "tab.disabled.set",
|
|
1952
|
+
"target": "audit",
|
|
1953
|
+
"params": {
|
|
1954
|
+
"disabled": true
|
|
1955
|
+
},
|
|
1956
|
+
"isPositive": true
|
|
1957
|
+
},
|
|
1958
|
+
{
|
|
1959
|
+
"id": "activate-tab",
|
|
1960
|
+
"request": "Open the documents tab by default.",
|
|
1961
|
+
"operationId": "tab.active.set",
|
|
1962
|
+
"target": "documents",
|
|
1963
|
+
"params": {
|
|
1964
|
+
"tabId": "documents",
|
|
1965
|
+
"selectedIndex": 2
|
|
1966
|
+
},
|
|
1967
|
+
"isPositive": true
|
|
1968
|
+
},
|
|
1969
|
+
{
|
|
1970
|
+
"id": "reject-duplicate-tab-id",
|
|
1971
|
+
"request": "Add another tab with id overview.",
|
|
1972
|
+
"operationId": "tab.add",
|
|
1973
|
+
"params": {
|
|
1974
|
+
"id": "overview",
|
|
1975
|
+
"textLabel": "Duplicate Overview"
|
|
1976
|
+
},
|
|
1977
|
+
"isPositive": false
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
"id": "reject-current-tab-content-as-tab-add",
|
|
1981
|
+
"request": "Create a list in this tab; do not add a new tab.",
|
|
1982
|
+
"operationId": "tab.add",
|
|
1983
|
+
"params": {
|
|
1984
|
+
"id": "list-in-this-tab",
|
|
1985
|
+
"textLabel": "List in this tab"
|
|
1986
|
+
},
|
|
1987
|
+
"isPositive": false
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
"id": "confirm-remove-content-tab",
|
|
1991
|
+
"request": "Remove the details tab that contains widgets.",
|
|
1992
|
+
"operationId": "tab.remove",
|
|
1993
|
+
"target": "details",
|
|
1994
|
+
"params": {
|
|
1995
|
+
"replacementActiveTabId": "overview"
|
|
1996
|
+
},
|
|
1997
|
+
"isPositive": true
|
|
1998
|
+
}
|
|
1999
|
+
]
|
|
2000
|
+
},
|
|
2001
|
+
"chunks": [
|
|
2002
|
+
{
|
|
2003
|
+
"chunkIndex": 0,
|
|
2004
|
+
"chunkKind": "summary",
|
|
2005
|
+
"content": "Component ID: praxis-tabs\nSelector: praxis-tabs\nFriendly Name: Praxis Tabs\nDescription: Abas dinâmicas baseadas em metadata, com MatTabGroup/TabNav e suporte a tokens M3 via appearance.\nLib/Package: @praxisui/tabs\nTags: widget, tabs, configurable, stable\nInputs:\n - config (TabsMetadata)\n - tabsId (string)\n - componentInstanceId (string)\n - configPersistenceStrategy (\"storage-first\" | \"input-first\")\n - selectedIndex (number)\n - enableCustomization (boolean)\n - form (FormGroup)\n - context (Record<string, any>)\nOutputs:\n - selectedIndexChange (number)\n - configChange (TabsConfigChangeEvent)\n - selectedTabChange (MatTabChangeEvent)\n - animationDone (void)\n - focusChange (MatTabChangeEvent)\n - indexFocused (number)\n - selectFocusedIndex (number)\n - widgetEvent (WidgetEventEnvelope)\n",
|
|
2006
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-tabs/src/lib/praxis-tabs.metadata.ts",
|
|
2007
|
+
"contentHash": "6ac4b5aa11ec48aec174a401af754d8d8efbee3e8e69402342098c6e1b91ce15",
|
|
2008
|
+
"sourceKind": "component_definition",
|
|
2009
|
+
"sourceId": "praxis-tabs",
|
|
2010
|
+
"corpusVersion": "1.0.0"
|
|
2011
|
+
},
|
|
2012
|
+
{
|
|
2013
|
+
"chunkIndex": 1,
|
|
2014
|
+
"chunkKind": "capabilities",
|
|
2015
|
+
"content": "Component Capabilities:\n - Path: meta\n Category: meta\n Kind: object\n Description: Metadata bag for tabs.\n - Path: appearance\n Category: appearance\n Kind: object\n Description: Appearance settings.\n - Path: appearance.density\n Category: appearance\n Kind: enum\n Description: Density preset.\n - Path: appearance.themeClass\n Category: appearance\n Kind: string\n Description: Theme CSS class applied to root.\n - Path: appearance.customCss\n Category: appearance\n Kind: string\n Description: Custom CSS injected into component.\n - Path: appearance.tokens\n Category: appearance\n Kind: object\n Description: Style tokens mapped to runtime CSS.\n - Path: behavior\n Category: behavior\n Kind: object\n Description: Behavior settings.\n - Path: behavior.lazyLoad\n Category: behavior\n Kind: boolean\n Description: Lazy load tab content.\n - Path: behavior.closeable\n Category: behavior\n Kind: boolean\n Description: Show close button on tabs.\n - Path: behavior.reorderable\n Category: behavior\n Kind: boolean\n Description: Allow reorder tabs/links.\n - Path: accessibility\n Category: accessibility\n Kind: object\n Description: Accessibility settings.\n - Path: accessibility.highContrast\n Category: accessibility\n Kind: boolean\n Description: High contrast mode.\n - Path: accessibility.reduceMotion\n Category: accessibility\n Kind: boolean\n Description: Reduce motion.\n - Path: group\n Category: group\n Kind: object\n Description: MatTabGroup settings.\n - Path: group.alignTabs\n Category: group\n Kind: enum\n Description: Align tabs in header.\n - Path: group.animationDuration\n Category: group\n Kind: string\n Description: Animation duration (e.g., 500ms).\n - Path: group.ariaLabel\n Category: group\n Kind: string\n Description: aria-label for tab group.\n - Path: group.ariaLabelledby\n Category: group\n Kind: string\n Description: aria-labelledby for tab group.\n - Path: group.color\n Category: group\n Kind: enum\n Description: M2 color.\n - Path: group.backgroundColor\n Category: group\n Kind: enum\n Description: M2 background color.\n - Path: group.disablePagination\n Category: group\n Kind: boolean\n Description: Disable pagination of header.\n - Path: group.disableRipple\n Category: group\n Kind: boolean\n Description: Disable ripple.\n - Path: group.dynamicHeight\n Category: group\n Kind: boolean\n Description: Enable dynamic height.\n - Path: group.fitInkBarToContent\n Category: group\n Kind: boolean\n Description: Fit ink bar to content.\n - Path: group.headerPosition\n Category: group\n Kind: enum\n Description: Header position.\n - Path: group.preserveContent\n Category: group\n Kind: boolean\n Description: Preserve content of inactive tabs.\n - Path: group.selectedIndex\n Category: group\n Kind: number\n Description: Selected tab index.\n - Path: group.stretchTabs\n Category: group\n Kind: boolean\n Description: Stretch tabs.\n - Path: nav\n Category: nav\n Kind: object\n Description: Tab nav settings.\n - Path: nav.animationDuration\n Category: nav\n Kind: string\n Description: Animation duration (e.g., 500ms).\n - Path: nav.ariaLabel\n Category: nav\n Kind: string\n Description: aria-label for nav mode.\n - Path: nav.ariaLabelledby\n Category: nav\n Kind: string\n Description: aria-labelledby for nav mode.\n - Path: nav.color\n Category: nav\n Kind: enum\n Description: M2 color.\n - Path: nav.backgroundColor\n Category: nav\n Kind: enum\n Description: M2 background color.\n - Path: nav.disablePagination\n Category: nav\n Kind: boolean\n Description: Disable pagination of nav.\n - Path: nav.disableRipple\n Category: nav\n Kind: boolean\n Description: Disable ripple.\n - Path: nav.fitInkBarToContent\n Category: nav\n Kind: boolean\n Description: Fit ink bar to content.\n - Path: nav.selectedIndex\n Category: nav\n Kind: number\n Description: Selected nav link index.\n - Path: nav.stretchTabs\n Category: nav\n Kind: boolean\n Description: Stretch nav tabs.\n - Path: nav.links\n Category: nav\n Kind: array\n Description: Nav links array.\n - Path: nav.links[].id\n Category: nav\n Kind: string\n Description: Link id.\n - Path: nav.links[].label\n Category: nav\n Kind: string\n Description: Link label.\n - Path: nav.links[].active\n Category: nav\n Kind: boolean\n Description: Link active flag.\n - Path: nav.links[].disabled\n Category: nav\n Kind: boolean\n Description: Disable link.\n - Path: nav.links[].disableRipple\n Category: nav\n Kind: boolean\n Description: Disable ripple on link.\n - Path: nav.links[].fitInkBarToContent\n Category: nav\n Kind: boolean\n Description: Fit ink bar to link content.\n - Path: nav.links[].content\n Category: nav\n Kind: array\n Description: Dynamic field metadata list.\n - Path: nav.links[].widgets\n Category: nav\n Kind: array\n Description: Widget definitions for link content.\n - Path: tabs\n Category: tabs\n Kind: array\n Description: Tabs array.\n - Path: tabs[].id\n Category: tabs\n Kind: string\n Description: Tab id.\n - Path: tabs[].textLabel\n Category: tabs\n Kind: string\n Description: Tab label.\n - Path: tabs[].labelClass\n Category: tabs\n Kind: string\n Description: Label class (string or string[]).\n - Path: tabs[].bodyClass\n Category: tabs\n Kind: string\n Description: Body class (string or string[]).\n - Path: tabs[].ariaLabel\n Category: tabs\n Kind: string\n Description: aria-label for tab.\n - Path: tabs[].ariaLabelledby\n Category: tabs\n Kind: string\n Description: aria-labelledby for tab.\n - Path: tabs[].disabled\n Category: tabs\n Kind: boolean\n Description: Disable tab.\n - Path: tabs[].content\n Category: tabs\n Kind: array\n Description: Dynamic field metadata list.\n - Path: tabs[].widgets\n Category: tabs\n Kind: array\n Description: Widget definitions for tab content.\n - Path: tabs[].isActive\n Category: tabs\n Kind: boolean\n Description: Active flag (metadata only).\n - Path: tabs[].origin\n Category: tabs\n Kind: number\n Description: Origin index (metadata only).\n - Path: tabs[].position\n Category: tabs\n Kind: number\n Description: Position index (metadata only).\n - Path: events\n Category: events\n Kind: object\n Description: Event config (placeholder).\nCapability Notes:\n - TabsMetadata drives both group and nav modes. Use nav.* when links are present.\n - appearance.customCss is injected into a <style> tag; avoid unsafe CSS from untrusted sources.\n - tabs[].content expects DynamicFieldMetadata[] and widgets[] expects WidgetDefinition[].\n",
|
|
2016
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-tabs/src/lib/ai/tabs-ai-capabilities.ts",
|
|
2017
|
+
"contentHash": "d06a68f06350b762c479c7debd5eb5b844ef46f99f0cecb289ee3a5d65bc7310",
|
|
2018
|
+
"sourceKind": "component_definition",
|
|
2019
|
+
"sourceId": "praxis-tabs",
|
|
2020
|
+
"corpusVersion": "1.0.0"
|
|
2021
|
+
},
|
|
2022
|
+
{
|
|
2023
|
+
"chunkIndex": 2,
|
|
2024
|
+
"chunkKind": "authoring_manifest",
|
|
2025
|
+
"content": "{\n \"schemaVersion\": \"1.0.0\",\n \"componentId\": \"praxis-tabs\",\n \"ownerPackage\": \"@praxisui/tabs\",\n \"configSchemaId\": \"TabsMetadata\",\n \"manifestVersion\": \"1.0.0\",\n \"runtimeInputs\": [\n {\n \"name\": \"config\",\n \"type\": \"TabsMetadata\",\n \"description\": \"Canonical tabs/nav configuration.\"\n },\n {\n \"name\": \"tabsId\",\n \"type\": \"string\",\n \"description\": \"Stable id used to derive persistence scope.\"\n },\n {\n \"name\": \"componentInstanceId\",\n \"type\": \"string\",\n \"description\": \"Optional instance discriminator for persistence scope.\"\n },\n {\n \"name\": \"configPersistenceStrategy\",\n \"type\": \"\\\"storage-first\\\" | \\\"input-first\\\"\",\n \"description\": \"Controls whether persisted customization or explicit input config governs the runtime. Governed previews with nested widgets should use input-first.\"\n },\n {\n \"name\": \"form\",\n \"type\": \"FormGroup\",\n \"description\": \"FormGroup consumed by dynamic field content.\"\n },\n {\n \"name\": \"context\",\n \"type\": \"Record<string, any>\",\n \"description\": \"Context passed to nested widgets.\"\n },\n {\n \"name\": \"enableCustomization\",\n \"type\": \"boolean\",\n \"description\": \"Enables Settings Panel authoring surfaces.\"\n }\n ],\n \"editableTargets\": [\n {\n \"kind\": \"tab\",\n \"resolver\": \"tab-by-id-or-label\",\n \"description\": \"A group-mode tab in config.tabs[].\"\n },\n {\n \"kind\": \"tabLabel\",\n \"resolver\": \"tab-by-id-or-label\",\n \"description\": \"The text label of a group-mode tab.\"\n },\n {\n \"kind\": \"tabIcon\",\n \"resolver\": \"tab-by-id-or-label\",\n \"description\": \"Icon metadata rendered in a group tab label.\"\n },\n {\n \"kind\": \"tabContent\",\n \"resolver\": \"tab-or-link-by-id\",\n \"description\": \"Dynamic fields or widgets hosted by a tab or nav link.\"\n },\n {\n \"kind\": \"activeTab\",\n \"resolver\": \"tab-index-or-id\",\n \"description\": \"Selected tab or nav link index.\"\n },\n {\n \"kind\": \"visibility\",\n \"resolver\": \"tab-or-link-by-id\",\n \"description\": \"Runtime visibility flag for a group tab or nav link.\"\n },\n {\n \"kind\": \"disabledState\",\n \"resolver\": \"tab-or-link-by-id\",\n \"description\": \"Disabled state of a tab or nav link.\"\n },\n {\n \"kind\": \"layout\",\n \"resolver\": \"tabs-layout-config\",\n \"description\": \"Group/nav mode, header position, density, stretch and behavior settings.\"\n }\n ],\n \"operations\": [\n {\n \"operationId\": \"tab.add\",\n \"title\": \"Add tab\",\n \"scope\": \"global\",\n \"targetKind\": \"tab\",\n \"target\": {\n \"kind\": \"tab\",\n \"resolver\": \"tabs-array\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": false\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"id\",\n \"textLabel\"\n ],\n \"properties\": {\n \"id\": {\n \"type\": \"string\"\n },\n \"textLabel\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"type\": \"string\"\n },\n \"disabled\": {\n \"type\": \"boolean\"\n },\n \"visible\": {\n \"type\": \"boolean\",\n \"default\": true\n },\n \"content\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"widgets\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"append-unique\",\n \"path\": \"tabs[]\",\n \"key\": \"id\"\n }\n ],\n \"validators\": [\n \"tab-id-unique\",\n \"tabs-mode-compatible\",\n \"tab-content-valid\"\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"affectedPaths\": [\n \"tabs[]\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"tab.remove\",\n \"title\": \"Remove tab\",\n \"scope\": \"layout\",\n \"targetKind\": \"tab\",\n \"target\": {\n \"kind\": \"tab\",\n \"resolver\": \"tab-by-id-or-label\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"replacementActiveTabId\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"tabs.remove-tab-and-reselect\",\n \"handlerContract\": {\n \"reads\": [\n \"tabs[]\",\n \"group.selectedIndex\"\n ],\n \"writes\": [\n \"tabs[]\",\n \"group.selectedIndex\"\n ],\n \"identityKeys\": [\n \"tabs[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"properties\": {\n \"replacementActiveTabId\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"target-tab-missing\",\n \"replacement-tab-missing\",\n \"confirmation-missing\"\n ],\n \"description\": \"Removes the target tab by stable id and reselects a safe replacement when the active/default tab is removed.\"\n }\n }\n ],\n \"destructive\": true,\n \"requiresConfirmation\": true,\n \"validators\": [\n \"tab-exists\",\n \"active-tab-removal-safe\",\n \"tab-content-removal-confirmed\"\n ],\n \"affectedPaths\": [\n \"tabs[]\",\n \"group.selectedIndex\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-exists\",\n \"confirmation-collected\"\n ]\n },\n {\n \"operationId\": \"tab.label.set\",\n \"title\": \"Set tab label\",\n \"scope\": \"layout\",\n \"targetKind\": \"tabLabel\",\n \"target\": {\n \"kind\": \"tabLabel\",\n \"resolver\": \"tab-by-id-or-label\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"textLabel\"\n ],\n \"properties\": {\n \"textLabel\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-by-key\",\n \"path\": \"tabs[]\",\n \"key\": \"id\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tab-exists\",\n \"tab-label-valid\"\n ],\n \"affectedPaths\": [\n \"tabs[].textLabel\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-exists\"\n ]\n },\n {\n \"operationId\": \"tab.icon.set\",\n \"title\": \"Set tab icon\",\n \"scope\": \"layout\",\n \"targetKind\": \"tabIcon\",\n \"target\": {\n \"kind\": \"tabIcon\",\n \"resolver\": \"tab-by-id-or-label\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"icon\"\n ],\n \"properties\": {\n \"icon\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-by-key\",\n \"path\": \"tabs[]\",\n \"key\": \"id\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tab-exists\",\n \"tab-icon-valid\"\n ],\n \"affectedPaths\": [\n \"tabs[].icon\"\n ],\n \"submissionImpact\": \"visual-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-exists\"\n ]\n },\n {\n \"operationId\": \"tab.order.set\",\n \"title\": \"Reorder tabs\",\n \"scope\": \"layout\",\n \"targetKind\": \"tab\",\n \"target\": {\n \"kind\": \"tab\",\n \"resolver\": \"tab-by-id-or-label\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"beforeTabId\"\n ],\n \"properties\": {\n \"beforeTabId\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"tabs.reorder-tab-and-preserve-selection\",\n \"handlerContract\": {\n \"reads\": [\n \"tabs[]\",\n \"group.selectedIndex\"\n ],\n \"writes\": [\n \"tabs[]\",\n \"group.selectedIndex\"\n ],\n \"identityKeys\": [\n \"tabs[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"beforeTabId\"\n ],\n \"properties\": {\n \"beforeTabId\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"target-tab-missing\",\n \"before-tab-missing\",\n \"unstable-tab-id\"\n ],\n \"description\": \"Reorders tabs by stable id and remaps group.selectedIndex when the selected tab crosses positions.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tab-exists\",\n \"tab-order-deterministic\"\n ],\n \"affectedPaths\": [\n \"tabs[]\",\n \"group.selectedIndex\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-exists\"\n ]\n },\n {\n \"operationId\": \"tab.disabled.set\",\n \"title\": \"Set tab disabled state\",\n \"scope\": \"interaction\",\n \"targetKind\": \"disabledState\",\n \"target\": {\n \"kind\": \"disabledState\",\n \"resolver\": \"tab-or-link-by-id\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"disabled\"\n ],\n \"properties\": {\n \"disabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"tabs.set-tab-or-link-disabled\",\n \"handlerContract\": {\n \"reads\": [\n \"tabs[]\",\n \"nav.links[]\",\n \"group.selectedIndex\",\n \"nav.selectedIndex\"\n ],\n \"writes\": [\n \"tabs[].disabled\",\n \"nav.links[].disabled\"\n ],\n \"identityKeys\": [\n \"tabs[].id\",\n \"nav.links[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"disabled\"\n ],\n \"properties\": {\n \"disabled\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"failureModes\": [\n \"target-tab-or-link-missing\",\n \"ambiguous-target\",\n \"active-item-disabled-without-reselection\"\n ],\n \"description\": \"Sets disabled on the resolved group tab or nav link without guessing between modes.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tab-or-link-exists\",\n \"active-tab-disabled-safe\"\n ],\n \"affectedPaths\": [\n \"tabs[].disabled\",\n \"nav.links[].disabled\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-or-link-exists\"\n ]\n },\n {\n \"operationId\": \"tab.visible.set\",\n \"title\": \"Set tab visibility\",\n \"scope\": \"interaction\",\n \"targetKind\": \"visibility\",\n \"target\": {\n \"kind\": \"visibility\",\n \"resolver\": \"tab-or-link-by-id\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"visible\"\n ],\n \"properties\": {\n \"visible\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"tabs.set-tab-or-link-visible\",\n \"handlerContract\": {\n \"reads\": [\n \"tabs[]\",\n \"nav.links[]\",\n \"group.selectedIndex\",\n \"nav.selectedIndex\"\n ],\n \"writes\": [\n \"tabs[].visible\",\n \"nav.links[].visible\"\n ],\n \"identityKeys\": [\n \"tabs[].id\",\n \"nav.links[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"visible\"\n ],\n \"properties\": {\n \"visible\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"failureModes\": [\n \"target-tab-or-link-missing\",\n \"ambiguous-target\",\n \"active-item-hidden-without-reselection\"\n ],\n \"description\": \"Sets visible on the resolved group tab or nav link and preserves deterministic visible-index mapping.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tab-or-link-exists\",\n \"active-tab-visibility-safe\"\n ],\n \"affectedPaths\": [\n \"tabs[].visible\",\n \"nav.links[].visible\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-or-link-exists\"\n ]\n },\n {\n \"operationId\": \"tab.active.set\",\n \"title\": \"Set active tab\",\n \"scope\": \"interaction\",\n \"targetKind\": \"activeTab\",\n \"target\": {\n \"kind\": \"activeTab\",\n \"resolver\": \"tab-index-or-id\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"selectedIndex\"\n ],\n \"properties\": {\n \"selectedIndex\": {\n \"type\": \"number\"\n },\n \"tabId\": {\n \"type\": \"string\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"tabs.set-active-item\",\n \"handlerContract\": {\n \"reads\": [\n \"tabs[]\",\n \"nav.links[]\",\n \"group.selectedIndex\",\n \"nav.selectedIndex\"\n ],\n \"writes\": [\n \"group.selectedIndex\",\n \"nav.selectedIndex\"\n ],\n \"identityKeys\": [\n \"tabs[].id\",\n \"nav.links[].id\"\n ],\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"selectedIndex\"\n ],\n \"properties\": {\n \"selectedIndex\": {\n \"type\": \"number\"\n },\n \"tabId\": {\n \"type\": \"string\"\n }\n }\n },\n \"failureModes\": [\n \"target-tab-or-link-missing\",\n \"selected-index-out-of-range\",\n \"hidden-or-disabled-target\"\n ],\n \"description\": \"Sets the active index for the current primary mode using either selectedIndex or a resolved tab/link id.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"active-tab-exists\",\n \"selected-index-in-range\"\n ],\n \"affectedPaths\": [\n \"group.selectedIndex\",\n \"nav.selectedIndex\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-or-link-exists\"\n ]\n },\n {\n \"operationId\": \"layout.variant.set\",\n \"title\": \"Set tabs layout variant\",\n \"scope\": \"layout\",\n \"targetKind\": \"layout\",\n \"target\": {\n \"kind\": \"layout\",\n \"resolver\": \"tabs-layout-config\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"required\": [\n \"mode\"\n ],\n \"properties\": {\n \"mode\": {\n \"enum\": [\n \"group\",\n \"nav\"\n ]\n },\n \"density\": {\n \"enum\": [\n \"compact\",\n \"comfortable\",\n \"spacious\"\n ]\n },\n \"headerPosition\": {\n \"enum\": [\n \"above\",\n \"below\"\n ]\n },\n \"alignTabs\": {\n \"enum\": [\n \"start\",\n \"center\",\n \"end\"\n ]\n },\n \"stretchTabs\": {\n \"type\": \"boolean\"\n },\n \"lazyLoad\": {\n \"type\": \"boolean\"\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"merge-object\",\n \"path\": \"appearance\"\n },\n {\n \"kind\": \"merge-object\",\n \"path\": \"group\"\n },\n {\n \"kind\": \"merge-object\",\n \"path\": \"nav\"\n },\n {\n \"kind\": \"merge-object\",\n \"path\": \"behavior\"\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tabs-mode-compatible\",\n \"layout-values-valid\",\n \"editor-runtime-round-trip\"\n ],\n \"affectedPaths\": [\n \"appearance.density\",\n \"group.headerPosition\",\n \"group.alignTabs\",\n \"group.stretchTabs\",\n \"nav.stretchTabs\",\n \"behavior.lazyLoad\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\"\n ]\n },\n {\n \"operationId\": \"tab.content.set\",\n \"title\": \"Set tab content\",\n \"scope\": \"layout\",\n \"targetKind\": \"tabContent\",\n \"target\": {\n \"kind\": \"tabContent\",\n \"resolver\": \"tab-or-link-by-id\",\n \"ambiguityPolicy\": \"fail\",\n \"required\": true\n },\n \"inputSchema\": {\n \"type\": \"object\",\n \"minProperties\": 1,\n \"properties\": {\n \"id\": {\n \"type\": \"string\"\n },\n \"textLabel\": {\n \"type\": \"string\"\n },\n \"icon\": {\n \"type\": \"string\"\n },\n \"disabled\": {\n \"type\": \"boolean\"\n },\n \"visible\": {\n \"type\": \"boolean\"\n },\n \"content\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n },\n \"widgets\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\"\n }\n }\n }\n },\n \"effects\": [\n {\n \"kind\": \"compile-domain-patch\",\n \"handler\": \"tabs.set-tab-or-link-content\",\n \"handlerContract\": {\n \"reads\": [\n \"tabs[]\",\n \"nav.links[]\"\n ],\n \"writes\": [\n \"tabs[].content\",\n \"tabs[].widgets\",\n \"nav.links[].content\",\n \"nav.links[].widgets\"\n ],\n \"identityKeys\": [\n \"tabs[].id\",\n \"nav.links[].id\"\n ],\n \"failureModes\": [\n \"target-tab-or-link-missing\",\n \"invalid-dynamic-field-content\",\n \"invalid-widget-definition\"\n ],\n \"description\": \"Updates content/widgets only on the resolved group tab or nav link while preserving nested widget identity.\"\n }\n }\n ],\n \"destructive\": false,\n \"requiresConfirmation\": false,\n \"validators\": [\n \"tab-or-link-exists\",\n \"tab-content-valid\",\n \"widget-event-delegated\"\n ],\n \"affectedPaths\": [\n \"tabs[].content\",\n \"tabs[].widgets\",\n \"nav.links[].content\",\n \"nav.links[].widgets\"\n ],\n \"submissionImpact\": \"config-only\",\n \"preconditions\": [\n \"config-initialized\",\n \"target-tab-or-link-exists\"\n ]\n }\n ],\n \"validators\": [\n {\n \"validatorId\": \"tab-id-unique\",\n \"level\": \"error\",\n \"code\": \"PTABS001\",\n \"description\": \"Tab ids and nav link ids must be unique within their mode.\"\n },\n {\n \"validatorId\": \"tab-exists\",\n \"level\": \"error\",\n \"code\": \"PTABS002\",\n \"description\": \"Target tab must exist before applying the operation.\"\n },\n {\n \"validatorId\": \"tab-or-link-exists\",\n \"level\": \"error\",\n \"code\": \"PTABS003\",\n \"description\": \"Target must resolve to an existing group tab or nav link.\"\n },\n {\n \"validatorId\": \"active-tab-exists\",\n \"level\": \"error\",\n \"code\": \"PTABS004\",\n \"description\": \"Active tab or nav link selection must reference an existing item.\"\n },\n {\n \"validatorId\": \"selected-index-in-range\",\n \"level\": \"error\",\n \"code\": \"PTABS005\",\n \"description\": \"Selected index must be clamped to the target mode item count.\"\n },\n {\n \"validatorId\": \"active-tab-removal-safe\",\n \"level\": \"error\",\n \"code\": \"PTABS006\",\n \"description\": \"Removing the active/default tab requires confirmation or a replacement active tab.\"\n },\n {\n \"validatorId\": \"tab-content-removal-confirmed\",\n \"level\": \"error\",\n \"code\": \"PTABS007\",\n \"description\": \"Removing a tab or link with content/widgets is destructive and requires confirmation.\"\n },\n {\n \"validatorId\": \"tab-label-valid\",\n \"level\": \"error\",\n \"code\": \"PTABS008\",\n \"description\": \"Tab labels must be non-empty text values after localization/domain projection.\"\n },\n {\n \"validatorId\": \"tab-icon-valid\",\n \"level\": \"warning\",\n \"code\": \"PTABS009\",\n \"description\": \"Tab icon metadata must remain compatible with the icon directive and editor round-trip.\"\n },\n {\n \"validatorId\": \"tab-order-deterministic\",\n \"level\": \"error\",\n \"code\": \"PTABS010\",\n \"description\": \"Tab ordering must use stable ids, not transient array index as identity.\"\n },\n {\n \"validatorId\": \"tabs-mode-compatible\",\n \"level\": \"error\",\n \"code\": \"PTABS011\",\n \"description\": \"Authoring must resolve to one primary mode: group tabs or nav links.\"\n },\n {\n \"validatorId\": \"layout-values-valid\",\n \"level\": \"error\",\n \"code\": \"PTABS012\",\n \"description\": \"Layout values must match TabsMetadata enums and runtime bindings.\"\n },\n {\n \"validatorId\": \"editor-runtime-round-trip\",\n \"level\": \"error\",\n \"code\": \"PTABS013\",\n \"description\": \"Settings Panel, quick setup, JSON editor and runtime must preserve ids, order and selected index.\"\n },\n {\n \"validatorId\": \"active-tab-disabled-safe\",\n \"level\": \"warning\",\n \"code\": \"PTABS014\",\n \"description\": \"Disabling the active item should move selection or request explicit confirmation.\"\n },\n {\n \"validatorId\": \"active-tab-visibility-safe\",\n \"level\": \"warning\",\n \"code\": \"PTABS015\",\n \"description\": \"Hiding the active item should move selection or request explicit confirmation.\"\n },\n {\n \"validatorId\": \"tab-content-valid\",\n \"level\": \"error\",\n \"code\": \"PTABS016\",\n \"description\": \"Tab content must be valid DynamicFieldMetadata[] or WidgetDefinition[] and preserve nested widget identity.\"\n },\n {\n \"validatorId\": \"widget-event-delegated\",\n \"level\": \"info\",\n \"code\": \"PTABS017\",\n \"description\": \"Nested widget event paths remain delegated to the tabs runtime contract and are not redefined by authoring.\"\n }\n ],\n \"roundTripRequirements\": [\n \"Operations must preserve stable tab/link ids; array index may be used only as a resolver fallback, never as canonical identity.\",\n \"Settings Panel, quick setup and JSON editor must round-trip through TabsAuthoringDocument without losing config or bindings.\",\n \"Group and nav modes must remain mutually explicit; authoring cannot silently mix config.tabs and nav.links as competing primary modes.\",\n \"Nested widget events remain delegated through widgetEvent path enrichment and component-port nestedPath semantics.\"\n ],\n \"examples\": [\n {\n \"id\": \"add-overview-tab\",\n \"request\": \"Add an Overview tab before the details tab.\",\n \"operationId\": \"tab.add\",\n \"params\": {\n \"id\": \"overview\",\n \"textLabel\": \"Overview\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-list-to-current-tab\",\n \"request\": \"Create a list widget inside the current training tab.\",\n \"operationId\": \"tab.content.set\",\n \"target\": \"training\",\n \"params\": {\n \"widgets\": [\n {\n \"id\": \"training-list\",\n \"component\": \"praxis-list\",\n \"title\": \"Training list\"\n }\n ]\n },\n \"isPositive\": true\n },\n {\n \"id\": \"add-form-fields-to-existing-tab\",\n \"request\": \"Add name, date and status fields to the existing onboarding tab.\",\n \"operationId\": \"tab.content.set\",\n \"target\": \"onboarding\",\n \"params\": {\n \"content\": [\n {\n \"name\": \"name\",\n \"label\": \"Name\",\n \"controlType\": \"text\"\n },\n {\n \"name\": \"plannedDate\",\n \"label\": \"Planned date\",\n \"controlType\": \"date\"\n },\n {\n \"name\": \"status\",\n \"label\": \"Status\",\n \"controlType\": \"select\"\n }\n ]\n },\n \"isPositive\": true\n },\n {\n \"id\": \"rename-tab\",\n \"request\": \"Rename the details tab to Account Details.\",\n \"operationId\": \"tab.label.set\",\n \"target\": \"details\",\n \"params\": {\n \"textLabel\": \"Account Details\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reorder-tabs\",\n \"request\": \"Move billing before overview.\",\n \"operationId\": \"tab.order.set\",\n \"target\": \"billing\",\n \"params\": {\n \"beforeTabId\": \"overview\"\n },\n \"isPositive\": true\n },\n {\n \"id\": \"disable-tab\",\n \"request\": \"Disable the audit tab until the user has permission.\",\n \"operationId\": \"tab.disabled.set\",\n \"target\": \"audit\",\n \"params\": {\n \"disabled\": true\n },\n \"isPositive\": true\n },\n {\n \"id\": \"activate-tab\",\n \"request\": \"Open the documents tab by default.\",\n \"operationId\": \"tab.active.set\",\n \"target\": \"documents\",\n \"params\": {\n \"tabId\": \"documents\",\n \"selectedIndex\": 2\n },\n \"isPositive\": true\n },\n {\n \"id\": \"reject-duplicate-tab-id\",\n \"request\": \"Add another tab with id overview.\",\n \"operationId\": \"tab.add\",\n \"params\": {\n \"id\": \"overview\",\n \"textLabel\": \"Duplicate Overview\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"reject-current-tab-content-as-tab-add\",\n \"request\": \"Create a list in this tab; do not add a new tab.\",\n \"operationId\": \"tab.add\",\n \"params\": {\n \"id\": \"list-in-this-tab\",\n \"textLabel\": \"List in this tab\"\n },\n \"isPositive\": false\n },\n {\n \"id\": \"confirm-remove-content-tab\",\n \"request\": \"Remove the details tab that contains widgets.\",\n \"operationId\": \"tab.remove\",\n \"target\": \"details\",\n \"params\": {\n \"replacementActiveTabId\": \"overview\"\n },\n \"isPositive\": true\n }\n ]\n}",
|
|
2026
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-tabs/src/lib/ai/praxis-tabs-authoring-manifest.ts",
|
|
2027
|
+
"contentHash": "f6ba5ad9580601e9a0f3edd06d36da420a21095928e443bba073bbf14fa9db80",
|
|
2028
|
+
"sourceKind": "component_definition",
|
|
2029
|
+
"sourceId": "praxis-tabs",
|
|
2030
|
+
"corpusVersion": "1.0.0"
|
|
2031
|
+
},
|
|
2032
|
+
{
|
|
2033
|
+
"chunkIndex": 3,
|
|
2034
|
+
"chunkKind": "context_pack",
|
|
2035
|
+
"content": "{\n \"componentContext\": {\n \"version\": \"v1\",\n \"optionsByPath\": {\n \"appearance.density\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"compact\",\n \"label\": \"Compact\"\n },\n {\n \"value\": \"comfortable\",\n \"label\": \"Comfortable\"\n },\n {\n \"value\": \"spacious\",\n \"label\": \"Spacious\"\n }\n ]\n },\n \"group.alignTabs\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"start\",\n \"label\": \"Start\"\n },\n {\n \"value\": \"center\",\n \"label\": \"Center\"\n },\n {\n \"value\": \"end\",\n \"label\": \"End\"\n }\n ]\n },\n \"group.headerPosition\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"above\",\n \"label\": \"Above\"\n },\n {\n \"value\": \"below\",\n \"label\": \"Below\"\n }\n ]\n },\n \"group.color\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"primary\",\n \"label\": \"Primary\"\n },\n {\n \"value\": \"accent\",\n \"label\": \"Accent\"\n },\n {\n \"value\": \"warn\",\n \"label\": \"Warn\"\n }\n ]\n },\n \"group.backgroundColor\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"primary\",\n \"label\": \"Primary\"\n },\n {\n \"value\": \"accent\",\n \"label\": \"Accent\"\n },\n {\n \"value\": \"warn\",\n \"label\": \"Warn\"\n }\n ]\n },\n \"nav.color\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"primary\",\n \"label\": \"Primary\"\n },\n {\n \"value\": \"accent\",\n \"label\": \"Accent\"\n },\n {\n \"value\": \"warn\",\n \"label\": \"Warn\"\n }\n ]\n },\n \"nav.backgroundColor\": {\n \"mode\": \"enum\",\n \"options\": [\n {\n \"value\": \"primary\",\n \"label\": \"Primary\"\n },\n {\n \"value\": \"accent\",\n \"label\": \"Accent\"\n },\n {\n \"value\": \"warn\",\n \"label\": \"Warn\"\n }\n ]\n }\n },\n \"actionCatalog\": [\n {\n \"id\": \"appearance.density.set\",\n \"intentExamples\": [\n \"density\",\n \"compact\",\n \"spacious\"\n ],\n \"patchTemplate\": {\n \"appearance\": {\n \"density\": \"{{value}}\"\n }\n }\n },\n {\n \"id\": \"group.alignTabs.set\",\n \"intentExamples\": [\n \"align tabs\",\n \"tab alignment\",\n \"align header\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"alignTabs\": \"{{value}}\"\n }\n }\n },\n {\n \"id\": \"group.headerPosition.set\",\n \"intentExamples\": [\n \"header position\",\n \"tabs position\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"headerPosition\": \"{{value}}\"\n }\n }\n },\n {\n \"id\": \"group.selectedIndex.set\",\n \"intentExamples\": [\n \"select tab\",\n \"active tab\",\n \"selected index\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"selectedIndex\": \"{{value}}\"\n }\n }\n },\n {\n \"id\": \"nav.selectedIndex.set\",\n \"intentExamples\": [\n \"select link\",\n \"active link\",\n \"selected nav\"\n ],\n \"patchTemplate\": {\n \"nav\": {\n \"selectedIndex\": \"{{value}}\"\n }\n }\n },\n {\n \"id\": \"behavior.lazyLoad.enable\",\n \"intentExamples\": [\n \"lazy load\",\n \"load on demand\",\n \"lazy\"\n ],\n \"patchTemplate\": {\n \"behavior\": {\n \"lazyLoad\": true\n }\n }\n },\n {\n \"id\": \"behavior.lazyLoad.disable\",\n \"intentExamples\": [\n \"no lazy\",\n \"eager load\"\n ],\n \"patchTemplate\": {\n \"behavior\": {\n \"lazyLoad\": false\n }\n }\n },\n {\n \"id\": \"group.stretchTabs.enable\",\n \"intentExamples\": [\n \"stretch tabs\",\n \"full width tabs\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"stretchTabs\": true\n }\n }\n },\n {\n \"id\": \"group.stretchTabs.disable\",\n \"intentExamples\": [\n \"no stretch tabs\",\n \"compact tabs\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"stretchTabs\": false\n }\n }\n },\n {\n \"id\": \"group.disablePagination.enable\",\n \"intentExamples\": [\n \"disable pagination\",\n \"no pagination\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"disablePagination\": true\n }\n }\n },\n {\n \"id\": \"group.disablePagination.disable\",\n \"intentExamples\": [\n \"enable pagination\",\n \"allow pagination\"\n ],\n \"patchTemplate\": {\n \"group\": {\n \"disablePagination\": false\n }\n }\n },\n {\n \"id\": \"tab.add\",\n \"intentExamples\": [\n \"add tab\",\n \"new tab\",\n \"create tab\",\n \"nova aba\",\n \"adicionar aba\",\n \"criar aba\"\n ],\n \"patchTemplate\": {\n \"tabs\": [\n {\n \"id\": \"{{target}}\",\n \"textLabel\": \"{{value}}\"\n }\n ]\n }\n },\n {\n \"id\": \"tab.content.set\",\n \"intentExamples\": [\n \"tab content\",\n \"current tab content\",\n \"add widget to tab\",\n \"list in current tab\",\n \"inside tab\",\n \"conteudo da aba\",\n \"nesta aba\",\n \"aba atual\",\n \"componente dentro da aba\"\n ],\n \"patchTemplate\": {\n \"tabs\": [\n {\n \"id\": \"{{target}}\",\n \"content\": \"{{params.content}}\",\n \"widgets\": \"{{params.widgets}}\"\n }\n ]\n }\n },\n {\n \"id\": \"tab.label.set\",\n \"intentExamples\": [\n \"rename tab\",\n \"tab label\",\n \"tab title\"\n ],\n \"patchTemplate\": {\n \"tabs\": [\n {\n \"id\": \"{{target}}\",\n \"textLabel\": \"{{value}}\"\n }\n ]\n }\n },\n {\n \"id\": \"tab.disable\",\n \"intentExamples\": [\n \"disable tab\",\n \"lock tab\"\n ],\n \"patchTemplate\": {\n \"tabs\": [\n {\n \"id\": \"{{target}}\",\n \"disabled\": true\n }\n ]\n }\n },\n {\n \"id\": \"tab.enable\",\n \"intentExamples\": [\n \"enable tab\",\n \"unlock tab\"\n ],\n \"patchTemplate\": {\n \"tabs\": [\n {\n \"id\": \"{{target}}\",\n \"disabled\": false\n }\n ]\n }\n },\n {\n \"id\": \"nav.link.add\",\n \"intentExamples\": [\n \"add link\",\n \"add nav link\",\n \"new link\"\n ],\n \"patchTemplate\": {\n \"nav\": {\n \"links\": [\n {\n \"id\": \"{{target}}\",\n \"label\": \"{{value}}\"\n }\n ]\n }\n }\n },\n {\n \"id\": \"nav.link.label.set\",\n \"intentExamples\": [\n \"rename link\",\n \"link label\"\n ],\n \"patchTemplate\": {\n \"nav\": {\n \"links\": [\n {\n \"id\": \"{{target}}\",\n \"label\": \"{{value}}\"\n }\n ]\n }\n }\n },\n {\n \"id\": \"nav.link.disable\",\n \"intentExamples\": [\n \"disable link\",\n \"lock link\"\n ],\n \"patchTemplate\": {\n \"nav\": {\n \"links\": [\n {\n \"id\": \"{{target}}\",\n \"disabled\": true\n }\n ]\n }\n }\n },\n {\n \"id\": \"nav.link.enable\",\n \"intentExamples\": [\n \"enable link\",\n \"unlock link\"\n ],\n \"patchTemplate\": {\n \"nav\": {\n \"links\": [\n {\n \"id\": \"{{target}}\",\n \"disabled\": false\n }\n ]\n }\n }\n }\n ],\n \"fieldResolvers\": {\n \"tabs[]\": [\n \"id\",\n \"textLabel\"\n ],\n \"nav.links[]\": [\n \"id\",\n \"label\"\n ]\n },\n \"hints\": [\n \"Use tabs[].id or tabs[].textLabel as merge keys; avoid array indexes.\",\n \"When using nav mode, prefer nav.links[]; when using group mode, prefer tabs[].\",\n \"Selected index expects a zero-based number.\",\n \"DOC: Widget purpose: tabs or nav links with dynamic content.\",\n \"DOC: Host inputs: tabsId (required), config (optional), and configPersistenceStrategy. Use input-first for governed previews that must render the explicit nested widget config.\",\n \"DOC: Provide either tabs[] (group mode) or nav.links[] (nav mode).\",\n \"DOC: Each tab/link should define a label (tabs[].textLabel or nav.links[].label).\"\n ]\n }\n}",
|
|
2036
|
+
"sourcePointer": "praxis-ui-angular/projects/praxis-tabs/src/lib/ai/tabs-context-pack.ts",
|
|
2037
|
+
"contentHash": "553c32fd70139826d73d295bead2d03c309ce7e3ad91d1d8430e3681defcda19",
|
|
2038
|
+
"sourceKind": "component_definition",
|
|
2039
|
+
"sourceId": "praxis-tabs",
|
|
2040
|
+
"corpusVersion": "1.0.0"
|
|
2041
|
+
},
|
|
2042
|
+
{
|
|
2043
|
+
"chunkIndex": 4,
|
|
2044
|
+
"chunkKind": "recipe",
|
|
2045
|
+
"content": "{\n \"_comment\": \"Receita para configuração de Abas (Praxis Tabs).\",\n \"templateMeta\": {\n \"registryKey\": \"praxis-tabs\",\n \"variantId\": \"base\",\n \"useWhen\": \"Base tabs configuration.\",\n \"examplePrompts\": [\n \"create a tabs layout\",\n \"add tabs with icons and routes\"\n ]\n },\n \"config\": {\n \"orientation\": \"horizontal\",\n \"lazyLoad\": true,\n \"animation\": true,\n \"keepAlive\": true,\n \"tabs\": [\n {\n \"id\": \"tab-overview\",\n \"label\": \"Visão Geral\",\n \"icon\": \"dashboard\",\n \"route\": \"./overview\"\n },\n {\n \"id\": \"tab-details\",\n \"label\": \"Detalhes\",\n \"icon\": \"list\",\n \"badge\": {\n \"content\": \"3\",\n \"color\": \"warn\"\n },\n \"route\": \"./details\"\n },\n {\n \"id\": \"tab-settings\",\n \"label\": \"Configurações\",\n \"icon\": \"settings\",\n \"disabled\": false,\n \"content\": {\n \"type\": \"component\",\n \"componentId\": \"settings-panel\"\n }\n }\n ]\n }\n}\n",
|
|
2046
|
+
"sourcePointer": "praxis-ui-angular/examples/ai-recipes/praxis-tabs.json",
|
|
2047
|
+
"contentHash": "82f4328235d1b31cc4d97442abd6e83c59f33b2320360098ca70aca508838d10",
|
|
2048
|
+
"sourceKind": "component_definition",
|
|
2049
|
+
"sourceId": "praxis-tabs",
|
|
2050
|
+
"corpusVersion": "1.0.0"
|
|
2051
|
+
}
|
|
2052
|
+
]
|
|
2053
|
+
}
|
|
2054
|
+
},
|
|
2055
|
+
"note": "Package-scoped Praxis component registry for source-free agent discovery. Use the canonical ingestion registry for cross-package aggregate analysis."
|
|
2056
|
+
}
|