@praxisui/expansion 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.
package/README.md CHANGED
@@ -136,6 +136,8 @@ const config: ExpansionMetadata = {
136
136
 
137
137
  Panel `content` and `widgets` are rendered lazily with `matExpansionPanelContent`, so child runtime is created when the panel opens. Use stable `panels[].id` values; authoring, persistence and nested paths rely on them.
138
138
 
139
+ Each panel can also declare an optional `quickView?: ResourceQuickViewBinding` (and `quickViewActionLabel?: string`) on `PanelMetadata`. When a valid target ID is resolved from `[context]` or the panel's form values, `PraxisExpansion` renders an explicit header action button (`data-testid="expansion-panel-quick-view-action"`, `triggerMode: 'explicit-button'`) with click/keyboard propagation stopped so inspecting the referenced entity never toggles the expansion panel.
140
+
139
141
  ## Persistence And Authoring
140
142
 
141
143
  When `expansionId` is provided, configuration is stored under a key derived from route, component type, `expansionId` and optional `componentInstanceId`. `enableCustomization` opens Settings Panel editing and the governed semantic assistant flow.
@@ -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/expansion",
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,
@@ -6,20 +6,22 @@ import { ActivatedRoute } from '@angular/router';
6
6
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
7
  import * as i2 from '@angular/material/expansion';
8
8
  import { MAT_EXPANSION_PANEL_DEFAULT_OPTIONS, MatExpansionModule, MatExpansionPanel } from '@angular/material/expansion';
9
- import * as i5 from '@angular/material/form-field';
9
+ import * as i6 from '@angular/material/form-field';
10
10
  import { MatFormFieldModule } from '@angular/material/form-field';
11
11
  import * as i3 from '@angular/material/icon';
12
12
  import { MatIconModule } from '@angular/material/icon';
13
13
  import * as i4 from '@angular/material/button';
14
14
  import { MatButtonModule } from '@angular/material/button';
15
- import * as i6 from '@angular/material/input';
15
+ import * as i7 from '@angular/material/input';
16
16
  import { MatInputModule } from '@angular/material/input';
17
- import * as i7 from '@angular/material/slide-toggle';
17
+ import * as i8 from '@angular/material/select';
18
+ import { MatSelectModule } from '@angular/material/select';
19
+ import * as i9 from '@angular/material/slide-toggle';
18
20
  import { MatSlideToggleModule } from '@angular/material/slide-toggle';
19
- import * as i8 from '@angular/material/tooltip';
21
+ import * as i5 from '@angular/material/tooltip';
20
22
  import { MatTooltipModule } from '@angular/material/tooltip';
21
23
  import { DynamicFieldLoaderDirective } from '@praxisui/dynamic-fields';
22
- import { deepMerge, ASYNC_CONFIG_STORAGE, DynamicFormService, ComponentKeyService, DynamicWidgetLoaderDirective, PraxisIconDirective, PraxisIconButtonComponent, ComponentMetadataRegistry } from '@praxisui/core';
24
+ import { deepMerge, ASYNC_CONFIG_STORAGE, DynamicFormService, ComponentKeyService, normalizeResourceQuickViewBinding, resolveResourceQuickViewTarget, DynamicWidgetLoaderDirective, PraxisIconDirective, PraxisQuickViewTriggerDirective, EmptyStateCardComponent, PraxisIconButtonComponent, ComponentMetadataRegistry } from '@praxisui/core';
23
25
  import { SettingsPanelService, SETTINGS_PANEL_DATA } from '@praxisui/settings-panel';
24
26
  import { firstValueFrom, BehaviorSubject, Subscription } from 'rxjs';
25
27
  import { take } from 'rxjs/operators';
@@ -600,6 +602,9 @@ class PraxisExpansion {
600
602
  this.buildPanelForms();
601
603
  this.persistConfig(this.config);
602
604
  }
605
+ if ('context' in changes) {
606
+ this.cdr.markForCheck();
607
+ }
603
608
  }
