Skip to content

Simplify theme caching logic#13593

Merged
sfc-gh-mbarnes merged 7 commits intodevelopfrom
update-theme-cache
Jan 17, 2026
Merged

Simplify theme caching logic#13593
sfc-gh-mbarnes merged 7 commits intodevelopfrom
update-theme-cache

Conversation

@mayagbarnes
Copy link
Copy Markdown
Collaborator

@mayagbarnes mayagbarnes commented Jan 15, 2026

Describe your changes

Refactor theme caching logic to store only the high‑level selection - "System", "Light", or "Dark" in localStorage as a simple string instead of persisting any theme configs.

  • Simplifies cache behavior (also sets the stage for upcoming app menu refactor)
  • Bump the cache version to clean up old cache entries
  • Improves handling of system preference updates for custom themes (which now have an auto when light & dark themes defined)
  • Consistently applies the logic behind Fix custom theme when embedded with embed_options #13498 where embed takes precedence of cached theme preference

We previously did not save "Auto" but since we are not saving config properties anymore, it is easier to save "Auto" as long as we ensure this is recalculated properly for system setting changes.

Testing Plan

  • JS Unit Tests: ✅ Added
  • E2E Tests: ✅ Added
  • Manual Testing: ✅

@mayagbarnes mayagbarnes added security-assessment-completed impact:internal PR changes only affect internal code change:refactor PR contains code refactoring without behavior change labels Jan 15, 2026
@snyk-io
Copy link
Copy Markdown
Contributor

snyk-io bot commented Jan 15, 2026

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

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 15, 2026

✅ PR preview is ready!

Name Link
📦 Wheel file https://core-previews.s3-us-west-2.amazonaws.com/pr-13593/streamlit-1.53.0-py3-none-any.whl
📦 @streamlit/component-v2-lib Download from artifacts
🕹️ Preview app pr-13593.streamlit.app (☁️ Deploy here if not accessible)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Jan 15, 2026

📈 Frontend coverage change detected

The frontend unit test (vitest) coverage has increased by 0.0800%

  • Current PR: 86.6500% (12935 lines, 1726 missed)
  • Latest develop: 86.5700% (12899 lines, 1732 missed)

🎉 Great job on improving test coverage!

📊 View detailed coverage comparison

@mayagbarnes mayagbarnes changed the title [WIP] Simplify theme caching logic Simplify theme caching logic Jan 16, 2026
@mayagbarnes mayagbarnes marked this pull request as ready for review January 16, 2026 04:35
Copilot AI review requested due to automatic review settings January 16, 2026 04:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request simplifies theme caching logic by storing only high-level theme selection strings ("System", "Light", "Dark") in localStorage instead of persisting complete theme configurations. The refactor improves handling of system preference updates for custom themes and ensures embed options consistently take precedence over cached theme preferences.

Changes:

  • Simplified cache format from storing full ThemeConfig objects to storing simple ThemeSelection strings
  • Added getPreferredTheme utility to unify preference retrieval logic
  • Enhanced system preference change handling for both preset and custom auto themes
  • Incremented cache version to 2 and added migration logic to clear old cache formats

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/lib/src/util/storageUtils.ts Incremented CACHED_THEME_VERSION to 2
frontend/lib/src/theme/utils.ts Replaced getCachedTheme/setCachedTheme with getCachedThemeSelection/setCachedThemeSelection; added getPreferredTheme and getThemeSelectionFromThemeConfig utilities; simplified mapping logic
frontend/lib/src/theme/utils.test.ts Updated tests to work with new string-based cache format
frontend/lib/src/theme/types.ts Redefined CachedTheme as ThemeSelection alias instead of object type
frontend/lib/src/index.ts Updated exports to reflect renamed and new functions
frontend/app/src/util/useThemeManager.ts Enhanced auto theme recalibration logic for custom themes; split updateTheme into applyTheme and updateTheme for better control over persistence
frontend/app/src/util/useThemeManager.test.ts Added comprehensive tests for system preference changes with custom themes
frontend/app/src/App.tsx Simplified theme preference logic by using new getPreferredTheme utility
frontend/app/src/App.test.tsx Updated test expectations to match new string-based cache format
e2e_playwright/main_menu_test.py Added E2E tests for cached preference persistence and auto theme recalibration
e2e_playwright/main_menu.py Added header to test app

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no bugs!

@lukasmasuch lukasmasuch added the ai-review If applied to PR or issue will run AI review workflow label Jan 17, 2026
@github-actions github-actions bot removed the ai-review If applied to PR or issue will run AI review workflow label Jan 17, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Summary

This PR refactors the theme caching logic to store only a high-level selection ("System", "Light", or "Dark") in localStorage instead of storing full theme configurations. The changes simplify cache behavior by:

  1. Replacing the complex CachedTheme type (object with name and themeInput) with a simple string union type ThemeSelection
  2. Renaming and simplifying caching functions: getCachedThemegetCachedThemeSelection, setCachedThemesetCachedThemeSelection
  3. Adding a new unified getPreferredTheme() function that handles both host-specified (embed options) and cached preferences
  4. Bumping the localStorage schema version from 1 to 2 to invalidate old cached themes
  5. Improving handling of system preference changes for custom themes with auto mode

