<!-- @license Copyright (c) 2015 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt The complete set of contributors may be found at http://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 http://polymer.github.io/PATENTS.txt --> <link rel="import" href="../polymer/polymer.html"> <!-- `iron-collapse` creates a collapsible block of content. By default, the content will be collapsed. Use `opened` or `toggle()` to show/hide the content. <button on-click="toggle">toggle collapse</button> <iron-collapse id="collapse"> <div>Content goes here...</div> </iron-collapse> ... toggle: function() { this.$.collapse.toggle(); } `iron-collapse` adjusts the height/width of the collapsible element to show/hide the content. So avoid putting padding/margin/border on the collapsible directly, and instead put a div inside and style that. <style> .collapse-content { padding: 15px; border: 1px solid #dedede; } </style> <iron-collapse> <div class="collapse-content"> <div>Content goes here...</div> </div> </iron-collapse> @group Iron Elements @hero hero.svg @demo demo/index.html @element iron-collapse --> <dom-module id="iron-collapse"> <style> :host { display: block; transition-duration: 300ms; overflow: auto; } :host(.iron-collapse-closed) { display: none; } </style> <template> <content></content> </template> </dom-module> <script> Polymer({ is: 'iron-collapse', properties: { /** * If true, the orientation is horizontal; otherwise is vertical. * * @attribute horizontal */ horizontal: { type: Boolean, value: false, observer: '_horizontalChanged' }, /** * Set opened to true to show the collapse element and to false to hide it. * * @attribute opened */ opened: { type: Boolean, value: false, notify: true, observer: '_openedChanged' }, /** * Set noAnimation to true to disable animations * * @attribute noAnimation */ noAnimation: { type: Boolean }, }, hostAttributes: { role: 'group', 'aria-hidden': 'true', 'aria-expanded': 'false' }, listeners: { transitionend: '_transitionEnd' }, attached: function() { // It will take care of setting correct classes and styles. this._transitionEnd(); }, /** * Toggle the opened state. * * @method toggle */ toggle: function() { this.opened = !this.opened; }, show: function() { this.opened = true; }, hide: function() { this.opened = false; }, updateSize: function(size, animated) { // No change! if (this.style[this.dimension] === size) { return; } this._updateTransition(false); // If we can animate, must do some prep work. if (animated && !this.noAnimation) { // Animation will start at the current size. var startSize = this._calcSize(); // For `auto` we must calculate what is the final size for the animation. // After the transition is done, _transitionEnd will set the size back to `auto`. if (size === 'auto') { this.style[this.dimension] = size; size = this._calcSize(); } // Go to startSize without animation. this.style[this.dimension] = startSize; // Force layout to ensure transition will go. Set offsetHeight to itself // so that compilers won't remove it. this.offsetHeight = this.offsetHeight; // Enable animation. this._updateTransition(true); } // Set the final size. this.style[this.dimension] = size; }, /** * enableTransition() is deprecated, but left over so it doesn't break existing code. * Please use `noAnimation` property instead. * * @method enableTransition * @deprecated since version 1.0.4 */ enableTransition: function(enabled) { console.warn('`enableTransition()` is deprecated, use `noAnimation` instead.'); this.noAnimation = !enabled; }, _updateTransition: function(enabled) { this.style.transitionDuration = (enabled && !this.noAnimation) ? '' : '0s'; }, _horizontalChanged: function() { this.dimension = this.horizontal ? 'width' : 'height'; this.style.transitionProperty = this.dimension; }, _openedChanged: function() { this.setAttribute('aria-expanded', this.opened); this.setAttribute('aria-hidden', !this.opened); this.toggleClass('iron-collapse-closed', false); this.toggleClass('iron-collapse-opened', false); this.updateSize(this.opened ? 'auto' : '0px', true); // Focus the current collapse. if (this.opened) { this.focus(); } if (this.noAnimation) { this._transitionEnd(); } }, _transitionEnd: function() { if (this.opened) { this.style[this.dimension] = 'auto'; } this.toggleClass('iron-collapse-closed', !this.opened); this.toggleClass('iron-collapse-opened', this.opened); this._updateTransition(false); }, _calcSize: function() { return this.getBoundingClientRect()[this.dimension] + 'px'; } }); </script>