Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 33 additions & 20 deletions goldens/material/snack-bar/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { ViewContainerRef } from '@angular/core';
export const MAT_SNACK_BAR_DATA: InjectionToken<any>;

// @public
export const MAT_SNACK_BAR_DEFAULT_OPTIONS: InjectionToken<MatSnackBarConfig<any>>;
export const MAT_SNACK_BAR_DEFAULT_OPTIONS: InjectionToken<MatSnackBarConfig<unknown>>;

// @public
export class MatSnackBar implements OnDestroy {
Expand All @@ -44,11 +44,11 @@ export class MatSnackBar implements OnDestroy {
handsetCssClass: string;
// (undocumented)
ngOnDestroy(): void;
open(message: string, action?: string, config?: MatSnackBarConfig): MatSnackBarRef<TextOnlySnackBar>;
get _openedSnackBarRef(): MatSnackBarRef<any> | null;
set _openedSnackBarRef(value: MatSnackBarRef<any> | null);
openFromComponent<T, D = any>(component: ComponentType<T>, config?: MatSnackBarConfig<D>): MatSnackBarRef<T>;
openFromTemplate(template: TemplateRef<any>, config?: MatSnackBarConfig): MatSnackBarRef<EmbeddedViewRef<any>>;
open(message: string, action?: string, config?: MatSnackBarConfig<unknown>): MatSnackBarRef<TextOnlySnackBar, TextOnlySnackBarData>;
get _openedSnackBarRef(): MatSnackBarRef<unknown> | null;
set _openedSnackBarRef(value: MatSnackBarRef<unknown> | null);
openFromComponent<T, D>(component: ComponentType<T>, config?: MatSnackBarConfig<D>): MatSnackBarRef<T, D>;
openFromTemplate<D>(template: TemplateRef<SnackBarTemplateContext<D>>, config?: MatSnackBarConfig<D>): MatSnackBarRef<EmbeddedViewRef<SnackBarTemplateContext<D>>, D>;
simpleSnackBarComponent: typeof SimpleSnackBar;
snackBarContainerComponent: typeof MatSnackBarContainer;
// (undocumented)
Expand Down Expand Up @@ -87,7 +87,7 @@ export class MatSnackBarConfig<D = any> {
}

// @public
export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy {
export class MatSnackBarContainer<D = unknown> extends BasePortalOutlet implements OnDestroy {
constructor(...args: unknown[]);
// (undocumented)
protected _animationsDisabled: boolean;
Expand All @@ -111,11 +111,11 @@ export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy
_portalOutlet: CdkPortalOutlet;
_role?: 'status' | 'alert';
// (undocumented)
snackBarConfig: MatSnackBarConfig<any>;
snackBarConfig: MatSnackBarConfig<D>;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<MatSnackBarContainer, "mat-snack-bar-container", never, {}, {}, never, never, true, never>;
static ɵcmp: i0.ɵɵComponentDeclaration<MatSnackBarContainer<any>, "mat-snack-bar-container", never, {}, {}, never, never, true, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<MatSnackBarContainer, never>;
static ɵfac: i0.ɵɵFactoryDeclaration<MatSnackBarContainer<any>, never>;
}

// @public
Expand Down Expand Up @@ -145,13 +145,13 @@ export class MatSnackBarModule {
}

// @public
export class MatSnackBarRef<T> {
constructor(containerInstance: MatSnackBarContainer, _overlayRef: OverlayRef);
export class MatSnackBarRef<T, D = unknown> {
constructor(containerInstance: MatSnackBarContainer<D>, _overlayRef: OverlayRef);
afterDismissed(): Observable<MatSnackBarDismiss>;
afterOpened(): Observable<void>;
// @deprecated
closeWithAction(): void;
containerInstance: MatSnackBarContainer;
containerInstance: MatSnackBarContainer<D>;
dismiss(): void;
_dismissAfter(duration: number): void;
dismissWithAction(): void;
Expand All @@ -168,29 +168,42 @@ export class SimpleSnackBar implements TextOnlySnackBar {
constructor(...args: unknown[]);
action(): void;
// (undocumented)
data: any;
data: TextOnlySnackBarData;
get hasAction(): boolean;
// (undocumented)
snackBarRef: MatSnackBarRef<SimpleSnackBar>;
snackBarRef: MatSnackBarRef<SimpleSnackBar, TextOnlySnackBarData>;
// (undocumented)
static ɵcmp: i0.ɵɵComponentDeclaration<SimpleSnackBar, "simple-snack-bar", ["matSnackBar"], {}, {}, never, never, true, never>;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<SimpleSnackBar, never>;
}

// @public (undocumented)
export interface SnackBarTemplateContext<D> {
// (undocumented)
$implicit?: D | null;
// (undocumented)
snackBarRef?: MatSnackBarRef<EmbeddedViewRef<SnackBarTemplateContext<D>>, D>;
}

// @public
export interface TextOnlySnackBar {
// (undocumented)
action: () => void;
// (undocumented)
data: {
message: string;
action: string;
};
data: TextOnlySnackBarData;
// (undocumented)
hasAction: boolean;
// (undocumented)
snackBarRef: MatSnackBarRef<TextOnlySnackBar>;
snackBarRef: MatSnackBarRef<TextOnlySnackBar, TextOnlySnackBarData>;
}

// @public
export interface TextOnlySnackBarData {
// (undocumented)
action: string;
// (undocumented)
message: string;
}

// (No @packageDocumentation comment for this package)
Expand Down
14 changes: 10 additions & 4 deletions src/material/snack-bar/simple-snack-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@ import {MatSnackBarRef} from './snack-bar-ref';
import {MAT_SNACK_BAR_DATA} from './snack-bar-config';
import {MatSnackBarAction, MatSnackBarActions, MatSnackBarLabel} from './snack-bar-content';

/** Input data for a simple snack bar component that has a message and a single action. */
export interface TextOnlySnackBarData {
message: string;
action: string;
}

/**
* Interface for a simple snack bar component that has a message and a single action.
*/
export interface TextOnlySnackBar {
data: {message: string; action: string};
snackBarRef: MatSnackBarRef<TextOnlySnackBar>;
data: TextOnlySnackBarData;
snackBarRef: MatSnackBarRef<TextOnlySnackBar, TextOnlySnackBarData>;
action: () => void;
hasAction: boolean;
}
Expand All @@ -35,8 +41,8 @@ export interface TextOnlySnackBar {
},
})
export class SimpleSnackBar implements TextOnlySnackBar {
snackBarRef = inject<MatSnackBarRef<SimpleSnackBar>>(MatSnackBarRef);
data = inject(MAT_SNACK_BAR_DATA);
snackBarRef = inject<MatSnackBarRef<SimpleSnackBar, TextOnlySnackBarData>>(MatSnackBarRef);
data = inject<TextOnlySnackBarData>(MAT_SNACK_BAR_DATA);

constructor(...args: unknown[]);
constructor() {}
Expand Down
1 change: 1 addition & 0 deletions src/material/snack-bar/snack-bar-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type MatSnackBarVerticalPosition = 'top' | 'bottom';
/**
* Configuration used when opening a snack-bar.
*/
// TODO: Change `any` type to `unknown` in a breaking change.
export class MatSnackBarConfig<D = any> {
/** The politeness level for the MatAriaLiveAnnouncer announcement. */
politeness?: AriaLivePoliteness = 'polite';
Expand Down
4 changes: 2 additions & 2 deletions src/material/snack-bar/snack-bar-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ const EXIT_ANIMATION = '_mat-snack-bar-exit';
'(animationcancel)': 'onAnimationEnd($event.animationName)',
},
})
export class MatSnackBarContainer extends BasePortalOutlet implements OnDestroy {
export class MatSnackBarContainer<D = unknown> extends BasePortalOutlet implements OnDestroy {
private _ngZone = inject(NgZone);
readonly _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);
private _changeDetectorRef = inject(ChangeDetectorRef);
private _platform = inject(Platform);
protected _animationsDisabled = _animationsDisabled();
snackBarConfig = inject(MatSnackBarConfig);
snackBarConfig = inject<MatSnackBarConfig<D>>(MatSnackBarConfig);

private _document = inject(DOCUMENT);
private _trackedModals = new Set<Element>();
Expand Down
6 changes: 3 additions & 3 deletions src/material/snack-bar/snack-bar-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ const MAX_TIMEOUT = Math.pow(2, 31) - 1;
/**
* Reference to a snack bar dispatched from the snack bar service.
*/
export class MatSnackBarRef<T> {
export class MatSnackBarRef<T, D = unknown> {
/** The instance of the component making up the content of the snack bar. */
instance!: T;

/**
* The instance of the component making up the content of the snack bar.
* @docs-private
*/
containerInstance: MatSnackBarContainer;
containerInstance: MatSnackBarContainer<D>;

/** Subject for notifying the user that the snack bar has been dismissed. */
private readonly _afterDismissed = new Subject<MatSnackBarDismiss>();
Expand All @@ -51,7 +51,7 @@ export class MatSnackBarRef<T> {
private _dismissedByAction = false;

constructor(
containerInstance: MatSnackBarContainer,
containerInstance: MatSnackBarContainer<D>,
private _overlayRef: OverlayRef,
) {
this.containerInstance = containerInstance;
Expand Down
25 changes: 17 additions & 8 deletions src/material/snack-bar/snack-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
MatSnackBarRef,
SimpleSnackBar,
} from './index';
import {MAT_SNACK_BAR_DEFAULT_OPTIONS} from './snack-bar';
import {MAT_SNACK_BAR_DEFAULT_OPTIONS, SnackBarTemplateContext} from './snack-bar';
import {MATERIAL_ANIMATIONS} from '../core';

describe('MatSnackBar', () => {
Expand Down Expand Up @@ -571,7 +571,10 @@ describe('MatSnackBar', () => {
});

it('should inject the snack bar reference into the component', () => {
const snackBarRef = snackBar.openFromComponent(BurritosNotification);
const snackBarRef = snackBar.openFromComponent<
BurritosNotification,
BurritosNotificationData
>(BurritosNotification);

expect(snackBarRef.instance.snackBarRef)
.withContext('Expected component to have an injected snack bar reference.')
Expand All @@ -585,10 +588,11 @@ describe('MatSnackBar', () => {
});

it('should be able to inject arbitrary user data', () => {
const data: BurritosNotificationData = {
burritoType: 'Chimichanga',
};
const snackBarRef = snackBar.openFromComponent(BurritosNotification, {
data: {
burritoType: 'Chimichanga',
},
data,
});

expect(snackBarRef.instance.data)
Expand Down Expand Up @@ -997,17 +1001,22 @@ class ComponentWithChildViewContainer {
`,
})
class ComponentWithTemplateRef {
@ViewChild(TemplateRef) templateRef!: TemplateRef<any>;
@ViewChild(TemplateRef) templateRef!: TemplateRef<SnackBarTemplateContext<{value: string}>>;
localValue!: string;
}

interface BurritosNotificationData {
burritoType: string;
}

/** Simple component for testing ComponentPortal. */
@Component({
template: '<p>Burritos are on the way.</p>',
})
class BurritosNotification {
snackBarRef = inject<MatSnackBarRef<BurritosNotification>>(MatSnackBarRef);
data = inject(MAT_SNACK_BAR_DATA);
snackBarRef =
inject<MatSnackBarRef<BurritosNotification, BurritosNotificationData>>(MatSnackBarRef);
data = inject<BurritosNotificationData>(MAT_SNACK_BAR_DATA);
}

@Component({
Expand Down
Loading
Loading