Code Quality

Strengths:

  • The refactoring is clean and well-structured with good separation of concerns
  • The new getPreferredTheme() function consolidates logic that was previously duplicated in App.tsx
  • The isThemeSelection type guard provides runtime validation
  • Good use of TypeScript types (ThemeSelection = "System" | "Light" | "Dark")
  • The mapCachedThemeSelectionToAvailableTheme function properly prioritizes custom themes over preset themes

Implementation Details:

  • storageUtils.ts:19 - Version bump from 1 to 2 is appropriate for the schema change
  • utils.ts:1150-1152 - Correct migration logic that clears versions 1 through CACHED_THEME_VERSION - 1
  • utils.ts:1179-1187 - Good handling of CUSTOM_THEME_NAME mapping to "System" with clear documentation

Minor Observations:

  • The code properly handles edge cases like missing localStorage, unrecognized theme names, and null values

Test Coverage

Unit Tests:

  • useThemeManager.test.ts - Comprehensive tests covering:

    • Theme updates and localStorage persistence
    • Auto selection saving (test renamed from "does not save Auto theme" to "saves Auto selection")
    • Custom auto theme recalibration on system preference changes
    • Preset auto theme recalibration
    • Font handling for imported themes
  • utils.test.ts - Good coverage of:

    • getCachedThemeSelection - null handling, version migration, retrieval
    • setCachedThemeSelection - localStorage unavailability, preset/auto theme saving
    • mapCachedThemeSelectionToAvailableTheme - various mapping scenarios
    • getDefaultTheme - auto theme, user preference, host-specified overrides

E2E Tests:

  • test_cached_preference_persists_on_reload - Tests that user's theme preference (e.g., Dark) persists after a page reload
  • test_auto_theme_recalibrates_on_system_change - Tests that "Use system setting" respects system preference changes

Test Quality Assessment:

  • Tests follow best practices: using expect for assertions, wait_until instead of wait_for_timeout
  • E2E tests use proper locators (get_by_test_id, get_by_text, get_by_role)
  • Tests include both positive assertions (theme is set) and implicit negative assertions (wrong theme is not shown)

Backwards Compatibility

Breaking Changes:

  • Users will lose their cached theme preference once when upgrading due to the schema version bump
  • This is an acceptable trade-off for the simplified architecture

Migration Handling:

  • deleteOldCachedThemes() properly clears old format cached themes (versions < 2)
  • The function also cleans up legacy key formats (stActiveTheme, stActiveTheme-${pathname})
  • Existing embed options (embed_options=light_theme / embed_options=dark_theme) continue to work and take precedence

API Changes:

  • Removed exports: getCachedTheme, mapCachedThemeToAvailableTheme
  • New exports: getCachedThemeSelection, setCachedThemeSelection, getThemeSelectionFromThemeConfig, getPreferredTheme, mapCachedThemeSelectionToAvailableTheme
  • CachedTheme type changed from object to string union (but this is internal)

Security & Risk

Security:

  • No security concerns identified
  • localStorage handling follows standard patterns
  • No sensitive data is stored (only theme preference strings)

Risk Assessment:

  • Low risk: The changes are well-tested and the migration path is clear
  • Mitigation: Schema versioning ensures clean migration
  • Regression potential: Minimal due to comprehensive unit and E2E test coverage

Recommendations

No blocking issues identified. The following are minor suggestions for consideration:

  1. Documentation: Consider adding a brief comment in storageUtils.ts explaining what version 2 represents (string-based selection vs object-based config).

  2. E2E Test Enhancement: The test_auto_theme_recalibrates_on_system_change test could include a negative assertion verifying the app is NOT using dark theme colors when in light mode (currently only checks background color changes).

  3. Minor improvement in main_menu.py: The added st.header("Main Menu Test") is a good change to ensure the test page has content. This is fine as-is.

Verdict

APPROVED: This is a well-implemented refactoring that simplifies theme caching logic while maintaining backwards compatibility. The code is clean, well-tested at both unit and E2E levels, and follows established patterns in the codebase. The schema version bump ensures a clean migration path for existing users.


This is an automated AI review. Please verify the feedback and use your judgment.

Copy link
Copy Markdown
Collaborator

@lukasmasuch lukasmasuch left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@sfc-gh-mbarnes sfc-gh-mbarnes merged commit 16e6e0c into develop Jan 17, 2026
54 of 55 checks passed
@sfc-gh-mbarnes sfc-gh-mbarnes deleted the update-theme-cache branch January 17, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

change:refactor PR contains code refactoring without behavior change impact:internal PR changes only affect internal code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants