[feat] Extract leading icon from alert body#14173
Conversation
…ovided When the `icon` parameter is not explicitly set, alert functions (st.error, st.warning, st.info, st.success) now automatically extract a leading emoji or Material icon from the body text and use it as the alert icon. - Add `extract_leading_icon` function to string_util.py - Add `_process_alert_body_and_icon` helper to alert.py - Comprehensive unit tests for icon extraction logic - E2E tests for emoji and material icon extraction from body
✅ 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!
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
There was a problem hiding this comment.
Pull request overview
This PR adds automatic extraction of a leading emoji or material icon shortcode from the body text of st.error(), st.warning(), st.info(), and st.success() alert functions, when no explicit icon parameter is provided. Previously, an emoji at the start of the body was rendered inline; now it is promoted to the alert's icon slot and removed from the body text. Explicit icon parameters always take precedence over auto-extraction.
Changes:
- A new
extract_leading_icon()function instring_util.pythat checks for a leading material icon shortcode (validated) or emoji at the start of a string and returns a(icon, remaining_text)tuple. - A new
_process_alert_body_and_icon()helper inalert.pythat replaces the directvalidate_icon_or_emoji/clean_textcalls in all four alert methods, adding the auto-extraction logic. - Tests and E2E test cases covering the new extraction behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
lib/streamlit/string_util.py |
Adds extract_leading_icon() function for material icon/emoji detection at start of text |
lib/streamlit/elements/alert.py |
Refactors alert body/icon processing into _process_alert_body_and_icon() with auto-extraction |
lib/tests/streamlit/string_util_test.py |
Unit tests for the new extract_leading_icon() function |
lib/tests/streamlit/elements/alert_test.py |
Unit tests verifying extraction behavior in all four alert types |
e2e_playwright/st_alert.py |
Adds two new test alert cases with leading emoji and material icon |
e2e_playwright/st_alert_test.py |
Updates alert count assertions and adds snapshot tests for the new extraction cases |
Consolidated Code ReviewSummaryThis PR adds automatic leading-icon extraction for alert elements ( Key implementation changes:
Reviewer AgreementBoth reviewers (
Verified FindingsAfter inspecting the codebase, I verified:
IssuesBlocking
Non-Blocking (Recommendations)
Code QualityThe implementation is clean and follows existing patterns well:
Test Coverage
Security & RiskNo security concerns. The implementation reuses existing, battle-tested validation functions. Regression risk is moderate due to the behavioral nature of the change — it silently alters how existing alert calls render when they have leading emoji/icons in the body text. AccessibilityNo accessibility concerns. Moving the icon from inline body text to the dedicated icon slot is neutral or positive since the icon slot likely has better semantic handling in the existing Alert frontend component. VerdictCHANGES REQUESTED: The core implementation is solid and well-tested, but the PR is not merge-ready due to (1) inaccurate public API docstrings and (2) missing E2E snapshot baselines that will cause CI failures. The opt-out mechanism concern should also be addressed or explicitly documented before merge. Consolidated review by 📋 Review by `gpt-5.3-codex-high`SummaryThis PR adds automatic leading-icon extraction for alerts: when Code QualityThe implementation is clean and avoids duplication by routing all four alert commands through a shared helper in Issue:
Test CoverageCoverage is generally strong:
Blocking issue:
Backwards CompatibilityThe explicit Security & RiskNo direct security concerns identified. AccessibilityNo frontend structural changes were made, so accessibility risk is low. Existing alert rendering/accessibility semantics should remain unchanged. Recommendations
VerdictCHANGES REQUESTED: The core implementation is solid, but the PR is not merge-ready until missing e2e snapshot baselines are added (and docs are aligned with the new behavior). This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR adds automatic extraction of a leading emoji or Material icon from alert body text ( Key changes:
Code QualityThe implementation is clean and well-structured. The A few observations:
Test CoverageUnit tests (
E2E tests (
Backwards CompatibilityThis is a breaking behavioral change for existing users whose alert body text starts with an emoji or Material icon shortcode and who do not pass an explicit # Before: 🔔 displayed inline in body text
st.warning("🔔 Important notification")
# After: 🔔 extracted as icon, body shows only "Important notification"While arguably an improvement in UX, this will silently change the rendering of existing apps. Users who intentionally placed emoji at the start of body text for inline display currently have no way to opt out without modifying their text content. The explicit Recommendation: Consider whether this should be gated behind a deprecation cycle, a config option, or at minimum prominently documented in a changelog/migration guide. At the very least, provide a documented workaround for users who want to suppress extraction. Security & RiskNo security concerns identified. The implementation reuses existing validation functions ( Regression risk is moderate due to the behavioral nature of the change — it silently alters how existing alert calls render when they have leading emoji/icons in the body text. AccessibilityNo accessibility concerns. The icon extraction simply changes where the icon is rendered (from inline body to the dedicated icon slot), which is already handled by the existing frontend Alert component. This should be a neutral or positive accessibility change since the icon slot likely has better semantic handling. Recommendations
VerdictCHANGES REQUESTED: The implementation is solid and well-tested, but the docstrings are inaccurate after this change (stating "no icon is displayed" when This is an automated AI review by |
Refactor _transformed_format_func in button_group.py to use the shared extract_leading_icon utility instead of manual icon detection logic. This keeps icon extraction consistent across st.alert and st.pills.
## Describe your changes Automated snapshot updates for #14173 created via the snapshot autofix CI workflow. This workflow was triggered by adding the `update-snapshots` label to a PR after Playwright E2E tests failed with snapshot mismatches. **Updated snapshots:** 12 file(s)⚠️ **Please review the snapshot changes carefully** - they could mask visual bugs if accepted blindly. This PR targets a feature branch and can be merged without review approval. Co-authored-by: Streamlit Bot <[email protected]>
Add re.DOTALL flag to EMOJI_EXTRACTION_REGEX to ensure multiline body text is preserved when extracting leading emoji icons, consistent with the material icon extraction path.
…for alerts - Add E2E text assertions to verify body text is correctly separated from extracted icon (not just visual snapshot comparison) - Add integration test for multiline body extraction with material icons to validate re.DOTALL flag works correctly end-to-end
Consolidated Code ReviewSummaryThis PR adds automatic extraction of a leading emoji or Material icon shortcode from alert body text ( Code QualityBoth reviewers agree the implementation is clean, well-structured, and follows existing codebase patterns. Specific highlights:
Disagreement on button_group.py regression risk:
Consolidator verdict on this disagreement: GPT-5.3's concern is technically correct. The Test CoverageBoth reviewers agree test coverage is thorough and well-organized:
Shared gap identified by both reviewers: No test covers the Backwards CompatibilityBoth reviewers acknowledge this is an intentional behavioral change: previously,
Both reviewers confirm that explicit Security & RiskNo security concerns identified by either reviewer. The changes only parse text against known emoji/icon sets and validate material icon names. No user input is executed or used in unsafe contexts. Risk assessment (agreed):
AccessibilityBoth reviewers agree there are no accessibility concerns. Moving icons from inline body text to the dedicated icon slot is semantically better for screen readers. Recommendations
VerdictAPPROVED -- Well-implemented feature with thorough test coverage and clean code. Both reviewers agree on code quality and test completeness. The key disagreement on the button-group regression is resolved: while GPT-5.3's concern is technically valid, the edge case is extremely narrow and unlikely to affect real users. The behavioral change to alerts is intentional and properly labeled. The recommendations above are non-blocking suggestions for follow-up. Consolidated review by Expected models: gpt-5.3-codex-high, opus-4.6-thinking -- all present. 📋 Review by `gpt-5.3-codex-high`SummaryThis PR adds automatic extraction of a leading emoji or Material icon from alert body text when Code QualityOverall, the implementation is clean and mostly consistent with existing patterns, but there is one functional regression in the button-group refactor:
Test CoverageCoverage is strong for the new alert feature:
Gap related to the regression above:
Backwards CompatibilityAlert behavior changes are intentional and documented (auto-extraction when However, the button-group refactor introduces an unintended compatibility change for certain formatted option labels (e.g. trailing Security & RiskNo direct security issues found. AccessibilityNo frontend accessibility regressions were identified in this PR. The change is backend-driven and e2e snapshots/text assertions confirm expected rendering for the new alert icon extraction cases. Recommendations
VerdictCHANGES REQUESTED: Alert extraction changes are good, but the button-group refactor introduces a backward-incompatible parsing regression that should be fixed before merge. This is an automated AI review by 📋 Review by `opus-4.6-thinking`SummaryThis PR adds automatic extraction of leading emojis or Material icon shortcodes from alert body text ( Code QualityThe code is well-structured and follows existing patterns in the codebase.
Test CoverageTest coverage is thorough and well-organized:
Backwards CompatibilityThis is a behavioral breaking change for existing users. Previously, Key considerations:
Security & RiskNo security concerns identified. The changes only parse text against known emoji/icon sets and validate material icon names. No user input is executed or used in unsafe contexts. Regression risks:
AccessibilityNo accessibility concerns. The feature moves icons from inline body text to the dedicated icon slot, which is semantically better for screen readers that can distinguish between icon and text content in the alert structure. Recommendations
VerdictAPPROVED: Well-implemented feature with thorough tests and clean code. The behavioral breaking change is acknowledged via labels and the explicit-icon-takes-precedence design ensures a smooth upgrade path for most users. The recommendations above are non-blocking suggestions for follow-up. This is an automated AI review by |
| it parsed to the frontend. | ||
|
|
||
| Note: The icon is only extracted if it's followed by a space or is the | ||
| entire content (icon-only). This matches the original behavior. |
There was a problem hiding this comment.
nit: I would remove the This matches the original behavior. comment as it seems like an LLM point-in-time comment.
Address PR review feedback to remove point-in-time comments that reference "original behavior" rather than describing current state.
Describe your changes
Automatically extract a leading emoji or Material icon from alert body text when no explicit
iconparameter is provided.st.error(),st.warning(),st.info(), orst.success()without aniconparameter, the function now checks if the body starts with an emoji or Material icon shortcode (e.g.,:material/warning:)iconparameter takes precedence over body extraction (backwards compatible)Example:
Github
st.warningetc pick up icons at the beginning of the text #10892Testing Plan
extract_leading_iconinstring_util_test.pyalert_test.py