3 Polymer('core-collapse', {
6 * Fired when the `core-collapse`'s `opened` property changes.
8 * @event core-collapse-open
12 * Fired when the target element has been resized as a result of the opened
19 * The target element that will be opened when the `core-collapse` is
20 * opened. If unspecified, the `core-collapse` itself is the target.
29 * If true, the orientation is horizontal; otherwise is vertical.
31 * @attribute horizontal
38 * Set opened to true to show the collapse element and to false to hide it.
47 * Collapsing/expanding animation duration in second.
56 * If true, the size of the target element is fixed and is set
57 * on the element. Otherwise it will try to
58 * use auto to determine the natural size to use
59 * for collapsing/expanding.
61 * @attribute fixedSize
68 * By default the collapsible element is set to overflow hidden. This helps
69 * avoid element bleeding outside the region and provides consistent overflow
70 * style across opened and closed states. Set this property to true to allow
71 * the collapsible element to overflow when it's opened.
73 * @attribute allowOverflow
80 this.transitionEndListener
= this.transitionEnd
.bind(this);
84 this.target
= this.target
|| this;
87 domReady: function() {
88 this.async(function() {
89 this.afterInitialUpdate
= true;
93 detached: function() {
95 this.removeListeners(this.target
);
99 targetChanged: function(old
) {
101 this.removeListeners(old
);
106 this.isTargetReady
= !!this.target
;
107 this.classList
.toggle('core-collapse-closed', this.target
!== this);
108 this.toggleOpenedStyle(false);
109 this.horizontalChanged();
110 this.addListeners(this.target
);
111 // set core-collapse-closed class initially to hide the target
112 this.toggleClosedClass(true);
116 addListeners: function(node
) {
117 node
.addEventListener('transitionend', this.transitionEndListener
);
120 removeListeners: function(node
) {
121 node
.removeEventListener('transitionend', this.transitionEndListener
);
124 horizontalChanged: function() {
125 this.dimension
= this.horizontal
? 'width' : 'height';
128 openedChanged: function() {
130 this.fire('core-collapse-open', this.opened
);
134 * Toggle the opened state.
139 this.opened
= !this.opened
;
142 setTransitionDuration: function(duration
) {
143 var s
= this.target
.style
;
144 s
.transition
= duration
? (this.dimension
+ ' ' + duration
+ 's') : null;
145 if (duration
=== 0) {
146 this.async('transitionEnd');
150 transitionEnd: function() {
151 if (this.opened
&& !this.fixedSize
) {
152 this.updateSize('auto', null);
154 this.setTransitionDuration(null);
155 this.toggleOpenedStyle(this.opened
);
156 this.toggleClosedClass(!this.opened
);
157 this.asyncFire('core-resize', null, this.target
);
160 toggleClosedClass: function(closed
) {
161 this.hasClosedClass
= closed
;
162 this.target
.classList
.toggle('core-collapse-closed', closed
);
165 toggleOpenedStyle: function(opened
) {
166 this.target
.style
.overflow
= this.allowOverflow
&& opened
? '' : 'hidden';
169 updateSize: function(size
, duration
, forceEnd
) {
170 this.setTransitionDuration(duration
);
172 var s
= this.target
.style
;
173 var nochange
= s
[this.dimension
] === size
;
174 s
[this.dimension
] = size
;
175 // transitonEnd will not be called if the size has not changed
176 if (forceEnd
&& nochange
) {
177 this.transitionEnd();
185 if (!this.isTargetReady
) {
186 this.targetChanged();
188 this.horizontalChanged();
189 this[this.opened
? 'show' : 'hide']();
192 calcSize: function() {
193 return this.target
.getBoundingClientRect()[this.dimension
] + 'px';
196 getComputedSize: function() {
197 return getComputedStyle(this.target
)[this.dimension
];
201 this.toggleClosedClass(false);
202 // for initial update, skip the expanding animation to optimize
203 // performance e.g. skip calcSize
204 if (!this.afterInitialUpdate
) {
205 this.transitionEnd();
208 if (!this.fixedSize
) {
209 this.updateSize('auto', null);
210 var s
= this.calcSize();
212 this.transitionEnd();
215 this.updateSize(0, null);
217 this.async(function() {
218 this.updateSize(this.size
|| s
, this.duration
, true);
223 this.toggleOpenedStyle(false);
224 // don't need to do anything if it's already hidden
225 if (this.hasClosedClass
&& !this.fixedSize
) {
228 if (this.fixedSize
) {
229 // save the size before hiding it
230 this.size
= this.getComputedSize();
232 this.updateSize(this.calcSize(), null);
234 this.async(function() {
235 this.updateSize(0, this.duration
);