Skip to content

Commit d4c9318

Browse files
committed
fix(material-experimental/mdc-snack-bar): avoid hard reference to base components and align API
The MDC snack bar was set up to extend the base `MatSnackBar` directly which has a reference to the base snack bar components. This means that the code and styles from the base components will be pulled in, even though it isn't being used. These changes move the snack bar logic into a base class that is extended by the default and MDC implementations. While working on these changes, I also noticed that the simple snack bar components was called `SimpleSnackBar` in the default implementation and `MatSimpleSnackBar` for MDC. I've aligned the naming in order to make it easier to migrate.
1 parent 0742bab commit d4c9318

File tree

9 files changed

+87
-46
lines changed

9 files changed

+87
-46
lines changed

src/dev-app/mdc-snack-bar/mdc-snack-bar-demo.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
import {Directionality} from '@angular/cdk/bidi';
1010
import {Component, TemplateRef, ViewChild, ViewEncapsulation} from '@angular/core';
11-
import {MatSnackBar} from '@angular/material-experimental/mdc-snack-bar';
1211
import {
12+
MatSnackBar,
1313
MatSnackBarConfig,
1414
MatSnackBarHorizontalPosition,
1515
MatSnackBarVerticalPosition
16-
} from '@angular/material/snack-bar';
16+
} from '@angular/material-experimental/mdc-snack-bar';
1717

1818
@Component({
1919
selector: 'mdc-snack-bar-demo',
@@ -22,7 +22,6 @@ import {
2222
encapsulation: ViewEncapsulation.None,
2323
})
2424
export class MdcSnackBarDemo {
25-
2625
@ViewChild('template') template: TemplateRef<any>;
2726
message = 'Snack Bar opened.';
2827
actionButtonLabel = 'Retry';

src/material-experimental/mdc-snack-bar/module.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {NgModule} from '@angular/core';
1313
import {MatButtonModule} from '@angular/material-experimental/mdc-button';
1414
import {MatCommonModule} from '@angular/material-experimental/mdc-core';
1515

16-
import {MatSimpleSnackBar} from './simple-snack-bar';
16+
import {SimpleSnackBar} from './simple-snack-bar';
1717
import {MatSnackBarContainer} from './snack-bar-container';
1818
import {
1919
MatSnackBarAction,
@@ -37,14 +37,14 @@ import {
3737
MatSnackBarAction,
3838
],
3939
declarations: [
40-
MatSimpleSnackBar,
40+
SimpleSnackBar,
4141
MatSnackBarContainer,
4242
MatSnackBarLabel,
4343
MatSnackBarActions,
4444
MatSnackBarAction,
4545
],
4646
entryComponents: [
47-
MatSimpleSnackBar,
47+
SimpleSnackBar,
4848
MatSnackBarContainer,
4949
],
5050
})

src/material-experimental/mdc-snack-bar/public-api.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ export {
1616
MatSnackBarConfig,
1717
MatSnackBarDismiss,
1818
MatSnackBarRef,
19-
SimpleSnackBar,
2019
MAT_SNACK_BAR_DATA,
2120
MAT_SNACK_BAR_DEFAULT_OPTIONS,
2221
MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY,

src/material-experimental/mdc-snack-bar/simple-snack-bar.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,10 @@
77
*/
88

99
import {ChangeDetectionStrategy, Component, Inject, ViewEncapsulation} from '@angular/core';
10-
import {
11-
MAT_SNACK_BAR_DATA,
12-
TextOnlySnackBar,
13-
MatSnackBarRef,
14-
SimpleSnackBar
15-
} from '@angular/material/snack-bar';
10+
import {MAT_SNACK_BAR_DATA, TextOnlySnackBar, MatSnackBarRef} from '@angular/material/snack-bar';
1611

1712
@Component({
18-
selector: 'mat-simple-snack-bar',
13+
selector: 'simple-snack-bar',
1914
templateUrl: 'simple-snack-bar.html',
2015
styleUrls: ['simple-snack-bar.css'],
2116
exportAs: 'matSnackBar',
@@ -25,7 +20,7 @@ import {
2520
'class': 'mat-mdc-simple-snack-bar',
2621
}
2722
})
28-
export class MatSimpleSnackBar implements TextOnlySnackBar {
23+
export class SimpleSnackBar implements TextOnlySnackBar {
2924
constructor(
3025
public snackBarRef: MatSnackBarRef<SimpleSnackBar>,
3126
@Inject(MAT_SNACK_BAR_DATA) public data: {message: string, action: string}) {
@@ -41,4 +36,3 @@ export class MatSimpleSnackBar implements TextOnlySnackBar {
4136
return !!this.data.action;
4237
}
4338
}
44-

src/material-experimental/mdc-snack-bar/snack-bar.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {NoopAnimationsModule} from '@angular/platform-browser/animations';
1515
import {
1616
MAT_SNACK_BAR_DATA,
1717
MAT_SNACK_BAR_DEFAULT_OPTIONS,
18-
MatSimpleSnackBar,
18+
SimpleSnackBar,
1919
MatSnackBar,
2020
MatSnackBarConfig, MatSnackBarContainer,
2121
MatSnackBarModule,
@@ -216,7 +216,7 @@ describe('MatSnackBar', () => {
216216

217217
viewContainerFixture.detectChanges();
218218

219-
expect(snackBarRef.instance instanceof MatSimpleSnackBar)
219+
expect(snackBarRef.instance instanceof SimpleSnackBar)
220220
.toBe(true, 'Expected the snack bar content component to be SimpleSnackBar');
221221
expect(snackBarRef.instance.snackBarRef)
222222
.toBe(snackBarRef,
@@ -240,7 +240,7 @@ describe('MatSnackBar', () => {
240240

241241
viewContainerFixture.detectChanges();
242242

243-
expect(snackBarRef.instance instanceof MatSimpleSnackBar)
243+
expect(snackBarRef.instance instanceof SimpleSnackBar)
244244
.toBe(true, 'Expected the snack bar content component to be SimpleSnackBar');
245245
expect(snackBarRef.instance.snackBarRef)
246246
.toBe(snackBarRef,

src/material-experimental/mdc-snack-bar/snack-bar.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,35 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Injectable} from '@angular/core';
10-
import {MatSnackBar as BaseMatSnackBar} from '@angular/material/snack-bar';
9+
import {LiveAnnouncer} from '@angular/cdk/a11y';
10+
import {BreakpointObserver} from '@angular/cdk/layout';
11+
import {Overlay} from '@angular/cdk/overlay';
12+
import {Inject, Injectable, Injector, Optional, SkipSelf} from '@angular/core';
13+
import {
14+
MatSnackBarConfig,
15+
MAT_SNACK_BAR_DEFAULT_OPTIONS,
16+
_MatSnackBarBase,
17+
} from '@angular/material/snack-bar';
1118
import {MatSnackBarModule} from './module';
12-
import {MatSimpleSnackBar} from './simple-snack-bar';
19+
import {SimpleSnackBar} from './simple-snack-bar';
1320
import {MatSnackBarContainer} from './snack-bar-container';
1421

1522
/**
1623
* Service to dispatch Material Design snack bar messages.
1724
*/
1825
@Injectable({providedIn: MatSnackBarModule})
19-
export class MatSnackBar extends BaseMatSnackBar {
20-
protected override simpleSnackBarComponent = MatSimpleSnackBar;
26+
export class MatSnackBar extends _MatSnackBarBase {
27+
protected override simpleSnackBarComponent = SimpleSnackBar;
2128
protected override snackBarContainerComponent = MatSnackBarContainer;
2229
protected override handsetCssClass = 'mat-mdc-snack-bar-handset';
30+
31+
constructor(
32+
overlay: Overlay,
33+
live: LiveAnnouncer,
34+
injector: Injector,
35+
breakpointObserver: BreakpointObserver,
36+
@Optional() @SkipSelf() parentSnackBar: MatSnackBar,
37+
@Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) defaultConfig: MatSnackBarConfig) {
38+
super(overlay, live, injector, breakpointObserver, parentSnackBar, defaultConfig);
39+
}
2340
}

src/material-experimental/mdc-snack-bar/testing/snack-bar-harness.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import {runHarnessTests} from '@angular/material/snack-bar/testing/shared.spec';
33
import {MatSnackBarHarness} from './snack-bar-harness';
44

55
describe('MDC-based MatSnackBarHarness', () => {
6-
runHarnessTests(MatSnackBarModule, MatSnackBar, MatSnackBarHarness as any);
6+
runHarnessTests(MatSnackBarModule, MatSnackBar as any, MatSnackBarHarness as any);
77
});

src/material/snack-bar/snack-bar.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,8 @@ export function MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY(): MatSnackBarConfig {
4242
return new MatSnackBarConfig();
4343
}
4444

45-
/**
46-
* Service to dispatch Material Design snack bar messages.
47-
*/
48-
@Injectable({providedIn: MatSnackBarModule})
49-
export class MatSnackBar implements OnDestroy {
45+
@Injectable()
46+
export abstract class _MatSnackBarBase implements OnDestroy {
5047
/**
5148
* Reference to the current snack bar in the view *at this level* (in the Angular injector tree).
5249
* If there is a parent snack-bar service, all operations should delegate to that parent
@@ -55,13 +52,13 @@ export class MatSnackBar implements OnDestroy {
5552
private _snackBarRefAtThisLevel: MatSnackBarRef<any> | null = null;
5653

5754
/** The component that should be rendered as the snack bar's simple component. */
58-
protected simpleSnackBarComponent: Type<TextOnlySnackBar> = SimpleSnackBar;
55+
protected abstract simpleSnackBarComponent: Type<TextOnlySnackBar>;
5956

6057
/** The container component that attaches the provided template or component. */
61-
protected snackBarContainerComponent: Type<_SnackBarContainer> = MatSnackBarContainer;
58+
protected abstract snackBarContainerComponent: Type<_SnackBarContainer>;
6259

6360
/** The CSS class to apply for handset mode. */
64-
protected handsetCssClass = 'mat-snack-bar-handset';
61+
protected abstract handsetCssClass: string;
6562

6663
/** Reference to the currently opened snackbar at *any* level. */
6764
get _openedSnackBarRef(): MatSnackBarRef<any> | null {
@@ -82,8 +79,8 @@ export class MatSnackBar implements OnDestroy {
8279
private _live: LiveAnnouncer,
8380
private _injector: Injector,
8481
private _breakpointObserver: BreakpointObserver,
85-
@Optional() @SkipSelf() private _parentSnackBar: MatSnackBar,
86-
@Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) private _defaultConfig: MatSnackBarConfig) {}
82+
private _parentSnackBar: _MatSnackBarBase,
83+
private _defaultConfig: MatSnackBarConfig) {}
8784

8885
/**
8986
* Creates and dispatches a snack bar with a custom component for the content, removing any
@@ -300,3 +297,23 @@ export class MatSnackBar implements OnDestroy {
300297
});
301298
}
302299
}
300+
301+
/**
302+
* Service to dispatch Material Design snack bar messages.
303+
*/
304+
@Injectable({providedIn: MatSnackBarModule})
305+
export class MatSnackBar extends _MatSnackBarBase {
306+
protected simpleSnackBarComponent = SimpleSnackBar;
307+
protected snackBarContainerComponent = MatSnackBarContainer;
308+
protected handsetCssClass = 'mat-snack-bar-handset';
309+
310+
constructor(
311+
overlay: Overlay,
312+
live: LiveAnnouncer,
313+
injector: Injector,
314+
breakpointObserver: BreakpointObserver,
315+
@Optional() @SkipSelf() parentSnackBar: MatSnackBar,
316+
@Inject(MAT_SNACK_BAR_DEFAULT_OPTIONS) defaultConfig: MatSnackBarConfig) {
317+
super(overlay, live, injector, breakpointObserver, parentSnackBar, defaultConfig);
318+
}
319+
}

tools/public_api_guard/material/snack-bar.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,14 @@ export const MAT_SNACK_BAR_DEFAULT_OPTIONS: InjectionToken<MatSnackBarConfig<any
4949
export function MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY(): MatSnackBarConfig;
5050

5151
// @public
52-
export class MatSnackBar implements OnDestroy {
53-
constructor(_overlay: Overlay, _live: LiveAnnouncer, _injector: Injector, _breakpointObserver: BreakpointObserver, _parentSnackBar: MatSnackBar, _defaultConfig: MatSnackBarConfig);
54-
dismiss(): void;
52+
export class MatSnackBar extends _MatSnackBarBase {
53+
constructor(overlay: Overlay, live: LiveAnnouncer, injector: Injector, breakpointObserver: BreakpointObserver, parentSnackBar: MatSnackBar, defaultConfig: MatSnackBarConfig);
54+
// (undocumented)
5555
protected handsetCssClass: string;
5656
// (undocumented)
57-
ngOnDestroy(): void;
58-
open(message: string, action?: string, config?: MatSnackBarConfig): MatSnackBarRef<TextOnlySnackBar>;
59-
get _openedSnackBarRef(): MatSnackBarRef<any> | null;
60-
set _openedSnackBarRef(value: MatSnackBarRef<any> | null);
61-
openFromComponent<T>(component: ComponentType<T>, config?: MatSnackBarConfig): MatSnackBarRef<T>;
62-
openFromTemplate(template: TemplateRef<any>, config?: MatSnackBarConfig): MatSnackBarRef<EmbeddedViewRef<any>>;
63-
protected simpleSnackBarComponent: Type<TextOnlySnackBar>;
64-
protected snackBarContainerComponent: Type<_SnackBarContainer>;
57+
protected simpleSnackBarComponent: typeof SimpleSnackBar;
58+
// (undocumented)
59+
protected snackBarContainerComponent: typeof MatSnackBarContainer;
6560
// (undocumented)
6661
static ɵfac: i0.ɵɵFactoryDeclaration<MatSnackBar, [null, null, null, null, { optional: true; skipSelf: true; }, null]>;
6762
// (undocumented)
@@ -73,6 +68,26 @@ export const matSnackBarAnimations: {
7368
readonly snackBarState: AnimationTriggerMetadata;
7469
};
7570

71+
// @public (undocumented)
72+
export abstract class _MatSnackBarBase implements OnDestroy {
73+
constructor(_overlay: Overlay, _live: LiveAnnouncer, _injector: Injector, _breakpointObserver: BreakpointObserver, _parentSnackBar: _MatSnackBarBase, _defaultConfig: MatSnackBarConfig);
74+
dismiss(): void;
75+
protected abstract handsetCssClass: string;
76+
// (undocumented)
77+
ngOnDestroy(): void;
78+
open(message: string, action?: string, config?: MatSnackBarConfig): MatSnackBarRef<TextOnlySnackBar>;
79+
get _openedSnackBarRef(): MatSnackBarRef<any> | null;
80+
set _openedSnackBarRef(value: MatSnackBarRef<any> | null);
81+
openFromComponent<T>(component: ComponentType<T>, config?: MatSnackBarConfig): MatSnackBarRef<T>;
82+
openFromTemplate(template: TemplateRef<any>, config?: MatSnackBarConfig): MatSnackBarRef<EmbeddedViewRef<any>>;
83+
protected abstract simpleSnackBarComponent: Type<TextOnlySnackBar>;
84+
protected abstract snackBarContainerComponent: Type<_SnackBarContainer>;
85+
// (undocumented)
86+
static ɵfac: i0.ɵɵFactoryDeclaration<_MatSnackBarBase, never>;
87+
// (undocumented)
88+
static ɵprov: i0.ɵɵInjectableDeclaration<_MatSnackBarBase>;
89+
}
90+
7691
// @public
7792
export class MatSnackBarConfig<D = any> {
7893
announcementMessage?: string;

0 commit comments

Comments
 (0)