import { LitElement, css, html, svg } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import { Signal, SignalWatcher } from '@lit-labs/signals'; import { getSignal, State } from './utils'; const converter = { fromAttribute(value: string): string[] { return value.split(',').map((v) => v.trim()); }, toAttribute(value: string[]): string { return value.join(','); }, }; /** * Fetch data from a URL and store it in a signal. */ @customElement('admin-status') export default class Status extends SignalWatcher(LitElement) { @property() state: string | Signal.State = ''; @property({ converter, }) loading: State[] = [State.Loading, State.Reloading]; @property({ converter, }) success: State[] = [State.Success]; @property({ converter, }) error: State[] = [State.Error]; @property({ attribute: 'no-empty', }) noEmpty: boolean = false; stateSignal?: Signal.State; connectedCallback() { super.connectedCallback(); this.stateSignal = getSignal(this.state); } static styles = css` @keyframes rotate { 100% { transform: rotate(360deg); } } .loading { display: inline-block; animation: rotate 2s linear infinite; font-size: 1em; } .loading svg { vertical-align: sub; } .error { font-size: 1em; } .error svg { vertical-align: sub; } .empty { width: 1em; display: inline-block; } .svg-error { fill: var(--bs-danger); } .svg-success { fill: var(--bs-success); } `; loadingSvg = svg``; errorSvg = svg` `; emptySvg = svg` `; successSvg = svg` `; render() { if (!this.stateSignal) { return html``; } if (this.loading.includes(this.stateSignal.get())) { return html`${this.loadingSvg}`; } if (this.error.includes(this.stateSignal.get())) { return html`${this.errorSvg}`; } if (this.success.includes(this.stateSignal.get())) { return html`${this.successSvg}`; } if (this.noEmpty) { return html``; } return html`${this.emptySvg}`; } }