New Component: streamlit-tree-select, a simple and elegant checkbox tree

Hello everyone,

I created my first custom component for a simple and elegant checkbox tree user input.

It’s super useful if you if you would like to improve the user experience when it comes to user inputs with underlying tree like structures.

Check out the documentation on GitHub: streamlit-tree-select

16 Likes

Sexy! Will definitely use

This is such a beautiful component! Well done @Schluca, and welcome to our forum :balloon:

Beautiful! You should definitely add this to the tracker: Streamlit Components - Community Tracker so we don’t lose track of it!

Fanilo

I like this! Will think about where I might be able to use it.

1 Like

Hi @Schluca - Very useful component and I’m trying to use it with a list of 2,500+ cities arranged in a hierarchy of regions/countries/cities. I want to be able to control selection of leaf city nodes. The default behaviour is multi-select, but I have cases where I require single-select. How can I configure single selection only? Essentially, any previous selection would be removed and the current selection would be checked.

Any ideas, and/or can you add this feature please?

Also, can you please add another (optional) property to the node specification, called metadata, so one can add additional properties to the tree which will be returned in addition to the value. I could shoehorn this meta data into the value string, but it would be neater to have a metadata property.

Many thanks,
Arvindra

Thank you so much!

Hi @asehmi, thank you very much!

I’m not quite sure what you are looking for. Would you like single selection per region or countries? Should the user be able to select one city per country or one per region? Currently it is not implemented but I will have a look into it. On the react-checkbox-tree I found a discussion regarding the topic which might be possible to implement: https://github.com/jakezatecky/react-checkbox-tree/issues/206

I will definitely take a look how I could implement the metadata implementation, but if you have time and ideas feel always free to contribute.

Lucas

Thank you very much! I will definitely add it once I reached Trust Level 1. :sweat_smile:

1 Like

Hi,

If I could allow only one leaf node at a time to be selected, that would be awesome. Here’s an example tree you can use:

[
    {
        "label": "Americas",
        "value": "Americas",
        "children": [
            {
                "label": "United States",
                "value": "United States",
                "children": [
                    {
                        "label": "Boston",
                        "value": "BOS"
                    },
                    {
                        "label": "Chicago",
                        "value": "CHI"
                    },
                    {
                        "label": "New York",
                        "value": "NYC"
                    },
                    {
                        "label": "San Francisco",
                        "value": "SFO"
                    },
                    {
                        "label": "Seattle",
                        "value": "SEA"
                    },
                    {
                        "label": "United States - Total",
                        "value": "USTOT"
                    }
                ]
            }
        ]
    },
    {
        "label": "Europe",
        "value": "Europe",
        "children": [
            {
                "label": "United Kingdom",
                "value": "United Kingdom",
                "children": [
                    {
                        "label": "Cambridge",
                        "value": "CMB"
                    },
                    {
                        "label": "London",
                        "value": "LDN"
                    },
                    {
                        "label": "Oxford",
                        "value": "OXF"
                    },
                    {
                        "label": "United Kingdom - Total",
                        "value": "UKTOT"
                    }
                ]
            }
        ]
    }
]

Having a metadata property isn’t important, as I could put a json string into the value property if necessary.

What would be really useful is to auto-generate an id field on your end to make the nodes unique. Currently, (in my full tree of 2,500+ nodes) I had to fudge the label names of some nodes as they collided. E.g. the Singapore city node label needs to be made different from the Singapore country node label, because they have the same name of course. This would make it simpler to create trees with branches that have different views on the same set of nodes, e.g. viewing economic indicators by country > indicator or by indicator > country.

In summary:

  1. Configurable single node selection
  2. Use an id property to distinguish nodes (user-supplied or generated silently)

Thanks,
Arvindra

P.S. I raised a couple of issues on your GitHub repo.

1 Like

@Schluca - Hi there, Thanks for this component. I raised a couple of issues / feature requests about this component in your GitHub repo. I was wondering if you have a plan to address these, so I can decide what to do next?

Thanks,
Arvindra

@Schluca Thank you for such a great solution! I plan to use it to display a tree on the sidebar for navigation.
Is it possible to configure for single node selection, be it leaf node or parent node?
Based on the singly selected node, I display content in the main section.

@Schluca thanks a lot for this component. I use it in my app currently. Unfortunately, for streamlit-tree-select, the color of .rct-title does not seem to inherit text-color from the theme.
Bild_2023-09-06_152635031

As a consequence, the contrast in the standard dark mode sidebar makes it almost unreadable. Same for the unchecked boxes (.rct-icons-fa4 .rct-icon-uncheck::before)

Bild_2023-09-06_152850004

I tried CSS hack and streamlit.components.v1 to change the color but I failed so far…

Maybe, you can fix this bug?

Also maybe @andfanilo has a way in mind to hack this in the meantime (I fail to get the selector right…)

Thanks a lot! Great component!

Hey @Schluca , congratulations for your component! It is really easy to use, and has been extremely useful on a project I’m currently working on.
I wanted to show, for each of the leaves, a total value so the user could know how many of that particular exam we have in the database. The only way I could highlight these values was replacing them (while creating the leaf’s name) with emoji-structured integer numbers, as in the following image:

exam_tree

However, for numbers with two or more digits, we have a ‘gap’ between the emojis, so it’s not so clear that in the above image we have a “11” and a “12”. I have seen that this space between emojis can be managed with CSS, but that would only work if the leaves’ names were structured in markdown.
Could I manage the component’s inner CSS in order to do it? Thanks!!

I have nodes as below where I need user to fill up text if “Others” were checked. Unfortunately, I have more than one “Others” and it is not allowed by streamlit. I comment it out to and the input text of Others is display above the tree-select (supposed display below the “Trading”) as shown in the picture below. Is there any way I can display it in correct location?
Secondly, the “Service Supplier” although is checked (sub tree under Service Supplier not fully checked), it is not recorded in dict of “checked” and only recorded as “expanded”. It will be a issue as expanded doesn’t mean is checked (as per picture)

       nodes = [
           {"label": "Material Supplier", "value": "Material Supplier"},
           {
               "label": "Service Supplier",
               "value": "Service Supplier",
               "children": [
                   {"label": "Automation", "value": "Automation"},
                   {"label": "Engineering", "value": "Engineering"},
                   {"label": "Logistics", "value": "Logistics"},
                   {"label": "Management", "value": "Management"},
                   {"label": "Consulting", "value": "Consulting"},
                   {"label": "Trading", "value": "Trading"},  
                   {"label":"Others","value": st.text_input(label="Others",key="1")}, 
               ],
           },
           {
               "label": "Steel User",
               "value": "Steel User",
               "children": [
                   {"label": "Roll Formers", "value": "Roll Formers"},
                   {"label": "Coil Service Centres", "value": "Coil Service Centres"},
                   {"label": "Fabricators", "value": "Fabricators"}, 
                   #{"label":"Others","value": st.text_input(label="Others",key="2")}, 
               ],
           },