[DynamicContainers] Callback support for expanders#14008
[DynamicContainers] Callback support for expanders#14008sfc-gh-lwilby merged 1 commit intodevelopfrom
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
✅ PR preview is ready!
|
📉 Frontend coverage change detectedThe frontend unit test (vitest) coverage has decreased by 0.0000%
✅ Coverage change is within normal range. |
8346511 to
b1364c6
Compare
b3c1e40 to
94a0eba
Compare
There was a problem hiding this comment.
Pull request overview
Adds callable on_change callback support to st.expander, including passing args/kwargs and enforcing key when a callback is used.
Changes:
- Extend
st.expander(on_change=...)to accept a callable plus optionalargs/kwargs. - Add/expand unit, typing, and Playwright E2E coverage for callback behavior.
- Update
st.expanderdocstring to describe the new callback mode.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/streamlit/elements/layouts.py | Adds callback + args/kwargs support to st.expander and updates validation/docs. |
| lib/tests/streamlit/elements/layouts_test.py | Adds unit tests covering callback requirements, firing behavior, and args/kwargs passthrough. |
| lib/tests/streamlit/typing/expander_container_types.py | Adds typing assertions for the new on_change callable and args/kwargs. |
| e2e_playwright/st_expander.py | Adds an E2E demo app section exercising callback expanders. |
| e2e_playwright/st_expander_test.py | Adds E2E tests verifying callback fires on toggle and receives args/kwargs. |
lib/streamlit/elements/layouts.py
Outdated
| serializer=serde.serialize, | ||
| ctx=ctx, | ||
| value_type="bool_value", | ||
| on_change_handler=on_change if callable(on_change) else None, | ||
| args=args, | ||
| kwargs=kwargs, |
There was a problem hiding this comment.
args/kwargs are forwarded to register_widget even when on_change_handler is None (e.g., on_change="rerun"). This makes it look like args/kwargs are supported for non-callback modes and can create inconsistent state/config. Consider only passing args/kwargs when on_change is callable (otherwise pass None) and/or raising a StreamlitAPIException if args/kwargs are provided without a callable.
94a0eba to
aaa79d8
Compare
ce0cc59 to
adfae87
Compare
| def test_expander_callback_with_args_kwargs(app: Page): | ||
| """Test that a callback with args and kwargs receives them correctly.""" | ||
| # Initially no result | ||
| expect(app.get_by_text("Callback args result:")).to_be_visible() | ||
|
|
There was a problem hiding this comment.
suggestion: Consider doing a direct string match rather than a substring match here. I believe as written this will pass for both Callback args result: and Callback args result: hello-toggled-world.
There was a problem hiding this comment.
Made this update to AGENTS.md about this as well #14102
lib/streamlit/elements/layouts.py
Outdated
|
|
||
| if on_change not in {"ignore", "rerun"}: | ||
| if not callable(on_change) and on_change not in {"ignore", "rerun"}: | ||
| raise StreamlitValueError("on_change", ["'rerun'", "'ignore'"]) |
There was a problem hiding this comment.
suggestion: Consider adding "a callable" to the StreamlitValueError.
Co-authored-by: lawilby <[email protected]>
adfae87 to
62f405e
Compare

Describe your changes
Adds callable
on_changecallback support tost.expander, extending the existing"ignore"/"rerun"string literals.on_changenow accepts a callable in addition to the existing string optionsargsandkwargsparameters pass through to the callbackkeywhen using a callable (consistent with existing expander behavior wherekeyis required for"rerun")st.session_state[key]inside the callback to distinguish between expand (True) and collapse (False) events.GitHub Issue Link (if applicable)
Testing Plan
lib/tests/streamlit/elements/layouts_test.pye2e_playwright/st_expander_test.pyContribution License Agreement
By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.