604
609
  ngOnDestroy() {
605
610
  this.storageLoad?.unsubscribe();
@@ -836,6 +841,44 @@ class PraxisExpansion {
836
841
  this.panelForms.set(key, form);
837
842
  return form;
838
843
  }
844
+ resolvePanelQuickViewBinding(panel) {
845
+ return normalizeResourceQuickViewBinding(panel?.quickView);
846
+ }
847
+ resolvePanelQuickViewContext(panel, index) {
848
+ const baseContext = this.context && typeof this.context === 'object' ? this.context : {};
849
+ const formValues = this.panelForms.get(this.panelKey(panel, index))?.getRawValue?.() ?? {};
850
+ const existingValues = baseContext['values'] && typeof baseContext['values'] === 'object'
851
+ ? baseContext['values']
852
+ : {};
853
+ return {
854
+ ...formValues,
855
+ ...baseContext,
856
+ values: {
857
+ ...formValues,
858
+ ...existingValues,
859
+ },
860
+ panel: {
861
+ id: panel.id,
862
+ title: panel.title,
863
+ description: panel.description,
864
+ index,
865
+ },
866
+ };
867
+ }
868
+ hasPanelQuickViewTarget(panel, index, binding) {
869
+ if (!binding || panel.disabled) {
870
+ return false;
871
+ }
872
+ return (resolveResourceQuickViewTarget(binding, this.resolvePanelQuickViewContext(panel, index)) !== null);
873
+ }
874
+ resolvePanelQuickViewLabel(panel) {
875
+ const custom = panel.quickViewActionLabel?.trim();
876
+ if (custom) {
877
+ return custom;
878
+ }
879
+ const base = 'Visualização rápida';
880
+ return panel.title ? `${base}: ${panel.title}` : base;
881
+ }
839
882
  applyConfigFromAdapter(next) {
840
883
  this.config = next;
841
884
  this.buildPanelForms();
@@ -1330,6 +1373,27 @@ class PraxisExpansion {
1330
1373
  @if (p.description) {
1331
1374
  <mat-panel-description>{{ p.description }}</mat-panel-description>
1332
1375
  }
1376
+ @if (resolvePanelQuickViewBinding(p); as qvBinding) {
1377
+ @if (hasPanelQuickViewTarget(p, i, qvBinding)) {
1378
+ <button
1379
+ mat-icon-button
1380
+ type="button"
1381
+ class="praxis-expansion-header-quick-view-action"
1382
+ data-testid="expansion-panel-quick-view-action"
1383
+ [attr.aria-label]="resolvePanelQuickViewLabel(p)"
1384
+ [matTooltip]="resolvePanelQuickViewLabel(p)"
1385
+ [disabled]="!!p.disabled"
1386
+ [praxisQuickView]="qvBinding"
1387
+ [praxisQuickViewRecord]="resolvePanelQuickViewContext(p, i)"
1388
+ [praxisQuickViewTriggerMode]="'explicit-button'"
1389
+ (click)="$event.stopPropagation()"
1390
+ (keydown.enter)="$event.stopPropagation()"
1391
+ (keydown.space)="$event.stopPropagation()"
1392
+ >
1393
+ <mat-icon [praxisIcon]="'preview'">preview</mat-icon>
1394
+ </button>
1395
+ }
1396
+ }
1333
1397
  </mat-expansion-panel-header>
1334
1398
 
1335
1399
  <ng-template matExpansionPanelContent>
@@ -1394,6 +1458,27 @@ class PraxisExpansion {
1394
1458
  @if (p.description) {
1395
1459
  <mat-panel-description>{{ p.description }}</mat-panel-description>
1396
1460
  }
1461
+ @if (resolvePanelQuickViewBinding(p); as qvBinding) {
1462
+ @if (hasPanelQuickViewTarget(p, 0, qvBinding)) {
1463
+ <button
1464
+ mat-icon-button
1465
+ type="button"
1466
+ class="praxis-expansion-header-quick-view-action"
1467
+ data-testid="expansion-panel-quick-view-action"
1468
+ [attr.aria-label]="resolvePanelQuickViewLabel(p)"
1469
+ [matTooltip]="resolvePanelQuickViewLabel(p)"
1470
+ [disabled]="!!p.disabled"
1471
+ [praxisQuickView]="qvBinding"
1472
+ [praxisQuickViewRecord]="resolvePanelQuickViewContext(p, 0)"
1473
+ [praxisQuickViewTriggerMode]="'explicit-button'"
1474
+ (click)="$event.stopPropagation()"
1475
+ (keydown.enter)="$event.stopPropagation()"
1476
+ (keydown.space)="$event.stopPropagation()"
1477
+ >
1478
+ <mat-icon [praxisIcon]="'preview'">preview</mat-icon>
1479
+ </button>
1480
+ }
1481
+ }
1397
1482
  </mat-expansion-panel-header>
1398
1483
 
1399
1484
  <ng-template matExpansionPanelContent>
@@ -1431,14 +1516,22 @@ class PraxisExpansion {
1431
1516
  </ng-template>
1432
1517
  </mat-expansion-panel>
1433
1518
  } @else {
1434
- <div class="praxis-expansion-empty">
1435
- <span>Nenhum painel configurado</span>
1436
- @if (enableCustomization) {
1437
- <button mat-stroked-button color="primary" (click)="openEditor()">
1438
- <mat-icon [praxisIcon]="'tune'"></mat-icon> Configurar
1439
- </button>
1440
- }
1441
- </div>
1519
+ <praxis-empty-state-card
1520
+ class="praxis-expansion-empty"
1521
+ [inline]="true"
1522
+ icon="unfold_more"
1523
+ title="Nenhum painel configurado"
1524
+ description="Adicione painéis retráteis para organizar formulários ou widgets por seção."
1525
+ [primaryAction]="
1526
+ enableCustomization
1527
+ ? {
1528
+ label: 'Configurar painéis',
1529
+ icon: 'tune',
1530
+ action: openEditor.bind(this),
1531
+ }
1532
+ : undefined
1533
+ "
1534
+ ></praxis-empty-state-card>
1442
1535
  }
1443
1536
  }
1444
1537
  </div>
@@ -1453,7 +1546,7 @@ class PraxisExpansion {
1453
1546
  <mat-icon fontIcon="edit"></mat-icon>
1454
1547
  </button>
1455
1548
  }
1456
- `, isInline: true, styles: [":host{display:block;position:relative;color:var(--md-sys-color-on-surface)}.praxis-expansion-root{display:block;--p-exp-surface: var(--md-sys-color-surface);--p-exp-surface-container: var(--md-sys-color-surface-container);--p-exp-border: var(--md-sys-color-outline-variant);--p-exp-text: var(--md-sys-color-on-surface);--p-exp-text-muted: var(--md-sys-color-on-surface-variant);--p-exp-focus: var(--md-sys-color-primary);--p-exp-radius: 12px}.mat-expansion-panel{background:var(--p-exp-surface);border:1px solid var(--p-exp-border);border-radius:var(--p-exp-radius);overflow:clip}.mat-expansion-panel:not(:last-child){margin-bottom:var(--p-exp-panel-gap, 12px)}.mat-expansion-panel-header{background:var(--p-exp-surface-container);color:var(--p-exp-text)}.mat-expansion-panel-header:focus-visible{outline:2px solid var(--p-exp-focus);outline-offset:-2px}.mat-expansion-panel-header-title{font-weight:600}.mat-expansion-panel-header-description{color:var(--p-exp-text-muted)}.mat-expansion-panel-body{padding:12px 16px 16px}.mat-action-row{border-top:1px solid var(--p-exp-border)}.density-compact .mat-expansion-panel-body{padding:8px 12px 12px}.density-compact .mat-expansion-panel-header{min-height:40px;padding:0 12px}.density-comfortable .mat-expansion-panel-body{padding:12px 16px 16px}.density-comfortable .mat-expansion-panel-header{min-height:48px;padding:0 16px}.density-spacious .mat-expansion-panel-body{padding:16px 20px 20px}.density-spacious .mat-expansion-panel-header{min-height:56px;padding:0 20px}.praxis-expansion-empty{display:flex;gap:8px;align-items:center;padding:8px 12px;color:var(--p-exp-text-muted)}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.expansion-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.expansion-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i2.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i2.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i2.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i2.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i2.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i2.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { 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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { 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 });
1549
+ `, isInline: true, styles: [":host{display:block;position:relative;color:var(--md-sys-color-on-surface)}.praxis-expansion-root{display:block;--p-exp-surface: var(--md-sys-color-surface);--p-exp-surface-container: var(--md-sys-color-surface-container);--p-exp-border: var(--md-sys-color-outline-variant);--p-exp-text: var(--md-sys-color-on-surface);--p-exp-text-muted: var(--md-sys-color-on-surface-variant);--p-exp-focus: var(--md-sys-color-primary);--p-exp-radius: 12px}.mat-expansion-panel{background:var(--p-exp-surface);border:1px solid var(--p-exp-border);border-radius:var(--p-exp-radius);overflow:clip}.mat-expansion-panel:not(:last-child){margin-bottom:var(--p-exp-panel-gap, 12px)}.mat-expansion-panel-header{background:var(--p-exp-surface-container);color:var(--p-exp-text)}.mat-expansion-panel-header:focus-visible{outline:2px solid var(--p-exp-focus);outline-offset:-2px}.mat-expansion-panel-header-title{font-weight:600}.mat-expansion-panel-header-description{color:var(--p-exp-text-muted)}.praxis-expansion-header-quick-view-action{width:32px;height:32px;padding:4px;margin-left:auto;margin-right:4px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.praxis-expansion-header-quick-view-action mat-icon{font-size:18px;width:18px;height:18px}.mat-expansion-panel-body{padding:12px 16px 16px}.mat-action-row{border-top:1px solid var(--p-exp-border)}.density-compact .mat-expansion-panel-body{padding:8px 12px 12px}.density-compact .mat-expansion-panel-header{min-height:40px;padding:0 12px}.density-comfortable .mat-expansion-panel-body{padding:12px 16px 16px}.density-comfortable .mat-expansion-panel-header{min-height:48px;padding:0 16px}.density-spacious .mat-expansion-panel-body{padding:16px 20px 20px}.density-spacious .mat-expansion-panel-header{min-height:56px;padding:0 20px}.praxis-expansion-empty{display:block}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.expansion-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.expansion-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i2.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i2.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "directive", type: i2.MatExpansionPanelActionRow, selector: "mat-action-row" }, { kind: "component", type: i2.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i2.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i2.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "directive", type: i2.MatExpansionPanelContent, selector: "ng-template[matExpansionPanelContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: "component", type: i4.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { 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: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "directive", type: PraxisQuickViewTriggerDirective, selector: "[praxisQuickView]", inputs: ["praxisQuickView", "praxisQuickViewRecord", "praxisQuickViewTriggerMode", "praxisQuickViewAnchorId", "praxisQuickViewSourceId", "praxisQuickViewEndpointKey", "praxisQuickViewApiUrlEntry", "praxisQuickViewQueryContext", "praxisQuickViewHoverOpenDelayMs", "praxisQuickViewHoverCloseDelayMs", "praxisQuickViewStopPropagation"], exportAs: ["praxisQuickView"] }, { kind: "component", type: EmptyStateCardComponent, selector: "praxis-empty-state-card", inputs: ["icon", "title", "description", "primaryAction", "secondaryActions", "inline", "tone", "variant", "alignment", "density", "iconContainer"] }, { 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 });
1457
1550
  }
1458
1551
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisExpansion, decorators: [{
1459
1552
  type: Component,
@@ -1462,9 +1555,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1462
1555
  MatExpansionModule,
1463
1556
  MatIconModule,
1464
1557
  MatButtonModule,
1558
+ MatTooltipModule,
1465
1559
  DynamicFieldLoaderDirective,
1466
1560
  DynamicWidgetLoaderDirective,
1467
1561
  PraxisIconDirective,
1562
+ PraxisQuickViewTriggerDirective,
1563
+ EmptyStateCardComponent,
1468
1564
  PraxisAiAssistantShellComponent,
1469
1565
  ], template: `
1470
1566
  <div
@@ -1562,6 +1658,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1562
1658
  @if (p.description) {
1563
1659
  <mat-panel-description>{{ p.description }}</mat-panel-description>
1564
1660
  }
1661
+ @if (resolvePanelQuickViewBinding(p); as qvBinding) {
1662
+ @if (hasPanelQuickViewTarget(p, i, qvBinding)) {
1663
+ <button
1664
+ mat-icon-button
1665
+ type="button"
1666
+ class="praxis-expansion-header-quick-view-action"
1667
+ data-testid="expansion-panel-quick-view-action"
1668
+ [attr.aria-label]="resolvePanelQuickViewLabel(p)"
1669
+ [matTooltip]="resolvePanelQuickViewLabel(p)"
1670
+ [disabled]="!!p.disabled"
1671
+ [praxisQuickView]="qvBinding"
1672
+ [praxisQuickViewRecord]="resolvePanelQuickViewContext(p, i)"
1673
+ [praxisQuickViewTriggerMode]="'explicit-button'"
1674
+ (click)="$event.stopPropagation()"
1675
+ (keydown.enter)="$event.stopPropagation()"
1676
+ (keydown.space)="$event.stopPropagation()"
1677
+ >
1678
+ <mat-icon [praxisIcon]="'preview'">preview</mat-icon>
1679
+ </button>
1680
+ }
1681
+ }
1565
1682
  </mat-expansion-panel-header>
1566
1683
 
1567
1684
  <ng-template matExpansionPanelContent>
@@ -1626,6 +1743,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1626
1743
  @if (p.description) {
1627
1744
  <mat-panel-description>{{ p.description }}</mat-panel-description>
1628
1745
  }
1746
+ @if (resolvePanelQuickViewBinding(p); as qvBinding) {
1747
+ @if (hasPanelQuickViewTarget(p, 0, qvBinding)) {
1748
+ <button
1749
+ mat-icon-button
1750
+ type="button"
1751
+ class="praxis-expansion-header-quick-view-action"
1752
+ data-testid="expansion-panel-quick-view-action"
1753
+ [attr.aria-label]="resolvePanelQuickViewLabel(p)"
1754
+ [matTooltip]="resolvePanelQuickViewLabel(p)"
1755
+ [disabled]="!!p.disabled"
1756
+ [praxisQuickView]="qvBinding"
1757
+ [praxisQuickViewRecord]="resolvePanelQuickViewContext(p, 0)"
1758
+ [praxisQuickViewTriggerMode]="'explicit-button'"
1759
+ (click)="$event.stopPropagation()"
1760
+ (keydown.enter)="$event.stopPropagation()"
1761
+ (keydown.space)="$event.stopPropagation()"
1762
+ >
1763
+ <mat-icon [praxisIcon]="'preview'">preview</mat-icon>
1764
+ </button>
1765
+ }
1766
+ }
1629
1767
  </mat-expansion-panel-header>
1630
1768
 
1631
1769
  <ng-template matExpansionPanelContent>
@@ -1663,14 +1801,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1663
1801
  </ng-template>
1664
1802
  </mat-expansion-panel>
1665
1803
  } @else {
1666
- <div class="praxis-expansion-empty">
1667
- <span>Nenhum painel configurado</span>
1668
- @if (enableCustomization) {
1669
- <button mat-stroked-button color="primary" (click)="openEditor()">
1670
- <mat-icon [praxisIcon]="'tune'"></mat-icon> Configurar
1671
- </button>
1672
- }
1673
- </div>
1804
+ <praxis-empty-state-card
1805
+ class="praxis-expansion-empty"
1806
+ [inline]="true"
1807
+ icon="unfold_more"
1808
+ title="Nenhum painel configurado"
1809
+ description="Adicione painéis retráteis para organizar formulários ou widgets por seção."
1810
+ [primaryAction]="
1811
+ enableCustomization
1812
+ ? {
1813
+ label: 'Configurar painéis',
1814
+ icon: 'tune',
1815
+ action: openEditor.bind(this),
1816
+ }
1817
+ : undefined
1818
+ "
1819
+ ></praxis-empty-state-card>
1674
1820
  }
1675
1821
  }
1676
1822
  </div>
@@ -1685,7 +1831,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
1685
1831
  <mat-icon fontIcon="edit"></mat-icon>
1686
1832
  </button>
1687
1833
  }
1688
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;position:relative;color:var(--md-sys-color-on-surface)}.praxis-expansion-root{display:block;--p-exp-surface: var(--md-sys-color-surface);--p-exp-surface-container: var(--md-sys-color-surface-container);--p-exp-border: var(--md-sys-color-outline-variant);--p-exp-text: var(--md-sys-color-on-surface);--p-exp-text-muted: var(--md-sys-color-on-surface-variant);--p-exp-focus: var(--md-sys-color-primary);--p-exp-radius: 12px}.mat-expansion-panel{background:var(--p-exp-surface);border:1px solid var(--p-exp-border);border-radius:var(--p-exp-radius);overflow:clip}.mat-expansion-panel:not(:last-child){margin-bottom:var(--p-exp-panel-gap, 12px)}.mat-expansion-panel-header{background:var(--p-exp-surface-container);color:var(--p-exp-text)}.mat-expansion-panel-header:focus-visible{outline:2px solid var(--p-exp-focus);outline-offset:-2px}.mat-expansion-panel-header-title{font-weight:600}.mat-expansion-panel-header-description{color:var(--p-exp-text-muted)}.mat-expansion-panel-body{padding:12px 16px 16px}.mat-action-row{border-top:1px solid var(--p-exp-border)}.density-compact .mat-expansion-panel-body{padding:8px 12px 12px}.density-compact .mat-expansion-panel-header{min-height:40px;padding:0 12px}.density-comfortable .mat-expansion-panel-body{padding:12px 16px 16px}.density-comfortable .mat-expansion-panel-header{min-height:48px;padding:0 16px}.density-spacious .mat-expansion-panel-body{padding:16px 20px 20px}.density-spacious .mat-expansion-panel-header{min-height:56px;padding:0 20px}.praxis-expansion-empty{display:flex;gap:8px;align-items:center;padding:8px 12px;color:var(--p-exp-text-muted)}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.expansion-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.expansion-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"] }]
1834
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;position:relative;color:var(--md-sys-color-on-surface)}.praxis-expansion-root{display:block;--p-exp-surface: var(--md-sys-color-surface);--p-exp-surface-container: var(--md-sys-color-surface-container);--p-exp-border: var(--md-sys-color-outline-variant);--p-exp-text: var(--md-sys-color-on-surface);--p-exp-text-muted: var(--md-sys-color-on-surface-variant);--p-exp-focus: var(--md-sys-color-primary);--p-exp-radius: 12px}.mat-expansion-panel{background:var(--p-exp-surface);border:1px solid var(--p-exp-border);border-radius:var(--p-exp-radius);overflow:clip}.mat-expansion-panel:not(:last-child){margin-bottom:var(--p-exp-panel-gap, 12px)}.mat-expansion-panel-header{background:var(--p-exp-surface-container);color:var(--p-exp-text)}.mat-expansion-panel-header:focus-visible{outline:2px solid var(--p-exp-focus);outline-offset:-2px}.mat-expansion-panel-header-title{font-weight:600}.mat-expansion-panel-header-description{color:var(--p-exp-text-muted)}.praxis-expansion-header-quick-view-action{width:32px;height:32px;padding:4px;margin-left:auto;margin-right:4px;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.praxis-expansion-header-quick-view-action mat-icon{font-size:18px;width:18px;height:18px}.mat-expansion-panel-body{padding:12px 16px 16px}.mat-action-row{border-top:1px solid var(--p-exp-border)}.density-compact .mat-expansion-panel-body{padding:8px 12px 12px}.density-compact .mat-expansion-panel-header{min-height:40px;padding:0 12px}.density-comfortable .mat-expansion-panel-body{padding:12px 16px 16px}.density-comfortable .mat-expansion-panel-header{min-height:48px;padding:0 16px}.density-spacious .mat-expansion-panel-body{padding:16px 20px 20px}.density-spacious .mat-expansion-panel-header{min-height:56px;padding:0 20px}.praxis-expansion-empty{display:block}.edit-fab{position:absolute;right:12px;bottom:12px;z-index:2}.expansion-ai-assistant{position:absolute;right:12px;bottom:72px;z-index:3}.expansion-ai-assistant-trigger{box-shadow:var(--md-sys-elevation-level2, 0 4px 12px rgba(0, 0, 0, .18))}\n"] }]
1689
1835
  }], propDecorators: { config: [{
1690
1836
  type: Input
1691
1837
  }], expansionId: [{
@@ -1904,12 +2050,12 @@ class PraxisExpansionConfigEditor {
1904
2050
  </mat-form-field>
1905
2051
  <mat-form-field appearance="outline">
1906
2052
  <mat-label>Densidade</mat-label>
1907
- <select matNativeControl [value]="config?.appearance?.density || ''" (change)="setAppearance('density', $any($event.target).value || undefined)">
1908
- <option value="">Padrão</option>
1909
- <option value="compact">Compacta</option>
1910
- <option value="comfortable">Confortável</option>
1911
- <option value="spacious">Espaçosa</option>
1912
- </select>
2053
+ <mat-select [value]="config?.appearance?.density || ''" (selectionChange)="setAppearance('density', $event.value || undefined)" placeholder="Padrão">
2054
+ <mat-option value="">Padrão</mat-option>
2055
+ <mat-option value="compact">Compacta</mat-option>
2056
+ <mat-option value="comfortable">Confortável</mat-option>
2057
+ <mat-option value="spacious">Espaçosa</mat-option>
2058
+ </mat-select>
1913
2059
  </mat-form-field>
1914
2060
  </div>
1915
2061
 
@@ -1933,13 +2079,13 @@ class PraxisExpansionConfigEditor {
1933
2079
  </mat-form-field>
1934
2080
  <mat-form-field appearance="outline">
1935
2081
  <mat-label>Estilo da borda</mat-label>
1936
- <select matNativeControl [value]="config?.appearance?.container?.borderStyle || ''" (change)="setContainer('borderStyle', $any($event.target).value || undefined)">
1937
- <option value="">Padrão</option>
1938
- <option value="solid">Solid</option>
1939
- <option value="dashed">Dashed</option>
1940
- <option value="dotted">Dotted</option>
1941
- <option value="none">None</option>
1942
- </select>
2082
+ <mat-select [value]="config?.appearance?.container?.borderStyle || ''" (selectionChange)="setContainer('borderStyle', $event.value || undefined)" placeholder="Padrão">
2083
+ <mat-option value="">Padrão</mat-option>
2084
+ <mat-option value="solid">Solid</mat-option>
2085
+ <mat-option value="dashed">Dashed</mat-option>
2086
+ <mat-option value="dotted">Dotted</mat-option>
2087
+ <mat-option value="none">None</mat-option>
2088
+ </mat-select>
1943
2089
  </mat-form-field>
1944
2090
  <mat-form-field appearance="outline">
1945
2091
  <mat-label>Raio da borda</mat-label>
@@ -2077,17 +2223,17 @@ class PraxisExpansionConfigEditor {
2077
2223
  </mat-form-field>
2078
2224
  <mat-form-field appearance="outline">
2079
2225
  <mat-label>Modo de exibição</mat-label>
2080
- <select matNativeControl [value]="config?.accordion?.displayMode || 'default'" (change)="setAccordion('displayMode', $any($event.target).value)">
2081
- <option value="default">Padrão</option>
2082
- <option value="flat">Flat</option>
2083
- </select>
2226
+ <mat-select [value]="config?.accordion?.displayMode || 'default'" (selectionChange)="setAccordion('displayMode', $event.value)">
2227
+ <mat-option value="default">Padrão</mat-option>
2228
+ <mat-option value="flat">Flat</mat-option>
2229
+ </mat-select>
2084
2230
  </mat-form-field>
2085
2231
  <mat-form-field appearance="outline">
2086
2232
  <mat-label>Posição do toggle</mat-label>
2087
- <select matNativeControl [value]="config?.accordion?.togglePosition || 'after'" (change)="setAccordion('togglePosition', $any($event.target).value)">
2088
- <option value="after">Depois</option>
2089
- <option value="before">Antes</option>
2090
- </select>
2233
+ <mat-select [value]="config?.accordion?.togglePosition || 'after'" (selectionChange)="setAccordion('togglePosition', $event.value)">
2234
+ <mat-option value="after">Depois</mat-option>
2235
+ <mat-option value="before">Antes</mat-option>
2236
+ </mat-select>
2091
2237
  </mat-form-field>
2092
2238
  <div class="row wrap">
2093
2239
  <mat-slide-toggle [checked]="config?.accordion?.multi || false" (change)="setAccordion('multi', $event.checked)">Múltiplos abertos</mat-slide-toggle>
@@ -2136,7 +2282,7 @@ class PraxisExpansionConfigEditor {
2136
2282
  </section>
2137
2283
  }
2138
2284
  </div>
2139
- `, isInline: true, styles: [":host{display:block;color:var(--md-sys-color-on-surface)}.pdx-expansion-editor{display:grid;gap:16px}.sec{border:1px solid var(--md-sys-color-outline-variant);padding:12px;border-radius:10px;background:var(--md-sys-color-surface-container-lowest);display:grid;gap:12px}.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.row.wrap{flex-wrap:wrap}.panel-row{display:flex;gap:8px;align-items:center;width:100%}.grow{flex:1 1 auto}.grid{display:grid;gap:10px;align-items:center}.grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.full{width:100%}.error{color:var(--md-sys-color-error);font-size:12px}.pdx-expansion-editor .mat-mdc-form-field{width:100%;--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)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i6.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: MatSlideToggleModule }, { kind: "component", type: i7.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: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2285
+ `, isInline: true, styles: [":host{display:block;container-type:inline-size;color:var(--pfx-settings-panel-text-primary, var(--md-sys-color-on-surface))}.pdx-expansion-editor{display:grid;gap:16px}.sec{border:1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));padding:14px;border-radius:12px;background:var(--pfx-settings-panel-surface, var(--md-sys-color-surface-container-lowest));display:grid;gap:12px}.sec h4,.sec h5{margin:0;font-weight:600;color:var(--pfx-settings-panel-text-primary, var(--md-sys-color-on-surface))}.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.row.wrap{flex-wrap:wrap}.panel-row{display:flex;gap:8px;align-items:center;width:100%;flex-wrap:wrap}.grow{flex:1 1 auto}.grid{display:grid;gap:10px;align-items:center}.grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.full{width:100%}.error{color:var(--md-sys-color-error);font-size:12px}.pdx-expansion-editor .mat-mdc-form-field{width:100%;--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)}@container (max-width: 600px){.grid.two{grid-template-columns:1fr}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.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: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i6.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i7.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: i8.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: i8.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { 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: MatTooltipModule }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2140
2286
  }
2141
2287
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisExpansionConfigEditor, decorators: [{
2142
2288
  type: Component,
@@ -2146,6 +2292,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2146
2292
  MatIconModule,
2147
2293
  MatFormFieldModule,
2148
2294
  MatInputModule,
2295
+ MatSelectModule,
2149
2296
  MatSlideToggleModule,
2150
2297
  MatTooltipModule,
2151
2298
  PraxisIconButtonComponent,
@@ -2161,12 +2308,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2161
2308
  </mat-form-field>
2162
2309
  <mat-form-field appearance="outline">
2163
2310
  <mat-label>Densidade</mat-label>
2164
- <select matNativeControl [value]="config?.appearance?.density || ''" (change)="setAppearance('density', $any($event.target).value || undefined)">
2165
- <option value="">Padrão</option>
2166
- <option value="compact">Compacta</option>
2167
- <option value="comfortable">Confortável</option>
2168
- <option value="spacious">Espaçosa</option>
2169
- </select>
2311
+ <mat-select [value]="config?.appearance?.density || ''" (selectionChange)="setAppearance('density', $event.value || undefined)" placeholder="Padrão">
2312
+ <mat-option value="">Padrão</mat-option>
2313
+ <mat-option value="compact">Compacta</mat-option>
2314
+ <mat-option value="comfortable">Confortável</mat-option>
2315
+ <mat-option value="spacious">Espaçosa</mat-option>
2316
+ </mat-select>
2170
2317
  </mat-form-field>
2171
2318
  </div>
2172
2319
 
@@ -2190,13 +2337,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2190
2337
  </mat-form-field>
2191
2338
  <mat-form-field appearance="outline">
2192
2339
  <mat-label>Estilo da borda</mat-label>
2193
- <select matNativeControl [value]="config?.appearance?.container?.borderStyle || ''" (change)="setContainer('borderStyle', $any($event.target).value || undefined)">
2194
- <option value="">Padrão</option>
2195
- <option value="solid">Solid</option>
2196
- <option value="dashed">Dashed</option>
2197
- <option value="dotted">Dotted</option>
2198
- <option value="none">None</option>
2199
- </select>
2340
+ <mat-select [value]="config?.appearance?.container?.borderStyle || ''" (selectionChange)="setContainer('borderStyle', $event.value || undefined)" placeholder="Padrão">
2341
+ <mat-option value="">Padrão</mat-option>
2342
+ <mat-option value="solid">Solid</mat-option>
2343
+ <mat-option value="dashed">Dashed</mat-option>
2344
+ <mat-option value="dotted">Dotted</mat-option>
2345
+ <mat-option value="none">None</mat-option>
2346
+ </mat-select>
2200
2347
  </mat-form-field>
2201
2348
  <mat-form-field appearance="outline">
2202
2349
  <mat-label>Raio da borda</mat-label>
@@ -2334,17 +2481,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2334
2481
  </mat-form-field>
2335
2482
  <mat-form-field appearance="outline">
2336
2483
  <mat-label>Modo de exibição</mat-label>
2337
- <select matNativeControl [value]="config?.accordion?.displayMode || 'default'" (change)="setAccordion('displayMode', $any($event.target).value)">
2338
- <option value="default">Padrão</option>
2339
- <option value="flat">Flat</option>
2340
- </select>
2484
+ <mat-select [value]="config?.accordion?.displayMode || 'default'" (selectionChange)="setAccordion('displayMode', $event.value)">
2485
+ <mat-option value="default">Padrão</mat-option>
2486
+ <mat-option value="flat">Flat</mat-option>
2487
+ </mat-select>
2341
2488
  </mat-form-field>
2342
2489
  <mat-form-field appearance="outline">
2343
2490
  <mat-label>Posição do toggle</mat-label>
2344
- <select matNativeControl [value]="config?.accordion?.togglePosition || 'after'" (change)="setAccordion('togglePosition', $any($event.target).value)">
2345
- <option value="after">Depois</option>
2346
- <option value="before">Antes</option>
2347
- </select>
2491
+ <mat-select [value]="config?.accordion?.togglePosition || 'after'" (selectionChange)="setAccordion('togglePosition', $event.value)">
2492
+ <mat-option value="after">Depois</mat-option>
2493
+ <mat-option value="before">Antes</mat-option>
2494
+ </mat-select>
2348
2495
  </mat-form-field>
2349
2496
  <div class="row wrap">
2350
2497
  <mat-slide-toggle [checked]="config?.accordion?.multi || false" (change)="setAccordion('multi', $event.checked)">Múltiplos abertos</mat-slide-toggle>
@@ -2393,7 +2540,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
2393
2540
  </section>
2394
2541
  }
2395
2542
  </div>
2396
- `, styles: [":host{display:block;color:var(--md-sys-color-on-surface)}.pdx-expansion-editor{display:grid;gap:16px}.sec{border:1px solid var(--md-sys-color-outline-variant);padding:12px;border-radius:10px;background:var(--md-sys-color-surface-container-lowest);display:grid;gap:12px}.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.row.wrap{flex-wrap:wrap}.panel-row{display:flex;gap:8px;align-items:center;width:100%}.grow{flex:1 1 auto}.grid{display:grid;gap:10px;align-items:center}.grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.full{width:100%}.error{color:var(--md-sys-color-error);font-size:12px}.pdx-expansion-editor .mat-mdc-form-field{width:100%;--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)}\n"] }]
2543
+ `, styles: [":host{display:block;container-type:inline-size;color:var(--pfx-settings-panel-text-primary, var(--md-sys-color-on-surface))}.pdx-expansion-editor{display:grid;gap:16px}.sec{border:1px solid var(--pfx-settings-panel-border, var(--md-sys-color-outline-variant));padding:14px;border-radius:12px;background:var(--pfx-settings-panel-surface, var(--md-sys-color-surface-container-lowest));display:grid;gap:12px}.sec h4,.sec h5{margin:0;font-weight:600;color:var(--pfx-settings-panel-text-primary, var(--md-sys-color-on-surface))}.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.row.wrap{flex-wrap:wrap}.panel-row{display:flex;gap:8px;align-items:center;width:100%;flex-wrap:wrap}.grow{flex:1 1 auto}.grid{display:grid;gap:10px;align-items:center}.grid.two{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}.full{width:100%}.error{color:var(--md-sys-color-error);font-size:12px}.pdx-expansion-editor .mat-mdc-form-field{width:100%;--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)}@container (max-width: 600px){.grid.two{grid-template-columns:1fr}}\n"] }]
2397
2544
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2398
2545
  type: Inject,
2399
2546
  args: [SETTINGS_PANEL_DATA]
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@praxisui/expansion",
3
- "version": "10.0.0-rc.4",
3
+ "version": "10.0.0-rc.41",
4
4
  "description": "Expansion panel (accordion) components for Praxis UI with metadata configuration and editor integration.",
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": {
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { OnChanges, OnDestroy, OnInit, EventEmitter, QueryList, SimpleChanges, AfterViewInit, Provider } from '@angular/core';
3
3
  import { FormGroup } from '@angular/forms';
4
4
  import { MatAccordionDisplayMode, MatAccordionTogglePosition, MatExpansionPanelDefaultOptions, MatAccordion, MatExpansionPanel } from '@angular/material/expansion';
5
- import { AiCapability, FieldMetadata, WidgetDefinition, WidgetEventEnvelope, SettingsValueProvider as SettingsValueProvider$1, ComponentDocMeta, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
5
+ import { AiCapability, FieldMetadata, WidgetDefinition, ResourceQuickViewBinding, WidgetEventEnvelope, SettingsValueProvider as SettingsValueProvider$1, ComponentDocMeta, AiCapabilityCategory, AiCapabilityCatalog, AiValueKind, ComponentAuthoringManifest } from '@praxisui/core';
6
6
  import { BehaviorSubject } from 'rxjs';
7
7
  import { BaseAiAdapter, PatchResult, PraxisAssistantTurnViewState, PraxisAssistantShellLayout, PraxisAssistantShellLabels, PraxisAssistantSessionSnapshot, PraxisAssistantShellQuickReply, PraxisAssistantShellMessage, PraxisAssistantShellContextItem } from '@praxisui/ai';
8
8
  import { SettingsValueProvider } from '@praxisui/settings-panel';
@@ -107,6 +107,17 @@ interface PanelMetadata {
107
107
  icon?: string;
108
108
  action?: string;
109
109
  }>;
110
+ /**
111
+ * Optional governed Resource Quick View binding for the panel header.
112
+ * Rendered strictly as an explicit button (`triggerMode: 'explicit-button'`)
113
+ * with event propagation stopped so hovering or clicking never toggles the
114
+ * expansion panel.
115
+ */
116
+ quickView?: ResourceQuickViewBinding;
117
+ /**
118
+ * Accessible label and tooltip for the panel header Quick View action button.
119
+ */
120
+ quickViewActionLabel?: string;
110
121
  }
111
122
  declare class PraxisExpansion implements OnChanges, OnDestroy, OnInit {
112
123
  config?: ExpansionMetadata | null;
@@ -195,6 +206,10 @@ declare class PraxisExpansion implements OnChanges, OnDestroy, OnInit {
195
206
  private findPanel;
196
207
  panelDomId(p: PanelMetadata | null, index: number): string;
197
208
  panelFormFor(panel: PanelMetadata, index: number): FormGroup<Record<string, any>>;
209
+ resolvePanelQuickViewBinding(panel: PanelMetadata | null | undefined): ResourceQuickViewBinding | null;
210
+ resolvePanelQuickViewContext(panel: PanelMetadata, index: number): Record<string, unknown>;
211
+ hasPanelQuickViewTarget(panel: PanelMetadata, index: number, binding: ResourceQuickViewBinding | null | undefined): boolean;
212
+ resolvePanelQuickViewLabel(panel: PanelMetadata): string;
198
213
  applyConfigFromAdapter(next: ExpansionMetadata): void;
199
214
  openAiAssistant(): void;
200
215
  openAiAssistantFromSession(session: PraxisAssistantSessionSnapshot): void;