import { __decorate } from "tslib";
import { html } from 'lit';
import { property, state } from 'lit/decorators.js';
import { observer, ExmgElement } from '@exmg/lit-base/index.js';
/**
* Helper function to toggle element
* @param className
* @param el
* @param val
*/
const toggleClass = (className, el, val) => {
if (val !== undefined) {
if (val) {
if (!el.classList.contains(className)) {
el.classList.add(className);
}
}
else {
el.classList.remove(className);
}
}
else {
el.classList.toggle(className);
}
};
export class ExmgCollapsedBase extends ExmgElement {
constructor() {
super();
/**
* Whether or not the element is opened or not
* @type {Boolean}
*/
this.opened = false;
/**
* Whether the element is transitioning or not
* @type {Boolean}
*/
this.transitioning = false;
this._desiredSize = '';
this._initialized = false;
this.addEventListener('transitionend', this._onTransitionEnd.bind(this));
this.setAttribute('role', 'group');
this.setAttribute('aria-hidden', 'true');
}
/**
* Toggle the current(opened/closed) state.
* @public
*/
toggle() {
this.opened = !this.opened;
}
/**
* Set the opened state
* @public
*/
show() {
this.opened = true;
}
/**
* Set the closed state
* @public
*/
hide() {
this.opened = false;
}
/**
* @private
*/
_calcSize() {
return this.getBoundingClientRect()['height'] + 'px';
}
/**
* @private
*/
_updateTransition(enabled) {
this.style.transitionDuration = enabled ? '' : '0s';
}
updateSize(size, animated) {
// Consider 'auto' as '', to take full size.
size = size === 'auto' ? '' : size;
let willAnimate = animated && this._desiredSize !== size;
this._desiredSize = size;
this._updateTransition(false);
// If we can animate, must do some prep work.
if (willAnimate) {
// Animation will start at the current size.
const 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 === '') {
this.style['maxHeight'] = '';
size = this._calcSize();
}
// Go to startSize without animation.
this.style['maxHeight'] = startSize;
// Force layout to ensure transition will go. Set scrollTop to itself
// so that compilers won't remove it.
// eslint-disable-next-line no-self-assign
this.scrollTop = this.scrollTop;
// Enable animation.
this._updateTransition(true);
// If final size is the same as startSize it will not animate.
willAnimate = size !== startSize;
}
// Set the final size.
this.style['maxHeight'] = size;
// If it won't animate, call transitionEnd to set correct classes.
if (!willAnimate) {
this._transitionEnd();
}
}
/**
* @private
*/
_openedChanged() {
this.setAttribute('aria-hidden', String(!this.opened));
if (this._initialized) {
this.transitioning = true;
}
toggleClass('collapse-closed', this, false);
toggleClass('collapse-opened', this, false);
this.updateSize(this.opened ? 'auto' : '0px', this._initialized);
// Focus the current collapse.
if (this.opened) {
this.focus();
}
this._initialized = true;
}
/**
* @private
*/
_onTransitionEnd(event) {
if (event.target === this) {
this._transitionEnd();
}
}
/**
* @private
*/
_transitionEnd() {
this.style['maxHeight'] = String(this._desiredSize);
toggleClass('collapse-closed', this, !this.opened);
toggleClass('collapse-opened', this, this.opened);
this._updateTransition(false);
this.transitioning = false;
}
render() {
return html ` <slot></slot> `;
}
}
__decorate([
property({ type: Boolean, reflect: true }),
observer(function () {
this._openedChanged();
})
], ExmgCollapsedBase.prototype, "opened", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], ExmgCollapsedBase.prototype, "transitioning", void 0);
__decorate([
state()
], ExmgCollapsedBase.prototype, "_desiredSize", void 0);
//# sourceMappingURL=exmg-collapsed-base.js.map