Streamlit-option-menu is a simple Streamlit component that allows users to select a single item from a list of options in a menu

I am getting this error, could you please guide me on what is going wrong.

The default vertical layout is working fine, though. How do I upgrade to the latest version?

1 Like

Hey, I upgraded and now it works fine!

pip install --upgrade streamlit-option-menu

1 Like

hi @victoryhb Thanks for this wonderful component, it really helps to create larger streamlit components. I would be interested in this feature too. Where do you want us to request new features? in this forum or directly in git?

1 Like

Hi all, I have just updated the component to allow flexible CSS definitions so we now have more fine-grained control over how the menu looks.
For details please upgrade and read the docs :grinning_face_with_smiling_eyes:

@Shawn_Pereira @imClumsyPanda @BeyondMyself @marduk @godot63

3 Likes

Thanks @victoryhb , God’s blessings for Streamlit veterans like you :slight_smile:

2 Likes

You are awesome @victoryhb , thanks so much! Will have some fun with this later today :partying_face:

1 Like

Thanks for mauch for this new version, it is fantastic. The menu now uses the full width before showing menu items on two lines. I love it!

3 Likes

nice update.

selected3 = option_menu(None, ["Home", "Upload",  "Tasks", 'Settings'], 
    icons=['house', 'cloud-upload', "list-task", 'gear'], 
    menu_icon="cast", default_index=0, orientation="horizontal",
    styles={
        "container": {"padding": "0!important", "background-color": "#fafafa"},
        "icon": {"color": "orange", "font-size": "25px"}, 
        "nav-link": {"font-size": "25px", "text-align": "left", "margin":"0px", "--hover-color": "#eee"},
        "nav-link-selected": {"background-color": "green"},
    }
)

image

4 Likes

Hi again @victoryhb and everyone,

Does anyone know how to use a Google Font in this component? Tried a couple of things but didn’t get it to work - code:

import streamlit as st
from streamlit_option_menu import option_menu

st.markdown("""
    <header>
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Permanent+Marker&display=swap" rel="stylesheet">
    </header>
    <style>
        html, body, h1, h2, h3, p, b [class*="css"] {font-family: 'Permanent Marker';}
    </style>
""", unsafe_allow_html=True)


st.title('Testing Streamlit Option Menu + Google Fonts')


selected3 = option_menu(None, ["Home", "Upload",  "Tasks", 'Settings'], 
    icons=['house', 'cloud-upload', "list-task", 'gear'], 
    menu_icon="cast", default_index=0, orientation="horizontal",
    styles={
        "container": {"padding": "0!important", "background-color": "#fafafa", "font-family": "Permanent Marker"},
        "icon": {"color": "orange", "font-size": "25px"}, 
        "nav-link": {"font-size": "25px", "text-align": "left", "margin":"0px", "--hover-color": "#eee"},
        "nav-link-selected": {"background-color": "green"},
    }
)

Hi @marduk, as the component is rendered in an iframe and insulated from the html code in markdown() in the main Streamlit page, I don’t think what you are trying to do is currently possible.

2 Likes

Do you have any sample code to create this page ?Can you please share?

Hi again @victoryhb ,

Still enjoying your component a lot :slight_smile:

Had a question though: when I hover the mouse over the menu options, my browser shows this (very ugly) path (see screenshot below). Do you know if there is a way to customize it or hide it?

Thanks in advance!

Hi @marduk, the link is like that due to the way Streamlit insulates third-party components (you may try other components and see something similar) and I don’t think there is much we can do about that (except fundamentally changing the underlying HTML, e.g., from a to button).

1 Like

Thank you @victoryhb very much for enhancing option-menu, I like it a lot and used it for navigation in each streamlit app I build.

I wish to submit a feature request if not on your roadmap already.
In the below example,

import streamlit as st
from streamlit_option_menu import option_menu

def do_home():
    st.write("home is where the heart is")

def do_setting():
    st.write("settings is my bettings")

menu_dict = {
    "Home" : {"fn": do_home},
    "Settings" : {"fn": do_setting},
}

selected = option_menu(None, 
    ["Home", "Settings"], 
    icons=["house", "gear"],
    default_index=0,
    orientation="horizontal")

if selected in menu_dict.keys():
    menu_dict[selected]["fn"]()

I have been using a menu_dict to associate menu-item with its action. However,
it would be nice if option_menu API accepts actions attribute with a list of callable python functions such as:

actions=[do_home, do_setting],

This would reduce amount of codes.
Thanks again!

2 Likes

Hi @wgong27514, thanks for the suggestion. However, while the suggested change may reduce the lines of code somewhat, it runs counter to the Python philosophy of “explicit is better than implicit” and therefore I don’t plan to implement it unless it is demonstrated to have other benefits.

Hi @victoryhb Thank you for evaluating the request and sharing your thought. I love your component as is

1 Like

Hi @victoryhb - I was having some fun trying out this nice component. Great contribution, thank you!

Using your component, I made a vertical sidebar options menu and horizontal main page option menus, one for each sidebar option selection. In all my apps I tend to use a page setting like this: st.set_page_config(page_title="My App", layout="wide"). The horizontal page menus appear centered in the main page area, as expected. However, I’d like to have them left-aligned (because on my wide screen this just looks much neater). Is there a "container" or other style setting that I can use to achieve this? If not, can left or right alignment be supported in your next release, please?

[What I tried as a workaround: I used st.columns to left align the page menus and this works quite well. But I found that the page content itself couldn’t contain columns as Streamlit doesn’t allow column nesting.]

Thanks,
Arvindra

2 Likes

Hi @asehmi, I think what you described is possible with CSS definitions introduced in the latest version. How you tried them yet?

1 Like

You’re right
 adding "margin": "0px !important" to the container style does the trick. Here’s a demo:
st-option-menu

Cheers!

2 Likes

Hi @victoryhb – This component is absolutely beautiful
 by far my favorite way to implement simple page-like navigation. Is it possible to implement the “on_change” streamlit function into the component?

The reason I ask: I need to save the user’s page selection into the URL using query_params (similar to this), but in order for it to work correctly, I need to update the session state using a callback when the page is changed by the user. So instead of option_menu I am using st.radio for now:

def update_query_params():
    st.experimental_set_query_params(page=pagelist.index(st.session_state.page))

selected_page = st.radio('', pagelist, index=page, key="page", on_change=update_query_params)

# selected_page = option_menu(None, pagelist, icons=pageicons, default_index=page, key="page", on_change=update_query_params)

Which works fine but is about 90% less beautiful vs your option_menu
 :sob:

2 Likes