@praxisui/dialog 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/dialog",
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,
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Directive, EventEmitter, inject, HostBinding, ContentChild, ViewChild, Output, Input, ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable, Injector, ApplicationRef, TemplateRef, ENVIRONMENT_INITIALIZER } from '@angular/core';
2
+ import { InjectionToken, Directive, EventEmitter, inject, HostBinding, ContentChild, ViewChild, Output, Input, ViewEncapsulation, ChangeDetectionStrategy, Component, Injectable, Injector, ApplicationRef, TemplateRef, signal, computed, ENVIRONMENT_INITIALIZER } from '@angular/core';
3
3
  import { Subject, firstValueFrom } from 'rxjs';
4
4
  import * as i1 from '@angular/common';
5
5
  import { CommonModule } from '@angular/common';
@@ -9,7 +9,7 @@ import * as i3 from '@angular/cdk/a11y';
9
9
  import { A11yModule } from '@angular/cdk/a11y';
10
10
  import * as i4 from '@angular/material/icon';
11
11
  import { MatIconModule } from '@angular/material/icon';
12
- import { PraxisIconDirective, PraxisLayerScaleStyleService, GlobalConfigService, GLOBAL_DIALOG_SERVICE, ComponentMetadataRegistry, markGlobalActionProviderOperational, GLOBAL_SURFACE_SERVICE, SurfaceOpenMaterializerService, LoggerService, SURFACE_DRAWER_BRIDGE, PraxisSurfaceHostComponent, SurfaceNavigationError } from '@praxisui/core';
12
+ import { PraxisIconDirective, PraxisLayerScaleStyleService, SURFACE_DRAWER_REF, SURFACE_DRAWER_CONTENT_DATA, GlobalConfigService, GLOBAL_DIALOG_SERVICE, ComponentMetadataRegistry, markGlobalActionProviderOperational, GLOBAL_SURFACE_SERVICE, SurfaceOpenMaterializerService, LoggerService, SURFACE_DRAWER_BRIDGE, PraxisSurfaceHostComponent, SurfaceNavigationError, PraxisI18nService, PraxisResourceIdentityComponent, isResourceQuickViewAnchorValid, PRAXIS_QUICK_VIEW_PRESENTER } from '@praxisui/core';
13
13
  import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
14
14
  import * as i1$1 from '@angular/forms';
15
15
  import { FormsModule } from '@angular/forms';
@@ -755,12 +755,17 @@ class PraxisDialog {
755
755
  open(content, config) {
756
756
  this.layerScale.ensureInstalled();
757
757
  const effectiveInjector = config?.injector ?? config?.viewContainerRef?.injector ?? this.injector;
758
+ const overlayRef = this.overlay.createOverlay(config ?? {});
759
+ const ref = new PraxisDialogRef(overlayRef);
758
760
  const injector = Injector.create({
759
- providers: [{ provide: PRAXIS_DIALOG_DATA, useValue: config?.data }],
761
+ providers: [
762
+ { provide: PRAXIS_DIALOG_DATA, useValue: config?.data },
763
+ { provide: PraxisDialogRef, useValue: ref },
764
+ { provide: SURFACE_DRAWER_REF, useValue: null },
765
+ { provide: SURFACE_DRAWER_CONTENT_DATA, useValue: null },
766
+ ],
760
767
  parent: effectiveInjector,
761
768
  });
762
- const overlayRef = this.overlay.createOverlay(config ?? {});
763
- const ref = new PraxisDialogRef(overlayRef);
764
769
  // Auto-id fallback if not provided
765
770
  let assignedId = config?.id ?? `praxis-dialog-${++this._seq}`;
766
771
  while (this.getDialogById(assignedId)) {
@@ -1368,13 +1373,20 @@ function toSurfaceSelectionResult(output, payload) {
1368
1373
  payload,
1369
1374
  };
1370
1375
  }
1371
- function resolveParentSurfaceRuntime(context) {
1376
+ function resolveParentSurfaceRuntime(context, runtimeInjector) {
1372
1377
  const runtime = context?.runtime?.state?.surfaceRuntime ||
1373
1378
  context?.payload?.surfaceContext?.surfaceRuntime ||
1374
1379
  context?.pageContext?.surfaceRuntime;
1375
- return runtime && typeof runtime === 'object'
1376
- ? runtime
1377
- : null;
1380
+ if (runtime && typeof runtime === 'object') {
1381
+ return runtime;
1382
+ }
1383
+ if (runtimeInjector && !runtimeInjector.get(PraxisDialogRef, null)) {
1384
+ const injectedRuntime = runtimeInjector.get(SURFACE_DRAWER_REF, null);
1385
+ if (injectedRuntime && typeof injectedRuntime === 'object') {
1386
+ return injectedRuntime;
1387
+ }
1388
+ }
1389
+ return null;
1378
1390
  }
1379
1391
  /**
1380
1392
  * The action origin is runtime-only: persisted surface payloads remain JSON
@@ -1485,7 +1497,7 @@ function providePraxisSurfaceGlobalActions() {
1485
1497
  }),
1486
1498
  },
1487
1499
  };
1488
- const parentRuntime = resolveParentSurfaceRuntime(context);
1500
+ const parentRuntime = resolveParentSurfaceRuntime(context, runtimeInjector);
1489
1501
  if (typeof parentRuntime?.['push'] === 'function') {
1490
1502
  const frameRef = await parentRuntime['push'](frame);
1491
1503
  if (!frameRef) {
@@ -1562,6 +1574,869 @@ function providePraxisSurfaceGlobalActions() {
1562
1574
  };
1563
1575
  }
1564
1576
 
1577
+ class PraxisQuickViewOverlayComponent {
1578
+ i18n = inject(PraxisI18nService, { optional: true });
1579
+ resolution = signal(null, ...(ngDevMode ? [{ debugName: "resolution" }] : /* istanbul ignore next */ []));
1580
+ bodyRenderer = signal(null, ...(ngDevMode ? [{ debugName: "bodyRenderer" }] : /* istanbul ignore next */ []));
1581
+ narrowModalMode = signal(false, ...(ngDevMode ? [{ debugName: "narrowModalMode" }] : /* istanbul ignore next */ []));
1582
+ failedAvatarUrl = signal(null, ...(ngDevMode ? [{ debugName: "failedAvatarUrl" }] : /* istanbul ignore next */ []));
1583
+ pointerEnter = new EventEmitter();
1584
+ pointerLeave = new EventEmitter();
1585
+ openDetail = new EventEmitter();
1586
+ copyValue = new EventEmitter();
1587
+ dismiss = new EventEmitter();
1588
+ dialogSurface;
1589
+ ctaButton;
1590
+ closeButton;
1591
+ summaryItems = computed(() => this.resolution()?.summaryItems ?? [], ...(ngDevMode ? [{ debugName: "summaryItems" }] : /* istanbul ignore next */ []));
1592
+ headerIdentity = computed(() => {
1593
+ const identity = this.resolution()?.identity ?? null;
1594
+ if (!identity) {
1595
+ return null;
1596
+ }
1597
+ if (this.shouldUseCustomBodyRenderer() || this.summaryItems().length > 0) {
1598
+ return {
1599
+ ...identity,
1600
+ metadata: [],
1601
+ };
1602
+ }
1603
+ return identity;
1604
+ }, ...(ngDevMode ? [{ debugName: "headerIdentity" }] : /* istanbul ignore next */ []));
1605
+ contextLabel = computed(() => {
1606
+ const res = this.resolution();
1607
+ const surfaceTitle = String(res?.surface?.title ?? '').trim();
1608
+ if (!surfaceTitle) {
1609
+ return null;
1610
+ }
1611
+ const mainTitle = String(res?.title ?? '').trim();
1612
+ return surfaceTitle.toLowerCase() === mainTitle.toLowerCase()
1613
+ ? null
1614
+ : surfaceTitle;
1615
+ }, ...(ngDevMode ? [{ debugName: "contextLabel" }] : /* istanbul ignore next */ []));
1616
+ hasContextEyebrow = computed(() => {
1617
+ const res = this.resolution();
1618
+ return Boolean((res?.icon && res.icon.trim().length > 0) || this.contextLabel());
1619
+ }, ...(ngDevMode ? [{ debugName: "hasContextEyebrow" }] : /* istanbul ignore next */ []));
1620
+ safeAvatarUrl = computed(() => {
1621
+ const res = this.resolution();
1622
+ const rawCandidate = res?.avatarUrl ??
1623
+ (typeof res?.identity?.avatar?.value === 'string'
1624
+ ? res.identity.avatar.value
1625
+ : null);
1626
+ if (typeof rawCandidate !== 'string') {
1627
+ return null;
1628
+ }
1629
+ const candidate = rawCandidate.trim();
1630
+ if (!candidate || this.failedAvatarUrl() === candidate) {
1631
+ return null;
1632
+ }
1633
+ if (candidate.startsWith('https://') ||
1634
+ candidate.startsWith('http://') ||
1635
+ (candidate.startsWith('/') && !candidate.startsWith('//'))) {
1636
+ return candidate;
1637
+ }
1638
+ return null;
1639
+ }, ...(ngDevMode ? [{ debugName: "safeAvatarUrl" }] : /* istanbul ignore next */ []));
1640
+ onAvatarError(failedUrl) {
1641
+ this.failedAvatarUrl.set(failedUrl);
1642
+ }
1643
+ closeAriaLabel = computed(() => this.translate('quickView.closeAriaLabel', 'Fechar visualização rápida'), ...(ngDevMode ? [{ debugName: "closeAriaLabel" }] : /* istanbul ignore next */ []));
1644
+ copyButtonLabel = computed(() => this.translate('quickView.copyAction', 'Copiar'), ...(ngDevMode ? [{ debugName: "copyButtonLabel" }] : /* istanbul ignore next */ []));
1645
+ emptyStateLabel = computed(() => this.translate('quickView.emptyAttributes', 'Nenhum atributo resumido está disponível para este registro.'), ...(ngDevMode ? [{ debugName: "emptyStateLabel" }] : /* istanbul ignore next */ []));
1646
+ unavailableStateLabel = computed(() => this.translate('quickView.unavailableContext', 'Este resumo não está disponível para o seu contexto atual.'), ...(ngDevMode ? [{ debugName: "unavailableStateLabel" }] : /* istanbul ignore next */ []));
1647
+ errorStateLabel = computed(() => this.translate('quickView.loadError', 'Não foi possível carregar o resumo deste registro.'), ...(ngDevMode ? [{ debugName: "errorStateLabel" }] : /* istanbul ignore next */ []));
1648
+ defaultCtaLabel = computed(() => this.translate('quickView.openDetail', 'Abrir detalhe'), ...(ngDevMode ? [{ debugName: "defaultCtaLabel" }] : /* istanbul ignore next */ []));
1649
+ maskedBadgeLabel = computed(() => this.translate('quickView.maskedBadge', 'LGPD'), ...(ngDevMode ? [{ debugName: "maskedBadgeLabel" }] : /* istanbul ignore next */ []));
1650
+ maskedFieldReasonLabel = computed(() => this.translate('quickView.maskedFieldReason', 'Dado protegido por política de governança / LGPD'), ...(ngDevMode ? [{ debugName: "maskedFieldReasonLabel" }] : /* istanbul ignore next */ []));
1651
+ accessibleLabel = computed(() => {
1652
+ const res = this.resolution();
1653
+ const identityTitle = String(res?.identity?.title?.value ?? res?.identity?.displayLabel ?? '').trim();
1654
+ return (identityTitle ||
1655
+ res?.title ||
1656
+ this.translate('quickView.dialogAriaLabel', 'Visualização rápida do registro'));
1657
+ }, ...(ngDevMode ? [{ debugName: "accessibleLabel" }] : /* istanbul ignore next */ []));
1658
+ translate(key, fallback) {
1659
+ if (!this.i18n) {
1660
+ return fallback;
1661
+ }
1662
+ const translated = this.i18n.t(key, undefined, fallback);
1663
+ return typeof translated === 'string' && translated.trim().length > 0
1664
+ ? translated
1665
+ : fallback;
1666
+ }
1667
+ shouldUseCustomBodyRenderer = computed(() => {
1668
+ const res = this.resolution();
1669
+ const renderer = this.bodyRenderer();
1670
+ return Boolean(res?.state === 'ready' && renderer && res.binding.contentRef);
1671
+ }, ...(ngDevMode ? [{ debugName: "shouldUseCustomBodyRenderer" }] : /* istanbul ignore next */ []));
1672
+ customBodyInputs = computed(() => {
1673
+ const res = this.resolution();
1674
+ const renderer = this.bodyRenderer();
1675
+ if (!res || !renderer) {
1676
+ return {};
1677
+ }
1678
+ return renderer.buildInputs({
1679
+ resolution: res,
1680
+ onOpenDetail: () => this.openDetail.emit(),
1681
+ onCopyValue: (value, field) => this.copyValue.emit({ value, field }),
1682
+ onDismiss: () => this.dismiss.emit('programmatic'),
1683
+ });
1684
+ }, ...(ngDevMode ? [{ debugName: "customBodyInputs" }] : /* istanbul ignore next */ []));
1685
+ focusInteractiveEntry() {
1686
+ const target = this.ctaButton?.nativeElement ??
1687
+ this.closeButton?.nativeElement ??
1688
+ this.dialogSurface?.nativeElement;
1689
+ if (target && typeof target.focus === 'function') {
1690
+ try {
1691
+ target.focus({ preventScroll: true });
1692
+ }
1693
+ catch {
1694
+ try {
1695
+ target.focus();
1696
+ }
1697
+ catch { }
1698
+ }
1699
+ }
1700
+ }
1701
+ isBadgeOrChip(item) {
1702
+ const presenter = item.presentation?.presenter;
1703
+ return presenter === 'badge' || presenter === 'chip';
1704
+ }
1705
+ onCopyItem(item) {
1706
+ if (!item.formattedValue || item.masked) {
1707
+ return;
1708
+ }
1709
+ this.copyValue.emit({
1710
+ value: item.formattedValue,
1711
+ field: item.field,
1712
+ });
1713
+ }
1714
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisQuickViewOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1715
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: PraxisQuickViewOverlayComponent, isStandalone: true, selector: "praxis-quick-view-overlay", outputs: { pointerEnter: "pointerEnter", pointerLeave: "pointerLeave", openDetail: "openDetail", copyValue: "copyValue", dismiss: "dismiss" }, viewQueries: [{ propertyName: "dialogSurface", first: true, predicate: ["dialogSurface"], descendants: true }, { propertyName: "ctaButton", first: true, predicate: ["ctaButton"], descendants: true }, { propertyName: "closeButton", first: true, predicate: ["closeButton"], descendants: true }], ngImport: i0, template: `
1716
+ <section
1717
+ #dialogSurface
1718
+ class="pdx-quick-view"
1719
+ [class.pdx-quick-view--narrow]="narrowModalMode()"
1720
+ role="dialog"
1721
+ [attr.aria-modal]="narrowModalMode() ? 'true' : null"
1722
+ [attr.aria-label]="accessibleLabel()"
1723
+ [attr.aria-busy]="resolution()?.state === 'loading' ? 'true' : null"
1724
+ [attr.data-quick-view-state]="resolution()?.state || 'idle'"
1725
+ tabindex="-1"
1726
+ (mouseenter)="pointerEnter.emit()"
1727
+ (mouseleave)="pointerLeave.emit()"
1728
+ >
1729
+ <header class="pdx-quick-view__header">
1730
+ @if (safeAvatarUrl(); as avatarSrc) {
1731
+ <div class="pdx-quick-view__avatar-wrap" data-testid="quick-view-avatar">
1732
+ <img
1733
+ class="pdx-quick-view__avatar-img"
1734
+ [src]="avatarSrc"
1735
+ alt=""
1736
+ loading="lazy"
1737
+ (error)="onAvatarError(avatarSrc)"
1738
+ />
1739
+ </div>
1740
+ }
1741
+ <div class="pdx-quick-view__heading">
1742
+ @if (hasContextEyebrow()) {
1743
+ <div class="pdx-quick-view__context" data-testid="quick-view-context">
1744
+ @if (resolution()?.icon; as iconName) {
1745
+ <span class="pdx-quick-view__context-icon-badge" aria-hidden="true">
1746
+ <mat-icon
1747
+ class="pdx-quick-view__context-icon"
1748
+ [praxisIcon]="iconName"
1749
+ ></mat-icon>
1750
+ </span>
1751
+ }
1752
+ @if (contextLabel(); as label) {
1753
+ <span class="pdx-quick-view__context-label">{{ label }}</span>
1754
+ }
1755
+ </div>
1756
+ }
1757
+ @if (headerIdentity(); as identity) {
1758
+ <praxis-resource-identity
1759
+ [identity]="identity"
1760
+ [emptyTitle]="resolution()?.title || ''"
1761
+ density="compact"
1762
+ [showMetadataLabels]="false"
1763
+ />
1764
+ } @else {
1765
+ <h2 class="pdx-quick-view__title">{{ resolution()?.title }}</h2>
1766
+ }
1767
+ @if (resolution()?.subtitle; as subtitle) {
1768
+ <p class="pdx-quick-view__subtitle">{{ subtitle }}</p>
1769
+ }
1770
+ </div>
1771
+ <button
1772
+ #closeButton
1773
+ type="button"
1774
+ class="pdx-quick-view__close"
1775
+ [attr.aria-label]="closeAriaLabel()"
1776
+ (click)="dismiss.emit('programmatic')"
1777
+ >
1778
+ ×
1779
+ </button>
1780
+ </header>
1781
+
1782
+ <div class="pdx-quick-view__body">
1783
+ @switch (resolution()?.state) {
1784
+ @case ('loading') {
1785
+ <div class="pdx-quick-view__skeleton" data-testid="quick-view-loading">
1786
+ <div class="pdx-quick-view__skeleton-line pdx-quick-view__skeleton-line--wide"></div>
1787
+ <div class="pdx-quick-view__skeleton-line"></div>
1788
+ <div class="pdx-quick-view__skeleton-line pdx-quick-view__skeleton-line--short"></div>
1789
+ </div>
1790
+ }
1791
+ @case ('ready') {
1792
+ @if (shouldUseCustomBodyRenderer()) {
1793
+ <ng-container
1794
+ *ngComponentOutlet="
1795
+ bodyRenderer()!.component;
1796
+ inputs: customBodyInputs()
1797
+ "
1798
+ />
1799
+ } @else {
1800
+ @if (summaryItems().length > 0) {
1801
+ <dl class="pdx-quick-view__summary-list" data-testid="quick-view-summary-list">
1802
+ @for (item of summaryItems(); track item.field) {
1803
+ <div class="pdx-quick-view__summary-item">
1804
+ <dt class="pdx-quick-view__summary-label">{{ item.label }}</dt>
1805
+ <dd class="pdx-quick-view__summary-value-wrap">
1806
+ <span
1807
+ class="pdx-quick-view__summary-value"
1808
+ [class.pdx-quick-view__summary-value--badge]="isBadgeOrChip(item)"
1809
+ [class.pdx-quick-view__summary-value--masked]="item.masked"
1810
+ [attr.title]="(item.masked ? (item.maskReason || maskedFieldReasonLabel()) : item.formattedValue) || null"
1811
+ >
1812
+ {{ item.formattedValue }}
1813
+ </span>
1814
+ @if (item.masked) {
1815
+ <span
1816
+ class="pdx-quick-view__masked-badge"
1817
+ data-testid="quick-view-masked-indicator"
1818
+ role="note"
1819
+ [attr.title]="item.maskReason || maskedFieldReasonLabel()"
1820
+ [attr.aria-label]="item.maskReason || maskedFieldReasonLabel()"
1821
+ >
1822
+ <svg
1823
+ class="pdx-quick-view__masked-icon"
1824
+ viewBox="0 0 16 16"
1825
+ fill="none"
1826
+ stroke="currentColor"
1827
+ stroke-width="1.5"
1828
+ aria-hidden="true"
1829
+ >
1830
+ <rect x="3.5" y="7" width="9" height="6.5" rx="1.5" />
1831
+ <path d="M5.5 7V5a2.5 2.5 0 0 1 5 0v2" />
1832
+ </svg>
1833
+ <span>{{ maskedBadgeLabel() }}</span>
1834
+ </span>
1835
+ }
1836
+ @if (item.copyable && !item.masked && item.formattedValue) {
1837
+ <button
1838
+ type="button"
1839
+ class="pdx-quick-view__copy-btn"
1840
+ [attr.aria-label]="copyButtonLabel() + ' ' + item.label"
1841
+ (click)="onCopyItem(item)"
1842
+ >
1843
+ {{ copyButtonLabel() }}
1844
+ </button>
1845
+ }
1846
+ </dd>
1847
+ </div>
1848
+ }
1849
+ </dl>
1850
+ }
1851
+ }
1852
+ }
1853
+ @case ('empty') {
1854
+ <p class="pdx-quick-view__feedback pdx-quick-view__feedback--empty" data-testid="quick-view-empty">
1855
+ {{ resolution()?.failureReason || emptyStateLabel() }}
1856
+ </p>
1857
+ }
1858
+ @case ('unavailable') {
1859
+ <p class="pdx-quick-view__feedback pdx-quick-view__feedback--unavailable" data-testid="quick-view-unavailable">
1860
+ {{ resolution()?.failureReason || unavailableStateLabel() }}
1861
+ </p>
1862
+ }
1863
+ @case ('error') {
1864
+ <p class="pdx-quick-view__feedback pdx-quick-view__feedback--error" data-testid="quick-view-error">
1865
+ {{ resolution()?.failureReason || errorStateLabel() }}
1866
+ </p>
1867
+ }
1868
+ }
1869
+ </div>
1870
+
1871
+ @if (resolution()?.state === 'ready' && resolution()?.ctaAvailable) {
1872
+ <footer class="pdx-quick-view__footer">
1873
+ <button
1874
+ #ctaButton
1875
+ type="button"
1876
+ class="pdx-quick-view__cta"
1877
+ data-testid="quick-view-open-detail"
1878
+ (click)="openDetail.emit()"
1879
+ >
1880
+ {{ resolution()?.ctaLabel || defaultCtaLabel() }}
1881
+ </button>
1882
+ </footer>
1883
+ }
1884
+ </section>
1885
+ `, isInline: true, styles: [":host{display:block;max-width:min(26rem,calc(100vw - 1.5rem));min-width:min(20rem,calc(100vw - 1.5rem));box-sizing:border-box}.pdx-quick-view{box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr);gap:.625rem;padding:.875rem 1rem;border-radius:var(--pdx-quick-view-radius, .75rem);background:var( --pdx-quick-view-bg, var(--md-sys-color-surface-container-high, var(--mat-sys-surface-container-high)) );color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface));border:1px solid color-mix(in srgb,var(--md-sys-color-outline, var(--mat-sys-outline)) 36%,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)));box-shadow:var( --pdx-quick-view-shadow, 0 18px 38px -6px color-mix(in srgb, var(--md-sys-color-shadow, #000000) 32%, transparent), 0 6px 16px -4px color-mix(in srgb, var(--md-sys-color-shadow, #000000) 18%, transparent) );outline:none;overflow:hidden}.pdx-quick-view--narrow{width:calc(100vw - 1.5rem);max-width:28rem;border-radius:var(--pdx-quick-view-narrow-radius, 1rem);padding:.75rem 1rem 1rem}.pdx-quick-view--narrow:before{content:\"\";display:block;width:2.25rem;height:.25rem;margin:0 auto .25rem;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant)) 32%,transparent)}.pdx-quick-view__header{display:flex;align-items:flex-start;justify-content:space-between;gap:.75rem;min-width:0;padding-bottom:.5rem;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 55%,transparent)}.pdx-quick-view__avatar-wrap{flex:0 0 auto;width:2.5rem;height:2.5rem;border-radius:999px;overflow:hidden;background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 12%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 60%,transparent);display:inline-flex;align-items:center;justify-content:center}.pdx-quick-view__avatar-img{width:100%;height:100%;object-fit:cover;display:block}.pdx-quick-view__heading{min-width:0;flex:1 1 auto;display:grid;gap:.25rem}.pdx-quick-view__context{display:inline-flex;align-items:center;gap:.375rem;min-width:0;margin-bottom:.0625rem}.pdx-quick-view__context-icon-badge{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border-radius:.3125rem;background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 14%,transparent);color:var(--md-sys-color-primary, var(--mat-sys-primary))}.pdx-quick-view__context-icon{width:.875rem;height:.875rem;font-size:.875rem;line-height:1}.pdx-quick-view__context-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.6875rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-primary, var(--mat-sys-primary))}.pdx-quick-view__title{margin:0;font-size:.9375rem;font-weight:600;line-height:1.35;color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface));overflow-wrap:anywhere}.pdx-quick-view__subtitle{margin:.25rem 0 0;font-size:.75rem;line-height:1.35;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant))}.pdx-quick-view__close{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border:none;border-radius:.375rem;background:transparent;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant));font-size:1.125rem;line-height:1;cursor:pointer;transition:background-color .14s ease,color .14s ease}.pdx-quick-view__close:hover{background:color-mix(in srgb,var(--md-sys-color-on-surface, var(--mat-sys-on-surface)) 8%,transparent);color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface))}.pdx-quick-view__close:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--mat-sys-primary));outline-offset:2px;background:color-mix(in srgb,var(--md-sys-color-on-surface, var(--mat-sys-on-surface)) 8%,transparent);color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface))}.pdx-quick-view__body{min-width:0}.pdx-quick-view__summary-list{margin:0;display:grid;grid-template-columns:minmax(0,1fr);gap:.4375rem;min-width:0}.pdx-quick-view__summary-item{display:flex;align-items:center;justify-content:space-between;gap:.625rem;min-width:0;font-size:.8125rem;line-height:1.35}.pdx-quick-view__summary-label{color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant));font-weight:500;flex:0 0 auto;max-width:42%;overflow-wrap:anywhere}.pdx-quick-view__summary-value-wrap{margin:0;flex:1 1 auto;display:inline-flex;align-items:center;justify-content:flex-end;gap:.375rem;min-width:0;text-align:right}.pdx-quick-view__summary-value{min-width:0;color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface));font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-quick-view__summary-value--badge{padding:.125rem .5rem;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 14%,transparent);color:var(--md-sys-color-primary, var(--mat-sys-primary));font-size:.75rem;font-weight:600}.pdx-quick-view__summary-value--masked{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;letter-spacing:.04em;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant))}.pdx-quick-view__masked-badge{display:inline-flex;align-items:center;gap:.25rem;flex:0 0 auto;padding:.0625rem .375rem;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-tertiary, var(--mat-sys-tertiary, #d97706)) 42%,transparent);background:color-mix(in srgb,var(--md-sys-color-tertiary, var(--mat-sys-tertiary, #d97706)) 12%,transparent);color:var(--md-sys-color-tertiary, var(--mat-sys-tertiary, #d97706));font-size:.6875rem;font-weight:600;line-height:1.2}.pdx-quick-view__masked-icon{width:.75rem;height:.75rem;flex:0 0 auto}.pdx-quick-view__copy-btn{flex:0 0 auto;white-space:nowrap;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 70%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container, var(--mat-sys-surface-container)) 65%,transparent);color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant));border-radius:.25rem;padding:.0625rem .375rem;font-size:.6875rem;font-weight:500;opacity:.78;cursor:pointer;transition:opacity .14s ease,background-color .14s ease,color .14s ease,border-color .14s ease}.pdx-quick-view__summary-item:hover .pdx-quick-view__copy-btn,.pdx-quick-view__copy-btn:focus-visible{opacity:1}.pdx-quick-view__copy-btn:hover{background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 10%,transparent);color:var(--md-sys-color-primary, var(--mat-sys-primary));border-color:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 40%,transparent)}.pdx-quick-view__copy-btn:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--mat-sys-primary));outline-offset:2px}.pdx-quick-view__feedback{margin:0;font-size:.8125rem;line-height:1.4;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant))}.pdx-quick-view__feedback--error{color:var(--md-sys-color-error, var(--mat-sys-error))}.pdx-quick-view__skeleton{display:grid;gap:.4375rem;padding:.125rem 0}.pdx-quick-view__skeleton-line{height:.75rem;border-radius:.25rem;background:color-mix(in srgb,var(--md-sys-color-on-surface, var(--mat-sys-on-surface)) 12%,transparent);width:75%}.pdx-quick-view__skeleton-line--wide{width:92%}.pdx-quick-view__skeleton-line--short{width:52%}.pdx-quick-view__footer{display:flex;justify-content:flex-end;padding-top:.5rem;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 65%,transparent)}.pdx-quick-view__cta{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;padding:.375rem .8125rem;border-radius:.375rem;border:none;background:var(--md-sys-color-primary, var(--mat-sys-primary));color:var(--md-sys-color-on-primary, var(--mat-sys-on-primary));font-size:.8125rem;font-weight:600;cursor:pointer;transition:filter .14s ease,box-shadow .14s ease}.pdx-quick-view__cta:hover{filter:brightness(1.06)}.pdx-quick-view__cta:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--mat-sys-primary));outline-offset:2px}.pdx-quick-view--narrow .pdx-quick-view__cta{width:100%;padding:.5rem .875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.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: PraxisResourceIdentityComponent, selector: "praxis-resource-identity", inputs: ["identity", "emptyTitle", "density", "showMetadataLabels", "showKey", "showKeyLabel", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1886
+ }
1887
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisQuickViewOverlayComponent, decorators: [{
1888
+ type: Component,
1889
+ args: [{ selector: 'praxis-quick-view-overlay', standalone: true, imports: [
1890
+ CommonModule,
1891
+ MatIconModule,
1892
+ PraxisIconDirective,
1893
+ PraxisResourceIdentityComponent,
1894
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: `
1895
+ <section
1896
+ #dialogSurface
1897
+ class="pdx-quick-view"
1898
+ [class.pdx-quick-view--narrow]="narrowModalMode()"
1899
+ role="dialog"
1900
+ [attr.aria-modal]="narrowModalMode() ? 'true' : null"
1901
+ [attr.aria-label]="accessibleLabel()"
1902
+ [attr.aria-busy]="resolution()?.state === 'loading' ? 'true' : null"
1903
+ [attr.data-quick-view-state]="resolution()?.state || 'idle'"
1904
+ tabindex="-1"
1905
+ (mouseenter)="pointerEnter.emit()"
1906
+ (mouseleave)="pointerLeave.emit()"
1907
+ >
1908
+ <header class="pdx-quick-view__header">
1909
+ @if (safeAvatarUrl(); as avatarSrc) {
1910
+ <div class="pdx-quick-view__avatar-wrap" data-testid="quick-view-avatar">
1911
+ <img
1912
+ class="pdx-quick-view__avatar-img"
1913
+ [src]="avatarSrc"
1914
+ alt=""
1915
+ loading="lazy"
1916
+ (error)="onAvatarError(avatarSrc)"
1917
+ />
1918
+ </div>
1919
+ }
1920
+ <div class="pdx-quick-view__heading">
1921
+ @if (hasContextEyebrow()) {
1922
+ <div class="pdx-quick-view__context" data-testid="quick-view-context">
1923
+ @if (resolution()?.icon; as iconName) {
1924
+ <span class="pdx-quick-view__context-icon-badge" aria-hidden="true">
1925
+ <mat-icon
1926
+ class="pdx-quick-view__context-icon"
1927
+ [praxisIcon]="iconName"
1928
+ ></mat-icon>
1929
+ </span>
1930
+ }
1931
+ @if (contextLabel(); as label) {
1932
+ <span class="pdx-quick-view__context-label">{{ label }}</span>
1933
+ }
1934
+ </div>
1935
+ }
1936
+ @if (headerIdentity(); as identity) {
1937
+ <praxis-resource-identity
1938
+ [identity]="identity"
1939
+ [emptyTitle]="resolution()?.title || ''"
1940
+ density="compact"
1941
+ [showMetadataLabels]="false"
1942
+ />
1943
+ } @else {
1944
+ <h2 class="pdx-quick-view__title">{{ resolution()?.title }}</h2>
1945
+ }
1946
+ @if (resolution()?.subtitle; as subtitle) {
1947
+ <p class="pdx-quick-view__subtitle">{{ subtitle }}</p>
1948
+ }
1949
+ </div>
1950
+ <button
1951
+ #closeButton
1952
+ type="button"
1953
+ class="pdx-quick-view__close"
1954
+ [attr.aria-label]="closeAriaLabel()"
1955
+ (click)="dismiss.emit('programmatic')"
1956
+ >
1957
+ ×
1958
+ </button>
1959
+ </header>
1960
+
1961
+ <div class="pdx-quick-view__body">
1962
+ @switch (resolution()?.state) {
1963
+ @case ('loading') {
1964
+ <div class="pdx-quick-view__skeleton" data-testid="quick-view-loading">
1965
+ <div class="pdx-quick-view__skeleton-line pdx-quick-view__skeleton-line--wide"></div>
1966
+ <div class="pdx-quick-view__skeleton-line"></div>
1967
+ <div class="pdx-quick-view__skeleton-line pdx-quick-view__skeleton-line--short"></div>
1968
+ </div>
1969
+ }
1970
+ @case ('ready') {
1971
+ @if (shouldUseCustomBodyRenderer()) {
1972
+ <ng-container
1973
+ *ngComponentOutlet="
1974
+ bodyRenderer()!.component;
1975
+ inputs: customBodyInputs()
1976
+ "
1977
+ />
1978
+ } @else {
1979
+ @if (summaryItems().length > 0) {
1980
+ <dl class="pdx-quick-view__summary-list" data-testid="quick-view-summary-list">
1981
+ @for (item of summaryItems(); track item.field) {
1982
+ <div class="pdx-quick-view__summary-item">
1983
+ <dt class="pdx-quick-view__summary-label">{{ item.label }}</dt>
1984
+ <dd class="pdx-quick-view__summary-value-wrap">
1985
+ <span
1986
+ class="pdx-quick-view__summary-value"
1987
+ [class.pdx-quick-view__summary-value--badge]="isBadgeOrChip(item)"
1988
+ [class.pdx-quick-view__summary-value--masked]="item.masked"
1989
+ [attr.title]="(item.masked ? (item.maskReason || maskedFieldReasonLabel()) : item.formattedValue) || null"
1990
+ >
1991
+ {{ item.formattedValue }}
1992
+ </span>
1993
+ @if (item.masked) {
1994
+ <span
1995
+ class="pdx-quick-view__masked-badge"
1996
+ data-testid="quick-view-masked-indicator"
1997
+ role="note"
1998
+ [attr.title]="item.maskReason || maskedFieldReasonLabel()"
1999
+ [attr.aria-label]="item.maskReason || maskedFieldReasonLabel()"
2000
+ >
2001
+ <svg
2002
+ class="pdx-quick-view__masked-icon"
2003
+ viewBox="0 0 16 16"
2004
+ fill="none"
2005
+ stroke="currentColor"
2006
+ stroke-width="1.5"
2007
+ aria-hidden="true"
2008
+ >
2009
+ <rect x="3.5" y="7" width="9" height="6.5" rx="1.5" />
2010
+ <path d="M5.5 7V5a2.5 2.5 0 0 1 5 0v2" />
2011
+ </svg>
2012
+ <span>{{ maskedBadgeLabel() }}</span>
2013
+ </span>
2014
+ }
2015
+ @if (item.copyable && !item.masked && item.formattedValue) {
2016
+ <button
2017
+ type="button"
2018
+ class="pdx-quick-view__copy-btn"
2019
+ [attr.aria-label]="copyButtonLabel() + ' ' + item.label"
2020
+ (click)="onCopyItem(item)"
2021
+ >
2022
+ {{ copyButtonLabel() }}
2023
+ </button>
2024
+ }
2025
+ </dd>
2026
+ </div>
2027
+ }
2028
+ </dl>
2029
+ }
2030
+ }
2031
+ }
2032
+ @case ('empty') {
2033
+ <p class="pdx-quick-view__feedback pdx-quick-view__feedback--empty" data-testid="quick-view-empty">
2034
+ {{ resolution()?.failureReason || emptyStateLabel() }}
2035
+ </p>
2036
+ }
2037
+ @case ('unavailable') {
2038
+ <p class="pdx-quick-view__feedback pdx-quick-view__feedback--unavailable" data-testid="quick-view-unavailable">
2039
+ {{ resolution()?.failureReason || unavailableStateLabel() }}
2040
+ </p>
2041
+ }
2042
+ @case ('error') {
2043
+ <p class="pdx-quick-view__feedback pdx-quick-view__feedback--error" data-testid="quick-view-error">
2044
+ {{ resolution()?.failureReason || errorStateLabel() }}
2045
+ </p>
2046
+ }
2047
+ }
2048
+ </div>
2049
+
2050
+ @if (resolution()?.state === 'ready' && resolution()?.ctaAvailable) {
2051
+ <footer class="pdx-quick-view__footer">
2052
+ <button
2053
+ #ctaButton
2054
+ type="button"
2055
+ class="pdx-quick-view__cta"
2056
+ data-testid="quick-view-open-detail"
2057
+ (click)="openDetail.emit()"
2058
+ >
2059
+ {{ resolution()?.ctaLabel || defaultCtaLabel() }}
2060
+ </button>
2061
+ </footer>
2062
+ }
2063
+ </section>
2064
+ `, styles: [":host{display:block;max-width:min(26rem,calc(100vw - 1.5rem));min-width:min(20rem,calc(100vw - 1.5rem));box-sizing:border-box}.pdx-quick-view{box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr);gap:.625rem;padding:.875rem 1rem;border-radius:var(--pdx-quick-view-radius, .75rem);background:var( --pdx-quick-view-bg, var(--md-sys-color-surface-container-high, var(--mat-sys-surface-container-high)) );color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface));border:1px solid color-mix(in srgb,var(--md-sys-color-outline, var(--mat-sys-outline)) 36%,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)));box-shadow:var( --pdx-quick-view-shadow, 0 18px 38px -6px color-mix(in srgb, var(--md-sys-color-shadow, #000000) 32%, transparent), 0 6px 16px -4px color-mix(in srgb, var(--md-sys-color-shadow, #000000) 18%, transparent) );outline:none;overflow:hidden}.pdx-quick-view--narrow{width:calc(100vw - 1.5rem);max-width:28rem;border-radius:var(--pdx-quick-view-narrow-radius, 1rem);padding:.75rem 1rem 1rem}.pdx-quick-view--narrow:before{content:\"\";display:block;width:2.25rem;height:.25rem;margin:0 auto .25rem;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant)) 32%,transparent)}.pdx-quick-view__header{display:flex;align-items:flex-start;justify-content:space-between;gap:.75rem;min-width:0;padding-bottom:.5rem;border-bottom:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 55%,transparent)}.pdx-quick-view__avatar-wrap{flex:0 0 auto;width:2.5rem;height:2.5rem;border-radius:999px;overflow:hidden;background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 12%,transparent);border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 60%,transparent);display:inline-flex;align-items:center;justify-content:center}.pdx-quick-view__avatar-img{width:100%;height:100%;object-fit:cover;display:block}.pdx-quick-view__heading{min-width:0;flex:1 1 auto;display:grid;gap:.25rem}.pdx-quick-view__context{display:inline-flex;align-items:center;gap:.375rem;min-width:0;margin-bottom:.0625rem}.pdx-quick-view__context-icon-badge{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border-radius:.3125rem;background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 14%,transparent);color:var(--md-sys-color-primary, var(--mat-sys-primary))}.pdx-quick-view__context-icon{width:.875rem;height:.875rem;font-size:.875rem;line-height:1}.pdx-quick-view__context-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.6875rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--md-sys-color-primary, var(--mat-sys-primary))}.pdx-quick-view__title{margin:0;font-size:.9375rem;font-weight:600;line-height:1.35;color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface));overflow-wrap:anywhere}.pdx-quick-view__subtitle{margin:.25rem 0 0;font-size:.75rem;line-height:1.35;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant))}.pdx-quick-view__close{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border:none;border-radius:.375rem;background:transparent;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant));font-size:1.125rem;line-height:1;cursor:pointer;transition:background-color .14s ease,color .14s ease}.pdx-quick-view__close:hover{background:color-mix(in srgb,var(--md-sys-color-on-surface, var(--mat-sys-on-surface)) 8%,transparent);color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface))}.pdx-quick-view__close:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--mat-sys-primary));outline-offset:2px;background:color-mix(in srgb,var(--md-sys-color-on-surface, var(--mat-sys-on-surface)) 8%,transparent);color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface))}.pdx-quick-view__body{min-width:0}.pdx-quick-view__summary-list{margin:0;display:grid;grid-template-columns:minmax(0,1fr);gap:.4375rem;min-width:0}.pdx-quick-view__summary-item{display:flex;align-items:center;justify-content:space-between;gap:.625rem;min-width:0;font-size:.8125rem;line-height:1.35}.pdx-quick-view__summary-label{color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant));font-weight:500;flex:0 0 auto;max-width:42%;overflow-wrap:anywhere}.pdx-quick-view__summary-value-wrap{margin:0;flex:1 1 auto;display:inline-flex;align-items:center;justify-content:flex-end;gap:.375rem;min-width:0;text-align:right}.pdx-quick-view__summary-value{min-width:0;color:var(--md-sys-color-on-surface, var(--mat-sys-on-surface));font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pdx-quick-view__summary-value--badge{padding:.125rem .5rem;border-radius:999px;background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 14%,transparent);color:var(--md-sys-color-primary, var(--mat-sys-primary));font-size:.75rem;font-weight:600}.pdx-quick-view__summary-value--masked{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;letter-spacing:.04em;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant))}.pdx-quick-view__masked-badge{display:inline-flex;align-items:center;gap:.25rem;flex:0 0 auto;padding:.0625rem .375rem;border-radius:999px;border:1px solid color-mix(in srgb,var(--md-sys-color-tertiary, var(--mat-sys-tertiary, #d97706)) 42%,transparent);background:color-mix(in srgb,var(--md-sys-color-tertiary, var(--mat-sys-tertiary, #d97706)) 12%,transparent);color:var(--md-sys-color-tertiary, var(--mat-sys-tertiary, #d97706));font-size:.6875rem;font-weight:600;line-height:1.2}.pdx-quick-view__masked-icon{width:.75rem;height:.75rem;flex:0 0 auto}.pdx-quick-view__copy-btn{flex:0 0 auto;white-space:nowrap;border:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 70%,transparent);background:color-mix(in srgb,var(--md-sys-color-surface-container, var(--mat-sys-surface-container)) 65%,transparent);color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant));border-radius:.25rem;padding:.0625rem .375rem;font-size:.6875rem;font-weight:500;opacity:.78;cursor:pointer;transition:opacity .14s ease,background-color .14s ease,color .14s ease,border-color .14s ease}.pdx-quick-view__summary-item:hover .pdx-quick-view__copy-btn,.pdx-quick-view__copy-btn:focus-visible{opacity:1}.pdx-quick-view__copy-btn:hover{background:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 10%,transparent);color:var(--md-sys-color-primary, var(--mat-sys-primary));border-color:color-mix(in srgb,var(--md-sys-color-primary, var(--mat-sys-primary)) 40%,transparent)}.pdx-quick-view__copy-btn:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--mat-sys-primary));outline-offset:2px}.pdx-quick-view__feedback{margin:0;font-size:.8125rem;line-height:1.4;color:var(--md-sys-color-on-surface-variant, var(--mat-sys-on-surface-variant))}.pdx-quick-view__feedback--error{color:var(--md-sys-color-error, var(--mat-sys-error))}.pdx-quick-view__skeleton{display:grid;gap:.4375rem;padding:.125rem 0}.pdx-quick-view__skeleton-line{height:.75rem;border-radius:.25rem;background:color-mix(in srgb,var(--md-sys-color-on-surface, var(--mat-sys-on-surface)) 12%,transparent);width:75%}.pdx-quick-view__skeleton-line--wide{width:92%}.pdx-quick-view__skeleton-line--short{width:52%}.pdx-quick-view__footer{display:flex;justify-content:flex-end;padding-top:.5rem;border-top:1px solid color-mix(in srgb,var(--md-sys-color-outline-variant, var(--mat-sys-outline-variant)) 65%,transparent)}.pdx-quick-view__cta{display:inline-flex;align-items:center;justify-content:center;gap:.375rem;padding:.375rem .8125rem;border-radius:.375rem;border:none;background:var(--md-sys-color-primary, var(--mat-sys-primary));color:var(--md-sys-color-on-primary, var(--mat-sys-on-primary));font-size:.8125rem;font-weight:600;cursor:pointer;transition:filter .14s ease,box-shadow .14s ease}.pdx-quick-view__cta:hover{filter:brightness(1.06)}.pdx-quick-view__cta:focus-visible{outline:2px solid var(--md-sys-color-primary, var(--mat-sys-primary));outline-offset:2px}.pdx-quick-view--narrow .pdx-quick-view__cta{width:100%;padding:.5rem .875rem}\n"] }]
2065
+ }], propDecorators: { pointerEnter: [{
2066
+ type: Output
2067
+ }], pointerLeave: [{
2068
+ type: Output
2069
+ }], openDetail: [{
2070
+ type: Output
2071
+ }], copyValue: [{
2072
+ type: Output
2073
+ }], dismiss: [{
2074
+ type: Output
2075
+ }], dialogSurface: [{
2076
+ type: ViewChild,
2077
+ args: ['dialogSurface']
2078
+ }], ctaButton: [{
2079
+ type: ViewChild,
2080
+ args: ['ctaButton']
2081
+ }], closeButton: [{
2082
+ type: ViewChild,
2083
+ args: ['closeButton']
2084
+ }] } });
2085
+
2086
+ const QUICK_VIEW_CONNECTED_POSITIONS = [
2087
+ {
2088
+ originX: 'start',
2089
+ originY: 'bottom',
2090
+ overlayX: 'start',
2091
+ overlayY: 'top',
2092
+ offsetY: 4,
2093
+ },
2094
+ {
2095
+ originX: 'end',
2096
+ originY: 'bottom',
2097
+ overlayX: 'end',
2098
+ overlayY: 'top',
2099
+ offsetY: 4,
2100
+ },
2101
+ {
2102
+ originX: 'start',
2103
+ originY: 'top',
2104
+ overlayX: 'start',
2105
+ overlayY: 'bottom',
2106
+ offsetY: -4,
2107
+ },
2108
+ {
2109
+ originX: 'end',
2110
+ originY: 'top',
2111
+ overlayX: 'end',
2112
+ overlayY: 'bottom',
2113
+ offsetY: -4,
2114
+ },
2115
+ {
2116
+ originX: 'end',
2117
+ originY: 'center',
2118
+ overlayX: 'start',
2119
+ overlayY: 'center',
2120
+ offsetX: 6,
2121
+ },
2122
+ {
2123
+ originX: 'start',
2124
+ originY: 'center',
2125
+ overlayX: 'end',
2126
+ overlayY: 'center',
2127
+ offsetX: -6,
2128
+ },
2129
+ ];
2130
+ /**
2131
+ * Apresentador conectado não-modal para Quick View em `@praxisui/dialog`.
2132
+ *
2133
+ * Regras arquiteturais:
2134
+ * - Em desktop (`hover`, `focus-shortcut`, `explicit-button`), utiliza `flexibleConnectedTo`
2135
+ * sem `aria-modal="true"` e sem trap global de foco;
2136
+ * - Em `narrow-tap` (ou viewport compacta <= 640px sob ativação explícita), utiliza folha compacta
2137
+ * inferior com backdrop e semântica modal real;
2138
+ * - Reposiciona em scroll/resize enquanto a âncora permanecer válida e fecha imediatamente
2139
+ * quando a âncora sai do DOM ou se torna inválida;
2140
+ * - Restaura o foco ao gatilho original quando o usuário fecha por `Escape` ou botão Fechar
2141
+ * estando com o foco dentro do card.
2142
+ */
2143
+ class QuickViewDialogPresenterService {
2144
+ overlay = inject(Overlay);
2145
+ injector = inject(Injector);
2146
+ layerScale = inject(PraxisLayerScaleStyleService);
2147
+ activeSession = null;
2148
+ present(options) {
2149
+ this.closeAll();
2150
+ this.layerScale.ensureInstalled();
2151
+ const narrowModalMode = this.shouldUseNarrowModalFallback(options);
2152
+ const overlayRef = this.overlay.create(this.buildOverlayConfig(options.anchor, narrowModalMode));
2153
+ const portal = new ComponentPortal(PraxisQuickViewOverlayComponent, null, this.injector);
2154
+ const compRef = overlayRef.attach(portal);
2155
+ compRef.instance.narrowModalMode.set(narrowModalMode);
2156
+ compRef.instance.bodyRenderer.set(options.bodyRenderer ?? null);
2157
+ compRef.instance.resolution.set(options.resolution);
2158
+ try {
2159
+ compRef.changeDetectorRef.detectChanges();
2160
+ }
2161
+ catch { }
2162
+ overlayRef.updatePosition();
2163
+ const session = new ActiveOverlaySession(overlayRef, compRef, options, narrowModalMode, (anchor) => this.resolveConnectedOrigin(anchor), () => {
2164
+ if (this.activeSession === session) {
2165
+ this.activeSession = null;
2166
+ }
2167
+ });
2168
+ this.activeSession = session;
2169
+ if (narrowModalMode ||
2170
+ options.trigger === 'explicit-button' ||
2171
+ options.trigger === 'focus-shortcut' ||
2172
+ options.trigger === 'narrow-tap') {
2173
+ queueMicrotask(() => {
2174
+ compRef.instance.focusInteractiveEntry();
2175
+ });
2176
+ }
2177
+ return session;
2178
+ }
2179
+ closeAll() {
2180
+ if (this.activeSession) {
2181
+ const current = this.activeSession;
2182
+ this.activeSession = null;
2183
+ current.close('programmatic');
2184
+ }
2185
+ }
2186
+ shouldUseNarrowModalFallback(options) {
2187
+ if (options.trigger === 'narrow-tap') {
2188
+ return true;
2189
+ }
2190
+ if (options.trigger === 'hover') {
2191
+ return false;
2192
+ }
2193
+ const width = typeof window !== 'undefined' && Number.isFinite(window.innerWidth)
2194
+ ? window.innerWidth
2195
+ : 1280;
2196
+ return (width <= 640 &&
2197
+ (options.trigger === 'explicit-button' ||
2198
+ options.trigger === 'focus-shortcut'));
2199
+ }
2200
+ buildOverlayConfig(anchor, narrowModalMode) {
2201
+ if (narrowModalMode) {
2202
+ const positionStrategy = this.overlay
2203
+ .position()
2204
+ .global()
2205
+ .centerHorizontally()
2206
+ .bottom('12px');
2207
+ return new OverlayConfig({
2208
+ hasBackdrop: true,
2209
+ panelClass: ['pdx-quick-view-overlay-pane', 'pdx-quick-view-overlay-pane--narrow'],
2210
+ backdropClass: 'pdx-quick-view-backdrop',
2211
+ positionStrategy,
2212
+ scrollStrategy: this.overlay.scrollStrategies.block(),
2213
+ });
2214
+ }
2215
+ const origin = this.resolveConnectedOrigin(anchor);
2216
+ const positionStrategy = this.overlay
2217
+ .position()
2218
+ .flexibleConnectedTo(origin)
2219
+ .withPositions(QUICK_VIEW_CONNECTED_POSITIONS)
2220
+ .withViewportMargin(12)
2221
+ .withPush(true)
2222
+ .withFlexibleDimensions(false);
2223
+ return new OverlayConfig({
2224
+ hasBackdrop: false,
2225
+ panelClass: 'pdx-quick-view-overlay-pane',
2226
+ positionStrategy,
2227
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
2228
+ });
2229
+ }
2230
+ resolveConnectedOrigin(anchor) {
2231
+ if (anchor.kind === 'element') {
2232
+ return anchor.element;
2233
+ }
2234
+ const rect = anchor.getViewportRect() ?? {
2235
+ x: 0,
2236
+ y: 0,
2237
+ width: 0,
2238
+ height: 0,
2239
+ };
2240
+ return {
2241
+ x: rect.x,
2242
+ y: rect.y,
2243
+ width: rect.width,
2244
+ height: rect.height,
2245
+ };
2246
+ }
2247
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: QuickViewDialogPresenterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2248
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: QuickViewDialogPresenterService, providedIn: 'root' });
2249
+ }
2250
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: QuickViewDialogPresenterService, decorators: [{
2251
+ type: Injectable,
2252
+ args: [{ providedIn: 'root' }]
2253
+ }] });
2254
+ class ActiveOverlaySession {
2255
+ overlayRef;
2256
+ compRef;
2257
+ options;
2258
+ narrowModalMode;
2259
+ resolveOrigin;
2260
+ onDisposed;
2261
+ closedSubject = new Subject();
2262
+ pointerEnterSubject = new Subject();
2263
+ pointerLeaveSubject = new Subject();
2264
+ subs = [];
2265
+ cleanupDomListeners = [];
2266
+ isClosed = false;
2267
+ closed$ = this.closedSubject.asObservable();
2268
+ pointerEnteredCard$ = this.pointerEnterSubject.asObservable();
2269
+ pointerLeftCard$ = this.pointerLeaveSubject.asObservable();
2270
+ constructor(overlayRef, compRef, options, narrowModalMode, resolveOrigin, onDisposed) {
2271
+ this.overlayRef = overlayRef;
2272
+ this.compRef = compRef;
2273
+ this.options = options;
2274
+ this.narrowModalMode = narrowModalMode;
2275
+ this.resolveOrigin = resolveOrigin;
2276
+ this.onDisposed = onDisposed;
2277
+ const inst = compRef.instance;
2278
+ this.subs.push(inst.pointerEnter.subscribe(() => this.pointerEnterSubject.next()), inst.pointerLeave.subscribe(() => this.pointerLeaveSubject.next()), inst.openDetail.subscribe(() => this.options.onOpenDetail()), inst.copyValue.subscribe(({ value, field }) => this.options.onCopyValue?.(value, field)), inst.dismiss.subscribe((reason) => this.close(reason)));
2279
+ if (narrowModalMode) {
2280
+ this.subs.push(overlayRef.backdropClick().subscribe(() => {
2281
+ this.close('outside-pointer');
2282
+ }));
2283
+ }
2284
+ this.installDomListeners();
2285
+ }
2286
+ update(resolution) {
2287
+ if (this.isClosed) {
2288
+ return;
2289
+ }
2290
+ const previousState = this.compRef.instance.resolution()?.state;
2291
+ const focusWasInside = this.wasFocusInsideOverlay();
2292
+ this.compRef.instance.resolution.set(resolution);
2293
+ try {
2294
+ this.compRef.changeDetectorRef.detectChanges();
2295
+ }
2296
+ catch { }
2297
+ this.updatePosition();
2298
+ if (previousState === 'loading' &&
2299
+ resolution.state === 'ready' &&
2300
+ (focusWasInside ||
2301
+ this.narrowModalMode ||
2302
+ this.options.trigger === 'explicit-button' ||
2303
+ this.options.trigger === 'focus-shortcut' ||
2304
+ this.options.trigger === 'narrow-tap')) {
2305
+ queueMicrotask(() => {
2306
+ if (!this.isClosed) {
2307
+ this.compRef.instance.focusInteractiveEntry();
2308
+ }
2309
+ });
2310
+ }
2311
+ }
2312
+ updatePosition() {
2313
+ if (this.isClosed) {
2314
+ return;
2315
+ }
2316
+ if (!isResourceQuickViewAnchorValid(this.options.anchor)) {
2317
+ this.close('anchor-invalid');
2318
+ return;
2319
+ }
2320
+ if (!this.narrowModalMode && this.options.anchor.kind === 'virtual-rect') {
2321
+ const strategy = this.overlayRef.getConfig().positionStrategy;
2322
+ strategy?.setOrigin?.(this.resolveOrigin(this.options.anchor));
2323
+ }
2324
+ this.overlayRef.updatePosition();
2325
+ }
2326
+ close(reason = 'programmatic') {
2327
+ if (this.isClosed) {
2328
+ return;
2329
+ }
2330
+ this.isClosed = true;
2331
+ const focusInside = this.wasFocusInsideOverlay();
2332
+ const isInteractiveTrigger = this.narrowModalMode ||
2333
+ this.options.trigger === 'explicit-button' ||
2334
+ this.options.trigger === 'focus-shortcut' ||
2335
+ this.options.trigger === 'narrow-tap';
2336
+ const shouldRestoreFocus = focusInside ||
2337
+ (isInteractiveTrigger &&
2338
+ (reason === 'escape' ||
2339
+ reason === 'programmatic' ||
2340
+ this.narrowModalMode));
2341
+ for (const cleanup of this.cleanupDomListeners) {
2342
+ cleanup();
2343
+ }
2344
+ this.cleanupDomListeners.length = 0;
2345
+ for (const sub of this.subs) {
2346
+ sub.unsubscribe();
2347
+ }
2348
+ this.subs.length = 0;
2349
+ try {
2350
+ this.overlayRef.dispose();
2351
+ }
2352
+ catch { }
2353
+ if (shouldRestoreFocus && reason !== 'cta') {
2354
+ this.restoreFocusToOrigin();
2355
+ }
2356
+ this.closedSubject.next(reason);
2357
+ this.closedSubject.complete();
2358
+ this.pointerEnterSubject.complete();
2359
+ this.pointerLeaveSubject.complete();
2360
+ this.onDisposed();
2361
+ this.options.onDismiss(reason);
2362
+ }
2363
+ installDomListeners() {
2364
+ if (typeof document !== 'undefined') {
2365
+ const onKeydown = (event) => {
2366
+ if (event.key === 'Escape') {
2367
+ event.preventDefault();
2368
+ event.stopPropagation();
2369
+ event.stopImmediatePropagation();
2370
+ this.close('escape');
2371
+ }
2372
+ };
2373
+ document.addEventListener('keydown', onKeydown, true);
2374
+ this.cleanupDomListeners.push(() => document.removeEventListener('keydown', onKeydown, true));
2375
+ if (!this.narrowModalMode) {
2376
+ const onPointerDown = (event) => {
2377
+ const target = event.target;
2378
+ if (!target) {
2379
+ return;
2380
+ }
2381
+ if (this.overlayRef.overlayElement?.contains(target)) {
2382
+ return;
2383
+ }
2384
+ const anchorEl = this.options.anchor.kind === 'element'
2385
+ ? this.options.anchor.element
2386
+ : this.options.anchor.hostElement;
2387
+ if (anchorEl && anchorEl.contains(target)) {
2388
+ return;
2389
+ }
2390
+ this.close('outside-pointer');
2391
+ };
2392
+ document.addEventListener('pointerdown', onPointerDown, true);
2393
+ this.cleanupDomListeners.push(() => document.removeEventListener('pointerdown', onPointerDown, true));
2394
+ }
2395
+ }
2396
+ if (typeof window !== 'undefined') {
2397
+ const onViewportChange = () => {
2398
+ this.updatePosition();
2399
+ };
2400
+ window.addEventListener('scroll', onViewportChange, true);
2401
+ window.addEventListener('resize', onViewportChange, { passive: true });
2402
+ this.cleanupDomListeners.push(() => {
2403
+ window.removeEventListener('scroll', onViewportChange, true);
2404
+ window.removeEventListener('resize', onViewportChange);
2405
+ });
2406
+ }
2407
+ }
2408
+ wasFocusInsideOverlay() {
2409
+ if (typeof document === 'undefined' || !document.activeElement) {
2410
+ return false;
2411
+ }
2412
+ return Boolean(this.overlayRef.overlayElement?.contains(document.activeElement));
2413
+ }
2414
+ restoreFocusToOrigin() {
2415
+ const anchor = this.options.anchor;
2416
+ const candidate = anchor.focusOrigin ??
2417
+ (anchor.kind === 'element' ? anchor.element : anchor.hostElement);
2418
+ if (candidate &&
2419
+ candidate.isConnected !== false &&
2420
+ typeof candidate.focus === 'function') {
2421
+ try {
2422
+ candidate.focus({ preventScroll: true });
2423
+ }
2424
+ catch {
2425
+ try {
2426
+ candidate.focus();
2427
+ }
2428
+ catch { }
2429
+ }
2430
+ }
2431
+ }
2432
+ }
2433
+ function providePraxisQuickViewDialogPresenter() {
2434
+ return {
2435
+ provide: PRAXIS_QUICK_VIEW_PRESENTER,
2436
+ useExisting: QuickViewDialogPresenterService,
2437
+ };
2438
+ }
2439
+
1565
2440
  class LongContentDialogExampleComponent {
1566
2441
  items = Array.from({ length: 40 }, (_, idx) => `Example line ${idx + 1}`);
1567
2442
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: LongContentDialogExampleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -2028,4 +2903,4 @@ const PRAXIS_DIALOG_AUTHORING_MANIFEST = {
2028
2903
  * Generated bundle index. Do not edit.
2029
2904
  */
2030
2905
 
2031
- export { LongContentDialogExampleComponent, PRAXIS_DIALOG_AUTHORING_MANIFEST, PRAXIS_DIALOG_COMPONENT_METADATA, PRAXIS_DIALOG_CONTENT_REGISTRY, PRAXIS_DIALOG_DATA, PRAXIS_DIALOG_DEFAULTS, PRAXIS_DIALOG_EXAMPLE_LONG_CONTENT, PRAXIS_DIALOG_GLOBAL_PRESETS, PRAXIS_DIALOG_I18N, PRAXIS_DIALOG_TEMPLATE_REGISTRY, PraxisDialog, PraxisDialogActionsDirective, PraxisDialogComponent, PraxisDialogContentDirective, PraxisDialogDirectives, PraxisDialogRef, PraxisDialogTitleDirective, provideDialogGlobalPresetsFromGlobalConfig, providePraxisDialogExamples, providePraxisDialogGlobalActions, providePraxisDialogMetadata, providePraxisSurfaceGlobalActions };
2906
+ export { LongContentDialogExampleComponent, PRAXIS_DIALOG_AUTHORING_MANIFEST, PRAXIS_DIALOG_COMPONENT_METADATA, PRAXIS_DIALOG_CONTENT_REGISTRY, PRAXIS_DIALOG_DATA, PRAXIS_DIALOG_DEFAULTS, PRAXIS_DIALOG_EXAMPLE_LONG_CONTENT, PRAXIS_DIALOG_GLOBAL_PRESETS, PRAXIS_DIALOG_I18N, PRAXIS_DIALOG_TEMPLATE_REGISTRY, PraxisDialog, PraxisDialogActionsDirective, PraxisDialogComponent, PraxisDialogContentDirective, PraxisDialogDirectives, PraxisDialogRef, PraxisDialogTitleDirective, PraxisQuickViewOverlayComponent, QuickViewDialogPresenterService, provideDialogGlobalPresetsFromGlobalConfig, providePraxisDialogExamples, providePraxisDialogGlobalActions, providePraxisDialogMetadata, providePraxisQuickViewDialogPresenter, providePraxisSurfaceGlobalActions };
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@praxisui/dialog",
3
- "version": "10.0.0-rc.4",
3
+ "version": "10.0.0-rc.41",
4
4
  "description": "Dialog helpers and components for Praxis UI with Angular Material integration.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
8
  "@angular/cdk": "^21.0.0",
9
9
  "@angular/forms": "^21.0.0",
10
- "@praxisui/core": "^10.0.0-rc.4",
10
+ "@praxisui/core": "^10.0.0-rc.41",
11
11
  "@angular/material": "^21.0.0",
12
12
  "@angular/platform-browser": "^21.0.0",
13
13
  "rxjs": "~7.8.0"
@@ -1,10 +1,11 @@
1
- import * as i0 from '@angular/core';
1
+ import * as _angular_core from '@angular/core';
2
2
  import { Injector, ViewContainerRef, InjectionToken, TemplateRef, ComponentRef, OnInit, AfterViewInit, OnChanges, OnDestroy, EventEmitter, ElementRef, SimpleChanges, Type, Provider } from '@angular/core';
3
3
  import { OverlayRef } from '@angular/cdk/overlay';
4
4
  import { Observable, Subject } from 'rxjs';
5
5
  import { CdkPortalOutlet } from '@angular/cdk/portal';
6
+ import * as _praxisui_core from '@praxisui/core';
7
+ import { ResourceQuickViewResolution, PraxisQuickViewBodyRenderer, ResourceQuickViewDismissReason, ResourceQuickViewSummaryItem, PraxisQuickViewPresenter, PraxisQuickViewPresentOptions, PraxisQuickViewPresenterSession, ComponentDocMeta, ComponentAuthoringManifest } from '@praxisui/core';
6
8
  import * as _praxisui_dialog from '@praxisui/dialog';
7
- import { ComponentDocMeta, ComponentAuthoringManifest } from '@praxisui/core';
8
9
 
9
10
  type ActionsLayout = 'start' | 'center' | 'end' | 'stretched';
10
11
  type DialogThemeColor = 'primary' | 'light' | 'dark';
@@ -191,22 +192,22 @@ declare class PraxisDialogRef<T = any, R = any> {
191
192
  declare class PraxisDialogTitleDirective {
192
193
  templateRef: TemplateRef<any>;
193
194
  constructor(templateRef: TemplateRef<any>);
194
- static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDialogTitleDirective, never>;
195
- static ɵdir: i0.ɵɵDirectiveDeclaration<PraxisDialogTitleDirective, "ng-template[praxisDialogTitle]", never, {}, {}, never, never, true, never>;
195
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisDialogTitleDirective, never>;
196
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PraxisDialogTitleDirective, "ng-template[praxisDialogTitle]", never, {}, {}, never, never, true, never>;
196
197
  }
197
198
 
198
199
  declare class PraxisDialogActionsDirective {
199
200
  templateRef: TemplateRef<any>;
200
201
  constructor(templateRef: TemplateRef<any>);
201
- static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDialogActionsDirective, never>;
202
- static ɵdir: i0.ɵɵDirectiveDeclaration<PraxisDialogActionsDirective, "ng-template[praxisDialogActions]", never, {}, {}, never, never, true, never>;
202
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisDialogActionsDirective, never>;
203
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PraxisDialogActionsDirective, "ng-template[praxisDialogActions]", never, {}, {}, never, never, true, never>;
203
204
  }
204
205
 
205
206
  declare class PraxisDialogContentDirective {
206
207
  templateRef: TemplateRef<any>;
207
208
  constructor(templateRef: TemplateRef<any>);
208
- static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDialogContentDirective, never>;
209
- static ɵdir: i0.ɵɵDirectiveDeclaration<PraxisDialogContentDirective, "ng-template[praxisDialogContent]", never, {}, {}, never, never, true, never>;
209
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisDialogContentDirective, never>;
210
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<PraxisDialogContentDirective, "ng-template[praxisDialogContent]", never, {}, {}, never, never, true, never>;
210
211
  }
211
212
 
212
213
  declare class PraxisDialogComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy {
@@ -287,8 +288,8 @@ declare class PraxisDialogComponent implements OnInit, AfterViewInit, OnChanges,
287
288
  beginOpenAnimation(): Promise<void>;
288
289
  beginCloseAnimation(): Promise<void>;
289
290
  private focusPrimaryAction;
290
- static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDialogComponent, never>;
291
- static ɵcmp: i0.ɵɵComponentDeclaration<PraxisDialogComponent, "praxis-dialog", never, { "title": { "alias": "title"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "actionsLayout": { "alias": "actionsLayout"; "required": false; }; "animation": { "alias": "animation"; "required": false; }; "open": { "alias": "open"; "required": false; }; "width": { "alias": "width"; "required": false; }; "height": { "alias": "height"; "required": false; }; "minWidth": { "alias": "minWidth"; "required": false; }; "maxWidth": { "alias": "maxWidth"; "required": false; }; "minHeight": { "alias": "minHeight"; "required": false; }; "maxHeight": { "alias": "maxHeight"; "required": false; }; "themeColor": { "alias": "themeColor"; "required": false; }; "disableClose": { "alias": "disableClose"; "required": false; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; }; "closeOnBackdropClick": { "alias": "closeOnBackdropClick"; "required": false; }; "overlayMode": { "alias": "overlayMode"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "panelClass": { "alias": "panelClass"; "required": false; }; "backdropClass": { "alias": "backdropClass"; "required": false; }; "position": { "alias": "position"; "required": false; }; "autoFocusedElement": { "alias": "autoFocusedElement"; "required": false; }; "autoFocus": { "alias": "autoFocus"; "required": false; }; "restoreFocus": { "alias": "restoreFocus"; "required": false; }; "id": { "alias": "id"; "required": false; }; "ariaRole": { "alias": "ariaRole"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "ariaLabelledBy": { "alias": "ariaLabelledBy"; "required": false; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; }; "styles": { "alias": "styles"; "required": false; }; "titleIcon": { "alias": "titleIcon"; "required": false; }; }, { "action": "action"; "close": "close"; "opened": "opened"; "afterClosed": "afterClosed"; }, ["titleTpl", "actionsTpl", "contentTpl"], never, true, never>;
291
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisDialogComponent, never>;
292
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisDialogComponent, "praxis-dialog", never, { "title": { "alias": "title"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; "actionsLayout": { "alias": "actionsLayout"; "required": false; }; "animation": { "alias": "animation"; "required": false; }; "open": { "alias": "open"; "required": false; }; "width": { "alias": "width"; "required": false; }; "height": { "alias": "height"; "required": false; }; "minWidth": { "alias": "minWidth"; "required": false; }; "maxWidth": { "alias": "maxWidth"; "required": false; }; "minHeight": { "alias": "minHeight"; "required": false; }; "maxHeight": { "alias": "maxHeight"; "required": false; }; "themeColor": { "alias": "themeColor"; "required": false; }; "disableClose": { "alias": "disableClose"; "required": false; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; }; "closeOnBackdropClick": { "alias": "closeOnBackdropClick"; "required": false; }; "overlayMode": { "alias": "overlayMode"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "panelClass": { "alias": "panelClass"; "required": false; }; "backdropClass": { "alias": "backdropClass"; "required": false; }; "position": { "alias": "position"; "required": false; }; "autoFocusedElement": { "alias": "autoFocusedElement"; "required": false; }; "autoFocus": { "alias": "autoFocus"; "required": false; }; "restoreFocus": { "alias": "restoreFocus"; "required": false; }; "id": { "alias": "id"; "required": false; }; "ariaRole": { "alias": "ariaRole"; "required": false; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; }; "ariaLabelledBy": { "alias": "ariaLabelledBy"; "required": false; }; "ariaDescribedBy": { "alias": "ariaDescribedBy"; "required": false; }; "styles": { "alias": "styles"; "required": false; }; "titleIcon": { "alias": "titleIcon"; "required": false; }; }, { "action": "action"; "close": "close"; "opened": "opened"; "afterClosed": "afterClosed"; }, ["titleTpl", "actionsTpl", "contentTpl"], never, true, never>;
292
293
  }
293
294
  declare const PraxisDialogDirectives: readonly [];
294
295
 
@@ -318,8 +319,8 @@ declare class PraxisDialog {
318
319
  private mergePresets;
319
320
  closeAll(): void;
320
321
  getDialogById(id: string): PraxisDialogRef<any> | undefined;
321
- static ɵfac: i0.ɵɵFactoryDeclaration<PraxisDialog, never>;
322
- static ɵprov: i0.ɵɵInjectableDeclaration<PraxisDialog>;
322
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisDialog, never>;
323
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<PraxisDialog>;
323
324
  }
324
325
  declare class SimpleDialogContentComponent {
325
326
  message?: string;
@@ -329,8 +330,8 @@ declare class SimpleDialogContentComponent {
329
330
  submit?: () => void;
330
331
  private readonly dialogData;
331
332
  constructor();
332
- static ɵfac: i0.ɵɵFactoryDeclaration<SimpleDialogContentComponent, never>;
333
- static ɵcmp: i0.ɵɵComponentDeclaration<SimpleDialogContentComponent, "praxis-simple-dialog-content", never, {}, {}, never, never, true, never>;
333
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SimpleDialogContentComponent, never>;
334
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SimpleDialogContentComponent, "praxis-simple-dialog-content", never, {}, {}, never, never, true, never>;
334
335
  }
335
336
 
336
337
  /**
@@ -343,18 +344,88 @@ declare function providePraxisDialogGlobalActions(): Provider;
343
344
 
344
345
  declare function providePraxisSurfaceGlobalActions(): Provider;
345
346
 
347
+ declare class PraxisQuickViewOverlayComponent {
348
+ private readonly i18n;
349
+ readonly resolution: _angular_core.WritableSignal<ResourceQuickViewResolution | null>;
350
+ readonly bodyRenderer: _angular_core.WritableSignal<PraxisQuickViewBodyRenderer | null>;
351
+ readonly narrowModalMode: _angular_core.WritableSignal<boolean>;
352
+ private readonly failedAvatarUrl;
353
+ readonly pointerEnter: EventEmitter<void>;
354
+ readonly pointerLeave: EventEmitter<void>;
355
+ readonly openDetail: EventEmitter<void>;
356
+ readonly copyValue: EventEmitter<{
357
+ value: string;
358
+ field?: string;
359
+ }>;
360
+ readonly dismiss: EventEmitter<ResourceQuickViewDismissReason>;
361
+ private readonly dialogSurface?;
362
+ private readonly ctaButton?;
363
+ private readonly closeButton?;
364
+ protected readonly summaryItems: _angular_core.Signal<readonly ResourceQuickViewSummaryItem[]>;
365
+ protected readonly headerIdentity: _angular_core.Signal<_praxisui_core.MaterializedResourceIdentity | null>;
366
+ protected readonly contextLabel: _angular_core.Signal<string | null>;
367
+ protected readonly hasContextEyebrow: _angular_core.Signal<boolean>;
368
+ protected readonly safeAvatarUrl: _angular_core.Signal<string | null>;
369
+ protected onAvatarError(failedUrl: string): void;
370
+ protected readonly closeAriaLabel: _angular_core.Signal<string>;
371
+ protected readonly copyButtonLabel: _angular_core.Signal<string>;
372
+ protected readonly emptyStateLabel: _angular_core.Signal<string>;
373
+ protected readonly unavailableStateLabel: _angular_core.Signal<string>;
374
+ protected readonly errorStateLabel: _angular_core.Signal<string>;
375
+ protected readonly defaultCtaLabel: _angular_core.Signal<string>;
376
+ protected readonly maskedBadgeLabel: _angular_core.Signal<string>;
377
+ protected readonly maskedFieldReasonLabel: _angular_core.Signal<string>;
378
+ protected readonly accessibleLabel: _angular_core.Signal<string>;
379
+ private translate;
380
+ protected readonly shouldUseCustomBodyRenderer: _angular_core.Signal<boolean>;
381
+ protected readonly customBodyInputs: _angular_core.Signal<Record<string, unknown>>;
382
+ focusInteractiveEntry(): void;
383
+ protected isBadgeOrChip(item: ResourceQuickViewSummaryItem): boolean;
384
+ protected onCopyItem(item: ResourceQuickViewSummaryItem): void;
385
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PraxisQuickViewOverlayComponent, never>;
386
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PraxisQuickViewOverlayComponent, "praxis-quick-view-overlay", never, {}, { "pointerEnter": "pointerEnter"; "pointerLeave": "pointerLeave"; "openDetail": "openDetail"; "copyValue": "copyValue"; "dismiss": "dismiss"; }, never, never, true, never>;
387
+ }
388
+
389
+ /**
390
+ * Apresentador conectado não-modal para Quick View em `@praxisui/dialog`.
391
+ *
392
+ * Regras arquiteturais:
393
+ * - Em desktop (`hover`, `focus-shortcut`, `explicit-button`), utiliza `flexibleConnectedTo`
394
+ * sem `aria-modal="true"` e sem trap global de foco;
395
+ * - Em `narrow-tap` (ou viewport compacta <= 640px sob ativação explícita), utiliza folha compacta
396
+ * inferior com backdrop e semântica modal real;
397
+ * - Reposiciona em scroll/resize enquanto a âncora permanecer válida e fecha imediatamente
398
+ * quando a âncora sai do DOM ou se torna inválida;
399
+ * - Restaura o foco ao gatilho original quando o usuário fecha por `Escape` ou botão Fechar
400
+ * estando com o foco dentro do card.
401
+ */
402
+ declare class QuickViewDialogPresenterService implements PraxisQuickViewPresenter {
403
+ private readonly overlay;
404
+ private readonly injector;
405
+ private readonly layerScale;
406
+ private activeSession;
407
+ present(options: PraxisQuickViewPresentOptions): PraxisQuickViewPresenterSession;
408
+ closeAll(): void;
409
+ private shouldUseNarrowModalFallback;
410
+ private buildOverlayConfig;
411
+ private resolveConnectedOrigin;
412
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<QuickViewDialogPresenterService, never>;
413
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<QuickViewDialogPresenterService>;
414
+ }
415
+ declare function providePraxisQuickViewDialogPresenter(): Provider;
416
+
346
417
  declare class LongContentDialogExampleComponent {
347
418
  readonly items: string[];
348
- static ɵfac: i0.ɵɵFactoryDeclaration<LongContentDialogExampleComponent, never>;
349
- static ɵcmp: i0.ɵɵComponentDeclaration<LongContentDialogExampleComponent, "praxis-long-content-dialog-example", never, {}, {}, never, never, true, never>;
419
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<LongContentDialogExampleComponent, never>;
420
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<LongContentDialogExampleComponent, "praxis-long-content-dialog-example", never, {}, {}, never, never, true, never>;
350
421
  }
351
422
 
352
423
  declare const PRAXIS_DIALOG_EXAMPLE_LONG_CONTENT = "praxis.long-content-example";
353
424
  declare function providePraxisDialogExamples(): {
354
- provide: i0.InjectionToken<readonly (() => void)[]>;
425
+ provide: _angular_core.InjectionToken<readonly (() => void)[]>;
355
426
  multi: boolean;
356
427
  useFactory: (registry: Record<string, any>) => () => void;
357
- deps: i0.InjectionToken<Record<string, _praxisui_dialog.ComponentType<any>>>[];
428
+ deps: _angular_core.InjectionToken<Record<string, _praxisui_dialog.ComponentType<any>>>[];
358
429
  };
359
430
 
360
431
  declare const PRAXIS_DIALOG_COMPONENT_METADATA: ComponentDocMeta;
@@ -362,5 +433,5 @@ declare function providePraxisDialogMetadata(): Provider;
362
433
 
363
434
  declare const PRAXIS_DIALOG_AUTHORING_MANIFEST: ComponentAuthoringManifest;
364
435
 
365
- export { LongContentDialogExampleComponent, PRAXIS_DIALOG_AUTHORING_MANIFEST, PRAXIS_DIALOG_COMPONENT_METADATA, PRAXIS_DIALOG_CONTENT_REGISTRY, PRAXIS_DIALOG_DATA, PRAXIS_DIALOG_DEFAULTS, PRAXIS_DIALOG_EXAMPLE_LONG_CONTENT, PRAXIS_DIALOG_GLOBAL_PRESETS, PRAXIS_DIALOG_I18N, PRAXIS_DIALOG_TEMPLATE_REGISTRY, PraxisDialog, PraxisDialogActionsDirective, PraxisDialogComponent, PraxisDialogContentDirective, PraxisDialogDirectives, PraxisDialogRef, PraxisDialogTitleDirective, provideDialogGlobalPresetsFromGlobalConfig, providePraxisDialogExamples, providePraxisDialogGlobalActions, providePraxisDialogMetadata, providePraxisSurfaceGlobalActions };
436
+ export { LongContentDialogExampleComponent, PRAXIS_DIALOG_AUTHORING_MANIFEST, PRAXIS_DIALOG_COMPONENT_METADATA, PRAXIS_DIALOG_CONTENT_REGISTRY, PRAXIS_DIALOG_DATA, PRAXIS_DIALOG_DEFAULTS, PRAXIS_DIALOG_EXAMPLE_LONG_CONTENT, PRAXIS_DIALOG_GLOBAL_PRESETS, PRAXIS_DIALOG_I18N, PRAXIS_DIALOG_TEMPLATE_REGISTRY, PraxisDialog, PraxisDialogActionsDirective, PraxisDialogComponent, PraxisDialogContentDirective, PraxisDialogDirectives, PraxisDialogRef, PraxisDialogTitleDirective, PraxisQuickViewOverlayComponent, QuickViewDialogPresenterService, provideDialogGlobalPresetsFromGlobalConfig, providePraxisDialogExamples, providePraxisDialogGlobalActions, providePraxisDialogMetadata, providePraxisQuickViewDialogPresenter, providePraxisSurfaceGlobalActions };
366
437
  export type { ActionsLayout, AnimationDirection, ComponentType, DialogAction, DialogAnimation, DialogAnimationType, DialogContentDescriptor, DialogThemeColor, PraxisAlertConfig, PraxisConfirmConfig, PraxisDialogConfig, PraxisDialogGlobalPresets, PraxisDialogPosition, PraxisDialogStyleConfig, PraxisPromptConfig };