@villedemontreal/angular-ui 3.0.0 → 3.1.0

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,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { SecurityContext, Injectable, Inject, Component, ViewEncapsulation, ChangeDetectionStrategy, Attribute, Input, NgModule, Directive, EventEmitter, Output, CUSTOM_ELEMENTS_SCHEMA, ViewChild, forwardRef, InjectionToken, ContentChildren, Optional, HostListener, ContentChild } from '@angular/core';
2
+ import { SecurityContext, Injectable, Inject, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, NgModule, Directive, EventEmitter, Output, CUSTOM_ELEMENTS_SCHEMA, ViewChild, forwardRef, InjectionToken, ContentChildren, Optional, HostListener, ContentChild, Injector, TemplateRef, SkipSelf } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { DOCUMENT, CommonModule } from '@angular/common';
5
5
  import * as i1 from '@angular/platform-browser';
@@ -9,6 +9,15 @@ import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/fo
9
9
  import * as i1$3 from '@angular/cdk/a11y';
10
10
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
11
11
  import * as i2 from '@angular/cdk/collections';
12
+ import * as i1$4 from '@angular/cdk/overlay';
13
+ import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
14
+ import * as i3 from '@angular/cdk/portal';
15
+ import { BasePortalOutlet, CdkPortalOutlet, ComponentPortal, TemplatePortal, PortalModule } from '@angular/cdk/portal';
16
+ import { Subject, filter, take, defer, startWith, Subscription } from 'rxjs';
17
+ import { _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
18
+ import { trigger, state, style, transition, group, animate, query, animateChild } from '@angular/animations';
19
+ import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
20
+ import { ANIMATION_MODULE_TYPE, BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
12
21
 
13
22
  function baoColorToHex(baoColor) {
14
23
  switch (baoColor) {
@@ -213,7 +222,7 @@ const TITLE = 'title';
213
222
  * `<bao-icon svgIcon="heart"></bao-icon>`
214
223
  */
215
224
  class BaoIconComponent {
216
- constructor(elementRef, iconRegistry, renderer, ariaHidden) {
225
+ constructor(elementRef, iconRegistry, renderer) {
217
226
  this.elementRef = elementRef;
218
227
  this.iconRegistry = iconRegistry;
219
228
  this.renderer = renderer;
@@ -221,11 +230,6 @@ class BaoIconComponent {
221
230
  * The size of the icon
222
231
  */
223
232
  this.size = 'x-small';
224
- // If the user has not explicitly set aria-hidden, mark the icon as hidden, as this is
225
- // the right thing to do for the majority of icon use-cases.
226
- if (!ariaHidden) {
227
- this.elementRef.nativeElement.setAttribute('aria-hidden', 'true');
228
- }
229
233
  this._titleId = '';
230
234
  this._title = '';
231
235
  this._svgIcon = '';
@@ -306,6 +310,9 @@ class BaoIconComponent {
306
310
  if (title) {
307
311
  svg = this.addTitleToSVG(svg, title);
308
312
  }
313
+ if (!title) {
314
+ svg.setAttribute('aria-hidden', 'true');
315
+ }
309
316
  this.setSvgElement(svg);
310
317
  }
311
318
  }
@@ -315,16 +322,19 @@ class BaoIconComponent {
315
322
  const titleText = this.renderer.createText(title);
316
323
  this.renderer.appendChild(titleNode, titleText);
317
324
  this.renderer.appendChild(svg, titleNode);
325
+ svg.setAttribute('aria-labelledby', this._titleId);
318
326
  return svg;
319
327
  }
320
328
  generateUniqueTitleId() {
321
329
  return this.title
322
- ? `${this.title}-${Math.random() * 10000000000000000}`
330
+ ? `${this.title
331
+ .replace(/[^A-Z0-9]+/gi, '')
332
+ .toLocaleLowerCase()}-${Math.floor(Math.random() * 10000000000000000)}`
323
333
  : '';
324
334
  }
325
335
  }
326
- BaoIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoIconComponent, deps: [{ token: i0.ElementRef }, { token: BaoIconDictionary }, { token: i0.Renderer2 }, { token: 'aria-hidden', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
327
- BaoIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: BaoIconComponent, selector: "bao-icon", inputs: { color: "color", size: "size", svgIcon: "svgIcon", title: "title" }, host: { attributes: { "role": "img" }, properties: { "class.bao-icon": "true", "class.notranslate": "true", "class.bao-icon-medium": "size === \"medium\"", "class.bao-icon-small": "size === \"small\"", "class.bao-icon-x-small": "size === \"x-small\"", "class.bao-icon-xx-small": "size === \"xx-small\"", "attr.data-bao-icon-type": "\"svg\"", "attr.aria-labelledby": "titleId", "attr.aria-hidden": "!title", "style.color": "hexColor" } }, exportAs: ["baoIcon"], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["bao-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;line-height:normal}bao-icon.bao-icon-medium{height:2.5rem;width:2.5rem}bao-icon.bao-icon-small{height:2rem;width:2rem;line-height:1.75rem}bao-icon.bao-icon-x-small{height:1.5rem;width:1.5rem;line-height:.5rem}bao-icon.bao-icon-xx-small{height:1rem;width:1rem;line-height:.85rem}bao-icon.bao-icon-spinner{animation:spin .75s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
336
+ BaoIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoIconComponent, deps: [{ token: i0.ElementRef }, { token: BaoIconDictionary }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
337
+ BaoIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: BaoIconComponent, selector: "bao-icon", inputs: { color: "color", size: "size", svgIcon: "svgIcon", title: "title" }, host: { attributes: { "role": "img" }, properties: { "class.bao-icon": "true", "class.notranslate": "true", "class.bao-icon-medium": "size === \"medium\"", "class.bao-icon-small": "size === \"small\"", "class.bao-icon-x-small": "size === \"x-small\"", "class.bao-icon-xx-small": "size === \"xx-small\"", "attr.data-bao-icon-type": "\"svg\"", "style.color": "hexColor" } }, exportAs: ["baoIcon"], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: ["bao-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;line-height:normal}bao-icon svg{height:100%;width:100%}bao-icon.bao-icon-medium{height:2.5rem;width:2.5rem}bao-icon.bao-icon-small{height:2rem;width:2rem;line-height:1.75rem}bao-icon.bao-icon-x-small{height:1.5rem;width:1.5rem;line-height:.5rem}bao-icon.bao-icon-xx-small{height:1rem;width:1rem;line-height:.85rem}bao-icon.bao-icon-spinner{animation:spin .75s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
328
338
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoIconComponent, decorators: [{
329
339
  type: Component,
330
340
  args: [{ template: '<ng-content></ng-content>', selector: 'bao-icon', exportAs: 'baoIcon', host: {
@@ -337,14 +347,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImpor
337
347
  '[class.bao-icon-x-small]': 'size === "x-small"',
338
348
  '[class.bao-icon-xx-small]': 'size === "xx-small"',
339
349
  '[attr.data-bao-icon-type]': '"svg"',
340
- '[attr.aria-labelledby]': 'titleId',
341
- '[attr.aria-hidden]': '!title',
342
350
  '[style.color]': 'hexColor'
343
- }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["bao-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;line-height:normal}bao-icon.bao-icon-medium{height:2.5rem;width:2.5rem}bao-icon.bao-icon-small{height:2rem;width:2rem;line-height:1.75rem}bao-icon.bao-icon-x-small{height:1.5rem;width:1.5rem;line-height:.5rem}bao-icon.bao-icon-xx-small{height:1rem;width:1rem;line-height:.85rem}bao-icon.bao-icon-spinner{animation:spin .75s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
344
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: BaoIconDictionary }, { type: i0.Renderer2 }, { type: undefined, decorators: [{
345
- type: Attribute,
346
- args: ['aria-hidden']
347
- }] }]; }, propDecorators: { color: [{
351
+ }, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["bao-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;line-height:normal}bao-icon svg{height:100%;width:100%}bao-icon.bao-icon-medium{height:2.5rem;width:2.5rem}bao-icon.bao-icon-small{height:2rem;width:2rem;line-height:1.75rem}bao-icon.bao-icon-x-small{height:1.5rem;width:1.5rem;line-height:.5rem}bao-icon.bao-icon-xx-small{height:1rem;width:1rem;line-height:.85rem}bao-icon.bao-icon-spinner{animation:spin .75s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
352
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: BaoIconDictionary }, { type: i0.Renderer2 }]; }, propDecorators: { color: [{
348
353
  type: Input
349
354
  }], size: [{
350
355
  type: Input
@@ -2930,6 +2935,933 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImpor
2930
2935
  * See LICENSE file in the project root for full license information.
2931
2936
  */
2932
2937
 
2938
+ /*
2939
+ * Copyright (c) 2022 Ville de Montreal. All rights reserved.
2940
+ * Licensed under the MIT license.
2941
+ * See LICENSE file in the project root for full license information.
2942
+ */
2943
+ /**
2944
+ * Animations used by MatDialog.
2945
+ * @docs-private
2946
+ */
2947
+ const baoModalAnimations = {
2948
+ /** Animation that is applied on the modal container by default. */
2949
+ modalContainer: trigger('modalContainer', [
2950
+ // Note: The `enter` animation transitions to `transform: none`, because for some reason
2951
+ // specifying the transform explicitly, causes IE both to blur the modal content and
2952
+ // decimate the animation performance. Leaving it as `none` solves both issues.
2953
+ state('void, exit', style({ opacity: 0, transform: 'scale(0.7)' })),
2954
+ state('enter', style({ transform: 'none' })),
2955
+ transition('* => enter', group([
2956
+ animate('150ms cubic-bezier(0, 0, 0.2, 1)', style({ transform: 'none', opacity: 1 })),
2957
+ query('@*', animateChild(), { optional: true })
2958
+ ])),
2959
+ transition('* => void, * => exit', group([
2960
+ animate('75ms cubic-bezier(0.4, 0.0, 0.2, 1)', style({ opacity: 0 })),
2961
+ query('@*', animateChild(), { optional: true })
2962
+ ]))
2963
+ ])
2964
+ };
2965
+
2966
+ /*
2967
+ * Copyright (c) 2022 Ville de Montreal. All rights reserved.
2968
+ * Licensed under the MIT license.
2969
+ * See LICENSE file in the project root for full license information.
2970
+ */
2971
+ var eModalDesktopWidthSize;
2972
+ (function (eModalDesktopWidthSize) {
2973
+ eModalDesktopWidthSize["SMALL"] = "bao-modal-sm";
2974
+ eModalDesktopWidthSize["MEDIUM"] = "bao-modal-md";
2975
+ eModalDesktopWidthSize["LARGE"] = "bao-modal-lg"; // Full width minus 32px (global margin : left and rigth)
2976
+ })(eModalDesktopWidthSize || (eModalDesktopWidthSize = {}));
2977
+ var eModalMobileWidthSize;
2978
+ (function (eModalMobileWidthSize) {
2979
+ eModalMobileWidthSize["FULL"] = "bao-modal-mobil-full";
2980
+ eModalMobileWidthSize["COMPACT"] = "bao-modal-mobil-compact"; // 300px
2981
+ })(eModalMobileWidthSize || (eModalMobileWidthSize = {}));
2982
+ /**
2983
+ * Configuration for opening a modal dialog with the BaoModal service.
2984
+ */
2985
+ class BaoModalInitialConfig {
2986
+ constructor() {
2987
+ /** The ARIA role of the dialog element. */
2988
+ this.role = 'dialog';
2989
+ /** Custom class for the overlay pane. */
2990
+ this.panelClass = '';
2991
+ /** Whether the dialog has a backdrop. */
2992
+ this.hasBackdrop = true;
2993
+ /** Custom class for the backdrop. */
2994
+ this.backdropClass = '';
2995
+ /** Whether the user can use escape or clicking on the backdrop to close the modal. */
2996
+ this.disableClose = false;
2997
+ /** Width of the dialog. */
2998
+ this.width = '';
2999
+ /** Height of the dialog. */
3000
+ this.height = '';
3001
+ /** Max-width of the dialog. If a number is provided, assumes pixel units. Defaults to 80vw. */
3002
+ this.maxWidth = '80vw';
3003
+ /** Data being injected into the child component. */
3004
+ this.data = null;
3005
+ /** ID of the element that describes the dialog. */
3006
+ this.ariaDescribedBy = null;
3007
+ /** ID of the element that labels the dialog. */
3008
+ this.ariaLabelledBy = null;
3009
+ /** Aria label to assign to the dialog element. */
3010
+ this.ariaLabel = null;
3011
+ /**
3012
+ * Where the dialog should focus on open.
3013
+ */
3014
+ this.autoFocus = 'first-tabbable';
3015
+ /**
3016
+ * Whether the dialog should restore focus to the
3017
+ * previously-focused element, after it's closed.
3018
+ */
3019
+ this.restoreFocus = true;
3020
+ /** Whether to wait for the opening animation to finish before trapping focus. */
3021
+ this.delayFocusTrap = true;
3022
+ /**
3023
+ * Whether the dialog should close when the user goes backwards/forwards in history.
3024
+ * Note that this usually doesn't include clicking on links (unless the user is using
3025
+ * the `HashLocationStrategy`).
3026
+ */
3027
+ this.closeOnNavigation = true;
3028
+ }
3029
+ }
3030
+
3031
+ /**
3032
+ * Throws an exception for the case when a ComponentPortal is
3033
+ * attached to a DomPortalOutlet without an origin.
3034
+ * @docs-private
3035
+ */
3036
+ function throwBaoModalContentAlreadyAttachedError() {
3037
+ throw Error('Attempting to attach modal content after content is already attached');
3038
+ }
3039
+ /**
3040
+ * Base class for the `BaoModalContainer`. The base class does not implement
3041
+ * animations as these are left to implementers of the modal container.
3042
+ */
3043
+ class _BaoModalContainerBase extends BasePortalOutlet {
3044
+ constructor(_elementRef, _focusTrapFactory, _changeDetectorRef, _document,
3045
+ /** The modal configuration. */
3046
+ _config, _interactivityChecker, _ngZone, _focusMonitor) {
3047
+ super();
3048
+ this._elementRef = _elementRef;
3049
+ this._focusTrapFactory = _focusTrapFactory;
3050
+ this._changeDetectorRef = _changeDetectorRef;
3051
+ this._config = _config;
3052
+ this._interactivityChecker = _interactivityChecker;
3053
+ this._ngZone = _ngZone;
3054
+ this._focusMonitor = _focusMonitor;
3055
+ /** Emits when an animation state changes. */
3056
+ this._animationStateChanged = new EventEmitter();
3057
+ /**
3058
+ * Type of interaction that led to the modal being closed. This is used to determine
3059
+ * whether the focus style will be applied when returning focus to its original location
3060
+ * after the modal is closed.
3061
+ */
3062
+ this._closeInteractionType = null;
3063
+ /** Element that was focused before the modal was opened. Save this to restore upon close. */
3064
+ this._elementFocusedBeforeDialogWasOpened = null;
3065
+ this._ariaLabelledBy = _config.ariaLabelledBy || null;
3066
+ this._document = _document;
3067
+ }
3068
+ /** Initializes the modal container with the attached content. */
3069
+ _initializeWithAttachedContent() {
3070
+ this._setupFocusTrap();
3071
+ // Save the previously focused element. This element will be re-focused
3072
+ // when the modal closes.
3073
+ this._capturePreviouslyFocusedElement();
3074
+ }
3075
+ /**
3076
+ * Attach a ComponentPortal as content to this modal container.
3077
+ */
3078
+ attachComponentPortal(portal) {
3079
+ return this._portalOutlet.attachComponentPortal(portal);
3080
+ }
3081
+ /**
3082
+ * Attach a TemplatePortal as content to this modal container.
3083
+ */
3084
+ attachTemplatePortal(portal) {
3085
+ return this._portalOutlet.attachTemplatePortal(portal);
3086
+ }
3087
+ /** Moves focus back into the modal if it was moved out. */
3088
+ async _recaptureFocus() {
3089
+ if (!this._containsFocus()) {
3090
+ await this._trapFocus();
3091
+ }
3092
+ }
3093
+ /**
3094
+ * Moves the focus inside the focus trap. When autoFocus is not set to 'modal', if focus
3095
+ * cannot be moved then focus will go to the modal container.
3096
+ */
3097
+ async _trapFocus() {
3098
+ const element = this._elementRef.nativeElement;
3099
+ // If were to attempt to focus immediately, then the content of the modal would not yet be
3100
+ // ready in instances where change detection has to run first. To deal with this, we simply
3101
+ // wait for the microtask queue to be empty when setting focus when autoFocus isn't set to
3102
+ // modal. If the element inside the modal can't be focused, then the container is focused
3103
+ // so the user can't tab into other elements behind it.
3104
+ switch (this._config.autoFocus) {
3105
+ case 'modal':
3106
+ // Ensure that focus is on the modal container. It's possible that a different
3107
+ // component tried to move focus while the open animation was running. See:
3108
+ // https://github.com/angular/components/issues/16215. Note that we only want to do this
3109
+ // if the focus isn't inside the modal already, because it's possible that the consumer
3110
+ // turned off `autoFocus` in order to move focus themselves.
3111
+ if (!this._containsFocus()) {
3112
+ element.focus();
3113
+ }
3114
+ break;
3115
+ case 'first-tabbable':
3116
+ // If we weren't able to find a focusable element in the modal, then focus the modal
3117
+ // container instead.
3118
+ const focusedSuccessfully = await this._focusTrap.focusInitialElementWhenReady();
3119
+ if (!focusedSuccessfully) {
3120
+ this._focusDialogContainer();
3121
+ }
3122
+ break;
3123
+ case 'first-heading':
3124
+ this._focusByCssSelector('h1, h2, h3, h4, h5, h6, [role="heading"]');
3125
+ break;
3126
+ default:
3127
+ this._focusByCssSelector(this._config.autoFocus);
3128
+ break;
3129
+ }
3130
+ }
3131
+ /** Restores focus to the element that was focused before the modal opened. */
3132
+ _restoreFocus() {
3133
+ const previousElement = this._elementFocusedBeforeDialogWasOpened;
3134
+ // We need the extra check, because IE can set the `activeElement` to null in some cases.
3135
+ if (this._config.restoreFocus &&
3136
+ previousElement &&
3137
+ typeof previousElement.focus === 'function') {
3138
+ const activeElement = _getFocusedElementPierceShadowDom();
3139
+ const element = this._elementRef.nativeElement;
3140
+ // Make sure that focus is still inside the modal or is on the body (usually because a
3141
+ // non-focusable element like the backdrop was clicked) before moving it. It's possible that
3142
+ // the consumer moved it themselves before the animation was done, in which case we shouldn't
3143
+ // do anything.
3144
+ if (!activeElement ||
3145
+ activeElement === this._document.body ||
3146
+ activeElement === element ||
3147
+ element.contains(activeElement)) {
3148
+ if (this._focusMonitor) {
3149
+ this._focusMonitor.focusVia(previousElement, this._closeInteractionType);
3150
+ this._closeInteractionType = null;
3151
+ }
3152
+ else {
3153
+ previousElement.focus();
3154
+ }
3155
+ }
3156
+ }
3157
+ if (this._focusTrap) {
3158
+ this._focusTrap.destroy();
3159
+ }
3160
+ }
3161
+ /**
3162
+ * Focuses the provided element. If the element is not focusable, it will add a tabIndex
3163
+ * attribute to forcefully focus it. The attribute is removed after focus is moved.
3164
+ */
3165
+ _forceFocus(element, options) {
3166
+ if (!this._interactivityChecker.isFocusable(element)) {
3167
+ element.tabIndex = -1;
3168
+ // The tabindex attribute should be removed to avoid navigating to that element again
3169
+ this._ngZone.runOutsideAngular(() => {
3170
+ element.addEventListener('blur', () => element.removeAttribute('tabindex'));
3171
+ element.addEventListener('mousedown', () => element.removeAttribute('tabindex'));
3172
+ });
3173
+ }
3174
+ element.focus(options);
3175
+ }
3176
+ /**
3177
+ * Focuses the first element that matches the given selector within the focus trap.
3178
+ */
3179
+ _focusByCssSelector(selector, options) {
3180
+ const elementToFocus = this._elementRef.nativeElement.querySelector(selector);
3181
+ if (elementToFocus) {
3182
+ this._forceFocus(elementToFocus, options);
3183
+ }
3184
+ }
3185
+ /** Sets up the focus trap. */
3186
+ _setupFocusTrap() {
3187
+ this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
3188
+ }
3189
+ /** Captures the element that was focused before the modal was opened. */
3190
+ _capturePreviouslyFocusedElement() {
3191
+ if (this._document) {
3192
+ this._elementFocusedBeforeDialogWasOpened =
3193
+ _getFocusedElementPierceShadowDom();
3194
+ }
3195
+ }
3196
+ /** Focuses the modal container. */
3197
+ _focusDialogContainer() {
3198
+ // Note that there is no focus method when rendering on the server.
3199
+ if (this._elementRef.nativeElement.focus) {
3200
+ this._elementRef.nativeElement.focus();
3201
+ }
3202
+ }
3203
+ /** Returns whether focus is inside the modal. */
3204
+ _containsFocus() {
3205
+ const element = this._elementRef.nativeElement;
3206
+ const activeElement = _getFocusedElementPierceShadowDom();
3207
+ return element === activeElement || element.contains(activeElement);
3208
+ }
3209
+ }
3210
+ _BaoModalContainerBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: _BaoModalContainerBase, deps: [{ token: i0.ElementRef }, { token: i1$3.ConfigurableFocusTrapFactory }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT, optional: true }, { token: BaoModalInitialConfig }, { token: i1$3.InteractivityChecker }, { token: i0.NgZone }, { token: i1$3.FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive });
3211
+ _BaoModalContainerBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: _BaoModalContainerBase, viewQueries: [{ propertyName: "_portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
3212
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: _BaoModalContainerBase, decorators: [{
3213
+ type: Directive
3214
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$3.ConfigurableFocusTrapFactory }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
3215
+ type: Optional
3216
+ }, {
3217
+ type: Inject,
3218
+ args: [DOCUMENT]
3219
+ }] }, { type: BaoModalInitialConfig }, { type: i1$3.InteractivityChecker }, { type: i0.NgZone }, { type: i1$3.FocusMonitor }]; }, propDecorators: { _portalOutlet: [{
3220
+ type: ViewChild,
3221
+ args: [CdkPortalOutlet, { static: true }]
3222
+ }] } });
3223
+ class BaoModalContainer extends _BaoModalContainerBase {
3224
+ constructor() {
3225
+ super(...arguments);
3226
+ /** State of the modal animation. */
3227
+ this._state = 'enter';
3228
+ }
3229
+ /** Callback, invoked whenever an animation on the host completes. */
3230
+ async _onAnimationDone({ toState, totalTime }) {
3231
+ if (toState === 'enter') {
3232
+ await this._trapFocus();
3233
+ this._animationStateChanged.next({ state: 'opened', totalTime });
3234
+ }
3235
+ else if (toState === 'exit') {
3236
+ this._restoreFocus();
3237
+ this._animationStateChanged.next({ state: 'closed', totalTime });
3238
+ }
3239
+ }
3240
+ /** Callback, invoked when an animation on the host starts. */
3241
+ _onAnimationStart({ toState, totalTime }) {
3242
+ if (toState === 'enter') {
3243
+ this._animationStateChanged.next({ state: 'opening', totalTime });
3244
+ }
3245
+ else if (toState === 'exit' || toState === 'void') {
3246
+ this._animationStateChanged.next({ state: 'closing', totalTime });
3247
+ }
3248
+ }
3249
+ /** Starts the modal exit animation. */
3250
+ _startExitAnimation() {
3251
+ this._state = 'exit';
3252
+ // Mark the container for check so it can react if the
3253
+ // view container is using OnPush change detection.
3254
+ this._changeDetectorRef.markForCheck();
3255
+ }
3256
+ }
3257
+ BaoModalContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalContainer, deps: null, target: i0.ɵɵFactoryTarget.Component });
3258
+ BaoModalContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.1.1", type: BaoModalContainer, selector: "bao-modal-container", host: { attributes: { "tabindex": "-1", "aria-modal": "true" }, listeners: { "@modalContainer.start": "_onAnimationStart($event)", "@modalContainer.done": "_onAnimationDone($event)" }, properties: { "id": "_id", "attr.role": "_config.role", "attr.aria-labelledby": "_config.ariaLabel ? null : _ariaLabelledBy", "attr.aria-label": "_config.ariaLabel", "attr.aria-describedby": "_config.ariaDescribedBy || null", "@modalContainer": "_state" }, classAttribute: "bao-modal-container" }, usesInheritance: true, ngImport: i0, template: "<ng-template cdkPortalOutlet></ng-template>\n", styles: [".bao-container{padding-right:16px;padding-left:16px;margin-right:auto;margin-left:auto;width:100%}@media (min-width: 576px){.bao-container{max-width:576px}}@media (min-width: 768px){.bao-container{max-width:768px}}@media (min-width: 992px){.bao-container{max-width:992px}}@media (min-width: 1200px){.bao-container{max-width:1200px}}.bao-row{display:flex;flex-wrap:wrap;margin-right:-16px;margin-left:-16px}.bao-col-12,.bao-col-lg-7{position:relative;width:100%;padding-right:1rem;padding-left:1rem}@media (min-width: 992px){.bao-col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex}.cdk-overlay-pane.bao-modal-mobil-full{width:100%;height:100%}.cdk-overlay-pane.bao-modal-mobil-compact{width:300px;height:100%}@media (min-width: 768px){.cdk-overlay-pane{width:500px;height:auto}.cdk-overlay-pane.bao-modal-lg{width:calc(100% - 4rem);height:calc(100% - 4rem)}.cdk-overlay-pane.bao-modal-md,.cdk-overlay-pane.bao-modal-sm{width:500px;height:auto}}@media (min-width: 992px){.cdk-overlay-pane{width:500px;height:auto}.cdk-overlay-pane.bao-modal-lg{width:calc(100% - 4rem);height:calc(100% - 4rem)}.cdk-overlay-pane.bao-modal-md{width:800px;height:auto}.cdk-overlay-pane.bao-modal-sm{width:500px;height:auto}}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.5}.cdk-high-contrast-active .cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}.cdk-overlay-dark-backdrop{background:black}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:.5}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.bao-modal-container{display:block;overflow:auto;width:100%;height:100%;min-height:inherit;max-height:inherit;background-color:#fff;background-clip:padding-box;border:0 solid rgba(0,0,0,.2);border-radius:.5rem;outline:0}.bao-modal-content{display:flex;flex-direction:column;height:100%}.bao-modal-header{flex:0 0 auto;display:flex;align-items:flex-start;justify-content:space-between;border-bottom:1px solid #ced4da;border-top-left-radius:.5rem;border-top-right-radius:.5rem}.bao-modal-header .bao-modal-title{font-size:1rem;line-height:1.5rem;margin:1rem 0 1rem 1rem}.bao-modal-header button{margin:.5rem}.bao-modal-body{display:block;padding:1rem;overflow:auto;flex-grow:1}@media (min-width: 768px){.bao-modal-body{padding:2rem}}.bao-modal-footer{display:flex;flex-wrap:wrap;padding:1rem;border-top:1px solid #ced4da;border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.bao-modal-footer.bao-modal-footer-order{justify-content:unset;flex-direction:column-reverse}.bao-modal-footer button{text-align:center}.bao-modal-footer .bao-button-primary,.bao-modal-footer .bao-button-secondary{width:100%;display:block}.bao-modal-footer .bao-button-secondary{margin-bottom:.5rem}.bao-modal-footer .bao-button-tertiary{display:none}@media (min-width: 768px){.bao-modal-footer{justify-content:flex-end}.bao-modal-footer.bao-modal-footer-order{flex-direction:row-reverse}.bao-modal-footer .bao-button-primary{margin-left:1rem}.bao-modal-footer .bao-button-secondary{margin-bottom:0}.bao-modal-footer .bao-button-primary,.bao-modal-footer .bao-button-secondary{width:auto}.bao-modal-footer .bao-button-tertiary{display:block}}\n"], directives: [{ type: i3.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [baoModalAnimations.modalContainer], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
3259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalContainer, decorators: [{
3260
+ type: Component,
3261
+ args: [{ selector: 'bao-modal-container', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, animations: [baoModalAnimations.modalContainer], host: {
3262
+ class: 'bao-modal-container',
3263
+ tabindex: '-1',
3264
+ 'aria-modal': 'true',
3265
+ '[id]': '_id',
3266
+ '[attr.role]': '_config.role',
3267
+ '[attr.aria-labelledby]': '_config.ariaLabel ? null : _ariaLabelledBy',
3268
+ '[attr.aria-label]': '_config.ariaLabel',
3269
+ '[attr.aria-describedby]': '_config.ariaDescribedBy || null',
3270
+ '[@modalContainer]': '_state',
3271
+ '(@modalContainer.start)': '_onAnimationStart($event)',
3272
+ '(@modalContainer.done)': '_onAnimationDone($event)'
3273
+ }, template: "<ng-template cdkPortalOutlet></ng-template>\n", styles: [".bao-container{padding-right:16px;padding-left:16px;margin-right:auto;margin-left:auto;width:100%}@media (min-width: 576px){.bao-container{max-width:576px}}@media (min-width: 768px){.bao-container{max-width:768px}}@media (min-width: 992px){.bao-container{max-width:992px}}@media (min-width: 1200px){.bao-container{max-width:1200px}}.bao-row{display:flex;flex-wrap:wrap;margin-right:-16px;margin-left:-16px}.bao-col-12,.bao-col-lg-7{position:relative;width:100%;padding-right:1rem;padding-left:1rem}@media (min-width: 992px){.bao-col-lg-7{flex:0 0 58.33333%;max-width:58.33333%}}.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex}.cdk-overlay-pane.bao-modal-mobil-full{width:100%;height:100%}.cdk-overlay-pane.bao-modal-mobil-compact{width:300px;height:100%}@media (min-width: 768px){.cdk-overlay-pane{width:500px;height:auto}.cdk-overlay-pane.bao-modal-lg{width:calc(100% - 4rem);height:calc(100% - 4rem)}.cdk-overlay-pane.bao-modal-md,.cdk-overlay-pane.bao-modal-sm{width:500px;height:auto}}@media (min-width: 992px){.cdk-overlay-pane{width:500px;height:auto}.cdk-overlay-pane.bao-modal-lg{width:calc(100% - 4rem);height:calc(100% - 4rem)}.cdk-overlay-pane.bao-modal-md{width:800px;height:auto}.cdk-overlay-pane.bao-modal-sm{width:500px;height:auto}}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity .4s cubic-bezier(.25,.8,.25,1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.5}.cdk-high-contrast-active .cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}.cdk-overlay-dark-backdrop{background:black}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:.5}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.bao-modal-container{display:block;overflow:auto;width:100%;height:100%;min-height:inherit;max-height:inherit;background-color:#fff;background-clip:padding-box;border:0 solid rgba(0,0,0,.2);border-radius:.5rem;outline:0}.bao-modal-content{display:flex;flex-direction:column;height:100%}.bao-modal-header{flex:0 0 auto;display:flex;align-items:flex-start;justify-content:space-between;border-bottom:1px solid #ced4da;border-top-left-radius:.5rem;border-top-right-radius:.5rem}.bao-modal-header .bao-modal-title{font-size:1rem;line-height:1.5rem;margin:1rem 0 1rem 1rem}.bao-modal-header button{margin:.5rem}.bao-modal-body{display:block;padding:1rem;overflow:auto;flex-grow:1}@media (min-width: 768px){.bao-modal-body{padding:2rem}}.bao-modal-footer{display:flex;flex-wrap:wrap;padding:1rem;border-top:1px solid #ced4da;border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.bao-modal-footer.bao-modal-footer-order{justify-content:unset;flex-direction:column-reverse}.bao-modal-footer button{text-align:center}.bao-modal-footer .bao-button-primary,.bao-modal-footer .bao-button-secondary{width:100%;display:block}.bao-modal-footer .bao-button-secondary{margin-bottom:.5rem}.bao-modal-footer .bao-button-tertiary{display:none}@media (min-width: 768px){.bao-modal-footer{justify-content:flex-end}.bao-modal-footer.bao-modal-footer-order{flex-direction:row-reverse}.bao-modal-footer .bao-button-primary{margin-left:1rem}.bao-modal-footer .bao-button-secondary{margin-bottom:0}.bao-modal-footer .bao-button-primary,.bao-modal-footer .bao-button-secondary{width:auto}.bao-modal-footer .bao-button-tertiary{display:block}}\n"] }]
3274
+ }] });
3275
+
3276
+ // Counter for unique modal ids.
3277
+ let uniqueId = 0;
3278
+ /**
3279
+ * Reference to a modal opened via the BaoModalService.
3280
+ */
3281
+ class BaoModalRef {
3282
+ constructor(_overlayRef, _containerInstance,
3283
+ /** Id of the modal. */
3284
+ id = `bao-modal-${uniqueId++}`) {
3285
+ this._overlayRef = _overlayRef;
3286
+ this._containerInstance = _containerInstance;
3287
+ this.id = id;
3288
+ /** Whether the user is allowed to close the modal. */
3289
+ this.disableClose = this._containerInstance._config.disableClose;
3290
+ /** Subject for notifying the user that the modal has finished opening. */
3291
+ this._afterOpened = new Subject();
3292
+ /** Subject for notifying the user that the modal has finished closing. */
3293
+ this._afterClosed = new Subject();
3294
+ /** Subject for notifying the user that the modal has started closing. */
3295
+ this._beforeClosed = new Subject();
3296
+ /** Current state of the modal. */
3297
+ this._state = 0 /* OPEN */;
3298
+ // Pass the id along to the container.
3299
+ _containerInstance._id = id;
3300
+ // Emit when opening animation completes
3301
+ _containerInstance._animationStateChanged
3302
+ .pipe(filter(event => event.state === 'opened'), take(1))
3303
+ .subscribe(() => {
3304
+ this._afterOpened.next();
3305
+ this._afterOpened.complete();
3306
+ });
3307
+ // Dispose overlay when closing animation is complete
3308
+ _containerInstance._animationStateChanged
3309
+ .pipe(filter(event => event.state === 'closed'), take(1))
3310
+ .subscribe(() => {
3311
+ clearTimeout(this._closeFallbackTimeout);
3312
+ this._finishModalClose();
3313
+ });
3314
+ _overlayRef.detachments().subscribe(() => {
3315
+ this._beforeClosed.next(this._result);
3316
+ this._beforeClosed.complete();
3317
+ this._afterClosed.next(this._result);
3318
+ this._afterClosed.complete();
3319
+ this.componentInstance = null;
3320
+ this._overlayRef.dispose();
3321
+ });
3322
+ _overlayRef
3323
+ .keydownEvents()
3324
+ .pipe(filter(event => {
3325
+ return (event.keyCode === ESCAPE &&
3326
+ !this.disableClose &&
3327
+ !hasModifierKey(event));
3328
+ }))
3329
+ .subscribe(event => {
3330
+ event.preventDefault();
3331
+ _closeModalVia(this, 'keyboard');
3332
+ });
3333
+ _overlayRef.backdropClick().subscribe(async () => {
3334
+ if (this.disableClose) {
3335
+ await this._containerInstance._recaptureFocus();
3336
+ }
3337
+ else {
3338
+ _closeModalVia(this, 'mouse');
3339
+ }
3340
+ });
3341
+ }
3342
+ /**
3343
+ * Close the modal.
3344
+ * @param modalResult Optional result to return to the modal opener.
3345
+ */
3346
+ close(modalResult) {
3347
+ this._result = modalResult;
3348
+ // Transition the backdrop in parallel to the modal.
3349
+ this._containerInstance._animationStateChanged
3350
+ .pipe(filter(event => event.state === 'closing'), take(1))
3351
+ .subscribe(event => {
3352
+ this._beforeClosed.next(modalResult);
3353
+ this._beforeClosed.complete();
3354
+ this._overlayRef.detachBackdrop();
3355
+ // The logic that disposes of the overlay depends on the exit animation completing, however
3356
+ // it isn't guaranteed if the parent view is destroyed while it's running. Add a fallback
3357
+ // timeout which will clean everything up if the animation hasn't fired within the specified
3358
+ // amount of time plus 100ms. We don't need to run this outside the NgZone, because for the
3359
+ // vast majority of cases the timeout will have been cleared before it has the chance to fire.
3360
+ this._closeFallbackTimeout = setTimeout(() => this._finishModalClose(), event.totalTime + 100);
3361
+ });
3362
+ this._state = 1 /* CLOSING */;
3363
+ this._containerInstance._startExitAnimation();
3364
+ }
3365
+ /**
3366
+ * Gets an observable that is notified when the modal is finished opening.
3367
+ */
3368
+ afterOpened() {
3369
+ return this._afterOpened;
3370
+ }
3371
+ /**
3372
+ * Gets an observable that is notified when the modal is finished closing.
3373
+ */
3374
+ afterClosed() {
3375
+ return this._afterClosed;
3376
+ }
3377
+ /**
3378
+ * Gets an observable that is notified when the modal has started closing.
3379
+ */
3380
+ beforeClosed() {
3381
+ return this._beforeClosed;
3382
+ }
3383
+ /**
3384
+ * Gets an observable that emits when the overlay's backdrop has been clicked.
3385
+ */
3386
+ backdropClick() {
3387
+ return this._overlayRef.backdropClick();
3388
+ }
3389
+ /**
3390
+ * Gets an observable that emits when keydown events are targeted on the overlay.
3391
+ */
3392
+ keydownEvents() {
3393
+ return this._overlayRef.keydownEvents();
3394
+ }
3395
+ /**
3396
+ * Updates the dialog's position.
3397
+ */
3398
+ updatePosition(position) {
3399
+ const strategy = this._getPositionStrategy();
3400
+ if (position && (position.left || position.right)) {
3401
+ position.left
3402
+ ? strategy.left(position.left)
3403
+ : strategy.right(position.right);
3404
+ }
3405
+ else {
3406
+ strategy.centerHorizontally();
3407
+ }
3408
+ if (position && (position.top || position.bottom)) {
3409
+ position.top
3410
+ ? strategy.top(position.top)
3411
+ : strategy.bottom(position.bottom);
3412
+ }
3413
+ else {
3414
+ strategy.centerVertically();
3415
+ }
3416
+ this._overlayRef.updatePosition();
3417
+ return this;
3418
+ }
3419
+ /**
3420
+ * Updates the modal's width and height.
3421
+ */
3422
+ updateSize(width = '', height = '') {
3423
+ this._overlayRef.updateSize({ width, height });
3424
+ this._overlayRef.updatePosition();
3425
+ return this;
3426
+ }
3427
+ /** Add a CSS class or an array of classes to the overlay pane. */
3428
+ addPanelClass(classes) {
3429
+ this._overlayRef.addPanelClass(classes);
3430
+ return this;
3431
+ }
3432
+ /** Remove a CSS class or an array of classes from the overlay pane. */
3433
+ removePanelClass(classes) {
3434
+ this._overlayRef.removePanelClass(classes);
3435
+ return this;
3436
+ }
3437
+ /** Gets the current state of the modal's lifecycle. */
3438
+ getState() {
3439
+ return this._state;
3440
+ }
3441
+ /**
3442
+ * Finishes the modal close by updating the state of the modal
3443
+ * and disposing the overlay.
3444
+ */
3445
+ _finishModalClose() {
3446
+ this._state = 2 /* CLOSED */;
3447
+ this._overlayRef.dispose();
3448
+ }
3449
+ /** Fetches the position strategy object from the overlay ref. */
3450
+ _getPositionStrategy() {
3451
+ return this._overlayRef.getConfig()
3452
+ .positionStrategy;
3453
+ }
3454
+ }
3455
+ /**
3456
+ * Closes the modal with the specified interaction type. This is currently not part of
3457
+ * `BaoModalRef` as that would conflict with custom modal ref mocks provided in tests.
3458
+ * More details. See: https://github.com/angular/components/pull/9257#issuecomment-651342226.
3459
+ */
3460
+ function _closeModalVia(ref, interactionType, result) {
3461
+ // Some mock modal ref instances in tests do not have the `_containerInstance` property.
3462
+ // For those, we keep the behavior as is and do not deal with the interaction type.
3463
+ if (ref._containerInstance !== undefined) {
3464
+ ref._containerInstance._closeInteractionType = interactionType;
3465
+ }
3466
+ return ref.close(result);
3467
+ }
3468
+
3469
+ /*
3470
+ * Copyright (c) 2022 Ville de Montreal. All rights reserved.
3471
+ * Licensed under the MIT license.
3472
+ * See LICENSE file in the project root for full license information.
3473
+ */
3474
+ /** Injection token that can be used to access the data that was passed in to a modal. */
3475
+ const BAO_MODAL_DATA = new InjectionToken('BaoModalData');
3476
+ class BaoModalBase {
3477
+ constructor(_overlay, _injector, _parentModal, _overlayContainer, _modalRefConstructor, _modalContainerType, _modalDataToken, _animationMode) {
3478
+ this._overlay = _overlay;
3479
+ this._injector = _injector;
3480
+ this._parentModal = _parentModal;
3481
+ this._overlayContainer = _overlayContainer;
3482
+ this._modalRefConstructor = _modalRefConstructor;
3483
+ this._modalContainerType = _modalContainerType;
3484
+ this._modalDataToken = _modalDataToken;
3485
+ this._animationMode = _animationMode;
3486
+ this.afterAllClosed = defer(() => this.openModals.length
3487
+ ? this.getAfterAllClosed()
3488
+ : this.getAfterAllClosed().pipe(startWith(undefined)));
3489
+ this._openModalsAtThisLevel = [];
3490
+ this._afterAllClosedAtThisLevel = new Subject();
3491
+ this._afterOpenedAtThisLevel = new Subject();
3492
+ this._ariaHiddenElements = new Map();
3493
+ this._modalAnimatingOpen = false;
3494
+ }
3495
+ /** Keeps track of the currently-open modals. */
3496
+ get openModals() {
3497
+ return this._parentModal
3498
+ ? this._parentModal.openModals
3499
+ : this._openModalsAtThisLevel;
3500
+ }
3501
+ /** Stream that emits when a modal has been opened. */
3502
+ get afterOpened() {
3503
+ // Maybe typescript version difference
3504
+ return this._parentModal
3505
+ ? this._parentModal.afterOpened
3506
+ : this._afterOpenedAtThisLevel;
3507
+ }
3508
+ getAfterAllClosed() {
3509
+ const parent = this._parentModal;
3510
+ return (parent ? parent.getAfterAllClosed() : this._afterAllClosedAtThisLevel);
3511
+ }
3512
+ /**
3513
+ * Opens a modal modal containing the given template.
3514
+ */
3515
+ open(componentOrTemplateRef, config) {
3516
+ const conf = this._applyConfigDefaults(config, new BaoModalInitialConfig());
3517
+ // If there is a modal that is currently animating open, return the MatmodalRef of that modal
3518
+ if (this._modalAnimatingOpen) {
3519
+ return this._lastModalRef;
3520
+ }
3521
+ const overlayRef = this._createOverlay(conf);
3522
+ const modalContainer = this._attachModalContainer(overlayRef, conf);
3523
+ if (this._animationMode !== 'NoopAnimations') {
3524
+ const animationStateSubscription = modalContainer._animationStateChanged.subscribe(modalAnimationEvent => {
3525
+ if (modalAnimationEvent.state === 'opening') {
3526
+ this._modalAnimatingOpen = true;
3527
+ }
3528
+ if (modalAnimationEvent.state === 'opened') {
3529
+ this._modalAnimatingOpen = false;
3530
+ animationStateSubscription.unsubscribe();
3531
+ }
3532
+ });
3533
+ if (!this._animationStateSubscriptions) {
3534
+ this._animationStateSubscriptions = new Subscription();
3535
+ }
3536
+ this._animationStateSubscriptions.add(animationStateSubscription);
3537
+ }
3538
+ const modalRef = this._attachModalContent(componentOrTemplateRef, modalContainer, overlayRef, conf);
3539
+ this._lastModalRef = modalRef;
3540
+ // If this is the first modal that we're opening, hide all the non-overlay content.
3541
+ if (!this.openModals.length) {
3542
+ this._hideNonModalContentFromAssistiveTechnology();
3543
+ }
3544
+ this.openModals.push(modalRef);
3545
+ modalRef.afterClosed().subscribe(() => this._removeOpenModal(modalRef));
3546
+ this.afterOpened.next(modalRef);
3547
+ // Notify the modal container that the content has been attached.
3548
+ modalContainer._initializeWithAttachedContent();
3549
+ return modalRef;
3550
+ }
3551
+ /**
3552
+ * Closes all of the currently-open modals.
3553
+ */
3554
+ closeAll() {
3555
+ this._closeModals(this.openModals);
3556
+ }
3557
+ /**
3558
+ * Finds an open modal by its id.
3559
+ */
3560
+ getModalById(id) {
3561
+ return this.openModals.find(modal => modal.id === id);
3562
+ }
3563
+ ngOnDestroy() {
3564
+ // Only close the modals at this level on destroy
3565
+ // since the parent service may still be active.
3566
+ this._closeModals(this._openModalsAtThisLevel);
3567
+ this._afterAllClosedAtThisLevel.complete();
3568
+ this._afterOpenedAtThisLevel.complete();
3569
+ // Clean up any subscriptions to modals that never finished opening.
3570
+ if (this._animationStateSubscriptions) {
3571
+ this._animationStateSubscriptions.unsubscribe();
3572
+ }
3573
+ }
3574
+ /**
3575
+ * Creates the overlay into which the modal will be loaded.
3576
+ */
3577
+ _createOverlay(config) {
3578
+ const overlayConfig = this._getOverlayConfig(config);
3579
+ return this._overlay.create(overlayConfig);
3580
+ }
3581
+ /**
3582
+ * Creates an overlay config from a modal config.
3583
+ */
3584
+ _getOverlayConfig(config) {
3585
+ const state = new OverlayConfig({
3586
+ positionStrategy: this._overlay.position().global(),
3587
+ scrollStrategy: this._overlay.scrollStrategies.block(),
3588
+ panelClass: config.panelClass,
3589
+ hasBackdrop: config.hasBackdrop,
3590
+ disposeOnNavigation: config.closeOnNavigation
3591
+ });
3592
+ if (config.backdropClass) {
3593
+ state.backdropClass = config.backdropClass;
3594
+ }
3595
+ return state;
3596
+ }
3597
+ /**
3598
+ * Attaches a modal container to a modal's already-created overlay.
3599
+ */
3600
+ _attachModalContainer(overlay, config) {
3601
+ const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
3602
+ const injector = Injector.create({
3603
+ parent: userInjector || this._injector,
3604
+ providers: [{ provide: BaoModalInitialConfig, useValue: config }]
3605
+ });
3606
+ const containerPortal = new ComponentPortal(this._modalContainerType, config.viewContainerRef, injector);
3607
+ const containerRef = overlay.attach(containerPortal);
3608
+ return containerRef.instance;
3609
+ }
3610
+ /**
3611
+ * Attaches the user-provided component to the already-created modal container.
3612
+ */
3613
+ _attachModalContent(componentOrTemplateRef, modalContainer, overlayRef, config) {
3614
+ // Create a reference to the modal we're creating in order to give the user a handle
3615
+ // to modify and close it.
3616
+ const modalRef = new this._modalRefConstructor(overlayRef, modalContainer, config.id);
3617
+ if (componentOrTemplateRef instanceof TemplateRef) {
3618
+ modalContainer.attachTemplatePortal(new TemplatePortal(componentOrTemplateRef, null, {
3619
+ $implicit: config.data,
3620
+ modalRef
3621
+ }));
3622
+ }
3623
+ else {
3624
+ const injector = this._createInjector(config, modalRef, modalContainer);
3625
+ const contentRef = modalContainer.attachComponentPortal(new ComponentPortal(componentOrTemplateRef, config.viewContainerRef, injector));
3626
+ modalRef.componentInstance = contentRef.instance;
3627
+ }
3628
+ modalRef
3629
+ .updateSize(config.width, config.height)
3630
+ .updatePosition(config.position);
3631
+ return modalRef;
3632
+ }
3633
+ /**
3634
+ * Creates a custom injector to be used inside the modal. This allows a component loaded inside
3635
+ * of a modal to close itself and, optionally, to return a value.
3636
+ */
3637
+ _createInjector(config, modalRef, modalContainer) {
3638
+ const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
3639
+ // The modal container should be provided as the modal container and the modal's
3640
+ // content are created out of the same `ViewContainerRef` and as such, are siblings
3641
+ // for injector purposes. To allow the hierarchy that is expected, the modal
3642
+ // container is explicitly provided in the injector.
3643
+ const providers = [
3644
+ { provide: this._modalContainerType, useValue: modalContainer },
3645
+ { provide: this._modalDataToken, useValue: config.data },
3646
+ { provide: this._modalRefConstructor, useValue: modalRef }
3647
+ ];
3648
+ return Injector.create({
3649
+ parent: userInjector || this._injector,
3650
+ providers
3651
+ });
3652
+ }
3653
+ /**
3654
+ * Removes a modal from the array of open modals.
3655
+ */
3656
+ _removeOpenModal(modalRef) {
3657
+ const index = this.openModals.indexOf(modalRef);
3658
+ if (index > -1) {
3659
+ this.openModals.splice(index, 1);
3660
+ // If all the modals were closed, remove/restore the `aria-hidden`
3661
+ // to a the siblings and emit to the `afterAllClosed` stream.
3662
+ if (!this.openModals.length) {
3663
+ this._ariaHiddenElements.forEach((previousValue, element) => {
3664
+ if (previousValue) {
3665
+ element.setAttribute('aria-hidden', previousValue);
3666
+ }
3667
+ else {
3668
+ element.removeAttribute('aria-hidden');
3669
+ }
3670
+ });
3671
+ this._ariaHiddenElements.clear();
3672
+ this.getAfterAllClosed().next();
3673
+ }
3674
+ }
3675
+ }
3676
+ /**
3677
+ * Hides all of the content that isn't an overlay from assistive technology.
3678
+ */
3679
+ _hideNonModalContentFromAssistiveTechnology() {
3680
+ const overlayContainer = this._overlayContainer.getContainerElement();
3681
+ // Ensure that the overlay container is attached to the DOM.
3682
+ if (overlayContainer.parentElement) {
3683
+ const siblings = overlayContainer.parentElement.children;
3684
+ for (let i = siblings.length - 1; i > -1; i--) {
3685
+ const sibling = siblings[i];
3686
+ if (sibling !== overlayContainer &&
3687
+ sibling.nodeName !== 'SCRIPT' &&
3688
+ sibling.nodeName !== 'STYLE' &&
3689
+ !sibling.hasAttribute('aria-live')) {
3690
+ this._ariaHiddenElements.set(sibling, sibling.getAttribute('aria-hidden'));
3691
+ sibling.setAttribute('aria-hidden', 'true');
3692
+ }
3693
+ }
3694
+ }
3695
+ }
3696
+ /** Closes all of the modals in an array. */
3697
+ _closeModals(modals) {
3698
+ let i = modals.length;
3699
+ while (i--) {
3700
+ modals[i].close();
3701
+ }
3702
+ }
3703
+ /**
3704
+ * Applies default options to the modal config.
3705
+ */
3706
+ _applyConfigDefaults(config, defaultOptions) {
3707
+ const desktopClass = config?.size || eModalDesktopWidthSize.SMALL;
3708
+ const mobilClass = config?.mobileSize || eModalMobileWidthSize.FULL;
3709
+ const data = config?.data || null;
3710
+ const ariaLabelledBy = config?.ariaLabelledBy || null;
3711
+ return {
3712
+ ...defaultOptions,
3713
+ ...{
3714
+ panelClass: [desktopClass, mobilClass],
3715
+ ariaLabelledBy,
3716
+ data
3717
+ }
3718
+ };
3719
+ }
3720
+ }
3721
+ BaoModalBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalBase, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
3722
+ BaoModalBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: BaoModalBase, ngImport: i0 });
3723
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalBase, decorators: [{
3724
+ type: Directive
3725
+ }], ctorParameters: function () { return [{ type: i1$4.Overlay }, { type: i0.Injector }, { type: undefined }, { type: i1$4.OverlayContainer }, { type: i0.Type }, { type: i0.Type }, { type: i0.InjectionToken }, { type: undefined }]; } });
3726
+ /**
3727
+ * Service to open modal.
3728
+ */
3729
+ class BaoModal extends BaoModalBase {
3730
+ constructor(overlay, injector, parentModal, overlayContainer, animationMode) {
3731
+ super(overlay, injector, parentModal, overlayContainer, BaoModalRef, BaoModalContainer, BAO_MODAL_DATA, animationMode);
3732
+ }
3733
+ }
3734
+ BaoModal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModal, deps: [{ token: i1$4.Overlay }, { token: i0.Injector }, { token: BaoModal, optional: true, skipSelf: true }, { token: i1$4.OverlayContainer }, { token: ANIMATION_MODULE_TYPE, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
3735
+ BaoModal.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModal });
3736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModal, decorators: [{
3737
+ type: Injectable
3738
+ }], ctorParameters: function () { return [{ type: i1$4.Overlay }, { type: i0.Injector }, { type: BaoModal, decorators: [{
3739
+ type: Optional
3740
+ }, {
3741
+ type: SkipSelf
3742
+ }] }, { type: i1$4.OverlayContainer }, { type: undefined, decorators: [{
3743
+ type: Optional
3744
+ }, {
3745
+ type: Inject,
3746
+ args: [ANIMATION_MODULE_TYPE]
3747
+ }] }]; } });
3748
+
3749
+ /*
3750
+ * Copyright (c) 2022 Ville de Montreal. All rights reserved.
3751
+ * Licensed under the MIT license.
3752
+ * See LICENSE file in the project root for full license information.
3753
+ */
3754
+ /**
3755
+ * Button that will close the current dialog.
3756
+ */
3757
+ class BaoModalClose {
3758
+ constructor(modalRef, _elementRef, _dialog) {
3759
+ this.modalRef = modalRef;
3760
+ this._elementRef = _elementRef;
3761
+ this._dialog = _dialog;
3762
+ /** Default to "button" to prevents accidental form submits. */
3763
+ this.type = 'button';
3764
+ }
3765
+ ngOnInit() {
3766
+ if (!this.modalRef) {
3767
+ // When this directive is included in a dialog via TemplateRef (rather than being
3768
+ // in a Component), the modalRef isn't available via injection because embedded
3769
+ // views cannot be given a custom injector. Instead, we look up the modalRef by
3770
+ // ID. This must occur in `onInit`, as the ID binding for the dialog container won't
3771
+ // be resolved at constructor time.
3772
+ this.modalRef =
3773
+ getClosestDialog(this._elementRef, this._dialog.openModals) || null;
3774
+ }
3775
+ }
3776
+ ngOnChanges(changes) {
3777
+ const proxiedChange = changes['_baoModalClose'] || changes['_baoModalCloseResult'];
3778
+ if (proxiedChange) {
3779
+ this.dialogResult = proxiedChange.currentValue;
3780
+ }
3781
+ }
3782
+ _onButtonClick(event) {
3783
+ // Determinate the focus origin using the click event, because using the FocusMonitor will
3784
+ // result in incorrect origins. Most of the time, close buttons will be auto focused in the
3785
+ // dialog, and therefore clicking the button won't result in a focus change. This means that
3786
+ // the FocusMonitor won't detect any origin change, and will always output `program`.
3787
+ _closeModalVia(this.modalRef, event.screenX === 0 && event.screenY === 0 ? 'keyboard' : 'mouse', this.dialogResult);
3788
+ }
3789
+ }
3790
+ BaoModalClose.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalClose, deps: [{ token: BaoModalRef, optional: true }, { token: i0.ElementRef }, { token: BaoModal }], target: i0.ɵɵFactoryTarget.Directive });
3791
+ BaoModalClose.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.1.1", type: BaoModalClose, selector: "[bao-modal-close], [baoModalClose]", inputs: { ariaLabel: ["aria-label", "ariaLabel"], type: "type", dialogResult: ["bao-modal-close", "dialogResult"], _baoModalClose: ["baoModalClose", "_baoModalClose"] }, host: { listeners: { "click": "_onButtonClick($event)" }, properties: { "attr.aria-label": "ariaLabel || null", "attr.type": "type" } }, exportAs: ["BaoModalClose"], usesOnChanges: true, ngImport: i0 });
3792
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalClose, decorators: [{
3793
+ type: Directive,
3794
+ args: [{
3795
+ selector: '[bao-modal-close], [baoModalClose]',
3796
+ exportAs: 'BaoModalClose',
3797
+ host: {
3798
+ '(click)': '_onButtonClick($event)',
3799
+ '[attr.aria-label]': 'ariaLabel || null',
3800
+ '[attr.type]': 'type'
3801
+ }
3802
+ }]
3803
+ }], ctorParameters: function () { return [{ type: BaoModalRef, decorators: [{
3804
+ type: Optional
3805
+ }] }, { type: i0.ElementRef }, { type: BaoModal }]; }, propDecorators: { ariaLabel: [{
3806
+ type: Input,
3807
+ args: ['aria-label']
3808
+ }], type: [{
3809
+ type: Input
3810
+ }], dialogResult: [{
3811
+ type: Input,
3812
+ args: ['bao-modal-close']
3813
+ }], _baoModalClose: [{
3814
+ type: Input,
3815
+ args: ['baoModalClose']
3816
+ }] } });
3817
+ /**
3818
+ * Finds the closest BaoModalRef to an element by looking at the DOM.
3819
+ */
3820
+ function getClosestDialog(element, openDialogs) {
3821
+ let parent = element.nativeElement.parentElement;
3822
+ while (parent && !parent.classList.contains('bao-modal-container')) {
3823
+ parent = parent.parentElement;
3824
+ }
3825
+ return parent ? openDialogs.find(dialog => dialog.id === parent.id) : null;
3826
+ }
3827
+
3828
+ /*
3829
+ * Copyright (c) 2022 Ville de Montreal. All rights reserved.
3830
+ * Licensed under the MIT license.
3831
+ * See LICENSE file in the project root for full license information.
3832
+ */
3833
+ const MODAL_DIRECTIVES = [BaoModalContainer, BaoModalClose];
3834
+ class BaoModalModule {
3835
+ }
3836
+ BaoModalModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3837
+ BaoModalModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalModule, declarations: [BaoModalContainer, BaoModalClose], imports: [CommonModule,
3838
+ OverlayModule,
3839
+ PortalModule,
3840
+ BrowserAnimationsModule,
3841
+ NoopAnimationsModule], exports: [BaoModalContainer, BaoModalClose] });
3842
+ BaoModalModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalModule, providers: [BaoModal], imports: [[
3843
+ CommonModule,
3844
+ OverlayModule,
3845
+ PortalModule,
3846
+ BrowserAnimationsModule,
3847
+ NoopAnimationsModule
3848
+ ]] });
3849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImport: i0, type: BaoModalModule, decorators: [{
3850
+ type: NgModule,
3851
+ args: [{
3852
+ imports: [
3853
+ CommonModule,
3854
+ OverlayModule,
3855
+ PortalModule,
3856
+ BrowserAnimationsModule,
3857
+ NoopAnimationsModule
3858
+ ],
3859
+ declarations: MODAL_DIRECTIVES,
3860
+ exports: MODAL_DIRECTIVES,
3861
+ providers: [BaoModal]
3862
+ }]
3863
+ }] });
3864
+
2933
3865
  /*
2934
3866
  * Copyright (c) 2022 Ville de Montreal. All rights reserved.
2935
3867
  * Licensed under the MIT license.
@@ -2955,7 +3887,8 @@ BaoModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.
2955
3887
  BaoRadioModule,
2956
3888
  BaoSummaryModule,
2957
3889
  BaoAvatarModule,
2958
- BaoTabsModule
3890
+ BaoTabsModule,
3891
+ BaoModalModule
2959
3892
  // TODO: reactivate once component does not depend on global css BaoBadgeModule,
2960
3893
  // TODO: reactivate once component does not depend on global css BaoSnackBarModule,
2961
3894
  ] });
@@ -2978,7 +3911,8 @@ BaoModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.
2978
3911
  BaoRadioModule,
2979
3912
  BaoSummaryModule,
2980
3913
  BaoAvatarModule,
2981
- BaoTabsModule
3914
+ BaoTabsModule,
3915
+ BaoModalModule
2982
3916
  // TODO: reactivate once component does not depend on global css BaoBadgeModule,
2983
3917
  // TODO: reactivate once component does not depend on global css BaoSnackBarModule,
2984
3918
  ] });
@@ -3006,7 +3940,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImpor
3006
3940
  BaoRadioModule,
3007
3941
  BaoSummaryModule,
3008
3942
  BaoAvatarModule,
3009
- BaoTabsModule
3943
+ BaoTabsModule,
3944
+ BaoModalModule
3010
3945
  // TODO: reactivate once component does not depend on global css BaoBadgeModule,
3011
3946
  // TODO: reactivate once component does not depend on global css BaoSnackBarModule,
3012
3947
  ]
@@ -3076,9 +4011,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.1.1", ngImpor
3076
4011
  * See LICENSE file in the project root for full license information.
3077
4012
  */
