diff --git a/src/core/preview/preview.less b/src/core/preview/preview.less index 19c24a39..602f073c 100644 --- a/src/core/preview/preview.less +++ b/src/core/preview/preview.less @@ -1,31 +1,29 @@ .uip-preview { - display: flex; - align-items: flex-start; + display: block; + overflow: hidden; grid-area: preview; - &-inner { - flex: 1 0 auto; - height: 100%; + &-container { + display: flex; + justify-content: center; + align-items: center; + position: relative; + margin: auto; + overflow: hidden; + width: auto; + height: auto; max-width: 100%; max-height: 100%; - overflow: auto; - } - &[resizable] &-inner { - resize: both; + transition: min-height 0.5s linear; } - &-stub { - flex: 0 0 0; - width: 0; - transition: height 0.5s linear; + &[resizable] &-container { + resize: both; } - &.centered-content { - .uip-preview-inner { - display: flex; - justify-content: center; - align-items: center; - } + &-inner { + max-width: 100%; + max-height: 100%; } } diff --git a/src/core/preview/preview.tsx b/src/core/preview/preview.tsx index 5e292604..83051a56 100644 --- a/src/core/preview/preview.tsx +++ b/src/core/preview/preview.tsx @@ -1,6 +1,7 @@ import React from 'jsx-dom'; -import {bind, memoize} from '@exadel/esl/modules/esl-utils/decorators'; -import {afterNextRender, promisifyTransition} from '@exadel/esl/modules/esl-utils/async'; + +import {bind, listen, memoize} from '@exadel/esl/modules/esl-utils/decorators'; +import {afterNextRender, skipOneRender} from '@exadel/esl/modules/esl-utils/async'; import {UIPPlugin} from '../base/plugin'; @@ -12,37 +13,45 @@ export class UIPPreview extends UIPPlugin { static is = 'uip-preview'; static observedAttributes: string[] = ['dir', 'resizable']; - /** Extra element to animate decreasing height of content smoothly */ - @memoize() - protected get $stub(): HTMLElement { - const type = this.constructor as typeof UIPPreview; - return () as HTMLElement; - } - /** {@link UIPPlugin} section wrapper */ @memoize() protected get $inner(): HTMLElement { const pluginType = this.constructor as typeof UIPPlugin; - return
as HTMLElement; + return
as HTMLElement; + } + + /** Extra element to animate decreasing height of content smoothly */ + @memoize() + protected get $container(): HTMLElement { + const type = this.constructor as typeof UIPPreview; + return ( +
+ + + {this.$inner} +
+ ) as HTMLElement; } /** Changes preview markup from state changes */ @bind protected _onRootStateChange(): void { - this.$stub.style.height = `${this.$inner.offsetHeight}px`; - this.appendChild(this.$stub); + this.$container.style.minHeight = `${this.$inner.offsetHeight}px`; this.$inner.innerHTML = this.model!.html; - afterNextRender(() => this.$stub.style.height = '0px'); - promisifyTransition(this.$stub, 'height').then(() => this.removeChild(this.$stub)); + afterNextRender(() => this.$container.style.minHeight = '0px'); + skipOneRender(() => { + if (this.$container.clientHeight !== this.$inner.offsetHeight) return; + this.$container.style.removeProperty('min-height'); + }); } protected override connectedCallback(): void { super.connectedCallback(); - this.appendChild(this.$inner); + this.appendChild(this.$container); } protected override disconnectedCallback(): void { - this.$inner.remove(); + this.$container.remove(); super.disconnectedCallback(); } @@ -61,4 +70,13 @@ export class UIPPreview extends UIPPlugin { this.$inner.dir = this.dir; isChanged && this.$$fire('uip:dirchange'); } + + @listen({ + event: 'transitionend', + target: (preview: UIPPreview) => preview.$container, + }) + protected _onTransitionEnd(e: TransitionEvent): void { + if (e.propertyName !== 'min-height') return; + this.$container.style.removeProperty('min-height'); + } }