@covalent/core
Version:
Core Teradata UI Platform for layouts, icons, custom components and themes. This should be added as a dependency for any project that wants to use layouts, icons and themes for Angular Material.
805 lines (795 loc) • 43.1 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, Directive, Optional, Inject, ViewChild, Component, ViewEncapsulation, ChangeDetectionStrategy, HostBinding, HostListener, Injector, TemplateRef, InjectFlags, Injectable, SkipSelf, Input, NgModule } from '@angular/core';
import * as i3 from '@angular/cdk/portal';
import { BasePortalOutlet, CdkPortalOutlet, ComponentPortal, TemplatePortal, PortalModule } from '@angular/cdk/portal';
import { AnimationDurations, AnimationCurves, MatCommonModule } from '@angular/material/core';
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA, MAT_DIALOG_DEFAULT_OPTIONS, MatDialogModule } from '@angular/material/dialog';
import * as i1$1 from '@angular/cdk/overlay';
import { OverlayConfig } from '@angular/cdk/overlay';
import * as i1 from '@angular/cdk/a11y';
import { DOCUMENT } from '@angular/common';
import { trigger, state, style, transition, animate } from '@angular/animations';
import { Subject, of } from 'rxjs';
import { filter, take } from 'rxjs/operators';
import { Directionality } from '@angular/cdk/bidi';
import { DialogRef } from '@angular/cdk/dialog';
const tdSideSheetAnimations = {
/** Animation that is applied on the side-sheet container by default. */
sideSheetContainer: trigger('sideSheetContainer', [
state('void, exit', style({ transform: 'translateX(100%)' })),
state('enter', style({ transform: 'translateX(0%)', opacity: 1 })),
transition('* => enter', animate(`${AnimationDurations.ENTERING} ${AnimationCurves.ACCELERATION_CURVE}`, style({ transform: 'translateX(0)', opacity: 1 }))),
transition('* => void, * => exit', animate(`${AnimationDurations.EXITING} ${AnimationCurves.ACCELERATION_CURVE}`, style({ transform: 'translateX(100%)' }))),
]),
};
var SubPageMode;
(function (SubPageMode) {
SubPageMode["pushed"] = "pushed";
SubPageMode["shifted"] = "shifted";
SubPageMode["none"] = "none";
})(SubPageMode || (SubPageMode = {}));
class CovalentSideSheetConfig extends MatDialogConfig {
subPageMode = SubPageMode.pushed;
}
function _getFocusedElementPierceShadowDom() {
let activeElement = typeof document !== 'undefined' && document
? document.activeElement
: null;
while (activeElement && activeElement.shadowRoot) {
const newActiveElement = activeElement.shadowRoot
.activeElement;
if (newActiveElement === activeElement) {
break;
}
else {
activeElement = newActiveElement;
}
}
return activeElement;
}
/**
* Base class for the `CovalentSideSheetContainer`. The base class does not implement
* animations as these are left to implementers of the side-sheet container.
*/
class _CovalentSideSheetContainerBase extends BasePortalOutlet {
_elementRef;
_focusTrapFactory;
_changeDetectorRef;
_config;
_focusMonitor;
_document;
/** The portal outlet inside of this container into which the side-sheet content will be loaded. */
_portalOutlet;
/** The class that traps and manages focus within the side-sheet. */
_focusTrap;
/** Emits when an animation state changes. */
_animationStateChanged = new EventEmitter();
/** Element that was focused before the side-sheet was opened. Save this to restore upon close. */
_elementFocusedBeforeSideSheetWasOpened = null;
/**
* Type of interaction that led to the side-sheet being closed. This is used to determine
* whether the focus style will be applied when returning focus to its original location
* after the side-sheet is closed.
*/
_closeInteractionType = null;
/** ID of the element that should be considered as the side-sheet's label. */
_ariaLabelledBy;
/** ID for the container DOM element. */
_id;
constructor(_elementRef, _focusTrapFactory, _changeDetectorRef, _document,
/** The side-sheet configuration. */
_config, _focusMonitor) {
super();
this._elementRef = _elementRef;
this._focusTrapFactory = _focusTrapFactory;
this._changeDetectorRef = _changeDetectorRef;
this._config = _config;
this._focusMonitor = _focusMonitor;
this._ariaLabelledBy = _config.ariaLabelledBy || null;
this._document = _document;
}
/** Initializes the side-sheet container with the attached content. */
_initializeWithAttachedContent() {
this._setupFocusTrap();
// Save the previously focused element. This element will be re-focused
// when the side-sheet closes.
this._capturePreviouslyFocusedElement();
}
/**
* Attach a ComponentPortal as content to this side-sheet container.
* @param portal Portal to be attached as the side-sheet content.
*/
attachComponentPortal(portal) {
return this._portalOutlet.attachComponentPortal(portal);
}
/**
* Attach a TemplatePortal as content to this side-sheet container.
* @param portal Portal to be attached as the side-sheet content.
*/
attachTemplatePortal(portal) {
return this._portalOutlet.attachTemplatePortal(portal);
}
/**
* Attaches a DOM portal to the side-sheet container.
* @param portal Portal to be attached.
* @deprecated To be turned into a method.
*/
attachDomPortal = (portal) => {
return this._portalOutlet.attachDomPortal(portal);
};
/** Moves focus back into the side-sheet if it was moved out. */
_recaptureFocus() {
if (!this._containsFocus()) {
this._trapFocus();
}
}
/**
* Moves the focus inside the focus trap. When autoFocus is not set to 'side-sheet', if focus
* cannot be moved then focus will go to the side-sheet container.
*/
_trapFocus() {
const element = this._elementRef.nativeElement;
if (!this._config.autoFocus) {
if (!this._containsFocus()) {
element.focus();
}
}
else {
this._focusTrap
.focusInitialElementWhenReady()
.then((focusedSuccessfully) => {
// If we weren't able to find a focusable element in the side-sheet, then focus the side-sheet
// container instead.
if (!focusedSuccessfully) {
this._focusSideSheetContainer();
}
});
}
}
/** Restores focus to the element that was focused before the side-sheet opened. */
_restoreFocus() {
const previousElement = this._elementFocusedBeforeSideSheetWasOpened;
// We need the extra check, because IE can set the `activeElement` to null in some cases.
if (this._config.restoreFocus &&
previousElement &&
typeof previousElement.focus === 'function') {
const activeElement = _getFocusedElementPierceShadowDom();
const element = this._elementRef.nativeElement;
// Make sure that focus is still inside the side-sheet or is on the body (usually because a
// non-focusable element like the backdrop was clicked) before moving it. It's possible that
// the consumer moved it themselves before the animation was done, in which case we shouldn't
// do anything.
if (!activeElement ||
activeElement === this._document.body ||
activeElement === element ||
element.contains(activeElement)) {
if (this._focusMonitor) {
this._focusMonitor.focusVia(previousElement, this._closeInteractionType);
this._closeInteractionType = null;
}
else {
previousElement.focus();
}
}
}
if (this._focusTrap) {
this._focusTrap.destroy();
}
}
/** Sets up the focus trap. */
_setupFocusTrap() {
this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
}
/** Captures the element that was focused before the side-sheet was opened. */
_capturePreviouslyFocusedElement() {
if (this._document) {
this._elementFocusedBeforeSideSheetWasOpened =
_getFocusedElementPierceShadowDom();
}
}
/** Focuses the side-sheet container. */
_focusSideSheetContainer() {
// Note that there is no focus method when rendering on the server.
if (this._elementRef.nativeElement.focus) {
this._elementRef.nativeElement.focus();
}
}
/** Returns whether focus is inside the side-sheet. */
_containsFocus() {
const element = this._elementRef.nativeElement;
const activeElement = _getFocusedElementPierceShadowDom();
return element === activeElement || element.contains(activeElement);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: _CovalentSideSheetContainerBase, deps: [{ token: i0.ElementRef }, { token: i1.ConfigurableFocusTrapFactory }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT, optional: true }, { token: CovalentSideSheetConfig }, { token: i1.FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: _CovalentSideSheetContainerBase, viewQueries: [{ propertyName: "_portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: _CovalentSideSheetContainerBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.ConfigurableFocusTrapFactory }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }, { type: CovalentSideSheetConfig }, { type: i1.FocusMonitor }], propDecorators: { _portalOutlet: [{
type: ViewChild,
args: [CdkPortalOutlet, { static: true }]
}] } });
/**
* Internal component that wraps the generated side-sheet content.
* This animation below is the only reason for duplicating most of the Material dialog code
*/
class CovalentSideSheetContainerComponent extends _CovalentSideSheetContainerBase {
/** State of the side-sheet animation. */
_state = 'enter';
tdSideSheetContainerClass = true;
tabIndex = -1;
arialModal = true;
idAttr = this._id;
roleAttr = this._config.role;
arialLabelByAttr = this._config.ariaLabel
? null
: this._ariaLabelledBy;
arialDescribeByAttr = this._config.ariaDescribedBy || null;
arialLabelAttr = this._config.ariaLabel;
get sideSheetAnimationState() {
return this._state;
}
onAnimateStart($event) {
this._onAnimationStart($event);
}
onAnimateDone($event) {
this._onAnimationDone($event);
}
/** Callback, invoked whenever an animation on the host completes. */
_onAnimationDone({ toState, totalTime }) {
if (toState === 'enter') {
this._trapFocus();
this._animationStateChanged.next({ state: 'opened', totalTime });
}
else if (toState === 'exit') {
this._restoreFocus();
this._animationStateChanged.next({ state: 'closed', totalTime });
}
}
/** Callback, invoked when an animation on the host starts. */
_onAnimationStart({ toState, totalTime }) {
if (toState === 'enter') {
this._animationStateChanged.next({ state: 'opening', totalTime });
}
else if (toState === 'exit' || toState === 'void') {
this._animationStateChanged.next({ state: 'closing', totalTime });
}
}
/** Starts the side-sheet exit animation. */
_startExitAnimation() {
this._state = 'exit';
this._changeDetectorRef.markForCheck();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetContainerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetContainerComponent, selector: "td-side-sheet-container", host: { listeners: { "@sideSheetContainer.start": "onAnimateStart($event)", "@sideSheetContainer.done": "onAnimateDone($event)" }, properties: { "class.td-side-sheet-container": "this.tdSideSheetContainerClass", "tabindex": "this.tabIndex", "aria-modal": "this.arialModal", "id": "this.idAttr", "attr.role": "this.roleAttr", "attr.aria-labelledby": "this.arialLabelByAttr", "attr.aria-describedby": "this.arialDescribeByAttr", "attr.aria-label": "this.arialLabelAttr", "@sideSheetContainer": "this.sideSheetAnimationState" } }, usesInheritance: true, ngImport: i0, template: ` <ng-template cdkPortalOutlet></ng-template> `, isInline: true, styles: [".td-side-sheet-container{box-shadow:0 8px 10px -5px #0003,0 16px 24px 2px #00000024,0 6px 30px 5px #0000001f;display:block;padding:24px;box-sizing:border-box;overflow:auto;outline:0;width:100%;height:100%;min-height:inherit;max-height:inherit}.td-side-sheet-wrapper{display:flex;flex-direction:column;height:100%}.td-side-sheet-content{margin:0 -24px;padding:0 24px;overflow:auto;flex:1;-webkit-overflow-scrolling:touch}.td-side-sheet-title{margin:-16px 0 20px;display:flex;align-items:center}.td-side-sheet-actions{padding:8px 0;margin:0 -16px -24px;display:flex;justify-content:space-between;flex-wrap:wrap;align-items:center;box-sizing:content-box}.td-side-sheet-actions[align=end]{justify-content:flex-end}.td-side-sheet-actions[align=center]{justify-content:center}.td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:8px}[dir=rtl] .td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:0;margin-right:8px}\n"], dependencies: [{ kind: "directive", type: i3.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [tdSideSheetAnimations.sideSheetContainer], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetContainerComponent, decorators: [{
type: Component,
args: [{ selector: 'td-side-sheet-container', template: ` <ng-template cdkPortalOutlet></ng-template> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, animations: [tdSideSheetAnimations.sideSheetContainer], styles: [".td-side-sheet-container{box-shadow:0 8px 10px -5px #0003,0 16px 24px 2px #00000024,0 6px 30px 5px #0000001f;display:block;padding:24px;box-sizing:border-box;overflow:auto;outline:0;width:100%;height:100%;min-height:inherit;max-height:inherit}.td-side-sheet-wrapper{display:flex;flex-direction:column;height:100%}.td-side-sheet-content{margin:0 -24px;padding:0 24px;overflow:auto;flex:1;-webkit-overflow-scrolling:touch}.td-side-sheet-title{margin:-16px 0 20px;display:flex;align-items:center}.td-side-sheet-actions{padding:8px 0;margin:0 -16px -24px;display:flex;justify-content:space-between;flex-wrap:wrap;align-items:center;box-sizing:content-box}.td-side-sheet-actions[align=end]{justify-content:flex-end}.td-side-sheet-actions[align=center]{justify-content:center}.td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:8px}[dir=rtl] .td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:0;margin-right:8px}\n"] }]
}], propDecorators: { tdSideSheetContainerClass: [{
type: HostBinding,
args: ['class.td-side-sheet-container']
}], tabIndex: [{
type: HostBinding,
args: ['tabindex']
}], arialModal: [{
type: HostBinding,
args: ['aria-modal']
}], idAttr: [{
type: HostBinding,
args: ['id']
}], roleAttr: [{
type: HostBinding,
args: ['attr.role']
}], arialLabelByAttr: [{
type: HostBinding,
args: ['attr.aria-labelledby']
}], arialDescribeByAttr: [{
type: HostBinding,
args: ['attr.aria-describedby']
}], arialLabelAttr: [{
type: HostBinding,
args: ['attr.aria-label']
}], sideSheetAnimationState: [{
type: HostBinding,
args: ['@sideSheetContainer']
}], onAnimateStart: [{
type: HostListener,
args: ['@sideSheetContainer.start', ['$event']]
}], onAnimateDone: [{
type: HostListener,
args: ['@sideSheetContainer.done', ['$event']]
}] } });
// Counter for unique dialog ids.
let uniqueId = 0;
// Create a new side sheet ref to change the id of the ref
class CovalentSideSheetRef extends MatDialogRef {
overlayRef;
config;
_containerInstance;
id;
constructor(overlayRef, config, _containerInstance, id = `td-side-sheet-${uniqueId++}`) {
const ref = new DialogRef(overlayRef, config);
super(ref, config, _containerInstance);
this.overlayRef = overlayRef;
this.config = config;
this._containerInstance = _containerInstance;
this.id = id;
ref.containerInstance =
this._containerInstance;
}
}
function _closeSideSheetVia(ref, interactionType, result) {
// Some mock dialog ref instances in tests do not have the `_containerInstance` property.
// For those, we keep the behavior as is and do not deal with the interaction type.
if (ref._containerInstance !== undefined) {
ref._containerInstance._closeInteractionType = interactionType;
}
return ref.close(result);
}
/* tslint:disable */
class _CovalentSideSheetBase {
_overlay;
_injector;
_defaultOptions;
_parentSideSheet;
_sideSheetRefConstructor;
_sideSheetContainerType;
_sideSheetDataToken;
_openSideSheetsAtThisLevel = [];
_afterAllClosedAtThisLevel = new Subject();
_afterOpenedAtThisLevel = new Subject();
_animationStateSubscriptions;
defaultSidebarConfig = {
minWidth: '400px',
maxWidth: '100vw',
};
constructor(_overlay, _injector, _defaultOptions, _parentSideSheet, _sideSheetRefConstructor, _sideSheetContainerType, _sideSheetDataToken) {
this._overlay = _overlay;
this._injector = _injector;
this._defaultOptions = _defaultOptions;
this._parentSideSheet = _parentSideSheet;
this._sideSheetRefConstructor = _sideSheetRefConstructor;
this._sideSheetContainerType = _sideSheetContainerType;
this._sideSheetDataToken = _sideSheetDataToken;
}
/** Keeps track of the currently-open side-sheets. */
get openSideSheets() {
return this._parentSideSheet
? this._parentSideSheet.openSideSheets
: this._openSideSheetsAtThisLevel;
}
open(componentOrTemplateRef, config) {
config = {
...(this._defaultOptions || new CovalentSideSheetConfig()),
...this.defaultSidebarConfig,
...config,
};
const overlayRef = this._createOverlay(config);
const sideSheetContainer = this._attachSideSheetContainer(overlayRef, config);
const sideSheetRef = this._attachSideSheetContent(componentOrTemplateRef, sideSheetContainer, overlayRef, config);
const prevSideSheetRef = this.openSideSheets.slice(-1)[0];
const prevOverlayRef = prevSideSheetRef?.overlayRef;
if (prevOverlayRef?.overlayElement &&
config.subPageMode !== SubPageMode.none) {
prevOverlayRef.overlayElement.style.transition = `${AnimationDurations.COMPLEX} ${AnimationCurves.DECELERATION_CURVE}`;
if (config.subPageMode === SubPageMode.pushed) {
// Animate previous side sheet to full width
prevOverlayRef.overlayElement.style.minWidth = `${window.innerWidth}px`;
}
else if (config.subPageMode === SubPageMode.shifted) {
// Animate previous side sheet to current sidesheet width + 200px
prevOverlayRef.overlayElement.style.minWidth = `${sideSheetRef.overlayRef.overlayElement.offsetWidth + 200}px`;
}
}
// Revert the previous side sheet config & size
sideSheetRef._containerInstance._animationStateChanged
.pipe(filter((event) => event.state === 'closing' && !!(prevSideSheetRef && prevOverlayRef)), take(1))
.subscribe(() => {
prevOverlayRef.overlayElement.style.transition = `${AnimationDurations.EXITING} ${AnimationCurves.DECELERATION_CURVE}`;
prevSideSheetRef.updateSize();
});
// Add new side sheet to open list
this.openSideSheets.push(sideSheetRef);
// Remove side sheet ref after closed
sideSheetRef
.afterClosed()
.pipe(take(1))
.subscribe(() => this._removeOpenSideSheet(sideSheetRef));
// Notify the side-sheet container that the content has been attached.
sideSheetContainer._initializeWithAttachedContent();
return sideSheetRef;
}
ngOnDestroy() {
// Only close the side-sheets at this level on destroy
// since the parent service may still be active.
this._closeSideSheets(this._openSideSheetsAtThisLevel);
this._afterAllClosedAtThisLevel.complete();
this._afterOpenedAtThisLevel.complete();
// Clean up any subscriptions to side-sheet that never finished opening.
if (this._animationStateSubscriptions) {
this._animationStateSubscriptions.unsubscribe();
}
}
/**
* Closes all of the currently-open side-sheets.
*/
closeAll() {
this._closeSideSheets(this.openSideSheets);
}
_createOverlay(config) {
const overlayConfig = new OverlayConfig({
positionStrategy: this._overlay.position().global(),
scrollStrategy: this._overlay.scrollStrategies.block(),
panelClass: config.panelClass,
hasBackdrop: config.hasBackdrop,
direction: config.direction,
minWidth: config.minWidth,
minHeight: config.minHeight,
maxWidth: config.maxWidth,
});
const overlayRef = this._overlay.create(overlayConfig);
const positionStrategy = overlayRef.getConfig()
.positionStrategy;
positionStrategy.right('0px');
return overlayRef;
}
/**
* Attaches a container to a side-sheets's already-created overlay.
* @param overlay Reference to the side-sheet's underlying overlay.
* @param config The side-sheet configuration.
* @returns A promise resolving to a ComponentRef for the attached container.
*/
_attachSideSheetContainer(overlay, config) {
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
const injector = Injector.create({
parent: userInjector || this._injector,
providers: [{ provide: CovalentSideSheetConfig, useValue: config }],
});
const containerPortal = new ComponentPortal(this._sideSheetContainerType, config.viewContainerRef, injector, config.componentFactoryResolver);
const containerRef = overlay.attach(containerPortal);
return containerRef.instance;
}
/**
* Attaches the user-provided component to the already-created side sheet container.
* @param componentOrTemplateRef The type of component being loaded into the side-sheet,
* or a TemplateRef to instantiate as the content.
* @param dialogContainer Reference to the wrapping side-sheet container.
* @param overlayRef Reference to the overlay in which the side-sheet resides.
* @param config The side-sheet configuration.
* @returns A promise resolving to the CovalentSideSheetRef that should be returned to the user.
*/
_attachSideSheetContent(componentOrTemplateRef, sideSheetContainer, overlayRef, config) {
// Create a reference to the side-sheet we're creating in order to give the user a handle
// to modify and close it.
const sideSheetRef = new this._sideSheetRefConstructor(overlayRef, config, sideSheetContainer, config.id);
if (componentOrTemplateRef instanceof TemplateRef) {
sideSheetContainer.attachTemplatePortal(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
new TemplatePortal(componentOrTemplateRef, null, {
$implicit: config.data,
sideSheetRef,
}));
}
else {
const injector = this._createInjector(config, sideSheetRef, sideSheetContainer);
const contentRef = sideSheetContainer.attach(new ComponentPortal(componentOrTemplateRef, config.viewContainerRef, injector));
sideSheetRef.componentInstance = contentRef.instance;
}
sideSheetRef.updateSize(config.width, config.height);
return sideSheetRef;
}
_createInjector(config, sideSheetRef, sideSheetContainer) {
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
// The side-sheet container should be provided as the side-sheet container and the side-sheet's
// content are created out of the same `ViewContainerRef` and as such, are siblings
// for injector purposes. To allow the hierarchy that is expected, the side-sheet
// container is explicitly provided in the injector.
const providers = [
{ provide: this._sideSheetContainerType, useValue: sideSheetContainer },
{ provide: this._sideSheetDataToken, useValue: config.data },
{ provide: this._sideSheetRefConstructor, useValue: sideSheetRef },
];
if (config.direction &&
(!userInjector ||
!userInjector.get(Directionality, null, InjectFlags.Optional))) {
providers.push({
provide: Directionality,
useValue: { value: config.direction, change: of() },
});
}
return Injector.create({
parent: userInjector || this._injector,
providers,
});
}
/**
* Removes a side sheet from the array of open side sheets.
* @param sideSheetRef Side Sheet to be removed.
*/
_removeOpenSideSheet(sideSheetRef) {
const index = this.openSideSheets.indexOf(sideSheetRef);
if (index > -1) {
this.openSideSheets.splice(index, 1);
}
}
/** Closes all of the side-sheet in an array. */
_closeSideSheets(sideSheets) {
let i = sideSheets.length;
while (i--) {
sideSheets[i].close();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: _CovalentSideSheetBase, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: _CovalentSideSheetBase, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: _CovalentSideSheetBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i1$1.Overlay }, { type: i0.Injector }, { type: undefined }, { type: undefined }, { type: i0.Type }, { type: i0.Type }, { type: i0.InjectionToken }] });
/**
* Service to open Covalent Design side-sheet.
*/
class CovalentSideSheet extends _CovalentSideSheetBase {
constructor(overlay, injector, defaultOptions, parentSideSheet) {
super(overlay, injector, defaultOptions, parentSideSheet, CovalentSideSheetRef, CovalentSideSheetContainerComponent, MAT_DIALOG_DATA);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheet, deps: [{ token: i1$1.Overlay }, { token: i0.Injector }, { token: MAT_DIALOG_DEFAULT_OPTIONS, optional: true }, { token: CovalentSideSheet, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheet });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheet, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i1$1.Overlay }, { type: i0.Injector }, { type: CovalentSideSheetConfig, decorators: [{
type: Optional
}, {
type: Inject,
args: [MAT_DIALOG_DEFAULT_OPTIONS]
}] }, { type: CovalentSideSheet, decorators: [{
type: Optional
}, {
type: SkipSelf
}] }] });
/* tslint:disable */
/** Counter used to generate unique IDs for dialog elements. */
let dialogElementUid = 0;
/**
* Button that will close the current dialog.
*/
class CovalentSideSheetCloseDirective {
dialogRef;
_elementRef;
_dialog;
/** Screenreader label for the button. */
ariaLabel;
/** Default to "button" to prevents accidental form submits. */
type = 'button';
/** Dialog close input. */
dialogResult;
_CovalentSideSheetClose;
onClick($event) {
this._onButtonClick($event);
}
constructor(dialogRef, _elementRef, _dialog) {
this.dialogRef = dialogRef;
this._elementRef = _elementRef;
this._dialog = _dialog;
}
ngOnInit() {
if (!this.dialogRef) {
// When this directive is included in a dialog via TemplateRef (rather than being
// in a Component), the DialogRef isn't available via injection because embedded
// views cannot be given a custom injector. Instead, we look up the DialogRef by
// ID. This must occur in `onInit`, as the ID binding for the dialog container won't
// be resolved at constructor time.
this.dialogRef = getClosestDialog(this._elementRef, this._dialog.openSideSheets);
}
}
ngOnChanges(changes) {
const proxiedChange = changes['_CovalentSideSheetClose'] ||
changes['_CovalentSideSheetCloseResult'];
if (proxiedChange) {
this.dialogResult = proxiedChange.currentValue;
}
}
_onButtonClick(event) {
// Determinate the focus origin using the click event, because using the FocusMonitor will
// result in incorrect origins. Most of the time, close buttons will be auto focused in the
// dialog, and therefore clicking the button won't result in a focus change. This means that
// the FocusMonitor won't detect any origin change, and will always output `program`.
_closeSideSheetVia(this.dialogRef, event.screenX === 0 && event.screenY === 0 ? 'keyboard' : 'mouse', this.dialogResult);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetCloseDirective, deps: [{ token: CovalentSideSheetRef, optional: true }, { token: i0.ElementRef }, { token: CovalentSideSheet }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetCloseDirective, selector: "[td-side-sheet-close], [CovalentSideSheetClose]", inputs: { ariaLabel: ["aria-label", "ariaLabel"], type: "type", dialogResult: ["td-side-sheet-close", "dialogResult"], _CovalentSideSheetClose: ["CovalentSideSheetClose", "_CovalentSideSheetClose"] }, host: { listeners: { "click": "onClick($event)" }, properties: { "attr.arial-label": "this.ariaLabel", "attr.type": "this.type" } }, exportAs: ["CovalentSideSheetClose"], usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetCloseDirective, decorators: [{
type: Directive,
args: [{
selector: '[td-side-sheet-close], [CovalentSideSheetClose]',
exportAs: 'CovalentSideSheetClose',
}]
}], ctorParameters: () => [{ type: CovalentSideSheetRef, decorators: [{
type: Optional
}] }, { type: i0.ElementRef }, { type: CovalentSideSheet }], propDecorators: { ariaLabel: [{
type: HostBinding,
args: ['attr.arial-label']
}, {
type: Input,
args: ['aria-label']
}], type: [{
type: HostBinding,
args: ['attr.type']
}, {
type: Input
}], dialogResult: [{
type: Input,
args: ['td-side-sheet-close']
}], _CovalentSideSheetClose: [{
type: Input,
args: ['CovalentSideSheetClose']
}], onClick: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
/**
* Title of a side sheet element. Stays fixed to the top of the side sheet when scrolling.
*/
class CovalentSideSheetTitleDirective {
_dialogRef;
_elementRef;
_dialog;
/** Unique id for the dialog title. If none is supplied, it will be auto-generated. */
id = `td-side-sheet-title-${dialogElementUid++}`;
tdSideSheetTitle = true;
idAttr = this.id;
constructor(
// The dialog title directive is always used in combination with a `CovalentSideSheetRef`.
// tslint:disable-next-line: lightweight-tokens
_dialogRef, _elementRef, _dialog) {
this._dialogRef = _dialogRef;
this._elementRef = _elementRef;
this._dialog = _dialog;
}
ngOnInit() {
if (this._dialogRef) {
Promise.resolve().then(() => {
const container = this._dialogRef._containerInstance;
if (container && !container._ariaLabelledByQueue.includes(this.id)) {
container._ariaLabelledByQueue.push(this.id);
}
});
}
else {
this._dialogRef = getClosestDialog(this._elementRef, this._dialog.openSideSheets);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetTitleDirective, deps: [{ token: CovalentSideSheetRef, optional: true }, { token: i0.ElementRef }, { token: CovalentSideSheet }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetTitleDirective, selector: "[td-side-sheet-title], [CovalentSideSheetTitle]", inputs: { id: "id" }, host: { properties: { "class.td-side-sheet-title": "this.tdSideSheetTitle", "attr.id": "this.idAttr" } }, exportAs: ["CovalentSideSheetTitle"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetTitleDirective, decorators: [{
type: Directive,
args: [{
selector: '[td-side-sheet-title], [CovalentSideSheetTitle]',
exportAs: 'CovalentSideSheetTitle',
}]
}], ctorParameters: () => [{ type: CovalentSideSheetRef, decorators: [{
type: Optional
}] }, { type: i0.ElementRef }, { type: CovalentSideSheet }], propDecorators: { id: [{
type: Input
}], tdSideSheetTitle: [{
type: HostBinding,
args: ['class.td-side-sheet-title']
}], idAttr: [{
type: HostBinding,
args: ['attr.id']
}] } });
/**
* Scrollable content container of a dialog.
*/
class CovalentSideSheetContentDirective {
tdSideSheetContent = true;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetContentDirective, selector: "[td-side-sheet-content], td-side-sheet-content, [CovalentSideSheetContent]", host: { properties: { "class.td-side-sheet-content": "this.tdSideSheetContent" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetContentDirective, decorators: [{
type: Directive,
args: [{
selector: `[td-side-sheet-content], td-side-sheet-content, [CovalentSideSheetContent]`,
}]
}], propDecorators: { tdSideSheetContent: [{
type: HostBinding,
args: ['class.td-side-sheet-content']
}] } });
/**
* Container for the bottom action buttons in a dialog.
* Stays fixed to the bottom when scrolling.
*/
class CovalentSideSheetActionsDirective {
tdSideSheetActions = true;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetActionsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetActionsDirective, selector: "[td-side-sheet-actions], td-side-sheet-actions, [CovalentSideSheetActions]", host: { properties: { "class.td-side-sheet-actions": "this.tdSideSheetActions" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetActionsDirective, decorators: [{
type: Directive,
args: [{
selector: `[td-side-sheet-actions], td-side-sheet-actions, [CovalentSideSheetActions]`,
}]
}], propDecorators: { tdSideSheetActions: [{
type: HostBinding,
args: ['class.td-side-sheet-actions']
}] } });
/**
* Container for the wrapper part of the dialog
*/
class CovalentSideSheetWrapperDirective {
tdSideSheetWrapper = true;
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetWrapperDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetWrapperDirective, selector: "[td-side-sheet-wrapper], td-side-sheet-wrapper, [CovalentSideSheetWrapper]", host: { properties: { "class.td-side-sheet-wrapper": "this.tdSideSheetWrapper" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetWrapperDirective, decorators: [{
type: Directive,
args: [{
selector: `[td-side-sheet-wrapper], td-side-sheet-wrapper, [CovalentSideSheetWrapper]`,
}]
}], propDecorators: { tdSideSheetWrapper: [{
type: HostBinding,
args: ['class.td-side-sheet-wrapper']
}] } });
/**
* Finds the closest CovalentSideSheetRef to an element by looking at the DOM.
* @param element Element relative to which to look for a dialog.
* @param openDialogs References to the currently-open dialogs.
*/
function getClosestDialog(element, openDialogs) {
let parent = element.nativeElement.parentElement;
while (parent && !parent.classList.contains('td-side-sheet-container')) {
parent = parent.parentElement;
}
return parent
? openDialogs.find((dialog) => dialog.id === parent?.id) ?? openDialogs[0]
: openDialogs[0];
}
class CovalentSideSheetModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetModule, declarations: [CovalentSideSheetContainerComponent,
CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective], imports: [PortalModule, MatDialogModule, MatCommonModule], exports: [CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetModule, providers: [CovalentSideSheet], imports: [PortalModule, MatDialogModule, MatCommonModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetModule, decorators: [{
type: NgModule,
args: [{
declarations: [
CovalentSideSheetContainerComponent,
CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective,
],
exports: [
CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective,
],
imports: [PortalModule, MatDialogModule, MatCommonModule],
providers: [CovalentSideSheet],
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { CovalentSideSheet, CovalentSideSheetActionsDirective, CovalentSideSheetCloseDirective, CovalentSideSheetConfig, CovalentSideSheetContentDirective, CovalentSideSheetModule, CovalentSideSheetRef, CovalentSideSheetTitleDirective, CovalentSideSheetWrapperDirective, SubPageMode, _CovalentSideSheetBase, _closeSideSheetVia };
//# sourceMappingURL=covalent-core-side-sheet.mjs.map