blob: 2a0e455f9c3a9415d049e2cc41df2491d1804598 [file] [log] [blame]
Sean McCullough71941bd2025-04-18 13:31:48 -07001import { css, html, LitElement } from "lit";
2import { customElement, property } from "lit/decorators.js";
Sean McCullough86b56862025-04-18 13:04:03 -07003
Sean McCullough71941bd2025-04-18 13:31:48 -07004@customElement("sketch-network-status")
Sean McCullough86b56862025-04-18 13:04:03 -07005export class SketchNetworkStatus extends LitElement {
Sean McCullough86b56862025-04-18 13:04:03 -07006 @property()
7 connection: string;
Sean McCulloughb29f8912025-04-20 15:39:11 -07008
Sean McCullough86b56862025-04-18 13:04:03 -07009 @property()
10 message: string;
Sean McCulloughb29f8912025-04-20 15:39:11 -070011
Sean McCullough86b56862025-04-18 13:04:03 -070012 @property()
13 error: string;
Sean McCullough71941bd2025-04-18 13:31:48 -070014
Sean McCullough86b56862025-04-18 13:04:03 -070015 // See https://lit.dev/docs/components/styles/ for how lit-element handles CSS.
16 // Note that these styles only apply to the scope of this web component's
17 // shadow DOM node, so they won't leak out or collide with CSS declared in
18 // other components or the containing web page (...unless you want it to do that).
19
20 static styles = css`
Sean McCullough71941bd2025-04-18 13:31:48 -070021 .status-container {
22 display: flex;
23 align-items: center;
24 }
Sean McCullough86b56862025-04-18 13:04:03 -070025
Sean McCullough71941bd2025-04-18 13:31:48 -070026 .polling-indicator {
27 display: inline-block;
28 width: 8px;
29 height: 8px;
30 border-radius: 50%;
31 margin-right: 4px;
32 background-color: #ccc;
33 }
Sean McCullough86b56862025-04-18 13:04:03 -070034
Sean McCullough71941bd2025-04-18 13:31:48 -070035 .polling-indicator.active {
36 background-color: #4caf50;
37 animation: pulse 1.5s infinite;
38 }
Sean McCullough86b56862025-04-18 13:04:03 -070039
Sean McCullough71941bd2025-04-18 13:31:48 -070040 .polling-indicator.error {
41 background-color: #f44336;
42 animation: pulse 1.5s infinite;
43 }
Sean McCullough86b56862025-04-18 13:04:03 -070044
Sean McCullough71941bd2025-04-18 13:31:48 -070045 @keyframes pulse {
46 0% {
47 opacity: 1;
48 }
49 50% {
50 opacity: 0.5;
51 }
52 100% {
53 opacity: 1;
54 }
55 }
Sean McCullough86b56862025-04-18 13:04:03 -070056
Sean McCullough71941bd2025-04-18 13:31:48 -070057 .status-text {
58 font-size: 11px;
59 color: #666;
60 }
61 `;
Sean McCullough86b56862025-04-18 13:04:03 -070062
63 constructor() {
64 super();
65 }
66
67 // See https://lit.dev/docs/components/lifecycle/
68 connectedCallback() {
69 super.connectedCallback();
70 }
71
72 // See https://lit.dev/docs/components/lifecycle/
73 disconnectedCallback() {
Sean McCullough71941bd2025-04-18 13:31:48 -070074 super.disconnectedCallback();
Sean McCullough86b56862025-04-18 13:04:03 -070075 }
76
77 indicator() {
78 if (this.connection === "disabled") {
Sean McCullough71941bd2025-04-18 13:31:48 -070079 return "";
Sean McCullough86b56862025-04-18 13:04:03 -070080 }
Sean McCullough71941bd2025-04-18 13:31:48 -070081 return this.connection === "connected" ? "active" : "error";
Sean McCullough86b56862025-04-18 13:04:03 -070082 }
83
84 render() {
85 return html`
Sean McCullough71941bd2025-04-18 13:31:48 -070086 <div class="status-container">
87 <span
88 id="pollingIndicator"
89 class="polling-indicator ${this.indicator()}"
90 ></span>
91 <span id="statusText" class="status-text"
92 >${this.error || this.message}</span
93 >
94 </div>
Sean McCullough86b56862025-04-18 13:04:03 -070095 `;
96 }
97}
98
99declare global {
100 interface HTMLElementTagNameMap {
101 "sketch-network-status": SketchNetworkStatus;
102 }
Sean McCullough71941bd2025-04-18 13:31:48 -0700103}