@praxisui/tabs 10.0.0-rc.3 → 10.0.0-rc.31

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-07T02:07:06.204Z",
3
+ "generatedAt": "2026-10-16T17:45:27.774Z",
4
4
  "packageName": "@praxisui/tabs",
5
- "packageVersion": "10.0.0-rc.3",
5
+ "packageVersion": "10.0.0-rc.31",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -55,6 +55,7 @@ function validateTabsAuthoringDocument(doc, _context) {
55
55
  validateModeAmbiguity(normalized.config, diagnostics);
56
56
  validateDuplicateTabIds(normalized.config, diagnostics);
57
57
  validateDuplicateLinkIds(normalized.config, diagnostics);
58
+ validateDuplicateChildWidgetKeys(normalized.config, diagnostics);
58
59
  validateUnsupportedGuidedFields(normalized.config, diagnostics);
59
60
  return diagnostics;
60
61
  }
@@ -86,11 +87,28 @@ function buildTabsApplyPlan(doc, runtime, options) {
86
87
  function serializeTabsAuthoringDocument(doc) {
87
88
  return normalizeTabsAuthoringDocument(doc);
88
89
  }
90
+ function buildUniqueChildWidgetKey(containerId, widgetId, existingKeys) {
91
+ const used = new Set(Array.from(existingKeys)
92
+ .map((key) => key.trim())
93
+ .filter(Boolean));
94
+ const ownerSlug = slugifyIdentifier(containerId) || 'item';
95
+ const widgetSlug = slugifyIdentifier((widgetId || 'widget').replace(/^praxis-/i, '')) || 'widget';
96
+ const base = `${ownerSlug}-${widgetSlug}`;
97
+ let candidate = base;
98
+ let suffix = 2;
99
+ while (used.has(candidate)) {
100
+ candidate = `${base}-${suffix++}`;
101
+ }
102
+ return candidate;
103
+ }
89
104
  function normalizeTabsConfig(config) {
90
105
  const next = cloneJson(config ?? {});
91
106
  if (!Array.isArray(next.tabs) || next.tabs.length === 0) {
92
107
  delete next.tabs;
93
108
  }
109
+ else {
110
+ next.tabs = next.tabs.map((tab, index) => normalizeContainerWidgets(tab, `tab${index + 1}`));
111
+ }
94
112
  if (!next.nav || typeof next.nav !== 'object') {
95
113
  delete next.nav;
96
114
  }
@@ -104,8 +122,8 @@ function normalizeTabsConfig(config) {
104
122
  next.nav.selectedIndex = clampIndex(next.nav.selectedIndex, next.nav.links?.length ?? 0);
105
123
  }
106
124
  if (Array.isArray(next.nav?.links)) {
107
- next.nav.links = next.nav.links.map((link) => {
108
- const copy = { ...link };
125
+ next.nav.links = next.nav.links.map((link, index) => {
126
+ const copy = normalizeContainerWidgets({ ...link }, `link${index + 1}`);
109
127
  delete copy.active;
110
128
  return copy;
111
129
  });
@@ -166,6 +184,74 @@ function validateDuplicateLinkIds(config, diagnostics) {
166
184
  seen.add(id);
167
185
  });
168
186
  }
187
+ function validateDuplicateChildWidgetKeys(config, diagnostics) {
188
+ (config.tabs ?? []).forEach((tab, tabIndex) => {
189
+ const seen = new Set();
190
+ (tab.widgets ?? []).forEach((widget, widgetIndex) => {
191
+ const key = normalizeId(widget?.childWidgetKey);
192
+ if (!key)
193
+ return;
194
+ if (seen.has(key)) {
195
+ diagnostics.push(errorDiagnostic('tabs.config.widgets.childWidgetKey.duplicate', 'Duplicate childWidgetKey detected within the same tab.', `config.tabs[${tabIndex}].widgets[${widgetIndex}].childWidgetKey`));
196
+ return;
197
+ }
198
+ seen.add(key);
199
+ });
200
+ });
201
+ (config.nav?.links ?? []).forEach((link, linkIndex) => {
202
+ const seen = new Set();
203
+ (link.widgets ?? []).forEach((widget, widgetIndex) => {
204
+ const key = normalizeId(widget?.childWidgetKey);
205
+ if (!key)
206
+ return;
207
+ if (seen.has(key)) {
208
+ diagnostics.push(errorDiagnostic('tabs.config.widgets.childWidgetKey.duplicate', 'Duplicate childWidgetKey detected within the same nav link.', `config.nav.links[${linkIndex}].widgets[${widgetIndex}].childWidgetKey`));
209
+ return;
210
+ }
211
+ seen.add(key);
212
+ });
213
+ });
214
+ }
215
+ function normalizeContainerWidgets(container, fallbackContainerId) {
216
+ if (!container || typeof container !== 'object' || !Array.isArray(container.widgets)) {
217
+ return container;
218
+ }
219
+ const usedKeys = new Set();
220
+ for (const widget of container.widgets) {
221
+ const explicitKey = normalizeId(widget?.childWidgetKey);
222
+ if (explicitKey) {
223
+ usedKeys.add(explicitKey);
224
+ }
225
+ }
226
+ return {
227
+ ...container,
228
+ widgets: container.widgets.map((widget) => {
229
+ if (!widget || typeof widget !== 'object') {
230
+ return widget;
231
+ }
232
+ const explicitKey = normalizeId(widget.childWidgetKey);
233
+ if (explicitKey) {
234
+ return {
235
+ ...widget,
236
+ childWidgetKey: explicitKey,
237
+ };
238
+ }
239
+ const generatedKey = buildUniqueChildWidgetKey(container.id || fallbackContainerId, widget.id, usedKeys);
240
+ usedKeys.add(generatedKey);
241
+ return {
242
+ ...widget,
243
+ childWidgetKey: generatedKey,
244
+ };
245
+ }),
246
+ };
247
+ }
248
+ function slugifyIdentifier(value) {
249
+ return String(value ?? '')
250
+ .trim()
251
+ .toLowerCase()
252
+ .replace(/[^a-z0-9]+/g, '-')
253
+ .replace(/^-|-$/g, '');
254
+ }
169
255
  function validateUnsupportedGuidedFields(config, diagnostics) {
170
256
  if (config.group?.contentTabIndex !== undefined) {
171
257
  diagnostics.push(infoDiagnostic('tabs.config.group.contentTabIndex.unsupported', 'group.contentTabIndex is outside the supported authoring surface.', 'config.group.contentTabIndex'));
@@ -849,7 +935,14 @@ class PraxisTabsConfigEditor {
849
935
  return;
850
936
  const t = this.editedConfig.tabs[tabIndex];
851
937
  t.widgets = t.widgets || [];
852
- t.widgets.push({ id });
938
+ const childWidgetKey = this.nextChildWidgetKey(t.id || `tab${tabIndex + 1}`, id, t.widgets);
939
+ const rp = (this.quickResourcePathTab[tabIndex] || '').trim();
940
+ const defaultInputs = this.buildDefaultWidgetInputs(id, rp);
941
+ t.widgets.push({
942
+ id,
943
+ childWidgetKey,
944
+ ...(defaultInputs ? { inputs: defaultInputs } : {}),
945
+ });
853
946
  this.onAppearanceChange();
854
947
  }
855
948
  removeWidgetFromTab(tabIndex, widgetIndex) {
@@ -859,6 +952,20 @@ class PraxisTabsConfigEditor {
859
952
  t.widgets.splice(widgetIndex, 1);
860
953
  this.onAppearanceChange();
861
954
  }
955
+ updateWidgetKeyTab(tabIndex, widgetIndex, key) {
956
+ const t = this.editedConfig.tabs?.[tabIndex];
957
+ const widget = t?.widgets?.[widgetIndex];
958
+ if (!widget)
959
+ return;
960
+ const trimmed = String(key ?? '').trim();
961
+ if (trimmed) {
962
+ widget.childWidgetKey = trimmed;
963
+ }
964
+ else {
965
+ delete widget.childWidgetKey;
966
+ }
967
+ this.onAppearanceChange();
968
+ }
862
969
  updateWidgetInputsTab(tabIndex, widgetIndex, text) {
863
970
  const t = this.editedConfig.tabs[tabIndex];
864
971
  try {
@@ -883,14 +990,30 @@ class PraxisTabsConfigEditor {
883
990
  return;
884
991
  const t = this.editedConfig.tabs[tabIndex];
885
992
  t.widgets = t.widgets || [];
993
+ const containerId = t.id || `tab${tabIndex + 1}`;
886
994
  if (type === 'form') {
887
- t.widgets.push({ id: 'praxis-dynamic-form', inputs: { resourcePath: rp } });
995
+ const id = 'praxis-dynamic-form';
996
+ t.widgets.push({
997
+ id,
998
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, t.widgets),
999
+ inputs: { resourcePath: rp },
1000
+ });
888
1001
  }
889
1002
  else if (type === 'table') {
890
- t.widgets.push({ id: 'praxis-table', inputs: { resourcePath: rp, tableId: rp } });
1003
+ const id = 'praxis-table';
1004
+ t.widgets.push({
1005
+ id,
1006
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, t.widgets),
1007
+ inputs: { resourcePath: rp, tableId: rp },
1008
+ });
891
1009
  }
892
1010
  else {
893
- t.widgets.push({ id: 'praxis-crud', inputs: { crudId: rp, metadata: { resource: { path: rp } } } });
1011
+ const id = 'praxis-crud';
1012
+ t.widgets.push({
1013
+ id,
1014
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, t.widgets),
1015
+ inputs: { crudId: rp, metadata: { resource: { path: rp } } },
1016
+ });
894
1017
  }
895
1018
  this.onAppearanceChange();
896
1019
  }
@@ -927,7 +1050,14 @@ class PraxisTabsConfigEditor {
927
1050
  return;
928
1051
  const l = this.nav.links[linkIndex];
929
1052
  l.widgets = l.widgets || [];
930
- l.widgets.push({ id });
1053
+ const childWidgetKey = this.nextChildWidgetKey(l.id || `link${linkIndex + 1}`, id, l.widgets);
1054
+ const rp = (this.quickResourcePathLink[linkIndex] || '').trim();
1055
+ const defaultInputs = this.buildDefaultWidgetInputs(id, rp);
1056
+ l.widgets.push({
1057
+ id,
1058
+ childWidgetKey,
1059
+ ...(defaultInputs ? { inputs: defaultInputs } : {}),
1060
+ });
931
1061
  this.onAppearanceChange();
932
1062
  }
933
1063
  removeWidgetFromLink(linkIndex, widgetIndex) {
@@ -937,6 +1067,20 @@ class PraxisTabsConfigEditor {
937
1067
  l.widgets.splice(widgetIndex, 1);
938
1068
  this.onAppearanceChange();
939
1069
  }
1070
+ updateWidgetKeyLink(linkIndex, widgetIndex, key) {
1071
+ const l = this.nav.links?.[linkIndex];
1072
+ const widget = l?.widgets?.[widgetIndex];
1073
+ if (!widget)
1074
+ return;
1075
+ const trimmed = String(key ?? '').trim();
1076
+ if (trimmed) {
1077
+ widget.childWidgetKey = trimmed;
1078
+ }
1079
+ else {
1080
+ delete widget.childWidgetKey;
1081
+ }
1082
+ this.onAppearanceChange();
1083
+ }
940
1084
  updateWidgetInputsLink(linkIndex, widgetIndex, text) {
941
1085
  const l = this.nav.links[linkIndex];
942
1086
  try {
@@ -961,17 +1105,58 @@ class PraxisTabsConfigEditor {
961
1105
  return;
962
1106
  const l = this.nav.links[linkIndex];
963
1107
  l.widgets = l.widgets || [];
1108
+ const containerId = l.id || `link${linkIndex + 1}`;
964
1109
  if (type === 'form') {
965
- l.widgets.push({ id: 'praxis-dynamic-form', inputs: { resourcePath: rp } });
1110
+ const id = 'praxis-dynamic-form';
1111
+ l.widgets.push({
1112
+ id,
1113
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, l.widgets),
1114
+ inputs: { resourcePath: rp },
1115
+ });
966
1116
  }
967
1117
  else if (type === 'table') {
968
- l.widgets.push({ id: 'praxis-table', inputs: { resourcePath: rp, tableId: rp } });
1118
+ const id = 'praxis-table';
1119
+ l.widgets.push({
1120
+ id,
1121
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, l.widgets),
1122
+ inputs: { resourcePath: rp, tableId: rp },
1123
+ });
969
1124
  }
970
1125
  else {
971
- l.widgets.push({ id: 'praxis-crud', inputs: { crudId: rp, metadata: { resource: { path: rp } } } });
1126
+ const id = 'praxis-crud';
1127
+ l.widgets.push({
1128
+ id,
1129
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, l.widgets),
1130
+ inputs: { crudId: rp, metadata: { resource: { path: rp } } },
1131
+ });
972
1132
  }
973
1133
  this.onAppearanceChange();
974
1134
  }
1135
+ nextChildWidgetKey(containerId, widgetId, widgets) {
1136
+ const existingKeys = (widgets ?? [])
1137
+ .map((widget) => String(widget?.childWidgetKey ?? '').trim())
1138
+ .filter(Boolean);
1139
+ return buildUniqueChildWidgetKey(containerId, widgetId, existingKeys);
1140
+ }
1141
+ buildDefaultWidgetInputs(widgetId, resourcePath) {
1142
+ if (widgetId === 'praxis-related-resource-outlet') {
1143
+ return {
1144
+ parentResourcePath: resourcePath,
1145
+ surfaceId: '',
1146
+ mode: 'inline',
1147
+ };
1148
+ }
1149
+ if (!resourcePath) {
1150
+ return undefined;
1151
+ }
1152
+ if (widgetId === 'praxis-table') {
1153
+ return { resourcePath, tableId: resourcePath };
1154
+ }
1155
+ if (widgetId === 'praxis-dynamic-form') {
1156
+ return { resourcePath };
1157
+ }
1158
+ return undefined;
1159
+ }
975
1160
  stringify(v) { try {
976
1161
  return v ? JSON.stringify(v, null, 2) : '';
977
1162
  }
@@ -1390,6 +1575,10 @@ class PraxisTabsConfigEditor {
1390
1575
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
1391
1576
  <button praxisIconButton="delete" size="compact" type="button" class="editor-icon-action--danger" (click)="removeWidgetFromTab(i, wi)" [matTooltip]="t('editor.actions.removeComponent', 'Remover componente')" [attr.aria-label]="t('editor.actions.removeComponent', 'Remover componente')"></button>
1392
1577
  </div>
1578
+ <mat-form-field appearance="outline">
1579
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
1580
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyTab(i, wi, $event)" />
1581
+ </mat-form-field>
1393
1582
  <div class="editor-grid two tight">
1394
1583
  <mat-form-field appearance="outline">
1395
1584
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -1484,6 +1673,10 @@ class PraxisTabsConfigEditor {
1484
1673
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
1485
1674
  <button praxisIconButton="delete" size="compact" type="button" class="editor-icon-action--danger" (click)="removeWidgetFromLink(i, wi)" [matTooltip]="t('editor.actions.removeComponent', 'Remover componente')" [attr.aria-label]="t('editor.actions.removeComponent', 'Remover componente')"></button>
1486
1675
  </div>
1676
+ <mat-form-field appearance="outline">
1677
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
1678
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyLink(i, wi, $event)" />
1679
+ </mat-form-field>
1487
1680
  <div class="editor-grid two tight">
1488
1681
  <mat-form-field appearance="outline">
1489
1682
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -1920,6 +2113,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1920
2113
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
1921
2114
  <button praxisIconButton="delete" size="compact" type="button" class="editor-icon-action--danger" (click)="removeWidgetFromTab(i, wi)" [matTooltip]="t('editor.actions.removeComponent', 'Remover componente')" [attr.aria-label]="t('editor.actions.removeComponent', 'Remover componente')"></button>
1922
2115
  </div>
2116
+ <mat-form-field appearance="outline">
2117
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
2118
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyTab(i, wi, $event)" />
2119
+ </mat-form-field>
1923
2120
  <div class="editor-grid two tight">
1924
2121
  <mat-form-field appearance="outline">
1925
2122
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -2014,6 +2211,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2014
2211
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
2015
2212
  <button praxisIconButton="delete" size="compact" type="button" class="editor-icon-action--danger" (click)="removeWidgetFromLink(i, wi)" [matTooltip]="t('editor.actions.removeComponent', 'Remover componente')" [attr.aria-label]="t('editor.actions.removeComponent', 'Remover componente')"></button>
2016
2213
  </div>
2214
+ <mat-form-field appearance="outline">
2215
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
2216
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyLink(i, wi, $event)" />
2217
+ </mat-form-field>
2017
2218
  <div class="editor-grid two tight">
2018
2219
  <mat-form-field appearance="outline">
2019
2220
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -5764,4 +5965,4 @@ const PRAXIS_TABS_AUTHORING_MANIFEST = {
5764
5965
  * Generated bundle index. Do not edit.
5765
5966
  */
5766
5967
 
5767
- export { PRAXIS_TABS_AUTHORING_MANIFEST, PRAXIS_TABS_COMPONENT_METADATA, PRAXIS_TABS_I18N_CONFIG, PRAXIS_TABS_I18N_NAMESPACE, PraxisTabs, PraxisTabsConfigEditor, PraxisTabsWidgetConfigEditor, TABS_AI_CAPABILITIES, buildTabsApplyPlan, createPraxisTabsI18nConfig, createTabsAuthoringDocument, normalizeTabsAuthoringDocument, providePraxisTabsI18n, providePraxisTabsMetadata, serializeTabsAuthoringDocument, toCanonicalTabsConfig, validateTabsAuthoringDocument };
5968
+ export { PRAXIS_TABS_AUTHORING_MANIFEST, PRAXIS_TABS_COMPONENT_METADATA, PRAXIS_TABS_I18N_CONFIG, PRAXIS_TABS_I18N_NAMESPACE, PraxisTabs, PraxisTabsConfigEditor, PraxisTabsWidgetConfigEditor, TABS_AI_CAPABILITIES, buildTabsApplyPlan, buildUniqueChildWidgetKey, createPraxisTabsI18nConfig, createTabsAuthoringDocument, normalizeTabsAuthoringDocument, providePraxisTabsI18n, providePraxisTabsMetadata, serializeTabsAuthoringDocument, toCanonicalTabsConfig, validateTabsAuthoringDocument };
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@praxisui/tabs",
3
- "version": "10.0.0-rc.3",
3
+ "version": "10.0.0-rc.31",
4
4
  "description": "Configurable tabs (group and nav) for Praxis UI with metadata-driven content and runtime editor.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
8
  "@angular/material": "^21.0.0",
9
9
  "@angular/cdk": "^21.0.0",
10
- "@praxisui/core": "^10.0.0-rc.3",
11
- "@praxisui/dynamic-fields": "^10.0.0-rc.3",
12
- "@praxisui/settings-panel": "^10.0.0-rc.3",
10
+ "@praxisui/core": "^10.0.0-rc.31",
11
+ "@praxisui/dynamic-fields": "^10.0.0-rc.31",
12
+ "@praxisui/settings-panel": "^10.0.0-rc.31",
13
13
  "@angular/forms": "^21.0.0",
14
14
  "@angular/router": "^21.0.0",
15
- "@praxisui/ai": "^10.0.0-rc.3",
15
+ "@praxisui/ai": "^10.0.0-rc.31",
16
16
  "rxjs": "~7.8.0"
17
17
  },
18
18
  "dependencies": {
@@ -492,6 +492,7 @@ declare class PraxisTabsConfigEditor implements SettingsValueProvider {
492
492
  moveTab(index: number, delta: number): void;
493
493
  addWidgetToTab(tabIndex: number): void;
494
494
  removeWidgetFromTab(tabIndex: number, widgetIndex: number): void;
495
+ updateWidgetKeyTab(tabIndex: number, widgetIndex: number, key: string): void;
495
496
  updateWidgetInputsTab(tabIndex: number, widgetIndex: number, text: string): void;
496
497
  updateWidgetOutputsTab(tabIndex: number, widgetIndex: number, text: string): void;
497
498
  addPresetToTab(tabIndex: number, type: 'form' | 'table' | 'crud'): void;
@@ -500,9 +501,12 @@ declare class PraxisTabsConfigEditor implements SettingsValueProvider {
500
501
  moveLink(index: number, delta: number): void;
501
502
  addWidgetToLink(linkIndex: number): void;
502
503
  removeWidgetFromLink(linkIndex: number, widgetIndex: number): void;
504
+ updateWidgetKeyLink(linkIndex: number, widgetIndex: number, key: string): void;
503
505
  updateWidgetInputsLink(linkIndex: number, widgetIndex: number, text: string): void;
504
506
  updateWidgetOutputsLink(linkIndex: number, widgetIndex: number, text: string): void;
505
507
  addPresetToLink(linkIndex: number, type: 'form' | 'table' | 'crud'): void;
508
+ private nextChildWidgetKey;
509
+ private buildDefaultWidgetInputs;
506
510
  stringify(v: any): string;
507
511
  getCompName(id: string): string;
508
512
  onTabWidgetDrop(tabIndex: number, event: CdkDragDrop<WidgetDefinition[]>): void;
@@ -560,6 +564,7 @@ declare function buildTabsApplyPlan(doc: TabsAuthoringDocument, runtime?: TabsRu
560
564
  saveBindings?: boolean;
561
565
  }): TabsApplyPlan;
562
566
  declare function serializeTabsAuthoringDocument(doc: TabsAuthoringDocument): TabsAuthoringDocument;
567
+ declare function buildUniqueChildWidgetKey(containerId: string | undefined, widgetId: string | undefined, existingKeys: Iterable<string>): string;
563
568
 
564
569
  /**
565
570
  * Capabilities catalog for Praxis Tabs (TabsMetadata).
@@ -586,5 +591,5 @@ declare const TABS_AI_CAPABILITIES: CapabilityCatalog;
586
591
 
587
592
  declare const PRAXIS_TABS_AUTHORING_MANIFEST: ComponentAuthoringManifest;
588
593
 
589
- export { PRAXIS_TABS_AUTHORING_MANIFEST, PRAXIS_TABS_COMPONENT_METADATA, PRAXIS_TABS_I18N_CONFIG, PRAXIS_TABS_I18N_NAMESPACE, PraxisTabs, PraxisTabsConfigEditor, PraxisTabsWidgetConfigEditor, TABS_AI_CAPABILITIES, buildTabsApplyPlan, createPraxisTabsI18nConfig, createTabsAuthoringDocument, normalizeTabsAuthoringDocument, providePraxisTabsI18n, providePraxisTabsMetadata, serializeTabsAuthoringDocument, toCanonicalTabsConfig, validateTabsAuthoringDocument };
594
+ export { PRAXIS_TABS_AUTHORING_MANIFEST, PRAXIS_TABS_COMPONENT_METADATA, PRAXIS_TABS_I18N_CONFIG, PRAXIS_TABS_I18N_NAMESPACE, PraxisTabs, PraxisTabsConfigEditor, PraxisTabsWidgetConfigEditor, TABS_AI_CAPABILITIES, buildTabsApplyPlan, buildUniqueChildWidgetKey, createPraxisTabsI18nConfig, createTabsAuthoringDocument, normalizeTabsAuthoringDocument, providePraxisTabsI18n, providePraxisTabsMetadata, serializeTabsAuthoringDocument, toCanonicalTabsConfig, validateTabsAuthoringDocument };
590
595
  export type { Capability, CapabilityCatalog, CapabilityCategory, PraxisTabsWidgetEditorInputs, PraxisTabsWidgetEditorValue, TabGroupMetadata, TabLinkMetadata, TabMetadata, TabNavMetadata, TabsAccessibilityConfig, TabsAppearanceConfig, TabsApplyPlan, TabsAuthoringBindings, TabsAuthoringDocument, TabsBehaviorConfig, TabsBindingsDiff, TabsConfigChangeEvent, TabsConfigPersistenceStrategy, TabsEditorDiagnostic, TabsEditorDiagnosticLevel, TabsEditorDocumentKind, TabsEventConfig, TabsMetadata, TabsRuntimeContext, TabsRuntimePlan, TabsStyleTokens, ValueKind };