Skip to content

Commit 334eed8

Browse files
feat(docs-infra): allow notification bar to show arbitrary content
This change generalises the notification bar rendering to allow more complex content to be displayed. Now you must provide the full HTML of the notification message when using `<aio-notification>`. Also you can control whether clicking the content triggers the notification to close or not. This will support the new notification specified in "Other Items #3" of angular#24140#issuecomment-397480410
1 parent 0110bf6 commit 334eed8

File tree

5 files changed

+60
-41
lines changed

5 files changed

+60
-41
lines changed

Diff for: aio/src/app/app.component.html

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
<mat-toolbar color="primary" class="app-toolbar no-print" [class.transitioning]="isTransitioning">
88
<mat-toolbar-row class="notification-container">
99
<aio-notification
10-
icon="insert_comment"
11-
iconLabel="Announcement"
12-
buttonText="Learn More"
13-
actionUrl="https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4"
1410
notificationId="angular-v6-announcement"
15-
expirationDate="2018-07-01"
11+
expirationDate="2019-07-01"
12+
[dismissOnContentClick]="true"
1613
(dismissed)="notificationDismissed()">
17-
Version 6 of Angular Now Available!
14+
<a href="https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4" class="flex">
15+
<mat-icon class="icon" svgIcon="insert_comment" aria-label="Announcement"></mat-icon>
16+
<span class="message">Version 6 of Angular Now Available!</span>
17+
<span class="action-button">Learn More</span>
18+
</a>
1819
</aio-notification>
1920
</mat-toolbar-row>
2021
<mat-toolbar-row>

Diff for: aio/src/app/layout/notification/notification.component.html

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
<a href="{{actionUrl}}" class="content" (click)="dismiss()">
2-
<mat-icon class="icon" [svgIcon]="icon" [attr.aria-label]="iconLabel"></mat-icon>
3-
<span class="message"><ng-content></ng-content></span>
4-
<span class="action-button">{{buttonText}}</span>
5-
</a>
1+
<span class="content" (click)="contentClick()">
2+
<ng-content></ng-content>
3+
</span>
64

75
<button mat-icon-button class="close-button" aria-label="Close" (click)="dismiss()">
86
<mat-icon svgIcon="close" aria-label="Dismiss notification"></mat-icon>

Diff for: aio/src/app/layout/notification/notification.component.spec.ts

