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-menu-behavior/iron-menu-behavior.html"> 13 <link rel="import" href="../iron-behaviors/iron-control-state.html"> 14 <link rel="import" href="../iron-collapse/iron-collapse.html"> 15 <link rel="import" href="../iron-flex-layout/iron-flex-layout.html"> 16 <link rel="import" href="../paper-styles/default-theme.html"> 17 <link rel="import" href="../paper-styles/color.html"> 18 <link rel="import" href="paper-menu-shared-styles.html"> 19 20 <!-- 21 `<paper-submenu>` is a nested menu inside of a parent `<paper-menu>`. It 22 consists of a trigger that expands or collapses another `<paper-menu>`: 23 24 <paper-menu> 25 <paper-submenu> 26 <paper-item class="menu-trigger">Topics</paper-item> 27 <paper-menu class="menu-content"> 28 <paper-item>Topic 1</paper-item> 29 <paper-item>Topic 2</paper-item> 30 <paper-item>Topic 3</paper-item> 31 </paper-menu> 32 </paper-submenu> 33 <paper-submenu> 34 <paper-item class="menu-trigger">Faves</paper-item> 35 <paper-menu class="menu-content"> 36 <paper-item>Fave 1</paper-item> 37 <paper-item>Fave 2</paper-item> 38 </paper-menu> 39 </paper-submenu> 40 <paper-submenu disabled> 41 <paper-item class="menu-trigger">Unavailable</paper-item> 42 <paper-menu class="menu-content"> 43 <paper-item>Disabled 1</paper-item> 44 <paper-item>Disabled 2</paper-item> 45 </paper-menu> 46 </paper-submenu> 47 </paper-menu> 48 49 Just like in `<paper-menu>`, the focused item is highlighted, and the selected 50 item has bolded text. Please see the `<paper-menu>` docs for which attributes 51 (such as `multi` and `selected`), and styling options are available for the 52 `menu-content` menu. 53 54 @group Paper Elements 55 @element paper-submenu 56 @hero hero.svg 57 @demo demo/index.html 58 --> 59 60 <dom-module id="paper-submenu"> 61 <template> 62 <style include="paper-menu-shared-styles"></style> 63 64 <div class="selectable-content" on-tap="_onTap"> 65 <content id="trigger" select=".menu-trigger"></content> 66 </div> 67 <iron-collapse id="collapse" opened="{{opened}}"> 68 <content id="content" select=".menu-content"></content> 69 </iron-collapse> 70 </template> 71 72 <script> 73 74 (function() { 75 76 Polymer({ 77 78 is: 'paper-submenu', 79 80 properties: { 81 /** 82 * Fired when the submenu is opened. 83 * 84 * @event paper-submenu-open 85 */ 86 87 /** 88 * Fired when the submenu is closed. 89 * 90 * @event paper-submenu-close 91 */ 92 93 /** 94 * Set opened to true to show the collapse element and to false to hide it. 95 * 96 * @attribute opened 97 */ 98 opened: { 99 type: Boolean, 100 value: false, 101 notify: true, 102 observer: '_openedChanged' 103 } 104 }, 105 106 behaviors: [ 107 Polymer.IronControlState 108 ], 109 110 listeners: { 111 'focus': '_onFocus' 112 }, 113 114 get __parent() { 115 return Polymer.dom(this).parentNode; 116 }, 117 118 get __trigger() { 119 return Polymer.dom(this.$.trigger).getDistributedNodes()[0]; 120 }, 121 122 get __content() { 123 return Polymer.dom(this.$.content).getDistributedNodes()[0]; 124 }, 125 126 attached: function() { 127 this.listen(this.__parent, 'iron-activate', '_onParentIronActivate'); 128 }, 129 130 dettached: function() { 131 this.unlisten(this.__parent, 'iron-activate', '_onParentIronActivate'); 132 }, 133 134 /** 135 * Expand the submenu content. 136 */ 137 open: function() { 138 if (!this.disabled && !this._active) { 139 this.$.collapse.show(); 140 this._active = true; 141 this.__trigger && this.__trigger.classList.add('iron-selected'); 142 this.__content && this.__content.focus(); 143 } 144 }, 145 146 /** 147 * Collapse the submenu content. 148 */ 149 close: function() { 150 if (this._active) { 151 this.$.collapse.hide(); 152 this._active = false; 153 this.__trigger && this.__trigger.classList.remove('iron-selected'); 154 } 155 }, 156 157 /** 158 * Toggle the submenu. 159 */ 160 toggle: function() { 161 if (this._active) { 162 this.close(); 163 } else { 164 this.open(); 165 } 166 }, 167 168 /** 169 * A handler that is called when the trigger is tapped. 170 */ 171 _onTap: function(e) { 172 if (!this.disabled) { 173 this.toggle(); 174 } 175 }, 176 177 /** 178 * Toggles the submenu content when the trigger is tapped. 179 */ 180 _openedChanged: function(opened, oldOpened) { 181 if (opened) { 182 this.fire('paper-submenu-open'); 183 } else if (oldOpened != null) { 184 this.fire('paper-submenu-close'); 185 } 186 }, 187 188 /** 189 * A handler that is called when `iron-activate` is fired. 190 * 191 * @param {CustomEvent} event An `iron-activate` event. 192 */ 193 _onParentIronActivate: function(event) { 194 var parent = this.__parent; 195 if (Polymer.dom(event).localTarget === parent) { 196 // The activated item can either be this submenu, in which case it 197 // should be expanded, or any of the other sibling submenus, in which 198 // case this submenu should be collapsed. 199 if (event.detail.item !== this && !parent.multi) { 200 this.close(); 201 } 202 } 203 }, 204 205 /** 206 * If the dropdown is open when disabled becomes true, close the 207 * dropdown. 208 * 209 * @param {boolean} disabled True if disabled, otherwise false. 210 */ 211 _disabledChanged: function(disabled) { 212 Polymer.IronControlState._disabledChanged.apply(this, arguments); 213 if (disabled && this._active) { 214 this.close(); 215 } 216 }, 217 218 /** 219 * Handler that is called when the menu receives focus. 220 * 221 * @param {FocusEvent} event A focus event. 222 */ 223 _onFocus: function(event) { 224 this.__trigger && this.__trigger.focus(); 225 } 226 227 }); 228 229 })(); 230 </script> 231 </dom-module> 232