diff --git a/README.md b/README.md index f842243..b53ff35 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Maui Theme -MauiTheme is Theming Libray that Makes the Theming on Dotnet Maui a Breeze with Persistent Theme State Between Sessions and Seamless Resource Swapping, Theme Switcher and Blazor Hybrid Support. +MauiTheme is a theming library that simplifies theming on .NET Maui, providing a seamless experience with persistent theme state between sessions, easy resource swapping, a theme switcher, and support for Blazor Hybrid. # Packages @@ -11,21 +11,21 @@ Package | Latest stable | Latest Preview | Description # Get Started -You need to Call `InitializeTheme()` in the `App.xaml.cs` Like Below Example +You need to call `InitializeTheme()` in the `App.xaml.cs` file as shown in the example below. Ensure that `InitializeTheme()` is called before setting up the MainPage property. ```csharp +using MauiTheme.Core; + public partial class App : Application { public App() { InitializeComponent(); - MainPage = new AppShell(); - - MauiTheme.Default.InitializeTheme(x => + Theme.Default.InitializeTheme(x => { // Default Theme - x.DefaultTheme = MauiAppTheme.Dark; + x.DefaultTheme = ThemeMode.Dark; // Default Styles Resources x.DefaultStyleResources = ["Resources/Styles/Styles.xaml"]; // All Resources Excluding Styles @@ -39,13 +39,15 @@ public partial class App : Application }); + MainPage = new AppShell(); + } } ``` # App.xaml Setup -The App.xaml should include the Default Color and Style Resource Like Below Example +The App.xaml should include the default color and style resources as shown below: ```xml @@ -69,7 +71,7 @@ The App.xaml should include the Default Color and Style Resource Like Below Exam # Blazor Hybrid Usage -In Order to Initialize the MauiTheme Blazor Hybrid, You need to call `UseMauiThemeHybrid()` in `program.cs` like below example +In Order to Initialize the MauiTheme Blazor Hybrid, you need to call `UseMauiThemeHybrid()` in `program.cs` as shown in the example below: ```csharp using MauiTheme.BlazorHybrid; @@ -81,14 +83,14 @@ public static class MauiProgram var builder = MauiApp.CreateBuilder(); // Initializing MauiTheme on Blazor Hybrid Project by Sharing the Instance of MauiTheme - builder.Services.UseMauiThemeHybrid(MauiTheme.Default); + builder.Services.UseMauiThemeHybrid(Theme.Default); return builder.Build(); } } ``` -If your using WebAssembly or Any Other Blazor Hosting Model, Where your sharing a razor class library within those and Blazor Hybrid +If you are using WebAssembly or any other Blazor hosting model, and you are sharing a Razor Class Library within those, as well as with Blazor Hybrid, you need call `UseMauiThemeBlazor` in those Classic Blazor Project to Avoid Runtime Crashing like below example: ```csharp var builder = WebAssemblyHostBuilder.CreateDefault(args); @@ -99,7 +101,7 @@ builder.Services.UseMauiThemeBlazor(); # Theme -When it comes to Switching Theme, You can change the `CurrentTheme` Property to Switch the Theme Like Below Example +When it comes to switching themes, you can change the `CurrentTheme` property to switch the theme like in the example below: ```csharp @@ -107,53 +109,53 @@ When it comes to Switching Theme, You can change the `CurrentTheme` Property to // -------------------------------------------------- // Dark -MauiTheme.Default.CurrentTheme = MauiAppTheme.Dark; +Theme.Default.CurrentTheme = ThemeMode.Dark; // Light -MauiTheme.Default.CurrentTheme = MauiAppTheme.Light; +Theme.Default.CurrentTheme = ThemeMode.Light; // System -MauiTheme.Default.CurrentTheme = MauiAppTheme.UnSpecified; +Theme.Default.CurrentTheme = ThemeMode.UnSpecified; // Blazor Hybrid // --------------------------------------------------- -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid ThemeHybrid // Dark -MauiThemeHybrid.CurrentTheme = MauiAppTheme.Dark; +ThemeHybrid.CurrentTheme = ThemeMode.Dark; // Light -MauiThemeHybrid.CurrentTheme = MauiAppTheme.Light; +ThemeHybrid.CurrentTheme = ThemeMode.Light; // System -MauiThemeHybrid.CurrentTheme = MauiAppTheme.UnSpecified; +ThemeHybrid.CurrentTheme = ThemeMode.UnSpecified; ``` # Resources -When it comes to Switching Resource, You can use `CurrentResource` Property to Swap the Resources Like Below Example, Make sure to Note that Resources is Applied Using The Key that you have passed into `InitializeTheme` `Resources` Property - +When it comes to switching resources, you can use the `CurrentResource` property to swap the resources, as shown in the example below. Make sure to note that resources are applied using the key that you have passed into the `InitializeTheme` `Resources` property. ```csharp // Maui -// --------------------------------------------------- +--------------------------------------------------- // Blue.xaml -MauiTheme.Default.CurrentResource = "Blue"; +Theme.Default.CurrentResource = "Blue"; // Purple.xaml -MauiTheme.Default.CurrentResource = "Purple"; +Theme.Default.CurrentResource = "Purple"; // Yellow.xaml -MauiTheme.Default.CurrentResource = "Yellow"; +Theme.Default.CurrentResource = "Yellow"; + // Blazor Hybrid -// --------------------------------------------------- +--------------------------------------------------- -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid ThemeHybrid -MauiThemeHybrid.CurrentResource = "Blue"; +ThemeHybrid.CurrentResource = "Blue"; ``` @@ -164,13 +166,13 @@ Mainly this is useful when theme or resource changes is invoked from external so ```csharp // Theme Changed Event -MauiTheme.Default.ThemeChanged += (s, t) => +Theme.Default.ThemeChanged += (s, t) => { Debug.Writeline($"New Theme : {t.ToString()}") } // Theme Changed Event -MauiTheme.Default.ResourceChanged += (s, r) => +Theme.Default.ResourceChanged += (s, r) => { Debug.Writeline($"New Resource : {r}") } @@ -181,18 +183,18 @@ MauiTheme.Default.ResourceChanged += (s, r) => This is mainly useful when listening to Theme or Resource Changes from External Sources for Instance from Maui, as you can see in the below example, we are invoking `StateChanged()` method in MauiThemeContext, Basically What that Says is Refresh the Razor Component Whenever Theme Changes -```razor +```csharp -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid ThemeHybrid @implements IDisposable Theme

