You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

2718 lines
89 KiB

import * as i0 from '@angular/core';
import { DOCUMENT, NgZone, inject, Injector, Injectable, RendererFactory2, Component, ChangeDetectionStrategy, ViewEncapsulation, afterNextRender, ElementRef, InjectionToken, ApplicationRef, Renderer2, ANIMATION_MODULE_TYPE, EnvironmentInjector, Directive, EventEmitter, TemplateRef, ViewContainerRef, booleanAttribute, Input, Output, NgModule } from '@angular/core';
import { Location } from '@angular/common';
import { Platform } from './_platform-chunk.mjs';
import { _getEventTarget } from './_shadow-dom-chunk.mjs';
import { _isTestEnvironment } from './_test-environment-chunk.mjs';
import { _CdkPrivateStyleLoader } from './_style-loader-chunk.mjs';
import { Subject, Subscription } from 'rxjs';
import { coerceCssPixelValue } from './_css-pixel-value-chunk.mjs';
import { coerceArray } from './_array-chunk.mjs';
import { ViewportRuler, ScrollDispatcher, ScrollingModule } from './scrolling.mjs';
import { DomPortalOutlet, TemplatePortal, PortalModule } from './portal.mjs';
import { supportsScrollBehavior } from './_scrolling-chunk.mjs';
import { filter, takeWhile } from 'rxjs/operators';
import { _IdGenerator } from './_id-generator-chunk.mjs';
import { Directionality } from './_directionality-chunk.mjs';
import { ESCAPE } from './_keycodes-chunk.mjs';
import { hasModifierKey } from './keycodes.mjs';
import { BidiModule } from './bidi.mjs';
const scrollBehaviorSupported = supportsScrollBehavior();
function createBlockScrollStrategy(injector) {
return new BlockScrollStrategy(injector.get(ViewportRuler), injector.get(DOCUMENT));
}
class BlockScrollStrategy {
_viewportRuler;
_previousHTMLStyles = {
top: '',
left: ''
};
_previousScrollPosition;
_isEnabled = false;
_document;
constructor(_viewportRuler, document) {
this._viewportRuler = _viewportRuler;
this._document = document;
}
attach() {}
enable() {
if (this._canBeEnabled()) {
const root = this._document.documentElement;
this._previousScrollPosition = this._viewportRuler.getViewportScrollPosition();
this._previousHTMLStyles.left = root.style.left || '';
this._previousHTMLStyles.top = root.style.top || '';
root.style.left = coerceCssPixelValue(-this._previousScrollPosition.left);
root.style.top = coerceCssPixelValue(-this._previousScrollPosition.top);
root.classList.add('cdk-global-scrollblock');
this._isEnabled = true;
}
}
disable() {
if (this._isEnabled) {
const html = this._document.documentElement;
const body = this._document.body;
const htmlStyle = html.style;
const bodyStyle = body.style;
const previousHtmlScrollBehavior = htmlStyle.scrollBehavior || '';
const previousBodyScrollBehavior = bodyStyle.scrollBehavior || '';
this._isEnabled = false;
htmlStyle.left = this._previousHTMLStyles.left;
htmlStyle.top = this._previousHTMLStyles.top;
html.classList.remove('cdk-global-scrollblock');
if (scrollBehaviorSupported) {
htmlStyle.scrollBehavior = bodyStyle.scrollBehavior = 'auto';
}
window.scroll(this._previousScrollPosition.left, this._previousScrollPosition.top);
if (scrollBehaviorSupported) {
htmlStyle.scrollBehavior = previousHtmlScrollBehavior;
bodyStyle.scrollBehavior = previousBodyScrollBehavior;
}
}
}
_canBeEnabled() {
const html = this._document.documentElement;
if (html.classList.contains('cdk-global-scrollblock') || this._isEnabled) {
return false;
}
const rootElement = this._document.documentElement;
const viewport = this._viewportRuler.getViewportSize();
return rootElement.scrollHeight > viewport.height || rootElement.scrollWidth > viewport.width;
}
}
function getMatScrollStrategyAlreadyAttachedError() {
return Error(`Scroll strategy has already been attached.`);
}
function createCloseScrollStrategy(injector, config) {
return new CloseScrollStrategy(injector.get(ScrollDispatcher), injector.get(NgZone), injector.get(ViewportRuler), config);
}
class CloseScrollStrategy {
_scrollDispatcher;
_ngZone;
_viewportRuler;
_config;
_scrollSubscription = null;
_overlayRef;
_initialScrollPosition;
constructor(_scrollDispatcher, _ngZone, _viewportRuler, _config) {
this._scrollDispatcher = _scrollDispatcher;
this._ngZone = _ngZone;
this._viewportRuler = _viewportRuler;
this._config = _config;
}
attach(overlayRef) {
if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw getMatScrollStrategyAlreadyAttachedError();
}
this._overlayRef = overlayRef;
}
enable() {
if (this._scrollSubscription) {
return;
}
const stream = this._scrollDispatcher.scrolled(0).pipe(filter(scrollable => {
return !scrollable || !this._overlayRef.overlayElement.contains(scrollable.getElementRef().nativeElement);
}));
if (this._config && this._config.threshold && this._config.threshold > 1) {
this._initialScrollPosition = this._viewportRuler.getViewportScrollPosition().top;
this._scrollSubscription = stream.subscribe(() => {
const scrollPosition = this._viewportRuler.getViewportScrollPosition().top;
if (Math.abs(scrollPosition - this._initialScrollPosition) > this._config.threshold) {
this._detach();
} else {
this._overlayRef.updatePosition();
}
});
} else {
this._scrollSubscription = stream.subscribe(this._detach);
}
}
disable() {
if (this._scrollSubscription) {
this._scrollSubscription.unsubscribe();
this._scrollSubscription = null;
}
}
detach() {
this.disable();
this._overlayRef = null;
}
_detach = () => {
this.disable();
if (this._overlayRef.hasAttached()) {
this._ngZone.run(() => this._overlayRef.detach());
}
};
}
function createNoopScrollStrategy() {
return new NoopScrollStrategy();
}
class NoopScrollStrategy {
enable() {}
disable() {}
attach() {}
}
function isElementScrolledOutsideView(element, scrollContainers) {
return scrollContainers.some(containerBounds => {
const outsideAbove = element.bottom < containerBounds.top;
const outsideBelow = element.top > containerBounds.bottom;
const outsideLeft = element.right < containerBounds.left;
const outsideRight = element.left > containerBounds.right;
return outsideAbove || outsideBelow || outsideLeft || outsideRight;
});
}
function isElementClippedByScrolling(element, scrollContainers) {
return scrollContainers.some(scrollContainerRect => {
const clippedAbove = element.top < scrollContainerRect.top;
const clippedBelow = element.bottom > scrollContainerRect.bottom;
const clippedLeft = element.left < scrollContainerRect.left;
const clippedRight = element.right > scrollContainerRect.right;
return clippedAbove || clippedBelow || clippedLeft || clippedRight;
});
}
function createRepositionScrollStrategy(injector, config) {
return new RepositionScrollStrategy(injector.get(ScrollDispatcher), injector.get(ViewportRuler), injector.get(NgZone), config);
}
class RepositionScrollStrategy {
_scrollDispatcher;
_viewportRuler;
_ngZone;
_config;
_scrollSubscription = null;
_overlayRef;
constructor(_scrollDispatcher, _viewportRuler, _ngZone, _config) {
this._scrollDispatcher = _scrollDispatcher;
this._viewportRuler = _viewportRuler;
this._ngZone = _ngZone;
this._config = _config;
}
attach(overlayRef) {
if (this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw getMatScrollStrategyAlreadyAttachedError();
}
this._overlayRef = overlayRef;
}
enable() {
if (!this._scrollSubscription) {
const throttle = this._config ? this._config.scrollThrottle : 0;
this._scrollSubscription = this._scrollDispatcher.scrolled(throttle).subscribe(() => {
this._overlayRef.updatePosition();
if (this._config && this._config.autoClose) {
const overlayRect = this._overlayRef.overlayElement.getBoundingClientRect();
const {
width,
height
} = this._viewportRuler.getViewportSize();
const parentRects = [{
width,
height,
bottom: height,
right: width,
top: 0,
left: 0
}];
if (isElementScrolledOutsideView(overlayRect, parentRects)) {
this.disable();
this._ngZone.run(() => this._overlayRef.detach());
}
}
});
}
}
disable() {
if (this._scrollSubscription) {
this._scrollSubscription.unsubscribe();
this._scrollSubscription = null;
}
}
detach() {
this.disable();
this._overlayRef = null;
}
}
class ScrollStrategyOptions {
_injector = inject(Injector);
constructor() {}
noop = () => new NoopScrollStrategy();
close = config => createCloseScrollStrategy(this._injector, config);
block = () => createBlockScrollStrategy(this._injector);
reposition = config => createRepositionScrollStrategy(this._injector, config);
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: ScrollStrategyOptions,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: ScrollStrategyOptions,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: ScrollStrategyOptions,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
class OverlayConfig {
positionStrategy;
scrollStrategy = new NoopScrollStrategy();
panelClass = '';
hasBackdrop = false;
backdropClass = 'cdk-overlay-dark-backdrop';
disableAnimations;
width;
height;
minWidth;
minHeight;
maxWidth;
maxHeight;
direction;
disposeOnNavigation = false;
usePopover;
constructor(config) {
if (config) {
const configKeys = Object.keys(config);
for (const key of configKeys) {
if (config[key] !== undefined) {
this[key] = config[key];
}
}
}
}
}
class ConnectionPositionPair {
offsetX;
offsetY;
panelClass;
originX;
originY;
overlayX;
overlayY;
constructor(origin, overlay, offsetX, offsetY, panelClass) {
this.offsetX = offsetX;
this.offsetY = offsetY;
this.panelClass = panelClass;
this.originX = origin.originX;
this.originY = origin.originY;
this.overlayX = overlay.overlayX;
this.overlayY = overlay.overlayY;
}
}
class ScrollingVisibility {
isOriginClipped = false;
isOriginOutsideView = false;
isOverlayClipped = false;
isOverlayOutsideView = false;
}
class ConnectedOverlayPositionChange {
connectionPair;
scrollableViewProperties;
constructor(connectionPair, scrollableViewProperties) {
this.connectionPair = connectionPair;
this.scrollableViewProperties = scrollableViewProperties;
}
}
function validateVerticalPosition(property, value) {
if (value !== 'top' && value !== 'bottom' && value !== 'center') {
throw Error(`ConnectedPosition: Invalid ${property} "${value}". ` + `Expected "top", "bottom" or "center".`);
}
}
function validateHorizontalPosition(property, value) {
if (value !== 'start' && value !== 'end' && value !== 'center') {
throw Error(`ConnectedPosition: Invalid ${property} "${value}". ` + `Expected "start", "end" or "center".`);
}
}
class BaseOverlayDispatcher {
_attachedOverlays = [];
_document = inject(DOCUMENT);
_isAttached = false;
constructor() {}
ngOnDestroy() {
this.detach();
}
add(overlayRef) {
this.remove(overlayRef);
this._attachedOverlays.push(overlayRef);
}
remove(overlayRef) {
const index = this._attachedOverlays.indexOf(overlayRef);
if (index > -1) {
this._attachedOverlays.splice(index, 1);
}
if (this._attachedOverlays.length === 0) {
this.detach();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: BaseOverlayDispatcher,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: BaseOverlayDispatcher,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: BaseOverlayDispatcher,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
class OverlayKeyboardDispatcher extends BaseOverlayDispatcher {
_ngZone = inject(NgZone);
_renderer = inject(RendererFactory2).createRenderer(null, null);
_cleanupKeydown;
add(overlayRef) {
super.add(overlayRef);
if (!this._isAttached) {
this._ngZone.runOutsideAngular(() => {
this._cleanupKeydown = this._renderer.listen('body', 'keydown', this._keydownListener);
});
this._isAttached = true;
}
}
detach() {
if (this._isAttached) {
this._cleanupKeydown?.();
this._isAttached = false;
}
}
_keydownListener = event => {
const overlays = this._attachedOverlays;
for (let i = overlays.length - 1; i > -1; i--) {
if (overlays[i]._keydownEvents.observers.length > 0) {
this._ngZone.run(() => overlays[i]._keydownEvents.next(event));
break;
}
}
};
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayKeyboardDispatcher,
deps: null,
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayKeyboardDispatcher,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayKeyboardDispatcher,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}]
});
class OverlayOutsideClickDispatcher extends BaseOverlayDispatcher {
_platform = inject(Platform);
_ngZone = inject(NgZone);
_renderer = inject(RendererFactory2).createRenderer(null, null);
_cursorOriginalValue;
_cursorStyleIsSet = false;
_pointerDownEventTarget = null;
_cleanups;
add(overlayRef) {
super.add(overlayRef);
if (!this._isAttached) {
const body = this._document.body;
const eventOptions = {
capture: true
};
const renderer = this._renderer;
this._cleanups = this._ngZone.runOutsideAngular(() => [renderer.listen(body, 'pointerdown', this._pointerDownListener, eventOptions), renderer.listen(body, 'click', this._clickListener, eventOptions), renderer.listen(body, 'auxclick', this._clickListener, eventOptions), renderer.listen(body, 'contextmenu', this._clickListener, eventOptions)]);
if (this._platform.IOS && !this._cursorStyleIsSet) {
this._cursorOriginalValue = body.style.cursor;
body.style.cursor = 'pointer';
this._cursorStyleIsSet = true;
}
this._isAttached = true;
}
}
detach() {
if (this._isAttached) {
this._cleanups?.forEach(cleanup => cleanup());
this._cleanups = undefined;
if (this._platform.IOS && this._cursorStyleIsSet) {
this._document.body.style.cursor = this._cursorOriginalValue;
this._cursorStyleIsSet = false;
}
this._isAttached = false;
}
}
_pointerDownListener = event => {
this._pointerDownEventTarget = _getEventTarget(event);
};
_clickListener = event => {
const target = _getEventTarget(event);
const origin = event.type === 'click' && this._pointerDownEventTarget ? this._pointerDownEventTarget : target;
this._pointerDownEventTarget = null;
const overlays = this._attachedOverlays.slice();
for (let i = overlays.length - 1; i > -1; i--) {
const overlayRef = overlays[i];
if (overlayRef._outsidePointerEvents.observers.length < 1 || !overlayRef.hasAttached()) {
continue;
}
if (containsPierceShadowDom(overlayRef.overlayElement, target) || containsPierceShadowDom(overlayRef.overlayElement, origin)) {
break;
}
const outsidePointerEvents = overlayRef._outsidePointerEvents;
if (this._ngZone) {
this._ngZone.run(() => outsidePointerEvents.next(event));
} else {
outsidePointerEvents.next(event);
}
}
};
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayOutsideClickDispatcher,
deps: null,
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayOutsideClickDispatcher,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayOutsideClickDispatcher,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}]
});
function containsPierceShadowDom(parent, child) {
const supportsShadowRoot = typeof ShadowRoot !== 'undefined' && ShadowRoot;
let current = child;
while (current) {
if (current === parent) {
return true;
}
current = supportsShadowRoot && current instanceof ShadowRoot ? current.host : current.parentNode;
}
return false;
}
class _CdkOverlayStyleLoader {
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: _CdkOverlayStyleLoader,
deps: [],
target: i0.ɵɵFactoryTarget.Component
});
static ɵcmp = i0.ɵɵngDeclareComponent({
minVersion: "14.0.0",
version: "21.0.3",
type: _CdkOverlayStyleLoader,
isStandalone: true,
selector: "ng-component",
host: {
attributes: {
"cdk-overlay-style-loader": ""
}
},
ngImport: i0,
template: '',
isInline: true,
styles: [".cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed}@layer cdk-overlay{.cdk-overlay-container{z-index:1000}}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute}@layer cdk-overlay{.cdk-global-overlay-wrapper{z-index:1000}}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;display:flex;max-width:100%;max-height:100%}@layer cdk-overlay{.cdk-overlay-pane{z-index:1000}}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;pointer-events:auto;-webkit-tap-highlight-color:rgba(0,0,0,0);opacity:0;touch-action:manipulation}@layer cdk-overlay{.cdk-overlay-backdrop{z-index:1000;transition:opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1)}}@media(prefers-reduced-motion){.cdk-overlay-backdrop{transition-duration:1ms}}.cdk-overlay-backdrop-showing{opacity:1}@media(forced-colors: active){.cdk-overlay-backdrop-showing{opacity:.6}}@layer cdk-overlay{.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}}.cdk-overlay-transparent-backdrop{transition:visibility 1ms linear,opacity 1ms linear;visibility:hidden;opacity:1}.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing,.cdk-high-contrast-active .cdk-overlay-transparent-backdrop{opacity:0;visibility:visible}.cdk-overlay-backdrop-noop-animation{transition:none}.cdk-overlay-connected-position-bounding-box{position:absolute;display:flex;flex-direction:column;min-width:1px;min-height:1px}@layer cdk-overlay{.cdk-overlay-connected-position-bounding-box{z-index:1000}}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.cdk-overlay-popover{background:none;border:none;padding:0;outline:0;overflow:visible;position:fixed;pointer-events:none;white-space:normal;color:inherit;text-decoration:none;width:100%;height:100%;inset:auto;top:0;left:0}.cdk-overlay-popover::backdrop{display:none}.cdk-overlay-popover .cdk-overlay-backdrop{position:fixed;z-index:auto}\n"],
changeDetection: i0.ChangeDetectionStrategy.OnPush,
encapsulation: i0.ViewEncapsulation.None
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: _CdkOverlayStyleLoader,
decorators: [{
type: Component,
args: [{
template: '',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
'cdk-overlay-style-loader': ''
},
styles: [".cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed}@layer cdk-overlay{.cdk-overlay-container{z-index:1000}}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute}@layer cdk-overlay{.cdk-global-overlay-wrapper{z-index:1000}}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;display:flex;max-width:100%;max-height:100%}@layer cdk-overlay{.cdk-overlay-pane{z-index:1000}}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;pointer-events:auto;-webkit-tap-highlight-color:rgba(0,0,0,0);opacity:0;touch-action:manipulation}@layer cdk-overlay{.cdk-overlay-backdrop{z-index:1000;transition:opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1)}}@media(prefers-reduced-motion){.cdk-overlay-backdrop{transition-duration:1ms}}.cdk-overlay-backdrop-showing{opacity:1}@media(forced-colors: active){.cdk-overlay-backdrop-showing{opacity:.6}}@layer cdk-overlay{.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}}.cdk-overlay-transparent-backdrop{transition:visibility 1ms linear,opacity 1ms linear;visibility:hidden;opacity:1}.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing,.cdk-high-contrast-active .cdk-overlay-transparent-backdrop{opacity:0;visibility:visible}.cdk-overlay-backdrop-noop-animation{transition:none}.cdk-overlay-connected-position-bounding-box{position:absolute;display:flex;flex-direction:column;min-width:1px;min-height:1px}@layer cdk-overlay{.cdk-overlay-connected-position-bounding-box{z-index:1000}}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}.cdk-overlay-popover{background:none;border:none;padding:0;outline:0;overflow:visible;position:fixed;pointer-events:none;white-space:normal;color:inherit;text-decoration:none;width:100%;height:100%;inset:auto;top:0;left:0}.cdk-overlay-popover::backdrop{display:none}.cdk-overlay-popover .cdk-overlay-backdrop{position:fixed;z-index:auto}\n"]
}]
}]
});
class OverlayContainer {
_platform = inject(Platform);
_containerElement;
_document = inject(DOCUMENT);
_styleLoader = inject(_CdkPrivateStyleLoader);
constructor() {}
ngOnDestroy() {
this._containerElement?.remove();
}
getContainerElement() {
this._loadStyles();
if (!this._containerElement) {
this._createContainer();
}
return this._containerElement;
}
_createContainer() {
const containerClass = 'cdk-overlay-container';
if (this._platform.isBrowser || _isTestEnvironment()) {
const oppositePlatformContainers = this._document.querySelectorAll(`.${containerClass}[platform="server"], ` + `.${containerClass}[platform="test"]`);
for (let i = 0; i < oppositePlatformContainers.length; i++) {
oppositePlatformContainers[i].remove();
}
}
const container = this._document.createElement('div');
container.classList.add(containerClass);
if (_isTestEnvironment()) {
container.setAttribute('platform', 'test');
} else if (!this._platform.isBrowser) {
container.setAttribute('platform', 'server');
}
this._document.body.appendChild(container);
this._containerElement = container;
}
_loadStyles() {
this._styleLoader.load(_CdkOverlayStyleLoader);
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayContainer,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayContainer,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayContainer,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
class BackdropRef {
_renderer;
_ngZone;
element;
_cleanupClick;
_cleanupTransitionEnd;
_fallbackTimeout;
constructor(document, _renderer, _ngZone, onClick) {
this._renderer = _renderer;
this._ngZone = _ngZone;
this.element = document.createElement('div');
this.element.classList.add('cdk-overlay-backdrop');
this._cleanupClick = _renderer.listen(this.element, 'click', onClick);
}
detach() {
this._ngZone.runOutsideAngular(() => {
const element = this.element;
clearTimeout(this._fallbackTimeout);
this._cleanupTransitionEnd?.();
this._cleanupTransitionEnd = this._renderer.listen(element, 'transitionend', this.dispose);
this._fallbackTimeout = setTimeout(this.dispose, 500);
element.style.pointerEvents = 'none';
element.classList.remove('cdk-overlay-backdrop-showing');
});
}
dispose = () => {
clearTimeout(this._fallbackTimeout);
this._cleanupClick?.();
this._cleanupTransitionEnd?.();
this._cleanupClick = this._cleanupTransitionEnd = this._fallbackTimeout = undefined;
this.element.remove();
};
}
function isElement(value) {
return value && value.nodeType === 1;
}
class OverlayRef {
_portalOutlet;
_host;
_pane;
_config;
_ngZone;
_keyboardDispatcher;
_document;
_location;
_outsideClickDispatcher;
_animationsDisabled;
_injector;
_renderer;
_backdropClick = new Subject();
_attachments = new Subject();
_detachments = new Subject();
_positionStrategy;
_scrollStrategy;
_locationChanges = Subscription.EMPTY;
_backdropRef = null;
_detachContentMutationObserver;
_detachContentAfterRenderRef;
_disposed = false;
_previousHostParent;
_keydownEvents = new Subject();
_outsidePointerEvents = new Subject();
_afterNextRenderRef;
constructor(_portalOutlet, _host, _pane, _config, _ngZone, _keyboardDispatcher, _document, _location, _outsideClickDispatcher, _animationsDisabled = false, _injector, _renderer) {
this._portalOutlet = _portalOutlet;
this._host = _host;
this._pane = _pane;
this._config = _config;
this._ngZone = _ngZone;
this._keyboardDispatcher = _keyboardDispatcher;
this._document = _document;
this._location = _location;
this._outsideClickDispatcher = _outsideClickDispatcher;
this._animationsDisabled = _animationsDisabled;
this._injector = _injector;
this._renderer = _renderer;
if (_config.scrollStrategy) {
this._scrollStrategy = _config.scrollStrategy;
this._scrollStrategy.attach(this);
}
this._positionStrategy = _config.positionStrategy;
}
get overlayElement() {
return this._pane;
}
get backdropElement() {
return this._backdropRef?.element || null;
}
get hostElement() {
return this._host;
}
attach(portal) {
if (this._disposed) {
return null;
}
this._attachHost();
const attachResult = this._portalOutlet.attach(portal);
this._positionStrategy?.attach(this);
this._updateStackingOrder();
this._updateElementSize();
this._updateElementDirection();
if (this._scrollStrategy) {
this._scrollStrategy.enable();
}
this._afterNextRenderRef?.destroy();
this._afterNextRenderRef = afterNextRender(() => {
if (this.hasAttached()) {
this.updatePosition();
}
}, {
injector: this._injector
});
this._togglePointerEvents(true);
if (this._config.hasBackdrop) {
this._attachBackdrop();
}
if (this._config.panelClass) {
this._toggleClasses(this._pane, this._config.panelClass, true);
}
this._attachments.next();
this._completeDetachContent();
this._keyboardDispatcher.add(this);
if (this._config.disposeOnNavigation) {
this._locationChanges = this._location.subscribe(() => this.dispose());
}
this._outsideClickDispatcher.add(this);
if (typeof attachResult?.onDestroy === 'function') {
attachResult.onDestroy(() => {
if (this.hasAttached()) {
this._ngZone.runOutsideAngular(() => Promise.resolve().then(() => this.detach()));
}
});
}
return attachResult;
}
detach() {
if (!this.hasAttached()) {
return;
}
this.detachBackdrop();
this._togglePointerEvents(false);
if (this._positionStrategy && this._positionStrategy.detach) {
this._positionStrategy.detach();
}
if (this._scrollStrategy) {
this._scrollStrategy.disable();
}
const detachmentResult = this._portalOutlet.detach();
this._detachments.next();
this._completeDetachContent();
this._keyboardDispatcher.remove(this);
this._detachContentWhenEmpty();
this._locationChanges.unsubscribe();
this._outsideClickDispatcher.remove(this);
return detachmentResult;
}
dispose() {
if (this._disposed) {
return;
}
const isAttached = this.hasAttached();
if (this._positionStrategy) {
this._positionStrategy.dispose();
}
this._disposeScrollStrategy();
this._backdropRef?.dispose();
this._locationChanges.unsubscribe();
this._keyboardDispatcher.remove(this);
this._portalOutlet.dispose();
this._attachments.complete();
this._backdropClick.complete();
this._keydownEvents.complete();
this._outsidePointerEvents.complete();
this._outsideClickDispatcher.remove(this);
this._host?.remove();
this._afterNextRenderRef?.destroy();
this._previousHostParent = this._pane = this._host = this._backdropRef = null;
if (isAttached) {
this._detachments.next();
}
this._detachments.complete();
this._completeDetachContent();
this._disposed = true;
}
hasAttached() {
return this._portalOutlet.hasAttached();
}
backdropClick() {
return this._backdropClick;
}
attachments() {
return this._attachments;
}
detachments() {
return this._detachments;
}
keydownEvents() {
return this._keydownEvents;
}
outsidePointerEvents() {
return this._outsidePointerEvents;
}
getConfig() {
return this._config;
}
updatePosition() {
if (this._positionStrategy) {
this._positionStrategy.apply();
}
}
updatePositionStrategy(strategy) {
if (strategy === this._positionStrategy) {
return;
}
if (this._positionStrategy) {
this._positionStrategy.dispose();
}
this._positionStrategy = strategy;
if (this.hasAttached()) {
strategy.attach(this);
this.updatePosition();
}
}
updateSize(sizeConfig) {
this._config = {
...this._config,
...sizeConfig
};
this._updateElementSize();
}
setDirection(dir) {
this._config = {
...this._config,
direction: dir
};
this._updateElementDirection();
}
addPanelClass(classes) {
if (this._pane) {
this._toggleClasses(this._pane, classes, true);
}
}
removePanelClass(classes) {
if (this._pane) {
this._toggleClasses(this._pane, classes, false);
}
}
getDirection() {
const direction = this._config.direction;
if (!direction) {
return 'ltr';
}
return typeof direction === 'string' ? direction : direction.value;
}
updateScrollStrategy(strategy) {
if (strategy === this._scrollStrategy) {
return;
}
this._disposeScrollStrategy();
this._scrollStrategy = strategy;
if (this.hasAttached()) {
strategy.attach(this);
strategy.enable();
}
}
_updateElementDirection() {
this._host.setAttribute('dir', this.getDirection());
}
_updateElementSize() {
if (!this._pane) {
return;
}
const style = this._pane.style;
style.width = coerceCssPixelValue(this._config.width);
style.height = coerceCssPixelValue(this._config.height);
style.minWidth = coerceCssPixelValue(this._config.minWidth);
style.minHeight = coerceCssPixelValue(this._config.minHeight);
style.maxWidth = coerceCssPixelValue(this._config.maxWidth);
style.maxHeight = coerceCssPixelValue(this._config.maxHeight);
}
_togglePointerEvents(enablePointer) {
this._pane.style.pointerEvents = enablePointer ? '' : 'none';
}
_attachHost() {
if (!this._host.parentElement) {
const customInsertionPoint = this._config.usePopover ? this._positionStrategy?.getPopoverInsertionPoint?.() : null;
if (isElement(customInsertionPoint)) {
customInsertionPoint.after(this._host);
} else if (customInsertionPoint?.type === 'parent') {
customInsertionPoint.element.appendChild(this._host);
} else {
this._previousHostParent?.appendChild(this._host);
}
}
if (this._config.usePopover) {
try {
this._host['showPopover']();
} catch {}
}
}
_attachBackdrop() {
const showingClass = 'cdk-overlay-backdrop-showing';
this._backdropRef?.dispose();
this._backdropRef = new BackdropRef(this._document, this._renderer, this._ngZone, event => {
this._backdropClick.next(event);
});
if (this._animationsDisabled) {
this._backdropRef.element.classList.add('cdk-overlay-backdrop-noop-animation');
}
if (this._config.backdropClass) {
this._toggleClasses(this._backdropRef.element, this._config.backdropClass, true);
}
if (this._config.usePopover) {
this._host.prepend(this._backdropRef.element);
} else {
this._host.parentElement.insertBefore(this._backdropRef.element, this._host);
}
if (!this._animationsDisabled && typeof requestAnimationFrame !== 'undefined') {
this._ngZone.runOutsideAngular(() => {
requestAnimationFrame(() => this._backdropRef?.element.classList.add(showingClass));
});
} else {
this._backdropRef.element.classList.add(showingClass);
}
}
_updateStackingOrder() {
if (!this._config.usePopover && this._host.nextSibling) {
this._host.parentNode.appendChild(this._host);
}
}
detachBackdrop() {
if (this._animationsDisabled) {
this._backdropRef?.dispose();
this._backdropRef = null;
} else {
this._backdropRef?.detach();
}
}
_toggleClasses(element, cssClasses, isAdd) {
const classes = coerceArray(cssClasses || []).filter(c => !!c);
if (classes.length) {
isAdd ? element.classList.add(...classes) : element.classList.remove(...classes);
}
}
_detachContentWhenEmpty() {
let rethrow = false;
try {
this._detachContentAfterRenderRef = afterNextRender(() => {
rethrow = true;
this._detachContent();
}, {
injector: this._injector
});
} catch (e) {
if (rethrow) {
throw e;
}
this._detachContent();
}
if (globalThis.MutationObserver && this._pane) {
this._detachContentMutationObserver ||= new globalThis.MutationObserver(() => {
this._detachContent();
});
this._detachContentMutationObserver.observe(this._pane, {
childList: true
});
}
}
_detachContent() {
if (!this._pane || !this._host || this._pane.children.length === 0) {
if (this._pane && this._config.panelClass) {
this._toggleClasses(this._pane, this._config.panelClass, false);
}
if (this._host && this._host.parentElement) {
this._previousHostParent = this._host.parentElement;
this._host.remove();
}
this._completeDetachContent();
}
}
_completeDetachContent() {
this._detachContentAfterRenderRef?.destroy();
this._detachContentAfterRenderRef = undefined;
this._detachContentMutationObserver?.disconnect();
}
_disposeScrollStrategy() {
const scrollStrategy = this._scrollStrategy;
scrollStrategy?.disable();
scrollStrategy?.detach?.();
}
}
const boundingBoxClass = 'cdk-overlay-connected-position-bounding-box';
const cssUnitPattern = /([A-Za-z%]+)$/;
function createFlexibleConnectedPositionStrategy(injector, origin) {
return new FlexibleConnectedPositionStrategy(origin, injector.get(ViewportRuler), injector.get(DOCUMENT), injector.get(Platform), injector.get(OverlayContainer));
}
class FlexibleConnectedPositionStrategy {
_viewportRuler;
_document;
_platform;
_overlayContainer;
_overlayRef;
_isInitialRender = false;
_lastBoundingBoxSize = {
width: 0,
height: 0
};
_isPushed = false;
_canPush = true;
_growAfterOpen = false;
_hasFlexibleDimensions = true;
_positionLocked = false;
_originRect;
_overlayRect;
_viewportRect;
_containerRect;
_viewportMargin = 0;
_scrollables = [];
_preferredPositions = [];
_origin;
_pane;
_isDisposed = false;
_boundingBox = null;
_lastPosition = null;
_lastScrollVisibility = null;
_positionChanges = new Subject();
_resizeSubscription = Subscription.EMPTY;
_offsetX = 0;
_offsetY = 0;
_transformOriginSelector;
_appliedPanelClasses = [];
_previousPushAmount = null;
_popoverLocation = 'global';
positionChanges = this._positionChanges;
get positions() {
return this._preferredPositions;
}
constructor(connectedTo, _viewportRuler, _document, _platform, _overlayContainer) {
this._viewportRuler = _viewportRuler;
this._document = _document;
this._platform = _platform;
this._overlayContainer = _overlayContainer;
this.setOrigin(connectedTo);
}
attach(overlayRef) {
if (this._overlayRef && overlayRef !== this._overlayRef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('This position strategy is already attached to an overlay');
}
this._validatePositions();
overlayRef.hostElement.classList.add(boundingBoxClass);
this._overlayRef = overlayRef;
this._boundingBox = overlayRef.hostElement;
this._pane = overlayRef.overlayElement;
this._isDisposed = false;
this._isInitialRender = true;
this._lastPosition = null;
this._resizeSubscription.unsubscribe();
this._resizeSubscription = this._viewportRuler.change().subscribe(() => {
this._isInitialRender = true;
this.apply();
});
}
apply() {
if (this._isDisposed || !this._platform.isBrowser) {
return;
}
if (!this._isInitialRender && this._positionLocked && this._lastPosition) {
this.reapplyLastPosition();
return;
}
this._clearPanelClasses();
this._resetOverlayElementStyles();
this._resetBoundingBoxStyles();
this._viewportRect = this._getNarrowedViewportRect();
this._originRect = this._getOriginRect();
this._overlayRect = this._pane.getBoundingClientRect();
this._containerRect = this._getContainerRect();
const originRect = this._originRect;
const overlayRect = this._overlayRect;
const viewportRect = this._viewportRect;
const containerRect = this._containerRect;
const flexibleFits = [];
let fallback;
for (let pos of this._preferredPositions) {
let originPoint = this._getOriginPoint(originRect, containerRect, pos);
let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, pos);
let overlayFit = this._getOverlayFit(overlayPoint, overlayRect, viewportRect, pos);
if (overlayFit.isCompletelyWithinViewport) {
this._isPushed = false;
this._applyPosition(pos, originPoint);
return;
}
if (this._canFitWithFlexibleDimensions(overlayFit, overlayPoint, viewportRect)) {
flexibleFits.push({
position: pos,
origin: originPoint,
overlayRect,
boundingBoxRect: this._calculateBoundingBoxRect(originPoint, pos)
});
continue;
}
if (!fallback || fallback.overlayFit.visibleArea < overlayFit.visibleArea) {
fallback = {
overlayFit,
overlayPoint,
originPoint,
position: pos,
overlayRect
};
}
}
if (flexibleFits.length) {
let bestFit = null;
let bestScore = -1;
for (const fit of flexibleFits) {
const score = fit.boundingBoxRect.width * fit.boundingBoxRect.height * (fit.position.weight || 1);
if (score > bestScore) {
bestScore = score;
bestFit = fit;
}
}
this._isPushed = false;
this._applyPosition(bestFit.position, bestFit.origin);
return;
}
if (this._canPush) {
this._isPushed = true;
this._applyPosition(fallback.position, fallback.originPoint);
return;
}
this._applyPosition(fallback.position, fallback.originPoint);
}
detach() {
this._clearPanelClasses();
this._lastPosition = null;
this._previousPushAmount = null;
this._resizeSubscription.unsubscribe();
}
dispose() {
if (this._isDisposed) {
return;
}
if (this._boundingBox) {
extendStyles(this._boundingBox.style, {
top: '',
left: '',
right: '',
bottom: '',
height: '',
width: '',
alignItems: '',
justifyContent: ''
});
}
if (this._pane) {
this._resetOverlayElementStyles();
}
if (this._overlayRef) {
this._overlayRef.hostElement.classList.remove(boundingBoxClass);
}
this.detach();
this._positionChanges.complete();
this._overlayRef = this._boundingBox = null;
this._isDisposed = true;
}
reapplyLastPosition() {
if (this._isDisposed || !this._platform.isBrowser) {
return;
}
const lastPosition = this._lastPosition;
if (lastPosition) {
this._originRect = this._getOriginRect();
this._overlayRect = this._pane.getBoundingClientRect();
this._viewportRect = this._getNarrowedViewportRect();
this._containerRect = this._getContainerRect();
this._applyPosition(lastPosition, this._getOriginPoint(this._originRect, this._containerRect, lastPosition));
} else {
this.apply();
}
}
withScrollableContainers(scrollables) {
this._scrollables = scrollables;
return this;
}
withPositions(positions) {
this._preferredPositions = positions;
if (positions.indexOf(this._lastPosition) === -1) {
this._lastPosition = null;
}
this._validatePositions();
return this;
}
withViewportMargin(margin) {
this._viewportMargin = margin;
return this;
}
withFlexibleDimensions(flexibleDimensions = true) {
this._hasFlexibleDimensions = flexibleDimensions;
return this;
}
withGrowAfterOpen(growAfterOpen = true) {
this._growAfterOpen = growAfterOpen;
return this;
}
withPush(canPush = true) {
this._canPush = canPush;
return this;
}
withLockedPosition(isLocked = true) {
this._positionLocked = isLocked;
return this;
}
setOrigin(origin) {
this._origin = origin;
return this;
}
withDefaultOffsetX(offset) {
this._offsetX = offset;
return this;
}
withDefaultOffsetY(offset) {
this._offsetY = offset;
return this;
}
withTransformOriginOn(selector) {
this._transformOriginSelector = selector;
return this;
}
withPopoverLocation(location) {
this._popoverLocation = location;
return this;
}
getPopoverInsertionPoint() {
if (this._popoverLocation === 'global') {
return null;
} else if (this._popoverLocation !== 'inline') {
return this._popoverLocation;
}
if (this._origin instanceof ElementRef) {
return this._origin.nativeElement;
} else if (isElement(this._origin)) {
return this._origin;
} else {
return null;
}
}
_getOriginPoint(originRect, containerRect, pos) {
let x;
if (pos.originX == 'center') {
x = originRect.left + originRect.width / 2;
} else {
const startX = this._isRtl() ? originRect.right : originRect.left;
const endX = this._isRtl() ? originRect.left : originRect.right;
x = pos.originX == 'start' ? startX : endX;
}
if (containerRect.left < 0) {
x -= containerRect.left;
}
let y;
if (pos.originY == 'center') {
y = originRect.top + originRect.height / 2;
} else {
y = pos.originY == 'top' ? originRect.top : originRect.bottom;
}
if (containerRect.top < 0) {
y -= containerRect.top;
}
return {
x,
y
};
}
_getOverlayPoint(originPoint, overlayRect, pos) {
let overlayStartX;
if (pos.overlayX == 'center') {
overlayStartX = -overlayRect.width / 2;
} else if (pos.overlayX === 'start') {
overlayStartX = this._isRtl() ? -overlayRect.width : 0;
} else {
overlayStartX = this._isRtl() ? 0 : -overlayRect.width;
}
let overlayStartY;
if (pos.overlayY == 'center') {
overlayStartY = -overlayRect.height / 2;
} else {
overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;
}
return {
x: originPoint.x + overlayStartX,
y: originPoint.y + overlayStartY
};
}
_getOverlayFit(point, rawOverlayRect, viewport, position) {
const overlay = getRoundedBoundingClientRect(rawOverlayRect);
let {
x,
y
} = point;
let offsetX = this._getOffset(position, 'x');
let offsetY = this._getOffset(position, 'y');
if (offsetX) {
x += offsetX;
}
if (offsetY) {
y += offsetY;
}
let leftOverflow = 0 - x;
let rightOverflow = x + overlay.width - viewport.width;
let topOverflow = 0 - y;
let bottomOverflow = y + overlay.height - viewport.height;
let visibleWidth = this._subtractOverflows(overlay.width, leftOverflow, rightOverflow);
let visibleHeight = this._subtractOverflows(overlay.height, topOverflow, bottomOverflow);
let visibleArea = visibleWidth * visibleHeight;
return {
visibleArea,
isCompletelyWithinViewport: overlay.width * overlay.height === visibleArea,
fitsInViewportVertically: visibleHeight === overlay.height,
fitsInViewportHorizontally: visibleWidth == overlay.width
};
}
_canFitWithFlexibleDimensions(fit, point, viewport) {
if (this._hasFlexibleDimensions) {
const availableHeight = viewport.bottom - point.y;
const availableWidth = viewport.right - point.x;
const minHeight = getPixelValue(this._overlayRef.getConfig().minHeight);
const minWidth = getPixelValue(this._overlayRef.getConfig().minWidth);
const verticalFit = fit.fitsInViewportVertically || minHeight != null && minHeight <= availableHeight;
const horizontalFit = fit.fitsInViewportHorizontally || minWidth != null && minWidth <= availableWidth;
return verticalFit && horizontalFit;
}
return false;
}
_pushOverlayOnScreen(start, rawOverlayRect, scrollPosition) {
if (this._previousPushAmount && this._positionLocked) {
return {
x: start.x + this._previousPushAmount.x,
y: start.y + this._previousPushAmount.y
};
}
const overlay = getRoundedBoundingClientRect(rawOverlayRect);
const viewport = this._viewportRect;
const overflowRight = Math.max(start.x + overlay.width - viewport.width, 0);
const overflowBottom = Math.max(start.y + overlay.height - viewport.height, 0);
const overflowTop = Math.max(viewport.top - scrollPosition.top - start.y, 0);
const overflowLeft = Math.max(viewport.left - scrollPosition.left - start.x, 0);
let pushX = 0;
let pushY = 0;
if (overlay.width <= viewport.width) {
pushX = overflowLeft || -overflowRight;
} else {
pushX = start.x < this._getViewportMarginStart() ? viewport.left - scrollPosition.left - start.x : 0;
}
if (overlay.height <= viewport.height) {
pushY = overflowTop || -overflowBottom;
} else {
pushY = start.y < this._getViewportMarginTop() ? viewport.top - scrollPosition.top - start.y : 0;
}
this._previousPushAmount = {
x: pushX,
y: pushY
};
return {
x: start.x + pushX,
y: start.y + pushY
};
}
_applyPosition(position, originPoint) {
this._setTransformOrigin(position);
this._setOverlayElementStyles(originPoint, position);
this._setBoundingBoxStyles(originPoint, position);
if (position.panelClass) {
this._addPanelClasses(position.panelClass);
}
if (this._positionChanges.observers.length) {
const scrollVisibility = this._getScrollVisibility();
if (position !== this._lastPosition || !this._lastScrollVisibility || !compareScrollVisibility(this._lastScrollVisibility, scrollVisibility)) {
const changeEvent = new ConnectedOverlayPositionChange(position, scrollVisibility);
this._positionChanges.next(changeEvent);
}
this._lastScrollVisibility = scrollVisibility;
}
this._lastPosition = position;
this._isInitialRender = false;
}
_setTransformOrigin(position) {
if (!this._transformOriginSelector) {
return;
}
const elements = this._boundingBox.querySelectorAll(this._transformOriginSelector);
let xOrigin;
let yOrigin = position.overlayY;
if (position.overlayX === 'center') {
xOrigin = 'center';
} else if (this._isRtl()) {
xOrigin = position.overlayX === 'start' ? 'right' : 'left';
} else {
xOrigin = position.overlayX === 'start' ? 'left' : 'right';
}
for (let i = 0; i < elements.length; i++) {
elements[i].style.transformOrigin = `${xOrigin} ${yOrigin}`;
}
}
_calculateBoundingBoxRect(origin, position) {
const viewport = this._viewportRect;
const isRtl = this._isRtl();
let height, top, bottom;
if (position.overlayY === 'top') {
top = origin.y;
height = viewport.height - top + this._getViewportMarginBottom();
} else if (position.overlayY === 'bottom') {
bottom = viewport.height - origin.y + this._getViewportMarginTop() + this._getViewportMarginBottom();
height = viewport.height - bottom + this._getViewportMarginTop();
} else {
const smallestDistanceToViewportEdge = Math.min(viewport.bottom - origin.y + viewport.top, origin.y);
const previousHeight = this._lastBoundingBoxSize.height;
height = smallestDistanceToViewportEdge * 2;
top = origin.y - smallestDistanceToViewportEdge;
if (height > previousHeight && !this._isInitialRender && !this._growAfterOpen) {
top = origin.y - previousHeight / 2;
}
}
const isBoundedByRightViewportEdge = position.overlayX === 'start' && !isRtl || position.overlayX === 'end' && isRtl;
const isBoundedByLeftViewportEdge = position.overlayX === 'end' && !isRtl || position.overlayX === 'start' && isRtl;
let width, left, right;
if (isBoundedByLeftViewportEdge) {
right = viewport.width - origin.x + this._getViewportMarginStart() + this._getViewportMarginEnd();
width = origin.x - this._getViewportMarginStart();
} else if (isBoundedByRightViewportEdge) {
left = origin.x;
width = viewport.right - origin.x - this._getViewportMarginEnd();
} else {
const smallestDistanceToViewportEdge = Math.min(viewport.right - origin.x + viewport.left, origin.x);
const previousWidth = this._lastBoundingBoxSize.width;
width = smallestDistanceToViewportEdge * 2;
left = origin.x - smallestDistanceToViewportEdge;
if (width > previousWidth && !this._isInitialRender && !this._growAfterOpen) {
left = origin.x - previousWidth / 2;
}
}
return {
top: top,
left: left,
bottom: bottom,
right: right,
width,
height
};
}
_setBoundingBoxStyles(origin, position) {
const boundingBoxRect = this._calculateBoundingBoxRect(origin, position);
if (!this._isInitialRender && !this._growAfterOpen) {
boundingBoxRect.height = Math.min(boundingBoxRect.height, this._lastBoundingBoxSize.height);
boundingBoxRect.width = Math.min(boundingBoxRect.width, this._lastBoundingBoxSize.width);
}
const styles = {};
if (this._hasExactPosition()) {
styles.top = styles.left = '0';
styles.bottom = styles.right = 'auto';
styles.maxHeight = styles.maxWidth = '';
styles.width = styles.height = '100%';
} else {
const maxHeight = this._overlayRef.getConfig().maxHeight;
const maxWidth = this._overlayRef.getConfig().maxWidth;
styles.width = coerceCssPixelValue(boundingBoxRect.width);
styles.height = coerceCssPixelValue(boundingBoxRect.height);
styles.top = coerceCssPixelValue(boundingBoxRect.top) || 'auto';
styles.bottom = coerceCssPixelValue(boundingBoxRect.bottom) || 'auto';
styles.left = coerceCssPixelValue(boundingBoxRect.left) || 'auto';
styles.right = coerceCssPixelValue(boundingBoxRect.right) || 'auto';
if (position.overlayX === 'center') {
styles.alignItems = 'center';
} else {
styles.alignItems = position.overlayX === 'end' ? 'flex-end' : 'flex-start';
}
if (position.overlayY === 'center') {
styles.justifyContent = 'center';
} else {
styles.justifyContent = position.overlayY === 'bottom' ? 'flex-end' : 'flex-start';
}
if (maxHeight) {
styles.maxHeight = coerceCssPixelValue(maxHeight);
}
if (maxWidth) {
styles.maxWidth = coerceCssPixelValue(maxWidth);
}
}
this._lastBoundingBoxSize = boundingBoxRect;
extendStyles(this._boundingBox.style, styles);
}
_resetBoundingBoxStyles() {
extendStyles(this._boundingBox.style, {
top: '0',
left: '0',
right: '0',
bottom: '0',
height: '',
width: '',
alignItems: '',
justifyContent: ''
});
}
_resetOverlayElementStyles() {
extendStyles(this._pane.style, {
top: '',
left: '',
bottom: '',
right: '',
position: '',
transform: ''
});
}
_setOverlayElementStyles(originPoint, position) {
const styles = {};
const hasExactPosition = this._hasExactPosition();
const hasFlexibleDimensions = this._hasFlexibleDimensions;
const config = this._overlayRef.getConfig();
if (hasExactPosition) {
const scrollPosition = this._viewportRuler.getViewportScrollPosition();
extendStyles(styles, this._getExactOverlayY(position, originPoint, scrollPosition));
extendStyles(styles, this._getExactOverlayX(position, originPoint, scrollPosition));
} else {
styles.position = 'static';
}
let transformString = '';
let offsetX = this._getOffset(position, 'x');
let offsetY = this._getOffset(position, 'y');
if (offsetX) {
transformString += `translateX(${offsetX}px) `;
}
if (offsetY) {
transformString += `translateY(${offsetY}px)`;
}
styles.transform = transformString.trim();
if (config.maxHeight) {
if (hasExactPosition) {
styles.maxHeight = coerceCssPixelValue(config.maxHeight);
} else if (hasFlexibleDimensions) {
styles.maxHeight = '';
}
}
if (config.maxWidth) {
if (hasExactPosition) {
styles.maxWidth = coerceCssPixelValue(config.maxWidth);
} else if (hasFlexibleDimensions) {
styles.maxWidth = '';
}
}
extendStyles(this._pane.style, styles);
}
_getExactOverlayY(position, originPoint, scrollPosition) {
let styles = {
top: '',
bottom: ''
};
let overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
if (this._isPushed) {
overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
}
if (position.overlayY === 'bottom') {
const documentHeight = this._document.documentElement.clientHeight;
styles.bottom = `${documentHeight - (overlayPoint.y + this._overlayRect.height)}px`;
} else {
styles.top = coerceCssPixelValue(overlayPoint.y);
}
return styles;
}
_getExactOverlayX(position, originPoint, scrollPosition) {
let styles = {
left: '',
right: ''
};
let overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
if (this._isPushed) {
overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
}
let horizontalStyleProperty;
if (this._isRtl()) {
horizontalStyleProperty = position.overlayX === 'end' ? 'left' : 'right';
} else {
horizontalStyleProperty = position.overlayX === 'end' ? 'right' : 'left';
}
if (horizontalStyleProperty === 'right') {
const documentWidth = this._document.documentElement.clientWidth;
styles.right = `${documentWidth - (overlayPoint.x + this._overlayRect.width)}px`;
} else {
styles.left = coerceCssPixelValue(overlayPoint.x);
}
return styles;
}
_getScrollVisibility() {
const originBounds = this._getOriginRect();
const overlayBounds = this._pane.getBoundingClientRect();
const scrollContainerBounds = this._scrollables.map(scrollable => {
return scrollable.getElementRef().nativeElement.getBoundingClientRect();
});
return {
isOriginClipped: isElementClippedByScrolling(originBounds, scrollContainerBounds),
isOriginOutsideView: isElementScrolledOutsideView(originBounds, scrollContainerBounds),
isOverlayClipped: isElementClippedByScrolling(overlayBounds, scrollContainerBounds),
isOverlayOutsideView: isElementScrolledOutsideView(overlayBounds, scrollContainerBounds)
};
}
_subtractOverflows(length, ...overflows) {
return overflows.reduce((currentValue, currentOverflow) => {
return currentValue - Math.max(currentOverflow, 0);
}, length);
}
_getNarrowedViewportRect() {
const width = this._document.documentElement.clientWidth;
const height = this._document.documentElement.clientHeight;
const scrollPosition = this._viewportRuler.getViewportScrollPosition();
return {
top: scrollPosition.top + this._getViewportMarginTop(),
left: scrollPosition.left + this._getViewportMarginStart(),
right: scrollPosition.left + width - this._getViewportMarginEnd(),
bottom: scrollPosition.top + height - this._getViewportMarginBottom(),
width: width - this._getViewportMarginStart() - this._getViewportMarginEnd(),
height: height - this._getViewportMarginTop() - this._getViewportMarginBottom()
};
}
_isRtl() {
return this._overlayRef.getDirection() === 'rtl';
}
_hasExactPosition() {
return !this._hasFlexibleDimensions || this._isPushed;
}
_getOffset(position, axis) {
if (axis === 'x') {
return position.offsetX == null ? this._offsetX : position.offsetX;
}
return position.offsetY == null ? this._offsetY : position.offsetY;
}
_validatePositions() {
if (typeof ngDevMode === 'undefined' || ngDevMode) {
if (!this._preferredPositions.length) {
throw Error('FlexibleConnectedPositionStrategy: At least one position is required.');
}
this._preferredPositions.forEach(pair => {
validateHorizontalPosition('originX', pair.originX);
validateVerticalPosition('originY', pair.originY);
validateHorizontalPosition('overlayX', pair.overlayX);
validateVerticalPosition('overlayY', pair.overlayY);
});
}
}
_addPanelClasses(cssClasses) {
if (this._pane) {
coerceArray(cssClasses).forEach(cssClass => {
if (cssClass !== '' && this._appliedPanelClasses.indexOf(cssClass) === -1) {
this._appliedPanelClasses.push(cssClass);
this._pane.classList.add(cssClass);
}
});
}
}
_clearPanelClasses() {
if (this._pane) {
this._appliedPanelClasses.forEach(cssClass => {
this._pane.classList.remove(cssClass);
});
this._appliedPanelClasses = [];
}
}
_getViewportMarginStart() {
if (typeof this._viewportMargin === 'number') return this._viewportMargin;
return this._viewportMargin?.start ?? 0;
}
_getViewportMarginEnd() {
if (typeof this._viewportMargin === 'number') return this._viewportMargin;
return this._viewportMargin?.end ?? 0;
}
_getViewportMarginTop() {
if (typeof this._viewportMargin === 'number') return this._viewportMargin;
return this._viewportMargin?.top ?? 0;
}
_getViewportMarginBottom() {
if (typeof this._viewportMargin === 'number') return this._viewportMargin;
return this._viewportMargin?.bottom ?? 0;
}
_getOriginRect() {
const origin = this._origin;
if (origin instanceof ElementRef) {
return origin.nativeElement.getBoundingClientRect();
}
if (origin instanceof Element) {
return origin.getBoundingClientRect();
}
const width = origin.width || 0;
const height = origin.height || 0;
return {
top: origin.y,
bottom: origin.y + height,
left: origin.x,
right: origin.x + width,
height,
width
};
}
_getContainerRect() {
const isInlinePopover = this._overlayRef.getConfig().usePopover && this._popoverLocation !== 'global';
const element = this._overlayContainer.getContainerElement();
if (isInlinePopover) {
element.style.display = 'block';
}
const dimensions = element.getBoundingClientRect();
if (isInlinePopover) {
element.style.display = '';
}
return dimensions;
}
}
function extendStyles(destination, source) {
for (let key in source) {
if (source.hasOwnProperty(key)) {
destination[key] = source[key];
}
}
return destination;
}
function getPixelValue(input) {
if (typeof input !== 'number' && input != null) {
const [value, units] = input.split(cssUnitPattern);
return !units || units === 'px' ? parseFloat(value) : null;
}
return input || null;
}
function getRoundedBoundingClientRect(clientRect) {
return {
top: Math.floor(clientRect.top),
right: Math.floor(clientRect.right),
bottom: Math.floor(clientRect.bottom),
left: Math.floor(clientRect.left),
width: Math.floor(clientRect.width),
height: Math.floor(clientRect.height)
};
}
function compareScrollVisibility(a, b) {
if (a === b) {
return true;
}
return a.isOriginClipped === b.isOriginClipped && a.isOriginOutsideView === b.isOriginOutsideView && a.isOverlayClipped === b.isOverlayClipped && a.isOverlayOutsideView === b.isOverlayOutsideView;
}
const STANDARD_DROPDOWN_BELOW_POSITIONS = [{
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top'
}, {
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'bottom'
}, {
originX: 'end',
originY: 'bottom',
overlayX: 'end',
overlayY: 'top'
}, {
originX: 'end',
originY: 'top',
overlayX: 'end',
overlayY: 'bottom'
}];
const STANDARD_DROPDOWN_ADJACENT_POSITIONS = [{
originX: 'end',
originY: 'top',
overlayX: 'start',
overlayY: 'top'
}, {
originX: 'end',
originY: 'bottom',
overlayX: 'start',
overlayY: 'bottom'
}, {
originX: 'start',
originY: 'top',
overlayX: 'end',
overlayY: 'top'
}, {
originX: 'start',
originY: 'bottom',
overlayX: 'end',
overlayY: 'bottom'
}];
const wrapperClass = 'cdk-global-overlay-wrapper';
function createGlobalPositionStrategy(_injector) {
return new GlobalPositionStrategy();
}
class GlobalPositionStrategy {
_overlayRef;
_cssPosition = 'static';
_topOffset = '';
_bottomOffset = '';
_alignItems = '';
_xPosition = '';
_xOffset = '';
_width = '';
_height = '';
_isDisposed = false;
attach(overlayRef) {
const config = overlayRef.getConfig();
this._overlayRef = overlayRef;
if (this._width && !config.width) {
overlayRef.updateSize({
width: this._width
});
}
if (this._height && !config.height) {
overlayRef.updateSize({
height: this._height
});
}
overlayRef.hostElement.classList.add(wrapperClass);
this._isDisposed = false;
}
top(value = '') {
this._bottomOffset = '';
this._topOffset = value;
this._alignItems = 'flex-start';
return this;
}
left(value = '') {
this._xOffset = value;
this._xPosition = 'left';
return this;
}
bottom(value = '') {
this._topOffset = '';
this._bottomOffset = value;
this._alignItems = 'flex-end';
return this;
}
right(value = '') {
this._xOffset = value;
this._xPosition = 'right';
return this;
}
start(value = '') {
this._xOffset = value;
this._xPosition = 'start';
return this;
}
end(value = '') {
this._xOffset = value;
this._xPosition = 'end';
return this;
}
width(value = '') {
if (this._overlayRef) {
this._overlayRef.updateSize({
width: value
});
} else {
this._width = value;
}
return this;
}
height(value = '') {
if (this._overlayRef) {
this._overlayRef.updateSize({
height: value
});
} else {
this._height = value;
}
return this;
}
centerHorizontally(offset = '') {
this.left(offset);
this._xPosition = 'center';
return this;
}
centerVertically(offset = '') {
this.top(offset);
this._alignItems = 'center';
return this;
}
apply() {
if (!this._overlayRef || !this._overlayRef.hasAttached()) {
return;
}
const styles = this._overlayRef.overlayElement.style;
const parentStyles = this._overlayRef.hostElement.style;
const config = this._overlayRef.getConfig();
const {
width,
height,
maxWidth,
maxHeight
} = config;
const shouldBeFlushHorizontally = (width === '100%' || width === '100vw') && (!maxWidth || maxWidth === '100%' || maxWidth === '100vw');
const shouldBeFlushVertically = (height === '100%' || height === '100vh') && (!maxHeight || maxHeight === '100%' || maxHeight === '100vh');
const xPosition = this._xPosition;
const xOffset = this._xOffset;
const isRtl = this._overlayRef.getConfig().direction === 'rtl';
let marginLeft = '';
let marginRight = '';
let justifyContent = '';
if (shouldBeFlushHorizontally) {
justifyContent = 'flex-start';
} else if (xPosition === 'center') {
justifyContent = 'center';
if (isRtl) {
marginRight = xOffset;
} else {
marginLeft = xOffset;
}
} else if (isRtl) {
if (xPosition === 'left' || xPosition === 'end') {
justifyContent = 'flex-end';
marginLeft = xOffset;
} else if (xPosition === 'right' || xPosition === 'start') {
justifyContent = 'flex-start';
marginRight = xOffset;
}
} else if (xPosition === 'left' || xPosition === 'start') {
justifyContent = 'flex-start';
marginLeft = xOffset;
} else if (xPosition === 'right' || xPosition === 'end') {
justifyContent = 'flex-end';
marginRight = xOffset;
}
styles.position = this._cssPosition;
styles.marginLeft = shouldBeFlushHorizontally ? '0' : marginLeft;
styles.marginTop = shouldBeFlushVertically ? '0' : this._topOffset;
styles.marginBottom = this._bottomOffset;
styles.marginRight = shouldBeFlushHorizontally ? '0' : marginRight;
parentStyles.justifyContent = justifyContent;
parentStyles.alignItems = shouldBeFlushVertically ? 'flex-start' : this._alignItems;
}
dispose() {
if (this._isDisposed || !this._overlayRef) {
return;
}
const styles = this._overlayRef.overlayElement.style;
const parent = this._overlayRef.hostElement;
const parentStyles = parent.style;
parent.classList.remove(wrapperClass);
parentStyles.justifyContent = parentStyles.alignItems = styles.marginTop = styles.marginBottom = styles.marginLeft = styles.marginRight = styles.position = '';
this._overlayRef = null;
this._isDisposed = true;
}
}
class OverlayPositionBuilder {
_injector = inject(Injector);
constructor() {}
global() {
return createGlobalPositionStrategy();
}
flexibleConnectedTo(origin) {
return createFlexibleConnectedPositionStrategy(this._injector, origin);
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayPositionBuilder,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayPositionBuilder,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayPositionBuilder,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
const OVERLAY_DEFAULT_CONFIG = new InjectionToken('OVERLAY_DEFAULT_CONFIG');
function createOverlayRef(injector, config) {
injector.get(_CdkPrivateStyleLoader).load(_CdkOverlayStyleLoader);
const overlayContainer = injector.get(OverlayContainer);
const doc = injector.get(DOCUMENT);
const idGenerator = injector.get(_IdGenerator);
const appRef = injector.get(ApplicationRef);
const directionality = injector.get(Directionality);
const renderer = injector.get(Renderer2, null, {
optional: true
}) || injector.get(RendererFactory2).createRenderer(null, null);
const overlayConfig = new OverlayConfig(config);
const defaultUsePopover = injector.get(OVERLAY_DEFAULT_CONFIG, null, {
optional: true
})?.usePopover ?? true;
overlayConfig.direction = overlayConfig.direction || directionality.value;
if (!('showPopover' in doc.body)) {
overlayConfig.usePopover = false;
} else {
overlayConfig.usePopover = config?.usePopover ?? defaultUsePopover;
}
const pane = doc.createElement('div');
const host = doc.createElement('div');
pane.id = idGenerator.getId('cdk-overlay-');
pane.classList.add('cdk-overlay-pane');
host.appendChild(pane);
if (overlayConfig.usePopover) {
host.setAttribute('popover', 'manual');
host.classList.add('cdk-overlay-popover');
}
const customInsertionPoint = overlayConfig.usePopover ? overlayConfig.positionStrategy?.getPopoverInsertionPoint?.() : null;
if (isElement(customInsertionPoint)) {
customInsertionPoint.after(host);
} else if (customInsertionPoint?.type === 'parent') {
customInsertionPoint.element.appendChild(host);
} else {
overlayContainer.getContainerElement().appendChild(host);
}
return new OverlayRef(new DomPortalOutlet(pane, appRef, injector), host, pane, overlayConfig, injector.get(NgZone), injector.get(OverlayKeyboardDispatcher), doc, injector.get(Location), injector.get(OverlayOutsideClickDispatcher), config?.disableAnimations ?? injector.get(ANIMATION_MODULE_TYPE, null, {
optional: true
}) === 'NoopAnimations', injector.get(EnvironmentInjector), renderer);
}
class Overlay {
scrollStrategies = inject(ScrollStrategyOptions);
_positionBuilder = inject(OverlayPositionBuilder);
_injector = inject(Injector);
constructor() {}
create(config) {
return createOverlayRef(this._injector, config);
}
position() {
return this._positionBuilder;
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: Overlay,
deps: [],
target: i0.ɵɵFactoryTarget.Injectable
});
static ɵprov = i0.ɵɵngDeclareInjectable({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: Overlay,
providedIn: 'root'
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: Overlay,
decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}],
ctorParameters: () => []
});
const defaultPositionList = [{
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top'
}, {
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'bottom'
}, {
originX: 'end',
originY: 'top',
overlayX: 'end',
overlayY: 'bottom'
}, {
originX: 'end',
originY: 'bottom',
overlayX: 'end',
overlayY: 'top'
}];
const CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY = new InjectionToken('cdk-connected-overlay-scroll-strategy', {
providedIn: 'root',
factory: () => {
const injector = inject(Injector);
return () => createRepositionScrollStrategy(injector);
}
});
class CdkOverlayOrigin {
elementRef = inject(ElementRef);
constructor() {}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: CdkOverlayOrigin,
deps: [],
target: i0.ɵɵFactoryTarget.Directive
});
static ɵdir = i0.ɵɵngDeclareDirective({
minVersion: "14.0.0",
version: "21.0.3",
type: CdkOverlayOrigin,
isStandalone: true,
selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]",
exportAs: ["cdkOverlayOrigin"],
ngImport: i0
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: CdkOverlayOrigin,
decorators: [{
type: Directive,
args: [{
selector: '[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]',
exportAs: 'cdkOverlayOrigin'
}]
}],
ctorParameters: () => []
});
const CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG = new InjectionToken('cdk-connected-overlay-default-config');
class CdkConnectedOverlay {
_dir = inject(Directionality, {
optional: true
});
_injector = inject(Injector);
_overlayRef;
_templatePortal;
_backdropSubscription = Subscription.EMPTY;
_attachSubscription = Subscription.EMPTY;
_detachSubscription = Subscription.EMPTY;
_positionSubscription = Subscription.EMPTY;
_offsetX;
_offsetY;
_position;
_scrollStrategyFactory = inject(CDK_CONNECTED_OVERLAY_SCROLL_STRATEGY);
_ngZone = inject(NgZone);
origin;
positions;
positionStrategy;
get offsetX() {
return this._offsetX;
}
set offsetX(offsetX) {
this._offsetX = offsetX;
if (this._position) {
this._updatePositionStrategy(this._position);
}
}
get offsetY() {
return this._offsetY;
}
set offsetY(offsetY) {
this._offsetY = offsetY;
if (this._position) {
this._updatePositionStrategy(this._position);
}
}
width;
height;
minWidth;
minHeight;
backdropClass;
panelClass;
viewportMargin = 0;
scrollStrategy;
open = false;
disableClose = false;
transformOriginSelector;
hasBackdrop = false;
lockPosition = false;
flexibleDimensions = false;
growAfterOpen = false;
push = false;
disposeOnNavigation = false;
usePopover;
matchWidth = false;
set _config(value) {
if (typeof value !== 'string') {
this._assignConfig(value);
}
}
backdropClick = new EventEmitter();
positionChange = new EventEmitter();
attach = new EventEmitter();
detach = new EventEmitter();
overlayKeydown = new EventEmitter();
overlayOutsideClick = new EventEmitter();
constructor() {
const templateRef = inject(TemplateRef);
const viewContainerRef = inject(ViewContainerRef);
const defaultConfig = inject(CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG, {
optional: true
});
const globalConfig = inject(OVERLAY_DEFAULT_CONFIG, {
optional: true
});
this.usePopover = globalConfig?.usePopover === false ? null : 'global';
this._templatePortal = new TemplatePortal(templateRef, viewContainerRef);
this.scrollStrategy = this._scrollStrategyFactory();
if (defaultConfig) {
this._assignConfig(defaultConfig);
}
}
get overlayRef() {
return this._overlayRef;
}
get dir() {
return this._dir ? this._dir.value : 'ltr';
}
ngOnDestroy() {
this._attachSubscription.unsubscribe();
this._detachSubscription.unsubscribe();
this._backdropSubscription.unsubscribe();
this._positionSubscription.unsubscribe();
this._overlayRef?.dispose();
}
ngOnChanges(changes) {
if (this._position) {
this._updatePositionStrategy(this._position);
this._overlayRef?.updateSize({
width: this._getWidth(),
minWidth: this.minWidth,
height: this.height,
minHeight: this.minHeight
});
if (changes['origin'] && this.open) {
this._position.apply();
}
}
if (changes['open']) {
this.open ? this.attachOverlay() : this.detachOverlay();
}
}
_createOverlay() {
if (!this.positions || !this.positions.length) {
this.positions = defaultPositionList;
}
const overlayRef = this._overlayRef = createOverlayRef(this._injector, this._buildConfig());
this._attachSubscription = overlayRef.attachments().subscribe(() => this.attach.emit());
this._detachSubscription = overlayRef.detachments().subscribe(() => this.detach.emit());
overlayRef.keydownEvents().subscribe(event => {
this.overlayKeydown.next(event);
if (event.keyCode === ESCAPE && !this.disableClose && !hasModifierKey(event)) {
event.preventDefault();
this.detachOverlay();
}
});
this._overlayRef.outsidePointerEvents().subscribe(event => {
const origin = this._getOriginElement();
const target = _getEventTarget(event);
if (!origin || origin !== target && !origin.contains(target)) {
this.overlayOutsideClick.next(event);
}
});
}
_buildConfig() {
const positionStrategy = this._position = this.positionStrategy || this._createPositionStrategy();
const overlayConfig = new OverlayConfig({
direction: this._dir || 'ltr',
positionStrategy,
scrollStrategy: this.scrollStrategy,
hasBackdrop: this.hasBackdrop,
disposeOnNavigation: this.disposeOnNavigation,
usePopover: !!this.usePopover
});
if (this.height || this.height === 0) {
overlayConfig.height = this.height;
}
if (this.minWidth || this.minWidth === 0) {
overlayConfig.minWidth = this.minWidth;
}
if (this.minHeight || this.minHeight === 0) {
overlayConfig.minHeight = this.minHeight;
}
if (this.backdropClass) {
overlayConfig.backdropClass = this.backdropClass;
}
if (this.panelClass) {
overlayConfig.panelClass = this.panelClass;
}
return overlayConfig;
}
_updatePositionStrategy(positionStrategy) {
const positions = this.positions.map(currentPosition => ({
originX: currentPosition.originX,
originY: currentPosition.originY,
overlayX: currentPosition.overlayX,
overlayY: currentPosition.overlayY,
offsetX: currentPosition.offsetX || this.offsetX,
offsetY: currentPosition.offsetY || this.offsetY,
panelClass: currentPosition.panelClass || undefined
}));
return positionStrategy.setOrigin(this._getOrigin()).withPositions(positions).withFlexibleDimensions(this.flexibleDimensions).withPush(this.push).withGrowAfterOpen(this.growAfterOpen).withViewportMargin(this.viewportMargin).withLockedPosition(this.lockPosition).withTransformOriginOn(this.transformOriginSelector).withPopoverLocation(this.usePopover === null ? 'global' : this.usePopover);
}
_createPositionStrategy() {
const strategy = createFlexibleConnectedPositionStrategy(this._injector, this._getOrigin());
this._updatePositionStrategy(strategy);
return strategy;
}
_getOrigin() {
if (this.origin instanceof CdkOverlayOrigin) {
return this.origin.elementRef;
} else {
return this.origin;
}
}
_getOriginElement() {
if (this.origin instanceof CdkOverlayOrigin) {
return this.origin.elementRef.nativeElement;
}
if (this.origin instanceof ElementRef) {
return this.origin.nativeElement;
}
if (typeof Element !== 'undefined' && this.origin instanceof Element) {
return this.origin;
}
return null;
}
_getWidth() {
if (this.width) {
return this.width;
}
return this.matchWidth ? this._getOriginElement()?.getBoundingClientRect?.().width : undefined;
}
attachOverlay() {
if (!this._overlayRef) {
this._createOverlay();
}
const ref = this._overlayRef;
ref.getConfig().hasBackdrop = this.hasBackdrop;
ref.updateSize({
width: this._getWidth()
});
if (!ref.hasAttached()) {
ref.attach(this._templatePortal);
}
if (this.hasBackdrop) {
this._backdropSubscription = ref.backdropClick().subscribe(event => this.backdropClick.emit(event));
} else {
this._backdropSubscription.unsubscribe();
}
this._positionSubscription.unsubscribe();
if (this.positionChange.observers.length > 0) {
this._positionSubscription = this._position.positionChanges.pipe(takeWhile(() => this.positionChange.observers.length > 0)).subscribe(position => {
this._ngZone.run(() => this.positionChange.emit(position));
if (this.positionChange.observers.length === 0) {
this._positionSubscription.unsubscribe();
}
});
}
this.open = true;
}
detachOverlay() {
this._overlayRef?.detach();
this._backdropSubscription.unsubscribe();
this._positionSubscription.unsubscribe();
this.open = false;
}
_assignConfig(config) {
this.origin = config.origin ?? this.origin;
this.positions = config.positions ?? this.positions;
this.positionStrategy = config.positionStrategy ?? this.positionStrategy;
this.offsetX = config.offsetX ?? this.offsetX;
this.offsetY = config.offsetY ?? this.offsetY;
this.width = config.width ?? this.width;
this.height = config.height ?? this.height;
this.minWidth = config.minWidth ?? this.minWidth;
this.minHeight = config.minHeight ?? this.minHeight;
this.backdropClass = config.backdropClass ?? this.backdropClass;
this.panelClass = config.panelClass ?? this.panelClass;
this.viewportMargin = config.viewportMargin ?? this.viewportMargin;
this.scrollStrategy = config.scrollStrategy ?? this.scrollStrategy;
this.disableClose = config.disableClose ?? this.disableClose;
this.transformOriginSelector = config.transformOriginSelector ?? this.transformOriginSelector;
this.hasBackdrop = config.hasBackdrop ?? this.hasBackdrop;
this.lockPosition = config.lockPosition ?? this.lockPosition;
this.flexibleDimensions = config.flexibleDimensions ?? this.flexibleDimensions;
this.growAfterOpen = config.growAfterOpen ?? this.growAfterOpen;
this.push = config.push ?? this.push;
this.disposeOnNavigation = config.disposeOnNavigation ?? this.disposeOnNavigation;
this.usePopover = config.usePopover ?? this.usePopover;
this.matchWidth = config.matchWidth ?? this.matchWidth;
}
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: CdkConnectedOverlay,
deps: [],
target: i0.ɵɵFactoryTarget.Directive
});
static ɵdir = i0.ɵɵngDeclareDirective({
minVersion: "16.1.0",
version: "21.0.3",
type: CdkConnectedOverlay,
isStandalone: true,
selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]",
inputs: {
origin: ["cdkConnectedOverlayOrigin", "origin"],
positions: ["cdkConnectedOverlayPositions", "positions"],
positionStrategy: ["cdkConnectedOverlayPositionStrategy", "positionStrategy"],
offsetX: ["cdkConnectedOverlayOffsetX", "offsetX"],
offsetY: ["cdkConnectedOverlayOffsetY", "offsetY"],
width: ["cdkConnectedOverlayWidth", "width"],
height: ["cdkConnectedOverlayHeight", "height"],
minWidth: ["cdkConnectedOverlayMinWidth", "minWidth"],
minHeight: ["cdkConnectedOverlayMinHeight", "minHeight"],
backdropClass: ["cdkConnectedOverlayBackdropClass", "backdropClass"],
panelClass: ["cdkConnectedOverlayPanelClass", "panelClass"],
viewportMargin: ["cdkConnectedOverlayViewportMargin", "viewportMargin"],
scrollStrategy: ["cdkConnectedOverlayScrollStrategy", "scrollStrategy"],
open: ["cdkConnectedOverlayOpen", "open"],
disableClose: ["cdkConnectedOverlayDisableClose", "disableClose"],
transformOriginSelector: ["cdkConnectedOverlayTransformOriginOn", "transformOriginSelector"],
hasBackdrop: ["cdkConnectedOverlayHasBackdrop", "hasBackdrop", booleanAttribute],
lockPosition: ["cdkConnectedOverlayLockPosition", "lockPosition", booleanAttribute],
flexibleDimensions: ["cdkConnectedOverlayFlexibleDimensions", "flexibleDimensions", booleanAttribute],
growAfterOpen: ["cdkConnectedOverlayGrowAfterOpen", "growAfterOpen", booleanAttribute],
push: ["cdkConnectedOverlayPush", "push", booleanAttribute],
disposeOnNavigation: ["cdkConnectedOverlayDisposeOnNavigation", "disposeOnNavigation", booleanAttribute],
usePopover: ["cdkConnectedOverlayUsePopover", "usePopover"],
matchWidth: ["cdkConnectedOverlayMatchWidth", "matchWidth", booleanAttribute],
_config: ["cdkConnectedOverlay", "_config"]
},
outputs: {
backdropClick: "backdropClick",
positionChange: "positionChange",
attach: "attach",
detach: "detach",
overlayKeydown: "overlayKeydown",
overlayOutsideClick: "overlayOutsideClick"
},
exportAs: ["cdkConnectedOverlay"],
usesOnChanges: true,
ngImport: i0
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: CdkConnectedOverlay,
decorators: [{
type: Directive,
args: [{
selector: '[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]',
exportAs: 'cdkConnectedOverlay'
}]
}],
ctorParameters: () => [],
propDecorators: {
origin: [{
type: Input,
args: ['cdkConnectedOverlayOrigin']
}],
positions: [{
type: Input,
args: ['cdkConnectedOverlayPositions']
}],
positionStrategy: [{
type: Input,
args: ['cdkConnectedOverlayPositionStrategy']
}],
offsetX: [{
type: Input,
args: ['cdkConnectedOverlayOffsetX']
}],
offsetY: [{
type: Input,
args: ['cdkConnectedOverlayOffsetY']
}],
width: [{
type: Input,
args: ['cdkConnectedOverlayWidth']
}],
height: [{
type: Input,
args: ['cdkConnectedOverlayHeight']
}],
minWidth: [{
type: Input,
args: ['cdkConnectedOverlayMinWidth']
}],
minHeight: [{
type: Input,
args: ['cdkConnectedOverlayMinHeight']
}],
backdropClass: [{
type: Input,
args: ['cdkConnectedOverlayBackdropClass']
}],
panelClass: [{
type: Input,
args: ['cdkConnectedOverlayPanelClass']
}],
viewportMargin: [{
type: Input,
args: ['cdkConnectedOverlayViewportMargin']
}],
scrollStrategy: [{
type: Input,
args: ['cdkConnectedOverlayScrollStrategy']
}],
open: [{
type: Input,
args: ['cdkConnectedOverlayOpen']
}],
disableClose: [{
type: Input,
args: ['cdkConnectedOverlayDisableClose']
}],
transformOriginSelector: [{
type: Input,
args: ['cdkConnectedOverlayTransformOriginOn']
}],
hasBackdrop: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayHasBackdrop',
transform: booleanAttribute
}]
}],
lockPosition: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayLockPosition',
transform: booleanAttribute
}]
}],
flexibleDimensions: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayFlexibleDimensions',
transform: booleanAttribute
}]
}],
growAfterOpen: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayGrowAfterOpen',
transform: booleanAttribute
}]
}],
push: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayPush',
transform: booleanAttribute
}]
}],
disposeOnNavigation: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayDisposeOnNavigation',
transform: booleanAttribute
}]
}],
usePopover: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayUsePopover'
}]
}],
matchWidth: [{
type: Input,
args: [{
alias: 'cdkConnectedOverlayMatchWidth',
transform: booleanAttribute
}]
}],
_config: [{
type: Input,
args: ['cdkConnectedOverlay']
}],
backdropClick: [{
type: Output
}],
positionChange: [{
type: Output
}],
attach: [{
type: Output
}],
detach: [{
type: Output
}],
overlayKeydown: [{
type: Output
}],
overlayOutsideClick: [{
type: Output
}]
}
});
class OverlayModule {
static ɵfac = i0.ɵɵngDeclareFactory({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayModule,
deps: [],
target: i0.ɵɵFactoryTarget.NgModule
});
static ɵmod = i0.ɵɵngDeclareNgModule({
minVersion: "14.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayModule,
imports: [BidiModule, PortalModule, ScrollingModule, CdkConnectedOverlay, CdkOverlayOrigin],
exports: [CdkConnectedOverlay, CdkOverlayOrigin, ScrollingModule]
});
static ɵinj = i0.ɵɵngDeclareInjector({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayModule,
providers: [Overlay],
imports: [BidiModule, PortalModule, ScrollingModule, ScrollingModule]
});
}
i0.ɵɵngDeclareClassMetadata({
minVersion: "12.0.0",
version: "21.0.3",
ngImport: i0,
type: OverlayModule,
decorators: [{
type: NgModule,
args: [{
imports: [BidiModule, PortalModule, ScrollingModule, CdkConnectedOverlay, CdkOverlayOrigin],
exports: [CdkConnectedOverlay, CdkOverlayOrigin, ScrollingModule],
providers: [Overlay]
}]
}]
});
export { BlockScrollStrategy, CDK_CONNECTED_OVERLAY_DEFAULT_CONFIG, CdkConnectedOverlay, CdkOverlayOrigin, CloseScrollStrategy, ConnectedOverlayPositionChange, ConnectionPositionPair, FlexibleConnectedPositionStrategy, GlobalPositionStrategy, NoopScrollStrategy, OVERLAY_DEFAULT_CONFIG, Overlay, OverlayConfig, OverlayContainer, OverlayKeyboardDispatcher, OverlayModule, OverlayOutsideClickDispatcher, OverlayPositionBuilder, OverlayRef, RepositionScrollStrategy, STANDARD_DROPDOWN_ADJACENT_POSITIONS, STANDARD_DROPDOWN_BELOW_POSITIONS, ScrollStrategyOptions, ScrollingVisibility, createBlockScrollStrategy, createCloseScrollStrategy, createFlexibleConnectedPositionStrategy, createGlobalPositionStrategy, createNoopScrollStrategy, createOverlayRef, createRepositionScrollStrategy, validateHorizontalPosition, validateVerticalPosition };
//# sourceMappingURL=_overlay-module-chunk.mjs.map