Implements a dark mode override system for DevExpress Blazor themes lacking native dark support. Adds a JS function to toggle a dx-dark class on <html>, updates ThemeState to detect native dark themes, and applies targeted CSS variable overrides for consistent dark styling. Disables prerendering to ensure JS interop, and improves theme switching logic and documentation.
86 lines
2.2 KiB
Plaintext
86 lines
2.2 KiB
Plaintext
@inherits LayoutComponentBase
|
||
@implements IDisposable
|
||
@inject ThemeState ThemeState
|
||
@inject IJSRuntime JS
|
||
|
||
<div class="page @(ThemeState.IsDarkMode ? "app-dark" : "app-light") @(ThemeState.IsNativeDarkTheme ? "native-dark" : "")">
|
||
<div class="sidebar">
|
||
<NavMenu />
|
||
</div>
|
||
|
||
<main>
|
||
<div class="top-row px-4">
|
||
<DxComboBox Data="@ThemeState.AvailableThemes"
|
||
Value="@ThemeState.CurrentThemeName"
|
||
ValueChanged="@((string t) => ThemeState.SetTheme(t))"
|
||
style="width: 130px;" />
|
||
<span style="margin-left: 12px;">
|
||
<DxButton Text="@(ThemeState.IsDarkMode ? "Dark Mode aus" : "Dark Mode an")"
|
||
Click="ToggleTheme" />
|
||
</span>
|
||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||
</div>
|
||
|
||
<article class="content px-4">
|
||
@Body
|
||
</article>
|
||
</main>
|
||
</div>
|
||
|
||
<div id="blazor-error-ui">
|
||
An unhandled error has occurred.
|
||
<a href="" class="reload">Reload</a>
|
||
<a class="dismiss">🗙</a>
|
||
</div>
|
||
|
||
@code {
|
||
private bool _isInteractive;
|
||
|
||
protected override void OnInitialized()
|
||
{
|
||
ThemeState.OnChange += OnThemeChanged;
|
||
}
|
||
|
||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||
{
|
||
if (firstRender)
|
||
{
|
||
_isInteractive = true;
|
||
}
|
||
await ApplyDxDarkOverrideAsync();
|
||
}
|
||
|
||
private async void OnThemeChanged()
|
||
{
|
||
StateHasChanged();
|
||
if (_isInteractive)
|
||
{
|
||
await ApplyDxDarkOverrideAsync();
|
||
}
|
||
}
|
||
|
||
private async Task ApplyDxDarkOverrideAsync()
|
||
{
|
||
if (!_isInteractive) return;
|
||
try
|
||
{
|
||
bool needsOverride = ThemeState.IsDarkMode && !ThemeState.IsNativeDarkTheme;
|
||
await JS.InvokeVoidAsync("setDxDarkOverride", needsOverride);
|
||
}
|
||
catch (JSException)
|
||
{
|
||
// JS-Funktion noch nicht verfügbar – kein Circuit-Crash
|
||
}
|
||
}
|
||
|
||
private void ToggleTheme()
|
||
{
|
||
ThemeState.SetDarkMode(!ThemeState.IsDarkMode);
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
ThemeState.OnChange -= OnThemeChanged;
|
||
}
|
||
}
|