@breadstone/mosaik-elements-angular 0.0.277 → 0.0.278

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.0.278 (2026-05-16)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **overlay:** implement backdrop configuration for overlays ([5b616ceff4](https://github.com/RueDeRennes/mosaik/commit/5b616ceff4))
6
+
1
7
  ## 0.0.277 (2026-05-15)
2
8
 
3
9
  This was a version bump only for mosaik-elements-angular to align it with other projects, there were no code changes.
@@ -5,7 +5,7 @@ import { AbsoluteItemElement, AbsoluteElement, ActionbarGroupElement, ActionbarI
5
5
  import { AbstractControl, FormGroupDirective, NgControl, TouchedChangeEvent, NG_VALUE_ACCESSOR, FormControl, FormArray, FormGroup } from '@angular/forms';
6
6
  import { BreakpointObserver } from '@angular/cdk/layout';
7
7
  import { CssLength, ThemeObserver, ThemeGeneratorServiceLocator, ThemeGenerator, ThemeObserverServiceLocator } from '@breadstone/mosaik-themes';
8
- import { Subscription, filter, of, isObservable, Subject, BehaviorSubject, take, takeUntil, fromEvent, timer, share, Observable } from 'rxjs';
8
+ import { Subscription, filter, of, isObservable, Subject, BehaviorSubject, merge, fromEvent, take, takeUntil, timer, share, Observable } from 'rxjs';
9
9
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
10
10
  import { FORM_FIELD, validate } from '@angular/forms/signals';
11
11
  import { BasePortalOutlet, CdkPortalOutlet, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
@@ -11867,6 +11867,66 @@ class StatelessInjector {
11867
11867
  }
11868
11868
  }
11869
11869
 
11870
+ // #region Imports
11871
+ /**
11872
+ * Coordinates CDK backdrop ownership across consecutive overlay stack segments.
11873
+ *
11874
+ * @internal
11875
+ */
11876
+ class OverlayBackdropStackCoordinator {
11877
+ // #region Fields
11878
+ static _entries = new Array();
11879
+ // #endregion
11880
+ // #region Methods
11881
+ /**
11882
+ * Resolves the effective CDK `hasBackdrop` value for a new overlay.
11883
+ *
11884
+ * @internal
11885
+ */
11886
+ static resolveHasBackdrop(hasBackdrop, options) {
11887
+ const backdropStackKey = options?.backdropStackKey;
11888
+ if (hasBackdrop !== true || options?.backdropStrategy === 'own' || !backdropStackKey) {
11889
+ return hasBackdrop;
11890
+ }
11891
+ return !OverlayBackdropStackCoordinator.hasBackdropInCurrentStack(backdropStackKey);
11892
+ }
11893
+ /**
11894
+ * Registers an overlay with its effective backdrop ownership.
11895
+ *
11896
+ * @internal
11897
+ */
11898
+ static register(overlayRef, hasBackdrop, options) {
11899
+ OverlayBackdropStackCoordinator._entries.push({
11900
+ overlayRef: overlayRef,
11901
+ backdropStackKey: options?.backdropStackKey,
11902
+ hasBackdrop: hasBackdrop === true
11903
+ });
11904
+ }
11905
+ /**
11906
+ * Unregisters an overlay from backdrop stack tracking.
11907
+ *
11908
+ * @internal
11909
+ */
11910
+ static unregister(overlayRef) {
11911
+ const index = OverlayBackdropStackCoordinator._entries.findIndex((entry) => entry.overlayRef === overlayRef);
11912
+ if (index >= 0) {
11913
+ OverlayBackdropStackCoordinator._entries.splice(index, 1);
11914
+ }
11915
+ }
11916
+ static hasBackdropInCurrentStack(backdropStackKey) {
11917
+ for (let index = OverlayBackdropStackCoordinator._entries.length - 1; index >= 0; index--) {
11918
+ const entry = OverlayBackdropStackCoordinator._entries[index];
11919
+ if (entry.backdropStackKey !== backdropStackKey) {
11920
+ return false;
11921
+ }
11922
+ if (entry.hasBackdrop) {
11923
+ return true;
11924
+ }
11925
+ }
11926
+ return false;
11927
+ }
11928
+ }
11929
+
11870
11930
  // #region Imports
11871
11931
  const OVERLAY_INTERACTION_STATE = getOverlayInteractionState();
11872
11932
  /**
@@ -12020,12 +12080,17 @@ class PortalProvider {
12020
12080
  /**
12021
12081
  * @protected
12022
12082
  */
12023
- createOverlay(config) {
12024
- config.positionStrategy = this.createPositionStrategy();
12025
- config.scrollStrategy = this.createScrollStrategy();
12026
- config.panelClass = withOverlayClass(config.panelClass, MOSAIK_CDK_OVERLAY_PANE_CLASS);
12027
- config.backdropClass = withOverlayClass(config.backdropClass, MOSAIK_CDK_BACKDROP_CLASS);
12028
- const overlayRef = this._overlay.create(config);
12083
+ createOverlay(config, options) {
12084
+ const overlayConfig = {
12085
+ ...config,
12086
+ hasBackdrop: OverlayBackdropStackCoordinator.resolveHasBackdrop(config.hasBackdrop, options),
12087
+ positionStrategy: this.createPositionStrategy(),
12088
+ scrollStrategy: this.createScrollStrategy(),
12089
+ panelClass: withOverlayClass(config.panelClass, MOSAIK_CDK_OVERLAY_PANE_CLASS),
12090
+ backdropClass: withOverlayClass(config.backdropClass, MOSAIK_CDK_BACKDROP_CLASS)
12091
+ };
12092
+ const overlayRef = this._overlay.create(overlayConfig);
12093
+ OverlayBackdropStackCoordinator.register(overlayRef, overlayConfig.hasBackdrop, options);
12029
12094
  useBackdropPointerEvents(overlayRef);
12030
12095
  overlayRef.attachments().subscribe(() => useBackdropPointerEvents(overlayRef));
12031
12096
  return overlayRef;
@@ -12075,6 +12140,7 @@ class PortalProvider {
12075
12140
  if (overlayRef.hasAttached()) {
12076
12141
  overlayRef.detach();
12077
12142
  }
12143
+ OverlayBackdropStackCoordinator.unregister(overlayRef);
12078
12144
  OverlayInteractionCoordinator.unregister(overlayRef);
12079
12145
  const index = this._cache.findIndex((x) => x.overlay === overlayRef);
12080
12146
  if (index >= 0) {
@@ -12109,9 +12175,8 @@ function withOverlayClass(value, className) {
12109
12175
  * @internal
12110
12176
  */
12111
12177
  function connectOverlayOutsideClose(overlayRef, closed, close) {
12112
- overlayRef.backdropClick().pipe(filter((event) => OverlayInteractionCoordinator.isTopMostForInteraction(overlayRef, event)), take(1), takeUntil(closed))
12113
- .subscribe(() => close());
12114
- overlayRef.outsidePointerEvents().pipe(filter((event) => OverlayInteractionCoordinator.isTopMostForInteraction(overlayRef, event)), filter((event) => !isOwnedMosaikPortalProjectionEvent(overlayRef, event)), take(1), takeUntil(closed))
12178
+ const ownerDocument = overlayRef.overlayElement.ownerDocument;
12179
+ merge(overlayRef.backdropClick(), overlayRef.outsidePointerEvents(), fromEvent(ownerDocument, 'pointerdown', { capture: true })).pipe(filter((event) => OverlayInteractionCoordinator.isTopMostForInteraction(overlayRef, event)), filter((event) => !isOverlayInteractionEvent(overlayRef, event)), filter((event) => !isOwnedMosaikPortalProjectionEvent(overlayRef, event)), take(1), takeUntil(closed))
12115
12180
  .subscribe(() => close());
12116
12181
  }
12117
12182
  /**
@@ -12147,6 +12212,13 @@ function isOwnedMosaikPortalProjectionEvent(overlayRef, event) {
12147
12212
  return event.composedPath()
12148
12213
  .some((target) => isMosaikPortalProjectionElement(target) && isProjectionOwnedByOverlay(overlayRef, target));
12149
12214
  }
12215
+ function isOverlayInteractionEvent(overlayRef, event) {
12216
+ return event.composedPath()
12217
+ .some((target) => isNode(target) && isComposedDescendantOf(overlayRef.overlayElement, target));
12218
+ }
12219
+ function isNode(target) {
12220
+ return typeof Node !== 'undefined' && target instanceof Node;
12221
+ }
12150
12222
  function isMosaikPortalProjectionElement(target) {
12151
12223
  return typeof HTMLElement !== 'undefined' && target instanceof HTMLElement && target.localName === 'mosaik-portal-projection';
12152
12224
  }
@@ -12234,6 +12306,9 @@ class DialogService extends PortalProvider {
12234
12306
  maxWidth: config?.maxSize?.width,
12235
12307
  maxHeight: config?.maxSize?.height,
12236
12308
  disposeOnNavigation: config?.closeOnNavigation
12309
+ }, {
12310
+ backdropStackKey: 'dialog',
12311
+ backdropStrategy: config?.backdropStrategy
12237
12312
  });
12238
12313
  const portal = this.createPortal(DialogPortalComponent, config);
12239
12314
  const componentRef = this.createComponent(portal, overlayRef, DialogPortalComponent, config);
@@ -15085,6 +15160,9 @@ class DrawerService extends PortalProvider {
15085
15160
  // maxWidth: config?.maxSize?.width,
15086
15161
  // maxHeight: config?.maxSize?.height,
15087
15162
  // disposeOnNavigation: config?.closeOnNavigation
15163
+ }, {
15164
+ backdropStackKey: 'drawer',
15165
+ backdropStrategy: config?.backdropStrategy
15088
15166
  });
15089
15167
  const portal = this.createPortal(DrawerPortalComponent, config);
15090
15168
  const componentRef = this.createComponent(portal, overlayRef, DrawerPortalComponent, config);
@@ -16041,6 +16119,9 @@ class MessageBoxService extends PortalProvider {
16041
16119
  const overlayRef = this.createOverlay({
16042
16120
  hasBackdrop: config?.hasBackdrop ?? true,
16043
16121
  disposeOnNavigation: config?.closeOnNavigation
16122
+ }, {
16123
+ backdropStackKey: 'message-box',
16124
+ backdropStrategy: config?.backdropStrategy
16044
16125
  });
16045
16126
  const portal = this.createPortal(MessageBoxPortalComponent, config);
16046
16127
  const componentRef = this.createComponent(portal, overlayRef, MessageBoxPortalComponent, config);
@@ -17697,6 +17778,9 @@ class SheetService extends PortalProvider {
17697
17778
  const overlayRef = this.createOverlay({
17698
17779
  hasBackdrop: config?.hasBackdrop,
17699
17780
  disposeOnNavigation: config?.closeOnNavigation
17781
+ }, {
17782
+ backdropStackKey: 'sheet',
17783
+ backdropStrategy: config?.backdropStrategy
17700
17784
  });
17701
17785
  const portal = this.createPortal(SheetPortalComponent, config);
17702
17786
  const componentRef = this.createComponent(portal, overlayRef, SheetPortalComponent, config);
@@ -18456,6 +18540,9 @@ class ToastService extends PortalProvider {
18456
18540
  const overlayRef = this.createOverlay({
18457
18541
  hasBackdrop: resolvedConfig?.hasBackdrop,
18458
18542
  disposeOnNavigation: resolvedConfig?.closeOnNavigation
18543
+ }, {
18544
+ backdropStackKey: 'toast',
18545
+ backdropStrategy: resolvedConfig?.backdropStrategy
18459
18546
  });
18460
18547
  const portal = this.createPortal(ToastPortalComponent, resolvedConfig);
18461
18548
  const componentRef = this.createComponent(portal, overlayRef, ToastPortalComponent, resolvedConfig);