Theme

- - @foreach (var item in (MauiAppTheme[])Enum.GetValues(typeof(MauiAppTheme))) + + @foreach (var item in (ThemeMode[])Enum.GetValues(typeof(ThemeMode))) { - + @item
} @@ -201,7 +203,7 @@ This is mainly useful when listening to Theme or Resource Changes from External

Color

- + Blue
Purple
Yellow
@@ -210,11 +212,11 @@ This is mainly useful when listening to Theme or Resource Changes from External @code{ - MauiThemeContext? themeContext; + ThemeContext? themeContext; protected override void OnInitialized() { - themeContext = MauiThemeContext.Create(MauiThemeHybrid, () => StateHasChanged()); + themeContext = ThemeContext.Create(ThemeHybrid, () => StateHasChanged()); base.OnInitialized(); } @@ -227,6 +229,26 @@ This is mainly useful when listening to Theme or Resource Changes from External ``` +# Properties and Methods - MauiTheme + +| Parameters | Type | Description | +| :--- | :---: | :---: +| **InitializeTheme()** | `method` | This is used for Initializing MauiTheme || +| **CurrentTheme** | `ThemeMode` | Gets or sets the current theme | +| **CurrentResource** | `string` | Gets or sets the current resource | +| **ThemeChanged** | `event` | Theme Changed event is fired whenever theme changes happens | +| **ResourceChanged** | `event` | Resource Changed event is fired whenever resource changes happens | +| **ThemeChangedCommand** | `ICommand` | Theme Changed Command is fired whenever theme changes happens | +| **ResourceChangedCommand** | `ICommand` | Resource Changed Command is fired whenever resource changes happens | + +# Properties and Methods - Hybrid + +| Parameters | Type | Description | +| :--- | :---: | :---: +| **CurrentTheme** | `ThemeMode` | Gets or sets the current theme | +| **CurrentResource** | `string` | Gets or sets the current resource | +| **ThemeContext.Create()** | `method` | Theme Context would trigger CallBack Whenever Theme Changes Happens Outside Blazor Context | + # License diff --git a/sample/MauiTheme.Sample.BlazorHybrid/App.xaml.cs b/sample/MauiTheme.Sample.BlazorHybrid/App.xaml.cs index dfc0a1b..239aa7d 100644 --- a/sample/MauiTheme.Sample.BlazorHybrid/App.xaml.cs +++ b/sample/MauiTheme.Sample.BlazorHybrid/App.xaml.cs @@ -8,10 +8,10 @@ public App() { InitializeComponent(); - MauiTheme.Default.InitializeTheme(x => + Theme.Default.InitializeTheme(x => { // Default Theme - x.DefaultTheme = MauiAppTheme.Light; + x.DefaultTheme = ThemeMode.Light; // Default Styles Resources x.DefaultStyleResources = ["Resources/Styles/Styles.xaml"]; // All Resources Excluding Styles diff --git a/sample/MauiTheme.Sample.BlazorHybrid/MainPage.xaml.cs b/sample/MauiTheme.Sample.BlazorHybrid/MainPage.xaml.cs index 2ed0d03..542ff90 100644 --- a/sample/MauiTheme.Sample.BlazorHybrid/MainPage.xaml.cs +++ b/sample/MauiTheme.Sample.BlazorHybrid/MainPage.xaml.cs @@ -10,8 +10,8 @@ public MainPage() InitializeComponent(); BindingContext = this; - MauiTheme.Default.ThemeChanged += Default_ThemeChanged; - MauiTheme.Default.ResourceChanged += Default_ResourceChanged; + Theme.Default.ThemeChanged += Default_ThemeChanged; + Theme.Default.ResourceChanged += Default_ResourceChanged; } private void Default_ResourceChanged(object? sender, ResourceChangedEventArgs e) @@ -19,30 +19,30 @@ private void Default_ResourceChanged(object? sender, ResourceChangedEventArgs e) OnPropertyChanged(nameof(ColorKey)); } - private void Default_ThemeChanged(object? sender, MauiAppThemeChangedEventArgs e) + private void Default_ThemeChanged(object? sender, ThemeModeChangedEventArgs e) { OnPropertyChanged(nameof(Selection)); } - public MauiAppTheme Selection + public ThemeMode Selection { - get => MauiTheme.Default.CurrentAppTheme; + get => Theme.Default.CurrentAppTheme; set { - if (value != MauiTheme.Default.CurrentAppTheme) + if (value != Theme.Default.CurrentAppTheme) { - MauiTheme.Default.CurrentAppTheme = value; + Theme.Default.CurrentAppTheme = value; OnPropertyChanged(nameof(Selection)); } } } public string ColorKey { - get => MauiTheme.Default.CurrentResource; + get => Theme.Default.CurrentResource; set { - if (value != MauiTheme.Default.CurrentResource) + if (value != Theme.Default.CurrentResource) { - MauiTheme.Default.CurrentResource = value; + Theme.Default.CurrentResource = value; OnPropertyChanged(nameof(ColorKey)); } } diff --git a/sample/MauiTheme.Sample.BlazorHybrid/MauiProgram.cs b/sample/MauiTheme.Sample.BlazorHybrid/MauiProgram.cs index 5a7f043..60ddba7 100644 --- a/sample/MauiTheme.Sample.BlazorHybrid/MauiProgram.cs +++ b/sample/MauiTheme.Sample.BlazorHybrid/MauiProgram.cs @@ -15,7 +15,7 @@ public static MauiApp CreateMauiApp() }); builder.Services.AddMauiBlazorWebView(); - builder.Services.UseMauiThemeHybrid(MauiTheme.Default); + builder.Services.UseMauiThemeHybrid(Theme.Default); #if DEBUG builder.Services.AddBlazorWebViewDeveloperTools(); diff --git a/sample/MauiTheme.Sample.Shared/Components/Pages/Theme.razor b/sample/MauiTheme.Sample.Shared/Components/Pages/Theme.razor index 2591d4e..8f06ced 100644 --- a/sample/MauiTheme.Sample.Shared/Components/Pages/Theme.razor +++ b/sample/MauiTheme.Sample.Shared/Components/Pages/Theme.razor @@ -1,14 +1,14 @@ @page "/theme" -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid MauiThemeHybrid @implements IDisposable Theme

Theme

- - @foreach (var item in (MauiAppTheme[])Enum.GetValues(typeof(MauiAppTheme))) + + @foreach (var item in (ThemeMode[])Enum.GetValues(typeof(ThemeMode))) { - + @item
} @@ -26,11 +26,11 @@ @code{ - MauiThemeContext? themeContext; + ThemeContext? themeContext; protected override void OnInitialized() { - themeContext = MauiThemeContext.Create(MauiThemeHybrid, () => StateHasChanged()); + themeContext = ThemeContext.Create(MauiThemeHybrid, () => StateHasChanged()); base.OnInitialized(); } diff --git a/sample/MauiTheme.Sample/App.xaml.cs b/sample/MauiTheme.Sample/App.xaml.cs index 63d6cf5..a97d74b 100644 --- a/sample/MauiTheme.Sample/App.xaml.cs +++ b/sample/MauiTheme.Sample/App.xaml.cs @@ -10,10 +10,10 @@ public App() MainPage = new AppShell(); - MauiTheme.Default.InitializeTheme(x => + Theme.Default.InitializeTheme(x => { // Default Theme - x.DefaultTheme = MauiAppTheme.Dark; + x.DefaultTheme = ThemeMode.Dark; // Default Styles Resources x.DefaultStyleResources = ["Resources/Styles/Styles.xaml"]; // All Resources Excluding Styles diff --git a/sample/MauiTheme.Sample/MainPage.xaml.cs b/sample/MauiTheme.Sample/MainPage.xaml.cs index 9b112f1..7d74eaf 100644 --- a/sample/MauiTheme.Sample/MainPage.xaml.cs +++ b/sample/MauiTheme.Sample/MainPage.xaml.cs @@ -14,14 +14,14 @@ public MainPage() BindingContext = this; } - public MauiAppTheme Selection + public ThemeMode Selection { - get => MauiTheme.Default.CurrentAppTheme; + get => Theme.Default.CurrentAppTheme; set { - if(value != MauiTheme.Default.CurrentAppTheme) + if(value != Theme.Default.CurrentAppTheme) { - MauiTheme.Default.CurrentAppTheme = value; + Theme.Default.CurrentAppTheme = value; OnPropertyChanged(nameof(Selection)); } } @@ -29,12 +29,12 @@ public MauiAppTheme Selection public string ColorKey { - get => MauiTheme.Default.CurrentResource; + get => Theme.Default.CurrentResource; set { - if (value != MauiTheme.Default.CurrentResource) + if (value != Theme.Default.CurrentResource) { - MauiTheme.Default.CurrentResource = value; + Theme.Default.CurrentResource = value; OnPropertyChanged(nameof(ColorKey)); } } diff --git a/src/MauiTheme.BlazorHybrid/BuilderExtension.cs b/src/MauiTheme.BlazorHybrid/BuilderExtension.cs index 357cc61..30bb250 100644 --- a/src/MauiTheme.BlazorHybrid/BuilderExtension.cs +++ b/src/MauiTheme.BlazorHybrid/BuilderExtension.cs @@ -9,7 +9,7 @@ public static class BuilderExtension /// /// An instance of IMauiThemeHybrid that needs to be provided from the Blazor Hybrid Project. /// Indicates whether the dependency should be stored as Scoped or Singleton. Defaults to Scoped. - public static IServiceCollection UseMauiThemeHybrid(this IServiceCollection services, IMauiThemeHybrid clientTheme, DependencyType dependencyType = DependencyType.Scoped) + public static IServiceCollection UseMauiThemeHybrid(this IServiceCollection services, IThemeHybrid clientTheme, DependencyType dependencyType = DependencyType.Scoped) { if (dependencyType == DependencyType.Scoped) services.AddScoped((_) => clientTheme); @@ -22,14 +22,17 @@ public static IServiceCollection UseMauiThemeHybrid(this IServiceCollection serv /// /// Initializes the Maui Theme for a Classic Blazor Project. Ensure not to use this BuilderExtension on Blazor Hybrid Projects. /// + /// + /// Remember that this Initializes a Mock of MauiTheme to avoid Runtime Exception When the MauiTheme is Called Directly on Classic Blazor Projects without Hybrid Hosting + /// /// Indicates whether to suppress exceptions. Defaults to True. /// Indicates whether the dependency should be stored as Scoped or Singleton. Defaults to Scoped. public static IServiceCollection UseMauiThemeBlazor(this IServiceCollection services, bool suppressException = true, DependencyType dependencyType = DependencyType.Scoped) { if (dependencyType == DependencyType.Scoped) - services.AddScoped((_) => new MauiThemeHybridDefault(suppressException)); + services.AddScoped((_) => new ThemeHybridDefault(suppressException)); else - services.AddSingleton(new MauiThemeHybridDefault(suppressException)); + services.AddSingleton(new ThemeHybridDefault(suppressException)); return services; } diff --git a/src/MauiTheme.BlazorHybrid/MauiTheme.BlazorHybrid.csproj b/src/MauiTheme.BlazorHybrid/MauiTheme.BlazorHybrid.csproj index cb94ceb..db9f4e1 100644 --- a/src/MauiTheme.BlazorHybrid/MauiTheme.BlazorHybrid.csproj +++ b/src/MauiTheme.BlazorHybrid/MauiTheme.BlazorHybrid.csproj @@ -25,9 +25,9 @@ Maui Theme - Blazor Hybrid is Extension of MauiTheme with Ability to Switch Theme and Resources from Blazor Hybrid Project without Any Maui Artifacts and Additionally Listening Theme Changes Happened from Maui App as well icon.png $(AssemblyName) ($(TargetFramework)) - 0.1.0.0 - 0.1.0.0 - 0.1.0-preview + 0.5.0.0 + 0.5.0.0 + 0.5.0 $(Version)$(VersionSuffix) true Maui,Blazor,BlazorHybrid,Theme,Color,DarkAndLight,AccentColors @@ -48,10 +48,10 @@ - + - + diff --git a/src/MauiTheme.BlazorHybrid/ReleaseNotes.txt b/src/MauiTheme.BlazorHybrid/ReleaseNotes.txt index 321b556..e2f0d9d 100644 --- a/src/MauiTheme.BlazorHybrid/ReleaseNotes.txt +++ b/src/MauiTheme.BlazorHybrid/ReleaseNotes.txt @@ -1,2 +1,7 @@ -v0.1.0-preview +v0.5.0 +• First Stable Build +• Breaking Changes, Check the Docs +https://github.com/AathifMahir/MauiTheme + +v0.1.0-preview • Blazor Hybrid Support \ No newline at end of file diff --git a/src/MauiTheme.BlazorHybrid/MauiThemeContext.cs b/src/MauiTheme.BlazorHybrid/ThemeContext.cs similarity index 69% rename from src/MauiTheme.BlazorHybrid/MauiThemeContext.cs rename to src/MauiTheme.BlazorHybrid/ThemeContext.cs index 6cab6ed..fc30370 100644 --- a/src/MauiTheme.BlazorHybrid/MauiThemeContext.cs +++ b/src/MauiTheme.BlazorHybrid/ThemeContext.cs @@ -1,21 +1,21 @@ using MauiTheme.Core; namespace MauiTheme.BlazorHybrid; -public sealed class MauiThemeContext +public sealed class ThemeContext { - private readonly IMauiThemeHybrid _mauiTheme; + private readonly IThemeHybrid _mauiTheme; public event Action? OnChanged; - private MauiThemeContext(IMauiThemeHybrid mauiTheme) + private ThemeContext(IThemeHybrid mauiTheme) { _mauiTheme = mauiTheme; _mauiTheme.ThemeChanged += MauiTheme_ThemeChanged; _mauiTheme.ResourceChanged += MauiTheme_ResourceChanged; } - public static MauiThemeContext Create(IMauiThemeHybrid mauiTheme, Action onThemeChangedCallback) + public static ThemeContext Create(IThemeHybrid mauiTheme, Action onThemeChangedCallback) { - var theme = new MauiThemeContext(mauiTheme); + var theme = new ThemeContext(mauiTheme); theme.OnChanged += onThemeChangedCallback; return theme; } @@ -25,7 +25,7 @@ private void MauiTheme_ResourceChanged(object? sender, Core.Events.ResourceChang OnChanged?.Invoke(); } - private void MauiTheme_ThemeChanged(object? sender, Core.Events.MauiAppThemeChangedEventArgs e) + private void MauiTheme_ThemeChanged(object? sender, Core.Events.ThemeModeChangedEventArgs e) { OnChanged?.Invoke(); } diff --git a/src/MauiTheme.BlazorHybrid/MauiThemeHybridDefault.cs b/src/MauiTheme.BlazorHybrid/ThemeHybridDefault.cs similarity index 79% rename from src/MauiTheme.BlazorHybrid/MauiThemeHybridDefault.cs rename to src/MauiTheme.BlazorHybrid/ThemeHybridDefault.cs index 8f623a6..19e1357 100644 --- a/src/MauiTheme.BlazorHybrid/MauiThemeHybridDefault.cs +++ b/src/MauiTheme.BlazorHybrid/ThemeHybridDefault.cs @@ -3,10 +3,10 @@ using MauiTheme.Core.Exceptions; namespace MauiTheme.BlazorHybrid; -internal sealed class MauiThemeHybridDefault : IMauiThemeHybrid +internal sealed class ThemeHybridDefault : IThemeHybrid { - readonly MauiAppTheme _currentAppTheme = MauiAppTheme.Unspecified; - public MauiAppTheme CurrentAppTheme + readonly ThemeMode _currentAppTheme = ThemeMode.Unspecified; + public ThemeMode CurrentAppTheme { get => _currentAppTheme; set @@ -37,14 +37,14 @@ public string CurrentResource } } - public MauiThemeContext Context { get; } = default!; + public ThemeContext Context { get; } = default!; readonly bool _suppressException; - public event EventHandler? ThemeChanged; + public event EventHandler? ThemeChanged; public event EventHandler? ResourceChanged; - public MauiThemeHybridDefault(bool suppressException) + public ThemeHybridDefault(bool suppressException) { _suppressException = suppressException; } diff --git a/src/MauiTheme.BlazorHybrid/readme.md b/src/MauiTheme.BlazorHybrid/readme.md index b3ac870..d420a1a 100644 --- a/src/MauiTheme.BlazorHybrid/readme.md +++ b/src/MauiTheme.BlazorHybrid/readme.md @@ -1,12 +1,12 @@ # Maui Theme Blazor Hybrid -MauiTheme Blazor Hybrid is Extension of Vanilla MauiTheme Library Where it Provides Access the MauiTheme Without Any Maui Artifacts Inside a Razor Class Library +**MauiTheme Blazor Hybrid** is an extension of the Vanilla MauiTheme Library, providing access to the MauiTheme without any Maui artifacts inside a Razor Class Library. -**Disclaimer:** You need to have [MauiTheme Library](https://www.nuget.org/packages/AathifMahir.Maui.MauiTheme) Installed on Your Maui Project and `InitializeTheme()` Method is Called in `App.xaml.cs` +**Disclaimer:** You need to have the [MauiTheme Library](https://www.nuget.org/packages/AathifMahir.Maui.MauiTheme) installed in your Maui project, and the `InitializeTheme()` method must be called in `App.xaml.cs`. # Get Started -In Order to Initialize the MauiTheme Blazor Hybrid, You need to call `UseMauiThemeHybrid()` in `program.cs` like below example +To initialize the MauiTheme Blazor Hybrid, you need to call `UseMauiThemeHybrid()` in `program.cs` as shown in the example below: ```csharp using MauiTheme.BlazorHybrid; @@ -18,7 +18,7 @@ public static class MauiProgram var builder = MauiApp.CreateBuilder(); // Initializing MauiTheme on Blazor Hybrid Project by Sharing the Instance of MauiTheme - builder.Services.UseMauiThemeHybrid(MauiTheme.Default); + builder.Services.UseMauiThemeHybrid(Theme.Default); return builder.Build(); } @@ -32,35 +32,38 @@ var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.Services.UseMauiThemeBlazor(); ``` +**Disclaimer:** Calling `UseMauiThemeBlazor()` won't make the MauiTheme available for Classic Blazor Hosting Models. Instead, this would prevent runtime exceptions if any property is changed outside of Blazor Hybrid context. + # Theme -When it comes to Switching Theme, You can change the `CurrentTheme` Property to Switch the Theme Like Below Example +When it comes to switching themes, you can change the `CurrentTheme` property to switch the theme like in the example below: ```csharp -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid ThemeHybrid // Dark -MauiThemeHybrid.CurrentTheme = MauiAppTheme.Dark; +ThemeHybrid.CurrentTheme = ThemeMode.Dark; // Light -MauiThemeHybrid.CurrentTheme = MauiAppTheme.Light; +ThemeHybrid.CurrentTheme = ThemeMode.Light; // System -MauiThemeHybrid.CurrentTheme = MauiAppTheme.UnSpecified; +ThemeHybrid.CurrentTheme = ThemeMode.UnSpecified; ``` # Resources -When it comes to Switching Resource, You can use `CurrentResource` Property to Swap the Resources Like Below Example, Make sure to Note that Resources is Applied Using The Key that you have passed into `InitializeTheme` `Resources` Property +When it comes to switching resources, you can use the `CurrentResource` property to swap the resources, as shown in the example below. Make sure to note that resources are applied using the key that you have passed into the `InitializeTheme` `Resources` property. + ```csharp -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid ThemeHybrid // Pass in your resource key that assigned in Maui Project -MauiThemeHybrid.CurrentResource = "Blue"; +ThemeHybrid.CurrentResource = "Blue"; ``` @@ -68,18 +71,18 @@ MauiThemeHybrid.CurrentResource = "Blue"; This is mainly useful when listening to Theme or Resource Changes from External Sources for Instance from Maui, as you can see in the below example, we are invoking `StateChanged()` method in MauiThemeContext, Basically What that Says is Refresh the Razor Component Whenever Theme Changes -```razor +```csharp -@inject IMauiThemeHybrid MauiThemeHybrid +@inject IThemeHybrid ThemeHybrid @implements IDisposable Theme

Theme

- - @foreach (var item in (MauiAppTheme[])Enum.GetValues(typeof(MauiAppTheme))) + + @foreach (var item in (ThemeMode[])Enum.GetValues(typeof(ThemeMode))) { - + @item
} @@ -88,7 +91,7 @@ This is mainly useful when listening to Theme or Resource Changes from External

Color

- + Blue
Purple
Yellow
@@ -97,11 +100,11 @@ This is mainly useful when listening to Theme or Resource Changes from External @code{ - MauiThemeContext? themeContext; + ThemeContext? themeContext; protected override void OnInitialized() { - themeContext = MauiThemeContext.Create(MauiThemeHybrid, () => StateHasChanged()); + themeContext = ThemeContext.Create(ThemeHybrid, () => StateHasChanged()); base.OnInitialized(); } @@ -114,6 +117,14 @@ This is mainly useful when listening to Theme or Resource Changes from External ``` +# Properties and Methods + +| Parameters | Type | Description | +| :--- | :---: | :---: +| **CurrentTheme** | `ThemeMode` | Gets or sets the current theme | +| **CurrentResource** | `string` | Gets or sets the current resource | +| **ThemeContext.Create()** | `method` | Theme Context would trigger CallBack Whenever Theme Changes Happens Outside Blazor Context | + # License diff --git a/src/MauiTheme.Core/Events/MauiAppThemeChangedEventArgs.cs b/src/MauiTheme.Core/Events/MauiAppThemeChangedEventArgs.cs deleted file mode 100644 index b161fc9..0000000 --- a/src/MauiTheme.Core/Events/MauiAppThemeChangedEventArgs.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace MauiTheme.Core.Events; -public sealed class MauiAppThemeChangedEventArgs : EventArgs -{ - public MauiAppTheme CurrentTheme { get; set; } - - public MauiAppThemeChangedEventArgs(MauiAppTheme currentTheme) - { - CurrentTheme = currentTheme; - } -} diff --git a/src/MauiTheme.Core/Events/ThemeModeChangedEventArgs.cs b/src/MauiTheme.Core/Events/ThemeModeChangedEventArgs.cs new file mode 100644 index 0000000..689e422 --- /dev/null +++ b/src/MauiTheme.Core/Events/ThemeModeChangedEventArgs.cs @@ -0,0 +1,10 @@ +namespace MauiTheme.Core.Events; +public sealed class ThemeModeChangedEventArgs : EventArgs +{ + public ThemeMode CurrentTheme { get; set; } + + public ThemeModeChangedEventArgs(ThemeMode currentTheme) + { + CurrentTheme = currentTheme; + } +} diff --git a/src/MauiTheme.Core/IMauiThemeHybrid.cs b/src/MauiTheme.Core/IThemeHybrid.cs similarity index 83% rename from src/MauiTheme.Core/IMauiThemeHybrid.cs rename to src/MauiTheme.Core/IThemeHybrid.cs index 4533a8f..d2c4ea2 100644 --- a/src/MauiTheme.Core/IMauiThemeHybrid.cs +++ b/src/MauiTheme.Core/IThemeHybrid.cs @@ -3,12 +3,12 @@ using MauiTheme.Core.Events; namespace MauiTheme.Core; -public interface IMauiThemeHybrid +public interface IThemeHybrid { /// /// Get or Set Current App Theme /// - public MauiAppTheme CurrentAppTheme { get; set; } + public ThemeMode CurrentAppTheme { get; set; } /// /// Get or Set Current App Resource using the Key that Used on Theme Initialization @@ -19,7 +19,7 @@ public interface IMauiThemeHybrid /// Theme Changed Event for Detecting Theme Changes at Realtime and also ThemeChanged Event Does Support Theme Change Notification from External Sources /// - event EventHandler? ThemeChanged; + event EventHandler? ThemeChanged; /// /// Resource Changed Event for Detecting Resource Changes at Realtime and also ResourceChanged Event Does Support Resource Change Notification from External Sources diff --git a/src/MauiTheme.Core/MauiTheme.Core.csproj b/src/MauiTheme.Core/MauiTheme.Core.csproj index 9c06eed..63e1a94 100644 --- a/src/MauiTheme.Core/MauiTheme.Core.csproj +++ b/src/MauiTheme.Core/MauiTheme.Core.csproj @@ -26,9 +26,9 @@ Maui Theme for Dotnet Maui with Ability Retain Sessions and Easy Resource Swapping, Easy Theme Switcher and etc.. icon.png $(AssemblyName) ($(TargetFramework)) - 0.1.0.0 - 0.1.0.0 - 0.1.0-preview + 0.5.0.0 + 0.5.0.0 + 0.5.0 $(Version)$(VersionSuffix) true Maui,Theme,Color,DarkAndLight,AccentColors diff --git a/src/MauiTheme.Core/ReleaseNotes.txt b/src/MauiTheme.Core/ReleaseNotes.txt index 56f7df0..355adfc 100644 --- a/src/MauiTheme.Core/ReleaseNotes.txt +++ b/src/MauiTheme.Core/ReleaseNotes.txt @@ -1,2 +1,7 @@ -v0.1.0-preview +v0.5.0 +• First Stable Build +• Breaking Changes, Check the Docs +https://github.com/AathifMahir/MauiTheme + +v0.1.0-preview • Core Library \ No newline at end of file diff --git a/src/MauiTheme.Core/MauiAppTheme.cs b/src/MauiTheme.Core/ThemeMode.cs similarity index 89% rename from src/MauiTheme.Core/MauiAppTheme.cs rename to src/MauiTheme.Core/ThemeMode.cs index 08071d1..2ef0811 100644 --- a/src/MauiTheme.Core/MauiAppTheme.cs +++ b/src/MauiTheme.Core/ThemeMode.cs @@ -1,5 +1,5 @@ namespace MauiTheme.Core; -public enum MauiAppTheme +public enum ThemeMode { /// Default, unknown or unspecified theme. Unspecified, diff --git a/src/MauiTheme/Extensions/EnumExtension.cs b/src/MauiTheme/Extensions/EnumExtension.cs index 6e4c742..222c1d1 100644 --- a/src/MauiTheme/Extensions/EnumExtension.cs +++ b/src/MauiTheme/Extensions/EnumExtension.cs @@ -3,12 +3,12 @@ namespace MauiTheme.Extensions; internal static class EnumExtension { - internal static AppTheme MapToAppTheme(this MauiAppTheme mauiAppTheme) => + internal static AppTheme MapToAppTheme(this ThemeMode mauiAppTheme) => mauiAppTheme switch { - MauiAppTheme.Unspecified => AppTheme.Unspecified, - MauiAppTheme.Dark => AppTheme.Dark, - MauiAppTheme.Light => AppTheme.Light, + ThemeMode.Unspecified => AppTheme.Unspecified, + ThemeMode.Dark => AppTheme.Dark, + ThemeMode.Light => AppTheme.Light, _ => AppTheme.Unspecified, }; } diff --git a/src/MauiTheme/IMauiTheme.cs b/src/MauiTheme/ITheme.cs similarity index 95% rename from src/MauiTheme/IMauiTheme.cs rename to src/MauiTheme/ITheme.cs index 4f5cdb1..9601589 100644 --- a/src/MauiTheme/IMauiTheme.cs +++ b/src/MauiTheme/ITheme.cs @@ -2,7 +2,7 @@ using System.Windows.Input; namespace MauiTheme; -public interface IMauiTheme : IMauiThemeHybrid +public interface ITheme : IThemeHybrid { /// /// Initializes the Maui Theme diff --git a/src/MauiTheme/MauiTheme.csproj b/src/MauiTheme/MauiTheme.csproj index 41e9cf6..227faf2 100644 --- a/src/MauiTheme/MauiTheme.csproj +++ b/src/MauiTheme/MauiTheme.csproj @@ -41,9 +41,9 @@ Maui Theme for Dotnet Maui with Ability Retain Sessions and Easy Resource Swapping, Easy Theme Switcher and etc.. icon.png $(AssemblyName) ($(TargetFramework)) - 0.1.0.0 - 0.1.0.0 - 0.1.1-preview + 0.5.0.0 + 0.5.0.0 + 0.5.0 $(Version)$(VersionSuffix) true Maui,Theme,Color,DarkAndLight,AccentColors diff --git a/src/MauiTheme/ReleaseNotes.txt b/src/MauiTheme/ReleaseNotes.txt index ce26945..a38538d 100644 --- a/src/MauiTheme/ReleaseNotes.txt +++ b/src/MauiTheme/ReleaseNotes.txt @@ -1,4 +1,9 @@ -v0.1.0-preview +v0.5.0 +• First Stable Build +• Breaking Changes, Check the Docs +https://github.com/AathifMahir/MauiTheme + +v0.1.0-preview • Enhancements and Fixes • Breaking Changes on Maui Built in AppTheme Construct, Now MauiTheme Uses Custom Construct Called MauiAppTheme diff --git a/src/MauiTheme/MauiTheme.cs b/src/MauiTheme/Theme.cs similarity index 77% rename from src/MauiTheme/MauiTheme.cs rename to src/MauiTheme/Theme.cs index dccc1da..173491e 100644 --- a/src/MauiTheme/MauiTheme.cs +++ b/src/MauiTheme/Theme.cs @@ -3,9 +3,9 @@ using System.Windows.Input; namespace MauiTheme; -public static class MauiTheme +public static class Theme { - public static MauiAppTheme CurrentAppTheme + public static ThemeMode CurrentAppTheme { get => Default.CurrentAppTheme; set => Default.CurrentAppTheme = value; @@ -18,7 +18,7 @@ public static string CurrentResource public static void InitializeTheme(Action configs) where TApp : Application => Default.InitializeTheme(configs); - public static event EventHandler? ThemeChanged + public static event EventHandler? ThemeChanged { add => Default.ThemeChanged += value; remove => Default.ThemeChanged -= value; @@ -42,10 +42,10 @@ public static ICommand? ResourceChangedCommand set => Default.ResourceChangedCommand = value; } - internal static void SetDefault(IMauiTheme? implementation) => + internal static void SetDefault(ITheme? implementation) => defaultTheme = implementation; - static IMauiTheme? defaultTheme; + static ITheme? defaultTheme; - public static IMauiTheme Default => defaultTheme ??= new MauiThemeDefault(); + public static ITheme Default => defaultTheme ??= new ThemeDefault(); } diff --git a/src/MauiTheme/ThemeConfiguration.cs b/src/MauiTheme/ThemeConfiguration.cs index ffb6d90..6e87095 100644 --- a/src/MauiTheme/ThemeConfiguration.cs +++ b/src/MauiTheme/ThemeConfiguration.cs @@ -9,7 +9,7 @@ public sealed class ThemeConfiguration /// /// Defaults to MauiAppTheme.Unspecified /// - public MauiAppTheme DefaultTheme { get; set; } = MauiAppTheme.Unspecified; + public ThemeMode DefaultTheme { get; set; } = ThemeMode.Unspecified; /// /// Implies an array of style resources that should be applied consistently with every theme change. diff --git a/src/MauiTheme/MauiThemeDefault.cs b/src/MauiTheme/ThemeDefault.cs similarity index 93% rename from src/MauiTheme/MauiThemeDefault.cs rename to src/MauiTheme/ThemeDefault.cs index 2a51fbd..de1939a 100644 --- a/src/MauiTheme/MauiThemeDefault.cs +++ b/src/MauiTheme/ThemeDefault.cs @@ -9,11 +9,11 @@ namespace MauiTheme; -internal sealed class MauiThemeDefault : IMauiTheme +internal sealed class ThemeDefault : ITheme { - private MauiAppTheme _currentAppTheme; - public MauiAppTheme CurrentAppTheme + private ThemeMode _currentAppTheme; + public ThemeMode CurrentAppTheme { get => _currentAppTheme; set @@ -23,7 +23,7 @@ public MauiAppTheme CurrentAppTheme _currentAppTheme = value; SetTheme(value); - ThemeChanged?.Invoke(this, new MauiAppThemeChangedEventArgs(value)); + ThemeChanged?.Invoke(this, new ThemeModeChangedEventArgs(value)); if (ThemeChangedCommand is not null && ThemeChangedCommand.CanExecute(value)) ThemeChangedCommand.Execute(value); @@ -57,12 +57,12 @@ public string CurrentResource const string _storageKey = "Theme"; ThemeStorage _themeStorage = new(); Dictionary _resources = new(); - MauiAppTheme _defaultTheme; + ThemeMode _defaultTheme; string[] _defaultStyleResources = Array.Empty(); - Assembly _appAssembly = typeof(MauiThemeDefault).Assembly; + Assembly _appAssembly = typeof(ThemeDefault).Assembly; bool _isInitialized = false; - public event EventHandler? ThemeChanged; + public event EventHandler? ThemeChanged; public event EventHandler? ResourceChanged; public void InitializeTheme(Action themeConfiguration) @@ -83,7 +83,7 @@ public void InitializeTheme(Action themeConfiguration) if (json.IsEmpty) { _currentResource = GetInitialResource(); - if (_defaultTheme is MauiAppTheme.Unspecified) return; + if (_defaultTheme is ThemeMode.Unspecified) return; ApplyTheme(_defaultTheme); return; } @@ -161,7 +161,7 @@ void SetResource(string resourceKey) Preferences.Default.Set(_storageKey, _themeStorage.ToJson()); } - void ApplyTheme(MauiAppTheme theme) + void ApplyTheme(ThemeMode theme) { if (Application.Current is null) return; var appTheme = theme.MapToAppTheme(); @@ -171,7 +171,7 @@ void ApplyTheme(MauiAppTheme theme) _currentAppTheme = theme; } - void SetTheme(MauiAppTheme appTheme) + void SetTheme(ThemeMode appTheme) { if (!_isInitialized) throw new MauiThemeException("Make sure to Initialize by using Initialize Theme before Setting the Theme"); diff --git a/src/MauiTheme/ThemeStorage.cs b/src/MauiTheme/ThemeStorage.cs index 9df7fe5..0ab4054 100644 --- a/src/MauiTheme/ThemeStorage.cs +++ b/src/MauiTheme/ThemeStorage.cs @@ -6,7 +6,7 @@ namespace MauiTheme; public sealed class ThemeStorage { [JsonPropertyName("Theme")] - public MauiAppTheme AppTheme { get; set; } + public ThemeMode AppTheme { get; set; } [JsonPropertyName("Resource")] public string Resource { get; set; } = string.Empty; diff --git a/src/MauiTheme/readme.md b/src/MauiTheme/readme.md index 26dee6f..e0510ea 100644 --- a/src/MauiTheme/readme.md +++ b/src/MauiTheme/readme.md @@ -1,48 +1,43 @@ # Maui Theme -|**Latest Stable** | **Latest Preview**| -| :---: | :---: | -|[![AathifMahir.Maui.MauiShakeDetector](https://img.shields.io/nuget/v/AathifMahir.Maui.MauiTheme)](https://www.nuget.org/packages/AathifMahir.Maui.MauiTheme/) | [![AathifMahir.Maui.MauiShakeDetector](https://img.shields.io/nuget/vpre/AathifMahir.Maui.MauiTheme)](https://nuget.org/packages/AathifMahir.Maui.MauiTheme/absoluteLatest) | - -MauiTheme is Theming Libray that Makes the Theming on Dotnet Maui a Breeze with Persistent Theme State Between Sessions and Seamless Resource Swapping, Theme Switcher and etc.. +MauiTheme is a theming library that makes theming on .NET MAUI a breeze, providing persistent theme state between sessions and seamless resource swapping, theme switcher, and more. # Get Started -You need to Call `InitializeTheme()` in the `App.xaml.cs` Like Below Example +You need to call `InitializeTheme()` in the `App.xaml.cs` file as shown in the example below. Ensure that `InitializeTheme()` is called before setting up the MainPage property. ```csharp +using MauiTheme.Core; + public partial class App : Application { public App() { InitializeComponent(); - MainPage = new AppShell(); - Theme.Default.InitializeTheme(x => { // Default Theme - x.DefaultTheme = MauiAppTheme.Dark; + x.DefaultTheme = ThemeMode.Dark; // Default Styles Resources - x.DefaultStyleResources = ["Resources/Styles/Styles.xaml"]; + x.DefaultStyleResources = new List { "Resources/Styles/Styles.xaml" }; // All Resources Excluding Styles - x.Resources = new() - { - {"Blue", "Resources/Styles/Blue.xaml"}, - {"Purple", "Resources/Styles/Colors.xaml"}, - {"Yellow", "Resources/Styles/Yellow.xaml" }, - {"Green", "Resources/Styles/Green.xaml" } - }; - + x.Resources = new Dictionary + { + {"Blue", "Resources/Styles/Blue.xaml"}, + {"Purple", "Resources/Styles/Colors.xaml"}, + {"Yellow", "Resources/Styles/Yellow.xaml" }, + {"Green", "Resources/Styles/Green.xaml" } + }; }); + MainPage = new AppShell(); } -} ``` # App.xaml Setup -The App.xaml should include the Default Color and Style Resource Like Below Example +The App.xaml should include the default color and style resources as shown below: ```xml @@ -66,24 +61,26 @@ The App.xaml should include the Default Color and Style Resource Like Below Exam # Theme -When it comes to Switching Theme, You can change the `CurrentTheme` Property to Switch the Theme Like Below Example +When it comes to switching themes, you can change the `CurrentTheme` property to switch the theme as shown below: ```csharp // Dark -Theme.Default.CurrentTheme = MauiAppTheme.Dark; +Theme.Default.CurrentTheme = ThemeMode.Dark; // Light -Theme.Default.CurrentTheme = MauiAppTheme.Light; +Theme.Default.CurrentTheme = ThemeMode.Light; // System -Theme.Default.CurrentTheme = MauiAppTheme.UnSpecified; +Theme.Default.CurrentTheme = ThemeMode.UnSpecified; ``` # Resources -When it comes to Switching Resource, You can use `CurrentResource` Property to Swap the Resources Like Below Example, Make sure to Note that Resources is Applied Using The Key that you have passed into `InitializeTheme` `Resources` Property +When it comes to switching resources, you can use the `CurrentResource` property to swap the resources. + +**Dislaimer:** the resources are applied using the key passed into the InitializeTheme `Resources` property: ```csharp @@ -100,25 +97,37 @@ Theme.Default.CurrentResource = "Yellow"; # Listening to Theme or Resource Changes -Mainly this is useful when theme or resource changes is invoked from external source for instance from a razor class library +This is mainly useful when theme or resource changes are invoked from an external source, such as a razor class library but nothing stopping from using it tradionally: ```csharp // Theme Changed Event -MauiTheme.Default.ThemeChanged += (s, t) => +Theme.Default.ThemeChanged += (s, t) => { Debug.Writeline($"New Theme : {t.ToString()}") } // Theme Changed Event -MauiTheme.Default.ResourceChanged += (s, r) => +Theme.Default.ResourceChanged += (s, r) => { Debug.Writeline($"New Resource : {r}") } ``` -Additionally we can use `ICommand` as well, Those are `ThemeChangedCommand` and `ResourceChangedCommand` +Additionally, we can use `ICommand` as well, those are `ThemeChangedCommand` and `ResourceChangedCommand`. + +# Properties and Methods + +| Parameters | Type | Description | +| :--- | :---: | :---: +| **InitializeTheme()** | `method` | This is used for Initializing MauiTheme || +| **CurrentTheme** | `ThemeMode` | Gets or sets the current theme | +| **CurrentResource** | `string` | Gets or sets the current resource | +| **ThemeChanged** | `event` | Theme Changed event is fired whenever theme changes happens | +| **ResourceChanged** | `event` | Resource Changed event is fired whenever resource changes happens | +| **ThemeChangedCommand** | `ICommand` | Theme Changed Command is fired whenever theme changes happens | +| **ResourceChangedCommand** | `ICommand` | Resource Changed Command is fired whenever resource changes happens | # License @@ -127,6 +136,6 @@ Maui Theme is Licensed Under [MIT License](https://github.com/AathifMahir/MauiTh # Contribute and Credit -Credits for @taublast for Helping with Resource Creation. +Credits to [@taublast](https://github.com/taublast) for Helping with Resource Creation. If you wish to contribute to this project, please don't hesitate to create an issue or request. Your input and feedback are highly appreciated. Additionally, if you're interested in supporting the project by providing resources or [**becoming a sponsor**](https://github.com/sponsors/AathifMahir), your contributions would be welcomed and instrumental in its continued development and success. Thank you for your interest in contributing to this endeavor. \ No newline at end of file