<!– @license Copyright © 2015 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at polymer.github.io/LICENSE.txt The complete set of authors may be found at polymer.github.io/AUTHORS.txt The complete set of contributors may be found at polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at polymer.github.io/PATENTS.txt –>

<link rel=“import” href=“../../polymer/polymer.html”> <link rel=“import” href=“../../iron-media-query/iron-media-query.html”> <link rel=“import” href=“../../iron-resizable-behavior/iron-resizable-behavior.html”> <link rel=“import” href=“../app-drawer/app-drawer.html”>

<!– app-drawer-layout is a wrapper element that positions an app-drawer and other content. When the viewport width is smaller than `responsiveWidth`, this element changes to narrow layout. In narrow layout, the drawer will be stacked on top of the main content. The drawer will slide in/out to hide/reveal the main content.

By default the drawer is aligned to the start, which is left in LTR layouts:

“`html <app-drawer-layout>

<app-drawer>
  drawer content
</app-drawer>
<div>
  main content
</div>

</app-drawer-layout> “`

Align the drawer at the end:

“`html <app-drawer-layout>

<app-drawer align="end">
   drawer content
</app-drawer>
<div>
  main content
</div>

</app-drawer-layout> “`

With an app-header-layout:

“`html <app-drawer-layout>

<app-drawer>
  drawer-content
</app-drawer>
<app-header-layout>
  <app-header>
    <app-toolbar>
      <div main-title>App name</div>
    </app-toolbar>
  </app-header>

  main content

</app-header-layout>

</app-drawer-layout> “`

Add the `drawer-toggle` attribute to elements inside `app-drawer-layout` that toggle the drawer on tap events:

“`html <app-drawer-layout>

<app-drawer>
  drawer-content
</app-drawer>
<app-header-layout>
  <app-header>
    <app-toolbar>
      <paper-icon-button icon="menu" drawer-toggle></paper-icon-button>
      <div main-title>App name</div>
    </app-toolbar>
  </app-header>

  main content

</app-header-layout>

</app-drawer-layout> “`

Add the `fullbleed` attribute to app-drawer-layout to make it fit the size of its container:

“`html <app-drawer-layout fullbleed>

<app-drawer>
   drawer content
</app-drawer>
<div>
  main content
</div>

</app-drawer-layout> “`

### Styling

Custom property | Description | Default —————————————–|————————————–|——— `–app-drawer-layout-content-transition` | Transition for the content container | none

@group App Elements @element app-drawer-layout @demo app-drawer-layout/demo/simple-drawer.html Simple Demo @demo app-drawer-layout/demo/two-drawers.html Two drawers –>

<dom-module id=“app-drawer-layout”>

<template>
  <style>
    :host {
      display: block;
    }

    :host([fullbleed]) {
      @apply(--layout-fit);
    }

    #contentContainer {
      position: relative;

      height: 100%;

      transition: var(--app-drawer-layout-content-transition, none);
    }

    #contentContainer:not(.narrow) > ::content [drawer-toggle] {
      display: none;
    }
  </style>

  <div id="contentContainer">
    <content select=":not(app-drawer)"></content>
  </div>

  <content id="drawerContent" select="app-drawer"></content>

  <iron-media-query
      query="[[_computeMediaQuery(forceNarrow, responsiveWidth)]]"
      on-query-matches-changed="_onQueryMatchesChanged"></iron-media-query>
</template>

<script>
  Polymer({
    is: 'app-drawer-layout',

    behaviors: [
      Polymer.IronResizableBehavior
    ],

    properties: {
      /**
       * If true, ignore `responsiveWidth` setting and force the narrow layout.
       */
      forceNarrow: {
        type: Boolean,
        value: false
      },

      /**
       * If the viewport's width is smaller than this value, the panel will change to narrow
       * layout. In the mode the drawer will be closed.
       */
      responsiveWidth: {
        type: String,
        value: '640px'
      },

      /**
       * Returns true if it is in narrow layout. This is useful if you need to show/hide
       * elements based on the layout.
       */
      narrow: {
        type: Boolean,
        readOnly: true,
        notify: true
      },

      /**
       * If true, the drawer will initially be opened when in narrow layout mode.
       */
      openedWhenNarrow: {
        type: Boolean,
        value: false
      }
    },

    listeners: {
      'tap': '_tapHandler',
      'app-drawer-attached': '_resetDrawerState',
      'app-drawer-reset-layout': 'resetLayout',
      'iron-resize': 'resetLayout'
    },

    observers: [
      'resetLayout(narrow, isAttached)',
      '_narrowChanged(narrow, isAttached)'
    ],

    /**
     * A reference to the app-drawer element.
     *
     * @property drawer
     */
    get drawer() {
      return Polymer.dom(this.$.drawerContent).getDistributedNodes()[0];
    },

    _tapHandler: function(e) {
      var target = Polymer.dom(e).localTarget;
      if (target && target.hasAttribute('drawer-toggle')) {
        var drawer = this.drawer;
        if (drawer && !drawer.persistent) {
          drawer.toggle();
        }
      }
    },

    resetLayout: function() {
      this.debounce('_resetLayout', function() {
        var drawer = this.drawer;
        var contentContainer = this.$.contentContainer;

        if (this.narrow || !drawer) {
          contentContainer.style.marginLeft = '';
          contentContainer.style.marginRight = '';
        } else {
          var drawerWidth = drawer.getWidth();
          if (drawer.position == 'right') {
            contentContainer.style.marginLeft = '';
            contentContainer.style.marginRight = drawerWidth + 'px';
          } else {
            contentContainer.style.marginLeft = drawerWidth + 'px';
            contentContainer.style.marginRight = '';
          }
        }
      });
    },

    _resetDrawerState: function() {
      this.debounce('_resetDrawerState', function() {
        var drawer = this.drawer;
        if (!drawer) {
          return;
        }

        if (this.narrow) {
          drawer.opened = this.openedWhenNarrow;
          drawer.persistent = false;
        } else {
          drawer.opened = drawer.persistent = true;
        }
      });
    },

    _narrowChanged: function(narrow) {
      this.toggleClass('narrow', narrow, this.$.contentContainer);
      this._resetDrawerState();
      this.notifyResize();
    },

    _onQueryMatchesChanged: function(event) {
      this._setNarrow(event.detail.value);
    },

    _computeMediaQuery: function(forceNarrow, responsiveWidth) {
      return forceNarrow ? '(min-width: 0px)' : '(max-width: ' + responsiveWidth + ')';
    }
  });
</script>

</dom-module>