Home | History | Annotate | Download | only in paper-toast
      1 <!--
      2 @license
      3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
      4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7 Code distributed by Google as part of the polymer project is also
      8 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
      9 -->
     10 
     11 <link rel="import" href="../polymer/polymer.html">
     12 <link rel="import" href="../iron-a11y-announcer/iron-a11y-announcer.html">
     13 <link rel="import" href="../iron-overlay-behavior/iron-overlay-behavior.html">
     14 
     15 <!--
     16 Material design: [Snackbards & toasts](https://www.google.com/design/spec/components/snackbars-toasts.html)
     17 
     18 `paper-toast` provides a subtle notification toast. Only one `paper-toast` will
     19 be visible on screen.
     20 
     21 Use `opened` to show the toast:
     22 
     23 Example:
     24 
     25     <paper-toast text="Hello world!" opened></paper-toast>
     26 
     27 Also `open()` or `show()` can be used to show the toast:
     28 
     29 Example:
     30 
     31     <paper-button on-click="openToast">Open Toast</paper-button>
     32     <paper-toast id="toast" text="Hello world!"></paper-toast>
     33 
     34     ...
     35 
     36     openToast: function() {
     37       this.$.toast.open();
     38     }
     39 
     40 Set `duration` to 0, a negative number or Infinity to persist the toast on screen:
     41 
     42 Example:
     43 
     44     <paper-toast text="Terms and conditions" opened duration="0">
     45       <a href="#">Show more</a>
     46     </paper-toast>
     47 
     48 
     49 ### Styling
     50 The following custom properties and mixins are available for styling:
     51 
     52 Custom property | Description | Default
     53 ----------------|-------------|----------
     54 `--paper-toast-background-color` | The paper-toast background-color | `#323232`
     55 `--paper-toast-color` | The paper-toast color | `#f1f1f1`
     56 
     57 This element applies the mixin `--paper-font-common-base` but does not import `paper-styles/typography.html`.
     58 In order to apply the `Roboto` font to this element, make sure you've imported `paper-styles/typography.html`.
     59 
     60 @group Paper Elements
     61 @element paper-toast
     62 @demo demo/index.html
     63 @hero hero.svg
     64 -->
     65 
     66 <dom-module id="paper-toast">
     67   <template>
     68     <style>
     69       :host {
     70         display: block;
     71         position: fixed;
     72         background-color: var(--paper-toast-background-color, #323232);
     73         color: var(--paper-toast-color, #f1f1f1);
     74         min-height: 48px;
     75         min-width: 288px;
     76         padding: 16px 24px;
     77         box-sizing: border-box;
     78         box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
     79         border-radius: 2px;
     80         margin: 12px;
     81         font-size: 14px;
     82         cursor: default;
     83         -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
     84         transition: transform 0.3s, opacity 0.3s;
     85         opacity: 0;
     86         -webkit-transform: translateY(100px);
     87         transform: translateY(100px);
     88         @apply(--paper-font-common-base);
     89       }
     90 
     91       :host(.capsule) {
     92         border-radius: 24px;
     93       }
     94 
     95       :host(.fit-bottom) {
     96         width: 100%;
     97         min-width: 0;
     98         border-radius: 0;
     99         margin: 0;
    100       }
    101 
    102       :host(.paper-toast-open) {
    103         opacity: 1;
    104         -webkit-transform: translateY(0px);
    105         transform: translateY(0px);
    106       }
    107     </style>
    108 
    109     <span id="label">{{text}}</span>
    110     <content></content>
    111   </template>
    112 
    113   <script>
    114     (function() {
    115       // Keeps track of the toast currently opened.
    116       var currentToast = null;
    117 
    118       Polymer({
    119         is: 'paper-toast',
    120 
    121         behaviors: [
    122           Polymer.IronOverlayBehavior
    123         ],
    124 
    125         properties: {
    126           /**
    127            * The element to fit `this` into.
    128            * Overridden from `Polymer.IronFitBehavior`.
    129            */
    130           fitInto: {
    131             type: Object,
    132             value: window,
    133             observer: '_onFitIntoChanged'
    134           },
    135 
    136           /**
    137            * The orientation against which to align the dropdown content
    138            * horizontally relative to `positionTarget`.
    139            * Overridden from `Polymer.IronFitBehavior`.
    140            */
    141           horizontalAlign: {
    142             type: String,
    143             value: 'left'
    144           },
    145 
    146           /**
    147            * The orientation against which to align the dropdown content
    148            * vertically relative to `positionTarget`.
    149            * Overridden from `Polymer.IronFitBehavior`.
    150            */
    151           verticalAlign: {
    152             type: String,
    153             value: 'bottom'
    154           },
    155 
    156           /**
    157            * The duration in milliseconds to show the toast.
    158            * Set to `0`, a negative number, or `Infinity`, to disable the
    159            * toast auto-closing.
    160            */
    161           duration: {
    162             type: Number,
    163             value: 3000
    164           },
    165 
    166           /**
    167            * The text to display in the toast.
    168            */
    169           text: {
    170             type: String,
    171             value: ''
    172           },
    173 
    174           /**
    175            * Overridden from `IronOverlayBehavior`.
    176            * Set to false to enable closing of the toast by clicking outside it.
    177            */
    178           noCancelOnOutsideClick: {
    179             type: Boolean,
    180             value: true
    181           },
    182 
    183           /**
    184            * Overridden from `IronOverlayBehavior`.
    185            * Set to true to disable auto-focusing the toast or child nodes with
    186            * the `autofocus` attribute` when the overlay is opened.
    187            */
    188           noAutoFocus: {
    189             type: Boolean,
    190             value: true
    191           }
    192         },
    193 
    194         listeners: {
    195           'transitionend': '__onTransitionEnd'
    196         },
    197 
    198         /**
    199          * Read-only. Deprecated. Use `opened` from `IronOverlayBehavior`.
    200          * @property visible
    201          * @deprecated
    202          */
    203         get visible() {
    204           Polymer.Base._warn('`visible` is deprecated, use `opened` instead');
    205           return this.opened;
    206         },
    207 
    208         /**
    209          * Read-only. Can auto-close if duration is a positive finite number.
    210          * @property _canAutoClose
    211          */
    212         get _canAutoClose() {
    213           return this.duration > 0 && this.duration !== Infinity;
    214         },
    215 
    216         created: function() {
    217           this._autoClose = null;
    218           Polymer.IronA11yAnnouncer.requestAvailability();
    219         },
    220 
    221         /**
    222          * Show the toast. Without arguments, this is the same as `open()` from `IronOverlayBehavior`.
    223          * @param {(Object|string)=} properties Properties to be set before opening the toast.
    224          * e.g. `toast.show('hello')` or `toast.show({text: 'hello', duration: 3000})`
    225          */
    226         show: function(properties) {
    227           if (typeof properties == 'string') {
    228             properties = { text: properties };
    229           }
    230           for (var property in properties) {
    231             if (property.indexOf('_') === 0) {
    232               Polymer.Base._warn('The property "' + property + '" is private and was not set.');
    233             } else if (property in this) {
    234               this[property] = properties[property];
    235             } else {
    236               Polymer.Base._warn('The property "' + property + '" is not valid.');
    237             }
    238           }
    239           this.open();
    240         },
    241 
    242         /**
    243          * Hide the toast. Same as `close()` from `IronOverlayBehavior`.
    244          */
    245         hide: function() {
    246           this.close();
    247         },
    248 
    249         /**
    250          * Called on transitions of the toast, indicating a finished animation
    251          * @private
    252          */
    253         __onTransitionEnd: function(e) {
    254           // there are different transitions that are happening when opening and
    255           // closing the toast. The last one so far is for `opacity`.
    256           // This marks the end of the transition, so we check for this to determine if this
    257           // is the correct event.
    258           if (e && e.target === this && e.propertyName === 'opacity') {
    259             if (this.opened) {
    260               this._finishRenderOpened();
    261             } else {
    262               this._finishRenderClosed();
    263             }
    264           }
    265         },
    266 
    267         /**
    268          * Overridden from `IronOverlayBehavior`.
    269          * Called when the value of `opened` changes.
    270          */
    271         _openedChanged: function() {
    272           if (this._autoClose !== null) {
    273             this.cancelAsync(this._autoClose);
    274             this._autoClose = null;
    275           }
    276           if (this.opened) {
    277             if (currentToast && currentToast !== this) {
    278               currentToast.close();
    279             }
    280             currentToast = this;
    281             this.fire('iron-announce', {
    282               text: this.text
    283             });
    284             if (this._canAutoClose) {
    285               this._autoClose = this.async(this.close, this.duration);
    286             }
    287           } else if (currentToast === this) {
    288             currentToast = null;
    289           }
    290           Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments);
    291         },
    292 
    293         /**
    294          * Overridden from `IronOverlayBehavior`.
    295          */
    296         _renderOpened: function() {
    297           this.classList.add('paper-toast-open');
    298         },
    299 
    300         /**
    301          * Overridden from `IronOverlayBehavior`.
    302          */
    303         _renderClosed: function() {
    304           this.classList.remove('paper-toast-open');
    305         },
    306 
    307         /**
    308          * @private
    309          */
    310         _onFitIntoChanged: function(fitInto) {
    311           this.positionTarget = fitInto;
    312         }
    313 
    314         /**
    315          * Fired when `paper-toast` is opened.
    316          *
    317          * @event 'iron-announce'
    318          * @param {{text: string}} detail Contains text that will be announced.
    319          */
    320       });
    321     })();
    322   </script>
    323 </dom-module>
    324