deliteful/Toaster
deliteful/Toaster is a widget that allows an application to notify the user
in a non obtrusive way (it will not steal the focus), through a quick little
message.  A toaster is an unobtrusive mechanism for displaying messages. Like
toasts, messages "pop up" in the window corner, temporarily overlaying any
content there. The message stays up for a certain duration, or until the user
dismisses it explicitly (with a swipe gesture or by clicking on the dismiss
button).
Toasters are preferable to alert boxes. Alerts must always be modal, meaning all action on the page stops until the user clicks OK or Cancel. Toasters are non-modal, so the user can continue working and finish their thought before responding.
Note that the Toaster widget depends on the ToasterMessage widget.
The behavior in a nutshell
The Toaster widget serves as a host for ToasterMessage instances, each with 
its own type, duration, etc.
When created, each instance goes through a lifecycle of 4 states:
- inserted: the instance is inserted in the DOM but still invisible,
- shown: the instance is made visible, with a fade-in animation,
- hidden: the instance is made invisible, either because it expired or it was dismissed,
- removed: the instance is removed from the DOM;
You can hook up animations on each of theses 4 states. (see animations). Note that a message that is dismissed or that has expired is not immediately removed from DOM. First, it's only hidden, and stay hidden until all the other expirable (and only expirable) messages reach the hidden state as well (either by being manually dismissed by the user or by expiring).
This prevents the message that haven't expired from moving around as some of them disappear, but at the same time, it avoids having awkward permanent holes in between persistent messages as it ends up stacking them together.
 

Table of Contents
Element Instantiation
Element Configuration
Element Styling
User Interactions
Element Events
Enterprise Use
Element Instantiation
See delite/Widget for full details on how instantiation lifecycle works.
Declarative Instantiation
var mytoaster;
require([
    "delite/register",
    "deliteful/Toaster",
    "requirejs-domready/domReady!"
    ], function(register, Toaster){
        register.parse()
        // posting a message
        mytoaster.postMessage("Form submitted");
    });
<d-toaster id="mytoaster"><d-toaster>
Programmatic Instantiation
var mytoaster;
require([
        "delite/register",
        "deliteful/Toaster",
        "requirejs-domready/domReady!"
        ], function(register, Toaster){
            mytoaster = new Toaster();
            mytoaster.placeAt("container");
            // posting a message
            mytoaster.postMessage("Form submitted");
        });
<div id="container"></div>
The Toaster.postMessage() also supports messages as widgets
var mytoaster;
require([
    "delite/register",
    "deliteful/ToasterMessage",
    "deliteful/Toaster",
    "requirejs-domready/domReady!"
    ], function(register, ToasterMessage, Toaster){
        mytoaster = new Toaster();
        mytoaster.placeAt("container");
        // defining the message as a widget
        var myMessage = new ToasterMessage("Form submitted");
        // posting
        mytoaster.postMessage(myMessage);
    });
Element Configuration
Placement of the toaster
The Toaster widget has a placement property which will determine where the
messages will appear on the screen (top-left corner, etc.). It is a string representing a
regular CSS class that is applied to the widget on creation.  If you choose not
to set this property, it will default to "d-toaster-placement-default".
Note that the widget comes with 7 placement options (i.e. 7 CSS classes that work right out of the box). It goes without saying that you can set this property to your own placement class.
| top-left
             | top-center
             | top-right
             | 
| default
             | ||
| bottom-left
             | bottom-center
             | bottom-right
             | 
Message types
The type property of ToasterMessage can be set to either "info", "error",
"warning" or "success". In case no type or an incorrect type is provided, "info" type
is used by default.
var m = new ToasterMessage({message: "content of my message", type: "success"});
mytoaster.postMessage(m);
// the shortcut
mytoaster.postMessage("content of my message", {type: "success"});
Each type is associated with a CSS class named d-toaster-type- which defines its styling.
Duration of a message
By default a message lasts for 2000ms after it is "posted" in the toaster. The property duration can be set to any positive integer.
However, if set to -1 the message will remain visible until the user
explicitly dismisses it (by clicking the dismiss button or swiping it out of the screen).
NB: if duration is set to -1 and dismissible to false, you'll obtain a persistent message
which your user has no way to dismiss - probably not ideal from
a user experience perspective.
// a message that fades after 6s
var m1 = new ToasterMessage({message: "This will auto-destruct in 6s", duration: 6000});
mytoaster.postMessage(m1);
// a message that waits for the user to dismiss it manually
var m2 = new ToasterMessage({message: "This will always stay there", duration: -1});
mytoaster.postMessage(m2);
// the shortcut
mytoaster.postMessage("This will auto-destruct in 6s", {duration: 6000});
mytoaster.postMessage("This will always stay there", {duration: -1});
Making a message dismissible
If dismissible is set to "on", the user can dismiss the message (either
with a swipe or the dismiss button). If set to "off", the user can only wait for the
message to disappear on its own.
When dismissible is set to "auto", the behavior depends on whether the message expires:
- a message that expires (duration >= 0) will not be dismissible,
- a message that does not expire (duration === -1) will be dismissible.
mytoaster.postMessage("content of my message", {dismissible: "off"});
NB: if dismissible is set to "off" on a persistent message, your user will have no way to dismiss it
and it will stay on the screen forever which probably is not ideal from a user experience perspective.
Checking if a message is dismissible
This methods returns a boolean that indicates whether a message is dismissible.
If returns true (resp. false) when dismissible is set to "on" (resp. "off").
If controls the visibility of the dismiss button and enables/disables the swipe-to-dismiss.
When dismissible is set to "auto", the output of the method also depends on the duration property:
- a message that is expirable (duration >= 0) will have no dismiss button or swipe-to-dismiss (isDismissible() === false)
- a message that does not expire (duration === -1) will have a dismiss button and swipe-to-dismiss (isDismissible() === true)
| dismissible | duration | isDismissible() | 
|---|---|---|
| on | * | true | 
| off | * | false | 
| auto | >= 0 | false | 
| auto | -1 | true | 
animations
For each of the 4 states of a ToasterMessage instance, an animation class is added
mytoaster = new Toaster({
    animationInitialClass: "d-toaster-initial",     // added on insertion
    animationEnterClass: "d-toaster-fadein",        // added on show
    animationQuitClass: "d-toaster-fadeout",        // added on hide
    animationEndClass: "d-toaster-fadefinish"       // added on removal
});
A fade-in/fade-out set of animation classes comes by default but you can define and use your own.
You need to make sure that animationEnterClass and animationQuitClass classes emit either a
transitionendor animationend sort of event, as moving from one state to the other requires animations ending
 to be properly detected.
