import { Prop, toNative } from 'vue-facing-decorator'; import TsxComponent, { Component } from '../../app/vuetsx'; import './loading-indicator.css'; interface LoadingIndicatorArgs { visible: boolean; cssClass?: string; displayDelay?: number ensureMinHeight?: boolean } export class LoadingIndicatorConfig { static defaultShowDelay = 0 } @Component class LoadingIndicatorComponent extends TsxComponent implements LoadingIndicatorArgs { @Prop() visible: boolean; @Prop() cssClass: string; @Prop() displayDelay?: number @Prop() ensureMinHeight?: boolean isVisible: boolean = null; mounted() { this.handleVisibleSync(); } updated() { this.handleVisibleSync(); } handleVisibleSync() { if (this.visible !== this.isVisible) { if (this.visible) { const delay = this.getDelay(); if (delay > 0) { setTimeout(() => { if (this.visible) { this.isVisible = true; } }, delay); } else { this.isVisible = true; } } else { this.isVisible = false; } } } getDelay(): number { return this.displayDelay ?? LoadingIndicatorConfig.defaultShowDelay; } render(h) { if (this.isVisible) { if (this.ensureMinHeight) { return (
{this.renderBlocker(h)}
) } else { return this.renderBlocker(h); } } else { return null; } } renderBlocker(h) { return (
Loading...
); } } const LoadingIndicator = toNative(LoadingIndicatorComponent); export default LoadingIndicator;