Skip to content

๐Ÿ”›ย ย Stateful Button

Submitted by Zachary Blackwood

Summary

Button that keeps track of its state, so that it works as a toggle button

Functions

button

Create a toggle button that remembers its state.

Works just like a normal streamlit button, but it remembers its state, so that it works as a toggle button. If you click it, it will be pressed, and if you click it again, it will be unpressed. Args and output are the same as for st.button.

Parameters:

Name Type Description Default
*args Any

Positional arguments passed to st.button.

()
key str | None

Required unique key for the button. Must not be None.

None
**kwargs Any

Keyword arguments passed to st.button.

{}

Returns:

Name Type Description
bool bool

True if the button is currently in pressed state, False otherwise.

Raises:

Type Description
ValueError

If key is not provided.

Source code in src/streamlit_extras/stateful_button/__init__.py
@extra
def button(*args: Any, key: str | None = None, **kwargs: Any) -> bool:
    """Create a toggle button that remembers its state.

    Works just like a normal streamlit button, but it remembers its state, so that
    it works as a toggle button. If you click it, it will be pressed, and if you click
    it again, it will be unpressed. Args and output are the same as for st.button.

    Args:
        *args: Positional arguments passed to st.button.
        key (str | None): Required unique key for the button. Must not be None.
        **kwargs: Keyword arguments passed to st.button.

    Returns:
        bool: True if the button is currently in pressed state, False otherwise.

    Raises:
        ValueError: If key is not provided.
    """

    if key is None:
        raise ValueError("Must pass key")

    if key not in st.session_state:
        st.session_state[key] = False

    if "type" not in kwargs:
        kwargs["type"] = "primary" if st.session_state[key] else "secondary"

    derived_key = f"{key}_derived"

    original_on_click = kwargs.get("on_click")

    def callback() -> None:
        if original_on_click is not None:
            original_on_click()
        toggle_state(key)

    kwargs["on_click"] = callback

    st.button(*args, key=derived_key, **kwargs)  # type: ignore[misc]

    return st.session_state[key]

Import:

from streamlit_extras.stateful_button import button # (1)!
  1. You should add this to the top of your .py file ๐Ÿ› 

Examples

example

def example() -> None:
    if button("Button 1", key="button1") and button("Button 2", key="button2"):
        if button("Button 3", key="button3"):
            st.write("All 3 buttons are pressed")
Output (beta)