@@ -17,6 +17,83 @@ def render_sidebar():
1717 4. Sign out button
1818 """
1919
20+ # --- CUSTOM JS SIDEBAR TOGGLE (Fallback for Cloud) ---
21+ # This script adds a robust custom button if the native one is missing
22+ toggle_script = """
23+ <script>
24+ function createToggle() {
25+ // Check if our custom toggle already exists
26+ if (document.getElementById('custom-sidebar-toggle')) return;
27+
28+ // Create the button
29+ const btn = document.createElement('button');
30+ btn.id = 'custom-sidebar-toggle';
31+ btn.innerHTML = '☰';
32+ btn.style.position = 'fixed';
33+ btn.style.top = '15px';
34+ btn.style.left = '15px';
35+ btn.style.zIndex = '9999999';
36+ btn.style.backgroundColor = 'rgba(59, 130, 246, 0.9)';
37+ btn.style.color = 'white';
38+ btn.style.border = 'none';
39+ btn.style.borderRadius = '8px';
40+ btn.style.width = '40px';
41+ btn.style.height = '40px';
42+ btn.style.fontSize = '20px';
43+ btn.style.cursor = 'pointer';
44+ btn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.3)';
45+ btn.style.display = 'flex';
46+ btn.style.alignItems = 'center';
47+ btn.style.justifyContent = 'center';
48+ btn.style.transition = 'all 0.3s ease';
49+
50+ // Add click event
51+ btn.onclick = function() {
52+ const sidebar = document.querySelector('section[data-testid="stSidebar"]');
53+ if (sidebar) {
54+ // Check if collapsed by width or transform
55+ const computedStyle = window.getComputedStyle(sidebar);
56+ const is collapsed = computedStyle.transform !== 'none' && computedStyle.transform !== 'matrix(1, 0, 0, 1, 0, 0)' || computedStyle.width === '0px';
57+
58+ if (sidebar.getAttribute('aria-expanded') === 'true') {
59+ // Collapse it
60+ // Try native button first
61+ const closeBtn = document.querySelector('button[data-testid="stSidebarCollapseButton"]');
62+ if (closeBtn) closeBtn.click();
63+ else {
64+ // Manual collapse hack (not ideal but works for visuals)
65+ sidebar.setAttribute('aria-expanded', 'false');
66+ }
67+ } else {
68+ // Expand it
69+ // Try native fallback expand button
70+ const openBtn = document.querySelector('[data-testid="stSidebarCollapsedControl"] button');
71+ if (openBtn) openBtn.click();
72+ else {
73+ sidebar.setAttribute('aria-expanded', 'true');
74+ }
75+ }
76+
77+ // Toggle button animation
78+ btn.style.transform = 'scale(0.9)';
79+ setTimeout(() => btn.style.transform = 'scale(1)', 150);
80+ }
81+ };
82+
83+ // Add to DOM
84+ document.body.appendChild(btn);
85+ }
86+
87+ // Run immediately and on intervals to ensure it persists
88+ createToggle();
89+ setInterval(createToggle, 1000);
90+ </script>
91+ """
92+
93+ # Inject via components to ensure script execution
94+ import streamlit .components .v1 as components
95+ components .html (toggle_script , height = 0 )
96+
2097 # --- SIDEBAR RENDER ---
2198 with st .sidebar :
2299 # --- 1. BRAND HEADER ---
0 commit comments