class Sidebar { constructor(onSelectSurface) { this.onSelectSurface = onSelectSurface; this.sidebar = document.getElementById('sidebar'); this.overlay = document.getElementById('sidebar-overlay'); this.tree = document.getElementById('sidebar-tree'); this.menuBtn = document.getElementById('menu-btn'); this.closeBtn = document.getElementById('sidebar-close'); this.workspaces = []; this.activeSurface = null; this._loaded = false; this.menuBtn.addEventListener('click', () => this.open()); this.closeBtn.addEventListener('click', () => this.close()); this.overlay.addEventListener('click', () => this.close()); // On desktop, sidebar is always visible via CSS (position: relative) // Check on resize to close overlay if switching to desktop this._onResize = () => { if (window.innerWidth >= 1024) { this.overlay.classList.remove('visible'); } }; window.addEventListener('resize', this._onResize); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && this.isOpen() && !this.isDesktop()) this.close(); }); this.render(); } open() { this.sidebar.classList.add('open'); this.overlay.classList.add('visible'); } close() { this.sidebar.classList.remove('open'); this.overlay.classList.remove('visible'); } isDesktop() { return window.innerWidth >= 1024; } isOpen() { return this.sidebar.classList.contains('open'); } setWorkspaces(workspaces) { this.workspaces = workspaces; this._loaded = true; this.render(); } setActiveSurface(surfaceRef) { this.activeSurface = surfaceRef; this.render(); } render() { this.tree.innerHTML = ''; if (this.workspaces.length === 0) { const empty = document.createElement('div'); empty.className = 'sidebar-empty'; empty.textContent = this._loaded ? 'No workspaces' : 'Loading...'; this.tree.appendChild(empty); return; } for (const ws of this.workspaces) { // Workspace group label const groupLabel = document.createElement('div'); groupLabel.className = 'ws-group-label'; groupLabel.textContent = ws.name || ws.ref; this.tree.appendChild(groupLabel); // Surfaces within workspace for (const pane of ws.panes) { for (const surface of pane.surfaces) { const item = document.createElement('div'); item.className = 'surface-item'; if (surface.ref === this.activeSurface) { item.classList.add('active'); } const icon = document.createElement('span'); icon.className = 'surface-icon'; icon.textContent = surface.type === 'browser' ? '\u{1F310}' : '\u{1F4BB}'; const label = document.createElement('span'); label.className = 'ws-label'; label.textContent = surface.title || surface.ref; item.appendChild(icon); item.appendChild(label); item.addEventListener('click', () => { this.onSelectSurface(ws.ref, surface.ref); this.setActiveSurface(surface.ref); if (!this.isDesktop()) this.close(); }); this.tree.appendChild(item); } } } } } window.Sidebar = Sidebar;