keycloak/keycloak

[quick-theme] Quick Theme exports only the last selected theme mode (light or dark)

Open

#49,125 建立於 2026年5月19日

在 GitHub 查看
 (2 留言) (1 反應) (0 負責人)Java (34,398 star) (8,346 fork)batch import
area/login/uihelp wantedkind/bugpriority/normalstatus/auto-bumpstatus/auto-expireteam/core-authn

描述

Before reporting an issue

  • I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.

Area

login/ui

Describe the bug

When using the Quick Theme feature to customize both light and dark mode colors, the exported .jar file only contains the CSS variables for the last selected theme mode. The other mode's values are completely lost.

Version

26.6.2

Regression

  • The issue is a regression

Expected behavior

Both light and dark mode color configurations should be preserved in the exported .jar, regardless of which theme mode is currently selected in the UI. The theme-settings.json inside the JAR should contain both "light" and "dark" keys with their respective values, and the generated theme-styles.css should populate both the :root and .pf-v5-theme-dark blocks.

Actual behavior

The theme-settings.json only contains the values for the last selected mode. The other mode is missing entirely. The generated theme-styles.css reflects this — the inactive mode block is empty:

:root {
  /* all light mode values here */
}
.pf-v5-theme-dark {
  /* completely empty */
}

How to Reproduce?

  1. Enable the quick-theme feature (--features=quick-theme).
  2. Go to Realm Settings → Themes → Quick Theme.
  3. Configure some colors in Light mode.
  4. Switch the toggle to Dark mode.
  5. Configure some colors in Dark mode.
  6. Click Download theme JAR.
  7. Extract the JAR and inspect theme-settings.json — only the dark mode values are present.

Anything else?

This regression was introduced in PR #46247, which merged the previously separate light/dark theme tabs into a single component with an internal toggle. The useEffect hook in ThemeColors.tsx has theme as a dependency:

useEffect(() => {
  setupForm();
  switchTheme(theme);
  return () => { switchTheme(originalTheme); };
}, [realm, theme]); // ← theme is a dependency

When the user toggles between light and dark, theme changes, the effect re-runs, setupForm() is called, which calls reset(), which calls:

form.reset({ [theme]: mapping.reduce(...) });

This only populates the form with the currently active theme's values, wiping the other theme's data from the form state. Since convert() serializes the form state into theme-settings.json, the inactive theme is never included in the export.

貢獻者指南