@praxisui/core 9.0.37 → 9.0.38

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-08-30T00:46:55.066Z",
3
+ "generatedAt": "2026-08-30T02:26:55.462Z",
4
4
  "packageName": "@praxisui/core",
5
- "packageVersion": "9.0.37",
5
+ "packageVersion": "9.0.38",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 4,
@@ -3644,7 +3644,8 @@ class ApiConfigStorage {
3644
3644
  return resolved.trim();
3645
3645
  return this.inferComponentType(key);
3646
3646
  };
3647
- // Simple in-memory cache of etag/payload per key to support 304 reuse
3647
+ // Keep read/write validators separate: weak ETags can revalidate GETs but
3648
+ // cannot satisfy If-Match for governed writes.
3648
3649
  cache = new Map();
3649
3650
  constructor() { }
3650
3651
  shouldLogLoadError(key, err) {
@@ -3671,7 +3672,7 @@ class ApiConfigStorage {
3671
3672
  }
3672
3673
  executeLoadConfigRequest(key, establishAvailability) {
3673
3674
  const cached = this.cache.get(key);
3674
- const etag = cached?.etag;
3675
+ const etag = cached?.readEtag ?? cached?.writeEtag;
3675
3676
  const { type, id } = this.resolveKey(key);
3676
3677
  const url = `${this.baseUrl}`;
3677
3678
  const params = this.buildParams(type, id, cached?.scope);
@@ -3694,11 +3695,14 @@ class ApiConfigStorage {
3694
3695
  return this.http
3695
3696
  .get(url, { observe: 'response', headers, params })
3696
3697
  .pipe(map((resp) => {
3697
- const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
3698
3698
  const body = resp.body;
3699
- if (nextEtag) {
3699
+ const responseEtag = resp.headers.get('ETag');
3700
+ const readEtag = this.resolveReadEtag(responseEtag, body?.etag);
3701
+ const writeEtag = this.resolveWriteEtag(responseEtag, body?.etag);
3702
+ if (readEtag || writeEtag) {
3700
3703
  this.cache.set(key, {
3701
- etag: nextEtag,
3704
+ readEtag,
3705
+ writeEtag,
3702
3706
  payload: body?.payload,
3703
3707
  scope: this.resolveResponseScope(body?.scope),
3704
3708
  });
@@ -3726,11 +3730,14 @@ class ApiConfigStorage {
3726
3730
  return this.http
3727
3731
  .get(url, { observe: 'response', headers, params })
3728
3732
  .pipe(map((resp) => {
3729
- const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
3730
3733
  const body = resp.body;
3731
- if (nextEtag) {
3734
+ const responseEtag = resp.headers.get('ETag');
3735
+ const readEtag = this.resolveReadEtag(responseEtag, body?.etag);
3736
+ const writeEtag = this.resolveWriteEtag(responseEtag, body?.etag);
3737
+ if (readEtag || writeEtag) {
3732
3738
  this.cache.set(key, {
3733
- etag: nextEtag,
3739
+ readEtag,
3740
+ writeEtag,
3734
3741
  payload: body?.payload,
3735
3742
  scope: this.resolveResponseScope(body?.scope),
3736
3743
  });
@@ -3757,16 +3764,20 @@ class ApiConfigStorage {
3757
3764
  const url = `${this.baseUrl}`;
3758
3765
  const cached = this.cache.get(key);
3759
3766
  const params = this.buildParams(type, id, cached?.scope);
3760
- const headers = this.buildHeaders(cached?.etag ? { 'If-Match': this.formatEtag(cached.etag) } : undefined);
3767
+ const headers = this.buildHeaders(cached?.writeEtag
3768
+ ? { 'If-Match': this.formatEtag(cached.writeEtag) }
3769
+ : undefined);
3761
3770
  return this.http
3762
3771
  .put(url, { payload: config }, { observe: 'response', headers, params })
3763
3772
  .pipe(map((resp) => {
3764
- const nextEtag = this.stripQuotes(resp.headers.get('ETag'));
3765
- const payload = resp.body?.payload ?? config;
3773
+ const body = resp.body;
3774
+ const responseEtag = resp.headers.get('ETag');
3775
+ const payload = body?.payload ?? config;
3766
3776
  this.cache.set(key, {
3767
- etag: nextEtag,
3777
+ readEtag: this.resolveReadEtag(responseEtag, body?.etag),
3778
+ writeEtag: this.resolveWriteEtag(responseEtag, body?.etag),
3768
3779
  payload,
3769
- scope: this.resolveResponseScope(resp.body?.scope) ?? cached?.scope,
3780
+ scope: this.resolveResponseScope(body?.scope) ?? cached?.scope,
3770
3781
  });
3771
3782
  }), catchError((err) => {
3772
3783
  if (this.shouldLogSaveError(key, err)) {
@@ -3799,18 +3810,22 @@ class ApiConfigStorage {
3799
3810
  shouldPropagateLoadError(key, _err) {
3800
3811
  if (this.opts?.errorPolicy !== 'fail')
3801
3812
  return false;
3802
- return key.startsWith('praxis:global-config');
3813
+ return (key.startsWith('praxis:global-config')
3814
+ || key.startsWith('dynamic-page:'));
3803
3815
  }
3804
3816
  isCriticalPersistenceKey(key) {
3805
3817
  return (key.startsWith('praxis:global-config')
3806
- || key.startsWith('table-config:'));
3818
+ || key.startsWith('table-config:')
3819
+ || key.startsWith('dynamic-page:'));
3807
3820
  }
3808
3821
  clearConfig(key) {
3809
3822
  const { type, id } = this.resolveKey(key);
3810
3823
  const url = `${this.baseUrl}`;
3811
3824
  const cached = this.cache.get(key);
3812
3825
  const params = this.buildParams(type, id, cached?.scope);
3813
- const headers = this.buildHeaders(cached?.etag ? { 'If-Match': this.formatEtag(cached.etag) } : undefined);
3826
+ const headers = this.buildHeaders(cached?.writeEtag
3827
+ ? { 'If-Match': this.formatEtag(cached.writeEtag) }
3828
+ : undefined);
3814
3829
  return this.http
3815
3830
  .delete(url, { observe: 'response', headers, params })
3816
3831
  .pipe(map(() => {
@@ -3922,19 +3937,35 @@ class ApiConfigStorage {
3922
3937
  const parts = value.split(':');
3923
3938
  return (parts.length === 4 || parts.length === 5) && !parts[0].includes('/');
3924
3939
  }
3925
- stripQuotes(value) {
3926
- if (!value)
3940
+ resolveReadEtag(responseHeader, responseBodyEtag) {
3941
+ const header = responseHeader?.trim();
3942
+ if (header)
3943
+ return header;
3944
+ return this.resolveWriteEtag(null, responseBodyEtag);
3945
+ }
3946
+ resolveWriteEtag(responseHeader, responseBodyEtag) {
3947
+ const bodyEtag = this.normalizeStrongEtag(responseBodyEtag);
3948
+ if (bodyEtag)
3949
+ return bodyEtag;
3950
+ return this.normalizeStrongEtag(responseHeader);
3951
+ }
3952
+ normalizeStrongEtag(value) {
3953
+ if (typeof value !== 'string')
3954
+ return null;
3955
+ const normalized = value.trim();
3956
+ if (!normalized || normalized.startsWith('W/'))
3927
3957
  return null;
3928
- const v = value.trim();
3929
- if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) {
3930
- return v.substring(1, v.length - 1);
3958
+ if (normalized.startsWith('"')
3959
+ && normalized.endsWith('"')
3960
+ && normalized.length >= 2) {
3961
+ return normalized.substring(1, normalized.length - 1);
3931
3962
  }
3932
- return v;
3963
+ return normalized;
3933
3964
  }
3934
3965
  formatEtag(etag) {
3935
3966
  if (!etag)
3936
3967
  return undefined;
3937
- return etag.startsWith('"') ? etag : `"${etag}"`;
3968
+ return etag.startsWith('"') || etag.startsWith('W/') ? etag : `"${etag}"`;
3938
3969
  }
3939
3970
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ApiConfigStorage, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3940
3971
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ApiConfigStorage, providedIn: 'root' });
@@ -31350,7 +31381,9 @@ class PraxisRichTextBlockComponent {
31350
31381
  contentFormat = 'plain';
31351
31382
  content = '';
31352
31383
  get renderedContent() {
31353
- const format = isAllowedEditorialContentFormat(this.contentFormat) ? this.contentFormat : 'plain';
31384
+ const format = isAllowedEditorialContentFormat(this.contentFormat)
31385
+ ? this.contentFormat
31386
+ : 'plain';
31354
31387
  const html = format === 'markdown'
31355
31388
  ? renderEditorialMarkdown(this.content)
31356
31389
  : renderEditorialPlain(this.content);
@@ -31363,11 +31396,15 @@ class PraxisRichTextBlockComponent {
31363
31396
  [class.prt-block-emphasis]="variant === 'emphasis'"
31364
31397
  [class.prt-block-subtle]="variant === 'subtle'"
31365
31398
  [class.prt-block-plain]="appearance === 'plain'"
31366
- >
31399
+ >
31367
31400
  @if (icon || title || subtitle) {
31368
31401
  <header class="prt-head">
31369
31402
  @if (icon) {
31370
- <mat-icon class="prt-icon" aria-hidden="true" [praxisIcon]="icon"></mat-icon>
31403
+ <mat-icon
31404
+ class="prt-icon"
31405
+ aria-hidden="true"
31406
+ [praxisIcon]="icon"
31407
+ ></mat-icon>
31371
31408
  }
31372
31409
  <div class="prt-title-wrap">
31373
31410
  @if (title) {
@@ -31379,15 +31416,15 @@ class PraxisRichTextBlockComponent {
31379
31416
  </div>
31380
31417
  </header>
31381
31418
  }
31382
-
31419
+
31383
31420
  <div class="prt-content" [innerHTML]="renderedContent"></div>
31384
31421
  </section>
31385
- `, isInline: true, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31422
+ `, isInline: true, styles: [":host{display:block;min-width:0;max-width:100%;--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 72%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4% ), color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64% ), color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 82%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 64%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent )}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 84%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ), color-mix( in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72% ), color-mix( in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 88%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 42%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-high) 88%, transparent )}.prt-block{display:grid;min-width:0;max-width:100%;box-sizing:border-box;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;min-width:0;gap:4px}.prt-title,.prt-subtitle,.prt-content{overflow-wrap:anywhere}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
31386
31423
  }
31387
31424
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PraxisRichTextBlockComponent, decorators: [{
31388
31425
  type: Component,
31389
31426
  args: [{ selector: 'praxis-rich-text-block', standalone: true, imports: [MatIconModule, PraxisIconDirective], host: {
31390
- 'class': 'praxis-rich-text-block',
31427
+ class: 'praxis-rich-text-block',
31391
31428
  '[attr.data-instance-id]': 'instanceId || null',
31392
31429
  '[attr.data-analytics-id]': 'analyticsId || null',
31393
31430
  '[attr.data-variant]': 'variant',
@@ -31399,11 +31436,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
31399
31436
  [class.prt-block-emphasis]="variant === 'emphasis'"
31400
31437
  [class.prt-block-subtle]="variant === 'subtle'"
31401
31438
  [class.prt-block-plain]="appearance === 'plain'"
31402
- >
31439
+ >
31403
31440
  @if (icon || title || subtitle) {
31404
31441
  <header class="prt-head">
31405
31442
  @if (icon) {
31406
- <mat-icon class="prt-icon" aria-hidden="true" [praxisIcon]="icon"></mat-icon>
31443
+ <mat-icon
31444
+ class="prt-icon"
31445
+ aria-hidden="true"
31446
+ [praxisIcon]="icon"
31447
+ ></mat-icon>
31407
31448
  }
31408
31449
  <div class="prt-title-wrap">
31409
31450
  @if (title) {
@@ -31415,10 +31456,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
31415
31456
  </div>
31416
31457
  </header>
31417
31458
  }
31418
-
31459
+
31419
31460
  <div class="prt-content" [innerHTML]="renderedContent"></div>
31420
31461
  </section>
31421
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 72%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4%), color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64%), color-mix(in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 82%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 64%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent)}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix(in srgb, var(--md-sys-color-outline-variant) 84%, transparent);--prt-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8%), color-mix(in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10%) );--prt-emphasis-border: color-mix(in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant));--prt-emphasis-bg: linear-gradient( 180deg, color-mix(in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72%), color-mix(in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8%) );--prt-subtle-bg: color-mix(in srgb, var(--md-sys-color-surface-container-low) 88%, transparent);--prt-icon-bg: color-mix(in srgb, var(--md-sys-color-primary-container) 42%, transparent);--prt-code-bg: color-mix(in srgb, var(--md-sys-color-surface-container-high) 88%, transparent)}.prt-block{display:grid;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;gap:4px}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"] }]
31462
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;min-width:0;max-width:100%;--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 72%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-surface-container-lowest) 4% ), color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 32%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 36%, var(--md-sys-color-surface) 64% ), color-mix( in srgb, var(--md-sys-color-surface) 96%, var(--md-sys-color-primary-container) 4% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 82%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 64%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-highest) 82%, transparent )}:host-context(.mdc-theme-dark),:host-context(.theme-dark){--prt-border: color-mix( in srgb, var(--md-sys-color-outline-variant) 84%, transparent );--prt-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-surface-container-low) 92%, var(--md-sys-color-surface) 8% ), color-mix( in srgb, var(--md-sys-color-surface-container) 90%, var(--md-sys-color-surface-container-high) 10% ) );--prt-emphasis-border: color-mix( in srgb, var(--md-sys-color-primary) 42%, var(--md-sys-color-outline-variant) );--prt-emphasis-bg: linear-gradient( 180deg, color-mix( in srgb, var(--md-sys-color-primary-container) 28%, var(--md-sys-color-surface-container-low) 72% ), color-mix( in srgb, var(--md-sys-color-surface-container) 92%, var(--md-sys-color-primary-container) 8% ) );--prt-subtle-bg: color-mix( in srgb, var(--md-sys-color-surface-container-low) 88%, transparent );--prt-icon-bg: color-mix( in srgb, var(--md-sys-color-primary-container) 42%, transparent );--prt-code-bg: color-mix( in srgb, var(--md-sys-color-surface-container-high) 88%, transparent )}.prt-block{display:grid;min-width:0;max-width:100%;box-sizing:border-box;gap:12px;padding:16px 18px;border-radius:16px;border:1px solid var(--prt-border);background:var(--prt-bg);color:var(--md-sys-color-on-surface)}.prt-block-emphasis{border-color:var(--prt-emphasis-border);background:var(--prt-emphasis-bg)}.prt-block-subtle{background:var(--prt-subtle-bg);border-style:dashed}.prt-block-plain{padding:0;border:0;border-radius:0;background:transparent}.prt-head{display:grid;grid-template-columns:auto 1fr;gap:12px;align-items:start}.prt-icon{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:12px;background:var(--prt-icon-bg);color:var(--md-sys-color-primary);font-size:20px;line-height:1}.prt-title-wrap{display:grid;min-width:0;gap:4px}.prt-title,.prt-subtitle,.prt-content{overflow-wrap:anywhere}.prt-title{margin:0;font-size:1rem;font-weight:700;line-height:1.3}.prt-subtitle{margin:0;color:var(--md-sys-color-on-surface-variant);font-size:.86rem;line-height:1.4}.prt-content{color:var(--md-sys-color-on-surface);font-size:.94rem;line-height:1.6}.prt-content :where(p,ul){margin:0}.prt-content :where(p+p,p+ul,ul+p,ul+ul){margin-top:10px}.prt-content ul{padding-left:18px}.prt-content a{color:var(--md-sys-color-primary);text-decoration:underline;text-underline-offset:2px}.prt-content strong{font-weight:700}.prt-content em{font-style:italic}.prt-content code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.88em;padding:.1em .35em;border-radius:6px;background:var(--prt-code-bg)}.prt-block-plain .prt-icon{width:32px;height:32px;border-radius:10px;background:color-mix(in srgb,var(--md-sys-color-surface-container-high) 80%,transparent)}.prt-block-plain .prt-content{font-size:.92rem}\n"] }]
31422
31463
  }], propDecorators: { instanceId: [{
31423
31464
  type: Input
31424
31465
  }], analyticsId: [{
@@ -31492,7 +31533,9 @@ function renderInlineMarkdown(text) {
31492
31533
  if (!normalized) {
31493
31534
  return escapeHtml(decodeHtml(label));
31494
31535
  }
31495
- const target = normalized.target ? ` target="${escapeHtml(normalized.target)}"` : '';
31536
+ const target = normalized.target
31537
+ ? ` target="${escapeHtml(normalized.target)}"`
31538
+ : '';
31496
31539
  const rel = normalized.rel || EDITORIAL_EXTERNAL_LINK_REL;
31497
31540
  return reserve(`<a href="${escapeHtml(normalized.href)}"${target} rel="${escapeHtml(rel)}">${escapeHtml(normalized.label)}</a>`);
31498
31541
  });
@@ -31523,7 +31566,7 @@ function decodeHtml(value) {
31523
31566
  .replace(/&lt;/g, '<')
31524
31567
  .replace(/&gt;/g, '>')
31525
31568
  .replace(/&quot;/g, '"')
31526
- .replace(/&#39;/g, '\'')
31569
+ .replace(/&#39;/g, "'")
31527
31570
  .replace(/&amp;/g, '&');
31528
31571
  }
31529
31572
 
@@ -32902,7 +32945,11 @@ class WidgetShellComponent {
32902
32945
  return false;
32903
32946
  if (this.shell?.showHeader != null)
32904
32947
  return !!this.shell.showHeader;
32905
- return !!(this.shell?.title || this.shell?.subtitle || this.shell?.icon || this.headerActions.length || this.windowActions.length);
32948
+ return !!(this.shell?.title ||
32949
+ this.shell?.subtitle ||
32950
+ this.shell?.icon ||
32951
+ this.headerActions.length ||
32952
+ this.windowActions.length);
32906
32953
  }
32907
32954
  get headerActions() {
32908
32955
  return (this.shell?.actions || []).filter((a) => this.isVisible(a) && (a.placement || 'header') === 'header');
@@ -32950,13 +32997,15 @@ class WidgetShellComponent {
32950
32997
  this.action.emit(event);
32951
32998
  }
32952
32999
  onHeaderPointerDown(event) {
32953
- if (!this.dragSurfaceInteractive || this.isInteractiveHeaderTarget(event.target)) {
33000
+ if (!this.dragSurfaceInteractive ||
33001
+ this.isInteractiveHeaderTarget(event.target)) {
32954
33002
  return;
32955
33003
  }
32956
33004
  this.dragSurfacePointerDown.emit(event);
32957
33005
  }
32958
33006
  onHeaderKeydown(event) {
32959
- if (!this.dragSurfaceInteractive || this.isInteractiveHeaderTarget(event.target)) {
33007
+ if (!this.dragSurfaceInteractive ||
33008
+ this.isInteractiveHeaderTarget(event.target)) {
32960
33009
  return;
32961
33010
  }
32962
33011
  this.dragSurfaceKeydown.emit(event);
@@ -33038,7 +33087,7 @@ class WidgetShellComponent {
33038
33087
  if (!presetId)
33039
33088
  return undefined;
33040
33089
  const ctxPresets = this.context?.ui?.shell?.presets || {};
33041
- return (ctxPresets && ctxPresets[presetId]) || BUILTIN_SHELL_PRESETS[presetId];
33090
+ return ((ctxPresets && ctxPresets[presetId]) || BUILTIN_SHELL_PRESETS[presetId]);
33042
33091
  }
33043
33092
  mergeAppearance(base, override) {
33044
33093
  if (!base && !override)
@@ -33080,294 +33129,378 @@ class WidgetShellComponent {
33080
33129
  }
33081
33130
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33082
33131
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: WidgetShellComponent, isStandalone: true, selector: "praxis-widget-shell", inputs: { shell: "shell", context: "context", dragSurfaceEnabled: "dragSurfaceEnabled", dragSurfaceLabel: "dragSurfaceLabel" }, outputs: { action: "action", dragSurfacePointerDown: "dragSurfacePointerDown", dragSurfaceKeydown: "dragSurfaceKeydown" }, host: { properties: { "class.pdx-widget-shell-collapsed": "this.hostCollapsed" } }, providers: [providePraxisI18nConfig(WIDGET_SHELL_I18N_CONFIG)], queries: [{ propertyName: "loader", first: true, predicate: DynamicWidgetLoaderDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
33083
- <section
33084
- class="pdx-shell"
33085
- [class.no-shell]="!shellEnabled"
33086
- [class.dashboard]="shellEnabled"
33087
- [class.collapsed]="collapsed"
33088
- [class.expanded]="expanded"
33089
- [class.fullscreen]="fullscreen"
33090
- [class.body-fill]="shell?.bodyLayout === 'fill'"
33091
- [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33092
- [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33093
- [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33094
- [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33095
- [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33096
- [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33097
- [style.--pdx-shell-header-border]="appearance?.header?.borderColor || null"
33098
- [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33099
- [style.--pdx-shell-subtitle-color]="appearance?.header?.subtitleColor || null"
33100
- [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33101
- [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33102
- [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33103
- [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33104
- [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33105
- [style.--pdx-shell-title-weight]="appearance?.typography?.titleWeight || null"
33106
- [style.--pdx-shell-subtitle-size]="appearance?.typography?.subtitleSize || null"
33107
- (click)="stopIfExpanded($event)"
33132
+ <section
33133
+ class="pdx-shell"
33134
+ [class.no-shell]="!shellEnabled"
33135
+ [class.dashboard]="shellEnabled"
33136
+ [class.collapsed]="collapsed"
33137
+ [class.expanded]="expanded"
33138
+ [class.fullscreen]="fullscreen"
33139
+ [class.body-fill]="shell?.bodyLayout === 'fill'"
33140
+ [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33141
+ [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33142
+ [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33143
+ [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33144
+ [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33145
+ [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33146
+ [style.--pdx-shell-header-border]="
33147
+ appearance?.header?.borderColor || null
33148
+ "
33149
+ [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33150
+ [style.--pdx-shell-subtitle-color]="
33151
+ appearance?.header?.subtitleColor || null
33152
+ "
33153
+ [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33154
+ [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33155
+ [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33156
+ [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33157
+ [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33158
+ [style.--pdx-shell-title-weight]="
33159
+ appearance?.typography?.titleWeight || null
33160
+ "
33161
+ [style.--pdx-shell-subtitle-size]="
33162
+ appearance?.typography?.subtitleSize || null
33163
+ "
33164
+ (click)="stopIfExpanded($event)"
33165
+ >
33166
+ @if (showHeader) {
33167
+ <header
33168
+ class="pdx-shell-header"
33169
+ [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33170
+ [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33171
+ [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33172
+ (pointerdown)="onHeaderPointerDown($event)"
33173
+ (keydown)="onHeaderKeydown($event)"
33108
33174
  >
33109
- @if (showHeader) {
33110
- <header
33111
- class="pdx-shell-header"
33112
- [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33113
- [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33114
- [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33115
- (pointerdown)="onHeaderPointerDown($event)"
33116
- (keydown)="onHeaderKeydown($event)"
33117
- >
33118
- <div class="pdx-shell-title">
33119
- @if (shell?.icon) {
33120
- <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33121
- }
33122
- <div class="pdx-shell-text">
33123
- <div class="pdx-shell-title-text">{{ shellText(shell?.title) }}</div>
33124
- @if (shell?.subtitle) {
33125
- <div class="pdx-shell-subtitle">{{ shellText(shell?.subtitle) }}</div>
33126
- }
33175
+ <div class="pdx-shell-title">
33176
+ @if (shell?.icon) {
33177
+ <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33178
+ }
33179
+ <div class="pdx-shell-text">
33180
+ <div class="pdx-shell-title-text">
33181
+ {{ shellText(shell?.title) }}
33127
33182
  </div>
33183
+ @if (shell?.subtitle) {
33184
+ <div class="pdx-shell-subtitle">
33185
+ {{ shellText(shell?.subtitle) }}
33186
+ </div>
33187
+ }
33128
33188
  </div>
33129
- <div class="pdx-shell-actions">
33130
- @if (!expanded && !fullscreen) {
33131
- @for (action of visibleHeaderActions; track action.id) {
33132
- <ng-container>
33133
- @if (action.variant !== 'icon') {
33134
- <button
33135
- [disabled]="action.disabled"
33136
- [matTooltip]="actionText(action.tooltip)"
33137
- matTooltipPosition="above"
33138
- [ngClass]="action.variant === 'outlined' ? 'pdx-action-outlined' : 'pdx-action-text'"
33139
- [class.pdx-shell-action--pressed]="action.pressed === true"
33140
- mat-button
33141
- type="button"
33142
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33143
- (click)="onAction(action, $event)"
33144
- >
33145
- @if (displayActionIcon(action); as actionIcon) {
33146
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33147
- }
33148
- <span class="pdx-action-label">{{ actionText(action.label) }}</span>
33149
- </button>
33150
- }
33151
- @if (action.variant === 'icon') {
33189
+ </div>
33190
+ <div class="pdx-shell-actions">
33191
+ @if (!expanded && !fullscreen) {
33192
+ @for (action of visibleHeaderActions; track action.id) {
33193
+ <ng-container>
33194
+ @if (action.variant !== 'icon') {
33195
+ <button
33196
+ [disabled]="action.disabled"
33197
+ [matTooltip]="actionText(action.tooltip)"
33198
+ matTooltipPosition="above"
33199
+ [ngClass]="
33200
+ action.variant === 'outlined'
33201
+ ? 'pdx-action-outlined'
33202
+ : 'pdx-action-text'
33203
+ "
33204
+ [class.pdx-shell-action--pressed]="
33205
+ action.pressed === true
33206
+ "
33207
+ mat-button
33208
+ type="button"
33209
+ [attr.aria-pressed]="
33210
+ action.pressed == null ? null : action.pressed
33211
+ "
33212
+ (click)="onAction(action, $event)"
33213
+ >
33152
33214
  @if (displayActionIcon(action); as actionIcon) {
33153
- <button
33154
- [praxisIconButton]="actionIcon"
33155
- size="compact"
33156
- [pressed]="actionPressedState(action)"
33157
- [disabled]="action.disabled"
33158
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33159
- matTooltipPosition="above"
33160
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33161
- type="button"
33162
- (click)="onAction(action, $event)"
33163
- ></button>
33215
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33164
33216
  }
33165
- }
33166
- </ng-container>
33167
- }
33168
- @if (overflowHeaderActions.length) {
33169
- <button
33170
- praxisIconButton="ms:more_horiz"
33171
- size="compact"
33172
- type="button"
33173
- [matTooltip]="moreActionsLabel()"
33174
- matTooltipPosition="above"
33175
- [attr.aria-label]="moreActionsLabel()"
33176
- [matMenuTriggerFor]="overflowMenu"
33177
- (click)="$event.stopPropagation()"
33178
- ></button>
33179
- }
33180
- }
33181
- @if (windowActions.length) {
33182
- <div class="pdx-shell-window-actions">
33183
- @for (action of windowActions; track action.id) {
33217
+ <span class="pdx-action-label">{{
33218
+ actionText(action.label)
33219
+ }}</span>
33220
+ </button>
33221
+ }
33222
+ @if (action.variant === 'icon') {
33184
33223
  @if (displayActionIcon(action); as actionIcon) {
33185
33224
  <button
33186
33225
  [praxisIconButton]="actionIcon"
33187
33226
  size="compact"
33188
33227
  [pressed]="actionPressedState(action)"
33189
33228
  [disabled]="action.disabled"
33190
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33229
+ [matTooltip]="
33230
+ actionText(action.tooltip, actionText(action.label))
33231
+ "
33191
33232
  matTooltipPosition="above"
33192
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33233
+ [attr.aria-label]="
33234
+ actionText(
33235
+ action.label,
33236
+ actionText(action.tooltip, action.id)
33237
+ )
33238
+ "
33193
33239
  type="button"
33194
33240
  (click)="onAction(action, $event)"
33195
33241
  ></button>
33196
33242
  }
33197
33243
  }
33198
- </div>
33244
+ </ng-container>
33199
33245
  }
33200
- </div>
33201
- <mat-menu #overflowMenu="matMenu">
33202
- @for (action of overflowHeaderActions; track action.id) {
33246
+ @if (overflowHeaderActions.length) {
33203
33247
  <button
33204
- mat-menu-item
33205
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33206
- (click)="onAction(action, $event)"
33207
- >
33248
+ praxisIconButton="ms:more_horiz"
33249
+ size="compact"
33250
+ type="button"
33251
+ [matTooltip]="moreActionsLabel()"
33252
+ matTooltipPosition="above"
33253
+ [attr.aria-label]="moreActionsLabel()"
33254
+ [matMenuTriggerFor]="overflowMenu"
33255
+ (click)="$event.stopPropagation()"
33256
+ ></button>
33257
+ }
33258
+ }
33259
+ @if (windowActions.length) {
33260
+ <div class="pdx-shell-window-actions">
33261
+ @for (action of windowActions; track action.id) {
33208
33262
  @if (displayActionIcon(action); as actionIcon) {
33209
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33263
+ <button
33264
+ [praxisIconButton]="actionIcon"
33265
+ size="compact"
33266
+ [pressed]="actionPressedState(action)"
33267
+ [disabled]="action.disabled"
33268
+ [matTooltip]="
33269
+ actionText(action.tooltip, actionText(action.label))
33270
+ "
33271
+ matTooltipPosition="above"
33272
+ [attr.aria-label]="
33273
+ actionText(
33274
+ action.label,
33275
+ actionText(action.tooltip, action.id)
33276
+ )
33277
+ "
33278
+ type="button"
33279
+ (click)="onAction(action, $event)"
33280
+ ></button>
33210
33281
  }
33211
- <span>{{ actionText(action.label, action.id) }}</span>
33212
- </button>
33213
- }
33214
- </mat-menu>
33215
- </header>
33216
- }
33217
- <div class="pdx-shell-body" [class.hidden]="collapsed">
33218
- <ng-content></ng-content>
33219
- </div>
33220
- </section>
33221
- @if (expanded || fullscreen) {
33222
- <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33282
+ }
33283
+ </div>
33284
+ }
33285
+ </div>
33286
+ <mat-menu #overflowMenu="matMenu">
33287
+ @for (action of overflowHeaderActions; track action.id) {
33288
+ <button
33289
+ mat-menu-item
33290
+ [attr.aria-pressed]="
33291
+ action.pressed == null ? null : action.pressed
33292
+ "
33293
+ (click)="onAction(action, $event)"
33294
+ >
33295
+ @if (displayActionIcon(action); as actionIcon) {
33296
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33297
+ }
33298
+ <span>{{ actionText(action.label, action.id) }}</span>
33299
+ </button>
33300
+ }
33301
+ </mat-menu>
33302
+ </header>
33223
33303
  }
33224
- `, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { 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 });
33304
+ <div class="pdx-shell-body" [class.hidden]="collapsed">
33305
+ <ng-content></ng-content>
33306
+ </div>
33307
+ </section>
33308
+ @if (expanded || fullscreen) {
33309
+ <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33310
+ }
33311
+ `, isInline: true, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var( --pdx-shell-card-bg, var( --pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low) ) );border:1px solid var( --pdx-shell-card-border, var( --pdx-dashboard-card-border, var(--md-sys-color-outline-variant) ) );border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var( --pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06) );overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var( --pdx-shell-header-bg, var(--md-sys-color-surface-container) )}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);color:var( --pdx-shell-subtitle-color, var(--md-sys-color-on-surface-variant, currentColor) );white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.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: i1$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { 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 });
33225
33312
  }
33226
33313
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: WidgetShellComponent, decorators: [{
33227
33314
  type: Component,
33228
- args: [{ selector: 'praxis-widget-shell', standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatMenuModule, MatTooltipModule, PraxisIconButtonComponent, PraxisIconDirective], providers: [providePraxisI18nConfig(WIDGET_SHELL_I18N_CONFIG)], template: `
33229
- <section
33230
- class="pdx-shell"
33231
- [class.no-shell]="!shellEnabled"
33232
- [class.dashboard]="shellEnabled"
33233
- [class.collapsed]="collapsed"
33234
- [class.expanded]="expanded"
33235
- [class.fullscreen]="fullscreen"
33236
- [class.body-fill]="shell?.bodyLayout === 'fill'"
33237
- [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33238
- [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33239
- [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33240
- [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33241
- [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33242
- [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33243
- [style.--pdx-shell-header-border]="appearance?.header?.borderColor || null"
33244
- [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33245
- [style.--pdx-shell-subtitle-color]="appearance?.header?.subtitleColor || null"
33246
- [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33247
- [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33248
- [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33249
- [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33250
- [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33251
- [style.--pdx-shell-title-weight]="appearance?.typography?.titleWeight || null"
33252
- [style.--pdx-shell-subtitle-size]="appearance?.typography?.subtitleSize || null"
33253
- (click)="stopIfExpanded($event)"
33315
+ args: [{ selector: 'praxis-widget-shell', standalone: true, imports: [
33316
+ CommonModule,
33317
+ MatButtonModule,
33318
+ MatIconModule,
33319
+ MatMenuModule,
33320
+ MatTooltipModule,
33321
+ PraxisIconButtonComponent,
33322
+ PraxisIconDirective,
33323
+ ], providers: [providePraxisI18nConfig(WIDGET_SHELL_I18N_CONFIG)], template: `
33324
+ <section
33325
+ class="pdx-shell"
33326
+ [class.no-shell]="!shellEnabled"
33327
+ [class.dashboard]="shellEnabled"
33328
+ [class.collapsed]="collapsed"
33329
+ [class.expanded]="expanded"
33330
+ [class.fullscreen]="fullscreen"
33331
+ [class.body-fill]="shell?.bodyLayout === 'fill'"
33332
+ [class.body-scroll]="shell?.bodyLayout === 'scroll'"
33333
+ [style.--pdx-shell-card-bg]="appearance?.card?.background || null"
33334
+ [style.--pdx-shell-card-border]="appearance?.card?.borderColor || null"
33335
+ [style.--pdx-shell-card-radius]="appearance?.card?.borderRadius || null"
33336
+ [style.--pdx-shell-card-shadow]="appearance?.card?.shadow || null"
33337
+ [style.--pdx-shell-header-bg]="appearance?.header?.background || null"
33338
+ [style.--pdx-shell-header-border]="
33339
+ appearance?.header?.borderColor || null
33340
+ "
33341
+ [style.--pdx-shell-title-color]="appearance?.header?.titleColor || null"
33342
+ [style.--pdx-shell-subtitle-color]="
33343
+ appearance?.header?.subtitleColor || null
33344
+ "
33345
+ [style.--pdx-shell-icon-color]="appearance?.header?.iconColor || null"
33346
+ [style.--pdx-shell-body-bg]="appearance?.body?.background || null"
33347
+ [style.--pdx-shell-body-color]="appearance?.body?.textColor || null"
33348
+ [style.--pdx-shell-body-padding]="appearance?.body?.padding || null"
33349
+ [style.--pdx-shell-title-size]="appearance?.typography?.titleSize || null"
33350
+ [style.--pdx-shell-title-weight]="
33351
+ appearance?.typography?.titleWeight || null
33352
+ "
33353
+ [style.--pdx-shell-subtitle-size]="
33354
+ appearance?.typography?.subtitleSize || null
33355
+ "
33356
+ (click)="stopIfExpanded($event)"
33357
+ >
33358
+ @if (showHeader) {
33359
+ <header
33360
+ class="pdx-shell-header"
33361
+ [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33362
+ [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33363
+ [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33364
+ (pointerdown)="onHeaderPointerDown($event)"
33365
+ (keydown)="onHeaderKeydown($event)"
33254
33366
  >
33255
- @if (showHeader) {
33256
- <header
33257
- class="pdx-shell-header"
33258
- [class.pdx-shell-header--drag-enabled]="dragSurfaceInteractive"
33259
- [attr.aria-label]="dragSurfaceInteractive ? dragSurfaceLabel : null"
33260
- [attr.tabindex]="dragSurfaceInteractive ? 0 : null"
33261
- (pointerdown)="onHeaderPointerDown($event)"
33262
- (keydown)="onHeaderKeydown($event)"
33263
- >
33264
- <div class="pdx-shell-title">
33265
- @if (shell?.icon) {
33266
- <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33267
- }
33268
- <div class="pdx-shell-text">
33269
- <div class="pdx-shell-title-text">{{ shellText(shell?.title) }}</div>
33270
- @if (shell?.subtitle) {
33271
- <div class="pdx-shell-subtitle">{{ shellText(shell?.subtitle) }}</div>
33272
- }
33367
+ <div class="pdx-shell-title">
33368
+ @if (shell?.icon) {
33369
+ <mat-icon [praxisIcon]="shell?.icon"></mat-icon>
33370
+ }
33371
+ <div class="pdx-shell-text">
33372
+ <div class="pdx-shell-title-text">
33373
+ {{ shellText(shell?.title) }}
33273
33374
  </div>
33375
+ @if (shell?.subtitle) {
33376
+ <div class="pdx-shell-subtitle">
33377
+ {{ shellText(shell?.subtitle) }}
33378
+ </div>
33379
+ }
33274
33380
  </div>
33275
- <div class="pdx-shell-actions">
33276
- @if (!expanded && !fullscreen) {
33277
- @for (action of visibleHeaderActions; track action.id) {
33278
- <ng-container>
33279
- @if (action.variant !== 'icon') {
33280
- <button
33281
- [disabled]="action.disabled"
33282
- [matTooltip]="actionText(action.tooltip)"
33283
- matTooltipPosition="above"
33284
- [ngClass]="action.variant === 'outlined' ? 'pdx-action-outlined' : 'pdx-action-text'"
33285
- [class.pdx-shell-action--pressed]="action.pressed === true"
33286
- mat-button
33287
- type="button"
33288
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33289
- (click)="onAction(action, $event)"
33290
- >
33291
- @if (displayActionIcon(action); as actionIcon) {
33292
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33293
- }
33294
- <span class="pdx-action-label">{{ actionText(action.label) }}</span>
33295
- </button>
33296
- }
33297
- @if (action.variant === 'icon') {
33381
+ </div>
33382
+ <div class="pdx-shell-actions">
33383
+ @if (!expanded && !fullscreen) {
33384
+ @for (action of visibleHeaderActions; track action.id) {
33385
+ <ng-container>
33386
+ @if (action.variant !== 'icon') {
33387
+ <button
33388
+ [disabled]="action.disabled"
33389
+ [matTooltip]="actionText(action.tooltip)"
33390
+ matTooltipPosition="above"
33391
+ [ngClass]="
33392
+ action.variant === 'outlined'
33393
+ ? 'pdx-action-outlined'
33394
+ : 'pdx-action-text'
33395
+ "
33396
+ [class.pdx-shell-action--pressed]="
33397
+ action.pressed === true
33398
+ "
33399
+ mat-button
33400
+ type="button"
33401
+ [attr.aria-pressed]="
33402
+ action.pressed == null ? null : action.pressed
33403
+ "
33404
+ (click)="onAction(action, $event)"
33405
+ >
33298
33406
  @if (displayActionIcon(action); as actionIcon) {
33299
- <button
33300
- [praxisIconButton]="actionIcon"
33301
- size="compact"
33302
- [pressed]="actionPressedState(action)"
33303
- [disabled]="action.disabled"
33304
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33305
- matTooltipPosition="above"
33306
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33307
- type="button"
33308
- (click)="onAction(action, $event)"
33309
- ></button>
33407
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33310
33408
  }
33311
- }
33312
- </ng-container>
33313
- }
33314
- @if (overflowHeaderActions.length) {
33315
- <button
33316
- praxisIconButton="ms:more_horiz"
33317
- size="compact"
33318
- type="button"
33319
- [matTooltip]="moreActionsLabel()"
33320
- matTooltipPosition="above"
33321
- [attr.aria-label]="moreActionsLabel()"
33322
- [matMenuTriggerFor]="overflowMenu"
33323
- (click)="$event.stopPropagation()"
33324
- ></button>
33325
- }
33326
- }
33327
- @if (windowActions.length) {
33328
- <div class="pdx-shell-window-actions">
33329
- @for (action of windowActions; track action.id) {
33409
+ <span class="pdx-action-label">{{
33410
+ actionText(action.label)
33411
+ }}</span>
33412
+ </button>
33413
+ }
33414
+ @if (action.variant === 'icon') {
33330
33415
  @if (displayActionIcon(action); as actionIcon) {
33331
33416
  <button
33332
33417
  [praxisIconButton]="actionIcon"
33333
33418
  size="compact"
33334
33419
  [pressed]="actionPressedState(action)"
33335
33420
  [disabled]="action.disabled"
33336
- [matTooltip]="actionText(action.tooltip, actionText(action.label))"
33421
+ [matTooltip]="
33422
+ actionText(action.tooltip, actionText(action.label))
33423
+ "
33337
33424
  matTooltipPosition="above"
33338
- [attr.aria-label]="actionText(action.label, actionText(action.tooltip, action.id))"
33425
+ [attr.aria-label]="
33426
+ actionText(
33427
+ action.label,
33428
+ actionText(action.tooltip, action.id)
33429
+ )
33430
+ "
33339
33431
  type="button"
33340
33432
  (click)="onAction(action, $event)"
33341
33433
  ></button>
33342
33434
  }
33343
33435
  }
33344
- </div>
33436
+ </ng-container>
33345
33437
  }
33346
- </div>
33347
- <mat-menu #overflowMenu="matMenu">
33348
- @for (action of overflowHeaderActions; track action.id) {
33438
+ @if (overflowHeaderActions.length) {
33349
33439
  <button
33350
- mat-menu-item
33351
- [attr.aria-pressed]="action.pressed == null ? null : action.pressed"
33352
- (click)="onAction(action, $event)"
33353
- >
33440
+ praxisIconButton="ms:more_horiz"
33441
+ size="compact"
33442
+ type="button"
33443
+ [matTooltip]="moreActionsLabel()"
33444
+ matTooltipPosition="above"
33445
+ [attr.aria-label]="moreActionsLabel()"
33446
+ [matMenuTriggerFor]="overflowMenu"
33447
+ (click)="$event.stopPropagation()"
33448
+ ></button>
33449
+ }
33450
+ }
33451
+ @if (windowActions.length) {
33452
+ <div class="pdx-shell-window-actions">
33453
+ @for (action of windowActions; track action.id) {
33354
33454
  @if (displayActionIcon(action); as actionIcon) {
33355
- <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33455
+ <button
33456
+ [praxisIconButton]="actionIcon"
33457
+ size="compact"
33458
+ [pressed]="actionPressedState(action)"
33459
+ [disabled]="action.disabled"
33460
+ [matTooltip]="
33461
+ actionText(action.tooltip, actionText(action.label))
33462
+ "
33463
+ matTooltipPosition="above"
33464
+ [attr.aria-label]="
33465
+ actionText(
33466
+ action.label,
33467
+ actionText(action.tooltip, action.id)
33468
+ )
33469
+ "
33470
+ type="button"
33471
+ (click)="onAction(action, $event)"
33472
+ ></button>
33356
33473
  }
33357
- <span>{{ actionText(action.label, action.id) }}</span>
33358
- </button>
33359
- }
33360
- </mat-menu>
33361
- </header>
33362
- }
33363
- <div class="pdx-shell-body" [class.hidden]="collapsed">
33364
- <ng-content></ng-content>
33365
- </div>
33366
- </section>
33367
- @if (expanded || fullscreen) {
33368
- <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33474
+ }
33475
+ </div>
33476
+ }
33477
+ </div>
33478
+ <mat-menu #overflowMenu="matMenu">
33479
+ @for (action of overflowHeaderActions; track action.id) {
33480
+ <button
33481
+ mat-menu-item
33482
+ [attr.aria-pressed]="
33483
+ action.pressed == null ? null : action.pressed
33484
+ "
33485
+ (click)="onAction(action, $event)"
33486
+ >
33487
+ @if (displayActionIcon(action); as actionIcon) {
33488
+ <mat-icon [praxisIcon]="actionIcon"></mat-icon>
33489
+ }
33490
+ <span>{{ actionText(action.label, action.id) }}</span>
33491
+ </button>
33492
+ }
33493
+ </mat-menu>
33494
+ </header>
33369
33495
  }
33370
- `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var(--pdx-shell-card-bg, var(--pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low)));border:1px solid var(--pdx-shell-card-border, var(--pdx-dashboard-card-border, var(--md-sys-color-outline-variant)));border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var(--pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06));overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var(--pdx-shell-header-bg, var(--md-sys-color-surface-container))}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);opacity:.75;color:var(--pdx-shell-subtitle-color, currentColor);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
33496
+ <div class="pdx-shell-body" [class.hidden]="collapsed">
33497
+ <ng-content></ng-content>
33498
+ </div>
33499
+ </section>
33500
+ @if (expanded || fullscreen) {
33501
+ <div class="pdx-shell-backdrop" (click)="closeOverlay()"></div>
33502
+ }
33503
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}:host(.pdx-widget-shell-collapsed){height:auto}.pdx-shell{position:relative;height:100%;display:flex;flex-direction:column}.pdx-shell.no-shell{background:transparent;border:none;border-radius:0;box-shadow:none}.pdx-shell.dashboard{background:var( --pdx-shell-card-bg, var( --pdx-dashboard-card-bg, var(--md-sys-color-surface-container-low) ) );border:1px solid var( --pdx-shell-card-border, var( --pdx-dashboard-card-border, var(--md-sys-color-outline-variant) ) );border-radius:var(--pdx-shell-card-radius, 12px);box-shadow:var( --pdx-shell-card-shadow, 0 4px 12px rgba(15, 23, 42, .06) );overflow:hidden}.pdx-shell-header{display:flex;align-items:center;gap:10px;padding:8px 10px 7px;border-bottom:1px solid var(--pdx-shell-header-border, var(--md-sys-color-outline-variant));background:var( --pdx-shell-header-bg, var(--md-sys-color-surface-container) )}.pdx-shell-header--drag-enabled{cursor:grab;-webkit-user-select:none;user-select:none;touch-action:none}.pdx-shell-header--drag-enabled:active{cursor:grabbing}.pdx-shell-header--drag-enabled:focus-visible{outline:2px solid color-mix(in srgb,var(--md-sys-color-primary) 72%,white 28%);outline-offset:-2px}.pdx-shell-title{display:flex;align-items:center;gap:8px;min-width:0;flex:1;color:var(--pdx-shell-title-color, inherit)}.pdx-shell-title mat-icon{color:var(--pdx-shell-icon-color, currentColor)}.pdx-shell-text{min-width:0}.pdx-shell-title-text{font-weight:var(--pdx-shell-title-weight, 600);font-size:var(--pdx-shell-title-size, 13px);line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-subtitle{font-size:var(--pdx-shell-subtitle-size, 11px);color:var( --pdx-shell-subtitle-color, var(--md-sys-color-on-surface-variant, currentColor) );white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pdx-shell-actions,.pdx-shell-window-actions{display:flex;align-items:center;gap:4px}.pdx-shell-window-actions{margin-left:auto}@media(max-width:640px){.pdx-shell-header,.pdx-shell-title{align-items:flex-start}.pdx-shell-text{display:grid;gap:2px}.pdx-shell-title-text,.pdx-shell-subtitle{display:-webkit-box;white-space:normal;overflow-wrap:anywhere;-webkit-box-orient:vertical}.pdx-shell-title-text,.pdx-shell-subtitle{-webkit-line-clamp:2}.pdx-shell-actions{flex:0 0 auto}}.pdx-action-outlined{border:1px solid var(--md-sys-color-outline-variant);border-radius:999px;padding:0 10px}.pdx-action-text{padding:0 8px}.pdx-shell-action--pressed:not(.praxis-icon-button){color:var(--md-sys-color-primary);background:color-mix(in srgb,var(--md-sys-color-primary) 12%,transparent)}.pdx-action-label{font-size:12px;font-weight:500}.pdx-shell-body{flex:1;min-height:0;padding:var(--pdx-shell-body-padding, 8px 10px 10px 10px);background:var(--pdx-shell-body-bg, transparent);color:var(--pdx-shell-body-color, inherit)}.pdx-shell.no-shell .pdx-shell-body{padding:0}.pdx-shell-body.hidden{display:none}.pdx-shell.collapsed{height:auto}.pdx-shell.collapsed .pdx-shell-header{border-bottom-color:transparent}.pdx-shell.body-fill .pdx-shell-body,.pdx-shell.body-scroll .pdx-shell-body,.pdx-shell.expanded .pdx-shell-body,.pdx-shell.fullscreen .pdx-shell-body{overflow:auto;display:flex;flex-direction:column;min-height:0}.pdx-shell.collapsed .pdx-shell-body{display:none}.pdx-shell.body-fill .pdx-shell-body{overflow:hidden}.pdx-shell.body-scroll .pdx-shell-body{overflow:auto}.pdx-shell.body-fill .pdx-shell-body>*,.pdx-shell.body-scroll .pdx-shell-body>*,.pdx-shell.expanded .pdx-shell-body>*,.pdx-shell.fullscreen .pdx-shell-body>*{flex:1 1 auto;min-height:0;width:100%}.pdx-shell.expanded{position:fixed;top:10vh;left:50%;width:min(920px,92vw);height:min(640px,82vh);transform:translate(-50%);z-index:var(--praxis-layer-widget-shell-expanded, 1290);box-shadow:var(--mat-elevation-level8)}.pdx-shell.fullscreen{position:fixed;inset:0;width:auto;height:auto;transform:none;border-radius:0;z-index:var(--praxis-layer-widget-shell-fullscreen, 1291);box-shadow:var(--mat-elevation-level8)}.pdx-shell-backdrop{position:fixed;inset:0;z-index:var(--praxis-layer-widget-shell-backdrop, 1280);background:#0000008c;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}\n"] }]
33371
33504
  }], propDecorators: { hostCollapsed: [{
33372
33505
  type: HostBinding,
33373
33506
  args: ['class.pdx-widget-shell-collapsed']
@@ -39475,9 +39608,7 @@ class DynamicWidgetPageComponent {
39475
39608
  return this.isAuthoringCapabilityEnabled('canvas');
39476
39609
  }
39477
39610
  canOpenPageSettings() {
39478
- return this.isAuthoringCapabilityEnabled('pageSettings')
39479
- && this.showPageSettingsButton
39480
- && !!(this.pageEditorComponent || this.defaultPageEditor);
39611
+ return this.showPageSettingsButton && this.canInvokePageSettings();
39481
39612
  }
39482
39613
  canOpenWidgetShellSettings() {
39483
39614
  return this.isWidgetShellCapabilityEnabled()
@@ -40211,7 +40342,7 @@ class DynamicWidgetPageComponent {
40211
40342
  return (endpoint.kind === 'component-port' && endpoint.ref.widget === widgetKey);
40212
40343
  }
40213
40344
  openPageSettings() {
40214
- if (!this.canOpenPageSettings())
40345
+ if (!this.canInvokePageSettings())
40215
40346
  return;
40216
40347
  if (!this.settingsPanel)
40217
40348
  return;
@@ -40237,6 +40368,10 @@ class DynamicWidgetPageComponent {
40237
40368
  ref.applied$.subscribe((result) => this.applyPageLayout(result, false));
40238
40369
  ref.saved$.subscribe((result) => this.applyPageLayout(result, true));
40239
40370
  }
40371
+ canInvokePageSettings() {
40372
+ return this.isAuthoringCapabilityEnabled('pageSettings')
40373
+ && !!(this.pageEditorComponent || this.defaultPageEditor);
40374
+ }
40240
40375
  applyWidgetShell(key, result, persist) {
40241
40376
  if (!result)
40242
40377
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/core",
3
- "version": "9.0.37",
3
+ "version": "9.0.38",
4
4
  "description": "Core library for Praxis UI Workspace: types, tokens, services and utilities shared across @praxisui/* packages.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
@@ -6213,7 +6213,9 @@ declare class ApiConfigStorage implements AsyncConfigStorage {
6213
6213
  private resolveKey;
6214
6214
  private inferComponentType;
6215
6215
  private looksLikePageKey;
6216
- private stripQuotes;
6216
+ private resolveReadEtag;
6217
+ private resolveWriteEtag;
6218
+ private normalizeStrongEtag;
6217
6219
  private formatEtag;
6218
6220
  static ɵfac: i0.ɵɵFactoryDeclaration<ApiConfigStorage, never>;
6219
6221
  static ɵprov: i0.ɵɵInjectableDeclaration<ApiConfigStorage>;
@@ -16651,6 +16653,7 @@ declare class DynamicWidgetPageComponent implements OnChanges, OnDestroy {
16651
16653
  private linkReferencesWidget;
16652
16654
  private endpointReferencesWidget;
16653
16655
  openPageSettings(): void;
16656
+ private canInvokePageSettings;
16654
16657
  private applyWidgetShell;
16655
16658
  private constrainWidgetShellResult;
16656
16659
  private restoreWidgetShellFields;