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

+1 for the on_change parameter! I also stumbled into this when adding it to streamlitbook

2 Likes

@joe @sebastiandres Thatā€™s a reasonable feature request. It will be available in the next release. Please stay tuned.

5 Likes

Really? Awesome! Thanks!!!

1 Like

Very awesome, thanks @victoryhb ! Youā€™re the man. Looking forward.

1 Like

Hi, I love this component, thank you for sharing with us !

I was wondering if there was any way to change the displayed page by clicking on a button or something ?

For example, on page 1 I could ask users to fill out different parameters and when they click a submit button it would send them on page 2 and run a function with their chosen parameters ? I know I can make it all happen on the same page but Iā€™d like to keep things separated while still have some interconnection between pagesā€¦

Though, Iā€™d understand if that is outside the scope of this project.

Hi @florianbrnrd, AFAIK, there is no concept of ā€œpageā€ in Streamlit. However, different states resulting from user actions can be saved in the session state, which you can use to select a particular menu item (using default_index) when the same code is run again after button clicks.

Hi, thanks for the reply.
I understand what you mean but since your option-menu makes it possible to show different pages/app/content based on what is selected it made me think it would be nice to be able to ā€œpropagateā€ some data from one page/app to the other.
I did some testing on my own and I eventually came up with what you described, and it worked fairly ok using session_state, but -indeed- the way streamlit works (and rerun pages from top to bottom) makes it hard to fully implement what I had in mind !
Guess Iā€™ll settle for a more simplistic behavior for my app.
Thanks again for the component, Iā€™m going to use it all the time :slight_smile:

Hi all (@victoryhb),

Iā€™m building an app and wanted to have a simpler way to describe nested menu structures with this nice component. I came up with something like this below (a simple example) along with the code that runs it:

menu = {
    'title': 'Todo App',
    'items': { 
        'Home' : {
            'action': None, 'item_icon': 'house', 'submenu': {
                'title': None,
                'items': { 
                    'View Tasks' : {'action': do_view_tasks, 'item_icon': 'list-task', 'submenu': None},
                    'Manage Tasks' : {'action': do_manage_tasks, 'item_icon': 'list-check', 'submenu': None},
                    'Upload Tasks' : {'action': do_upload_tasks, 'item_icon': 'cloud-upload-fill', 'submenu': None},
                },
                'menu_icon': None,
                'default_index': 0,
                'with_view_panel': 'main',
                'orientation': 'horizontal',
                'styles': styles
            }
        },
        'Settings' : {
            'action': None, 'item_icon': 'gear', 'submenu': {
                'title': None,
                'items': { 
                    'Manage Credentials' : {'action': do_credentials, 'item_icon': 'key', 'submenu': None},
                    'View Logs' : {'action': do_logs, 'item_icon': 'journals', 'submenu': None},
                },
                'menu_icon': None,
                'default_index': 0,
                'with_view_panel': 'main',
                'orientation': 'horizontal',
                'styles': styles
            }
        }
    },
    'menu_icon': 'clipboard2-check-fill',
    'default_index': 0,
    'with_view_panel': 'sidebar',
    'orientation': 'vertical',
    'styles': styles
}

In theory this dict object could be externalized in a json file. The menu renderer, show_menu(), can be modified to consume and display the json representation. You could then display different menus depending on authorization rules, for example. In a similar vein, the menu scheme can be easily augmented with role scope attributes that the menu renderer uses to include/exclude menu options.

Hope someone finds it useful.

Arvindra

3 Likes

Copy from github issue here
Hi @victoryhb and @andfanilo and All
Thank you very much for this component, it makes my app more beautiful and user-friendly.
My streamlit-option-menu version is 0.3.2.
After I deploy my app on the server, I find a problem that I cannot overcome even I try my best to set different kind of ā€œstylesā€ option.(BTW, Iā€™m not familiar with CSS).
If my app runs on the widescreen displayer, after user maximizes the webpage, the option_menu couldnā€™t extend the width just like the other widget, there is empty space on the left and right of the option menu , just like the following picture

Is there a parameter such as use_column_width for st.image ? or Can I just set some parameters for styles parameter?

Need your kindly suggestions.
Thanks a lot
This text will be hidden

Hi @asehmi, your solution to handle complex menu structures reminds me a similar one I came up with while trying to reduce some boilerplate code and make easier dealing with streamlit-option-menu.

Since you kindly share with us all your solution, I decided to share mine as well with same spirit :slight_smile: and thanks of course to @victoryhb for such an amazing component!

I quickly packaged my solution within a demo app: hope can be useful or inspiring for someone!

@asehmi I like your approach because it tries to standardize menu structures in a commonly used format like JSON - I took a shot with Pythonā€™s dataclasses but more or less on a similar path. And, just like in your last sentence, I also had the need to restrict some page display to a whitelist of selected users: I found that the usage of session state and auth methods suggested in the docs are just the cherry on top! :cherries:

3 Likes

@sis Nice. Good job on your solution and thanks for sharing. There are many ways to skin the cat as they say. In my solution I wanted to keep the MVC parts quite separate (M = model/representation, V = view/option-menu component, C = controller/renderer).

P.S. I couldnā€™t get your demo to load. Perhaps it needs restarting?

Great to see this component, the best have ever see

@asehmi got it, I didnā€™t know about MVC pattern (Iā€™m just an amateur software dev :slight_smile:) but I will definitely deep dive about pros and cons, thanks!

About the demo app: itā€™s really strange, I checked it just now and seems to be up and running. Anyway, I tried rebooting: hope this will make it available again to everyone.

This is the error still showing in my console

Hello, @victoryhb! First of all, congrats on your creation! Itā€™s trully amazing! I have a doubt regarding one thing: Is it possible to change the frontend menu through the backend? What happens is that after running a model training I would like to go back automatically to the home page, but Iā€™m not able to send this to option_menu this command. It brings me the error that Iā€™m trying to create two option menus, one with the command coming from the front end and the other coming from the backend. Thank you!

options = option_menu(ā€œMain Menuā€, [ā€œInput Dataā€, ā€œData preparationā€,ā€œparametersā€,ā€œotherā€],
icons=[ā€™ box arrow in down ', ā€™ wrench adjustable ā€˜,ā€™ bar chart line ā€˜,ā€™ map '], menu_icon=ā€œcastā€, default_index=0)
options
hello.
I use this code but when running it, the icon of options doesnā€™t show.
is need to do code for using bootstrap icons?

Hi @victoryhb this is a great little component, do you know if thereā€™s a way to use this in combination with the new official multi-page feature Streamlit recently announced? Introducing multipage apps! šŸ“„

Weā€™d like to use this new mutli-page functionality to be able to break up the app a little more but I really like the visual styling of your options-menu (and ability to use bootstrap icons) better than the default Streamlit emoji-type menu for multi-page apps shown in the blog post above.

Have you tried it with the ā€œ-ā€ between the words of the icon names instead of spaces? ā€˜box-arrow-in-downā€™ instead of ā€˜box arrow in downā€™

Demonstrated here.

1 Like

Perfect, thank you!!

1 Like