3078
4013
 
4014
+ /*
4015
+ * Copyright (c) 2022 Ville de Montreal. All rights reserved.
4016
+ * Licensed under the MIT license.
4017
+ * See LICENSE file in the project root for full license information.
4018
+ */
4019
+
3079
4020
  /**
3080
4021
  * Generated bundle index. Do not edit.
3081
4022
  */
3082
4023
 
3083
- export { BAO_RADIO_GROUP, BaoAlertActions, BaoAlertComponent, BaoAlertContent, BaoAlertLink, BaoAlertModule, BaoAlertTitle, BaoAvatarComponent, BaoAvatarContent, BaoAvatarModule, BaoBadgeComponent, BaoBadgeModule, BaoBreadcrumbComponent, BaoBreadcrumbModule, BaoButtonComponent, BaoButtonModule, BaoCardComponent, BaoCardContent, BaoCardHeader, BaoCardModule, BaoCardTextInterface, BaoCardTitle, BaoCheckBoxDescription, BaoCheckboxComponent, BaoCheckboxGroupComponent, BaoCheckboxModule, BaoCommonComponentsModule, BaoErrorTextComponent, BaoGuidingTextComponent, BaoHeaderInfoComponent, BaoHeaderInfoContent, BaoHeaderInfoModule, BaoHeaderInfoSubtitle, BaoHeaderInfoSurtitle, BaoHeaderInfoTitle, BaoHeaderInfoTitleGroupComponent, BaoIconComponent, BaoIconModule, BaoLabelTextComponent, BaoList, BaoListItem, BaoListItemDescription, BaoListItemTitle, BaoListModule, BaoListSummary, BaoListSummaryItem, BaoModule, BaoNavList, BaoRadioButtonComponent, BaoRadioButtonGroupComponent, BaoRadioDescription, BaoRadioModule, BaoSummaryComponent, BaoSummaryDescription, BaoSummaryModule, BaoTabHeader, BaoTabPanel, BaoTablistComponent, BaoTabsContainer, BaoTabsModule, BaoTagComponent, BaoTagModule, BaoTitleTextComponent };
4024
+ export { BAO_MODAL_DATA, BAO_RADIO_GROUP, BaoAlertActions, BaoAlertComponent, BaoAlertContent, BaoAlertLink, BaoAlertModule, BaoAlertTitle, BaoAvatarComponent, BaoAvatarContent, BaoAvatarModule, BaoBadgeComponent, BaoBadgeModule, BaoBreadcrumbComponent, BaoBreadcrumbModule, BaoButtonComponent, BaoButtonModule, BaoCardComponent, BaoCardContent, BaoCardHeader, BaoCardModule, BaoCardTextInterface, BaoCardTitle, BaoCheckBoxDescription, BaoCheckboxComponent, BaoCheckboxGroupComponent, BaoCheckboxModule, BaoCommonComponentsModule, BaoErrorTextComponent, BaoGuidingTextComponent, BaoHeaderInfoComponent, BaoHeaderInfoContent, BaoHeaderInfoModule, BaoHeaderInfoSubtitle, BaoHeaderInfoSurtitle, BaoHeaderInfoTitle, BaoHeaderInfoTitleGroupComponent, BaoIconComponent, BaoIconModule, BaoLabelTextComponent, BaoList, BaoListItem, BaoListItemDescription, BaoListItemTitle, BaoListModule, BaoListSummary, BaoListSummaryItem, BaoModal, BaoModalBase, BaoModalClose, BaoModalContainer, BaoModalInitialConfig, BaoModalModule, BaoModalRef, BaoModule, BaoNavList, BaoRadioButtonComponent, BaoRadioButtonGroupComponent, BaoRadioDescription, BaoRadioModule, BaoSummaryComponent, BaoSummaryDescription, BaoSummaryModule, BaoTabHeader, BaoTabPanel, BaoTablistComponent, BaoTabsContainer, BaoTabsModule, BaoTagComponent, BaoTagModule, BaoTitleTextComponent, _BaoModalContainerBase, _closeModalVia, eModalDesktopWidthSize, eModalMobileWidthSize, throwBaoModalContentAlreadyAttachedError };
3084
4025
  //# sourceMappingURL=villedemontreal-angular-ui.mjs.map