streamlit / streamlit

Streamlit — A faster way to build and share data apps.
https://streamlit.io
Apache License 2.0
35.91k stars 3.11k forks source link

segmented_control with a required value #9870

Open RubenVanEldik opened 1 week ago

RubenVanEldik commented 1 week ago

Checklist

Summary

Hi all,

The segmented_control component is a fantastic new component that I think will be used a lot by Streamlit users.

However, I currently miss 1 option, that is to require a value. For example, now it is possible to provide a default value which can be unclicked.

Why?

In many use cases where segmented_control will be used in a single mode, the developer might want to force the user to select something.

How?

I propose to expand the segmented_control (and pills) API by adding an extra parameter 'required' . If required is True, a value must always be selected.

options = ["North", "East", "South", "West"]
selection = st.segmented_control(
    "Directions",
    options,
    selection_mode="single",
    required=True,
    default="South",
)
github-actions[bot] commented 1 week ago

To help Streamlit prioritize this feature, react with a 👍 (thumbs up emoji) to the initial post.

Your vote helps us identify which enhancements matter most to our users.

Visits

jrieke commented 1 week ago

Somewhat related: #7165

RubenVanEldik commented 1 week ago

Hi @jrieke! Thank you for the feedback. It is indeed related, but I think it is significantly easier to solve, as we won't need any front-end magic, I think. We only need to check if a required=True when the last item is deselected.

If y'all would be interested in this feature I could try to create a pull request for it. I think a lot of users would benefit from this!

tom-wood-red commented 1 week ago

I set my segmented controls with a default value, but I just noticed that it is possible to double-click on a segmented control and remove a value from it. I would like to stop that behaviour (I am trying to use them much like a prettier form of radio button), which I think setting required=True could be made to do (i.e. remove the option to set the value to None).

RubenVanEldik commented 1 week ago

I think “prettier version of a radio button” is a great way to describe how segmented controls will be used by many users!

I would love to hear from the maintainers if they are interested in supporting this feature and if the solution proposed here would work.

jrieke commented 6 days ago

Definitely interested in a PR! We also have a required parameter for several column config types, so this would match nicely. I think one thing I'd love to figure out before we commit to that parameter name is how we can in the future extend it to other commands. E.g. for st.selectbox, we were thinking in the past whether we should have a parameter clearable that shows a little X on the right side to delete the selection (similar to st.multiselect). Both concepts are pretty similar but have some differences. Let me put this on my todo list and try to think it through in the next few days!

jrieke commented 6 days ago

Another question is how we deal with default values. E.g. if required=True but default=None, should this just select the first value? Or have no value selected until the user selects one? Or raise an exception?

RubenVanEldik commented 6 days ago

Thank you for the input!

I think clearable and required are indeed very similar. Clearable is, I think, the exact opposite behaviour of required. To standardize the naming we should select a single name for all these components. (It’s up to you to select which name ;)) There are basically 3 states for the required keyword:

  1. auto: this is the current behaviour in selectbox, where it is only clearable if the default is None
  2. False: this is the current behaviour for segmented_control.
  3. True: the behaviour requested in this issue

I think we should remove the ‘auto’ behaviour in selectbox, as this is both opaque (I only found out about this last month, after using Streamlit for over 2 years) and it makes the Streamlit codebase cleaner. This would be a breaking change though. However, this is up to you, and can be handled completely separately from this request.

Regarding the default values. We can use overloads to only accept the combination required=True, default=T and the combination required=False, default=T | None. This will force all typed repositories to use it correctly and we can raise an error during runtime if this is not the case.

I am currently on holiday, I can start on a simple demo PR in two weeks.

Apologies for any errors, I wrote this on my phone.