-
Notifications
You must be signed in to change notification settings - Fork 65
Toastr service and component #1614
Changes from 16 commits
3f4222e
a450054
4b809aa
d55f351
833bcc7
b553659
ab82ba3
db21c76
a282a86
995f024
f4c10f0
c8994ae
d210c2b
11ab289
a49ebf3
28c09b6
3b5d5cb
35de170
ce8ba62
bc37187
82c286d
52f7983
692cbf0
803a205
ed4558f
35e789d
8c8f6c2
a4f23b3
7d3458f
03c63ae
a37b829
99696ac
874ef58
636c5dd
0158250
f57ffc0
e548824
c6c847b
bdc97a6
ff5093c
83e7d04
6104aaf
01c38d6
2fa1e41
57bfe9c
6e766de
d576545
15103e0
37f50ec
ac1e7bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './toast-demo.component'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div> | ||
<button (click)='openMessage()'>Open toast</button> | ||
<sky-toast></sky-toast> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Component } from '@angular/core'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs barrel import format. |
||
|
||
import { | ||
SkyToastService | ||
} from '../../core'; | ||
|
||
@Component({ | ||
selector: 'sky-toast-demo', | ||
templateUrl: './toast-demo.component.html' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs |
||
}) | ||
export class SkyToastDemoComponent { | ||
constructor(private toastSvc: SkyToastService) { } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All constructor injections should be on a single line. #1647 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
public openMessage() { | ||
this.toastSvc.openMessage("Bananas aren't shoes"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -819,6 +819,10 @@ | |
"_description": "The close button for the timepicker modal", | ||
"message": "Done" | ||
}, | ||
"toast_close": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's text for a button, I usually suffix the key with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done. Sorry missed that after applying the inf scroll changes from before |
||
"_description": "Screen reader text for the close button on toasts", | ||
"message": "Close the toast" | ||
}, | ||
"token_dismiss_button_title": { | ||
"_description": "The default text for the token dismiss button title.", | ||
"message": "Remove item" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { SkyToastComponent } from './toast.component'; | ||
export { SkyToastService } from './toast.service'; | ||
export { SkyToastModule } from './toast.module'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<div class="sky-toaster"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a great start, but we'll need to inject the Toast "host" component at the bottom of the page, just before the closing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't seem to incorporate any assistive technology support from what I can see. Especially for the case where type=danger for error identification, but I think we should support this for all the type. This could be done an ARIA live region. It needs to be present in the DOM empty and then have content injected. See - https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions For type=danger it would make sense to use aria-live="assertive" so this is read out immediately. While the other types would be aria-live="polite" which is more the intent for these to be not immediate/interruptive. IBM's Carbon Design system notification component is a good example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Blackbaud-MattGregg Sorry, I'm still not fully familiar with accessibility requirements, but I'm going through the learning videos right now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @blackbaud-conorwright that's great. If those things are in, it should be good to go from this accessibility perspective. thanks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sweet! Thank you 😄 |
||
<aside *ngFor="let message of messages | async"> | ||
<div class="sky-toast" | ||
[ngClass]="{'sky-toast-info': message.toastType=='info', | ||
'sky-toast-warning': message.toastType=='warning', | ||
'sky-toast-danger': message.toastType=='danger', | ||
'sky-toast-success': message.toastType=='success'}"> | ||
<div class='sky-toast-content'>{{message.message}}</div> | ||
<button | ||
type="button" | ||
class="sky-toast-close" | ||
(click)="message.close()" | ||
[attr.aria-label]="'toast_close' | skyResources" | ||
[hidden]="!true"> | ||
<span aria-hidden="true"><i class="fa fa-close"></i></span> | ||
</button> | ||
</div> | ||
</aside> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
@import "../../scss/variables"; | ||
|
||
.sky-toaster { | ||
bottom: 0; | ||
right: 0; | ||
display: block; | ||
position: fixed; | ||
padding-bottom: $sky-margin-double; | ||
padding-right: $sky-margin-double; | ||
} | ||
|
||
.sky-toast { | ||
padding: 0 $sky-padding; | ||
margin-bottom: $sky-margin-double; | ||
border-left: solid 30px; | ||
border-radius: $sky-border-radius; | ||
color: $sky-text-color-default; | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
|
||
.sky-toast-content { | ||
padding-top: $sky-padding; | ||
padding-bottom: $sky-padding; | ||
width: 100%; | ||
|
||
::ng-deep a { | ||
color: change-color($sky-text-color-default, $alpha: 0.8); | ||
text-decoration: underline; | ||
|
||
&:hover { | ||
color: $sky-text-color-default; | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
button { | ||
margin-left: auto; | ||
width: 32px; | ||
height: 32px; | ||
} | ||
} | ||
|
||
.sky-toast-info { | ||
background-color: $sky-background-color-info; | ||
border-color: $sky-highlight-color-info; | ||
|
||
&:before { | ||
content: "\f06a"; | ||
font-family: FontAwesome; | ||
margin-left: -31px; | ||
margin-right: 20px; | ||
color: $sky-color-white; | ||
} | ||
} | ||
|
||
.sky-toast-success { | ||
background-color: $sky-background-color-success; | ||
border-color: $sky-highlight-color-success; | ||
|
||
&:before { | ||
content: "\f00c"; | ||
font-family: FontAwesome; | ||
margin-left: -32px; | ||
margin-right: 19px; | ||
color: $sky-color-white; | ||
} | ||
} | ||
|
||
.sky-toast-warning { | ||
background-color: $sky-background-color-warning; | ||
border-color: $sky-highlight-color-warning; | ||
|
||
&:before { | ||
content: "\f071"; | ||
font-family: FontAwesome; | ||
margin-left: -32px; | ||
margin-right: 19px; | ||
color: $sky-color-white; | ||
} | ||
} | ||
|
||
.sky-toast-danger { | ||
background-color: $sky-background-color-danger; | ||
border-color: $sky-highlight-color-danger; | ||
|
||
&:before { | ||
content: "\f071"; | ||
font-family: FontAwesome; | ||
margin-left: -32px; | ||
margin-right: 19px; | ||
color: $sky-color-white; | ||
} | ||
} | ||
|
||
.sky-toast-close { | ||
cursor: pointer; | ||
font-weight: bold; | ||
line-height: 1; | ||
margin: 0; | ||
padding: 0; | ||
color: $sky-text-color-default; | ||
opacity: 0.8; | ||
border: none; | ||
background-color: transparent; | ||
display: block; | ||
|
||
&:hover { | ||
opacity: 1.0; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Component, OnInit } from '@angular/core'; | ||
import { SkyToastService } from './toast.service'; | ||
import { Observable } from 'rxjs/Observable'; | ||
|
||
@Component({ | ||
selector: 'sky-toast', | ||
templateUrl: './toast.component.html', | ||
styleUrls: ['./toast.component.scss'], | ||
}) | ||
export class SkyToastComponent implements OnInit { | ||
|
||
messages: Observable<any>; | ||
|
||
constructor(private toast: SkyToastService) { } | ||
|
||
ngOnInit() { | ||
this.messages = this.toast.getMessages | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { CommonModule } from '@angular/common'; | ||
import { SkyToastService } from './toast.service'; | ||
import { SkyToastComponent } from './toast.component'; | ||
import { SkyResourcesModule } from '../resources'; | ||
|
||
export { SkyToastService } | ||
|
||
@NgModule({ | ||
declarations: [ | ||
SkyToastComponent | ||
], | ||
imports: [ | ||
CommonModule, SkyResourcesModule | ||
], | ||
exports: [ | ||
SkyToastComponent | ||
], | ||
providers: [ | ||
SkyToastService | ||
], | ||
entryComponents: [ | ||
] | ||
}) | ||
export class SkyToastModule { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { SkyErrorModalService } from './error-modal.service'; | ||
import { MockModalService } from './fixtures/mocks'; | ||
import { ErrorModalConfig } from './error-modal-config'; | ||
import { SkyErrorModalFormComponent } from './error-modal-form.component'; | ||
|
||
describe('Error modal service', () => { | ||
it('Test open is called with correct parameters', () => { | ||
let modalService = new MockModalService(undefined, undefined, undefined); | ||
|
||
const config: ErrorModalConfig = { | ||
errorTitle: 'Error title', | ||
errorDescription: 'Description of error', | ||
errorCloseText: 'Close button text' | ||
}; | ||
|
||
const expectedProvider = { provide: ErrorModalConfig, useValue: config }; | ||
|
||
let service = new SkyErrorModalService(modalService); | ||
service.open(config); | ||
|
||
expect(modalService.openCalls.length).toBe(1); | ||
expect(modalService.openCalls[0].component).toBe(SkyErrorModalFormComponent); | ||
expect(modalService.openCalls[0].providers).toEqual([expectedProvider]); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you missing the "custom" toast component here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added