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