|
import streamlit as st |
|
|
|
import time |
|
|
|
|
|
st.set_page_config(page_title="Floating Status Button", layout="wide") |
|
|
|
|
|
if 'processing' not in st.session_state: |
|
st.session_state.processing = False |
|
if 'section' not in st.session_state: |
|
st.session_state.section = 'top' |
|
|
|
|
|
def start_processing(): |
|
st.session_state.processing = True |
|
|
|
def end_processing(): |
|
st.session_state.processing = False |
|
|
|
def go_to_section(section): |
|
st.session_state.section = section |
|
|
|
|
|
st.markdown(""" |
|
<style> |
|
/* Floating action button style */ |
|
.float-button { |
|
position: fixed; |
|
width: 60px; |
|
height: 60px; |
|
bottom: 40px; |
|
right: 40px; |
|
background-color: #0066ff; |
|
color: #FFF; |
|
border-radius: 50px; |
|
text-align: center; |
|
box-shadow: 2px 2px 3px #999; |
|
z-index: 99999; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
font-size: 16px; |
|
text-decoration: none; |
|
font-weight: bold; |
|
} |
|
|
|
.float-button.processing { |
|
background-color: #ff9800; |
|
animation: pulse 1.5s infinite; |
|
} |
|
|
|
@keyframes pulse { |
|
0% { |
|
transform: scale(0.95); |
|
box-shadow: 0 0 0 0 rgba(255, 152, 0, 0.7); |
|
} |
|
|
|
70% { |
|
transform: scale(1); |
|
box-shadow: 0 0 0 10px rgba(255, 152, 0, 0); |
|
} |
|
|
|
100% { |
|
transform: scale(0.95); |
|
box-shadow: 0 0 0 0 rgba(255, 152, 0, 0); |
|
} |
|
} |
|
|
|
/* Hide the default scrollbar */ |
|
::-webkit-scrollbar { |
|
display: none; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
button_class = "float-button processing" if st.session_state.processing else "float-button" |
|
button_text = "⌛" if st.session_state.processing else "⬆️" |
|
|
|
|
|
st.markdown(f""" |
|
<a href="#top" class="{button_class}" id="status-float-button">{button_text}</a> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.title("App with Floating Status", anchor="top") |
|
st.write("This app demonstrates a floating status button that also lets you navigate back to top") |
|
|
|
|
|
tabs = st.tabs(["Section 1", "Section 2", "Section 3"]) |
|
|
|
with tabs[0]: |
|
st.header("Section 1") |
|
st.write("Content for section 1") |
|
|
|
|
|
if st.button("Start Process 1", on_click=start_processing): |
|
with st.spinner("Running process..."): |
|
|
|
progress = st.progress(0) |
|
for i in range(100): |
|
time.sleep(0.02) |
|
progress.progress(i + 1) |
|
end_processing() |
|
st.success("Process 1 completed!") |
|
|
|
|
|
for i in range(10): |
|
st.write(f"Content line {i} in section 1") |
|
|
|
with tabs[1]: |
|
st.header("Section 2") |
|
st.write("Content for section 2") |
|
|
|
|
|
if st.button("Start Process 2", on_click=start_processing): |
|
with st.spinner("Running process..."): |
|
|
|
progress = st.progress(0) |
|
for i in range(100): |
|
time.sleep(0.03) |
|
progress.progress(i + 1) |
|
end_processing() |
|
st.success("Process 2 completed!") |
|
|
|
|
|
for i in range(10): |
|
st.write(f"Content line {i} in section 2") |
|
|
|
with tabs[2]: |
|
st.header("Section 3") |
|
st.write("Content for section 3") |
|
|
|
|
|
if st.button("Start Process 3", on_click=start_processing): |
|
with st.spinner("Running process..."): |
|
|
|
progress = st.progress(0) |
|
for i in range(100): |
|
time.sleep(0.04) |
|
progress.progress(i + 1) |
|
end_processing() |
|
st.success("Process 3 completed!") |
|
|
|
|
|
for i in range(10): |
|
st.write(f"Content line {i} in section 3") |
|
|
|
|
|
st.markdown("---") |
|
st.header("Additional Content") |
|
for i in range(20): |
|
st.write(f"Additional content line {i}") |
|
|
|
|
|
st.logo(image="images/menu_book_60dp_75FBFD.png") |
|
st.sidebar.title("SBS V2.0 mapper") |
|
st.sidebar.subheader("(work in progress)") |
|
st.sidebar.text("Demo by JA-RAD") |
|
|
|
|
|
type_text_page = st.Page( |
|
page="pages/type_text.py", |
|
title="DEMO (work in progress)", |
|
icon=":material/keyboard:", |
|
default=True,) |
|
|
|
|
|
pg = st.navigation(pages=[type_text_page]) |
|
|
|
pg.run() |