Skip to content

Expose default_color_mode in rx.Config#6716

Open
masenf wants to merge 4 commits into
mainfrom
masenf/default-color-mode
Open

Expose default_color_mode in rx.Config#6716
masenf wants to merge 4 commits into
mainfrom
masenf/default-color-mode

Conversation

@masenf

@masenf masenf commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@masenf masenf requested a review from a team as a code owner July 7, 2026 22:29
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR exposes default_color_mode in rx.Config (and as REFLEX_DEFAULT_COLOR_MODE env var), letting apps control the initial color mode — "system", "light", or "dark" — without needing a Radix theme component. The constants SYSTEM_COLOR_MODE / LIGHT_COLOR_MODE / DARK_COLOR_MODE and the LiteralColorMode type alias are moved from style.py into reflex_base.constants.base and re-exported cleanly.

  • New _resolve_default_color_mode(theme) in compiler.py checks the Radix theme's appearance prop first (non-"inherit" literal wins), then falls back to Config.default_color_mode; both compile_contexts and compile_document_root use the same theme source, keeping the JS context file and the pre-hydration preload script in sync.
  • preload_color_theme now accepts the resolved default and embeds it via repr() into the inline script, eliminating the flash of the wrong theme on first paint even without a Radix theme.
  • Tests are well-isolated: _mock_config_color_mode constructs a fresh Config per test (rather than mutating the singleton), and env-var validation for LiteralColorMode is correctly handled by the existing interpret_env_var_value machinery.

Confidence Score: 5/5

Safe to merge — the change is additive, defaults to the existing system behavior, and the two compiler call-sites resolve the color mode from the same theme object so they cannot drift out of sync.

The refactor is clean: constants are moved not duplicated, the new helper is tested with isolated mocks, and env-var validation delegates to existing Literal-aware machinery that raises on invalid input. No existing behavior is broken.

No files require special attention.

Important Files Changed

Filename Overview
packages/reflex-base/src/reflex_base/constants/base.py Adds SYSTEM_COLOR_MODE, LIGHT_COLOR_MODE, DARK_COLOR_MODE constants and LiteralColorMode type alias, relocated from style.py — clean extraction.
packages/reflex-base/src/reflex_base/constants/init.py Re-exports the four new symbols from base.py and adds them to all — straightforward bookkeeping.
packages/reflex-base/src/reflex_base/style.py Drops the now-duplicate local definitions and re-imports them from constants.base using the explicit as Name re-export pattern — correct approach for a py.typed package.
packages/reflex-base/src/reflex_base/config.py Adds default_color_mode: LiteralColorMode = "system" to BaseConfig. The Literal-aware interpret_env_var_value validates REFLEX_DEFAULT_COLOR_MODE against allowed values, so invalid env var input raises a clear error rather than silently propagating.
reflex/compiler/compiler.py Introduces _resolve_default_color_mode() which checks theme.appearance (LiteralStringVar != "inherit") first, then falls back to get_config().default_color_mode. Both compile_contexts and compile_document_root use the same radix_themes_plugin.get_theme() so the context file and preload script will always agree.
reflex/compiler/utils.py Threads default_color_mode through create_document_root to preload_color_theme — minimal, correct change.
reflex/utils/misc.py preload_color_theme now accepts a default_color_mode parameter (defaulting to "system") and embeds it via Python repr() into the inline JS — produces valid single-quoted JS string literals for all three allowed values.
tests/units/compiler/test_compiler.py Well-structured new tests: _mock_config_color_mode builds a fresh Config per test rather than mutating the singleton, preventing inter-test leakage regardless of execution order.
tests/units/test_config.py Adds two tests: default_color_mode defaults to "system" and REFLEX_DEFAULT_COLOR_MODE="dark" is accepted by the env var mechanism.

Reviews (4): Last reviewed commit: "add news fragment" | Re-trigger Greptile

@codspeed-hq

codspeed-hq Bot commented Jul 7, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 26 untouched benchmarks
⏩ 8 skipped benchmarks1


Comparing masenf/default-color-mode (3709c9b) with main (2d446c3)2

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (d54ad96) during the generation of this report, so 2d446c3 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Comment thread tests/units/compiler/test_compiler.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5a912f962

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread reflex/compiler/compiler.py Outdated
appearance = getattr(theme, "appearance", None)
if appearance is None or str(LiteralVar.create(appearance)) == '"inherit"':
appearance = LiteralVar.create(SYSTEM_COLOR_MODE)
appearance = LiteralVar.create(get_config().default_color_mode)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Propagate default color mode into the preload script

When an app sets default_color_mode="dark" or "light" and the browser has no saved theme in localStorage, this only changes the compiled context/ThemeProvider default; create_document_root still unconditionally injects preload_color_theme(), whose inline script applies localStorage.getItem("theme") || "system" before hydration. For example, a dark default on a light OS first paints light and then flips to dark after React initializes, so the new config still produces a visible FOUC/mismatched initial class unless the preload path receives the same default.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant