import { FolkShape } from "./folk-shape"; import { css, html } from "./tags"; const PIANO_URL = "https://musiclab.chromeexperiments.com/Shared-Piano/"; const styles = css` :host { background: #1e1e2e; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); min-width: 400px; min-height: 300px; overflow: hidden; } .piano-container { width: 100%; height: 100%; position: relative; } .piano-iframe { width: 100%; height: 100%; border: none; } .loading { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%); color: white; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-size: 18px; gap: 12px; } .loading.hidden { display: none; } .error { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%); color: white; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; gap: 12px; } .error.hidden { display: none; } .error-message { font-size: 14px; color: #f87171; } .retry-btn { background: #6366f1; color: white; border: none; border-radius: 6px; padding: 8px 16px; cursor: pointer; font-size: 14px; } .retry-btn:hover { background: #4f46e5; } .controls { position: absolute; top: 8px; right: 8px; display: flex; gap: 4px; } .control-btn { background: rgba(0, 0, 0, 0.5); color: white; border: none; border-radius: 4px; padding: 4px 8px; cursor: pointer; font-size: 14px; } .control-btn:hover { background: rgba(0, 0, 0, 0.7); } .minimized { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #1e1e2e 0%, #2d2d44 100%); color: white; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-size: 24px; cursor: pointer; } .minimized.hidden { display: none; } `; declare global { interface HTMLElementTagNameMap { "folk-piano": FolkPiano; } } export class FolkPiano extends FolkShape { static override tagName = "folk-piano"; static { const sheet = new CSSStyleSheet(); const parentRules = Array.from(FolkShape.styles.cssRules) .map((r) => r.cssText) .join("\n"); const childRules = Array.from(styles.cssRules) .map((r) => r.cssText) .join("\n"); sheet.replaceSync(`${parentRules}\n${childRules}`); this.styles = sheet; } #isMinimized = false; #isLoading = true; #hasError = false; #iframe: HTMLIFrameElement | null = null; #loadingEl: HTMLElement | null = null; #errorEl: HTMLElement | null = null; #minimizedEl: HTMLElement | null = null; #containerEl: HTMLElement | null = null; get isMinimized() { return this.#isMinimized; } set isMinimized(value: boolean) { this.#isMinimized = value; this.#updateVisibility(); this.requestUpdate("isMinimized"); } override createRenderRoot() { const root = super.createRenderRoot(); const wrapper = document.createElement("div"); wrapper.innerHTML = html`