Skip to content

Commit 2c89d0a

Browse files
committed
Add ForceAnchor class to fix behavior with StreamLit fragment updates; Add fragment functionality to Example 5
1 parent bb9d90c commit 2c89d0a

File tree

2 files changed

+36
-20
lines changed

2 files changed

+36
-20
lines changed

example.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,21 @@
5656
}
5757
})
5858

59-
import time;
60-
time.sleep(2)
61-
6259
# 5. Force anchor
63-
st.subheader("Example 5", help="Programatically select an anchor")
64-
force_settings = None
65-
if st.button("Go to Settings"):
66-
force_settings = "Settings"
67-
scroll_navbar(
68-
anchor_ids,
69-
key="navbar5",
70-
anchor_icons=anchor_icons,
71-
orientation="horizontal",
72-
force_anchor=force_settings)
60+
st.subheader("Example 5", help="Programatically select an anchor within StreamLit fragment")
61+
@st.fragment
62+
def example5():
63+
from streamlit_scroll_navigation import ForceAnchor
64+
force_settings = ForceAnchor()
65+
if st.button("Go to Settings"):
66+
force_settings.push("Settings")
67+
scroll_navbar(
68+
anchor_ids,
69+
key="navbar5",
70+
anchor_icons=anchor_icons,
71+
orientation="horizontal",
72+
force_anchor=force_settings)
73+
example5()
7374

7475
# 6. Retrieve active anchor
7576
with st.sidebar:

streamlit_scroll_navigation/__init__.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,26 @@ def instantiate_crossorigin_interface(key):
6060
width=0,
6161
)
6262

63-
@st.fragment
63+
class ForceAnchor:
64+
anchor:str
65+
def __init__(self):
66+
self.anchor = None
67+
68+
def push(self, anchor):
69+
self.anchor = anchor
70+
71+
def pop(self):
72+
anchor = self.anchor
73+
self.anchor = None
74+
return anchor
75+
76+
@st.fragment()
6477
def scroll_navbar(
6578
anchor_ids: Collection[str],
6679
key: str = 'scroll_navbar_default',
6780
anchor_icons: Collection[str] = None,
6881
anchor_labels: Collection[str] = None,
69-
force_anchor: str = None,
82+
force_anchor: ForceAnchor | None = None,
7083
orientation: Literal['vertical', 'horizontal'] = 'vertical',
7184
override_styles: Dict[str, str] = {},
7285
auto_update_anchor: bool = True,
@@ -87,9 +100,9 @@ def scroll_navbar(
87100
A collection of labels for each navigation button.
88101
Each label corresponds to an anchor in anchor_ids.
89102
If None, the anchor IDs will be used. Defaults to None.
90-
force_anchor (str, optional):
91-
An anchor ID to force navigation to.
92-
Setting this will simulate clicking on an anchor. Defaults to None.
103+
force_anchor (str, ForceAnchor):
104+
A ForceAnchor object to push anchors to programatically select.
105+
Setting this and pushing an anchor ID will simulate clicking on an anchor. Defaults to None.
93106
orientation (Literal['vertical', 'horizontal'], optional):
94107
The orientation of the navigation bar. Defaults to 'vertical'.
95108
override_styles (Dict[str, str], optional):
@@ -118,15 +131,17 @@ def scroll_navbar(
118131

119132
inject_crossorigin_interface()
120133
instantiate_crossorigin_interface(key)
134+
# Pop the anchor string from ForceAnchor object
135+
force_anchor_str = force_anchor.pop() if force_anchor else None
121136
component_value = _component_func(
122137
anchor_ids=anchor_ids,
123138
key=key,
124139
anchor_icons=anchor_icons,
125140
anchor_labels=anchor_labels,
126-
force_anchor=force_anchor,
141+
force_anchor=force_anchor_str,
127142
orientation=orientation,
128143
override_styles=override_styles,
129144
auto_update_anchor=auto_update_anchor,
130145
disable_scroll=disable_scroll,
131146
)
132-
return component_value
147+
return component_value

0 commit comments

Comments
 (0)