You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
800 lines
37 KiB
800 lines
37 KiB
import * as i1 from '@angular/cdk/overlay';
|
|
import { OverlayModule, OverlayConfig, Overlay } from '@angular/cdk/overlay';
|
|
import { BasePortalOutlet, CdkPortalOutlet, PortalModule, ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
|
|
import { CommonModule } from '@angular/common';
|
|
import * as i0 from '@angular/core';
|
|
import { InjectionToken, Component, ViewEncapsulation, ChangeDetectionStrategy, Inject, NgZone, ElementRef, ChangeDetectorRef, ViewChild, NgModule, Injector, TemplateRef, Injectable, Optional, SkipSelf } from '@angular/core';
|
|
import { MatCommonModule } from '@angular/material/core';
|
|
import { MatButtonModule } from '@angular/material/button';
|
|
import { Subject } from 'rxjs';
|
|
import { Platform } from '@angular/cdk/platform';
|
|
import { take, takeUntil } from 'rxjs/operators';
|
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
import * as i2 from '@angular/cdk/a11y';
|
|
import { LiveAnnouncer } from '@angular/cdk/a11y';
|
|
import * as i3 from '@angular/cdk/layout';
|
|
import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/** Injection token that can be used to access the data that was passed in to a snack bar. */
|
|
import * as ɵngcc0 from '@angular/core';
|
|
import * as ɵngcc1 from '@angular/common';
|
|
import * as ɵngcc2 from '@angular/material/button';
|
|
import * as ɵngcc3 from '@angular/cdk/platform';
|
|
import * as ɵngcc4 from '@angular/cdk/portal';
|
|
import * as ɵngcc5 from '@angular/cdk/overlay';
|
|
import * as ɵngcc6 from '@angular/cdk/a11y';
|
|
import * as ɵngcc7 from '@angular/cdk/layout';
|
|
|
|
function SimpleSnackBar_div_2_Template(rf, ctx) { if (rf & 1) {
|
|
const _r2 = ɵngcc0.ɵɵgetCurrentView();
|
|
ɵngcc0.ɵɵelementStart(0, "div", 1);
|
|
ɵngcc0.ɵɵelementStart(1, "button", 2);
|
|
ɵngcc0.ɵɵlistener("click", function SimpleSnackBar_div_2_Template_button_click_1_listener() { ɵngcc0.ɵɵrestoreView(_r2); const ctx_r1 = ɵngcc0.ɵɵnextContext(); return ctx_r1.action(); });
|
|
ɵngcc0.ɵɵtext(2);
|
|
ɵngcc0.ɵɵelementEnd();
|
|
ɵngcc0.ɵɵelementEnd();
|
|
} if (rf & 2) {
|
|
const ctx_r0 = ɵngcc0.ɵɵnextContext();
|
|
ɵngcc0.ɵɵadvance(2);
|
|
ɵngcc0.ɵɵtextInterpolate(ctx_r0.data.action);
|
|
} }
|
|
function MatSnackBarContainer_ng_template_1_Template(rf, ctx) { }
|
|
const MAT_SNACK_BAR_DATA = new InjectionToken('MatSnackBarData');
|
|
/**
|
|
* Configuration used when opening a snack-bar.
|
|
*/
|
|
class MatSnackBarConfig {
|
|
constructor() {
|
|
/** The politeness level for the MatAriaLiveAnnouncer announcement. */
|
|
this.politeness = 'assertive';
|
|
/**
|
|
* Message to be announced by the LiveAnnouncer. When opening a snackbar without a custom
|
|
* component or template, the announcement message will default to the specified message.
|
|
*/
|
|
this.announcementMessage = '';
|
|
/** The length of time in milliseconds to wait before automatically dismissing the snack bar. */
|
|
this.duration = 0;
|
|
/** Data being injected into the child component. */
|
|
this.data = null;
|
|
/** The horizontal position to place the snack bar. */
|
|
this.horizontalPosition = 'center';
|
|
/** The vertical position to place the snack bar. */
|
|
this.verticalPosition = 'bottom';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/** Maximum amount of milliseconds that can be passed into setTimeout. */
|
|
const MAX_TIMEOUT = Math.pow(2, 31) - 1;
|
|
/**
|
|
* Reference to a snack bar dispatched from the snack bar service.
|
|
*/
|
|
class MatSnackBarRef {
|
|
constructor(containerInstance, _overlayRef) {
|
|
this._overlayRef = _overlayRef;
|
|
/** Subject for notifying the user that the snack bar has been dismissed. */
|
|
this._afterDismissed = new Subject();
|
|
/** Subject for notifying the user that the snack bar has opened and appeared. */
|
|
this._afterOpened = new Subject();
|
|
/** Subject for notifying the user that the snack bar action was called. */
|
|
this._onAction = new Subject();
|
|
/** Whether the snack bar was dismissed using the action button. */
|
|
this._dismissedByAction = false;
|
|
this.containerInstance = containerInstance;
|
|
// Dismiss snackbar on action.
|
|
this.onAction().subscribe(() => this.dismiss());
|
|
containerInstance._onExit.subscribe(() => this._finishDismiss());
|
|
}
|
|
/** Dismisses the snack bar. */
|
|
dismiss() {
|
|
if (!this._afterDismissed.closed) {
|
|
this.containerInstance.exit();
|
|
}
|
|
clearTimeout(this._durationTimeoutId);
|
|
}
|
|
/** Marks the snackbar action clicked. */
|
|
dismissWithAction() {
|
|
if (!this._onAction.closed) {
|
|
this._dismissedByAction = true;
|
|
this._onAction.next();
|
|
this._onAction.complete();
|
|
}
|
|
clearTimeout(this._durationTimeoutId);
|
|
}
|
|
/**
|
|
* Marks the snackbar action clicked.
|
|
* @deprecated Use `dismissWithAction` instead.
|
|
* @breaking-change 8.0.0
|
|
*/
|
|
closeWithAction() {
|
|
this.dismissWithAction();
|
|
}
|
|
/** Dismisses the snack bar after some duration */
|
|
_dismissAfter(duration) {
|
|
// Note that we need to cap the duration to the maximum value for setTimeout, because
|
|
// it'll revert to 1 if somebody passes in something greater (e.g. `Infinity`). See #17234.
|
|
this._durationTimeoutId = setTimeout(() => this.dismiss(), Math.min(duration, MAX_TIMEOUT));
|
|
}
|
|
/** Marks the snackbar as opened */
|
|
_open() {
|
|
if (!this._afterOpened.closed) {
|
|
this._afterOpened.next();
|
|
this._afterOpened.complete();
|
|
}
|
|
}
|
|
/** Cleans up the DOM after closing. */
|
|
_finishDismiss() {
|
|
this._overlayRef.dispose();
|
|
if (!this._onAction.closed) {
|
|
this._onAction.complete();
|
|
}
|
|
this._afterDismissed.next({ dismissedByAction: this._dismissedByAction });
|
|
this._afterDismissed.complete();
|
|
this._dismissedByAction = false;
|
|
}
|
|
/** Gets an observable that is notified when the snack bar is finished closing. */
|
|
afterDismissed() {
|
|
return this._afterDismissed;
|
|
}
|
|
/** Gets an observable that is notified when the snack bar has opened and appeared. */
|
|
afterOpened() {
|
|
return this.containerInstance._onEnter;
|
|
}
|
|
/** Gets an observable that is notified when the snack bar action is called. */
|
|
onAction() {
|
|
return this._onAction;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/**
|
|
* A component used to open as the default snack bar, matching material spec.
|
|
* This should only be used internally by the snack bar service.
|
|
*/
|
|
class SimpleSnackBar {
|
|
constructor(snackBarRef, data) {
|
|
this.snackBarRef = snackBarRef;
|
|
this.data = data;
|
|
}
|
|
/** Performs the action on the snack bar. */
|
|
action() {
|
|
this.snackBarRef.dismissWithAction();
|
|
}
|
|
/** If the action button should be shown. */
|
|
get hasAction() {
|
|
return !!this.data.action;
|
|
}
|
|
}
|
|
SimpleSnackBar.ɵfac = function SimpleSnackBar_Factory(t) { return new (t || SimpleSnackBar)(ɵngcc0.ɵɵdirectiveInject(MatSnackBarRef), ɵngcc0.ɵɵdirectiveInject(MAT_SNACK_BAR_DATA)); };
|
|
SimpleSnackBar.ɵcmp = /*@__PURE__*/ ɵngcc0.ɵɵdefineComponent({ type: SimpleSnackBar, selectors: [["simple-snack-bar"]], hostAttrs: [1, "mat-simple-snackbar"], decls: 3, vars: 2, consts: [["class", "mat-simple-snackbar-action", 4, "ngIf"], [1, "mat-simple-snackbar-action"], ["mat-button", "", 3, "click"]], template: function SimpleSnackBar_Template(rf, ctx) { if (rf & 1) {
|
|
ɵngcc0.ɵɵelementStart(0, "span");
|
|
ɵngcc0.ɵɵtext(1);
|
|
ɵngcc0.ɵɵelementEnd();
|
|
ɵngcc0.ɵɵtemplate(2, SimpleSnackBar_div_2_Template, 3, 1, "div", 0);
|
|
} if (rf & 2) {
|
|
ɵngcc0.ɵɵadvance(1);
|
|
ɵngcc0.ɵɵtextInterpolate(ctx.data.message);
|
|
ɵngcc0.ɵɵadvance(1);
|
|
ɵngcc0.ɵɵproperty("ngIf", ctx.hasAction);
|
|
} }, directives: [ɵngcc1.NgIf, ɵngcc2.MatButton], styles: [".mat-simple-snackbar{display:flex;justify-content:space-between;align-items:center;line-height:20px;opacity:1}.mat-simple-snackbar-action{flex-shrink:0;margin:-8px -8px -8px 8px}.mat-simple-snackbar-action button{max-height:36px;min-width:0}[dir=rtl] .mat-simple-snackbar-action{margin-left:-8px;margin-right:8px}\n"], encapsulation: 2, changeDetection: 0 });
|
|
SimpleSnackBar.ctorParameters = () => [
|
|
{ type: MatSnackBarRef },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [MAT_SNACK_BAR_DATA,] }] }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(SimpleSnackBar, [{
|
|
type: Component,
|
|
args: [{
|
|
selector: 'simple-snack-bar',
|
|
template: "<span>{{data.message}}</span>\n<div class=\"mat-simple-snackbar-action\" *ngIf=\"hasAction\">\n <button mat-button (click)=\"action()\">{{data.action}}</button>\n</div>\n",
|
|
encapsulation: ViewEncapsulation.None,
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
host: {
|
|
'class': 'mat-simple-snackbar'
|
|
},
|
|
styles: [".mat-simple-snackbar{display:flex;justify-content:space-between;align-items:center;line-height:20px;opacity:1}.mat-simple-snackbar-action{flex-shrink:0;margin:-8px -8px -8px 8px}.mat-simple-snackbar-action button{max-height:36px;min-width:0}[dir=rtl] .mat-simple-snackbar-action{margin-left:-8px;margin-right:8px}\n"]
|
|
}]
|
|
}], function () { return [{ type: MatSnackBarRef }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [MAT_SNACK_BAR_DATA]
|
|
}] }]; }, null); })();
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/**
|
|
* Animations used by the Material snack bar.
|
|
* @docs-private
|
|
*/
|
|
const matSnackBarAnimations = {
|
|
/** Animation that shows and hides a snack bar. */
|
|
snackBarState: trigger('state', [
|
|
state('void, hidden', style({
|
|
transform: 'scale(0.8)',
|
|
opacity: 0,
|
|
})),
|
|
state('visible', style({
|
|
transform: 'scale(1)',
|
|
opacity: 1,
|
|
})),
|
|
transition('* => visible', animate('150ms cubic-bezier(0, 0, 0.2, 1)')),
|
|
transition('* => void, * => hidden', animate('75ms cubic-bezier(0.4, 0.0, 1, 1)', style({
|
|
opacity: 0
|
|
}))),
|
|
])
|
|
};
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/**
|
|
* Internal component that wraps user-provided snack bar content.
|
|
* @docs-private
|
|
*/
|
|
class MatSnackBarContainer extends BasePortalOutlet {
|
|
constructor(_ngZone, _elementRef, _changeDetectorRef, _platform,
|
|
/** The snack bar configuration. */
|
|
snackBarConfig) {
|
|
super();
|
|
this._ngZone = _ngZone;
|
|
this._elementRef = _elementRef;
|
|
this._changeDetectorRef = _changeDetectorRef;
|
|
this._platform = _platform;
|
|
this.snackBarConfig = snackBarConfig;
|
|
/** The number of milliseconds to wait before announcing the snack bar's content. */
|
|
this._announceDelay = 150;
|
|
/** Whether the component has been destroyed. */
|
|
this._destroyed = false;
|
|
/** Subject for notifying that the snack bar has announced to screen readers. */
|
|
this._onAnnounce = new Subject();
|
|
/** Subject for notifying that the snack bar has exited from view. */
|
|
this._onExit = new Subject();
|
|
/** Subject for notifying that the snack bar has finished entering the view. */
|
|
this._onEnter = new Subject();
|
|
/** The state of the snack bar animations. */
|
|
this._animationState = 'void';
|
|
/**
|
|
* Attaches a DOM portal to the snack bar container.
|
|
* @deprecated To be turned into a method.
|
|
* @breaking-change 10.0.0
|
|
*/
|
|
this.attachDomPortal = (portal) => {
|
|
this._assertNotAttached();
|
|
this._applySnackBarClasses();
|
|
return this._portalOutlet.attachDomPortal(portal);
|
|
};
|
|
// Use aria-live rather than a live role like 'alert' or 'status'
|
|
// because NVDA and JAWS have show inconsistent behavior with live roles.
|
|
if (snackBarConfig.politeness === 'assertive' && !snackBarConfig.announcementMessage) {
|
|
this._live = 'assertive';
|
|
}
|
|
else if (snackBarConfig.politeness === 'off') {
|
|
this._live = 'off';
|
|
}
|
|
else {
|
|
this._live = 'polite';
|
|
}
|
|
// Only set role for Firefox. Set role based on aria-live because setting role="alert" implies
|
|
// aria-live="assertive" which may cause issues if aria-live is set to "polite" above.
|
|
if (this._platform.FIREFOX) {
|
|
if (this._live === 'polite') {
|
|
this._role = 'status';
|
|
}
|
|
if (this._live === 'assertive') {
|
|
this._role = 'alert';
|
|
}
|
|
}
|
|
}
|
|
/** Attach a component portal as content to this snack bar container. */
|
|
attachComponentPortal(portal) {
|
|
this._assertNotAttached();
|
|
this._applySnackBarClasses();
|
|
return this._portalOutlet.attachComponentPortal(portal);
|
|
}
|
|
/** Attach a template portal as content to this snack bar container. */
|
|
attachTemplatePortal(portal) {
|
|
this._assertNotAttached();
|
|
this._applySnackBarClasses();
|
|
return this._portalOutlet.attachTemplatePortal(portal);
|
|
}
|
|
/** Handle end of animations, updating the state of the snackbar. */
|
|
onAnimationEnd(event) {
|
|
const { fromState, toState } = event;
|
|
if ((toState === 'void' && fromState !== 'void') || toState === 'hidden') {
|
|
this._completeExit();
|
|
}
|
|
if (toState === 'visible') {
|
|
// Note: we shouldn't use `this` inside the zone callback,
|
|
// because it can cause a memory leak.
|
|
const onEnter = this._onEnter;
|
|
this._ngZone.run(() => {
|
|
onEnter.next();
|
|
onEnter.complete();
|
|
});
|
|
}
|
|
}
|
|
/** Begin animation of snack bar entrance into view. */
|
|
enter() {
|
|
if (!this._destroyed) {
|
|
this._animationState = 'visible';
|
|
this._changeDetectorRef.detectChanges();
|
|
this._screenReaderAnnounce();
|
|
}
|
|
}
|
|
/** Begin animation of the snack bar exiting from view. */
|
|
exit() {
|
|
// Note: this one transitions to `hidden`, rather than `void`, in order to handle the case
|
|
// where multiple snack bars are opened in quick succession (e.g. two consecutive calls to
|
|
// `MatSnackBar.open`).
|
|
this._animationState = 'hidden';
|
|
// Mark this element with an 'exit' attribute to indicate that the snackbar has
|
|
// been dismissed and will soon be removed from the DOM. This is used by the snackbar
|
|
// test harness.
|
|
this._elementRef.nativeElement.setAttribute('mat-exit', '');
|
|
// If the snack bar hasn't been announced by the time it exits it wouldn't have been open
|
|
// long enough to visually read it either, so clear the timeout for announcing.
|
|
clearTimeout(this._announceTimeoutId);
|
|
return this._onExit;
|
|
}
|
|
/** Makes sure the exit callbacks have been invoked when the element is destroyed. */
|
|
ngOnDestroy() {
|
|
this._destroyed = true;
|
|
this._completeExit();
|
|
}
|
|
/**
|
|
* Waits for the zone to settle before removing the element. Helps prevent
|
|
* errors where we end up removing an element which is in the middle of an animation.
|
|
*/
|
|
_completeExit() {
|
|
this._ngZone.onMicrotaskEmpty.pipe(take(1)).subscribe(() => {
|
|
this._onExit.next();
|
|
this._onExit.complete();
|
|
});
|
|
}
|
|
/** Applies the various positioning and user-configured CSS classes to the snack bar. */
|
|
_applySnackBarClasses() {
|
|
const element = this._elementRef.nativeElement;
|
|
const panelClasses = this.snackBarConfig.panelClass;
|
|
if (panelClasses) {
|
|
if (Array.isArray(panelClasses)) {
|
|
// Note that we can't use a spread here, because IE doesn't support multiple arguments.
|
|
panelClasses.forEach(cssClass => element.classList.add(cssClass));
|
|
}
|
|
else {
|
|
element.classList.add(panelClasses);
|
|
}
|
|
}
|
|
if (this.snackBarConfig.horizontalPosition === 'center') {
|
|
element.classList.add('mat-snack-bar-center');
|
|
}
|
|
if (this.snackBarConfig.verticalPosition === 'top') {
|
|
element.classList.add('mat-snack-bar-top');
|
|
}
|
|
}
|
|
/** Asserts that no content is already attached to the container. */
|
|
_assertNotAttached() {
|
|
if (this._portalOutlet.hasAttached() && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
throw Error('Attempting to attach snack bar content after content is already attached');
|
|
}
|
|
}
|
|
/**
|
|
* Starts a timeout to move the snack bar content to the live region so screen readers will
|
|
* announce it.
|
|
*/
|
|
_screenReaderAnnounce() {
|
|
if (!this._announceTimeoutId) {
|
|
this._ngZone.runOutsideAngular(() => {
|
|
this._announceTimeoutId = setTimeout(() => {
|
|
const inertElement = this._elementRef.nativeElement.querySelector('[aria-hidden]');
|
|
const liveElement = this._elementRef.nativeElement.querySelector('[aria-live]');
|
|
if (inertElement && liveElement) {
|
|
// If an element in the snack bar content is focused before being moved
|
|
// track it and restore focus after moving to the live region.
|
|
let focusedElement = null;
|
|
if (this._platform.isBrowser &&
|
|
document.activeElement instanceof HTMLElement &&
|
|
inertElement.contains(document.activeElement)) {
|
|
focusedElement = document.activeElement;
|
|
}
|
|
inertElement.removeAttribute('aria-hidden');
|
|
liveElement.appendChild(inertElement);
|
|
focusedElement === null || focusedElement === void 0 ? void 0 : focusedElement.focus();
|
|
this._onAnnounce.next();
|
|
this._onAnnounce.complete();
|
|
}
|
|
}, this._announceDelay);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
MatSnackBarContainer.ɵfac = function MatSnackBarContainer_Factory(t) { return new (t || MatSnackBarContainer)(ɵngcc0.ɵɵdirectiveInject(ɵngcc0.NgZone), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ElementRef), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ChangeDetectorRef), ɵngcc0.ɵɵdirectiveInject(ɵngcc3.Platform), ɵngcc0.ɵɵdirectiveInject(MatSnackBarConfig)); };
|
|
MatSnackBarContainer.ɵcmp = /*@__PURE__*/ ɵngcc0.ɵɵdefineComponent({ type: MatSnackBarContainer, selectors: [["snack-bar-container"]], viewQuery: function MatSnackBarContainer_Query(rf, ctx) { if (rf & 1) {
|
|
ɵngcc0.ɵɵviewQuery(CdkPortalOutlet, 7);
|
|
} if (rf & 2) {
|
|
let _t;
|
|
ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx._portalOutlet = _t.first);
|
|
} }, hostAttrs: [1, "mat-snack-bar-container"], hostVars: 1, hostBindings: function MatSnackBarContainer_HostBindings(rf, ctx) { if (rf & 1) {
|
|
ɵngcc0.ɵɵsyntheticHostListener("@state.done", function MatSnackBarContainer_animation_state_done_HostBindingHandler($event) { return ctx.onAnimationEnd($event); });
|
|
} if (rf & 2) {
|
|
ɵngcc0.ɵɵsyntheticHostProperty("@state", ctx._animationState);
|
|
} }, features: [ɵngcc0.ɵɵInheritDefinitionFeature], decls: 3, vars: 2, consts: [["aria-hidden", "true"], ["cdkPortalOutlet", ""]], template: function MatSnackBarContainer_Template(rf, ctx) { if (rf & 1) {
|
|
ɵngcc0.ɵɵelementStart(0, "div", 0);
|
|
ɵngcc0.ɵɵtemplate(1, MatSnackBarContainer_ng_template_1_Template, 0, 0, "ng-template", 1);
|
|
ɵngcc0.ɵɵelementEnd();
|
|
ɵngcc0.ɵɵelement(2, "div");
|
|
} if (rf & 2) {
|
|
ɵngcc0.ɵɵadvance(2);
|
|
ɵngcc0.ɵɵattribute("aria-live", ctx._live)("role", ctx._role);
|
|
} }, directives: [ɵngcc4.CdkPortalOutlet], styles: [".mat-snack-bar-container{border-radius:4px;box-sizing:border-box;display:block;margin:24px;max-width:33vw;min-width:344px;padding:14px 16px;min-height:48px;transform-origin:center}.cdk-high-contrast-active .mat-snack-bar-container{border:solid 1px}.mat-snack-bar-handset{width:100%}.mat-snack-bar-handset .mat-snack-bar-container{margin:8px;max-width:100%;min-width:0;width:100%}\n"], encapsulation: 2, data: { animation: [matSnackBarAnimations.snackBarState] } });
|
|
MatSnackBarContainer.ctorParameters = () => [
|
|
{ type: NgZone },
|
|
{ type: ElementRef },
|
|
{ type: ChangeDetectorRef },
|
|
{ type: Platform },
|
|
{ type: MatSnackBarConfig }
|
|
];
|
|
MatSnackBarContainer.propDecorators = {
|
|
_portalOutlet: [{ type: ViewChild, args: [CdkPortalOutlet, { static: true },] }]
|
|
};
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatSnackBarContainer, [{
|
|
type: Component,
|
|
args: [{
|
|
selector: 'snack-bar-container',
|
|
template: "<!-- Initially holds the snack bar content, will be empty after announcing to screen readers. -->\n<div aria-hidden=\"true\">\n <ng-template cdkPortalOutlet></ng-template>\n</div>\n\n<!-- Will receive the snack bar content from the non-live div, move will happen a short delay after opening -->\n<div [attr.aria-live]=\"_live\" [attr.role]=\"_role\"></div>\n",
|
|
// In Ivy embedded views will be change detected from their declaration place, rather than
|
|
// where they were stamped out. This means that we can't have the snack bar container be OnPush,
|
|
// because it might cause snack bars that were opened from a template not to be out of date.
|
|
// tslint:disable-next-line:validate-decorators
|
|
changeDetection: ChangeDetectionStrategy.Default,
|
|
encapsulation: ViewEncapsulation.None,
|
|
animations: [matSnackBarAnimations.snackBarState],
|
|
host: {
|
|
'class': 'mat-snack-bar-container',
|
|
'[@state]': '_animationState',
|
|
'(@state.done)': 'onAnimationEnd($event)'
|
|
},
|
|
styles: [".mat-snack-bar-container{border-radius:4px;box-sizing:border-box;display:block;margin:24px;max-width:33vw;min-width:344px;padding:14px 16px;min-height:48px;transform-origin:center}.cdk-high-contrast-active .mat-snack-bar-container{border:solid 1px}.mat-snack-bar-handset{width:100%}.mat-snack-bar-handset .mat-snack-bar-container{margin:8px;max-width:100%;min-width:0;width:100%}\n"]
|
|
}]
|
|
}], function () { return [{ type: ɵngcc0.NgZone }, { type: ɵngcc0.ElementRef }, { type: ɵngcc0.ChangeDetectorRef }, { type: ɵngcc3.Platform }, { type: MatSnackBarConfig }]; }, { _portalOutlet: [{
|
|
type: ViewChild,
|
|
args: [CdkPortalOutlet, { static: true }]
|
|
}] }); })();
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
class MatSnackBarModule {
|
|
}
|
|
MatSnackBarModule.ɵfac = function MatSnackBarModule_Factory(t) { return new (t || MatSnackBarModule)(); };
|
|
MatSnackBarModule.ɵmod = /*@__PURE__*/ ɵngcc0.ɵɵdefineNgModule({ type: MatSnackBarModule });
|
|
MatSnackBarModule.ɵinj = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjector({ imports: [[
|
|
OverlayModule,
|
|
PortalModule,
|
|
CommonModule,
|
|
MatButtonModule,
|
|
MatCommonModule,
|
|
], MatCommonModule] });
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatSnackBarModule, [{
|
|
type: NgModule,
|
|
args: [{
|
|
imports: [
|
|
OverlayModule,
|
|
PortalModule,
|
|
CommonModule,
|
|
MatButtonModule,
|
|
MatCommonModule,
|
|
],
|
|
exports: [MatSnackBarContainer, MatCommonModule],
|
|
declarations: [MatSnackBarContainer, SimpleSnackBar],
|
|
entryComponents: [MatSnackBarContainer, SimpleSnackBar]
|
|
}]
|
|
}], null, null); })();
|
|
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && ɵngcc0.ɵɵsetNgModuleScope(MatSnackBarModule, { declarations: function () { return [MatSnackBarContainer, SimpleSnackBar]; }, imports: function () { return [OverlayModule,
|
|
PortalModule,
|
|
CommonModule,
|
|
MatButtonModule,
|
|
MatCommonModule]; }, exports: function () { return [MatSnackBarContainer, MatCommonModule]; } }); })();
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
/** Injection token that can be used to specify default snack bar. */
|
|
const MAT_SNACK_BAR_DEFAULT_OPTIONS = new InjectionToken('mat-snack-bar-default-options', {
|
|
providedIn: 'root',
|
|
factory: MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY,
|
|
});
|
|
/** @docs-private */
|
|
function MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY() {
|
|
return new MatSnackBarConfig();
|
|
}
|
|
/**
|
|
* Service to dispatch Material Design snack bar messages.
|
|
*/
|
|
class MatSnackBar {
|
|
constructor(_overlay, _live, _injector, _breakpointObserver, _parentSnackBar, _defaultConfig) {
|
|
this._overlay = _overlay;
|
|
this._live = _live;
|
|
this._injector = _injector;
|
|
this._breakpointObserver = _breakpointObserver;
|
|
this._parentSnackBar = _parentSnackBar;
|
|
this._defaultConfig = _defaultConfig;
|
|
/**
|
|
* Reference to the current snack bar in the view *at this level* (in the Angular injector tree).
|
|
* If there is a parent snack-bar service, all operations should delegate to that parent
|
|
* via `_openedSnackBarRef`.
|
|
*/
|
|
this._snackBarRefAtThisLevel = null;
|
|
/** The component that should be rendered as the snack bar's simple component. */
|
|
this.simpleSnackBarComponent = SimpleSnackBar;
|
|
/** The container component that attaches the provided template or component. */
|
|
this.snackBarContainerComponent = MatSnackBarContainer;
|
|
/** The CSS class to apply for handset mode. */
|
|
this.handsetCssClass = 'mat-snack-bar-handset';
|
|
}
|
|
/** Reference to the currently opened snackbar at *any* level. */
|
|
get _openedSnackBarRef() {
|
|
const parent = this._parentSnackBar;
|
|
return parent ? parent._openedSnackBarRef : this._snackBarRefAtThisLevel;
|
|
}
|
|
set _openedSnackBarRef(value) {
|
|
if (this._parentSnackBar) {
|
|
this._parentSnackBar._openedSnackBarRef = value;
|
|
}
|
|
else {
|
|
this._snackBarRefAtThisLevel = value;
|
|
}
|
|
}
|
|
/**
|
|
* Creates and dispatches a snack bar with a custom component for the content, removing any
|
|
* currently opened snack bars.
|
|
*
|
|
* @param component Component to be instantiated.
|
|
* @param config Extra configuration for the snack bar.
|
|
*/
|
|
openFromComponent(component, config) {
|
|
return this._attach(component, config);
|
|
}
|
|
/**
|
|
* Creates and dispatches a snack bar with a custom template for the content, removing any
|
|
* currently opened snack bars.
|
|
*
|
|
* @param template Template to be instantiated.
|
|
* @param config Extra configuration for the snack bar.
|
|
*/
|
|
openFromTemplate(template, config) {
|
|
return this._attach(template, config);
|
|
}
|
|
/**
|
|
* Opens a snackbar with a message and an optional action.
|
|
* @param message The message to show in the snackbar.
|
|
* @param action The label for the snackbar action.
|
|
* @param config Additional configuration options for the snackbar.
|
|
*/
|
|
open(message, action = '', config) {
|
|
const _config = Object.assign(Object.assign({}, this._defaultConfig), config);
|
|
// Since the user doesn't have access to the component, we can
|
|
// override the data to pass in our own message and action.
|
|
_config.data = { message, action };
|
|
// Since the snack bar has `role="alert"`, we don't
|
|
// want to announce the same message twice.
|
|
if (_config.announcementMessage === message) {
|
|
_config.announcementMessage = undefined;
|
|
}
|
|
return this.openFromComponent(this.simpleSnackBarComponent, _config);
|
|
}
|
|
/**
|
|
* Dismisses the currently-visible snack bar.
|
|
*/
|
|
dismiss() {
|
|
if (this._openedSnackBarRef) {
|
|
this._openedSnackBarRef.dismiss();
|
|
}
|
|
}
|
|
ngOnDestroy() {
|
|
// Only dismiss the snack bar at the current level on destroy.
|
|
if (this._snackBarRefAtThisLevel) {
|
|
this._snackBarRefAtThisLevel.dismiss();
|
|
}
|
|
}
|
|
/**
|
|
* Attaches the snack bar container component to the overlay.
|
|
*/
|
|
_attachSnackBarContainer(overlayRef, config) {
|
|
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
|
|
const injector = Injector.create({
|
|
parent: userInjector || this._injector,
|
|
providers: [{ provide: MatSnackBarConfig, useValue: config }]
|
|
});
|
|
const containerPortal = new ComponentPortal(this.snackBarContainerComponent, config.viewContainerRef, injector);
|
|
const containerRef = overlayRef.attach(containerPortal);
|
|
containerRef.instance.snackBarConfig = config;
|
|
return containerRef.instance;
|
|
}
|
|
/**
|
|
* Places a new component or a template as the content of the snack bar container.
|
|
*/
|
|
_attach(content, userConfig) {
|
|
const config = Object.assign(Object.assign(Object.assign({}, new MatSnackBarConfig()), this._defaultConfig), userConfig);
|
|
const overlayRef = this._createOverlay(config);
|
|
const container = this._attachSnackBarContainer(overlayRef, config);
|
|
const snackBarRef = new MatSnackBarRef(container, overlayRef);
|
|
if (content instanceof TemplateRef) {
|
|
const portal = new TemplatePortal(content, null, {
|
|
$implicit: config.data,
|
|
snackBarRef
|
|
});
|
|
snackBarRef.instance = container.attachTemplatePortal(portal);
|
|
}
|
|
else {
|
|
const injector = this._createInjector(config, snackBarRef);
|
|
const portal = new ComponentPortal(content, undefined, injector);
|
|
const contentRef = container.attachComponentPortal(portal);
|
|
// We can't pass this via the injector, because the injector is created earlier.
|
|
snackBarRef.instance = contentRef.instance;
|
|
}
|
|
// Subscribe to the breakpoint observer and attach the mat-snack-bar-handset class as
|
|
// appropriate. This class is applied to the overlay element because the overlay must expand to
|
|
// fill the width of the screen for full width snackbars.
|
|
this._breakpointObserver.observe(Breakpoints.HandsetPortrait).pipe(takeUntil(overlayRef.detachments())).subscribe(state => {
|
|
const classList = overlayRef.overlayElement.classList;
|
|
state.matches ? classList.add(this.handsetCssClass) : classList.remove(this.handsetCssClass);
|
|
});
|
|
if (config.announcementMessage) {
|
|
// Wait until the snack bar contents have been announced then deliver this message.
|
|
container._onAnnounce.subscribe(() => {
|
|
this._live.announce(config.announcementMessage, config.politeness);
|
|
});
|
|
}
|
|
this._animateSnackBar(snackBarRef, config);
|
|
this._openedSnackBarRef = snackBarRef;
|
|
return this._openedSnackBarRef;
|
|
}
|
|
/** Animates the old snack bar out and the new one in. */
|
|
_animateSnackBar(snackBarRef, config) {
|
|
// When the snackbar is dismissed, clear the reference to it.
|
|
snackBarRef.afterDismissed().subscribe(() => {
|
|
// Clear the snackbar ref if it hasn't already been replaced by a newer snackbar.
|
|
if (this._openedSnackBarRef == snackBarRef) {
|
|
this._openedSnackBarRef = null;
|
|
}
|
|
if (config.announcementMessage) {
|
|
this._live.clear();
|
|
}
|
|
});
|
|
if (this._openedSnackBarRef) {
|
|
// If a snack bar is already in view, dismiss it and enter the
|
|
// new snack bar after exit animation is complete.
|
|
this._openedSnackBarRef.afterDismissed().subscribe(() => {
|
|
snackBarRef.containerInstance.enter();
|
|
});
|
|
this._openedSnackBarRef.dismiss();
|
|
}
|
|
else {
|
|
// If no snack bar is in view, enter the new snack bar.
|
|
snackBarRef.containerInstance.enter();
|
|
}
|
|
// If a dismiss timeout is provided, set up dismiss based on after the snackbar is opened.
|
|
if (config.duration && config.duration > 0) {
|
|
snackBarRef.afterOpened().subscribe(() => snackBarRef._dismissAfter(config.duration));
|
|
}
|
|
}
|
|
/**
|
|
* Creates a new overlay and places it in the correct location.
|
|
* @param config The user-specified snack bar config.
|
|
*/
|
|
_createOverlay(config) {
|
|
const overlayConfig = new OverlayConfig();
|
|
overlayConfig.direction = config.direction;
|
|
let positionStrategy = this._overlay.position().global();
|
|
// Set horizontal position.
|
|
const isRtl = config.direction === 'rtl';
|
|
const isLeft = (config.horizontalPosition === 'left' ||
|
|
(config.horizontalPosition === 'start' && !isRtl) ||
|
|
(config.horizontalPosition === 'end' && isRtl));
|
|
const isRight = !isLeft && config.horizontalPosition !== 'center';
|
|
if (isLeft) {
|
|
positionStrategy.left('0');
|
|
}
|
|
else if (isRight) {
|
|
positionStrategy.right('0');
|
|
}
|
|
else {
|
|
positionStrategy.centerHorizontally();
|
|
}
|
|
// Set horizontal position.
|
|
if (config.verticalPosition === 'top') {
|
|
positionStrategy.top('0');
|
|
}
|
|
else {
|
|
positionStrategy.bottom('0');
|
|
}
|
|
overlayConfig.positionStrategy = positionStrategy;
|
|
return this._overlay.create(overlayConfig);
|
|
}
|
|
/**
|
|
* Creates an injector to be used inside of a snack bar component.
|
|
* @param config Config that was used to create the snack bar.
|
|
* @param snackBarRef Reference to the snack bar.
|
|
*/
|
|
_createInjector(config, snackBarRef) {
|
|
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
|
|
return Injector.create({
|
|
parent: userInjector || this._injector,
|
|
providers: [
|
|
{ provide: MatSnackBarRef, useValue: snackBarRef },
|
|
{ provide: MAT_SNACK_BAR_DATA, useValue: config.data }
|
|
]
|
|
});
|
|
}
|
|
}
|
|
MatSnackBar.ɵfac = function MatSnackBar_Factory(t) { return new (t || MatSnackBar)(ɵngcc0.ɵɵinject(ɵngcc5.Overlay), ɵngcc0.ɵɵinject(ɵngcc6.LiveAnnouncer), ɵngcc0.ɵɵinject(ɵngcc0.Injector), ɵngcc0.ɵɵinject(ɵngcc7.BreakpointObserver), ɵngcc0.ɵɵinject(MatSnackBar, 12), ɵngcc0.ɵɵinject(MAT_SNACK_BAR_DEFAULT_OPTIONS)); };
|
|
MatSnackBar.ɵprov = i0.ɵɵdefineInjectable({ factory: function MatSnackBar_Factory() { return new MatSnackBar(i0.ɵɵinject(i1.Overlay), i0.ɵɵinject(i2.LiveAnnouncer), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(i3.BreakpointObserver), i0.ɵɵinject(MatSnackBar, 12), i0.ɵɵinject(MAT_SNACK_BAR_DEFAULT_OPTIONS)); }, token: MatSnackBar, providedIn: MatSnackBarModule });
|
|
MatSnackBar.ctorParameters = () => [
|
|
{ type: Overlay },
|
|
{ type: LiveAnnouncer },
|
|
{ type: Injector },
|
|
{ type: BreakpointObserver },
|
|
{ type: MatSnackBar, decorators: [{ type: Optional }, { type: SkipSelf }] },
|
|
{ type: MatSnackBarConfig, decorators: [{ type: Inject, args: [MAT_SNACK_BAR_DEFAULT_OPTIONS,] }] }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatSnackBar, [{
|
|
type: Injectable,
|
|
args: [{ providedIn: MatSnackBarModule }]
|
|
}], function () { return [{ type: ɵngcc5.Overlay }, { type: ɵngcc6.LiveAnnouncer }, { type: ɵngcc0.Injector }, { type: ɵngcc7.BreakpointObserver }, { type: MatSnackBar, decorators: [{
|
|
type: Optional
|
|
}, {
|
|
type: SkipSelf
|
|
}] }, { type: MatSnackBarConfig, decorators: [{
|
|
type: Inject,
|
|
args: [MAT_SNACK_BAR_DEFAULT_OPTIONS]
|
|
}] }]; }, null); })();
|
|
|
|
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
/**
|
|
* Generated bundle index. Do not edit.
|
|
*/
|
|
|
|
export { MAT_SNACK_BAR_DATA, MAT_SNACK_BAR_DEFAULT_OPTIONS, MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY, MatSnackBar, MatSnackBarConfig, MatSnackBarContainer, MatSnackBarModule, MatSnackBarRef, SimpleSnackBar, matSnackBarAnimations };
|
|
|
|
//# sourceMappingURL=snack-bar.js.map
|