5 // this would be the only `paper-drawer-panel` in
6 // the whole app that can be in `dragging` state
7 var sharedPanel = null;
9 function classNames(obj) {
11 for (var key in obj) {
12 if (obj.hasOwnProperty(key) && obj[key]) {
17 return classes.join(' ');
22 is: 'paper-drawer-panel',
25 * Fired when the narrow layout changes.
27 * @event paper-responsive-change {{narrow: boolean}} detail -
28 * narrow: true if the panel is in narrow layout.
32 * Fired when the a panel is selected.
34 * Listening for this event is an alternative to observing changes in the `selected` attribute.
35 * This event is fired both when a panel is selected.
37 * @event iron-select {{item: Object}} detail -
38 * item: The panel that the event refers to.
42 * Fired when a panel is deselected.
44 * Listening for this event is an alternative to observing changes in the `selected` attribute.
45 * This event is fired both when a panel is deselected.
47 * @event iron-deselect {{item: Object}} detail -
48 * item: The panel that the event refers to.
53 * The panel to be selected when `paper-drawer-panel` changes to narrow
62 * If true, swipe from the edge is disable.
70 * If true, swipe to open/close the drawer is disabled.
78 * Whether the user is dragging the drawer interactively.
88 * Width of the drawer panel.
96 * How many pixels on the side of the screen are sensitive to edge
99 edgeSwipeSensitivity: {
105 * If true, ignore `responsiveWidth` setting and force the narrow layout.
113 * Whether the browser has support for the transform CSS property.
118 return 'transform' in this.style;
123 * Whether the browser has support for the will-change CSS property.
128 return 'willChange' in this.style;
133 * Returns true if the panel is in narrow layout. This is useful if you
134 * need to show/hide elements based on the layout.
137 reflectToAttribute: true,
145 * Whether the drawer is peeking out from the edge.
155 * Max-width when the panel changes to narrow layout.
163 * If true, position the drawer to the right.
171 * The panel that is being selected. `drawer` for the drawer panel and
172 * `main` for the main panel.
175 reflectToAttribute: true,
182 * The attribute on elements that should toggle the drawer on tap, also elements will
183 * automatically be hidden in wide layout.
185 drawerToggleAttribute: {
187 value: 'paper-drawer-toggle'
191 * Whether the transition is enabled.
203 down: '_downHandler',
208 '_forceNarrowChanged(forceNarrow, defaultSelected)'
212 * Toggles the panel open and closed.
214 * @method togglePanel
216 togglePanel: function() {
217 if (this._isMainSelected()) {
229 openDrawer: function() {
230 this.selected = 'drawer';
236 * @method closeDrawer
238 closeDrawer: function() {
239 this.selected = 'main';
243 // Avoid transition at the beginning e.g. page loads and enable
244 // transitions only after the element is rendered and ready.
245 this.transition = true;
248 _computeIronSelectorClass: function(narrow, transition, dragging, rightDrawer, peeking) {
251 'narrow-layout': narrow,
252 'right-drawer': rightDrawer,
253 'left-drawer': !rightDrawer,
254 transition: transition,
259 _computeDrawerStyle: function(drawerWidth) {
260 return 'width:' + drawerWidth + ';';
263 _computeMainStyle: function(narrow, rightDrawer, drawerWidth) {
266 style += 'left:' + ((narrow || rightDrawer) ? '0' : drawerWidth) + ';';
269 style += 'right:' + (narrow ? '' : drawerWidth) + ';';
275 _computeMediaQuery: function(forceNarrow, responsiveWidth) {
276 return forceNarrow ? '' : '(max-width: ' + responsiveWidth + ')';
279 _computeSwipeOverlayHidden: function(narrow, disableEdgeSwipe) {
280 return !narrow || disableEdgeSwipe;
283 _onTrack: function(event) {
284 if (sharedPanel && this !== sharedPanel) {
287 switch (event.detail.state) {
289 this._trackStart(event);
295 this._trackEnd(event);
301 _responsiveChange: function(narrow) {
302 this._setNarrow(narrow);
305 this.selected = this.defaultSelected;
308 this.setScrollDirection(this._swipeAllowed() ? 'y' : 'all');
309 this.fire('paper-responsive-change', {narrow: this.narrow});
312 _onQueryMatchesChanged: function(event) {
313 this._responsiveChange(event.detail.value);
316 _forceNarrowChanged: function() {
317 // set the narrow mode only if we reached the `responsiveWidth`
318 this._responsiveChange(this.forceNarrow || this.$.mq.queryMatches);
321 _swipeAllowed: function() {
322 return this.narrow && !this.disableSwipe;
325 _isMainSelected: function() {
326 return this.selected === 'main';
329 _startEdgePeek: function() {
330 this.width = this.$.drawer.offsetWidth;
331 this._moveDrawer(this._translateXForDeltaX(this.rightDrawer ?
332 -this.edgeSwipeSensitivity : this.edgeSwipeSensitivity));
333 this._setPeeking(true);
336 _stopEdgePeek: function() {
338 this._setPeeking(false);
339 this._moveDrawer(null);
343 _downHandler: function(event) {
344 if (!this.dragging && this._isMainSelected() && this._isEdgeTouch(event) && !sharedPanel) {
345 this._startEdgePeek();
347 event.preventDefault();
353 _upHandler: function() {
354 this._stopEdgePeek();
359 _onTap: function(event) {
360 var targetElement = Polymer.dom(event).localTarget;
361 var isTargetToggleElement = targetElement &&
362 this.drawerToggleAttribute &&
363 targetElement.hasAttribute(this.drawerToggleAttribute);
365 if (isTargetToggleElement) {
370 _isEdgeTouch: function(event) {
371 var x = event.detail.x;
373 return !this.disableEdgeSwipe && this._swipeAllowed() &&
375 x >= this.offsetWidth - this.edgeSwipeSensitivity :
376 x <= this.edgeSwipeSensitivity);
379 _trackStart: function(event) {
380 if (this._swipeAllowed()) {
382 this._setDragging(true);
384 if (this._isMainSelected()) {
385 this._setDragging(this.peeking || this._isEdgeTouch(event));
389 this.width = this.$.drawer.offsetWidth;
390 this.transition = false;
395 _translateXForDeltaX: function(deltaX) {
396 var isMain = this._isMainSelected();
398 if (this.rightDrawer) {
399 return Math.max(0, isMain ? this.width + deltaX : deltaX);
401 return Math.min(0, isMain ? deltaX - this.width : deltaX);
405 _trackX: function(event) {
407 var dx = event.detail.dx;
410 if (Math.abs(dx) <= this.edgeSwipeSensitivity) {
411 // Ignore trackx until we move past the edge peek.
414 this._setPeeking(false);
417 this._moveDrawer(this._translateXForDeltaX(dx));
421 _trackEnd: function(event) {
423 var xDirection = event.detail.dx > 0;
425 this._setDragging(false);
426 this.transition = true;
428 this._moveDrawer(null);
430 if (this.rightDrawer) {
431 this[xDirection ? 'closeDrawer' : 'openDrawer']();
433 this[xDirection ? 'openDrawer' : 'closeDrawer']();
438 _transformForTranslateX: function(translateX) {
439 if (translateX === null) {
443 return this.hasWillChange ? 'translateX(' + translateX + 'px)' :
444 'translate3d(' + translateX + 'px, 0, 0)';
447 _moveDrawer: function(translateX) {
448 this.transform(this._transformForTranslateX(translateX), this.$.drawer);