@praxisui/tabs 9.0.4-rc.3 → 9.0.4-rc.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -102,6 +102,8 @@ const navTabs: TabsMetadata = {
102
102
 
103
103
  Use stable ids for tabs and nav links. When `tabsId` is provided, the component stores configuration under a key derived from route, component type, `tabsId` and optional `componentInstanceId`.
104
104
 
105
+ When a tab or navigation link contains multiple `widgets`, the runtime renders them as sibling surfaces in a density-aware vertical stack. The default rhythm is 12 px for `compact`, 16 px for `comfortable`, and 24 px for `spacious`, preventing adjacent tables, forms, lists, or related-resource outlets from visually merging. This is container chrome only; it does not change widget inputs, events, identity, or composition bindings.
106
+
105
107
  ## Runtime Authoring
106
108
 
107
109
  With `enableCustomization`, the component can open quick setup or the full `PraxisTabsConfigEditor` through Settings Panel. The editor round-trips through `TabsAuthoringDocument`, applies only runtime-backed fields and emits `configChange` so the host can persist canonical page or manifest changes.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-07-31T14:02:14.681Z",
3
+ "generatedAt": "2026-08-05T01:36:08.693Z",
4
4
  "packageName": "@praxisui/tabs",
5
- "packageVersion": "9.0.4-rc.3",
5
+ "packageVersion": "9.0.4-rc.30",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -3195,6 +3195,11 @@ class PraxisTabs {
3195
3195
  this.loadStoredConfigForCurrentIdentity({ warnMissingId: false });
3196
3196
  }
3197
3197
  if (changes['config'] && this.config) {
3198
+ // Composition links may replace the container config while preserving the
3199
+ // identity of an affected nested widget. Cached clones must not keep the
3200
+ // previous inputs in that case (for example, a newly selected parent
3201
+ // identity projected into a related-resource outlet).
3202
+ this.widgetDefinitionCache = new WeakMap();
3198
3203
  // Reset loaded caches on config change and seed with current selections
3199
3204
  this.syncSelectionFromConfig();
3200
3205
  this.syncGeneratedContentForm();
@@ -4376,13 +4381,17 @@ class PraxisTabs {
4376
4381
  ></ng-container>
4377
4382
  }
4378
4383
  @if (safeWidgetDefinitions(l.widgets).length) {
4379
- @for (w of safeWidgetDefinitions(l.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4380
- <ng-container
4381
- [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4382
- [context]="context || {}"
4383
- (widgetEvent)="emitWidgetEvent(linkEventPath(l.id, currentNavIndex()), $event)"
4384
- ></ng-container>
4385
- }
4384
+ <div class="praxis-tabs-widget-stack" data-role="nested-widget-stack">
4385
+ @for (w of safeWidgetDefinitions(l.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4386
+ <div class="praxis-tabs-widget-surface" [attr.data-child-widget-key]="trackWidgetDefinition(wi, w)">
4387
+ <ng-container
4388
+ [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4389
+ [context]="context || {}"
4390
+ (widgetEvent)="emitWidgetEvent(linkEventPath(l.id, currentNavIndex()), $event)"
4391
+ ></ng-container>
4392
+ </div>
4393
+ }
4394
+ </div>
4386
4395
  }
4387
4396
  } @else {
4388
4397
  <praxis-empty-state-card
@@ -4478,13 +4487,17 @@ class PraxisTabs {
4478
4487
  ></ng-container>
4479
4488
  }
4480
4489
  @if (safeWidgetDefinitions(entry.tab.widgets).length) {
4481
- @for (w of safeWidgetDefinitions(entry.tab.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4482
- <ng-container
4483
- [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4484
- [context]="context || {}"
4485
- (widgetEvent)="emitWidgetEvent(tabEventPath(entry.tab.id, entry.index), $event)"
4486
- ></ng-container>
4487
- }
4490
+ <div class="praxis-tabs-widget-stack" data-role="nested-widget-stack">
4491
+ @for (w of safeWidgetDefinitions(entry.tab.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4492
+ <div class="praxis-tabs-widget-surface" [attr.data-child-widget-key]="trackWidgetDefinition(wi, w)">
4493
+ <ng-container
4494
+ [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4495
+ [context]="context || {}"
4496
+ (widgetEvent)="emitWidgetEvent(tabEventPath(entry.tab.id, entry.index), $event)"
4497
+ ></ng-container>
4498
+ </div>
4499
+ }
4500
+ </div>
4488
4501
  }
4489
4502
  } @else {
4490
4503
  <praxis-empty-state-card
@@ -4527,7 +4540,7 @@ class PraxisTabs {
4527
4540
  </button>
4528
4541
  }
4529
4542
  </div>
4530
- `, 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,.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}.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 });
4543
+ `, 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,.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 });
4531
4544
  }
4532
4545
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisTabs, decorators: [{
4533
4546
  type: Component,
@@ -4689,13 +4702,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4689
4702
  ></ng-container>
4690
4703
  }
4691
4704
  @if (safeWidgetDefinitions(l.widgets).length) {
4692
- @for (w of safeWidgetDefinitions(l.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4693
- <ng-container
4694
- [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4695
- [context]="context || {}"
4696
- (widgetEvent)="emitWidgetEvent(linkEventPath(l.id, currentNavIndex()), $event)"
4697
- ></ng-container>
4698
- }
4705
+ <div class="praxis-tabs-widget-stack" data-role="nested-widget-stack">
4706
+ @for (w of safeWidgetDefinitions(l.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4707
+ <div class="praxis-tabs-widget-surface" [attr.data-child-widget-key]="trackWidgetDefinition(wi, w)">
4708
+ <ng-container
4709
+ [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4710
+ [context]="context || {}"
4711
+ (widgetEvent)="emitWidgetEvent(linkEventPath(l.id, currentNavIndex()), $event)"
4712
+ ></ng-container>
4713
+ </div>
4714
+ }
4715
+ </div>
4699
4716
  }
4700
4717
  } @else {
4701
4718
  <praxis-empty-state-card
@@ -4791,13 +4808,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4791
4808
  ></ng-container>
4792
4809
  }
4793
4810
  @if (safeWidgetDefinitions(entry.tab.widgets).length) {
4794
- @for (w of safeWidgetDefinitions(entry.tab.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4795
- <ng-container
4796
- [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4797
- [context]="context || {}"
4798
- (widgetEvent)="emitWidgetEvent(tabEventPath(entry.tab.id, entry.index), $event)"
4799
- ></ng-container>
4800
- }
4811
+ <div class="praxis-tabs-widget-stack" data-role="nested-widget-stack">
4812
+ @for (w of safeWidgetDefinitions(entry.tab.widgets); track trackWidgetDefinition(wi, w); let wi = $index) {
4813
+ <div class="praxis-tabs-widget-surface" [attr.data-child-widget-key]="trackWidgetDefinition(wi, w)">
4814
+ <ng-container
4815
+ [dynamicWidgetLoader]="resolveWidgetDefinition(w)"
4816
+ [context]="context || {}"
4817
+ (widgetEvent)="emitWidgetEvent(tabEventPath(entry.tab.id, entry.index), $event)"
4818
+ ></ng-container>
4819
+ </div>
4820
+ }
4821
+ </div>
4801
4822
  }
4802
4823
  } @else {
4803
4824
  <praxis-empty-state-card
@@ -4840,7 +4861,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
4840
4861
  </button>
4841
4862
  }
4842
4863
  </div>
4843
- `, changeDetection: ChangeDetectionStrategy.OnPush, 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,.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}.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"] }]
4864
+ `, changeDetection: ChangeDetectionStrategy.OnPush, 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,.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"] }]
4844
4865
  }], propDecorators: { config: [{
4845
4866
  type: Input
4846
4867
  }], tabsId: [{
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@praxisui/tabs",
3
- "version": "9.0.4-rc.3",
3
+ "version": "9.0.4-rc.30",
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": "^9.0.4-rc.3",
11
- "@praxisui/dynamic-fields": "^9.0.4-rc.3",
12
- "@praxisui/settings-panel": "^9.0.4-rc.3",
10
+ "@praxisui/core": "^9.0.4-rc.30",
11
+ "@praxisui/dynamic-fields": "^9.0.4-rc.30",
12
+ "@praxisui/settings-panel": "^9.0.4-rc.30",
13
13
  "@angular/forms": "^21.0.0",
14
14
  "@angular/router": "^21.0.0",
15
- "@praxisui/ai": "^9.0.4-rc.3",
15
+ "@praxisui/ai": "^9.0.4-rc.30",
16
16
  "rxjs": "~7.8.0"
17
17
  },
18
18
  "dependencies": {
@@ -207,7 +207,7 @@ declare class PraxisTabs implements OnInit, OnChanges, OnDestroy {
207
207
  private navLoaded;
208
208
  private controlledSelectedIndex?;
209
209
  private readonly destroy$;
210
- private readonly widgetDefinitionCache;
210
+ private widgetDefinitionCache;
211
211
  private readonly generatedContentForm;
212
212
  ngOnInit(): void;
213
213
  ngOnChanges(changes: SimpleChanges): void;