+38-24
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,49 @@ describe('NotificationComponent', () => {
3030
fixture.detectChanges();
3131
}
3232

33-
it('should display the message', () => {
34-
configTestingModule();
35-
createComponent();
36-
expect(fixture.nativeElement.innerHTML).toContain('Help Angular by taking a <strong>1 minute survey</strong>!');
37-
});
33+
describe('content projection', () => {
34+
it('should display the message text', () => {
35+
configTestingModule();
36+
createComponent();
37+
expect(fixture.nativeElement.innerHTML).toContain('Version 6 of Angular Now Available!');
38+
});
3839

39-
it('should display an icon', () => {
40-
configTestingModule();
41-
createComponent();
42-
const iconElement = fixture.debugElement.query(By.css('.icon'));
43-
expect(iconElement.properties['svgIcon']).toEqual('insert_comment');
44-
expect(iconElement.attributes['aria-label']).toEqual('Survey');
40+
it('should render HTML elements', () => {
41+
configTestingModule();
42+
createComponent();
43+
const button = fixture.debugElement.query(By.css('.action-button'));
44+
expect(button.nativeElement.textContent).toEqual('Learn More');
45+
});
46+
47+
it('should process Angular directives', () => {
48+
configTestingModule();
49+
createComponent();
50+
const badSpans = fixture.debugElement.queryAll(By.css('.bad'));
51+
expect(badSpans.length).toEqual(0);
52+
});
4553
});
4654

47-
it('should display a button', () => {
55+
it('should call dismiss() when the message link is clicked, if dismissOnContentClick is true', () => {
4856
configTestingModule();
4957
createComponent();
50-
const button = fixture.debugElement.query(By.css('.action-button'));
51-
expect(button.nativeElement.textContent).toEqual('Go to survey');
58+
spyOn(component, 'dismiss');
59+
component.dismissOnContentClick = true;
60+
const message: HTMLSpanElement = fixture.debugElement.query(By.css('.messageholder')).nativeElement;
61+
message.click();
62+
expect(component.dismiss).toHaveBeenCalled();
5263
});
5364

54-
it('should call dismiss when the message link is clicked', () => {
65+
it('should not call dismiss() when the message link is clicked, if dismissOnContentClick is false', () => {
5566
configTestingModule();
5667
createComponent();
5768
spyOn(component, 'dismiss');
58-
fixture.debugElement.query(By.css('a')).triggerEventHandler('click', null);
59-
fixture.detectChanges();
60-
expect(component.dismiss).toHaveBeenCalled();
69+
component.dismissOnContentClick = false;
70+
const message: HTMLSpanElement = fixture.debugElement.query(By.css('.messageholder')).nativeElement;
71+
message.click();
72+
expect(component.dismiss).not.toHaveBeenCalled();
6173
});
6274

63-
it('should call dismiss when the close button is clicked', () => {
75+
it('should call dismiss() when the close button is clicked', () => {
6476
configTestingModule();
6577
createComponent();
6678
spyOn(component, 'dismiss');
@@ -104,13 +116,15 @@ describe('NotificationComponent', () => {
104116
@Component({
105117
template: `
106118
<aio-notification
107-
icon="insert_comment"
108-
iconLabel="Survey"
109-
buttonText="Go to survey"
110-
actionUrl="https://bit.ly/angular-survey-2018"
111119
notificationId="survey-january-2018"
112120
expirationDate="2018-01-22">
113-
Help Angular by taking a <strong>1 minute survey</strong>!
121+
<span class="messageholder">
122+
<a href="https://blog.angular.io/version-6-0-0-of-angular-now-available-cc56b0efa7a4">
123+
<span *ngIf="false" class="bad">This should not appear</span>
124+
<span class="message">Version 6 of Angular Now Available!</span>
125+
<span class="action-button">Learn More</span>
126+
</a>
127+
</span>
114128
</aio-notification>`
115129
})
116130
class TestComponent {

Diff for: aio/src/app/layout/notification/notification.component.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ const LOCAL_STORAGE_NAMESPACE = 'aio-notification/';
2222
export class NotificationComponent implements OnInit {
2323
private get localStorage() { return this.window.localStorage; }
2424

25-
@Input() icon: string;
26-
@Input() iconLabel: string;
27-
@Input() buttonText: string;
28-
@Input() actionUrl: string;
25+
@Input() dismissOnContentClick: boolean;
2926
@Input() notificationId: string;
3027
@Input() expirationDate: string;
3128
@Output() dismissed = new EventEmitter();
@@ -44,6 +41,12 @@ export class NotificationComponent implements OnInit {
4441
this.showNotification = previouslyHidden || expired ? 'hide' : 'show';
4542
}
4643

44+
contentClick() {
45+
if (this.dismissOnContentClick) {
46+
this.dismiss();
47+
}
48+
}
49+
4750
dismiss() {
4851
this.localStorage.setItem(LOCAL_STORAGE_NAMESPACE + this.notificationId, 'hide');
4952
this.showNotification = 'hide';

Diff for: aio/src/styles/2-modules/_notification.scss

+5-2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@ aio-notification {
3131
}
3232

3333
.content {
34-
display: flex;
3534
max-width: calc(100% - #{$notificationHeight});
3635
text-transform: none;
3736
padding: 0;
3837

38+
.flex {
39+
display: flex;
40+
}
41+
3942
.icon {
4043
margin-right: 10px;
4144
@media (max-width: 464px) {
@@ -46,10 +49,10 @@ aio-notification {
4649
.message {
4750
overflow: hidden;
4851
text-overflow: ellipsis;
52+
margin-right: 10px;
4953
}
5054

5155
.action-button {
52-
margin-left: 10px;
5356
background: $brightred;
5457
border-radius: 15px;
5558
text-transform: uppercase;

0 commit comments

Comments
 (0)