@praxisui/tabs 10.0.0-rc.4 → 10.0.0-rc.41

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-07T11:07:08.250Z",
3
+ "generatedAt": "2026-10-27T22:14:23.237Z",
4
4
  "packageName": "@praxisui/tabs",
5
- "packageVersion": "10.0.0-rc.4",
5
+ "packageVersion": "10.0.0-rc.41",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -7,11 +7,11 @@ import * as i3 from '@angular/material/tabs';
7
7
  import { MatTabsModule, MatTabGroup, MatTabNav } from '@angular/material/tabs';
8
8
  import * as i4$1 from '@angular/material/icon';
9
9
  import { MatIconModule } from '@angular/material/icon';
10
- import * as i10 from '@angular/material/tooltip';
10
+ import * as i11 from '@angular/material/tooltip';
11
11
  import { MatTooltipModule } from '@angular/material/tooltip';
12
12
  import * as i1 from '@praxisui/core';
13
13
  import { providePraxisI18n, PraxisI18nService, PraxisIconDirective, PraxisIconButtonComponent, providePraxisI18nConfig, deepMerge, ASYNC_CONFIG_STORAGE, ComponentKeyService, LoggerService, EmptyStateCardComponent, DynamicWidgetLoaderDirective, ComponentMetadataRegistry } from '@praxisui/core';
14
- import * as i6 from '@angular/material/button';
14
+ import * as i6$1 from '@angular/material/button';
15
15
  import { MatButtonModule } from '@angular/material/button';
16
16
  import * as i2_1 from '@angular/forms';
17
17
  import { FormsModule, FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
@@ -21,9 +21,11 @@ import * as i4 from '@angular/material/form-field';
21
21
  import { MatFormFieldModule } from '@angular/material/form-field';
22
22
  import * as i5 from '@angular/material/input';
23
23
  import { MatInputModule } from '@angular/material/input';
24
- import * as i8 from '@angular/material/slide-toggle';
24
+ import * as i6 from '@angular/material/select';
25
+ import { MatSelectModule } from '@angular/material/select';
26
+ import * as i9 from '@angular/material/slide-toggle';
25
27
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
26
- import * as i9 from '@angular/cdk/drag-drop';
28
+ import * as i10 from '@angular/cdk/drag-drop';
27
29
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
28
30
  import { BehaviorSubject, firstValueFrom, Subject, Subscription } from 'rxjs';
29
31
  import { produce } from 'immer';
@@ -55,6 +57,7 @@ function validateTabsAuthoringDocument(doc, _context) {
55
57
  validateModeAmbiguity(normalized.config, diagnostics);
56
58
  validateDuplicateTabIds(normalized.config, diagnostics);
57
59
  validateDuplicateLinkIds(normalized.config, diagnostics);
60
+ validateDuplicateChildWidgetKeys(normalized.config, diagnostics);
58
61
  validateUnsupportedGuidedFields(normalized.config, diagnostics);
59
62
  return diagnostics;
60
63
  }
@@ -86,11 +89,28 @@ function buildTabsApplyPlan(doc, runtime, options) {
86
89
  function serializeTabsAuthoringDocument(doc) {
87
90
  return normalizeTabsAuthoringDocument(doc);
88
91
  }
92
+ function buildUniqueChildWidgetKey(containerId, widgetId, existingKeys) {
93
+ const used = new Set(Array.from(existingKeys)
94
+ .map((key) => key.trim())
95
+ .filter(Boolean));
96
+ const ownerSlug = slugifyIdentifier(containerId) || 'item';
97
+ const widgetSlug = slugifyIdentifier((widgetId || 'widget').replace(/^praxis-/i, '')) || 'widget';
98
+ const base = `${ownerSlug}-${widgetSlug}`;
99
+ let candidate = base;
100
+ let suffix = 2;
101
+ while (used.has(candidate)) {
102
+ candidate = `${base}-${suffix++}`;
103
+ }
104
+ return candidate;
105
+ }
89
106
  function normalizeTabsConfig(config) {
90
107
  const next = cloneJson(config ?? {});
91
108
  if (!Array.isArray(next.tabs) || next.tabs.length === 0) {
92
109
  delete next.tabs;
93
110
  }
111
+ else {
112
+ next.tabs = next.tabs.map((tab, index) => normalizeContainerWidgets(tab, `tab${index + 1}`));
113
+ }
94
114
  if (!next.nav || typeof next.nav !== 'object') {
95
115
  delete next.nav;
96
116
  }
@@ -104,8 +124,8 @@ function normalizeTabsConfig(config) {
104
124
  next.nav.selectedIndex = clampIndex(next.nav.selectedIndex, next.nav.links?.length ?? 0);
105
125
  }
106
126
  if (Array.isArray(next.nav?.links)) {
107
- next.nav.links = next.nav.links.map((link) => {
108
- const copy = { ...link };
127
+ next.nav.links = next.nav.links.map((link, index) => {
128
+ const copy = normalizeContainerWidgets({ ...link }, `link${index + 1}`);
109
129
  delete copy.active;
110
130
  return copy;
111
131
  });
@@ -166,6 +186,74 @@ function validateDuplicateLinkIds(config, diagnostics) {
166
186
  seen.add(id);
167
187
  });
168
188
  }
189
+ function validateDuplicateChildWidgetKeys(config, diagnostics) {
190
+ (config.tabs ?? []).forEach((tab, tabIndex) => {
191
+ const seen = new Set();
192
+ (tab.widgets ?? []).forEach((widget, widgetIndex) => {
193
+ const key = normalizeId(widget?.childWidgetKey);
194
+ if (!key)
195
+ return;
196
+ if (seen.has(key)) {
197
+ diagnostics.push(errorDiagnostic('tabs.config.widgets.childWidgetKey.duplicate', 'Duplicate childWidgetKey detected within the same tab.', `config.tabs[${tabIndex}].widgets[${widgetIndex}].childWidgetKey`));
198
+ return;
199
+ }
200
+ seen.add(key);
201
+ });
202
+ });
203
+ (config.nav?.links ?? []).forEach((link, linkIndex) => {
204
+ const seen = new Set();
205
+ (link.widgets ?? []).forEach((widget, widgetIndex) => {
206
+ const key = normalizeId(widget?.childWidgetKey);
207
+ if (!key)
208
+ return;
209
+ if (seen.has(key)) {
210
+ diagnostics.push(errorDiagnostic('tabs.config.widgets.childWidgetKey.duplicate', 'Duplicate childWidgetKey detected within the same nav link.', `config.nav.links[${linkIndex}].widgets[${widgetIndex}].childWidgetKey`));
211
+ return;
212
+ }
213
+ seen.add(key);
214
+ });
215
+ });
216
+ }
217
+ function normalizeContainerWidgets(container, fallbackContainerId) {
218
+ if (!container || typeof container !== 'object' || !Array.isArray(container.widgets)) {
219
+ return container;
220
+ }
221
+ const usedKeys = new Set();
222
+ for (const widget of container.widgets) {
223
+ const explicitKey = normalizeId(widget?.childWidgetKey);
224
+ if (explicitKey) {
225
+ usedKeys.add(explicitKey);
226
+ }
227
+ }
228
+ return {
229
+ ...container,
230
+ widgets: container.widgets.map((widget) => {
231
+ if (!widget || typeof widget !== 'object') {
232
+ return widget;
233
+ }
234
+ const explicitKey = normalizeId(widget.childWidgetKey);
235
+ if (explicitKey) {
236
+ return {
237
+ ...widget,
238
+ childWidgetKey: explicitKey,
239
+ };
240
+ }
241
+ const generatedKey = buildUniqueChildWidgetKey(container.id || fallbackContainerId, widget.id, usedKeys);
242
+ usedKeys.add(generatedKey);
243
+ return {
244
+ ...widget,
245
+ childWidgetKey: generatedKey,
246
+ };
247
+ }),
248
+ };
249
+ }
250
+ function slugifyIdentifier(value) {
251
+ return String(value ?? '')
252
+ .trim()
253
+ .toLowerCase()
254
+ .replace(/[^a-z0-9]+/g, '-')
255
+ .replace(/^-|-$/g, '');
256
+ }
169
257
  function validateUnsupportedGuidedFields(config, diagnostics) {
170
258
  if (config.group?.contentTabIndex !== undefined) {
171
259
  diagnostics.push(infoDiagnostic('tabs.config.group.contentTabIndex.unsupported', 'group.contentTabIndex is outside the supported authoring surface.', 'config.group.contentTabIndex'));
@@ -849,7 +937,14 @@ class PraxisTabsConfigEditor {
849
937
  return;
850
938
  const t = this.editedConfig.tabs[tabIndex];
851
939
  t.widgets = t.widgets || [];
852
- t.widgets.push({ id });
940
+ const childWidgetKey = this.nextChildWidgetKey(t.id || `tab${tabIndex + 1}`, id, t.widgets);
941
+ const rp = (this.quickResourcePathTab[tabIndex] || '').trim();
942
+ const defaultInputs = this.buildDefaultWidgetInputs(id, rp);
943
+ t.widgets.push({
944
+ id,
945
+ childWidgetKey,
946
+ ...(defaultInputs ? { inputs: defaultInputs } : {}),
947
+ });
853
948
  this.onAppearanceChange();
854
949
  }
855
950
  removeWidgetFromTab(tabIndex, widgetIndex) {
@@ -859,6 +954,20 @@ class PraxisTabsConfigEditor {
859
954
  t.widgets.splice(widgetIndex, 1);
860
955
  this.onAppearanceChange();
861
956
  }
957
+ updateWidgetKeyTab(tabIndex, widgetIndex, key) {
958
+ const t = this.editedConfig.tabs?.[tabIndex];
959
+ const widget = t?.widgets?.[widgetIndex];
960
+ if (!widget)
961
+ return;
962
+ const trimmed = String(key ?? '').trim();
963
+ if (trimmed) {
964
+ widget.childWidgetKey = trimmed;
965
+ }
966
+ else {
967
+ delete widget.childWidgetKey;
968
+ }
969
+ this.onAppearanceChange();
970
+ }
862
971
  updateWidgetInputsTab(tabIndex, widgetIndex, text) {
863
972
  const t = this.editedConfig.tabs[tabIndex];
864
973
  try {
@@ -883,14 +992,30 @@ class PraxisTabsConfigEditor {
883
992
  return;
884
993
  const t = this.editedConfig.tabs[tabIndex];
885
994
  t.widgets = t.widgets || [];
995
+ const containerId = t.id || `tab${tabIndex + 1}`;
886
996
  if (type === 'form') {
887
- t.widgets.push({ id: 'praxis-dynamic-form', inputs: { resourcePath: rp } });
997
+ const id = 'praxis-dynamic-form';
998
+ t.widgets.push({
999
+ id,
1000
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, t.widgets),
1001
+ inputs: { resourcePath: rp },
1002
+ });
888
1003
  }
889
1004
  else if (type === 'table') {
890
- t.widgets.push({ id: 'praxis-table', inputs: { resourcePath: rp, tableId: rp } });
1005
+ const id = 'praxis-table';
1006
+ t.widgets.push({
1007
+ id,
1008
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, t.widgets),
1009
+ inputs: { resourcePath: rp, tableId: rp },
1010
+ });
891
1011
  }
892
1012
  else {
893
- t.widgets.push({ id: 'praxis-crud', inputs: { crudId: rp, metadata: { resource: { path: rp } } } });
1013
+ const id = 'praxis-crud';
1014
+ t.widgets.push({
1015
+ id,
1016
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, t.widgets),
1017
+ inputs: { crudId: rp, metadata: { resource: { path: rp } } },
1018
+ });
894
1019
  }
895
1020
  this.onAppearanceChange();
896
1021
  }
@@ -927,7 +1052,14 @@ class PraxisTabsConfigEditor {
927
1052
  return;
928
1053
  const l = this.nav.links[linkIndex];
929
1054
  l.widgets = l.widgets || [];
930
- l.widgets.push({ id });
1055
+ const childWidgetKey = this.nextChildWidgetKey(l.id || `link${linkIndex + 1}`, id, l.widgets);
1056
+ const rp = (this.quickResourcePathLink[linkIndex] || '').trim();
1057
+ const defaultInputs = this.buildDefaultWidgetInputs(id, rp);
1058
+ l.widgets.push({
1059
+ id,
1060
+ childWidgetKey,
1061
+ ...(defaultInputs ? { inputs: defaultInputs } : {}),
1062
+ });
931
1063
  this.onAppearanceChange();
932
1064
  }
933
1065
  removeWidgetFromLink(linkIndex, widgetIndex) {
@@ -937,6 +1069,20 @@ class PraxisTabsConfigEditor {
937
1069
  l.widgets.splice(widgetIndex, 1);
938
1070
  this.onAppearanceChange();
939
1071
  }
1072
+ updateWidgetKeyLink(linkIndex, widgetIndex, key) {
1073
+ const l = this.nav.links?.[linkIndex];
1074
+ const widget = l?.widgets?.[widgetIndex];
1075
+ if (!widget)
1076
+ return;
1077
+ const trimmed = String(key ?? '').trim();
1078
+ if (trimmed) {
1079
+ widget.childWidgetKey = trimmed;
1080
+ }
1081
+ else {
1082
+ delete widget.childWidgetKey;
1083
+ }
1084
+ this.onAppearanceChange();
1085
+ }
940
1086
  updateWidgetInputsLink(linkIndex, widgetIndex, text) {
941
1087
  const l = this.nav.links[linkIndex];
942
1088
  try {
@@ -961,17 +1107,58 @@ class PraxisTabsConfigEditor {
961
1107
  return;
962
1108
  const l = this.nav.links[linkIndex];
963
1109
  l.widgets = l.widgets || [];
1110
+ const containerId = l.id || `link${linkIndex + 1}`;
964
1111
  if (type === 'form') {
965
- l.widgets.push({ id: 'praxis-dynamic-form', inputs: { resourcePath: rp } });
1112
+ const id = 'praxis-dynamic-form';
1113
+ l.widgets.push({
1114
+ id,
1115
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, l.widgets),
1116
+ inputs: { resourcePath: rp },
1117
+ });
966
1118
  }
967
1119
  else if (type === 'table') {
968
- l.widgets.push({ id: 'praxis-table', inputs: { resourcePath: rp, tableId: rp } });
1120
+ const id = 'praxis-table';
1121
+ l.widgets.push({
1122
+ id,
1123
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, l.widgets),
1124
+ inputs: { resourcePath: rp, tableId: rp },
1125
+ });
969
1126
  }
970
1127
  else {
971
- l.widgets.push({ id: 'praxis-crud', inputs: { crudId: rp, metadata: { resource: { path: rp } } } });
1128
+ const id = 'praxis-crud';
1129
+ l.widgets.push({
1130
+ id,
1131
+ childWidgetKey: this.nextChildWidgetKey(containerId, id, l.widgets),
1132
+ inputs: { crudId: rp, metadata: { resource: { path: rp } } },
1133
+ });
972
1134
  }
973
1135
  this.onAppearanceChange();
974
1136
  }
1137
+ nextChildWidgetKey(containerId, widgetId, widgets) {
1138
+ const existingKeys = (widgets ?? [])
1139
+ .map((widget) => String(widget?.childWidgetKey ?? '').trim())
1140
+ .filter(Boolean);
1141
+ return buildUniqueChildWidgetKey(containerId, widgetId, existingKeys);
1142
+ }
1143
+ buildDefaultWidgetInputs(widgetId, resourcePath) {
1144
+ if (widgetId === 'praxis-related-resource-outlet') {
1145
+ return {
1146
+ parentResourcePath: resourcePath,
1147
+ surfaceId: '',
1148
+ mode: 'inline',
1149
+ };
1150
+ }
1151
+ if (!resourcePath) {
1152
+ return undefined;
1153
+ }
1154
+ if (widgetId === 'praxis-table') {
1155
+ return { resourcePath, tableId: resourcePath };
1156
+ }
1157
+ if (widgetId === 'praxis-dynamic-form') {
1158
+ return { resourcePath };
1159
+ }
1160
+ return undefined;
1161
+ }
975
1162
  stringify(v) { try {
976
1163
  return v ? JSON.stringify(v, null, 2) : '';
977
1164
  }
@@ -1000,10 +1187,10 @@ class PraxisTabsConfigEditor {
1000
1187
  <div class="editor-topbar">
1001
1188
  <mat-form-field appearance="outline" class="editor-mode-field">
1002
1189
  <mat-label>{{ t('editor.fields.mode', 'Modo principal') }}</mat-label>
1003
- <select matNativeControl [ngModel]="primaryMode" (ngModelChange)="setPrimaryMode($event)">
1004
- <option value="group">{{ t('editor.mode.group', 'Grupo de abas') }}</option>
1005
- <option value="nav">{{ t('editor.mode.nav', 'Navegacao por links') }}</option>
1006
- </select>
1190
+ <mat-select [ngModel]="primaryMode" (ngModelChange)="setPrimaryMode($event)">
1191
+ <mat-option value="group">{{ t('editor.mode.group', 'Grupo de abas') }}</mat-option>
1192
+ <mat-option value="nav">{{ t('editor.mode.nav', 'Navegacao por links') }}</mat-option>
1193
+ </mat-select>
1007
1194
  </mat-form-field>
1008
1195
  </div>
1009
1196
 
@@ -1041,19 +1228,19 @@ class PraxisTabsConfigEditor {
1041
1228
  <div class="editor-section">
1042
1229
  <div class="editor-grid two">
1043
1230
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.groupAlignTabs', 'Alinhamento das abas') }}</mat-label>
1044
- <select matNativeControl [(ngModel)]="group.alignTabs" (ngModelChange)="onAppearanceChange()">
1045
- <option [ngValue]="undefined">{{ t('editor.options.default', 'Padrao') }}</option>
1046
- <option value="start">{{ t('editor.options.start', 'Inicio') }}</option>
1047
- <option value="center">{{ t('editor.options.center', 'Centro') }}</option>
1048
- <option value="end">{{ t('editor.options.end', 'Fim') }}</option>
1049
- </select>
1231
+ <mat-select [(ngModel)]="group.alignTabs" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.default', 'Padrao')">
1232
+ <mat-option [value]="undefined">{{ t('editor.options.default', 'Padrao') }}</mat-option>
1233
+ <mat-option value="start">{{ t('editor.options.start', 'Inicio') }}</mat-option>
1234
+ <mat-option value="center">{{ t('editor.options.center', 'Centro') }}</mat-option>
1235
+ <mat-option value="end">{{ t('editor.options.end', 'Fim') }}</mat-option>
1236
+ </mat-select>
1050
1237
  </mat-form-field>
1051
1238
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.groupHeaderPosition', 'Posicao do header') }}</mat-label>
1052
- <select matNativeControl [(ngModel)]="group.headerPosition" (ngModelChange)="onAppearanceChange()">
1053
- <option [ngValue]="undefined">{{ t('editor.options.aboveDefault', 'Acima (padrao)') }}</option>
1054
- <option value="above">{{ t('editor.options.above', 'Acima') }}</option>
1055
- <option value="below">{{ t('editor.options.below', 'Abaixo') }}</option>
1056
- </select>
1239
+ <mat-select [(ngModel)]="group.headerPosition" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.aboveDefault', 'Acima (padrao)')">
1240
+ <mat-option [value]="undefined">{{ t('editor.options.aboveDefault', 'Acima (padrao)') }}</mat-option>
1241
+ <mat-option value="above">{{ t('editor.options.above', 'Acima') }}</mat-option>
1242
+ <mat-option value="below">{{ t('editor.options.below', 'Abaixo') }}</mat-option>
1243
+ </mat-select>
1057
1244
  </mat-form-field>
1058
1245
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.selectedIndex', 'Indice selecionado') }}</mat-label>
1059
1246
  <input matInput type="number" [(ngModel)]="group.selectedIndex" (ngModelChange)="onAppearanceChange()" />
@@ -1080,12 +1267,12 @@ class PraxisTabsConfigEditor {
1080
1267
  ></button>
1081
1268
  </mat-form-field>
1082
1269
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.color', 'Cor (M2)') }}</mat-label>
1083
- <select matNativeControl [(ngModel)]="group.color" (ngModelChange)="onAppearanceChange()">
1084
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1085
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1086
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1087
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1088
- </select>
1270
+ <mat-select [(ngModel)]="group.color" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1271
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1272
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1273
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1274
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1275
+ </mat-select>
1089
1276
  <button
1090
1277
  praxisIconButton="help_outline"
1091
1278
  size="dense"
@@ -1097,12 +1284,12 @@ class PraxisTabsConfigEditor {
1097
1284
  ></button>
1098
1285
  </mat-form-field>
1099
1286
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.backgroundColor', 'Cor de fundo (M2)') }}</mat-label>
1100
- <select matNativeControl [(ngModel)]="group.backgroundColor" (ngModelChange)="onAppearanceChange()">
1101
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1102
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1103
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1104
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1105
- </select>
1287
+ <mat-select [(ngModel)]="group.backgroundColor" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1288
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1289
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1290
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1291
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1292
+ </mat-select>
1106
1293
  <button
1107
1294
  praxisIconButton="help_outline"
1108
1295
  size="dense"
@@ -1166,12 +1353,12 @@ class PraxisTabsConfigEditor {
1166
1353
  <input matInput [(ngModel)]="nav.ariaLabelledby" (ngModelChange)="onAppearanceChange()" />
1167
1354
  </mat-form-field>
1168
1355
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.color', 'Cor (M2)') }}</mat-label>
1169
- <select matNativeControl [(ngModel)]="nav.color" (ngModelChange)="onAppearanceChange()">
1170
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1171
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1172
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1173
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1174
- </select>
1356
+ <mat-select [(ngModel)]="nav.color" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1357
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1358
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1359
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1360
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1361
+ </mat-select>
1175
1362
  <button
1176
1363
  praxisIconButton="help_outline"
1177
1364
  size="dense"
@@ -1183,12 +1370,12 @@ class PraxisTabsConfigEditor {
1183
1370
  ></button>
1184
1371
  </mat-form-field>
1185
1372
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.backgroundColor', 'Cor de fundo (M2)') }}</mat-label>
1186
- <select matNativeControl [(ngModel)]="nav.backgroundColor" (ngModelChange)="onAppearanceChange()">
1187
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1188
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1189
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1190
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1191
- </select>
1373
+ <mat-select [(ngModel)]="nav.backgroundColor" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1374
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1375
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1376
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1377
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1378
+ </mat-select>
1192
1379
  <button
1193
1380
  praxisIconButton="help_outline"
1194
1381
  size="dense"
@@ -1270,12 +1457,12 @@ class PraxisTabsConfigEditor {
1270
1457
 
1271
1458
  <mat-form-field appearance="outline">
1272
1459
  <mat-label>{{ t('editor.fields.density', 'Densidade') }}</mat-label>
1273
- <select matNativeControl [(ngModel)]="appearance.density" (ngModelChange)="onAppearanceChange()">
1274
- <option [ngValue]="undefined">{{ t('editor.density.default', 'Padrao') }}</option>
1275
- <option value="compact">{{ t('editor.density.compact', 'Compacta') }}</option>
1276
- <option value="comfortable">{{ t('editor.density.comfortable', 'Confortavel') }}</option>
1277
- <option value="spacious">{{ t('editor.density.spacious', 'Espacosa') }}</option>
1278
- </select>
1460
+ <mat-select [(ngModel)]="appearance.density" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.density.default', 'Padrao')">
1461
+ <mat-option [value]="undefined">{{ t('editor.density.default', 'Padrao') }}</mat-option>
1462
+ <mat-option value="compact">{{ t('editor.density.compact', 'Compacta') }}</mat-option>
1463
+ <mat-option value="comfortable">{{ t('editor.density.comfortable', 'Confortavel') }}</mat-option>
1464
+ <mat-option value="spacious">{{ t('editor.density.spacious', 'Espacosa') }}</mat-option>
1465
+ </mat-select>
1279
1466
  </mat-form-field>
1280
1467
  </div>
1281
1468
 
@@ -1364,12 +1551,12 @@ class PraxisTabsConfigEditor {
1364
1551
  <div class="editor-row">
1365
1552
  <mat-form-field appearance="outline" class="editor-field-min">
1366
1553
  <mat-label>{{ t('editor.fields.addComponent', 'Adicionar componente') }}</mat-label>
1367
- <select matNativeControl [(ngModel)]="selectedTabWidgetId[i]">
1368
- <option [ngValue]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</option>
1554
+ <mat-select [(ngModel)]="selectedTabWidgetId[i]" [placeholder]="t('editor.fields.selectPlaceholder', '(selecione)')">
1555
+ <mat-option [value]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</mat-option>
1369
1556
  @for (c of componentOptions; track c) {
1370
- <option [ngValue]="c.id">{{ c.friendlyName || c.id }}</option>
1557
+ <mat-option [value]="c.id">{{ c.friendlyName || c.id }}</mat-option>
1371
1558
  }
1372
- </select>
1559
+ </mat-select>
1373
1560
  </mat-form-field>
1374
1561
  <button mat-stroked-button (click)="addWidgetToTab(i)"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ t('editor.actions.add', 'Adicionar') }}</button>
1375
1562
  <span class="editor-spacer"></span>
@@ -1390,6 +1577,10 @@ class PraxisTabsConfigEditor {
1390
1577
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
1391
1578
  <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
1579
  </div>
1580
+ <mat-form-field appearance="outline">
1581
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
1582
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyTab(i, wi, $event)" />
1583
+ </mat-form-field>
1393
1584
  <div class="editor-grid two tight">
1394
1585
  <mat-form-field appearance="outline">
1395
1586
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -1458,12 +1649,12 @@ class PraxisTabsConfigEditor {
1458
1649
  <div class="editor-row">
1459
1650
  <mat-form-field appearance="outline" class="editor-field-min">
1460
1651
  <mat-label>{{ t('editor.fields.addComponent', 'Adicionar componente') }}</mat-label>
1461
- <select matNativeControl [(ngModel)]="selectedLinkWidgetId[i]">
1462
- <option [ngValue]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</option>
1652
+ <mat-select [(ngModel)]="selectedLinkWidgetId[i]" [placeholder]="t('editor.fields.selectPlaceholder', '(selecione)')">
1653
+ <mat-option [value]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</mat-option>
1463
1654
  @for (c of componentOptions; track c) {
1464
- <option [ngValue]="c.id">{{ c.friendlyName || c.id }}</option>
1655
+ <mat-option [value]="c.id">{{ c.friendlyName || c.id }}</mat-option>
1465
1656
  }
1466
- </select>
1657
+ </mat-select>
1467
1658
  </mat-form-field>
1468
1659
  <button mat-stroked-button (click)="addWidgetToLink(i)"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ t('editor.actions.add', 'Adicionar') }}</button>
1469
1660
  <span class="editor-spacer"></span>
@@ -1484,6 +1675,10 @@ class PraxisTabsConfigEditor {
1484
1675
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
1485
1676
  <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
1677
  </div>
1678
+ <mat-form-field appearance="outline">
1679
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
1680
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyLink(i, wi, $event)" />
1681
+ </mat-form-field>
1487
1682
  <div class="editor-grid two tight">
1488
1683
  <mat-form-field appearance="outline">
1489
1684
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -1509,7 +1704,7 @@ class PraxisTabsConfigEditor {
1509
1704
  </mat-tab>
1510
1705
  </mat-tab-group>
1511
1706
  </div>
1512
- `, isInline: true, styles: [":host{display:block;color:var(--md-sys-color-on-surface)}.editor-shell{display:grid;gap:12px}.editor-topbar{display:flex;align-items:start;justify-content:flex-start}.editor-mode-field{width:min(320px,100%)}.editor-diagnostics{display:grid;gap:8px}.editor-diagnostics-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.editor-diagnostic{display:grid;gap:4px;padding:10px 12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}.editor-diagnostic code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:var(--md-sys-color-on-surface-variant)}.editor-diagnostic.level-error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-color:var(--md-sys-color-error)}.editor-diagnostic.level-warning{background:var(--md-sys-color-tertiary-container, var(--md-sys-color-surface-container));color:var(--md-sys-color-on-tertiary-container, var(--md-sys-color-on-surface));border-color:var(--md-sys-color-outline-variant)}.editor-tabs{--editor-surface: var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));--editor-border: 1px solid var(--md-sys-color-outline-variant);--editor-radius: 12px;--editor-muted: var(--md-sys-color-on-surface-variant)}.editor-section{padding:12px;display:grid;gap:12px;background:var(--editor-surface);border:var(--editor-border);border-radius:var(--editor-radius)}.editor-section-lg{gap:16px}.editor-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.editor-grid{display:grid;gap:12px}.editor-grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid.tight{gap:8px}.editor-toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.editor-muted{color:var(--editor-muted)}.editor-title{margin:6px 0 8px;font-size:1rem}.editor-title-row{display:flex;align-items:center;gap:8px}.editor-code{white-space:pre-wrap;background:var(--md-sys-color-surface-container);padding:8px;border-radius:6px;border:1px solid var(--md-sys-color-outline-variant)}.editor-card{border:1px solid var(--md-sys-color-outline-variant);padding:10px;border-radius:10px;display:grid;gap:8px;background:var(--md-sys-color-surface)}.editor-card.dashed{border-style:dashed}.editor-card-header{display:flex;align-items:center;gap:8px}.editor-card-title{flex:1;font-weight:600}.editor-divider{border-top:1px solid var(--md-sys-color-outline-variant);padding-top:8px}.editor-spacer{flex:1}.editor-field-min{min-width:260px}.editor-section .editor-field-min{width:260px;max-width:260px}.editor-field-240{width:240px}.editor-section .editor-field-240{width:240px;max-width:240px}.editor-json{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.editor-section .mat-mdc-form-field{width:100%;max-width:520px;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.editor-section .mat-mdc-form-field.full{max-width:none}.editor-icon-action--danger{color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2_1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2_1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2_1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2_1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2_1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2_1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2_1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
1707
+ `, isInline: true, styles: [":host{display:block;container-type:inline-size;color:var(--pfx-settings-panel-text-primary, var(--md-sys-color-on-surface))}.editor-shell{display:grid;gap:12px}.editor-topbar{display:flex;align-items:start;justify-content:flex-start}.editor-mode-field{width:min(320px,100%)}.editor-diagnostics{display:grid;gap:8px}.editor-diagnostics-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.editor-diagnostic{display:grid;gap:4px;padding:10px 12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}.editor-diagnostic code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:var(--md-sys-color-on-surface-variant)}.editor-diagnostic.level-error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-color:var(--md-sys-color-error)}.editor-diagnostic.level-warning{background:var(--md-sys-color-tertiary-container, var(--md-sys-color-surface-container));color:var(--md-sys-color-on-tertiary-container, var(--md-sys-color-on-surface));border-color:var(--md-sys-color-outline-variant)}.editor-tabs{--editor-surface: var(--pfx-settings-panel-surface-elevated, var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface)));--editor-border: 1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));--editor-radius: 12px;--editor-muted: var(--pfx-settings-panel-text-secondary, var(--md-sys-color-on-surface-variant))}.editor-section{padding:12px;display:grid;gap:12px;background:var(--editor-surface);border:var(--editor-border);border-radius:var(--editor-radius)}.editor-section-lg{gap:16px}.editor-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.editor-grid{display:grid;gap:12px}.editor-grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid.tight{gap:8px}.editor-toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.editor-muted{color:var(--editor-muted)}.editor-title{margin:6px 0 8px;font-size:1rem}.editor-title-row{display:flex;align-items:center;gap:8px}.editor-code{white-space:pre-wrap;background:var(--md-sys-color-surface-container);padding:8px;border-radius:6px;border:1px solid var(--md-sys-color-outline-variant)}.editor-card{border:1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));padding:10px;border-radius:10px;display:grid;gap:8px;background:var(--pfx-settings-panel-surface, var(--md-sys-color-surface))}.editor-card.dashed{border-style:dashed}.editor-card-header{display:flex;align-items:center;gap:8px}.editor-card-title{flex:1;font-weight:600}.editor-divider{border-top:1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));padding-top:8px}.editor-spacer{flex:1}.editor-field-min{min-width:260px}.editor-section .editor-field-min{width:260px;max-width:260px}.editor-field-240{width:240px}.editor-section .editor-field-240{width:240px;max-width:240px}@container (max-width: 640px){.editor-grid.two{grid-template-columns:1fr}.editor-field-min,.editor-section .editor-field-min,.editor-field-240,.editor-section .editor-field-240{min-width:0;width:100%;max-width:100%}}.editor-json{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.editor-section .mat-mdc-form-field{width:100%;max-width:520px;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.editor-section .mat-mdc-form-field.full{max-width:none}.editor-icon-action--danger{color:var(--md-sys-color-error)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2_1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2_1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2_1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2_1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i6.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i9.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i10.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i10.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i10.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] });
1513
1708
  }
1514
1709
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisTabsConfigEditor, decorators: [{
1515
1710
  type: Component,
@@ -1518,6 +1713,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1518
1713
  MatTabsModule,
1519
1714
  MatFormFieldModule,
1520
1715
  MatInputModule,
1716
+ MatSelectModule,
1521
1717
  MatIconModule,
1522
1718
  PraxisIconDirective,
1523
1719
  PraxisIconButtonComponent,
@@ -1530,10 +1726,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1530
1726
  <div class="editor-topbar">
1531
1727
  <mat-form-field appearance="outline" class="editor-mode-field">
1532
1728
  <mat-label>{{ t('editor.fields.mode', 'Modo principal') }}</mat-label>
1533
- <select matNativeControl [ngModel]="primaryMode" (ngModelChange)="setPrimaryMode($event)">
1534
- <option value="group">{{ t('editor.mode.group', 'Grupo de abas') }}</option>
1535
- <option value="nav">{{ t('editor.mode.nav', 'Navegacao por links') }}</option>
1536
- </select>
1729
+ <mat-select [ngModel]="primaryMode" (ngModelChange)="setPrimaryMode($event)">
1730
+ <mat-option value="group">{{ t('editor.mode.group', 'Grupo de abas') }}</mat-option>
1731
+ <mat-option value="nav">{{ t('editor.mode.nav', 'Navegacao por links') }}</mat-option>
1732
+ </mat-select>
1537
1733
  </mat-form-field>
1538
1734
  </div>
1539
1735
 
@@ -1571,19 +1767,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1571
1767
  <div class="editor-section">
1572
1768
  <div class="editor-grid two">
1573
1769
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.groupAlignTabs', 'Alinhamento das abas') }}</mat-label>
1574
- <select matNativeControl [(ngModel)]="group.alignTabs" (ngModelChange)="onAppearanceChange()">
1575
- <option [ngValue]="undefined">{{ t('editor.options.default', 'Padrao') }}</option>
1576
- <option value="start">{{ t('editor.options.start', 'Inicio') }}</option>
1577
- <option value="center">{{ t('editor.options.center', 'Centro') }}</option>
1578
- <option value="end">{{ t('editor.options.end', 'Fim') }}</option>
1579
- </select>
1770
+ <mat-select [(ngModel)]="group.alignTabs" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.default', 'Padrao')">
1771
+ <mat-option [value]="undefined">{{ t('editor.options.default', 'Padrao') }}</mat-option>
1772
+ <mat-option value="start">{{ t('editor.options.start', 'Inicio') }}</mat-option>
1773
+ <mat-option value="center">{{ t('editor.options.center', 'Centro') }}</mat-option>
1774
+ <mat-option value="end">{{ t('editor.options.end', 'Fim') }}</mat-option>
1775
+ </mat-select>
1580
1776
  </mat-form-field>
1581
1777
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.groupHeaderPosition', 'Posicao do header') }}</mat-label>
1582
- <select matNativeControl [(ngModel)]="group.headerPosition" (ngModelChange)="onAppearanceChange()">
1583
- <option [ngValue]="undefined">{{ t('editor.options.aboveDefault', 'Acima (padrao)') }}</option>
1584
- <option value="above">{{ t('editor.options.above', 'Acima') }}</option>
1585
- <option value="below">{{ t('editor.options.below', 'Abaixo') }}</option>
1586
- </select>
1778
+ <mat-select [(ngModel)]="group.headerPosition" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.aboveDefault', 'Acima (padrao)')">
1779
+ <mat-option [value]="undefined">{{ t('editor.options.aboveDefault', 'Acima (padrao)') }}</mat-option>
1780
+ <mat-option value="above">{{ t('editor.options.above', 'Acima') }}</mat-option>
1781
+ <mat-option value="below">{{ t('editor.options.below', 'Abaixo') }}</mat-option>
1782
+ </mat-select>
1587
1783
  </mat-form-field>
1588
1784
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.selectedIndex', 'Indice selecionado') }}</mat-label>
1589
1785
  <input matInput type="number" [(ngModel)]="group.selectedIndex" (ngModelChange)="onAppearanceChange()" />
@@ -1610,12 +1806,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1610
1806
  ></button>
1611
1807
  </mat-form-field>
1612
1808
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.color', 'Cor (M2)') }}</mat-label>
1613
- <select matNativeControl [(ngModel)]="group.color" (ngModelChange)="onAppearanceChange()">
1614
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1615
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1616
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1617
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1618
- </select>
1809
+ <mat-select [(ngModel)]="group.color" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1810
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1811
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1812
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1813
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1814
+ </mat-select>
1619
1815
  <button
1620
1816
  praxisIconButton="help_outline"
1621
1817
  size="dense"
@@ -1627,12 +1823,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1627
1823
  ></button>
1628
1824
  </mat-form-field>
1629
1825
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.backgroundColor', 'Cor de fundo (M2)') }}</mat-label>
1630
- <select matNativeControl [(ngModel)]="group.backgroundColor" (ngModelChange)="onAppearanceChange()">
1631
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1632
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1633
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1634
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1635
- </select>
1826
+ <mat-select [(ngModel)]="group.backgroundColor" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1827
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1828
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1829
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1830
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1831
+ </mat-select>
1636
1832
  <button
1637
1833
  praxisIconButton="help_outline"
1638
1834
  size="dense"
@@ -1696,12 +1892,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1696
1892
  <input matInput [(ngModel)]="nav.ariaLabelledby" (ngModelChange)="onAppearanceChange()" />
1697
1893
  </mat-form-field>
1698
1894
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.color', 'Cor (M2)') }}</mat-label>
1699
- <select matNativeControl [(ngModel)]="nav.color" (ngModelChange)="onAppearanceChange()">
1700
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1701
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1702
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1703
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1704
- </select>
1895
+ <mat-select [(ngModel)]="nav.color" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1896
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1897
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1898
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1899
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1900
+ </mat-select>
1705
1901
  <button
1706
1902
  praxisIconButton="help_outline"
1707
1903
  size="dense"
@@ -1713,12 +1909,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1713
1909
  ></button>
1714
1910
  </mat-form-field>
1715
1911
  <mat-form-field appearance="outline"><mat-label>{{ t('editor.fields.backgroundColor', 'Cor de fundo (M2)') }}</mat-label>
1716
- <select matNativeControl [(ngModel)]="nav.backgroundColor" (ngModelChange)="onAppearanceChange()">
1717
- <option [ngValue]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</option>
1718
- <option value="primary">{{ t('editor.options.primary', 'Primary') }}</option>
1719
- <option value="accent">{{ t('editor.options.accent', 'Accent') }}</option>
1720
- <option value="warn">{{ t('editor.options.warn', 'Warn') }}</option>
1721
- </select>
1912
+ <mat-select [(ngModel)]="nav.backgroundColor" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.options.none', '(nenhuma)')">
1913
+ <mat-option [value]="undefined">{{ t('editor.options.none', '(nenhuma)') }}</mat-option>
1914
+ <mat-option value="primary">{{ t('editor.options.primary', 'Primary') }}</mat-option>
1915
+ <mat-option value="accent">{{ t('editor.options.accent', 'Accent') }}</mat-option>
1916
+ <mat-option value="warn">{{ t('editor.options.warn', 'Warn') }}</mat-option>
1917
+ </mat-select>
1722
1918
  <button
1723
1919
  praxisIconButton="help_outline"
1724
1920
  size="dense"
@@ -1800,12 +1996,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1800
1996
 
1801
1997
  <mat-form-field appearance="outline">
1802
1998
  <mat-label>{{ t('editor.fields.density', 'Densidade') }}</mat-label>
1803
- <select matNativeControl [(ngModel)]="appearance.density" (ngModelChange)="onAppearanceChange()">
1804
- <option [ngValue]="undefined">{{ t('editor.density.default', 'Padrao') }}</option>
1805
- <option value="compact">{{ t('editor.density.compact', 'Compacta') }}</option>
1806
- <option value="comfortable">{{ t('editor.density.comfortable', 'Confortavel') }}</option>
1807
- <option value="spacious">{{ t('editor.density.spacious', 'Espacosa') }}</option>
1808
- </select>
1999
+ <mat-select [(ngModel)]="appearance.density" (ngModelChange)="onAppearanceChange()" [placeholder]="t('editor.density.default', 'Padrao')">
2000
+ <mat-option [value]="undefined">{{ t('editor.density.default', 'Padrao') }}</mat-option>
2001
+ <mat-option value="compact">{{ t('editor.density.compact', 'Compacta') }}</mat-option>
2002
+ <mat-option value="comfortable">{{ t('editor.density.comfortable', 'Confortavel') }}</mat-option>
2003
+ <mat-option value="spacious">{{ t('editor.density.spacious', 'Espacosa') }}</mat-option>
2004
+ </mat-select>
1809
2005
  </mat-form-field>
1810
2006
  </div>
1811
2007
 
@@ -1894,12 +2090,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1894
2090
  <div class="editor-row">
1895
2091
  <mat-form-field appearance="outline" class="editor-field-min">
1896
2092
  <mat-label>{{ t('editor.fields.addComponent', 'Adicionar componente') }}</mat-label>
1897
- <select matNativeControl [(ngModel)]="selectedTabWidgetId[i]">
1898
- <option [ngValue]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</option>
2093
+ <mat-select [(ngModel)]="selectedTabWidgetId[i]" [placeholder]="t('editor.fields.selectPlaceholder', '(selecione)')">
2094
+ <mat-option [value]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</mat-option>
1899
2095
  @for (c of componentOptions; track c) {
1900
- <option [ngValue]="c.id">{{ c.friendlyName || c.id }}</option>
2096
+ <mat-option [value]="c.id">{{ c.friendlyName || c.id }}</mat-option>
1901
2097
  }
1902
- </select>
2098
+ </mat-select>
1903
2099
  </mat-form-field>
1904
2100
  <button mat-stroked-button (click)="addWidgetToTab(i)"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ t('editor.actions.add', 'Adicionar') }}</button>
1905
2101
  <span class="editor-spacer"></span>
@@ -1920,6 +2116,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1920
2116
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
1921
2117
  <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
2118
  </div>
2119
+ <mat-form-field appearance="outline">
2120
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
2121
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyTab(i, wi, $event)" />
2122
+ </mat-form-field>
1923
2123
  <div class="editor-grid two tight">
1924
2124
  <mat-form-field appearance="outline">
1925
2125
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -1988,12 +2188,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1988
2188
  <div class="editor-row">
1989
2189
  <mat-form-field appearance="outline" class="editor-field-min">
1990
2190
  <mat-label>{{ t('editor.fields.addComponent', 'Adicionar componente') }}</mat-label>
1991
- <select matNativeControl [(ngModel)]="selectedLinkWidgetId[i]">
1992
- <option [ngValue]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</option>
2191
+ <mat-select [(ngModel)]="selectedLinkWidgetId[i]" [placeholder]="t('editor.fields.selectPlaceholder', '(selecione)')">
2192
+ <mat-option [value]="''">{{ t('editor.fields.selectPlaceholder', '(selecione)') }}</mat-option>
1993
2193
  @for (c of componentOptions; track c) {
1994
- <option [ngValue]="c.id">{{ c.friendlyName || c.id }}</option>
2194
+ <mat-option [value]="c.id">{{ c.friendlyName || c.id }}</mat-option>
1995
2195
  }
1996
- </select>
2196
+ </mat-select>
1997
2197
  </mat-form-field>
1998
2198
  <button mat-stroked-button (click)="addWidgetToLink(i)"><mat-icon [praxisIcon]="'add'"></mat-icon>{{ t('editor.actions.add', 'Adicionar') }}</button>
1999
2199
  <span class="editor-spacer"></span>
@@ -2014,6 +2214,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2014
2214
  <strong class="editor-card-title">{{ getCompName(w.id) }}</strong>
2015
2215
  <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
2216
  </div>
2217
+ <mat-form-field appearance="outline">
2218
+ <mat-label>{{ t('editor.fields.childWidgetKey', 'Chave da instancia (childWidgetKey)') }}</mat-label>
2219
+ <input matInput [ngModel]="w.childWidgetKey || ''" (ngModelChange)="updateWidgetKeyLink(i, wi, $event)" />
2220
+ </mat-form-field>
2017
2221
  <div class="editor-grid two tight">
2018
2222
  <mat-form-field appearance="outline">
2019
2223
  <mat-label>{{ t('editor.fields.inputsJson', 'Inputs (JSON)') }}</mat-label>
@@ -2039,7 +2243,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2039
2243
  </mat-tab>
2040
2244
  </mat-tab-group>
2041
2245
  </div>
2042
- `, styles: [":host{display:block;color:var(--md-sys-color-on-surface)}.editor-shell{display:grid;gap:12px}.editor-topbar{display:flex;align-items:start;justify-content:flex-start}.editor-mode-field{width:min(320px,100%)}.editor-diagnostics{display:grid;gap:8px}.editor-diagnostics-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.editor-diagnostic{display:grid;gap:4px;padding:10px 12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}.editor-diagnostic code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:var(--md-sys-color-on-surface-variant)}.editor-diagnostic.level-error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-color:var(--md-sys-color-error)}.editor-diagnostic.level-warning{background:var(--md-sys-color-tertiary-container, var(--md-sys-color-surface-container));color:var(--md-sys-color-on-tertiary-container, var(--md-sys-color-on-surface));border-color:var(--md-sys-color-outline-variant)}.editor-tabs{--editor-surface: var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));--editor-border: 1px solid var(--md-sys-color-outline-variant);--editor-radius: 12px;--editor-muted: var(--md-sys-color-on-surface-variant)}.editor-section{padding:12px;display:grid;gap:12px;background:var(--editor-surface);border:var(--editor-border);border-radius:var(--editor-radius)}.editor-section-lg{gap:16px}.editor-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.editor-grid{display:grid;gap:12px}.editor-grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid.tight{gap:8px}.editor-toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.editor-muted{color:var(--editor-muted)}.editor-title{margin:6px 0 8px;font-size:1rem}.editor-title-row{display:flex;align-items:center;gap:8px}.editor-code{white-space:pre-wrap;background:var(--md-sys-color-surface-container);padding:8px;border-radius:6px;border:1px solid var(--md-sys-color-outline-variant)}.editor-card{border:1px solid var(--md-sys-color-outline-variant);padding:10px;border-radius:10px;display:grid;gap:8px;background:var(--md-sys-color-surface)}.editor-card.dashed{border-style:dashed}.editor-card-header{display:flex;align-items:center;gap:8px}.editor-card-title{flex:1;font-weight:600}.editor-divider{border-top:1px solid var(--md-sys-color-outline-variant);padding-top:8px}.editor-spacer{flex:1}.editor-field-min{min-width:260px}.editor-section .editor-field-min{width:260px;max-width:260px}.editor-field-240{width:240px}.editor-section .editor-field-240{width:240px;max-width:240px}.editor-json{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.editor-section .mat-mdc-form-field{width:100%;max-width:520px;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.editor-section .mat-mdc-form-field.full{max-width:none}.editor-icon-action--danger{color:var(--md-sys-color-error)}\n"] }]
2246
+ `, styles: [":host{display:block;container-type:inline-size;color:var(--pfx-settings-panel-text-primary, var(--md-sys-color-on-surface))}.editor-shell{display:grid;gap:12px}.editor-topbar{display:flex;align-items:start;justify-content:flex-start}.editor-mode-field{width:min(320px,100%)}.editor-diagnostics{display:grid;gap:8px}.editor-diagnostics-title{font-size:.95rem;font-weight:600;color:var(--md-sys-color-on-surface)}.editor-diagnostic{display:grid;gap:4px;padding:10px 12px;border-radius:10px;border:1px solid var(--md-sys-color-outline-variant);background:var(--md-sys-color-surface-container);color:var(--md-sys-color-on-surface)}.editor-diagnostic code{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;color:var(--md-sys-color-on-surface-variant)}.editor-diagnostic.level-error{background:var(--md-sys-color-error-container);color:var(--md-sys-color-on-error-container);border-color:var(--md-sys-color-error)}.editor-diagnostic.level-warning{background:var(--md-sys-color-tertiary-container, var(--md-sys-color-surface-container));color:var(--md-sys-color-on-tertiary-container, var(--md-sys-color-on-surface));border-color:var(--md-sys-color-outline-variant)}.editor-tabs{--editor-surface: var(--pfx-settings-panel-surface-elevated, var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface)));--editor-border: 1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));--editor-radius: 12px;--editor-muted: var(--pfx-settings-panel-text-secondary, var(--md-sys-color-on-surface-variant))}.editor-section{padding:12px;display:grid;gap:12px;background:var(--editor-surface);border:var(--editor-border);border-radius:var(--editor-radius)}.editor-section-lg{gap:16px}.editor-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center}.editor-grid{display:grid;gap:12px}.editor-grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.editor-grid.tight{gap:8px}.editor-toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.editor-muted{color:var(--editor-muted)}.editor-title{margin:6px 0 8px;font-size:1rem}.editor-title-row{display:flex;align-items:center;gap:8px}.editor-code{white-space:pre-wrap;background:var(--md-sys-color-surface-container);padding:8px;border-radius:6px;border:1px solid var(--md-sys-color-outline-variant)}.editor-card{border:1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));padding:10px;border-radius:10px;display:grid;gap:8px;background:var(--pfx-settings-panel-surface, var(--md-sys-color-surface))}.editor-card.dashed{border-style:dashed}.editor-card-header{display:flex;align-items:center;gap:8px}.editor-card-title{flex:1;font-weight:600}.editor-divider{border-top:1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));padding-top:8px}.editor-spacer{flex:1}.editor-field-min{min-width:260px}.editor-section .editor-field-min{width:260px;max-width:260px}.editor-field-240{width:240px}.editor-section .editor-field-240{width:240px;max-width:240px}@container (max-width: 640px){.editor-grid.two{grid-template-columns:1fr}.editor-field-min,.editor-section .editor-field-min,.editor-field-240,.editor-section .editor-field-240{min-width:0;width:100%;max-width:100%}}.editor-json{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.editor-section .mat-mdc-form-field{width:100%;max-width:520px;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.editor-section .mat-mdc-form-field.full{max-width:none}.editor-icon-action--danger{color:var(--md-sys-color-error)}\n"] }]
2043
2247
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2044
2248
  type: Inject,
2045
2249
  args: [SETTINGS_PANEL_DATA]
@@ -2184,7 +2388,7 @@ class TabsQuickSetupComponent {
2184
2388
  <mat-slide-toggle [(ngModel)]="model.stretchTabs" (ngModelChange)="updateState()">{{ t('editor.toggles.stretchTabs', 'Esticar abas') }}</mat-slide-toggle>
2185
2389
  </div>
2186
2390
  </div>
2187
- `, isInline: true, styles: [":host{display:block;color:var(--md-sys-color-on-surface)}.setup-root{display:grid;gap:12px;padding:8px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.setup-row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.setup-row.wrap{flex-wrap:wrap}.setup-grid{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:start}.setup-root .mat-mdc-form-field{width:100%;max-width:520px;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:16px;background:var(--md-sys-color-surface)}.hint{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2_1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2_1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2_1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i8.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
2391
+ `, isInline: true, styles: [":host{display:block;color:var(--md-sys-color-on-surface)}.setup-root{display:grid;gap:12px;padding:8px;background:var(--md-sys-color-surface-container-lowest, var(--md-sys-color-surface));border:1px solid var(--md-sys-color-outline-variant);border-radius:12px}.setup-row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.setup-row.wrap{flex-wrap:wrap}.setup-grid{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:start}.setup-root .mat-mdc-form-field{width:100%;max-width:520px;--mdc-outlined-text-field-container-height: 48px;--mdc-outlined-text-field-outline-color: var(--md-sys-color-outline-variant);--mdc-outlined-text-field-hover-outline-color: var(--md-sys-color-outline);--mdc-outlined-text-field-focus-outline-color: var(--md-sys-color-primary);--mdc-outlined-text-field-error-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-focus-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-error-hover-outline-color: var(--md-sys-color-error);--mdc-outlined-text-field-label-text-color: var(--md-sys-color-on-surface-variant);--mdc-outlined-text-field-input-text-color: var(--md-sys-color-on-surface);--mdc-outlined-text-field-supporting-text-color: var(--md-sys-color-on-surface-variant)}.chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px;border:1px solid var(--md-sys-color-outline-variant);border-radius:16px;background:var(--md-sys-color-surface)}.hint{color:var(--md-sys-color-on-surface-variant)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2_1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2_1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2_1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6$1.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i9.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
2188
2392
  }
2189
2393
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: TabsQuickSetupComponent, decorators: [{
2190
2394
  type: Component,
@@ -4692,7 +4896,7 @@ class PraxisTabs {
4692
4896
  </button>
4693
4897
  }
4694
4898
  </div>
4695
- `, isInline: true, styles: [".praxis-tabs-root{position:relative;display:block}.praxis-tabs-group.align-start .mat-mdc-tab-header{justify-content:flex-start}.praxis-tabs-group.align-center .mat-mdc-tab-header{justify-content:center}.praxis-tabs-group.align-end .mat-mdc-tab-header{justify-content:flex-end}.praxis-tabs-group--header-only .mat-mdc-tab-body-wrapper{display:none}:host ::ng-deep .praxis-tabs-group.mat-mdc-tab-group-dynamic-height>.mat-mdc-tab-body-wrapper,:host ::ng-deep .praxis-tabs-group.mat-mdc-tab-group-dynamic-height>.mat-mdc-tab-body-wrapper>.mat-mdc-tab-body,:host ::ng-deep .praxis-tabs-group.mat-mdc-tab-group-dynamic-height>.mat-mdc-tab-body-wrapper>.mat-mdc-tab-body>.mat-mdc-tab-body-content{overflow:clip}.praxis-tabs-nav-panel--header-only{display:none}.density-compact .mat-mdc-tab-body-content{padding:8px}.density-comfortable .mat-mdc-tab-body-content{padding:16px}.density-spacious .mat-mdc-tab-body-content{padding:24px}.praxis-tabs-widget-stack{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--p-tabs-widget-stack-gap, 16px);min-width:0}.praxis-tabs-widget-surface{display:block;min-width:0}.density-compact .praxis-tabs-widget-stack{--p-tabs-widget-stack-gap: 12px}.density-comfortable .praxis-tabs-widget-stack{--p-tabs-widget-stack-gap: 16px}.density-spacious .praxis-tabs-widget-stack{--p-tabs-widget-stack-gap: 24px}.tabs-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.tabs-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2)}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.edit-fab-secondary{right:56px}.tab-empty{padding:16px;color:var(--md-sys-color-on-surface-variant);font-style:italic}.high-contrast{filter:contrast(1.2)}.reduce-motion{--mat-animation-duration: 0ms}.drag-handle{display:inline-flex;align-items:center;vertical-align:middle;margin-right:4px;cursor:grab}.tab-label-icon{font-size:18px;width:18px;height:18px;margin-right:6px;vertical-align:middle}:host-context(.pdx-gridster-item) .praxis-tabs-root{display:flex;flex-direction:column;height:100%;min-height:0}:host-context(.pdx-gridster-item) .praxis-tabs-group,:host-context(.pdx-gridster-item) .mat-mdc-tab-group{flex:1 1 auto;min-height:0}:host-context(.pdx-gridster-item) .mat-mdc-tab-body-wrapper,:host-context(.pdx-gridster-item) .mat-mdc-tab-body-content{height:100%;min-height:0}:host-context(.pdx-gridster-item) .mat-mdc-tab-body-content{overflow:auto}:host-context(.pdx-gridster-item) .praxis-tabnav-content{flex:1 1 auto;min-height:0;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2_1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2_1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i3.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i3.MatTabNav, selector: "[mat-tab-nav-bar]", inputs: ["fitInkBarToContent", "mat-stretch-tabs", "animationDuration", "backgroundColor", "disableRipple", "color", "tabPanel"], exportAs: ["matTabNavBar", "matTabNav"] }, { kind: "component", type: i3.MatTabNavPanel, selector: "mat-tab-nav-panel", inputs: ["id"], exportAs: ["matTabNavPanel"] }, { kind: "component", type: i3.MatTabLink, selector: "[mat-tab-link], [matTabLink]", inputs: ["active", "disabled", "disableRipple", "tabIndex", "id"], exportAs: ["matTabLink"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i9.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i9.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i9.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick", "canvasFocus"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4899
+ `, isInline: true, styles: [".praxis-tabs-root{position:relative;display:block}.praxis-tabs-group.align-start .mat-mdc-tab-header{justify-content:flex-start}.praxis-tabs-group.align-center .mat-mdc-tab-header{justify-content:center}.praxis-tabs-group.align-end .mat-mdc-tab-header{justify-content:flex-end}.praxis-tabs-group--header-only .mat-mdc-tab-body-wrapper{display:none}:host ::ng-deep .praxis-tabs-group.mat-mdc-tab-group-dynamic-height>.mat-mdc-tab-body-wrapper,:host ::ng-deep .praxis-tabs-group.mat-mdc-tab-group-dynamic-height>.mat-mdc-tab-body-wrapper>.mat-mdc-tab-body,:host ::ng-deep .praxis-tabs-group.mat-mdc-tab-group-dynamic-height>.mat-mdc-tab-body-wrapper>.mat-mdc-tab-body>.mat-mdc-tab-body-content{overflow:clip}.praxis-tabs-nav-panel--header-only{display:none}.density-compact .mat-mdc-tab-body-content{padding:8px}.density-comfortable .mat-mdc-tab-body-content{padding:16px}.density-spacious .mat-mdc-tab-body-content{padding:24px}.praxis-tabs-widget-stack{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--p-tabs-widget-stack-gap, 16px);min-width:0}.praxis-tabs-widget-surface{display:block;min-width:0}.density-compact .praxis-tabs-widget-stack{--p-tabs-widget-stack-gap: 12px}.density-comfortable .praxis-tabs-widget-stack{--p-tabs-widget-stack-gap: 16px}.density-spacious .praxis-tabs-widget-stack{--p-tabs-widget-stack-gap: 24px}.tabs-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.tabs-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2)}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.edit-fab-secondary{right:56px}.tab-empty{padding:16px;color:var(--md-sys-color-on-surface-variant);font-style:italic}.high-contrast{filter:contrast(1.2)}.reduce-motion{--mat-animation-duration: 0ms}.drag-handle{display:inline-flex;align-items:center;vertical-align:middle;margin-right:4px;cursor:grab}.tab-label-icon{font-size:18px;width:18px;height:18px;margin-right:6px;vertical-align:middle}:host-context(.pdx-gridster-item) .praxis-tabs-root{display:flex;flex-direction:column;height:100%;min-height:0}:host-context(.pdx-gridster-item) .praxis-tabs-group,:host-context(.pdx-gridster-item) .mat-mdc-tab-group{flex:1 1 auto;min-height:0}:host-context(.pdx-gridster-item) .mat-mdc-tab-body-wrapper,:host-context(.pdx-gridster-item) .mat-mdc-tab-body-content{height:100%;min-height:0}:host-context(.pdx-gridster-item) .mat-mdc-tab-body-content{overflow:auto}:host-context(.pdx-gridster-item) .praxis-tabnav-content{flex:1 1 auto;min-height:0;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2_1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2_1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i3.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i3.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i3.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "component", type: i3.MatTabNav, selector: "[mat-tab-nav-bar]", inputs: ["fitInkBarToContent", "mat-stretch-tabs", "animationDuration", "backgroundColor", "disableRipple", "color", "tabPanel"], exportAs: ["matTabNavBar", "matTabNav"] }, { kind: "component", type: i3.MatTabNavPanel, selector: "mat-tab-nav-panel", inputs: ["id"], exportAs: ["matTabNavPanel"] }, { kind: "component", type: i3.MatTabLink, selector: "[mat-tab-link], [matTabLink]", inputs: ["active", "disabled", "disableRipple", "tabIndex", "id"], exportAs: ["matTabLink"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6$1.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i10.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i10.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i10.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }, { kind: "directive", type: DynamicFieldLoaderDirective, selector: "[dynamicFieldLoader]", inputs: ["fields", "formGroup", "enableExternalControlBinding", "itemTemplate", "debugTrace", "debugTraceLabel", "readonlyMode", "disabledMode", "presentationMode", "visible", "canvasMode"], outputs: ["componentsCreated", "fieldCreated", "fieldDestroyed", "renderError", "canvasMouseEnter", "canvasMouseLeave", "canvasClick", "canvasFocus"] }, { kind: "directive", type: DynamicWidgetLoaderDirective, selector: "[dynamicWidgetLoader]", inputs: ["dynamicWidgetLoader", "ownerWidgetKey", "context", "strictValidation", "autoWireOutputs"], outputs: ["widgetEvent", "widgetDiagnostic"], exportAs: ["dynamicWidgetLoader"] }, { kind: "component", type: PraxisAiAssistantShellComponent, selector: "praxis-ai-assistant-shell", inputs: ["labels", "mode", "state", "contextItems", "attachments", "messages", "quickReplies", "recommendedIntents", "prompt", "statusText", "errorText", "testIdPrefix", "panelTestId", "submitTestId", "applyTestId", "primaryAction", "secondaryActions", "governanceActions", "busy", "canSubmit", "canApply", "submitOnEnter", "showAttachAction", "enablePastedAttachments", "enableFileAttachments", "attachmentAccept", "attachmentMultiple", "voiceInputMode", "voiceLanguage", "draggable", "resizable", "minWidth", "minHeight", "margin", "layout"], outputs: ["promptChange", "submitPrompt", "apply", "retryTurn", "cancelTurn", "shellAction", "close", "attach", "attachmentsPasted", "attachmentsSelected", "removeAttachment", "messageAction", "editMessage", "resendMessage", "quickReply", "recommendedIntent", "layoutChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4696
4900
  }
4697
4901
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisTabs, decorators: [{
4698
4902
  type: Component,
@@ -5764,4 +5968,4 @@ const PRAXIS_TABS_AUTHORING_MANIFEST = {
5764
5968
  * Generated bundle index. Do not edit.
5765
5969
  */
5766
5970
 
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 };
5971
+ 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.4",
3
+ "version": "10.0.0-rc.41",
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.4",
11
- "@praxisui/dynamic-fields": "^10.0.0-rc.4",
12
- "@praxisui/settings-panel": "^10.0.0-rc.4",
10
+ "@praxisui/core": "^10.0.0-rc.41",
11
+ "@praxisui/dynamic-fields": "^10.0.0-rc.41",
12
+ "@praxisui/settings-panel": "^10.0.0-rc.41",
13
13
  "@angular/forms": "^21.0.0",
14
14
  "@angular/router": "^21.0.0",
15
- "@praxisui/ai": "^10.0.0-rc.4",
15
+ "@praxisui/ai": "^10.0.0-rc.41",
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 };