Skip to content

bug(ThemeProvider): 'auto' theme value is overridden with actual dark/light value #8063

@Jihed-Halimi

Description

@Jihed-Halimi

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The ThemeProvider component has a logic issue where the 'auto' theme setting is being converted to its actual value ('dark' or 'light') and persisted to localStorage. This causes the theme preference to lose the automatic/responsive behavior on subsequent page loads.
Current Behavior

  1. User selects "Auto" theme mode
  2. getTheme() retrieves the stored 'auto' value
  3. getTheme() then converts 'auto' to getAutoThemeValue() (returns 'dark' or 'light')
  4. The actual value ('dark' or 'light') gets saved to localStorage instead of 'auto'
  5. On next page load, theme is locked to that specific value rather than following system preferences

Expected Behavior

• When user selects "Auto" theme, the string 'auto' should be persisted to localStorage
• On page load, if theme is 'auto', it should be resolved to the actual value only for DOM rendering
• The system should continue to respond to system dark mode preference changes

Interactive render mode

Interactive Server (Interactive server-side rendering (interactive SSR) using Blazor Server)

Steps To Reproduce

utility.js

Exceptions (if any)

No response

.NET Version

NET9.0

Anything else?

Root Cause

The issue exists in two functions in utility.js:718-724:
In getTheme():

if (theme === null || theme === 'auto') {
    theme = getAutoThemeValue();  // Converts 'auto' too early
}

In setTheme(): The function doesn't properly handle the 'auto' case before resolution.

Proposed Solution

  1. Modify getTheme() in utility.js:718-724
    Remove the early conversion of 'auto' to its actual value:
export function getTheme(useLocalstorage = true) {
    useLocalstorage = useLocalstorage ?? true;
    let theme = null;
    if (useLocalstorage) {
        theme = localStorage.getItem('theme');
    }
    else {
        theme = document.documentElement.getAttribute('data-bs-theme');
    }
    // REMOVED: if (theme === null || theme === 'auto') { theme = getAutoThemeValue(); }
    return theme;
}
  1. Modify setTheme() in utility.js:718-724
    Update the theme resolution logic to handle 'auto' properly:
export function setTheme(theme, sync) {
    if (theme === 'auto') {
        document.documentElement.setAttribute('data-bs-theme', getAutoThemeValue())
    }
    else {
        document.documentElement.setAttribute('data-bs-theme', theme);
    }

    if (sync === true) {
        const providers = document.querySelectorAll('.bb-theme-mode');
        providers.forEach(p => {
            const activeItem = p.querySelector(`.dropdown-item[data-bb-theme-value="${theme}"]`);
            setActiveTheme(p, activeItem)
        })
        saveTheme(theme);  // Now saves 'auto' instead of the resolved value
    }
    EventHandler.trigger(document, 'changed.bb.theme', { theme: theme });
}

Benefits

• ✅ System theme preference changes are now respected
• ✅ 'auto' setting persists and behaves as intended
• ✅ Better user experience when switching between light/dark mode at OS level
• ✅ Aligns with the media query listener already in place

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions