Skip to content

Commit f73a437

Browse files
committed
fix: Add Python-based 'Show Menu' button as reliable sidebar toggle fallback
1 parent 2870945 commit f73a437

File tree

1 file changed

+40
-73
lines changed

1 file changed

+40
-73
lines changed

frontend/components/sidebar.py

Lines changed: 40 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -17,82 +17,49 @@ 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';
20+
# --- SIDEBAR CONTROLLER (Python Fallback) ---
21+
# If native toggle fails, this button in the MAIN area allows forcing sidebar open
22+
23+
# Initialize state
24+
if 'sidebar_force_open' not in st.session_state:
25+
st.session_state.sidebar_force_open = False
4926

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-
}
27+
# Logic to handle toggle
28+
def toggle_sidebar():
29+
st.session_state.sidebar_force_open = not st.session_state.sidebar_force_open
8630

87-
// Run immediately and on intervals to ensure it persists
88-
createToggle();
89-
setInterval(createToggle, 1000);
90-
</script>
91-
"""
31+
# Render a small floating visible button in main area (if sidebar is closed or logic dictates)
32+
# We place this in main area containers
33+
placeholder = st.container()
34+
col1, col2 = placeholder.columns([1, 20])
35+
with col1:
36+
# Only show "SHOW" button we aren't forcing it open,
37+
# allowing user to click it to "Force Open"
38+
if not st.session_state.sidebar_force_open:
39+
st.button("☰", key="custom_sidebar_show", on_click=toggle_sidebar, help="Show / Hide Sidebar")
9240

93-
# Inject via components to ensure script execution
94-
import streamlit.components.v1 as components
95-
components.html(toggle_script, height=0)
41+
# If forced open, inject CSS to override collapse
42+
if st.session_state.sidebar_force_open:
43+
st.markdown("""
44+
<style>
45+
section[data-testid="stSidebar"] {
46+
transform: translateX(0) !important;
47+
visibility: visible !important;
48+
width: 280px !important;
49+
min-width: 280px !important;
50+
}
51+
/* Hide the expand button when we are forcing open */
52+
[data-testid="stSidebarCollapsedControl"] {
53+
display: none !important;
54+
}
55+
</style>
56+
""", unsafe_allow_html=True)
57+
58+
# Show a "Close" button at top of sidebar
59+
with st.sidebar:
60+
if st.button("✖️ Close Menu", key="custom_sidebar_close", type="secondary"):
61+
toggle_sidebar()
62+
st.rerun()
9663

9764
# --- SIDEBAR RENDER ---
9865
with st.sidebar:

0 commit comments

Comments
 (0)