Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@sfc-gh-lwilby
Copy link
Collaborator

Describe your changes

Our original implementation doesn't render expanders when they are empty. This PR removes this restriction so that empty expanders are rendered.

st.expander("Empty expander")

Screenshot 2025-06-17 at 2 55 31 PM

Our original implementation doesn't render containers when they are empty (except if a height is provided). This modifies the implementation so that containers without height but with a border are also rendered. Empty containers with no border and no height are not rendered.

# Test that an empty container with a border is rendered.
with st.container(border=True):
    st.container(border=True)

# Test that an empty container with height is rendered.
with st.container(border=True):
    st.container(height=200)

# Test that an empty container without height or border is not rendered.
with st.container(border=True):
    st.container()

Screenshot 2025-06-17 at 2 56 00 PM

GitHub Issue Link (if applicable)

Testing Plan

Unit Tests (JS and/or Python) ✅
E2E Tests ✅


Contribution License Agreement

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.

@sfc-gh-lwilby sfc-gh-lwilby added security-assessment-completed Security assessment has been completed for PR change:bugfix PR contains bug fix implementation impact:users PR changes affect end users labels Jun 17, 2025
@snyk-io
Copy link
Contributor

snyk-io bot commented Jun 17, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

license/snyk check is complete. No issues have been found. (View Details)

@github-actions
Copy link
Contributor

github-actions bot commented Jun 17, 2025

✅ PR preview is ready!

Name Link
📦 Wheel file https://core-previews.s3-us-west-2.amazonaws.com/pr-11669/streamlit-1.45.1-py3-none-any.whl
🕹️ Preview app pr-11669.streamlit.app (☁️ Deploy here if not accessible)

@sfc-gh-lwilby sfc-gh-lwilby force-pushed the fix/render-empty-containers-with-border-empty-expanders branch from 3f79f53 to 2b1f5ad Compare June 17, 2025 14:38
@sfc-gh-lwilby sfc-gh-lwilby marked this pull request as ready for review June 18, 2025 13:39
def test_empty_expander_not_rendered(app: Page):
"""Test that an empty expander is not rendered."""
expect(app.get_by_text("Empty expander")).not_to_be_attached()
expect(app.get_by_text("Empty expander")).to_be_visible()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (non-blocking): Consider adding snapshot tests for these scenarios.

Copy link
Collaborator Author

@sfc-gh-lwilby sfc-gh-lwilby Jun 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking for these we could save some snapshot space. But I was on the fence with this one since there are some visual details of how the expander looks when empty that could be altered.

Comment on lines 79 to 83
def test_empty_expander_rendered(app: Page, assert_snapshot: ImageCompareFunction):
"""Test that an empty expander is not rendered."""
expect(app.get_by_text("Empty expander")).not_to_be_attached()
empty_expander = app.get_by_test_id("stExpander").nth(13)
expect(empty_expander).to_be_visible()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring for test_empty_expander_rendered() still states "Test that an empty expander is not rendered" which contradicts the new behavior being implemented and tested. The docstring should be updated to accurately reflect that the test is now verifying empty expanders are rendered, matching the actual test assertions and the PR's purpose.

Suggested change
def test_empty_expander_rendered(app: Page, assert_snapshot: ImageCompareFunction):
"""Test that an empty expander is not rendered."""
expect(app.get_by_text("Empty expander")).not_to_be_attached()
empty_expander = app.get_by_test_id("stExpander").nth(13)
expect(empty_expander).to_be_visible()
def test_empty_expander_rendered(app: Page, assert_snapshot: ImageCompareFunction):
"""Test that an empty expander is rendered."""
empty_expander = app.get_by_test_id("stExpander").nth(13)
expect(empty_expander).to_be_visible()

Spotted by Diamond (based on custom rules)

Is this helpful? React 👍 or 👎 to let us know.

@sfc-gh-lwilby sfc-gh-lwilby merged commit 461bf4c into develop Jun 20, 2025
37 checks passed
@sfc-gh-lwilby sfc-gh-lwilby deleted the fix/render-empty-containers-with-border-empty-expanders branch June 20, 2025 09:09
@okapiadmin
Copy link

okapiadmin commented Sep 27, 2025

Sadly, my code takes advantage of what I did not know was a bug. I want my expanders to only render when not empty. Is it possible to add a parameter that makes this a controllable feature? e.g.,
st.expander(label, expanded=False, *, icon=None, width="stretch", display_empty=True)

@sfc-gh-lwilby
Copy link
Collaborator Author

Sadly, my code takes advantage of what I did not know was a bug. I want my expanders to only render when not empty. Is it possible to add a parameter that makes this a controllable feature? e.g., st.expander(label, expanded=False, *, icon=None, width="stretch", display_empty=True)

Can you give more details of what you are trying to do @okapiadmin ? The expanders are not being rendered when they are empty except when they have height or a border, is your issue that you want to style with a border or height but hide them when empty? Or is the issue you want to display an empty expander with no border/height?

cc @jrieke

@okapiadmin
Copy link

The code I use to set up the filters is "st.expander(label, expanded=True)". I do not set the height and am not aware of an st.expander parameter that controls the border.

The app in question (https://nychsfilter.streamlit.app) allows users to dynamically select filters from >100 choices. To make it easier to navigate the filters are grouped into categories with one expander per category The expanders are set up early in the code and filter widgets are added later. The desired behavior is to render expanders if and only if they contain at least one filter widget.

The live production version, running streamlit 1.44.1, does not render empty expanders. This is as desired. When I run locally, the code behaves as desired with streamlit 1.46.1 and below; but starting with 1.47.0 all expanders - including empty ones - are rendered.

@sfc-gh-lwilby
Copy link
Collaborator Author

@okapiadmin ahh, yes, sorry we changed this also for containers and I was thinking of the behaviour for containers. For st.expander the decision was to always render it since it always has some visible part even when empty.

Can you create an enhancement request with your use case? Our product/design team will take a look at the enhancement issue to weigh in.

But also, for your app, I think there could be a workaround using a wrapper function, or maybe classes. If you are able to share the source code I could take a look.

@sfc-gh-jrieke
Copy link
Contributor

@okapiadmin Feel free to create a GitHub issue as an enhancement, so we can see if other people want the same thing :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:bugfix PR contains bug fix implementation impact:users PR changes affect end users security-assessment-completed Security assessment has been completed for PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants