@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.
820 lines (810 loc) • 42.2 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, ElementRef, ChangeDetectorRef, EventEmitter, Directive, ViewChild, ChangeDetectionStrategy, ViewEncapsulation, Component, HostListener, HostBinding, Injector, TemplateRef, Injectable, Optional, Inject, SkipSelf, Input, NgModule } from '@angular/core';
import * as i1 from '@angular/cdk/overlay';
import { OverlayConfig } from '@angular/cdk/overlay';
import { BasePortalOutlet, CdkPortalOutlet, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
import { MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA, MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
import { AnimationDurations, AnimationCurves } from '@angular/material/core';
import { ConfigurableFocusTrapFactory, FocusMonitor } from '@angular/cdk/a11y';
import { DOCUMENT } from '@angular/common';
import { trigger, state, transition, style, 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 CovalentSideSheetContainerComponent_ng_template_0_Template(rf, ctx) { }
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 = inject(ElementRef);
_focusTrapFactory = inject(ConfigurableFocusTrapFactory);
_changeDetectorRef = inject(ChangeDetectorRef);
_config = inject(CovalentSideSheetConfig);
_focusMonitor = inject(FocusMonitor);
_document = null;
/** 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() {
const _document = inject(DOCUMENT, { optional: true });
super();
const _config = this._config;
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 = function _CovalentSideSheetContainerBase_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || _CovalentSideSheetContainerBase)(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: _CovalentSideSheetContainerBase, viewQuery: function _CovalentSideSheetContainerBase_Query(rf, ctx) { if (rf & 1) {
i0.ɵɵviewQuery(CdkPortalOutlet, 7);
} if (rf & 2) {
let _t;
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx._portalOutlet = _t.first);
} }, features: [i0.ɵɵInheritDefinitionFeature] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(_CovalentSideSheetContainerBase, [{
type: Directive
}], () => [], { _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 = /*@__PURE__*/ (() => { let ɵCovalentSideSheetContainerComponent_BaseFactory; return function CovalentSideSheetContainerComponent_Factory(__ngFactoryType__) { return (ɵCovalentSideSheetContainerComponent_BaseFactory || (ɵCovalentSideSheetContainerComponent_BaseFactory = i0.ɵɵgetInheritedFactory(CovalentSideSheetContainerComponent)))(__ngFactoryType__ || CovalentSideSheetContainerComponent); }; })();
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CovalentSideSheetContainerComponent, selectors: [["td-side-sheet-container"]], hostVars: 10, hostBindings: function CovalentSideSheetContainerComponent_HostBindings(rf, ctx) { if (rf & 1) {
i0.ɵɵsyntheticHostListener("@sideSheetContainer.start", function CovalentSideSheetContainerComponent_animation_sideSheetContainer_start_HostBindingHandler($event) { return ctx.onAnimateStart($event); })("@sideSheetContainer.done", function CovalentSideSheetContainerComponent_animation_sideSheetContainer_done_HostBindingHandler($event) { return ctx.onAnimateDone($event); });
} if (rf & 2) {
i0.ɵɵdomProperty("tabindex", ctx.tabIndex)("aria-modal", ctx.arialModal)("id", ctx.idAttr);
i0.ɵɵsyntheticHostProperty("@sideSheetContainer", ctx.sideSheetAnimationState);
i0.ɵɵattribute("role", ctx.roleAttr)("aria-labelledby", ctx.arialLabelByAttr)("aria-describedby", ctx.arialDescribeByAttr)("aria-label", ctx.arialLabelAttr);
i0.ɵɵclassProp("td-side-sheet-container", ctx.tdSideSheetContainerClass);
} }, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 0, consts: [["cdkPortalOutlet", ""]], template: function CovalentSideSheetContainerComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵtemplate(0, CovalentSideSheetContainerComponent_ng_template_0_Template, 0, 0, "ng-template", 0);
} }, dependencies: [CdkPortalOutlet], 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"], encapsulation: 2, data: { animation: [tdSideSheetAnimations.sideSheetContainer] } });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetContainerComponent, [{
type: Component,
args: [{ selector: 'td-side-sheet-container', template: ` <ng-template cdkPortalOutlet></ng-template> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, animations: [tdSideSheetAnimations.sideSheetContainer], imports: [CdkPortalOutlet], 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"] }]
}], null, { 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']]
}] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CovalentSideSheetContainerComponent, { className: "CovalentSideSheetContainerComponent", filePath: "side-sheet-container.ts", lineNumber: 256 }); })();
// 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);
}
/* eslint-disable @angular-eslint/prefer-inject */
/* 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);
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, {
optional: true,
}))) {
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 = function _CovalentSideSheetBase_Factory(__ngFactoryType__) { i0.ɵɵinvalidFactory(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: _CovalentSideSheetBase });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(_CovalentSideSheetBase, [{
type: Directive
}], () => [{ type: i1.Overlay }, { type: i0.Injector }, { type: undefined }, { type: undefined }, { type: i0.Type }, { type: i0.Type }, { type: i0.InjectionToken }], null); })();
/**
* 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 = function CovalentSideSheet_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheet)(i0.ɵɵinject(i1.Overlay), i0.ɵɵinject(i0.Injector), i0.ɵɵinject(MAT_DIALOG_DEFAULT_OPTIONS, 8), i0.ɵɵinject(CovalentSideSheet, 12)); };
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: CovalentSideSheet, factory: CovalentSideSheet.ɵfac });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheet, [{
type: Injectable
}], () => [{ type: i1.Overlay }, { type: i0.Injector }, { type: CovalentSideSheetConfig, decorators: [{
type: Optional
}, {
type: Inject,
args: [MAT_DIALOG_DEFAULT_OPTIONS]
}] }, { type: CovalentSideSheet, decorators: [{
type: Optional
}, {
type: SkipSelf
}] }], null); })();
/* tslint:disable */
/** Counter used to generate unique IDs for dialog elements. */
let dialogElementUid = 0;
/**
* Button that will close the current dialog.
*/
class CovalentSideSheetCloseDirective {
dialogRef = inject(CovalentSideSheetRef, {
optional: true,
});
_elementRef = inject(ElementRef);
_dialog = inject(CovalentSideSheet);
/** 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);
}
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`.
if (!this.dialogRef) {
return;
}
_closeSideSheetVia(this.dialogRef, event.screenX === 0 && event.screenY === 0 ? 'keyboard' : 'mouse', this.dialogResult);
}
static ɵfac = function CovalentSideSheetCloseDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheetCloseDirective)(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CovalentSideSheetCloseDirective, selectors: [["", "td-side-sheet-close", ""], ["", "CovalentSideSheetClose", ""]], hostVars: 2, hostBindings: function CovalentSideSheetCloseDirective_HostBindings(rf, ctx) { if (rf & 1) {
i0.ɵɵlistener("click", function CovalentSideSheetCloseDirective_click_HostBindingHandler($event) { return ctx.onClick($event); });
} if (rf & 2) {
i0.ɵɵattribute("arial-label", ctx.ariaLabel)("type", ctx.type);
} }, inputs: { ariaLabel: [0, "aria-label", "ariaLabel"], type: "type", dialogResult: [0, "td-side-sheet-close", "dialogResult"], _CovalentSideSheetClose: [0, "CovalentSideSheetClose", "_CovalentSideSheetClose"] }, exportAs: ["CovalentSideSheetClose"], features: [i0.ɵɵNgOnChangesFeature] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetCloseDirective, [{
type: Directive,
args: [{
selector: '[td-side-sheet-close], [CovalentSideSheetClose]',
exportAs: 'CovalentSideSheetClose',
}]
}], null, { 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 = inject(CovalentSideSheetRef, {
optional: true,
});
_elementRef = inject(ElementRef);
_dialog = inject(CovalentSideSheet);
/** 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;
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 = function CovalentSideSheetTitleDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheetTitleDirective)(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CovalentSideSheetTitleDirective, selectors: [["", "td-side-sheet-title", ""], ["", "CovalentSideSheetTitle", ""]], hostVars: 3, hostBindings: function CovalentSideSheetTitleDirective_HostBindings(rf, ctx) { if (rf & 2) {
i0.ɵɵattribute("id", ctx.idAttr);
i0.ɵɵclassProp("td-side-sheet-title", ctx.tdSideSheetTitle);
} }, inputs: { id: "id" }, exportAs: ["CovalentSideSheetTitle"] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetTitleDirective, [{
type: Directive,
args: [{
selector: '[td-side-sheet-title], [CovalentSideSheetTitle]',
exportAs: 'CovalentSideSheetTitle',
}]
}], null, { 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 = function CovalentSideSheetContentDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheetContentDirective)(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CovalentSideSheetContentDirective, selectors: [["", "td-side-sheet-content", ""], ["td-side-sheet-content"], ["", "CovalentSideSheetContent", ""]], hostVars: 2, hostBindings: function CovalentSideSheetContentDirective_HostBindings(rf, ctx) { if (rf & 2) {
i0.ɵɵclassProp("td-side-sheet-content", ctx.tdSideSheetContent);
} } });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetContentDirective, [{
type: Directive,
args: [{
selector: `[td-side-sheet-content], td-side-sheet-content, [CovalentSideSheetContent]`,
}]
}], null, { 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 = function CovalentSideSheetActionsDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheetActionsDirective)(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CovalentSideSheetActionsDirective, selectors: [["", "td-side-sheet-actions", ""], ["td-side-sheet-actions"], ["", "CovalentSideSheetActions", ""]], hostVars: 2, hostBindings: function CovalentSideSheetActionsDirective_HostBindings(rf, ctx) { if (rf & 2) {
i0.ɵɵclassProp("td-side-sheet-actions", ctx.tdSideSheetActions);
} } });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetActionsDirective, [{
type: Directive,
args: [{
selector: `[td-side-sheet-actions], td-side-sheet-actions, [CovalentSideSheetActions]`,
}]
}], null, { tdSideSheetActions: [{
type: HostBinding,
args: ['class.td-side-sheet-actions']
}] }); })();
/**
* Container for the wrapper part of the dialog
*/
class CovalentSideSheetWrapperDirective {
tdSideSheetWrapper = true;
static ɵfac = function CovalentSideSheetWrapperDirective_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheetWrapperDirective)(); };
static ɵdir = /*@__PURE__*/ i0.ɵɵdefineDirective({ type: CovalentSideSheetWrapperDirective, selectors: [["", "td-side-sheet-wrapper", ""], ["td-side-sheet-wrapper"], ["", "CovalentSideSheetWrapper", ""]], hostVars: 2, hostBindings: function CovalentSideSheetWrapperDirective_HostBindings(rf, ctx) { if (rf & 2) {
i0.ɵɵclassProp("td-side-sheet-wrapper", ctx.tdSideSheetWrapper);
} } });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetWrapperDirective, [{
type: Directive,
args: [{
selector: `[td-side-sheet-wrapper], td-side-sheet-wrapper, [CovalentSideSheetWrapper]`,
}]
}], null, { 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];
}
/**
* @deprecated This module is deprecated and will be removed in future versions.
* Please migrate to using standalone components as soon as possible.
*/
class CovalentSideSheetModule {
static ɵfac = function CovalentSideSheetModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CovalentSideSheetModule)(); };
static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: CovalentSideSheetModule });
static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ providers: [CovalentSideSheet] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CovalentSideSheetModule, [{
type: NgModule,
args: [{
imports: [
CovalentSideSheetContainerComponent,
CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective,
],
exports: [
CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective,
],
providers: [CovalentSideSheet],
}]
}], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(CovalentSideSheetModule, { imports: [CovalentSideSheetContainerComponent,
CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective], exports: [CovalentSideSheetActionsDirective,
CovalentSideSheetCloseDirective,
CovalentSideSheetContentDirective,
CovalentSideSheetTitleDirective,
CovalentSideSheetWrapperDirective] }); })();
/**
* 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