7 // this would be the only `paper-drawer-panel` in
8 // the whole app that can be in `dragging` state
9 var sharedPanel = null;
11 function classNames(obj) {
13 for (var key in obj) {
14 if (obj.hasOwnProperty(key) && obj[key]) {
19 return classes.join(' ');
24 is: 'paper-drawer-panel',
27 * Fired when the narrow layout changes.
29 * @event paper-responsive-change {{narrow: boolean}} detail -
30 * narrow: true if the panel is in narrow layout.
34 * Fired when the a panel is selected.
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.
39 * @event iron-select {{item: Object}} detail -
40 * item: The panel that the event refers to.
44 * Fired when a panel is deselected.
46 * Listening for this event is an alternative to observing changes in the `selected` attribute.
47 * This event is fired both when a panel is deselected.
49 * @event iron-deselect {{item: Object}} detail -
50 * item: The panel that the event refers to.
55 * The panel to be selected when `paper-drawer-panel` changes to narrow
64 * If true, swipe from the edge is disable.
72 * If true, swipe to open/close the drawer is disabled.
80 * Whether the user is dragging the drawer interactively.
90 * Width of the drawer panel.
98 * How many pixels on the side of the screen are sensitive to edge
101 edgeSwipeSensitivity: {
107 * If true, ignore `responsiveWidth` setting and force the narrow layout.
115 * Whether the browser has support for the transform CSS property.
120 return 'transform' in this.style;
125 * Whether the browser has support for the will-change CSS property.
130 return 'willChange' in this.style;
135 * Returns true if the panel is in narrow layout. This is useful if you
136 * need to show/hide elements based on the layout.
139 reflectToAttribute: true,
147 * Whether the drawer is peeking out from the edge.
157 * Max-width when the panel changes to narrow layout.
165 * If true, position the drawer to the right.
173 * The panel that is being selected. `drawer` for the drawer panel and
174 * `main` for the main panel.
177 reflectToAttribute: true,
184 * The attribute on elements that should toggle the drawer on tap, also elements will
185 * automatically be hidden in wide layout.
187 drawerToggleAttribute: {
189 value: 'paper-drawer-toggle'
193 * Whether the transition is enabled.
205 down: '_downHandler',
210 '_forceNarrowChanged(forceNarrow, defaultSelected)'
214 * Toggles the panel open and closed.
216 * @method togglePanel
218 togglePanel: function() {
219 if (this._isMainSelected()) {
231 openDrawer: function() {
232 this.selected = 'drawer';
238 * @method closeDrawer
240 closeDrawer: function() {
241 this.selected = 'main';
245 // Avoid transition at the beginning e.g. page loads and enable
246 // transitions only after the element is rendered and ready.
247 this.transition = true;
250 _computeIronSelectorClass: function(narrow, transition, dragging, rightDrawer, peeking) {
253 'narrow-layout': narrow,
254 'right-drawer': rightDrawer,
255 'left-drawer': !rightDrawer,
256 transition: transition,
261 _computeDrawerStyle: function(drawerWidth) {
262 return 'width:' + drawerWidth + ';';
265 _computeMainStyle: function(narrow, rightDrawer, drawerWidth) {
268 style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';';
271 style += 'right:' + (narrow ? '' : drawerWidth) + ';';
277 _computeMediaQuery: function(forceNarrow, responsiveWidth) {
278 return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')';
281 _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) {
282 return !narrow || disableEdgeSwipe;
285 _onTrack: function(event) {
286 if (sharedPanel && this !== sharedPanel) {
289 switch (event.detail.state) {
291 this._trackStart(event);
297 this._trackEnd(event);
303 _responsiveChange: function(narrow) {
304 this._setNarrow(narrow);
307 this.selected = this.defaultSelected;
310 this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all');
311 this.fire('paper-responsive-change', {narrow: this.narrow});
314 _onQueryMatchesChanged: function(event) {
315 this._responsiveChange(event.detail.value);
318 _forceNarrowChanged: function() {
319 // set the narrow mode only if we reached the `responsiveWidth`
320 this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches);
323 _swipeAllowed: function() {
324 return this.narrow && !this.disableSwipe;
327 _isMainSelected: function() {
328 return this.selected === 'main';
331 _startEdgePeek: function() {
332 this.width = this.$.drawer.offsetWidth;
333 this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ?
334 -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity));
335 this._setPeeking(true);
338 _stopEdgePeek: function() {
340 this._setPeeking(false);
341 this._moveDrawer(null);
345 _downHandler: function(event) {
346 if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(event) && !sharedPanel) {
347 this._startEdgePeek();
349 event.preventDefault();
355 _upHandler: function() {
356 this._stopEdgePeek();
361 _onTap: function(event) {
362 var targetElement = Polymer.dom(event).localTarget;
363 var isTargetToggleElement = targetElement &&
364 this.drawerToggleAttribute &&
365 targetElement.hasAttribute(this.drawerToggleAttribute);
367 if (isTargetToggleElement) {
372 _isEdgeTouch: function(event) {
373 var x = event.detail.x;
375 return !this.disableEdgeSwipe && this._swipeAllowed() &&
377 x >= this.offsetWidth - this.edgeSwipeSensitivity :
378 x <= this.edgeSwipeSensitivity);
381 _trackStart: function(event) {
382 if (this._swipeAllowed()) {
384 this._setDragging(true);
386 if (this._isMainSelected()) {
387 this._setDragging(this.peeking || this._isEdgeTouch(event));
391 this.width = this.$.drawer.offsetWidth;
392 this.transition = false;
397 _translateXForDeltaX: function(deltaX) {
398 var isMain = this._isMainSelected();
400 if (this.rightDrawer) {
401 return Math.max(0, isMain ? this.width + deltaX : deltaX);
403 return Math.min(0, isMain ? deltaX - this.width : deltaX);
407 _trackX: function(event) {
409 var dx = event.detail.dx;
412 if (Math.abs(dx) <= this.edgeSwipeSensitivity) {
413 // Ignore trackx until we move past the edge peek.
416 this._setPeeking(false);
419 this._moveDrawer(this._translateXForDeltaX(dx));
423 _trackEnd: function(event) {
425 var xDirection = event.detail.dx > 0;
427 this._setDragging(false);
428 this.transition = true;
430 this._moveDrawer(null);
432 if (this.rightDrawer) {
433 this[xDirection ? 'closeDrawer' : 'openDrawer']();
435 this[xDirection ? 'openDrawer' : 'closeDrawer']();
440 _transformForTranslateX: function(translateX) {
441 if (translateX === null) {
445 return this.hasWillChange ? 'translateX(' + translateX + 'px)' :
446 'translate3d(' + translateX + 'px, 0, 0)';
449 _moveDrawer: function(translateX) {
450 this.transform(this._transformForTranslateX(translateX), this.$.drawer);