diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
index acf0224f659..fb6f05ea55d 100644
--- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
+++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/src/BootstrapBlazor.Server/Components/Components/Header.razor b/src/BootstrapBlazor.Server/Components/Components/Header.razor
index abf04151a31..5a2200b9615 100644
--- a/src/BootstrapBlazor.Server/Components/Components/Header.razor
+++ b/src/BootstrapBlazor.Server/Components/Components/Header.razor
@@ -48,5 +48,5 @@
@DownloadText
diff --git a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs
index f996d2122dd..783caf74ba2 100644
--- a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs
+++ b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs
@@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
+using Microsoft.JSInterop;
+
namespace BootstrapBlazor.Server.Components.Components;
///
@@ -13,6 +15,10 @@ public partial class ThemeMode
[Inject, NotNull]
private IIconTheme? IconTheme { get; set; }
+ [Inject]
+ [NotNull]
+ private IThemeProvider? ThemeProvider { get; set; }
+
private string? GetLightIconClassString => CssBuilder.Default("icon-light")
.AddClass(_lightModeIcon)
.Build();
@@ -35,4 +41,17 @@ protected override void OnInitialized()
_darkModeIcon ??= IconTheme.GetIconByKey(ComponentIcons.ThemeProviderDarkModeIcon);
_lightModeIcon ??= IconTheme.GetIconByKey(ComponentIcons.ThemeProviderLightModeIcon);
}
+
+ ///
+ ///
+ ///
+ protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, nameof(OnThemeChanged));
+
+ ///
+ /// The callback when theme changed
+ ///
+ ///
+ ///
+ [JSInvokable]
+ public ValueTask OnThemeChanged(string themeName) => ThemeProvider.SetThemeAsync(themeName);
}
diff --git a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.js b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.js
index f0a7962ba3b..ce6ed515de3 100644
--- a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.js
+++ b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.js
@@ -1,7 +1,7 @@
import { getTheme, switchTheme, calcCenterPosition } from "../../_content/BootstrapBlazor/modules/utility.js"
import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js"
-export function init(id) {
+export function init(id, invoke, method) {
const el = document.getElementById(id);
if (el) {
EventHandler.on(el, 'click', e => {
@@ -15,6 +15,7 @@ export function init(id) {
const rect = calcCenterPosition(el);
switchTheme(theme, rect.x, rect.y);
+ invoke.invokeMethodAsync(method, theme);
});
}
}
diff --git a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/BaseDockView.cs b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/BaseDockView.cs
index b43fb66ad7d..ca40bad886f 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/BaseDockView.cs
+++ b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/BaseDockView.cs
@@ -22,6 +22,10 @@ public abstract class BaseDockView : ComponentBase
[NotNull]
private MockDataTableDynamicService? DataTableDynamicService { get; set; }
+ [Inject]
+ [NotNull]
+ private IThemeProvider? ThemeProviderService { get; set; }
+
///
/// 获得/设置 数据集合
///
@@ -39,6 +43,11 @@ public abstract class BaseDockView : ComponentBase
///
protected DataTableDynamicContext? DataTableDynamicContext { get; set; }
+ ///
+ /// Gets or sets the theme
+ ///
+ protected DockViewTheme Theme { get; set; } = DockViewTheme.Light;
+
///
/// 获得 实例方法
///
@@ -51,6 +60,8 @@ public abstract class BaseDockView : ComponentBase
///
protected override void OnInitialized()
{
+ base.OnInitialized();
+
Items = Foo.GenerateFoo(LocalizerFoo, 50);
// 模拟数据从数据库中获得
@@ -63,6 +74,22 @@ protected override void OnInitialized()
TreeItems.AddRange(TreeFoo.GenerateFoos(LocalizerFoo, 3, 101, 1010));
DataTableDynamicContext = DataTableDynamicService.CreateContext();
+
+ ThemeProviderService.ThemeChangedAsync += OnThemeChanged;
+ }
+
+ private Task OnThemeChanged(string themeName)
+ {
+ if (themeName == "dark")
+ {
+ Theme = DockViewTheme.Dark;
+ }
+ else
+ {
+ Theme = DockViewTheme.Light;
+ }
+ StateHasChanged();
+ return Task.CompletedTask;
}
///
diff --git a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewCol.razor b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewCol.razor
index 422522d84ad..38632f3419e 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewCol.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewCol.razor
@@ -5,7 +5,7 @@
@((MarkupString)Localizer["DockViewColIntro"].Value)
-
+
@((MarkupString)Localizer["DockViewComplexIntro"].Value)
-
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewGroup.razor b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewGroup.razor
index 891e1af7d83..3e5e85ad94b 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewGroup.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewGroup.razor
@@ -5,7 +5,7 @@
@((MarkupString)Localizer["DockViewGroupIntro"].Value)
-
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewLayout.razor b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewLayout.razor
index 08fffe29a95..8d469704886 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewLayout.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewLayout.razor
@@ -12,7 +12,7 @@
-
+
-
+
@((MarkupString)Localizer["DockViewNestIntro"].Value)
-
+
-
+
-
+
? Localizer { get; set; }
-
- private DockViewTheme _theme;
}
diff --git a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewRow.razor b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewRow.razor
index e5bb196c9e9..e53c5225a57 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewRow.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/DockViews2/DockViewRow.razor
@@ -5,7 +5,7 @@
@((MarkupString)Localizer["DockViewRowIntro"].Value)
-
+
@((MarkupString)Localizer["DockViewTitleIntro"].Value)
-
+
-
+
? Localizer { get; set; }
+ [Inject]
+ [NotNull]
+ private IThemeProvider? ThemeProviderService { get; set; }
+
private string? ClassString => CssBuilder.Default("dropdown bb-theme-mode")
.AddClassFromAttributes(AdditionalAttributes)
.Build();
@@ -139,5 +143,6 @@ public async Task OnThemeChanged(ThemeValue name)
{
await OnThemeChangedAsync(name);
}
+ await ThemeProviderService.SetThemeAsync(name.ToDescriptionString());
}
}
diff --git a/src/BootstrapBlazor/Components/ThemeProvider/ThemeValue.cs b/src/BootstrapBlazor/Components/ThemeProvider/ThemeValue.cs
index 3276c2354dd..5305bcfc357 100644
--- a/src/BootstrapBlazor/Components/ThemeProvider/ThemeValue.cs
+++ b/src/BootstrapBlazor/Components/ThemeProvider/ThemeValue.cs
@@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information.
// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone
+using System.ComponentModel;
+
namespace BootstrapBlazor.Components;
///
@@ -14,20 +16,24 @@ public enum ThemeValue
///
/// 自动
///
+ [Description("auto")]
Auto,
///
/// 明亮主题
///
+ [Description("light")]
Light,
///
/// 暗黑主题
///
+ [Description("dark")]
Dark,
///
/// 使用本地保存选项
///
+ [Description("useLocalStorage")]
UseLocalStorage,
}
diff --git a/src/BootstrapBlazor/Services/DefaultThemeProvider.cs b/src/BootstrapBlazor/Services/DefaultThemeProvider.cs
index 9fddf9c6bd6..397a7b4800a 100644
--- a/src/BootstrapBlazor/Services/DefaultThemeProvider.cs
+++ b/src/BootstrapBlazor/Services/DefaultThemeProvider.cs
@@ -7,6 +7,11 @@ namespace BootstrapBlazor.Components;
class DefaultThemeProvider(IJSRuntime jsRuntime) : IThemeProvider
{
+ ///
+ ///
+ ///
+ public Func? ThemeChangedAsync { get; set; }
+
///
///
///
@@ -15,6 +20,11 @@ public async ValueTask SetThemeAsync(string themeName)
{
var module = await jsRuntime.LoadUtility();
await module.SetThemeAsync(themeName);
+
+ if (ThemeChangedAsync is not null)
+ {
+ await ThemeChangedAsync(themeName);
+ }
}
///
diff --git a/src/BootstrapBlazor/Services/IThemeProvider.cs b/src/BootstrapBlazor/Services/IThemeProvider.cs
index f2c0fc03bba..070c9040cdb 100644
--- a/src/BootstrapBlazor/Services/IThemeProvider.cs
+++ b/src/BootstrapBlazor/Services/IThemeProvider.cs
@@ -6,18 +6,25 @@
namespace BootstrapBlazor.Components;
///
-/// 主题提供器接口
+/// Interface for theme provider
///
public interface IThemeProvider
{
///
- /// 设置主题方法
+ /// Sets the theme asynchronously.
///
- ///
+ /// The name of the theme to set.
+ /// A representing the asynchronous operation.
ValueTask SetThemeAsync(string themeName);
///
- /// 获得当前主题方法
+ /// Gets the current theme asynchronously.
///
+ /// A representing the asynchronous operation, with the current theme name as the result.
ValueTask GetThemeAsync();
+
+ ///
+ /// The callback when theme changed
+ ///
+ Func? ThemeChangedAsync { get; set; }
}
diff --git a/test/UnitTest/Services/ThemeProviderTest.cs b/test/UnitTest/Services/ThemeProviderTest.cs
index 3b219a2dae5..0f09ed404db 100644
--- a/test/UnitTest/Services/ThemeProviderTest.cs
+++ b/test/UnitTest/Services/ThemeProviderTest.cs
@@ -10,8 +10,15 @@ public class ThemeProviderTest : BootstrapBlazorTestBase
[Fact]
public async Task SetTheme_Ok()
{
+ var themeName = "";
var themeProviderService = Context.Services.GetRequiredService();
+ themeProviderService.ThemeChangedAsync = async theme =>
+ {
+ themeName = theme;
+ await Task.CompletedTask;
+ };
await themeProviderService.SetThemeAsync("light");
+ Assert.Equal("light", themeName);
}
[Fact]