Message templating
The ToasterMessage widget comes with a default template
<template class="" data-touch-action="none">
    <button type="button" class="d-toaster-dismiss" attach-point="_dismissButton"></button>
    <span class="d-toaster-icon"></span>
    <span class="d-toaster-message-content">
    </span>
</template>
Currently, there is no way to set up your own template as the template file
path is hard coded in the widget. If you want to set up your own template, one
way to do it could be to create your own widget inheriting from ToasterMessage.
Element Styling
Supported themes
This widget provides default styling for the following delite themes:
- bootstrap
- ios
- holodark
CSS classes
- Placement of the Toaster 
 all placement classes- d-toaster-placement-*are documented in this section.- css .d-toaster-placement-default .d-toaster-inner { left: 20%; bottom: 10%; width: 60%; }
- Message types 
 there is one class for each message type allowed.
.d-toaster-type-error {
    background-color: #d9edf7;
    border-color: #bce8f1;
    color: #31708f;
}
.d-toaster-type-info    {...}
.d-toaster-type-warning {...}
.d-toaster-type-success {...}
- The dismiss button
 this class allows to set its position and any property a button can take. Use thecontentproperty to change the character used to represent the button.
.d-toaster-dismiss {...}
.d-toaster-dismiss::before {
    content: "×";
}
- Entering/Leaving animations
 Regarding the animations used by default when a message enters/leavers the screen. Though you can easily override theses classes, it is probably better to define your own and set your instance of Toaster to use them see [configuration section)(#animations).
.d-toaster-initial { // sets the initial state
    opacity: 0;
    transition-property: opacity;
    transition-timing-function: linear;
}
.d-toaster-fadein {
    opacity: 1;
    transition-duration: 700ms
}
.d-toaster-fadeout {
    opacity: 0;
    transition-duration: 1000ms
}
Regarding the swipe-to-dismiss animation, it is controlled by:
.d-toaster-swipeout {
    animation-name: d-toaster-swipeout; /* you can reference here your own @keyframes */
    animation-timing-function: linear;
    animation-duration: 700ms;
    animation-fill-mode: both;
    /* omitting their -webkit- prefixed equivalent */
}
User interaction
Dismissal of a message
A user can dismiss a message either by clicking on the dismiss button, or swiping the message off the screen.
You can control this through the dismissible property.
You can call ToasterMessage.dismiss() anytime to dismiss a message - regardless of the fact that
the dismissible property was set to "on" or "off". The message will enter the hidden state and disappear from the screen.
This is the very same method called after a swipe is detected or the dismiss button is clicked.
You can also provide an animation class to accompany the dismissal, such as a slide-out animation.
var m = new ToasterMessage({message: "content of my message", dismissible: "off"});
...
m.dismiss("slide-out");
Element Events
| event name | dispatched | cancelable | bubbles | properties | 
|---|---|---|---|---|
| messageInserted | When a new message is inserted in the toaster | Yes | Yes | 
 | 
| messageExpired | When a message expires | Yes | Yes | 
 | 
| messageRemoved | When a message is removed | Yes | Yes | 
 | 
Enterprise Use
Accessibility
| type | status | comment | 
|---|---|---|
| Keyboard | none | The widget does not provide with any kind of interaction through the keyboard, besides | 
| Visual Formatting | partial | The message type information, which is conveyed only through color, disappears in high contrast mode. A few options are to be considered to solve this: the developer could use icons or explicitly indicate the type in the content of the message. | 
| Screen Reader | ok | Tested on JAWS 15 and iOS 6 VoiceOver. | 
Globalization
Nothing in particular here.
Security
This widget has no specific security concern. Refer to delite/Widget for general
security advice on this base class.
Browser Support
This widget supports all supported browsers without any degraded behavior.
