Delete chrome.mediaGalleriesPrivate because the functionality unique to it has since...
[chromium-blink-merge.git] / third_party / polymer / components / core-collapse / core-collapse.html
blob6d7f5b0b11992996c1357d88ff7f1940621188c9
1 <!--
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.github.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/CONTRIBUTORS.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/PATENTS.txt
8 -->
10 <!--
11 `core-collapse` creates a collapsible block of content. By default, the content
12 will be collapsed. Use `opened` or `toggle()` to show/hide the content.
14 <button on-click="{{toggle}}">toggle collapse</button>
16 <core-collapse id="collapse">
17 Content goes here...
18 </core-collapse>
20 ...
22 toggle: function() {
23 this.$.collapse.toggle();
26 `core-collapse` adjusts the height/width of the collapsible element to show/hide
27 the content. So avoid putting padding/margin/border on the collapsible directly,
28 and instead put a div inside and style that.
30 <style>
31 .collapse-content {
32 padding: 15px;
33 border: 1px solid #dedede;
35 </style>
37 <core-collapse>
38 <div class="collapse-content">
39 Content goes here...
40 </div>
41 </core-collapse>
43 @group Polymer Core Elements
44 @element core-collapse
45 -->
47 <link rel="import" href="../polymer/polymer.html">
49 <link rel="stylesheet" href="core-collapse.css" shim-shadowdom>
51 <polymer-element name="core-collapse" attributes="target horizontal opened duration fixedSize allowOverflow">
52 <template>
54 <content></content>
56 </template>
57 <script>
59 Polymer('core-collapse', {
61 /**
62 * Fired when the `core-collapse`'s `opened` property changes.
64 * @event core-collapse-open
67 /**
68 * Fired when the target element has been resized as a result of the opened
69 * state changing.
71 * @event core-resize
74 /**
75 * The target element that will be opened when the `core-collapse` is
76 * opened. If unspecified, the `core-collapse` itself is the target.
78 * @attribute target
79 * @type object
80 * @default null
82 target: null,
84 /**
85 * If true, the orientation is horizontal; otherwise is vertical.
87 * @attribute horizontal
88 * @type boolean
89 * @default false
91 horizontal: false,
93 /**
94 * Set opened to true to show the collapse element and to false to hide it.
96 * @attribute opened
97 * @type boolean
98 * @default false
100 opened: false,
103 * Collapsing/expanding animation duration in second.
105 * @attribute duration
106 * @type number
107 * @default 0.33
109 duration: 0.33,
112 * If true, the size of the target element is fixed and is set
113 * on the element. Otherwise it will try to
114 * use auto to determine the natural size to use
115 * for collapsing/expanding.
117 * @attribute fixedSize
118 * @type boolean
119 * @default false
121 fixedSize: false,
124 * By default the collapsible element is set to overflow hidden. This helps
125 * avoid element bleeding outside the region and provides consistent overflow
126 * style across opened and closed states. Set this property to true to allow
127 * the collapsible element to overflow when it's opened.
129 * @attribute allowOverflow
130 * @type boolean
131 * @default false
133 allowOverflow: false,
135 created: function() {
136 this.transitionEndListener = this.transitionEnd.bind(this);
139 ready: function() {
140 this.target = this.target || this;
143 domReady: function() {
144 this.async(function() {
145 this.afterInitialUpdate = true;
149 detached: function() {
150 if (this.target) {
151 this.removeListeners(this.target);
155 targetChanged: function(old) {
156 if (old) {
157 this.removeListeners(old);
159 if (!this.target) {
160 return;
162 this.isTargetReady = !!this.target;
163 this.classList.toggle('core-collapse-closed', this.target !== this);
164 this.toggleOpenedStyle(false);
165 this.horizontalChanged();
166 this.addListeners(this.target);
167 // set core-collapse-closed class initially to hide the target
168 this.toggleClosedClass(true);
169 this.update();
172 addListeners: function(node) {
173 node.addEventListener('transitionend', this.transitionEndListener);
176 removeListeners: function(node) {
177 node.removeEventListener('transitionend', this.transitionEndListener);
180 horizontalChanged: function() {
181 this.dimension = this.horizontal ? 'width' : 'height';
184 openedChanged: function() {
185 this.update();
186 this.fire('core-collapse-open', this.opened);
190 * Toggle the opened state.
192 * @method toggle
194 toggle: function() {
195 this.opened = !this.opened;
198 setTransitionDuration: function(duration) {
199 var s = this.target.style;
200 s.transition = duration ? (this.dimension + ' ' + duration + 's') : null;
201 if (duration === 0) {
202 this.async('transitionEnd');
206 transitionEnd: function() {
207 if (this.opened && !this.fixedSize) {
208 this.updateSize('auto', null);
210 this.setTransitionDuration(null);
211 this.toggleOpenedStyle(this.opened);
212 this.toggleClosedClass(!this.opened);
213 this.asyncFire('core-resize', null, this.target);
216 toggleClosedClass: function(closed) {
217 this.hasClosedClass = closed;
218 this.target.classList.toggle('core-collapse-closed', closed);
221 toggleOpenedStyle: function(opened) {
222 this.target.style.overflow = this.allowOverflow && opened ? '' : 'hidden';
225 updateSize: function(size, duration, forceEnd) {
226 this.setTransitionDuration(duration);
227 this.calcSize();
228 var s = this.target.style;
229 var nochange = s[this.dimension] === size;
230 s[this.dimension] = size;
231 // transitonEnd will not be called if the size has not changed
232 if (forceEnd && nochange) {
233 this.transitionEnd();
237 update: function() {
238 if (!this.target) {
239 return;
241 if (!this.isTargetReady) {
242 this.targetChanged();
244 this.horizontalChanged();
245 this[this.opened ? 'show' : 'hide']();
248 calcSize: function() {
249 return this.target.getBoundingClientRect()[this.dimension] + 'px';
252 getComputedSize: function() {
253 return getComputedStyle(this.target)[this.dimension];
256 show: function() {
257 this.toggleClosedClass(false);
258 // for initial update, skip the expanding animation to optimize
259 // performance e.g. skip calcSize
260 if (!this.afterInitialUpdate) {
261 this.transitionEnd();
262 return;
264 if (!this.fixedSize) {
265 this.updateSize('auto', null);
266 var s = this.calcSize();
267 if (s == '0px') {
268 this.transitionEnd();
269 return;
271 this.updateSize(0, null);
273 this.async(function() {
274 this.updateSize(this.size || s, this.duration, true);
278 hide: function() {
279 this.toggleOpenedStyle(false);
280 // don't need to do anything if it's already hidden
281 if (this.hasClosedClass && !this.fixedSize) {
282 return;
284 if (this.fixedSize) {
285 // save the size before hiding it
286 this.size = this.getComputedSize();
287 } else {
288 this.updateSize(this.calcSize(), null);
290 this.async(function() {
291 this.updateSize(0, this.duration);
297 </script>
298 </polymer-element>