| OLD | NEW |
| (Empty) |
| 1 | |
| 2 | |
| 3 (function() { | |
| 4 | |
| 5 'use strict'; | |
| 6 | |
| 7 // this would be the only `paper-drawer-panel` in | |
| 8 // the whole app that can be in `dragging` state | |
| 9 var sharedPanel = null; | |
| 10 | |
| 11 function classNames(obj) { | |
| 12 var classes = []; | |
| 13 for (var key in obj) { | |
| 14 if (obj.hasOwnProperty(key) && obj[key]) { | |
| 15 classes.push(key); | |
| 16 } | |
| 17 } | |
| 18 | |
| 19 return classes.join(' '); | |
| 20 } | |
| 21 | |
| 22 Polymer({ | |
| 23 | |
| 24 is: 'paper-drawer-panel', | |
| 25 | |
| 26 /** | |
| 27 * Fired when the narrow layout changes. | |
| 28 * | |
| 29 * @event paper-responsive-change {{narrow: boolean}} detail - | |
| 30 * narrow: true if the panel is in narrow layout. | |
| 31 */ | |
| 32 | |
| 33 /** | |
| 34 * Fired when the selected panel changes. | |
| 35 * | |
| 36 * Listening for this event is an alternative to observing changes in the
`selected` attribute. | |
| 37 * This event is fired both when a panel is selected and deselected. | |
| 38 * The `isSelected` detail property contains the selection state. | |
| 39 * | |
| 40 * @event paper-select {{isSelected: boolean, item: Object}} detail - | |
| 41 * isSelected: True for selection and false for deselection. | |
| 42 * item: The panel that the event refers to. | |
| 43 */ | |
| 44 | |
| 45 properties: { | |
| 46 | |
| 47 /** | |
| 48 * The panel to be selected when `paper-drawer-panel` changes to narrow | |
| 49 * layout. | |
| 50 */ | |
| 51 defaultSelected: { | |
| 52 type: String, | |
| 53 value: 'main' | |
| 54 }, | |
| 55 | |
| 56 /** | |
| 57 * If true, swipe from the edge is disable. | |
| 58 */ | |
| 59 disableEdgeSwipe: { | |
| 60 type: Boolean, | |
| 61 value: false | |
| 62 }, | |
| 63 | |
| 64 /** | |
| 65 * If true, swipe to open/close the drawer is disabled. | |
| 66 */ | |
| 67 disableSwipe: { | |
| 68 type: Boolean, | |
| 69 value: false | |
| 70 }, | |
| 71 | |
| 72 /** | |
| 73 * Whether the user is dragging the drawer interactively. | |
| 74 */ | |
| 75 dragging: { | |
| 76 type: Boolean, | |
| 77 value: false | |
| 78 }, | |
| 79 | |
| 80 /** | |
| 81 * Width of the drawer panel. | |
| 82 */ | |
| 83 drawerWidth: { | |
| 84 type: String, | |
| 85 value: '256px' | |
| 86 }, | |
| 87 | |
| 88 /** | |
| 89 * How many pixels on the side of the screen are sensitive to edge | |
| 90 * swipes and peek. | |
| 91 */ | |
| 92 edgeSwipeSensitivity: { | |
| 93 type: Number, | |
| 94 value: 30 | |
| 95 }, | |
| 96 | |
| 97 /** | |
| 98 * If true, ignore `responsiveWidth` setting and force the narrow layout
. | |
| 99 */ | |
| 100 forceNarrow: { | |
| 101 type: Boolean, | |
| 102 value: false | |
| 103 }, | |
| 104 | |
| 105 /** | |
| 106 * Whether the browser has support for the transform CSS property. | |
| 107 */ | |
| 108 hasTransform: { | |
| 109 type: Boolean, | |
| 110 value: function() { | |
| 111 return 'transform' in this.style; | |
| 112 } | |
| 113 }, | |
| 114 | |
| 115 /** | |
| 116 * Whether the browser has support for the will-change CSS property. | |
| 117 */ | |
| 118 hasWillChange: { | |
| 119 type: Boolean, | |
| 120 value: function() { | |
| 121 return 'willChange' in this.style; | |
| 122 } | |
| 123 }, | |
| 124 | |
| 125 /** | |
| 126 * Returns true if the panel is in narrow layout. This is useful if you | |
| 127 * need to show/hide elements based on the layout. | |
| 128 */ | |
| 129 narrow: { | |
| 130 reflectToAttribute: true, | |
| 131 type: Boolean, | |
| 132 value: false, | |
| 133 notify: true | |
| 134 }, | |
| 135 | |
| 136 /** | |
| 137 * Whether the drawer is peeking out from the edge. | |
| 138 */ | |
| 139 peeking: { | |
| 140 type: Boolean, | |
| 141 value: false | |
| 142 }, | |
| 143 | |
| 144 /** | |
| 145 * Max-width when the panel changes to narrow layout. | |
| 146 */ | |
| 147 responsiveWidth: { | |
| 148 type: String, | |
| 149 value: '640px' | |
| 150 }, | |
| 151 | |
| 152 /** | |
| 153 * If true, position the drawer to the right. | |
| 154 */ | |
| 155 rightDrawer: { | |
| 156 type: Boolean, | |
| 157 value: false | |
| 158 }, | |
| 159 | |
| 160 /** | |
| 161 * The panel that is being selected. `drawer` for the drawer panel and | |
| 162 * `main` for the main panel. | |
| 163 */ | |
| 164 selected: { | |
| 165 reflectToAttribute: true, | |
| 166 type: String, | |
| 167 value: null | |
| 168 }, | |
| 169 | |
| 170 /** | |
| 171 * The attribute on elements that should toggle the drawer on tap, also
elements will | |
| 172 * automatically be hidden in wide layout. | |
| 173 */ | |
| 174 drawerToggleAttribute: { | |
| 175 type: String, | |
| 176 value: 'paper-drawer-toggle' | |
| 177 }, | |
| 178 | |
| 179 /** | |
| 180 * Whether the transition is enabled. | |
| 181 */ | |
| 182 transition: { | |
| 183 type: Boolean, | |
| 184 value: false | |
| 185 }, | |
| 186 | |
| 187 }, | |
| 188 | |
| 189 listeners: { | |
| 190 tap: '_onTap', | |
| 191 track: '_onTrack', | |
| 192 down: '_downHandler', | |
| 193 up: '_upHandler' | |
| 194 }, | |
| 195 | |
| 196 observers: [ | |
| 197 '_forceNarrowChanged(forceNarrow, defaultSelected)' | |
| 198 ], | |
| 199 | |
| 200 /** | |
| 201 * Toggles the panel open and closed. | |
| 202 * | |
| 203 * @method togglePanel | |
| 204 */ | |
| 205 togglePanel: function() { | |
| 206 if (this._isMainSelected()) { | |
| 207 this.openDrawer(); | |
| 208 } else { | |
| 209 this.closeDrawer(); | |
| 210 } | |
| 211 }, | |
| 212 | |
| 213 /** | |
| 214 * Opens the drawer. | |
| 215 * | |
| 216 * @method openDrawer | |
| 217 */ | |
| 218 openDrawer: function() { | |
| 219 this.selected = 'drawer'; | |
| 220 }, | |
| 221 | |
| 222 /** | |
| 223 * Closes the drawer. | |
| 224 * | |
| 225 * @method closeDrawer | |
| 226 */ | |
| 227 closeDrawer: function() { | |
| 228 this.selected = 'main'; | |
| 229 }, | |
| 230 | |
| 231 ready: function() { | |
| 232 // Avoid transition at the beginning e.g. page loads and enable | |
| 233 // transitions only after the element is rendered and ready. | |
| 234 this.transition = true; | |
| 235 }, | |
| 236 | |
| 237 _computeIronSelectorClass: function(narrow, transition, dragging, rightDra
wer) { | |
| 238 return classNames({ | |
| 239 dragging: dragging, | |
| 240 'narrow-layout': narrow, | |
| 241 'right-drawer': rightDrawer, | |
| 242 'left-drawer': !rightDrawer, | |
| 243 transition: transition | |
| 244 }); | |
| 245 }, | |
| 246 | |
| 247 _computeDrawerStyle: function(drawerWidth) { | |
| 248 return 'width:' + drawerWidth + ';'; | |
| 249 }, | |
| 250 | |
| 251 _computeMainStyle: function(narrow, rightDrawer, drawerWidth) { | |
| 252 var style = ''; | |
| 253 | |
| 254 style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';'; | |
| 255 | |
| 256 if (rightDrawer) { | |
| 257 style += 'right:' + (narrow ? '' : drawerWidth) + ';'; | |
| 258 } else { | |
| 259 style += 'right:;'; | |
| 260 } | |
| 261 | |
| 262 return style; | |
| 263 }, | |
| 264 | |
| 265 _computeMediaQuery: function(forceNarrow, responsiveWidth) { | |
| 266 return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')'; | |
| 267 }, | |
| 268 | |
| 269 _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) { | |
| 270 return !narrow || disableEdgeSwipe; | |
| 271 }, | |
| 272 | |
| 273 _onTrack: function(e) { | |
| 274 if (sharedPanel && this !== sharedPanel) { | |
| 275 return; | |
| 276 } | |
| 277 switch (e.detail.state) { | |
| 278 case 'start': | |
| 279 this._trackStart(e); | |
| 280 break; | |
| 281 case 'track': | |
| 282 this._trackX(e); | |
| 283 break; | |
| 284 case 'end': | |
| 285 this._trackEnd(e); | |
| 286 break; | |
| 287 } | |
| 288 | |
| 289 }, | |
| 290 | |
| 291 _responsiveChange: function(narrow) { | |
| 292 this.narrow = narrow; | |
| 293 | |
| 294 if (this.narrow) { | |
| 295 this.selected = this.defaultSelected; | |
| 296 } | |
| 297 | |
| 298 this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all'); | |
| 299 this.fire('paper-responsive-change', {narrow: this.narrow}); | |
| 300 }, | |
| 301 | |
| 302 _onQueryMatchesChanged: function(e) { | |
| 303 this._responsiveChange(e.detail.value); | |
| 304 }, | |
| 305 | |
| 306 _forceNarrowChanged: function() { | |
| 307 // set the narrow mode only if we reached the `responsiveWidth` | |
| 308 this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches); | |
| 309 }, | |
| 310 | |
| 311 _swipeAllowed: function() { | |
| 312 return this.narrow && !this.disableSwipe; | |
| 313 }, | |
| 314 | |
| 315 _isMainSelected: function() { | |
| 316 return this.selected === 'main'; | |
| 317 }, | |
| 318 | |
| 319 _startEdgePeek: function() { | |
| 320 this.width = this.$.drawer.offsetWidth; | |
| 321 this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ? | |
| 322 -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity)); | |
| 323 this.peeking = true; | |
| 324 }, | |
| 325 | |
| 326 _stopEdgePeek: function() { | |
| 327 if (this.peeking) { | |
| 328 this.peeking = false; | |
| 329 this._moveDrawer(null); | |
| 330 } | |
| 331 }, | |
| 332 | |
| 333 _downHandler: function(e) { | |
| 334 if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(e) &&
!sharedPanel) { | |
| 335 this._startEdgePeek(); | |
| 336 // grab this panel | |
| 337 sharedPanel = this; | |
| 338 } | |
| 339 }, | |
| 340 | |
| 341 _upHandler: function() { | |
| 342 this._stopEdgePeek(); | |
| 343 // release the panel | |
| 344 sharedPanel = null; | |
| 345 }, | |
| 346 | |
| 347 _onTap: function(e) { | |
| 348 var targetElement = Polymer.dom(e).localTarget; | |
| 349 var isTargetToggleElement = targetElement && | |
| 350 this.drawerToggleAttribute && | |
| 351 targetElement.hasAttribute(this.drawerToggleAttribute); | |
| 352 | |
| 353 if (isTargetToggleElement) { | |
| 354 this.togglePanel(); | |
| 355 } | |
| 356 }, | |
| 357 | |
| 358 _isEdgeTouch: function(e) { | |
| 359 var x = e.detail.x; | |
| 360 | |
| 361 return !this.disableEdgeSwipe && this._swipeAllowed() && | |
| 362 (this.rightDrawer ? | |
| 363 x >= this.offsetWidth - this.edgeSwipeSensitivity : | |
| 364 x <= this.edgeSwipeSensitivity); | |
| 365 }, | |
| 366 | |
| 367 _trackStart: function() { | |
| 368 if (this._swipeAllowed()) { | |
| 369 sharedPanel = this; | |
| 370 this.dragging = true; | |
| 371 | |
| 372 if (this._isMainSelected()) { | |
| 373 this.dragging = this.peeking || this._isEdgeTouch(event); | |
| 374 } | |
| 375 | |
| 376 if (this.dragging) { | |
| 377 this.width = this.$.drawer.offsetWidth; | |
| 378 this.transition = false; | |
| 379 } | |
| 380 } | |
| 381 }, | |
| 382 | |
| 383 _translateXForDeltaX: function(deltaX) { | |
| 384 var isMain = this._isMainSelected(); | |
| 385 | |
| 386 if (this.rightDrawer) { | |
| 387 return Math.max(0, isMain ? this.width + deltaX : deltaX); | |
| 388 } else { | |
| 389 return Math.min(0, isMain ? deltaX - this.width : deltaX); | |
| 390 } | |
| 391 }, | |
| 392 | |
| 393 _trackX: function(e) { | |
| 394 if (this.dragging) { | |
| 395 var dx = e.detail.dx; | |
| 396 | |
| 397 if (this.peeking) { | |
| 398 if (Math.abs(dx) <= this.edgeSwipeSensitivity) { | |
| 399 // Ignore trackx until we move past the edge peek. | |
| 400 return; | |
| 401 } | |
| 402 this.peeking = false; | |
| 403 } | |
| 404 | |
| 405 this._moveDrawer(this._translateXForDeltaX(dx)); | |
| 406 } | |
| 407 }, | |
| 408 | |
| 409 _trackEnd: function(e) { | |
| 410 if (this.dragging) { | |
| 411 var xDirection = e.detail.dx > 0; | |
| 412 | |
| 413 this.dragging = false; | |
| 414 this.transition = true; | |
| 415 sharedPanel = null; | |
| 416 this._moveDrawer(null); | |
| 417 | |
| 418 if (this.rightDrawer) { | |
| 419 this[xDirection ? 'closeDrawer' : 'openDrawer'](); | |
| 420 } else { | |
| 421 this[xDirection ? 'openDrawer' : 'closeDrawer'](); | |
| 422 } | |
| 423 } | |
| 424 }, | |
| 425 | |
| 426 _transformForTranslateX: function(translateX) { | |
| 427 if (translateX === null) { | |
| 428 return ''; | |
| 429 } | |
| 430 | |
| 431 return this.hasWillChange ? 'translateX(' + translateX + 'px)' : | |
| 432 'translate3d(' + translateX + 'px, 0, 0)'; | |
| 433 }, | |
| 434 | |
| 435 _moveDrawer: function(translateX) { | |
| 436 var s = this.$.drawer.style; | |
| 437 | |
| 438 if (this.hasTransform) { | |
| 439 s.transform = this._transformForTranslateX(translateX); | |
| 440 } else { | |
| 441 s.webkitTransform = this._transformForTranslateX(translateX); | |
| 442 } | |
| 443 } | |
| 444 | |
| 445 }); | |
| 446 | |
| 447 }()); | |
| 448 | |
| OLD | NEW |