| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | |
| 3 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | |
| 4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | |
| 5 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | |
| 6 Code distributed by Google as part of the polymer project is also | |
| 7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | |
| 8 --> | |
| 9 | |
| 10 <link rel="import" href="../polymer/polymer.html"> | |
| 11 <link rel="import" href="../paper-styles/paper-styles.html"> | |
| 12 | |
| 13 <!-- | |
| 14 `paper-toolbar` is a horizontal bar containing items that can be used for | |
| 15 label, navigation, search and actions. The items place inside the | |
| 16 `paper-toolbar` are projected into a `class="horizontal center layout"` containe
r inside of | |
| 17 `paper-toolbar`'s Shadow DOM. You can use flex attributes to control the items' | |
| 18 sizing. | |
| 19 | |
| 20 Example: | |
| 21 | |
| 22 <paper-toolbar> | |
| 23 <paper-icon-button icon="menu" on-tap="menuAction"></paper-icon-button> | |
| 24 <div class="title">Title</div> | |
| 25 <paper-icon-button icon="more-vert" on-tap="moreAction"></paper-icon-butto
n> | |
| 26 </paper-toolbar> | |
| 27 | |
| 28 `paper-toolbar` has a standard height, but can made be taller by setting `tall` | |
| 29 class on the `paper-toolbar`. This will make the toolbar 3x the normal height. | |
| 30 | |
| 31 <paper-toolbar class="tall"> | |
| 32 <paper-icon-button icon="menu"></paper-icon-button> | |
| 33 </paper-toolbar> | |
| 34 | |
| 35 Apply `medium-tall` class to make the toolbar medium tall. This will make the | |
| 36 toolbar 2x the normal height. | |
| 37 | |
| 38 <paper-toolbar class="medium-tall"> | |
| 39 <paper-icon-button icon="menu"></paper-icon-button> | |
| 40 </paper-toolbar> | |
| 41 | |
| 42 When `tall`, items can pin to either the top (default), middle or bottom. Use | |
| 43 `middle` class for middle content and `bottom` class for bottom content. | |
| 44 | |
| 45 <paper-toolbar class="tall"> | |
| 46 <paper-icon-button icon="menu"></paper-icon-button> | |
| 47 <div class="middle title">Middle Title</div> | |
| 48 <div class="bottom title">Bottom Title</div> | |
| 49 </paper-toolbar> | |
| 50 | |
| 51 For `medium-tall` toolbar, the middle and bottom contents overlap and are | |
| 52 pinned to the bottom. But `middleJustify` and `bottomJustify` attributes are | |
| 53 still honored separately. | |
| 54 | |
| 55 To make an element completely fit at the bottom of the toolbar, use `fit` along | |
| 56 with `bottom`. | |
| 57 | |
| 58 <paper-toolbar class="tall"> | |
| 59 <div id="progressBar" class="bottom fit"></div> | |
| 60 </paper-toolbar> | |
| 61 | |
| 62 ### Styling | |
| 63 | |
| 64 The following custom properties and mixins are available for styling: | |
| 65 | |
| 66 Custom property | Description | Default | |
| 67 ----------------|-------------|---------- | |
| 68 `--paper-toolbar-background` | Toolbar background color | `--default-primary
-color` | |
| 69 `--paper-toolbar-color` | Toolbar foreground color | `--text-primary-co
lor` | |
| 70 `--paper-toolbar` | Mixin applied to the toolbar | `{}` | |
| 71 | |
| 72 ### Accessibility | |
| 73 | |
| 74 `<paper-toolbar>` has `role="toolbar"` by default. Any elements with the class `
title` will | |
| 75 be used as the label of the toolbar via `aria-labelledby`. | |
| 76 | |
| 77 @demo demo/index.html | |
| 78 --> | |
| 79 | |
| 80 <dom-module id="paper-toolbar"> | |
| 81 | |
| 82 <style> | |
| 83 :host { | |
| 84 /* technical */ | |
| 85 display: block; | |
| 86 position: relative; | |
| 87 box-sizing: border-box; | |
| 88 -moz-box-sizing: border-box; | |
| 89 | |
| 90 /* size */ | |
| 91 height: 64px; | |
| 92 | |
| 93 background: var(--paper-toolbar-background, --default-primary-color); | |
| 94 color: var(--paper-toolbar-color, --text-primary-color); | |
| 95 | |
| 96 @apply(--paper-toolbar); | |
| 97 } | |
| 98 | |
| 99 :host(.animate) { | |
| 100 /* transition */ | |
| 101 transition: height 0.18s ease-in; | |
| 102 } | |
| 103 | |
| 104 :host(.medium-tall) { | |
| 105 height: 128px; | |
| 106 } | |
| 107 | |
| 108 :host(.tall) { | |
| 109 height: 192px; | |
| 110 } | |
| 111 | |
| 112 .toolbar-tools { | |
| 113 position: relative; | |
| 114 height: 64px; | |
| 115 padding: 0 16px; | |
| 116 pointer-events: none; | |
| 117 } | |
| 118 | |
| 119 /* | |
| 120 * TODO: Where should media query breakpoints live so they can be shared bet
ween elements? | |
| 121 */ | |
| 122 | |
| 123 @media (max-width: 639px) { | |
| 124 :host { | |
| 125 height: 56px; | |
| 126 } | |
| 127 | |
| 128 :host(.medium-tall) { | |
| 129 height: 112px; | |
| 130 } | |
| 131 | |
| 132 :host(.tall) { | |
| 133 height: 168px; | |
| 134 } | |
| 135 | |
| 136 .toolbar-tools { | |
| 137 height: 56px; | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 #topBar { | |
| 142 position: relative; | |
| 143 } | |
| 144 | |
| 145 /* middle bar */ | |
| 146 #middleBar { | |
| 147 position: absolute; | |
| 148 top: 0; | |
| 149 right: 0; | |
| 150 left: 0; | |
| 151 } | |
| 152 | |
| 153 :host(.tall) #middleBar, | |
| 154 :host(.medium-tall) #middleBar { | |
| 155 -webkit-transform: translateY(100%); | |
| 156 transform: translateY(100%); | |
| 157 } | |
| 158 | |
| 159 /* bottom bar */ | |
| 160 #bottomBar { | |
| 161 position: absolute; | |
| 162 right: 0; | |
| 163 bottom: 0; | |
| 164 left: 0; | |
| 165 } | |
| 166 | |
| 167 /* | |
| 168 * make elements (e.g. buttons) respond to mouse/touch events | |
| 169 * | |
| 170 * `.toolbar-tools` disables touch events so multiple toolbars can stack and
not | |
| 171 * absorb events. All children must have pointer events re-enabled to work a
s | |
| 172 * expected. | |
| 173 */ | |
| 174 .toolbar-tools > ::content > *:not([disabled]) { | |
| 175 pointer-events: auto; | |
| 176 } | |
| 177 | |
| 178 .toolbar-tools > ::content .title { | |
| 179 @apply(--paper-font-title); | |
| 180 @apply(--layout-flex); | |
| 181 | |
| 182 pointer-events: none; | |
| 183 text-overflow: ellipsis; | |
| 184 white-space: nowrap; | |
| 185 overflow: hidden; | |
| 186 | |
| 187 /* | |
| 188 * Polymer/polymer/issues/1525 | |
| 189 * --paper-font-title defines a `font-weight` | |
| 190 * let's override its value, but we need `important!` | |
| 191 * because all mixins are resolved in rule's selector that has higher prec
edence | |
| 192 * than the current selector. | |
| 193 */ | |
| 194 font-weight: 400 !important; | |
| 195 } | |
| 196 | |
| 197 /** | |
| 198 * TODO: Refactor these selectors | |
| 199 * Work in progress. | |
| 200 */ | |
| 201 .toolbar-tools > ::content paper-icon-button[icon=menu] { | |
| 202 margin-right: 24px; | |
| 203 } | |
| 204 | |
| 205 .toolbar-tools > ::content > .title, | |
| 206 .toolbar-tools > ::content[select=".middle"] > .title, | |
| 207 .toolbar-tools > ::content[select=".bottom"] > .title { | |
| 208 margin-left: 56px; | |
| 209 } | |
| 210 | |
| 211 .toolbar-tools > ::content > paper-icon-button + .title, | |
| 212 .toolbar-tools > ::content[select=".middle"] paper-icon-button + .title, | |
| 213 .toolbar-tools > ::content[select=".bottom"] paper-icon-button + .title { | |
| 214 margin-left: 0; | |
| 215 } | |
| 216 | |
| 217 .toolbar-tools > ::content > .fit { | |
| 218 position: absolute; | |
| 219 top: auto; | |
| 220 right: 0; | |
| 221 bottom: 0; | |
| 222 left: 0; | |
| 223 width: auto; | |
| 224 margin: 0; | |
| 225 } | |
| 226 | |
| 227 </style> | |
| 228 | |
| 229 <template> | |
| 230 | |
| 231 <div id="topBar" class$="[[_computeBarClassName(justify)]]"> | |
| 232 <content select=":not(.middle):not(.bottom)"></content> | |
| 233 </div> | |
| 234 | |
| 235 <div id="middleBar" class$="[[_computeBarClassName(middleJustify)]]"> | |
| 236 <content select=".middle"></content> | |
| 237 </div> | |
| 238 | |
| 239 <div id="bottomBar" class$="[[_computeBarClassName(bottomJustify)]]"> | |
| 240 <content select=".bottom"></content> | |
| 241 </div> | |
| 242 | |
| 243 </template> | |
| 244 | |
| 245 </dom-module> | |
| 246 | |
| 247 <script> | |
| 248 | |
| 249 (function() { | |
| 250 | |
| 251 'use strict'; | |
| 252 | |
| 253 function classNames(obj) { | |
| 254 var classNames = []; | |
| 255 for (var key in obj) { | |
| 256 if (obj.hasOwnProperty(key) && obj[key]) { | |
| 257 classNames.push(key); | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 return classNames.join(' '); | |
| 262 } | |
| 263 | |
| 264 Polymer({ | |
| 265 | |
| 266 is: 'paper-toolbar', | |
| 267 | |
| 268 hostAttributes: { | |
| 269 'role': 'toolbar' | |
| 270 }, | |
| 271 | |
| 272 properties: { | |
| 273 | |
| 274 /** | |
| 275 * Controls how the items are aligned horizontally when they are placed | |
| 276 * at the bottom. | |
| 277 * Options are `start`, `center`, `end`, `justified` and `around`. | |
| 278 * | |
| 279 * @attribute bottomJustify | |
| 280 * @type string | |
| 281 * @default '' | |
| 282 */ | |
| 283 bottomJustify: { | |
| 284 type: String, | |
| 285 value: '' | |
| 286 }, | |
| 287 | |
| 288 /** | |
| 289 * Controls how the items are aligned horizontally. | |
| 290 * Options are `start`, `center`, `end`, `justified` and `around`. | |
| 291 * | |
| 292 * @attribute justify | |
| 293 * @type string | |
| 294 * @default '' | |
| 295 */ | |
| 296 justify: { | |
| 297 type: String, | |
| 298 value: '' | |
| 299 }, | |
| 300 | |
| 301 /** | |
| 302 * Controls how the items are aligned horizontally when they are placed | |
| 303 * in the middle. | |
| 304 * Options are `start`, `center`, `end`, `justified` and `around`. | |
| 305 * | |
| 306 * @attribute middleJustify | |
| 307 * @type string | |
| 308 * @default '' | |
| 309 */ | |
| 310 middleJustify: { | |
| 311 type: String, | |
| 312 value: '' | |
| 313 } | |
| 314 | |
| 315 }, | |
| 316 | |
| 317 attached: function() { | |
| 318 this._observer = this._observe(this); | |
| 319 this._updateAriaLabelledBy(); | |
| 320 }, | |
| 321 | |
| 322 detached: function() { | |
| 323 if (this._observer) { | |
| 324 this._observer.disconnect(); | |
| 325 } | |
| 326 }, | |
| 327 | |
| 328 _observe: function(node) { | |
| 329 var observer = new MutationObserver(function() { | |
| 330 this._updateAriaLabelledBy(); | |
| 331 }.bind(this)); | |
| 332 observer.observe(node, { | |
| 333 childList: true, | |
| 334 subtree: true | |
| 335 }); | |
| 336 return observer; | |
| 337 }, | |
| 338 | |
| 339 _updateAriaLabelledBy: function() { | |
| 340 var labelledBy = []; | |
| 341 var contents = Polymer.dom(this.root).querySelectorAll('content'); | |
| 342 for (var content, index = 0; content = contents[index]; index++) { | |
| 343 var nodes = Polymer.dom(content).getDistributedNodes(); | |
| 344 for (var node, jndex = 0; node = nodes[jndex]; jndex++) { | |
| 345 if (node.classList && node.classList.contains('title')) { | |
| 346 if (node.id) { | |
| 347 labelledBy.push(node.id); | |
| 348 } else { | |
| 349 var id = 'paper-toolbar-label-' + Math.floor(Math.random() * 100
00); | |
| 350 node.id = id; | |
| 351 labelledBy.push(id); | |
| 352 } | |
| 353 } | |
| 354 } | |
| 355 } | |
| 356 if (labelledBy.length > 0) { | |
| 357 this.setAttribute('aria-labelledby', labelledBy.join(' ')); | |
| 358 } | |
| 359 }, | |
| 360 | |
| 361 _computeBarClassName: function(barJustify) { | |
| 362 var classObj = { | |
| 363 'center': true, | |
| 364 'horizontal': true, | |
| 365 'layout': true, | |
| 366 'toolbar-tools': true | |
| 367 }; | |
| 368 | |
| 369 // If a blank string or any falsy value is given, no other class name is | |
| 370 // added. | |
| 371 if (barJustify) { | |
| 372 var justifyClassName = (barJustify === 'justified') ? | |
| 373 barJustify : | |
| 374 barJustify + '-justified'; | |
| 375 | |
| 376 classObj[justifyClassName] = true; | |
| 377 } | |
| 378 | |
| 379 return classNames(classObj); | |
| 380 } | |
| 381 | |
| 382 }); | |
| 383 | |
| 384 }()); | |
| 385 | |
| 386 </script> | |
| OLD | NEW |