diff --git a/src/MudBlazor.ThemeManager/Components/MudThemeManager.razor.cs b/src/MudBlazor.ThemeManager/Components/MudThemeManager.razor.cs index c847693..7eb832f 100644 --- a/src/MudBlazor.ThemeManager/Components/MudThemeManager.razor.cs +++ b/src/MudBlazor.ThemeManager/Components/MudThemeManager.razor.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Components; using MudBlazor.State; using MudBlazor.ThemeManager.Extensions; -using System.Diagnostics.CodeAnalysis; namespace MudBlazor.ThemeManager; @@ -49,7 +48,6 @@ public MudThemeManager() [Parameter] public EventCallback ThemeChanged { get; set; } - [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")] protected override void OnInitialized() { base.OnInitialized(); diff --git a/src/MudBlazor.ThemeManager/Extensions/Extension.cs b/src/MudBlazor.ThemeManager/Extensions/Extension.cs index c9ed70c..cdc1e50 100644 --- a/src/MudBlazor.ThemeManager/Extensions/Extension.cs +++ b/src/MudBlazor.ThemeManager/Extensions/Extension.cs @@ -1,22 +1,98 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text.Json; +using System.Text.Json; namespace MudBlazor.ThemeManager.Extensions; internal static class Extension { - private static readonly JsonSerializerOptions JsonOptions = new(); + private static readonly PaletteSerializerContext PaletteSerializerContext = new(); + private static readonly ThemeSerializerContext ThemeSerializerContext = new(); - [RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")] - public static T? DeepClone(this T source) + public static MudTheme DeepClone(this MudTheme source) { - if (source is not null) + // TODO: Needs this to be done https://github.com/MudBlazor/MudBlazor/pull/9434 + //var themeType = typeof(MudTheme); + //var serializeStr = JsonSerializer.Serialize(source, themeType, ThemeSerializerContext); + //var copyObj = (MudTheme?)JsonSerializer.Deserialize(serializeStr, themeType, ThemeSerializerContext); + + //return copyObj; + + // Code below is a workaround for the above issue + + return new MudTheme + { + PaletteDark = source.PaletteDark.DeepClone() ?? new PaletteDark(), + PaletteLight = source.PaletteLight.DeepClone() ?? new PaletteLight(), + Shadows = DeepCloneTheme(source.Shadows) ?? new Shadow(), + LayoutProperties = DeepCloneTheme(source.LayoutProperties) ?? new LayoutProperties(), + ZIndex = DeepCloneTheme(source.ZIndex) ?? new ZIndex(), + PseudoCss = DeepCloneTheme(source.PseudoCss) ?? new PseudoCss(), + // Exception case + Typography = new Typography + { + Default = DeepCloneBaseTypography(source.Typography.Default), + H1 = DeepCloneBaseTypography(source.Typography.H1), + H2 = DeepCloneBaseTypography(source.Typography.H2), + H3 = DeepCloneBaseTypography(source.Typography.H3), + H4 = DeepCloneBaseTypography(source.Typography.H4), + H5 = DeepCloneBaseTypography(source.Typography.H5), + H6 = DeepCloneBaseTypography(source.Typography.H6), + Subtitle1 = DeepCloneBaseTypography(source.Typography.Subtitle1), + Subtitle2 = DeepCloneBaseTypography(source.Typography.Subtitle2), + Body1 = DeepCloneBaseTypography(source.Typography.Body1), + Body2 = DeepCloneBaseTypography(source.Typography.Body2), + Input = DeepCloneBaseTypography(source.Typography.Input), + Button = DeepCloneBaseTypography(source.Typography.Button), + Caption = DeepCloneBaseTypography(source.Typography.Caption), + Overline = DeepCloneBaseTypography(source.Typography.Overline) + } + }; + } + + public static PaletteDark? DeepClone(this PaletteDark source) => DeepClonePalette(source); + + public static PaletteLight? DeepClone(this PaletteLight source) => DeepClonePalette(source); + + private static T? DeepClonePalette(T source) where T : Palette + { + var paletteType = typeof(T); + var serializeStr = JsonSerializer.Serialize(source, paletteType, PaletteSerializerContext); + var copyObj = (T?)JsonSerializer.Deserialize(serializeStr, paletteType, PaletteSerializerContext); + + return copyObj; + } + + private static T? DeepCloneTheme(T source) where T : class + { + var paletteType = typeof(T); + var serializeStr = JsonSerializer.Serialize(source, paletteType, ThemeSerializerContext); + var copyObj = (T?)JsonSerializer.Deserialize(serializeStr, paletteType, ThemeSerializerContext); + + return copyObj; + } + + private static T DeepCloneBaseTypography(T baseTypography) where T : BaseTypography, new() + { + string[] fontFamilyCloned = new string[baseTypography.FontFamily?.Length ?? 0]; + if (baseTypography.FontFamily is not null) { - var serializeStr = JsonSerializer.Serialize(source, JsonOptions); - var copyObj = JsonSerializer.Deserialize(serializeStr, JsonOptions); - return copyObj; + Array.Copy(baseTypography.FontFamily, fontFamilyCloned, baseTypography.FontFamily.Length); } - return default; + + var fontWeightCloned = baseTypography.FontWeight; + var fontSizeCloned = baseTypography.FontSize; + var lineHeightCloned = baseTypography.LineHeight; + var letterSpacingCloned = baseTypography.LetterSpacing; + var textTransformCloned = baseTypography.TextTransform; + + return new T + { + FontWeight = fontWeightCloned, + FontFamily = fontFamilyCloned, + FontSize = fontSizeCloned, + LineHeight = lineHeightCloned, + LetterSpacing = letterSpacingCloned, + TextTransform = textTransformCloned, + }; } } \ No newline at end of file diff --git a/src/MudBlazor.ThemeManager/Extensions/PaletteSerializerContext.cs b/src/MudBlazor.ThemeManager/Extensions/PaletteSerializerContext.cs new file mode 100644 index 0000000..83538eb --- /dev/null +++ b/src/MudBlazor.ThemeManager/Extensions/PaletteSerializerContext.cs @@ -0,0 +1,8 @@ +using System.Text.Json.Serialization; + +namespace MudBlazor.ThemeManager.Extensions; + +[JsonSerializable(typeof(Palette))] +[JsonSerializable(typeof(PaletteDark))] +[JsonSerializable(typeof(PaletteLight))] +internal sealed partial class PaletteSerializerContext : JsonSerializerContext; \ No newline at end of file diff --git a/src/MudBlazor.ThemeManager/Extensions/ThemeSerializerContext.cs b/src/MudBlazor.ThemeManager/Extensions/ThemeSerializerContext.cs new file mode 100644 index 0000000..02d74a6 --- /dev/null +++ b/src/MudBlazor.ThemeManager/Extensions/ThemeSerializerContext.cs @@ -0,0 +1,11 @@ +using System.Text.Json.Serialization; + +namespace MudBlazor.ThemeManager.Extensions; + + +//[JsonSerializable(typeof(MudTheme))] TODO: Needs this to be done https://github.com/MudBlazor/MudBlazor/pull/9434 rest can be removed after +[JsonSerializable(typeof(Shadow))] +[JsonSerializable(typeof(LayoutProperties))] +[JsonSerializable(typeof(ZIndex))] +[JsonSerializable(typeof(PseudoCss))] +internal sealed partial class ThemeSerializerContext : JsonSerializerContext; \ No newline at end of file diff --git a/src/MudBlazor.ThemeManager/MudBlazor.ThemeManager.csproj b/src/MudBlazor.ThemeManager/MudBlazor.ThemeManager.csproj index 11802e7..0fbadb0 100644 --- a/src/MudBlazor.ThemeManager/MudBlazor.ThemeManager.csproj +++ b/src/MudBlazor.ThemeManager/MudBlazor.ThemeManager.csproj @@ -2,6 +2,7 @@ net7.0;net8.0 + latest enable enable true