Possible bug? st.date_input inside @st.dialog

Hello everybody!

Using Streamlit 1.56.0, a simple combination of st.date_input inside a @st.dialog seems to misbehave, as the date picker keeps coming up after selection; clicking outside the picker stops it from coming back up. Below a quick snippet to reproduce this behavior.

Can anyone confirm and/or sugggest a workaround?

Regards.

import streamlit as st

st.title(“Bug: date input inside dialog”)

@st.dialog(“Enter Capacity Update”, width=“large”)

def popup():

col1, col2 = st.columns(\[1,2\])  

with col1:

    valid_from = st.date_input("Valid From:")

with col2:

    update_comment = st.text_area(label = "Comments", placeholder = "Update Comment (Optional)")

if st.button(“Launch dialog and select a date…”):

popup()

st.write(“…the date picker won’t close automatically and keeps popping up.”)

st.write(“Now compare with the normal behaviour, where the dialog is closed after a selection.”)

valid_from = st.date_input(“Valid From:”)

update_comment = st.text_area(label = “Comments”, placeholder = “Update Comment (Optional)”)

Welcome to the community and thanks for the clear repro! :tada: Yes, this is a known UX quirk: when you use st.date_input inside an @st.dialog, the date picker can keep popping up after selection, especially if the dialog is reopened or rerun—this is due to the dialog auto-focusing the first widget, which causes the calendar popup to reappear. Clicking outside the picker or dialog will stop it, but it’s not ideal for users. This behavior has been confirmed by others and is tracked in Streamlit’s issue tracker (see GitHub issue #11808).

Currently, there isn’t an official fix or built-in workaround in Streamlit 1.56.0. Some users try to shift focus programmatically or add a dummy widget before the date input, but results are mixed. If this bug is a blocker, consider using a custom date picker component (like st-rsuite) or placing the date input outside the dialog for now. If you have a minimal reproducible example or repo, please share it—others may have creative workarounds! Community, feel free to jump in with your solutions or vote on the linked GitHub issue to help prioritize a fix.

Sources: