UNPKG

@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
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